From d02c9bdda51071905920e3f5434b17c8c4ddfdf1 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 7 Oct 2022 09:29:38 -0700 Subject: [PATCH 01/58] Fp6 mult --- evm/src/cpu/kernel/asm/fields/Fp6.asm | 154 ++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 evm/src/cpu/kernel/asm/fields/Fp6.asm diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm new file mode 100644 index 00000000..41d854c7 --- /dev/null +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -0,0 +1,154 @@ +Fp6: + DUP3 + DUP11 + MUL + DUP2 + DUP14 + MUL + SUB + DUP12 + DUP8 + MUL + DUP9 + DUP5 + MUL + ADD + DUP7 + DUP7 + MUL + DUP12 + DUP12 + MUL + ADD + SUB + DUP7 + DUP5 + MUL + DUP10 + DUP8 + MUL + ADD + DUP12 + DUP10 + MUL + ADD + DUP14 + DUP12 + MUL + ADD + DUP15 + DUP7 + MUL + DUP14 + DUP6 + MUL + ADD + DUP2 + DUP4 + PUSH 9 + MUL + SUB + ADD + %mstore_kernel_general(0) + PUSH 9 + MUL + ADD + ADD + %mstore_kernel_general(1) + DUP4 + DUP12 + MUL + DUP3 + DUP11 + MUL + ADD + DUP3 + DUP13 + MUL + DUP6 + DUP12 + MUL + SUB + DUP12 + DUP10 + MUL + DUP9 + DUP7 + MUL + ADD + DUP2 + DUP4 + PUSH 9 + MUL + SUB + SUB + DUP15 + DUP9 + MUL + DUP12 + DUP6 + MUL + ADD + ADD + %mstore_kernel_general(2) + PUSH 9 + MUL + ADD + DUP13 + DUP9 + MUL + DUP12 + DUP8 + MUL + ADD + DUP10 + DUP6 + MUL + ADD + DUP8 + DUP4 + MUL + ADD + ADD + %mstore_kernel_general(3) + DUP10 + DUP12 + MUL + DUP7 + DUP9 + MUL + ADD + DUP3 + DUP5 + MUL + ADD + DUP13 + DUP11 + MUL + DUP10 + DUP8 + MUL + ADD + DUP6 + DUP4 + MUL + ADD + SUB + %mstore_kernel_general(4) + MUL + SWAP2 + MUL + ADD + SWAP2 + MUL + ADD + SWAP2 + MUL + ADD + SWAP2 + MUL + ADD + SWAP2 + MUL + ADD + %mstore_kernel_general(5) \ No newline at end of file From 00534286a609e8cafcd3d1296d08ad271a4edad8 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 7 Oct 2022 15:41:46 -0700 Subject: [PATCH 02/58] Fp12 mult + Fp6 macros --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 59 +++++++++ evm/src/cpu/kernel/asm/fields/Fp6.asm | 166 ++++++++++++++++++++++++- 2 files changed, 223 insertions(+), 2 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/fields/Fp12.asm diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm new file mode 100644 index 00000000..400676de --- /dev/null +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -0,0 +1,59 @@ +/// F = f + f'z +/// G = g + g'z +/// +/// h + h'z = FG +/// +/// h = fg + sh(f'g') +/// h' = (f+f')(g+g') - fg - f'g' + +mul_Fp12: + %load_fp6(6) + %load_fp6(18) + %dup2_fp6 + %dup2_fp6 + // stack: g', f', g', f' + %mul_fp6 + %dup1_fp6 + // stack: g'f', g'f', g', f' + %store_fp6_sh(36) + %store_fp6(42) + // stack: g', f' + %load_fp6(12) + // stack: g , g', f' + %swap_fp6 + // stack: g', g , f' + %dup2_fp6 + // stack: g , g', g , f' + %add_fp6 + %swap_fp6 + // stack: g + g', g , f' + %swap_fp6 + // stack: g , g + g', f' + %load_fp6(0) + // stack: f, g , g'+ g , f' + %mul_fp6 + %store_fp6(48) + // stack: g'+ g , f' + %swap_fp6 + %load_fp6(0) + %add_fp6 + // stack: f'+ f, g'+ g + %mul_fp6 + // stack: (f+f')(g+g') + %load_fp6(42) + %bus_fp6(42) + // stack: (f+f')(g+g') - f'g' + %load_fp6(48) + %swap_fp6 + // stack: (f+f')(g+g') - f'g' , fg + %dup2_fp6 + %bus_fp6 + // stack: (f+f')(g+g') - f'g' - fg, fg + %store_fp6(30) + // stack: fg + %load_fp6(36) + // stack: sh(f'g') , fg + %add_fp6 + // stack: sh(f'g') + fg + %store_fp6(24) + JUMP diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index 41d854c7..0d67b38f 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -1,4 +1,165 @@ -Fp6: +// cost: 6 loads + 6 offsets + 5 adds = 6*4 + 6*1 + 5*2 = 40 +%macro load_fp6(offset) + // stack: + PUSH $offset + %add_const(5) + %mload_kernel_general + // stack: x5 + PUSH $offset + %add_const(4) + %mload_kernel_general + // stack: x4, x5 + PUSH $offset + %add_const(3) + %mload_kernel_general + // stack: x3, x4, x5 + PUSH $offset + %add_const(2) + %mload_kernel_general + // stack: x2, x3, x4, x5 + PUSH $offset + %add_const(1) + %mload_kernel_general + // stack: x1, x2, x3, x4, x5 + PUSH $offset + %mload_kernel_general + // stack: x0, x1, x2, x3, x4, x5 +%endmacro + +// cost: 40 +%macro store_fp6(offset) + // stack: x0, x1, x2, x3, x4, x5 + PUSH $offset + %mstore_kernel_general + // stack: x1, x2, x3, x4, x5 + PUSH $offset + %add_const(1) + %mstore_kernel_general + // stack: x2, x3, x4, x5 + PUSH $offset + %add_const(2) + %mstore_kernel_general + // stack: x3, x4, x5 + PUSH $offset + %add_const(3) + %mstore_kernel_general + // stack: x4, x5 + PUSH $offset + %add_const(4) + %mstore_kernel_general + // stack: x5 + PUSH $offset + %add_const(5) + %mstore_kernel_general + // stack: +%endmacro + +// cost: 6 +%macro dup1_fp6 + // stack: F: 6 + DUP6 + DUP6 + DUP6 + DUP6 + DUP6 + DUP6 + // stack: F: 6, F: 6 +%endmacro + +// cost: 6 +%macro dup2_fp6 + // stack: F: 6, G: 6 + DUP12 + DUP12 + DUP12 + DUP12 + DUP12 + DUP12 + // stack: G: 6, F: 6, G: 6 +%endmacro + +// cost: 16 +%macro swap_fp6 + // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 + SWAP6 + // stack: g0, f1, f2, f3, f4, f5, f0, g1, g2, g3, g4, g5 + SWAP1 + SWAP7 + SWAP1 + // stack: g0, g1, f2, f3, f4, f5, f0, f1, g2, g3, g4, g5 + SWAP2 + SWAP8 + SWAP2 + // stack: g0, g1, g2, f3, f4, f5, f0, f1, f2, g3, g4, g5 + SWAP3 + SWAP9 + SWAP3 + // stack: g0, g1, g2, g3, f4, f5, f0, f1, f2, f3, g4, g5 + SWAP4 + SWAP10 + SWAP4 + // stack: g0, g1, g2, g3, g4, f5, f0, f1, f2, f3, f4, g5 + SWAP5 + SWAP11 + SWAP5 + // stack: g0, g1, g2, g3, g4, g5, f0, f1, f2, f3, f4, f5 +%endmacro + +// cost: 16 +%macro add_fp6 + // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 + SWAP7 + ADD + SWAP6 + // stack: f0, f2, f3, f4, f5, g0, h1, g2, g3, g4, g5 + SWAP7 + ADD + SWAP6 + // stack: f0, f3, f4, f5, g0, h1, h2, g3, g4, g5 + SWAP7 + ADD + SWAP6 + // stack: f0, f4, f5, g0, h1, h2, h3, g4, g5 + SWAP7 + ADD + SWAP6 + // stack: f0, f5, g0, h1, h2, h3, h4, g5 + SWAP7 + ADD + SWAP6 + // stack: f0, g0, h1, h2, h3, h4, h5 + ADD + // stack: h0, h1, h2, h3, h4, h5 +%endmacro + +// *backwards order subtraction* cost: 16 +%macro bus_fp6 + // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 + SWAP7 + SUB + SWAP6 + // stack: f0, f2, f3, f4, f5, g0, h1, g2, g3, g4, g5 + SWAP7 + SUB + SWAP6 + // stack: f0, f3, f4, f5, g0, h1, h2, g3, g4, g5 + SWAP7 + SUB + SWAP6 + // stack: f0, f4, f5, g0, h1, h2, h3, g4, g5 + SWAP7 + SUB + SWAP6 + // stack: f0, f5, g0, h1, h2, h3, h4, g5 + SWAP7 + SUB + SWAP6 + // stack: f0, g0, h1, h2, h3, h4, h5 + SUB + // stack: h0, h1, h2, h3, h4, h5 +%endmacro + +%macro mul_Fp6 DUP3 DUP11 MUL @@ -151,4 +312,5 @@ Fp6: SWAP2 MUL ADD - %mstore_kernel_general(5) \ No newline at end of file + %mstore_kernel_general(5) +%endmacro From 7b1db488463b204a970a6b57e002c100311f486a Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 7 Oct 2022 18:13:32 -0700 Subject: [PATCH 03/58] Fp6 mult purely on stack --- evm/src/cpu/kernel/asm/fields/Fp6.asm | 237 ++++++++++++++++---------- evm/src/cpu/kernel/interpreter.rs | 27 ++- 2 files changed, 168 insertions(+), 96 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index 0d67b38f..e97cf653 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -54,6 +54,36 @@ // stack: %endmacro +// cost: 49 +%macro store_fp6_sh(offset) + // stack: x0, x1, x2, x3, x4, x5 + PUSH $offset + %add_const(2) + %mstore_kernel_general + // stack: x1, x2, x3, x4, x5 + PUSH $offset + %add_const(3) + %mstore_kernel_general + // stack: x2, x3, x4, x5 + PUSH $offset + %add_const(4) + %mstore_kernel_general + // stack: x3, x4, x5 + PUSH $offset + %add_const(5) + %mstore_kernel_general + // stack: x4, x5 + %i9 + // stack: y5, y4 + PUSH $offset + %add_const(1) + %mstore_kernel_general + // stack: y4 + PUSH $offset + %mstore_kernel_general + // stack: +%endmacro + // cost: 6 %macro dup1_fp6 // stack: F: 6 @@ -160,142 +190,147 @@ %endmacro %macro mul_Fp6 - DUP3 - DUP11 - MUL - DUP2 - DUP14 - MUL - SUB - DUP12 - DUP8 - MUL - DUP9 - DUP5 - MUL - ADD - DUP7 - DUP7 - MUL - DUP12 - DUP12 - MUL - ADD - SUB - DUP7 - DUP5 - MUL - DUP10 - DUP8 - MUL - ADD - DUP12 - DUP10 - MUL - ADD - DUP14 - DUP12 - MUL - ADD - DUP15 - DUP7 - MUL - DUP14 DUP6 - MUL - ADD - DUP2 - DUP4 - PUSH 9 - MUL - SUB - ADD - %mstore_kernel_general(0) - PUSH 9 - MUL - ADD - ADD - %mstore_kernel_general(1) - DUP4 DUP12 MUL + DUP5 + DUP5 + MUL + SUB DUP3 - DUP11 + DUP10 + MUL + DUP14 + DUP8 MUL ADD - DUP3 + DUP11 + DUP10 + MUL DUP13 - MUL - DUP6 - DUP12 - MUL - SUB - DUP12 - DUP10 - MUL - DUP9 - DUP7 + DUP5 MUL ADD - DUP2 - DUP4 - PUSH 9 + SUB + DUP11 + DUP8 + MUL + DUP15 + DUP11 + MUL + ADD + DUP13 + DUP12 + MUL + ADD + DUP5 + DUP5 + MUL + ADD + DUP6 + DUP10 MUL - SUB - SUB DUP15 DUP9 MUL - DUP12 - DUP6 + ADD + DUP2 + DUP4 + PUSH 9 MUL + SUB ADD - ADD - %mstore_kernel_general(2) + SWAP15 + SWAP3 + SWAP2 + SWAP1 PUSH 9 MUL ADD - DUP13 + ADD + SWAP9 DUP9 + DUP5 MUL - DUP12 DUP8 + DUP14 MUL ADD - DUP10 + DUP8 DUP6 MUL + DUP11 + DUP15 + MUL + SUB + DUP15 + DUP5 + MUL + DUP4 + DUP12 + MUL ADD + DUP2 + DUP4 + PUSH 9 + MUL + SUB + SUB DUP8 + DUP15 + MUL + DUP7 + DUP11 + MUL + ADD + ADD + SWAP13 + SWAP2 + SWAP1 + PUSH 9 + MUL + ADD + DUP7 + DUP5 + MUL + DUP16 DUP4 MUL ADD + DUP6 + DUP12 + MUL + ADD + DUP4 + DUP10 + MUL + ADD + ADD + SWAP13 + DUP15 + DUP7 + MUL + DUP4 + DUP6 + MUL ADD - %mstore_kernel_general(3) DUP10 DUP12 MUL - DUP7 - DUP9 - MUL ADD + DUP8 DUP3 + MUL + DUP7 DUP5 MUL ADD DUP13 DUP11 MUL - DUP10 - DUP8 - MUL - ADD - DUP6 - DUP4 - MUL ADD SUB - %mstore_kernel_general(4) + SWAP15 MUL SWAP2 MUL @@ -312,5 +347,21 @@ SWAP2 MUL ADD - %mstore_kernel_general(5) + SWAP5 +%endmacro + +// cost: 9; note this returns y, x for x + yi +%macro i9 + // stack: a , b + DUP2 + DUP2 + // stack: a , b, a , b + %mul_const(9) + SUB + // stack: 9a - b, a , b + SWAP2 + // stack: b , a, 9a - b + %mul_const(9) + ADD + // stack: 9b + a, 9a - b %endmacro diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 589ba6b3..ad517931 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -214,9 +214,12 @@ impl<'a> Interpreter<'a> { self.incr(1); match opcode { 0x00 => self.run_stop(), // "STOP", - 0x01 => self.run_add(), // "ADD", - 0x02 => self.run_mul(), // "MUL", - 0x03 => self.run_sub(), // "SUB", + // 0x01 => self.run_add(), // "ADD", + // 0x02 => self.run_mul(), // "MUL", + // 0x03 => self.run_sub(), // "SUB", + 0x01 => self.run_add_p(), // "ADD", + 0x02 => self.run_mul_p(), // "MUL", + 0x03 => self.run_sub_p(), // "SUB", 0x04 => self.run_div(), // "DIV", 0x05 => todo!(), // "SDIV", 0x06 => self.run_mod(), // "MOD", @@ -322,18 +325,36 @@ impl<'a> Interpreter<'a> { self.push(x.overflowing_add(y).0); } + fn run_add_p(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(U256::try_from((x + y) % 101).unwrap()); + } + fn run_mul(&mut self) { let x = self.pop(); let y = self.pop(); self.push(x.overflowing_mul(y).0); } + fn run_mul_p(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(U256::try_from(x.full_mul(y) % 101).unwrap()); + } + fn run_sub(&mut self) { let x = self.pop(); let y = self.pop(); self.push(x.overflowing_sub(y).0); } + fn run_sub_p(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(U256::try_from((x - y) % 101).unwrap()); + } + fn run_div(&mut self) { let x = self.pop(); let y = self.pop(); From f83504b16e6af069b551abf5b5e7221dd0b1dc63 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 7 Oct 2022 18:19:46 -0700 Subject: [PATCH 04/58] separate module + stack comments --- evm/src/cpu/kernel/asm/fields/Fp6.asm | 161 ----------- evm/src/cpu/kernel/asm/fields/Fp6_mul.asm | 318 ++++++++++++++++++++++ 2 files changed, 318 insertions(+), 161 deletions(-) create mode 100644 evm/src/cpu/kernel/asm/fields/Fp6_mul.asm diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index e97cf653..d83ef0f3 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -189,167 +189,6 @@ // stack: h0, h1, h2, h3, h4, h5 %endmacro -%macro mul_Fp6 - DUP6 - DUP12 - MUL - DUP5 - DUP5 - MUL - SUB - DUP3 - DUP10 - MUL - DUP14 - DUP8 - MUL - ADD - DUP11 - DUP10 - MUL - DUP13 - DUP5 - MUL - ADD - SUB - DUP11 - DUP8 - MUL - DUP15 - DUP11 - MUL - ADD - DUP13 - DUP12 - MUL - ADD - DUP5 - DUP5 - MUL - ADD - DUP6 - DUP10 - MUL - DUP15 - DUP9 - MUL - ADD - DUP2 - DUP4 - PUSH 9 - MUL - SUB - ADD - SWAP15 - SWAP3 - SWAP2 - SWAP1 - PUSH 9 - MUL - ADD - ADD - SWAP9 - DUP9 - DUP5 - MUL - DUP8 - DUP14 - MUL - ADD - DUP8 - DUP6 - MUL - DUP11 - DUP15 - MUL - SUB - DUP15 - DUP5 - MUL - DUP4 - DUP12 - MUL - ADD - DUP2 - DUP4 - PUSH 9 - MUL - SUB - SUB - DUP8 - DUP15 - MUL - DUP7 - DUP11 - MUL - ADD - ADD - SWAP13 - SWAP2 - SWAP1 - PUSH 9 - MUL - ADD - DUP7 - DUP5 - MUL - DUP16 - DUP4 - MUL - ADD - DUP6 - DUP12 - MUL - ADD - DUP4 - DUP10 - MUL - ADD - ADD - SWAP13 - DUP15 - DUP7 - MUL - DUP4 - DUP6 - MUL - ADD - DUP10 - DUP12 - MUL - ADD - DUP8 - DUP3 - MUL - DUP7 - DUP5 - MUL - ADD - DUP13 - DUP11 - MUL - ADD - SUB - SWAP15 - MUL - SWAP2 - MUL - ADD - SWAP2 - MUL - ADD - SWAP2 - MUL - ADD - SWAP2 - MUL - ADD - SWAP2 - MUL - ADD - SWAP5 -%endmacro - // cost: 9; note this returns y, x for x + yi %macro i9 // stack: a , b diff --git a/evm/src/cpu/kernel/asm/fields/Fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/Fp6_mul.asm new file mode 100644 index 00000000..6bfbdd41 --- /dev/null +++ b/evm/src/cpu/kernel/asm/fields/Fp6_mul.asm @@ -0,0 +1,318 @@ +%macro mul_Fp6 + DUP6 + // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP12 + // stack: d0_, c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP5 + // stack: c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP5 + // stack: d0, c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d0c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + SUB + // stack: d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP3 + // stack: c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP10 + // stack: d1_, c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP14 + // stack: c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP8 + // stack: d2_, c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d2_c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP11 + // stack: c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP10 + // stack: d2, c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP13 + // stack: c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP5 + // stack: d1, c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d1c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: d1c2 + d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + SUB + // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP11 + // stack: c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP8 + // stack: d2_, c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP15 + // stack: c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP11 + // stack: d2, c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d2c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP13 + // stack: c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP12 + // stack: d1_, c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d1_c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP5 + // stack: c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP5 + // stack: d1, c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: d1c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP6 + // stack: d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP10 + // stack: c0_, d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP15 + // stack: d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP9 + // stack: c0, d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: c0d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP2 + // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + DUP4 + // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + PUSH 9 + // stack: 9, d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + MUL + // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + SUB + // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + ADD + // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + SWAP15 + // stack: c1_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP3 + // stack: d0c0 - d0_c0_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP1 + // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + PUSH 9 + // stack: 9, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP9 + // stack: d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP9 + // stack: d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP5 + // stack: c2_, d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP8 + // stack: d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP14 + // stack: c2, d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP8 + // stack: d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP6 + // stack: c2_, d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP11 + // stack: d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP15 + // stack: c2, d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SUB + // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP15 + // stack: d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP5 + // stack: c1_, d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + // stack: d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP12 + // stack: c0_, d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0_d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP2 + // stack: c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + // stack: c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + PUSH 9 + // stack: 9, c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: 9c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SUB + // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SUB + // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP8 + // stack: d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP15 + // stack: c1, d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP7 + // stack: d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP11 + // stack: c0, d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0d1 + c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP13 + // stack: c1, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: c2d2_ + c2_d2, c2d2 - c2_d2_, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP1 + // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + PUSH 9 + // stack: 9, c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: 9c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP7 + // stack: d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP5 + // stack: c1_, d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP16 + // stack: d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + // stack: c1, d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP6 + // stack: d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP12 + // stack: c0_, d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0_d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + // stack: d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP10 + // stack: c0, d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP13 + // stack: c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP15 + // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP7 + // stack: c2_, d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + // stack: d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP6 + // stack: c1_, d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1_d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP10 + // stack: d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP12 + // stack: c0_, d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0_d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP8 + // stack: d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP3 + // stack: c2, d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP7 + // stack: d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP5 + // stack: c1, d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c1d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP13 + // stack: d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP11 + // stack: c0, d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: c0d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SUB + // stack: c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP15 + // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d0_c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d1_, c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d1_c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: d1_c1 + d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d1, c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d1c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: d1c1_ + d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d0, c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d0c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: d0c2_ + d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d2_, c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d2_c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP2 + // stack: d2, c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + MUL + // stack: d2c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADD + // stack: d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP5 + // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2 +%endmacro From d1bad81985c3172c4528f3fd2c76f0a4ff641bbd Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 12 Oct 2022 10:06:34 -0400 Subject: [PATCH 05/58] stuff --- evm/src/cpu/kernel/aggregator.rs | 1 + .../asm/fields/{Fp6_mul.asm => fp6mul.asm} | 6 +++-- evm/src/cpu/kernel/tests/fields.rs | 22 +++++++++++++++++++ evm/src/cpu/kernel/tests/mod.rs | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) rename evm/src/cpu/kernel/asm/fields/{Fp6_mul.asm => fp6mul.asm} (99%) create mode 100644 evm/src/cpu/kernel/tests/fields.rs diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 0d94c86f..73479745 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -33,6 +33,7 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), include_str!("asm/halt.asm"), + include_str!("asm/fields/fp6mul.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), include_str!("asm/memory/memcpy.asm"), diff --git a/evm/src/cpu/kernel/asm/fields/Fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm similarity index 99% rename from evm/src/cpu/kernel/asm/fields/Fp6_mul.asm rename to evm/src/cpu/kernel/asm/fields/fp6mul.asm index 6bfbdd41..e994fdcf 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,4 +1,5 @@ -%macro mul_Fp6 +mul_Fp6: + DUP6 // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP12 @@ -315,4 +316,5 @@ // stack: d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP5 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2 -%endmacro + + %jump(0xdeadbeef) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs new file mode 100644 index 00000000..17a59731 --- /dev/null +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -0,0 +1,22 @@ +use anyhow::Result; +use ethereum_types::U256; + +use crate::cpu::kernel::aggregator::combined_kernel; +use crate::cpu::kernel::interpreter::run_with_kernel; + + +#[test] +fn test_field() -> Result<()> { + + let kernel = combined_kernel(); + let initial_offset = kernel.global_labels["mul_Fp6"]; + let initial_stack: Vec = vec![0, 0, 3, 1, 0, 1, 0, 1, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).collect(); + let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + .stack() + .to_vec(); + + let expected: Vec = vec![2, 12, -1, 1, 3, 0].iter().map(|&x| U256::from(x as u32)).collect(); + assert_eq!(final_stack, expected); + + Ok(()) +} diff --git a/evm/src/cpu/kernel/tests/mod.rs b/evm/src/cpu/kernel/tests/mod.rs index 9148d6a4..c73fb1ba 100644 --- a/evm/src/cpu/kernel/tests/mod.rs +++ b/evm/src/cpu/kernel/tests/mod.rs @@ -3,6 +3,7 @@ mod curve_ops; mod ecrecover; mod exp; mod hash; +mod fields; mod mpt; mod packing; mod ripemd; From d3e2b982eea35b97409c2378b0d14b63c62baa04 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 13 Oct 2022 17:28:17 -0400 Subject: [PATCH 06/58] new op codes --- evm/src/cpu/kernel/asm/fields/fp6mul.asm | 150 +++++++++++------------ evm/src/cpu/kernel/interpreter.rs | 15 +-- 2 files changed, 80 insertions(+), 85 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index e994fdcf..46e71a2f 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,92 +1,91 @@ mul_Fp6: - DUP6 // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP12 // stack: d0_, c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP5 // stack: c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP5 // stack: d0, c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d0c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUB + SUBFP254 // stack: d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP3 // stack: c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP10 // stack: d1_, c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP14 // stack: c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP8 // stack: d2_, c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d2_c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP11 // stack: c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP10 // stack: d2, c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP13 // stack: c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP5 // stack: d1, c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d1c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: d1c2 + d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUB + SUBFP254 // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP11 // stack: c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP8 // stack: d2_, c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP15 // stack: c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP11 // stack: d2, c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d2c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP13 // stack: c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP12 // stack: d1_, c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d1_c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP5 // stack: c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP5 // stack: d1, c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: d1c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP6 // stack: d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP10 // stack: c0_, d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP15 // stack: d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP9 // stack: c0, d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: c0d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP2 // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ @@ -94,11 +93,11 @@ mul_Fp6: // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ PUSH 9 // stack: 9, d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MUL + MULFP254 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUB + SUBFP254 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADD + ADDFP254 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ SWAP15 // stack: c1_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 @@ -110,11 +109,11 @@ mul_Fp6: // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 PUSH 9 // stack: 9, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP9 // stack: d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 @@ -122,43 +121,43 @@ mul_Fp6: // stack: d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP5 // stack: c2_, d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 // stack: d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP14 // stack: c2, d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 // stack: d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP6 // stack: c2_, d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP11 // stack: d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP15 // stack: c2, d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUB + SUBFP254 // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP15 // stack: d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP5 // stack: c1_, d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP4 // stack: d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP12 // stack: c0_, d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0_d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP2 // stack: c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 @@ -166,27 +165,27 @@ mul_Fp6: // stack: c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 PUSH 9 // stack: 9, c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: 9c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUB + SUBFP254 // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUB + SUBFP254 // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 // stack: d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP15 // stack: c1, d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP7 // stack: d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP11 // stack: c0, d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0d1 + c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP13 // stack: c1, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 @@ -196,41 +195,41 @@ mul_Fp6: // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 PUSH 9 // stack: 9, c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: 9c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP7 // stack: d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP5 // stack: c1_, d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP16 // stack: d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP4 // stack: c1, d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP6 // stack: d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP12 // stack: c0_, d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0_d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP4 // stack: d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP10 // stack: c0, d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP13 // stack: c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 @@ -238,83 +237,82 @@ mul_Fp6: // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP7 // stack: c2_, d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP4 // stack: d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP6 // stack: c1_, d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1_d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP10 // stack: d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP12 // stack: c0_, d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0_d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 // stack: d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP3 // stack: c2, d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP7 // stack: d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP5 // stack: c1, d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c1d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP13 // stack: d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP11 // stack: c0, d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: c0d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUB + SUBFP254 // stack: c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP15 // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d0_c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 // stack: d1_, c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d1_c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: d1_c1 + d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 // stack: d1, c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d1c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: d1c1_ + d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 // stack: d0, c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d0c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: d0c2_ + d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 // stack: d2_, c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d2_c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 // stack: d2, c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MUL + MULFP254 // stack: d2c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADD + ADDFP254 // stack: d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP5 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2 - %jump(0xdeadbeef) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 7c9cc841..8464160e 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -227,12 +227,9 @@ impl<'a> Interpreter<'a> { self.incr(1); match opcode { 0x00 => self.run_stop(), // "STOP", - // 0x01 => self.run_add(), // "ADD", - // 0x02 => self.run_mul(), // "MUL", - // 0x03 => self.run_sub(), // "SUB", - 0x01 => self.run_add_p(), // "ADD", - 0x02 => self.run_mul_p(), // "MUL", - 0x03 => self.run_sub_p(), // "SUB", + 0x01 => self.run_add(), // "ADD", + 0x02 => self.run_mul(), // "MUL", + 0x03 => self.run_sub(), // "SUB", 0x04 => self.run_div(), // "DIV", 0x05 => todo!(), // "SDIV", 0x06 => self.run_mod(), // "MOD", @@ -241,9 +238,9 @@ impl<'a> Interpreter<'a> { 0x09 => self.run_mulmod(), // "MULMOD", 0x0a => self.run_exp(), // "EXP", 0x0b => todo!(), // "SIGNEXTEND", - 0x0c => todo!(), // "ADDFP254", - 0x0d => todo!(), // "MULFP254", - 0x0e => todo!(), // "SUBFP254", + 0x0c => self.run_add_p(), // "ADDFP254", + 0x0d => self.run_mul_p(), // "MULFP254", + 0x0e => self.run_sub_p(), // "SUBFP254", 0x10 => self.run_lt(), // "LT", 0x11 => self.run_gt(), // "GT", 0x12 => todo!(), // "SLT", From fc2ea6281d38a00f8718cf1bb887317567d4fbc5 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 13 Oct 2022 18:09:27 -0400 Subject: [PATCH 07/58] Fp6 mul test passes --- evm/src/cpu/kernel/asm/fields/fp6mul.asm | 5 +++-- evm/src/cpu/kernel/interpreter.rs | 2 +- evm/src/cpu/kernel/tests/fields.rs | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index 46e71a2f..5eef91ba 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,4 +1,5 @@ -mul_Fp6: +global mul_Fp6: + // stack: d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP6 // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP12 @@ -99,7 +100,7 @@ mul_Fp6: // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ ADDFP254 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SWAP15 + SWAP15 // stack: c1_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP3 // stack: d0c0 - d0_c0_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 8464160e..cb335be7 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -380,7 +380,7 @@ impl<'a> Interpreter<'a> { fn run_sub_p(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(U256::try_from((x - y) % 101).unwrap()); + self.push(U256::try_from((U256::from(101) + x - y) % 101).unwrap()); } fn run_div(&mut self) { diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 17a59731..bc644e24 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -10,12 +10,12 @@ fn test_field() -> Result<()> { let kernel = combined_kernel(); let initial_offset = kernel.global_labels["mul_Fp6"]; - let initial_stack: Vec = vec![0, 0, 3, 1, 0, 1, 0, 1, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).collect(); + let initial_stack: Vec = vec![0, 0, 3, 1, 0, 1, 0, 1, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); - let expected: Vec = vec![2, 12, -1, 1, 3, 0].iter().map(|&x| U256::from(x as u32)).collect(); + let expected: Vec = vec![2, 12, 100, 1, 3, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); assert_eq!(final_stack, expected); Ok(()) From adc8c33b0db736266a45194a048a8360b2aaa40b Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 13 Oct 2022 20:06:19 -0400 Subject: [PATCH 08/58] Fp12 --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 12 ++++++++-- evm/src/cpu/kernel/asm/fields/fp6mul.asm | 28 ++++++++++++++++++++++-- evm/src/cpu/kernel/tests/fields.rs | 4 ++-- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index 400676de..a872739b 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -5,8 +5,15 @@ /// /// h = fg + sh(f'g') /// h' = (f+f')(g+g') - fg - f'g' +/// +/// Note: each symbol in the stack comments takes up six words -mul_Fp12: +global mul_Fp12: + +pre_mul: + + +calc: %load_fp6(6) %load_fp6(18) %dup2_fp6 @@ -56,4 +63,5 @@ mul_Fp12: %add_fp6 // stack: sh(f'g') + fg %store_fp6(24) - JUMP + + %jump(0xdeadbeef) diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index 5eef91ba..39d06c86 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,4 +1,28 @@ -global mul_Fp6: +macro mul_Fp6 + // stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ + SWAP3 + // stack: c1_, c0_, c1, c0, c2, c2_, d0, d0_, d1, d1_, d2, d2_ + SWAP11 + // stack: d2_, c0_, c1, c0, c2, c2_, d0, d0_, d1, d1_, d2, c1_ + SWAP4 + // stack: c2, c0_, c1, c0, d2_, c2_, d0, d0_, d1, d1_, d2, c1_ + SWAP9 + // stack: d1_, c0_, c1, c0, d2_, c2_, d0, d0_, d1, c2, d2, c1_ + SWAP7 + // stack: d0_, c0_, c1, c0, d2_, c2_, d0, d1_, d1, c2, d2, c1_ + SWAP10 + // stack: d2, c0_, c1, c0, d2_, c2_, d0, d1_, d1, c2, d0_, c1_ + SWAP6 + // stack: d0, c0_, c1, c0, d2_, c2_, d2, d1_, d1, c2, d0_, c1_ + SWAP2 + // stack: c1, c0_, d0, c0, d2_, c2_, d2, d1_, d1, c2, d0_, c1_ + SWAP8 + // stack: d1, c0_, d0, c0, d2_, c2_, d2, d1_, c1, c2, d0_, c1_ + SWAP1 + // stack: c0_, d1, d0, c0, d2_, c2_, d2, d1_, c1, c2, d0_, c1_ + SWAP5 + // stack: c2_, d1, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ + SWAP1 // stack: d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP6 // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ @@ -316,4 +340,4 @@ global mul_Fp6: // stack: d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP5 // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2 - %jump(0xdeadbeef) +%endmacro diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index bc644e24..c21a273e 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -9,8 +9,8 @@ use crate::cpu::kernel::interpreter::run_with_kernel; fn test_field() -> Result<()> { let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["mul_Fp6"]; - let initial_stack: Vec = vec![0, 0, 3, 1, 0, 1, 0, 1, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); + let initial_offset = kernel.global_labels["mul_Fp12"]; + let initial_stack: Vec = vec![1, 1, 0, 0, 1, 0, 3, 0, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); From 3cff0928c4df6a29e975e6bc98642c012be407a3 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Mon, 17 Oct 2022 11:02:24 -0400 Subject: [PATCH 09/58] better test API --- evm/src/cpu/kernel/aggregator.rs | 2 ++ evm/src/cpu/kernel/asm/fields/Fp12.asm | 27 ++++++++++++++++------- evm/src/cpu/kernel/asm/fields/Fp6.asm | 28 ++++++++++++------------ evm/src/cpu/kernel/asm/fields/fp6mul.asm | 2 +- evm/src/cpu/kernel/interpreter.rs | 2 +- evm/src/cpu/kernel/tests/fields.rs | 20 ++++++++++++----- evm/src/cpu/kernel/tests/mod.rs | 2 +- 7 files changed, 52 insertions(+), 31 deletions(-) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index ab18f330..15b11cd6 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -33,7 +33,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), include_str!("asm/halt.asm"), + include_str!("asm/fields/fp6.asm"), include_str!("asm/fields/fp6mul.asm"), + include_str!("asm/fields/fp12.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), include_str!("asm/memory/memcpy.asm"), diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index a872739b..d55a98b2 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -8,12 +8,24 @@ /// /// Note: each symbol in the stack comments takes up six words +global test_mul_Fp12: + // stack: f, f', g, g' + %store_fp6(0) + %store_fp6(6) + %store_fp6(12) + %store_fp6(18) + PUSH return_on_stack + // stack: return_on_stack + %jump(mul_Fp12) +return_on_stack: + // stack: + %load_fp6(24) + %load_fp6(30) + // stack: h, h' + %jump(0xdeadbeef) + + global mul_Fp12: - -pre_mul: - - -calc: %load_fp6(6) %load_fp6(18) %dup2_fp6 @@ -48,7 +60,7 @@ calc: %mul_fp6 // stack: (f+f')(g+g') %load_fp6(42) - %bus_fp6(42) + %bus_fp6 // stack: (f+f')(g+g') - f'g' %load_fp6(48) %swap_fp6 @@ -63,5 +75,4 @@ calc: %add_fp6 // stack: sh(f'g') + fg %store_fp6(24) - - %jump(0xdeadbeef) + JUMP diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index d83ef0f3..70166e6c 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -139,26 +139,26 @@ %macro add_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 SWAP7 - ADD + ADDFP254 SWAP6 // stack: f0, f2, f3, f4, f5, g0, h1, g2, g3, g4, g5 SWAP7 - ADD + ADDFP254 SWAP6 // stack: f0, f3, f4, f5, g0, h1, h2, g3, g4, g5 SWAP7 - ADD + ADDFP254 SWAP6 // stack: f0, f4, f5, g0, h1, h2, h3, g4, g5 SWAP7 - ADD + ADDFP254 SWAP6 // stack: f0, f5, g0, h1, h2, h3, h4, g5 SWAP7 - ADD + ADDFP254 SWAP6 // stack: f0, g0, h1, h2, h3, h4, h5 - ADD + ADDFP254 // stack: h0, h1, h2, h3, h4, h5 %endmacro @@ -166,26 +166,26 @@ %macro bus_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 SWAP7 - SUB + SUBFP254 SWAP6 // stack: f0, f2, f3, f4, f5, g0, h1, g2, g3, g4, g5 SWAP7 - SUB + SUBFP254 SWAP6 // stack: f0, f3, f4, f5, g0, h1, h2, g3, g4, g5 SWAP7 - SUB + SUBFP254 SWAP6 // stack: f0, f4, f5, g0, h1, h2, h3, g4, g5 SWAP7 - SUB + SUBFP254 SWAP6 // stack: f0, f5, g0, h1, h2, h3, h4, g5 SWAP7 - SUB + SUBFP254 SWAP6 // stack: f0, g0, h1, h2, h3, h4, h5 - SUB + SUBFP254 // stack: h0, h1, h2, h3, h4, h5 %endmacro @@ -196,11 +196,11 @@ DUP2 // stack: a , b, a , b %mul_const(9) - SUB + SUBFP254 // stack: 9a - b, a , b SWAP2 // stack: b , a, 9a - b %mul_const(9) - ADD + ADDFP254 // stack: 9b + a, 9a - b %endmacro diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index 39d06c86..a7c10489 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,4 +1,4 @@ -macro mul_Fp6 +%macro mul_fp6 // stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ SWAP3 // stack: c1_, c0_, c1, c0, c2, c2_, d0, d0_, d1, d1_, d2, d2_ diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index cb335be7..0fd6464f 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -370,7 +370,7 @@ impl<'a> Interpreter<'a> { let y = self.pop(); self.push(U256::try_from(x.full_mul(y) % 101).unwrap()); } - + fn run_sub(&mut self) { let x = self.pop(); let y = self.pop(); diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index c21a273e..1c8a2243 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -4,19 +4,27 @@ use ethereum_types::U256; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; - #[test] fn test_field() -> Result<()> { - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["mul_Fp12"]; - let initial_stack: Vec = vec![1, 1, 0, 0, 1, 0, 3, 0, 0, 1, 0, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); + let initial_offset = kernel.global_labels["test_mul_Fp12"]; + let initial_stack: Vec = vec![ + 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, + ] + .iter() + .map(|&x| U256::from(x as u32)) + .rev() + .collect(); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); + let expected: Vec = vec![5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0] + .iter() + .map(|&x| U256::from(x as u32)) + .rev() + .collect(); - let expected: Vec = vec![2, 12, 100, 1, 3, 0].iter().map(|&x| U256::from(x as u32)).rev().collect(); assert_eq!(final_stack, expected); - + Ok(()) } diff --git a/evm/src/cpu/kernel/tests/mod.rs b/evm/src/cpu/kernel/tests/mod.rs index c73fb1ba..91f3f229 100644 --- a/evm/src/cpu/kernel/tests/mod.rs +++ b/evm/src/cpu/kernel/tests/mod.rs @@ -2,8 +2,8 @@ mod core; mod curve_ops; mod ecrecover; mod exp; -mod hash; mod fields; +mod hash; mod mpt; mod packing; mod ripemd; From a0f7e6619d8996af2fcb9e359d9de9d35845c92b Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Mon, 17 Oct 2022 14:57:32 -0400 Subject: [PATCH 10/58] fix fp6, better test function --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 9 +- evm/src/cpu/kernel/asm/fields/fp6mul.asm | 445 +++++++---------------- evm/src/cpu/kernel/tests/fields.rs | 47 ++- 3 files changed, 170 insertions(+), 331 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index d55a98b2..06211670 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -6,7 +6,12 @@ /// h = fg + sh(f'g') /// h' = (f+f')(g+g') - fg - f'g' /// -/// Note: each symbol in the stack comments takes up six words +/// Note: each symbol in the stack comments consists of six words + +global test_mul_Fp6: + %mul_fp6 + %jump(0xdeadbeef) + global test_mul_Fp12: // stack: f, f', g, g' @@ -44,8 +49,8 @@ global mul_Fp12: %dup2_fp6 // stack: g , g', g , f' %add_fp6 - %swap_fp6 // stack: g + g', g , f' + %jump(0xdeadbeef) %swap_fp6 // stack: g , g + g', f' %load_fp6(0) diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index a7c10489..2d4ddabb 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,343 +1,162 @@ +// cost: 159 %macro mul_fp6 - // stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ - SWAP3 - // stack: c1_, c0_, c1, c0, c2, c2_, d0, d0_, d1, d1_, d2, d2_ - SWAP11 - // stack: d2_, c0_, c1, c0, c2, c2_, d0, d0_, d1, d1_, d2, c1_ - SWAP4 - // stack: c2, c0_, c1, c0, d2_, c2_, d0, d0_, d1, d1_, d2, c1_ - SWAP9 - // stack: d1_, c0_, c1, c0, d2_, c2_, d0, d0_, d1, c2, d2, c1_ - SWAP7 - // stack: d0_, c0_, c1, c0, d2_, c2_, d0, d1_, d1, c2, d2, c1_ - SWAP10 - // stack: d2, c0_, c1, c0, d2_, c2_, d0, d1_, d1, c2, d0_, c1_ - SWAP6 - // stack: d0, c0_, c1, c0, d2_, c2_, d2, d1_, d1, c2, d0_, c1_ - SWAP2 - // stack: c1, c0_, d0, c0, d2_, c2_, d2, d1_, d1, c2, d0_, c1_ - SWAP8 - // stack: d1, c0_, d0, c0, d2_, c2_, d2, d1_, c1, c2, d0_, c1_ - SWAP1 - // stack: c0_, d1, d0, c0, d2_, c2_, d2, d1_, c1, c2, d0_, c1_ - SWAP5 - // stack: c2_, d1, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SWAP1 - // stack: d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP6 - // stack: c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP12 - // stack: d0_, c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP5 - // stack: c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP5 - // stack: d0, c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d0c0, d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUBFP254 - // stack: d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP3 - // stack: c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP10 - // stack: d1_, c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP14 - // stack: c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP8 - // stack: d2_, c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d2_c1_, d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP11 - // stack: c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP10 - // stack: d2, c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP13 - // stack: c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP5 - // stack: d1, c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d1c2, d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: d1c2 + d2c1, d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUBFP254 - // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP11 - // stack: c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP8 - // stack: d2_, c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP15 - // stack: c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP11 - // stack: d2, c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d2c1_, d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP13 - // stack: c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP12 - // stack: d1_, c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d1_c2, d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP5 - // stack: c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP5 - // stack: d1, c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: d1c2_, d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP6 - // stack: d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP10 - // stack: c0_, d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP15 - // stack: d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP9 - // stack: c0, d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - MULFP254 - // stack: c0d0_, c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ DUP2 - // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - DUP4 - // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - PUSH 9 - // stack: 9, d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ MULFP254 - // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SUBFP254 - // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1, c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - ADDFP254 - // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, c1_ - SWAP15 - // stack: c1_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP3 - // stack: d0c0 - d0_c0_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP2 - // stack: d1c2 + d2c1 - d2_c1_ + d1_c2_, d1c2_ + d1_c2 + d2c1_ + d2_c1, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP1 - // stack: d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - PUSH 9 - // stack: 9, d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1, d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_, d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, d1_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP9 - // stack: d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP9 - // stack: d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP5 - // stack: c2_, d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 - // stack: d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP4 + MULFP254 + ADDFP254 + DUP7 + DUP12 + MULFP254 + DUP6 + DUP15 + MULFP254 + ADDFP254 + DUP5 DUP14 - // stack: c2, d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 MULFP254 - // stack: c2d2_, c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP8 - // stack: d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP6 - // stack: c2_, d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP11 - // stack: d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP15 - // stack: c2, d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c2d2, c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUBFP254 - // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP15 - // stack: d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP5 - // stack: c1_, d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP4 - // stack: d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP12 - // stack: c0_, d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c0_d1_, c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP2 - // stack: c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP4 - // stack: c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - PUSH 9 - // stack: 9, c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: 9c2d2_ + c2_d2, c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUBFP254 - // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_, c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SUBFP254 - // stack: 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP8 - // stack: d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP15 - // stack: c1, d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP7 - // stack: d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP11 - // stack: c0, d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c0d1, c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0d1 + c1d0, 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c1, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP13 - // stack: c1, c2d2 - c2_d2_, c2d2_ + c2_d2, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP2 - // stack: c2d2_ + c2_d2, c2d2 - c2_d2_, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP1 - // stack: c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - PUSH 9 - // stack: 9, c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: 9c2d2 - c2_d2_, c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP7 - // stack: d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP5 - // stack: c1_, d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP16 - // stack: d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP4 - // stack: c1, d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1d0_, c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP6 - // stack: d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP12 - // stack: c0_, d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c0_d1, c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP4 - // stack: d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP10 - // stack: c0, d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c0d1_, c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0, 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - SWAP13 - // stack: c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP15 - // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP7 - // stack: c2_, d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP4 - // stack: d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP6 - // stack: c1_, d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1_d1_, c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP10 - // stack: d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP12 - // stack: c0_, d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c0_d2_, c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP8 - // stack: d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP3 - // stack: c2, d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP7 - // stack: d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP5 - // stack: c1, d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: c1d1, c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - ADDFP254 - // stack: c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 DUP13 - // stack: d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - DUP11 - // stack: c0, d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 MULFP254 - // stack: c0d2, c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SUBFP254 - // stack: c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP5 + DUP15 + MULFP254 + DUP7 + DUP15 + MULFP254 + ADDFP254 + DUP8 + DUP14 + MULFP254 + ADDFP254 + DUP9 + DUP13 + MULFP254 + ADDFP254 + DUP11 + DUP6 + MULFP254 + DUP11 + DUP6 + MULFP254 + SUBFP254 + DUP2 + DUP4 + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 SWAP15 - // stack: d0_, c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 - MULFP254 - // stack: d0_c2, c1, d1_, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP3 SWAP2 - // stack: d1_, c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP1 + PUSH 9 MULFP254 - // stack: d1_c1, d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: d1_c1 + d0_c2, c1_, d1, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADDFP254 + SWAP9 + DUP13 + DUP9 + MULFP254 + DUP3 + DUP9 + MULFP254 + ADDFP254 + DUP3 + DUP10 + MULFP254 + DUP15 + DUP10 + MULFP254 + SUBFP254 + DUP3 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP2 + DUP4 + PUSH 9 + MULFP254 + SUBFP254 + SUBFP254 + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + ADDFP254 + SWAP13 SWAP2 - // stack: d1, c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + SWAP1 + PUSH 9 MULFP254 - // stack: d1c1_, d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: d1c1_ + d1_c1 + d0_c2, c2_, d0, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + DUP11 + DUP9 + MULFP254 + DUP4 + DUP9 + MULFP254 + ADDFP254 + DUP3 + DUP8 + MULFP254 + ADDFP254 + DUP15 + DUP7 + MULFP254 + ADDFP254 + ADDFP254 + SWAP13 + DUP3 + DUP11 + MULFP254 + DUP2 + DUP10 + MULFP254 + ADDFP254 + DUP5 + DUP8 + MULFP254 + ADDFP254 + DUP16 + DUP7 + MULFP254 + DUP4 + DUP10 + MULFP254 + ADDFP254 + DUP13 + DUP12 + MULFP254 + ADDFP254 + SUBFP254 + SWAP15 + SWAP7 + MULFP254 + SWAP7 + MULFP254 + SWAP7 + MULFP254 SWAP2 - // stack: d0, c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 MULFP254 - // stack: d0c2_, d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: d0c2_ + d1c1_ + d1_c1 + d0_c2, c0, d2_, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP2 - // stack: d2_, c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 MULFP254 - // stack: d2_c0, d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, c0_, d2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 + ADDFP254 + ADDFP254 SWAP2 - // stack: d2, c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 MULFP254 - // stack: d2c0_, d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 ADDFP254 - // stack: d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0 SWAP5 - // stack: 9d1c2 + d2c1 - d2_c1_ + d1_c2_ - d1c2_ + d1_c2 + d2c1_ + d2_c1 + c0d0_ + c0_d0, 9d1c2_ + d1_c2 + d2c1_ + d2_c1 + d1c2 + d2c1 - d2_c1_ + d1_c2_ + d0c0 - d0_c0_, c0d1 + c1d0 + 9c2d2_ + c2_d2 - c2d2 - c2_d2_ - c0_d1_ + c1_d0_, c0d1_ + c0_d1 + c1d0_ + c1_d0 + 9c2d2 - c2_d2_ + c2d2_ + c2_d2, c0d2 + c1d1 + c2d0 - c0_d2_ + c1_d1_ + c2_d0_, d2c0_ + d2_c0 + d0c2_ + d1c1_ + d1_c1 + d0_c2 %endmacro diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 1c8a2243..eab41f8b 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -4,25 +4,40 @@ use ethereum_types::U256; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; -#[test] -fn test_field() -> Result<()> { - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["test_mul_Fp12"]; - let initial_stack: Vec = vec![ - 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, - ] - .iter() - .map(|&x| U256::from(x as u32)) - .rev() - .collect(); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? - .stack() - .to_vec(); - let expected: Vec = vec![5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0] +fn make_stack(xs: &[u32]) -> Vec { + Vec::from(xs) .iter() .map(|&x| U256::from(x as u32)) .rev() - .collect(); + .collect() +} + +#[test] +fn test_fp6() -> Result<()> { + let kernel = combined_kernel(); + let initial_offset = kernel.global_labels["test_mul_Fp6"]; + let initial_stack: Vec = make_stack(&[1, 1, 0, 0, 1, 0, 3, 0, 0, 1, 0, 0]); + let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + .stack() + .to_vec(); + let expected: Vec = make_stack(&[2, 12, 100, 1, 3, 0]); + + assert_eq!(final_stack, expected); + + Ok(()) +} + +#[test] +fn test_fp12() -> Result<()> { + let kernel = combined_kernel(); + let initial_offset = kernel.global_labels["test_mul_Fp12"]; + let initial_stack: Vec = make_stack(&[ + 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, + ]); + let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + .stack() + .to_vec(); + let expected: Vec = make_stack(&[5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0]); assert_eq!(final_stack, expected); From b534b221a096fd0b04b86a7b1897d0edf010c8f1 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Mon, 17 Oct 2022 15:58:56 -0400 Subject: [PATCH 11/58] fix fp6 subtraction---fp12 tests running! --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 12 ++++++------ evm/src/cpu/kernel/asm/fields/Fp6.asm | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index 06211670..9b3f603c 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -24,8 +24,8 @@ global test_mul_Fp12: %jump(mul_Fp12) return_on_stack: // stack: - %load_fp6(24) %load_fp6(30) + %load_fp6(24) // stack: h, h' %jump(0xdeadbeef) @@ -38,7 +38,7 @@ global mul_Fp12: // stack: g', f', g', f' %mul_fp6 %dup1_fp6 - // stack: g'f', g'f', g', f' + // stack: f'g', f'g', g', f' %store_fp6_sh(36) %store_fp6(42) // stack: g', f' @@ -50,21 +50,21 @@ global mul_Fp12: // stack: g , g', g , f' %add_fp6 // stack: g + g', g , f' - %jump(0xdeadbeef) %swap_fp6 // stack: g , g + g', f' %load_fp6(0) - // stack: f, g , g'+ g , f' + // stack: f, g , g + g', f' %mul_fp6 %store_fp6(48) - // stack: g'+ g , f' + // stack: g + g', f' %swap_fp6 %load_fp6(0) %add_fp6 - // stack: f'+ f, g'+ g + // stack: f+f', g+g' %mul_fp6 // stack: (f+f')(g+g') %load_fp6(42) + // stack: f'g', (f+f')(g+g') %bus_fp6 // stack: (f+f')(g+g') - f'g' %load_fp6(48) diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index 70166e6c..7ab2cf87 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -162,7 +162,7 @@ // stack: h0, h1, h2, h3, h4, h5 %endmacro -// *backwards order subtraction* cost: 16 +// *backwards order subtraction* cost: 17 %macro bus_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 SWAP7 @@ -185,6 +185,7 @@ SUBFP254 SWAP6 // stack: f0, g0, h1, h2, h3, h4, h5 + SWAP1 SUBFP254 // stack: h0, h1, h2, h3, h4, h5 %endmacro From d475ab9368d1117768b6b1fd919ba7bbc8b53ba1 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Mon, 17 Oct 2022 23:19:14 -0400 Subject: [PATCH 12/58] fp6 passes randomized tests --- evm/src/cpu/kernel/asm/fields/fp6mul.asm | 163 +++++++++++++++-------- evm/src/cpu/kernel/tests/fields.rs | 146 +++++++++++++++++--- 2 files changed, 235 insertions(+), 74 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm index 2d4ddabb..ea0cd77f 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6mul.asm @@ -1,64 +1,99 @@ -// cost: 159 +// cost: 156 %macro mul_fp6 - DUP8 - DUP2 - MULFP254 - DUP8 - DUP4 - MULFP254 - ADDFP254 - DUP7 + /// E0 = C0D0 + i9(C1D2 + C2D1) + /// + /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i + /// + /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i + /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i + /// + /// CDX = C1D2 + C2D1 + /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i + /// + /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i + /// + /// E0 = 9CDX - CDX_ + C0D0 + /// E0_ = 9CDX_ + CDX + C0D0_ + + // CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 DUP12 - MULFP254 - DUP6 - DUP15 - MULFP254 - ADDFP254 - DUP5 - DUP14 - MULFP254 - DUP8 - DUP13 - MULFP254 - ADDFP254 - SUBFP254 - DUP5 - DUP15 - MULFP254 - DUP7 - DUP15 - MULFP254 - ADDFP254 - DUP8 - DUP14 - MULFP254 - ADDFP254 - DUP9 - DUP13 - MULFP254 - ADDFP254 - DUP11 - DUP6 - MULFP254 - DUP11 - DUP6 - MULFP254 - SUBFP254 - DUP2 DUP4 + MULFP254 + DUP12 + DUP6 + MULFP254 + ADDFP254 + DUP11 + DUP7 + MULFP254 + ADDFP254 + DUP10 + DUP8 + MULFP254 + ADDFP254 + // C0D0_ = c0d0_ + c0_d0 + DUP9 + DUP3 + MULFP254 + DUP9 + DUP5 + MULFP254 + ADDFP254 + // CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP14 + DUP7 + MULFP254 + DUP13 + DUP10 + MULFP254 + ADDFP254 + SUBFP254 + // C0D0 = c0d0 - c0_d0_ + DUP11 + DUP6 + MULFP254 + DUP11 + DUP6 + MULFP254 + SUBFP254 + // stack: C0D0 , CDX , C0D0_, CDX_ + DUP4 + DUP3 + // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ PUSH 9 MULFP254 SUBFP254 ADDFP254 + // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ SWAP15 SWAP3 - SWAP2 - SWAP1 + // stack: CDX_ , CDX , C0D0_ PUSH 9 MULFP254 ADDFP254 ADDFP254 + // stack: 9CDX_ + CDX + C0D0_ SWAP9 + + /// E1 = C0D1 + C1D0 + i9(C2D2) + /// + /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i + /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i + /// + /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i + /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i + /// + /// E1 = 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_) + /// E1_ = C2D2 + 9C2D2_ + c0d1_ + c0_d1 + c1d0_ + c1_d0 + + // C2D2_ = c2d2_ + c2_d2 DUP13 DUP9 MULFP254 @@ -66,6 +101,7 @@ DUP9 MULFP254 ADDFP254 + // C2D2 = c2d2 - c2_d2_ DUP3 DUP10 MULFP254 @@ -73,6 +109,8 @@ DUP10 MULFP254 SUBFP254 + // stack: C2D2, C2D2_ + // c0d1 + c1d0 - (c0_d1_ + c1_d0_) DUP3 DUP9 MULFP254 @@ -80,12 +118,6 @@ DUP8 MULFP254 ADDFP254 - DUP2 - DUP4 - PUSH 9 - MULFP254 - SUBFP254 - SUBFP254 DUP12 DUP9 MULFP254 @@ -93,13 +125,24 @@ DUP8 MULFP254 ADDFP254 + SUBFP254 + // stack: c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + DUP3 + DUP3 + // stack: C2D2 , C2D2_ , c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + PUSH 9 + MULFP254 + SUBFP254 ADDFP254 + // stack: 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ SWAP13 SWAP2 - SWAP1 + // stack: C2D2_ , C2D2 PUSH 9 MULFP254 ADDFP254 + // stack: 9C2D2_ + C2D2 + // c0d1_ + c0_d1 + c1d0_ + c1_d0 DUP11 DUP9 MULFP254 @@ -117,6 +160,15 @@ ADDFP254 ADDFP254 SWAP13 + /// E2 = C0D2 + C1D1 + C2D0 + /// + /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i + /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i + /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i + /// + /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) + /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + // c0_d2_ + c1_d1_ + c2_d0_ DUP3 DUP11 MULFP254 @@ -128,6 +180,7 @@ DUP8 MULFP254 ADDFP254 + // c0d2 + c1d1 + c2d0 DUP16 DUP7 MULFP254 @@ -139,8 +192,10 @@ DUP12 MULFP254 ADDFP254 + // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ SUBFP254 SWAP15 + // c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 SWAP7 MULFP254 SWAP7 diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index eab41f8b..3f8eb89f 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -1,45 +1,151 @@ use anyhow::Result; use ethereum_types::U256; +use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; -fn make_stack(xs: &[u32]) -> Vec { - Vec::from(xs) - .iter() - .map(|&x| U256::from(x as u32)) +const P254: u32 = 101; + +fn add_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { + let [a, a_] = a; + let [b, b_] = b; + [(a + b) % P254, (a_ + b_) % P254] +} + +fn add3_fp2(a: [u32; 2], b: [u32; 2], c: [u32; 2]) -> [u32; 2] { + let [a, a_] = a; + let [b, b_] = b; + let [c, c_] = c; + [(a + b + c) % P254, (a_ + b_ + c_) % P254] +} + +fn sub_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { + let [a, a_] = a; + let [b, b_] = b; + [(P254 + a - b) % P254, (P254 + a_ - b_) % P254] +} + +fn mul_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { + let [a, a_] = a; + let [b, b_] = b; + [ + (P254 + (a * b) % P254 - (a_ * b_) % P254) % P254, + ((a * b_) % P254 + (a_ * b) % P254) % P254, + ] +} + +fn i9(a: [u32; 2]) -> [u32; 2] { + let [a, a_] = a; + [(9 * a - a_) % P254, (a + 9 * a_) % P254] +} + +fn add_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { + let [c0, c1, c2] = c; + let [d0, d1, d2] = d; + + let e0 = add_fp2(c0, d0); + let e1 = add_fp2(c1, d1); + let e2 = add_fp2(c2, d2); + [e0, e1, e2] +} + +fn sub_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { + let [c0, c1, c2] = c; + let [d0, d1, d2] = d; + + let e0 = sub_fp2(c0, d0); + let e1 = sub_fp2(c1, d1); + let e2 = sub_fp2(c2, d2); + [e0, e1, e2] +} + +fn mul_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { + let [c0, c1, c2] = c; + let [d0, d1, d2] = d; + + let c0d0 = mul_fp2(c0, d0); + let c0d1 = mul_fp2(c0, d1); + let c0d2 = mul_fp2(c0, d2); + let c1d0 = mul_fp2(c1, d0); + let c1d1 = mul_fp2(c1, d1); + let c1d2 = mul_fp2(c1, d2); + let c2d0 = mul_fp2(c2, d0); + let c2d1 = mul_fp2(c2, d1); + let c2d2 = mul_fp2(c2, d2); + let cd12 = add_fp2(c1d2, c2d1); + + [ + add_fp2(c0d0, i9(cd12)), + add3_fp2(c0d1, c1d0, i9(c2d2)), + add3_fp2(c0d2, c1d1, c2d0), + ] +} + +fn sh(c: [[u32; 2]; 3]) -> [[u32; 2]; 3] { + let [c0, c1, c2] = c; + [i9(c2), c0, c1] +} + +fn mul_fp12(f: [[[u32; 2]; 3]; 2], g: [[[u32; 2]; 3]; 2]) -> [[[u32; 2]; 3]; 2] { + let [f0, f1] = f; + let [g0, g1] = g; + + let h0 = mul_fp6(f0, g0); + let h1 = mul_fp6(f1, g1); + let h01 = mul_fp6(add_fp6(f0, f1), add_fp6(g0, g1)); + [add_fp6(h0, sh(h1)), sub_fp6(h01, add_fp6(h0, h1))] +} + +fn make_stack(xs: Vec) -> Vec { + xs.iter() + .map(|&x| U256::from(x as u32) % P254) .rev() .collect() } +fn gen_fp6() -> [[u32; 2]; 3] { + let mut rng = thread_rng(); + [ + [rng.gen_range(0..P254), rng.gen_range(0..P254)], + [rng.gen_range(0..P254), rng.gen_range(0..P254)], + [rng.gen_range(0..P254), rng.gen_range(0..P254)], + ] +} + #[test] fn test_fp6() -> Result<()> { + let c = gen_fp6(); + let d = gen_fp6(); + let input: Vec = [c, d].into_iter().flatten().flatten().collect(); + let output: Vec = mul_fp6(c, d).into_iter().flatten().collect(); + let kernel = combined_kernel(); let initial_offset = kernel.global_labels["test_mul_Fp6"]; - let initial_stack: Vec = make_stack(&[1, 1, 0, 0, 1, 0, 3, 0, 0, 1, 0, 0]); + let initial_stack: Vec = make_stack(input); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); - let expected: Vec = make_stack(&[2, 12, 100, 1, 3, 0]); + let expected = make_stack(output); assert_eq!(final_stack, expected); Ok(()) } -#[test] -fn test_fp12() -> Result<()> { - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["test_mul_Fp12"]; - let initial_stack: Vec = make_stack(&[ - 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, - ]); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? - .stack() - .to_vec(); - let expected: Vec = make_stack(&[5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0]); +// #[test] +// fn test_fp12() -> Result<()> { +// let kernel = combined_kernel(); +// let initial_offset = kernel.global_labels["test_mul_Fp12"]; +// let initial_stack: Vec = make_stack(&[ +// 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, +// ]); +// let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? +// .stack() +// .to_vec(); +// let expected: Vec = make_stack(&[5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0]); - assert_eq!(final_stack, expected); +// assert_eq!(final_stack, expected); - Ok(()) -} +// Ok(()) +// } From 8a85cd30708f7c93494f5eb0487681bb9d0aa2b4 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 00:07:57 -0400 Subject: [PATCH 13/58] fp12 is running --- evm/src/cpu/kernel/tests/fields.rs | 39 ++++++++++++++++-------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 3f8eb89f..32c4ae0a 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -37,7 +37,7 @@ fn mul_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { fn i9(a: [u32; 2]) -> [u32; 2] { let [a, a_] = a; - [(9 * a - a_) % P254, (a + 9 * a_) % P254] + [(P254 + 9 * a - a_) % P254, (a + 9 * a_) % P254] } fn add_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { @@ -97,7 +97,7 @@ fn mul_fp12(f: [[[u32; 2]; 3]; 2], g: [[[u32; 2]; 3]; 2]) -> [[[u32; 2]; 3]; 2] [add_fp6(h0, sh(h1)), sub_fp6(h01, add_fp6(h0, h1))] } -fn make_stack(xs: Vec) -> Vec { +fn as_stack(xs: Vec) -> Vec { xs.iter() .map(|&x| U256::from(x as u32) % P254) .rev() @@ -122,30 +122,33 @@ fn test_fp6() -> Result<()> { let kernel = combined_kernel(); let initial_offset = kernel.global_labels["test_mul_Fp6"]; - let initial_stack: Vec = make_stack(input); + let initial_stack: Vec = as_stack(input); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); - let expected = make_stack(output); + let expected = as_stack(output); assert_eq!(final_stack, expected); Ok(()) } -// #[test] -// fn test_fp12() -> Result<()> { -// let kernel = combined_kernel(); -// let initial_offset = kernel.global_labels["test_mul_Fp12"]; -// let initial_stack: Vec = make_stack(&[ -// 1, 1, 0, 0, 1, 0, 3, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 3, 0, 0, 1, 0, 0, -// ]); -// let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? -// .stack() -// .to_vec(); -// let expected: Vec = make_stack(&[5, 5, 9, 0, 5, 3, 17, 12, 100, 1, 3, 0]); +#[test] +fn test_fp12() -> Result<()> { + let f = [gen_fp6(), gen_fp6()]; + let g = [gen_fp6(), gen_fp6()]; + let input: Vec = [f, g].into_iter().flatten().flatten().flatten().collect(); + let output: Vec = mul_fp12(f, g).into_iter().flatten().flatten().collect(); -// assert_eq!(final_stack, expected); + let kernel = combined_kernel(); + let initial_offset = kernel.global_labels["test_mul_Fp12"]; + let initial_stack: Vec = as_stack(input); + let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + .stack() + .to_vec(); -// Ok(()) -// } + let expected = as_stack(output); + assert_eq!(final_stack, expected); + + Ok(()) +} From b9a1b4413d0765e9e55a2e2d706b91e706b9ef75 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 00:21:12 -0400 Subject: [PATCH 14/58] move fp6mul and add more comments --- evm/src/cpu/kernel/aggregator.rs | 1 - evm/src/cpu/kernel/asm/fields/Fp6.asm | 229 +++++++++++++++++++++++ evm/src/cpu/kernel/asm/fields/fp6mul.asm | 217 --------------------- 3 files changed, 229 insertions(+), 218 deletions(-) delete mode 100644 evm/src/cpu/kernel/asm/fields/fp6mul.asm diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 843db031..27ff2975 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -34,7 +34,6 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/exp.asm"), include_str!("asm/halt.asm"), include_str!("asm/fields/fp6.asm"), - include_str!("asm/fields/fp6mul.asm"), include_str!("asm/fields/fp12.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index 7ab2cf87..b39a8c24 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -205,3 +205,232 @@ ADDFP254 // stack: 9b + a, 9a - b %endmacro + +// cost: 156 +%macro mul_fp6 + /// E = E0 + E1t + E2t^2 = CD + /// + /// C = C0 + C1t + C2t^2 + /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 + /// + /// D = D0 + D1t + D2t^2 + /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 + /// + /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ + /// final stack: e0, e0_, e1, e1_, e2, e2_ + + /// E0 = C0D0 + i9(C1D2 + C2D1) + /// + /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i + /// + /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i + /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i + /// + /// CDX = C1D2 + C2D1 + /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i + /// + /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i + /// + /// E0 = 9CDX - CDX_ + C0D0 + /// E0_ = 9CDX_ + CDX + C0D0_ + + // CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 + DUP12 + DUP4 + MULFP254 + DUP12 + DUP6 + MULFP254 + ADDFP254 + DUP11 + DUP7 + MULFP254 + ADDFP254 + DUP10 + DUP8 + MULFP254 + ADDFP254 + // C0D0_ = c0d0_ + c0_d0 + DUP9 + DUP3 + MULFP254 + DUP9 + DUP5 + MULFP254 + ADDFP254 + // CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP14 + DUP7 + MULFP254 + DUP13 + DUP10 + MULFP254 + ADDFP254 + SUBFP254 + // C0D0 = c0d0 - c0_d0_ + DUP11 + DUP6 + MULFP254 + DUP11 + DUP6 + MULFP254 + SUBFP254 + // stack: C0D0 , CDX , C0D0_, CDX_ + DUP4 + DUP3 + // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ + SWAP15 + SWAP3 + // stack: CDX_ , CDX , C0D0_ + PUSH 9 + MULFP254 + ADDFP254 + ADDFP254 + // stack: 9CDX_ + CDX + C0D0_ + SWAP9 + + /// E1 = C0D1 + C1D0 + i9(C2D2) + /// + /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i + /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i + /// + /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i + /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i + /// + /// E1 = 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_) + /// E1_ = C2D2 + 9C2D2_ + c0d1_ + c0_d1 + c1d0_ + c1_d0 + + // C2D2_ = c2d2_ + c2_d2 + DUP13 + DUP9 + MULFP254 + DUP3 + DUP9 + MULFP254 + ADDFP254 + // C2D2 = c2d2 - c2_d2_ + DUP3 + DUP10 + MULFP254 + DUP15 + DUP10 + MULFP254 + SUBFP254 + // stack: C2D2, C2D2_ + // c0d1 + c1d0 - (c0_d1_ + c1_d0_) + DUP3 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + SUBFP254 + // stack: c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + DUP3 + DUP3 + // stack: C2D2 , C2D2_ , c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + SWAP13 + SWAP2 + // stack: C2D2_ , C2D2 + PUSH 9 + MULFP254 + ADDFP254 + // stack: 9C2D2_ + C2D2 + // c0d1_ + c0_d1 + c1d0_ + c1_d0 + DUP11 + DUP9 + MULFP254 + DUP4 + DUP9 + MULFP254 + ADDFP254 + DUP3 + DUP8 + MULFP254 + ADDFP254 + DUP15 + DUP7 + MULFP254 + ADDFP254 + ADDFP254 + SWAP13 + /// E2 = C0D2 + C1D1 + C2D0 + /// + /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i + /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i + /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i + /// + /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) + /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + // c0_d2_ + c1_d1_ + c2_d0_ + DUP3 + DUP11 + MULFP254 + DUP2 + DUP10 + MULFP254 + ADDFP254 + DUP5 + DUP8 + MULFP254 + ADDFP254 + // c0d2 + c1d1 + c2d0 + DUP16 + DUP7 + MULFP254 + DUP4 + DUP10 + MULFP254 + ADDFP254 + DUP13 + DUP12 + MULFP254 + ADDFP254 + // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ + SUBFP254 + SWAP15 + // c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + SWAP7 + MULFP254 + SWAP7 + MULFP254 + SWAP7 + MULFP254 + SWAP2 + MULFP254 + ADDFP254 + SWAP2 + MULFP254 + ADDFP254 + ADDFP254 + ADDFP254 + SWAP2 + MULFP254 + ADDFP254 + SWAP5 +%endmacro diff --git a/evm/src/cpu/kernel/asm/fields/fp6mul.asm b/evm/src/cpu/kernel/asm/fields/fp6mul.asm deleted file mode 100644 index ea0cd77f..00000000 --- a/evm/src/cpu/kernel/asm/fields/fp6mul.asm +++ /dev/null @@ -1,217 +0,0 @@ -// cost: 156 -%macro mul_fp6 - /// E0 = C0D0 + i9(C1D2 + C2D1) - /// - /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i - /// - /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i - /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i - /// - /// CDX = C1D2 + C2D1 - /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i - /// - /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i - /// - /// E0 = 9CDX - CDX_ + C0D0 - /// E0_ = 9CDX_ + CDX + C0D0_ - - // CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 - DUP12 - DUP4 - MULFP254 - DUP12 - DUP6 - MULFP254 - ADDFP254 - DUP11 - DUP7 - MULFP254 - ADDFP254 - DUP10 - DUP8 - MULFP254 - ADDFP254 - // C0D0_ = c0d0_ + c0_d0 - DUP9 - DUP3 - MULFP254 - DUP9 - DUP5 - MULFP254 - ADDFP254 - // CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP14 - DUP7 - MULFP254 - DUP13 - DUP10 - MULFP254 - ADDFP254 - SUBFP254 - // C0D0 = c0d0 - c0_d0_ - DUP11 - DUP6 - MULFP254 - DUP11 - DUP6 - MULFP254 - SUBFP254 - // stack: C0D0 , CDX , C0D0_, CDX_ - DUP4 - DUP3 - // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ - SWAP15 - SWAP3 - // stack: CDX_ , CDX , C0D0_ - PUSH 9 - MULFP254 - ADDFP254 - ADDFP254 - // stack: 9CDX_ + CDX + C0D0_ - SWAP9 - - /// E1 = C0D1 + C1D0 + i9(C2D2) - /// - /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i - /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i - /// - /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i - /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i - /// - /// E1 = 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_) - /// E1_ = C2D2 + 9C2D2_ + c0d1_ + c0_d1 + c1d0_ + c1_d0 - - // C2D2_ = c2d2_ + c2_d2 - DUP13 - DUP9 - MULFP254 - DUP3 - DUP9 - MULFP254 - ADDFP254 - // C2D2 = c2d2 - c2_d2_ - DUP3 - DUP10 - MULFP254 - DUP15 - DUP10 - MULFP254 - SUBFP254 - // stack: C2D2, C2D2_ - // c0d1 + c1d0 - (c0_d1_ + c1_d0_) - DUP3 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - SUBFP254 - // stack: c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ - DUP3 - DUP3 - // stack: C2D2 , C2D2_ , c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ - SWAP13 - SWAP2 - // stack: C2D2_ , C2D2 - PUSH 9 - MULFP254 - ADDFP254 - // stack: 9C2D2_ + C2D2 - // c0d1_ + c0_d1 + c1d0_ + c1_d0 - DUP11 - DUP9 - MULFP254 - DUP4 - DUP9 - MULFP254 - ADDFP254 - DUP3 - DUP8 - MULFP254 - ADDFP254 - DUP15 - DUP7 - MULFP254 - ADDFP254 - ADDFP254 - SWAP13 - /// E2 = C0D2 + C1D1 + C2D0 - /// - /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i - /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i - /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i - /// - /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) - /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - // c0_d2_ + c1_d1_ + c2_d0_ - DUP3 - DUP11 - MULFP254 - DUP2 - DUP10 - MULFP254 - ADDFP254 - DUP5 - DUP8 - MULFP254 - ADDFP254 - // c0d2 + c1d1 + c2d0 - DUP16 - DUP7 - MULFP254 - DUP4 - DUP10 - MULFP254 - ADDFP254 - DUP13 - DUP12 - MULFP254 - ADDFP254 - // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ - SUBFP254 - SWAP15 - // c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - SWAP7 - MULFP254 - SWAP7 - MULFP254 - SWAP7 - MULFP254 - SWAP2 - MULFP254 - ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - ADDFP254 - ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - SWAP5 -%endmacro From ccbf85d5695c57ac10ce20309320f6e360cebd2b Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 00:22:51 -0400 Subject: [PATCH 15/58] remove fp6 test since it's redundant --- evm/src/cpu/kernel/tests/fields.rs | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 32c4ae0a..da0f1071 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -97,13 +97,6 @@ fn mul_fp12(f: [[[u32; 2]; 3]; 2], g: [[[u32; 2]; 3]; 2]) -> [[[u32; 2]; 3]; 2] [add_fp6(h0, sh(h1)), sub_fp6(h01, add_fp6(h0, h1))] } -fn as_stack(xs: Vec) -> Vec { - xs.iter() - .map(|&x| U256::from(x as u32) % P254) - .rev() - .collect() -} - fn gen_fp6() -> [[u32; 2]; 3] { let mut rng = thread_rng(); [ @@ -113,24 +106,11 @@ fn gen_fp6() -> [[u32; 2]; 3] { ] } -#[test] -fn test_fp6() -> Result<()> { - let c = gen_fp6(); - let d = gen_fp6(); - let input: Vec = [c, d].into_iter().flatten().flatten().collect(); - let output: Vec = mul_fp6(c, d).into_iter().flatten().collect(); - - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["test_mul_Fp6"]; - let initial_stack: Vec = as_stack(input); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? - .stack() - .to_vec(); - - let expected = as_stack(output); - assert_eq!(final_stack, expected); - - Ok(()) +fn as_stack(xs: Vec) -> Vec { + xs.iter() + .map(|&x| U256::from(x as u32) % P254) + .rev() + .collect() } #[test] From 6a6fbec9f5ba57f5fa8a8db9bfaa32ffd87b3d1a Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 01:19:24 -0400 Subject: [PATCH 16/58] remove fp6 test --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index 9b3f603c..19a9a5d2 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -8,10 +8,6 @@ /// /// Note: each symbol in the stack comments consists of six words -global test_mul_Fp6: - %mul_fp6 - %jump(0xdeadbeef) - global test_mul_Fp12: // stack: f, f', g, g' From c9bbd2dfa08e30d538fd5f60ca5ee888f74cc160 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 01:31:28 -0400 Subject: [PATCH 17/58] naming --- evm/src/cpu/kernel/interpreter.rs | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 0fd6464f..119e1f98 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -238,9 +238,9 @@ impl<'a> Interpreter<'a> { 0x09 => self.run_mulmod(), // "MULMOD", 0x0a => self.run_exp(), // "EXP", 0x0b => todo!(), // "SIGNEXTEND", - 0x0c => self.run_add_p(), // "ADDFP254", - 0x0d => self.run_mul_p(), // "MULFP254", - 0x0e => self.run_sub_p(), // "SUBFP254", + 0x0c => self.run_addfp254(), // "ADDFP254", + 0x0d => self.run_mulfp254(), // "MULFP254", + 0x0e => self.run_subfp254(), // "SUBFP254", 0x10 => self.run_lt(), // "LT", 0x11 => self.run_gt(), // "GT", 0x12 => todo!(), // "SLT", @@ -353,31 +353,30 @@ impl<'a> Interpreter<'a> { self.push(x.overflowing_add(y).0); } - fn run_add_p(&mut self) { - let x = self.pop(); - let y = self.pop(); - self.push(U256::try_from((x + y) % 101).unwrap()); - } - fn run_mul(&mut self) { let x = self.pop(); let y = self.pop(); self.push(x.overflowing_mul(y).0); } - fn run_mul_p(&mut self) { - let x = self.pop(); - let y = self.pop(); - self.push(U256::try_from(x.full_mul(y) % 101).unwrap()); - } - fn run_sub(&mut self) { let x = self.pop(); let y = self.pop(); self.push(x.overflowing_sub(y).0); } - fn run_sub_p(&mut self) { + fn run_addfp254(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(U256::try_from((x + y) % 101).unwrap()); + } + fn run_mulfp254(&mut self) { + let x = self.pop(); + let y = self.pop(); + self.push(U256::try_from(x.full_mul(y) % 101).unwrap()); + } + + fn run_subfp254(&mut self) { let x = self.pop(); let y = self.pop(); self.push(U256::try_from((U256::from(101) + x - y) % 101).unwrap()); From 75cabedc3853b527b7462a0eefb3f07db84067d0 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 10:34:41 -0400 Subject: [PATCH 18/58] better abstraction --- evm/src/cpu/kernel/tests/fields.rs | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index da0f1071..cf269bb8 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -7,37 +7,53 @@ use crate::cpu::kernel::interpreter::run_with_kernel; const P254: u32 = 101; +fn add_fp(x: u32, y: u32) -> u32 { + (x + y) % P254 +} + +fn add3_fp(x: u32, y: u32, z: u32) -> u32 { + (x + y + z) % P254 +} + +fn mul_fp(x: u32, y: u32) -> u32 { + (x * y) % P254 +} + +fn sub_fp(x: u32, y: u32) -> u32 { + (P254 + x - y) % P254 +} + fn add_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { let [a, a_] = a; let [b, b_] = b; - [(a + b) % P254, (a_ + b_) % P254] + [add_fp(a, b), add_fp(a_, b_)] } fn add3_fp2(a: [u32; 2], b: [u32; 2], c: [u32; 2]) -> [u32; 2] { let [a, a_] = a; let [b, b_] = b; let [c, c_] = c; - [(a + b + c) % P254, (a_ + b_ + c_) % P254] + [add3_fp(a, b, c), add3_fp(a_, b_, c_)] } fn sub_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { let [a, a_] = a; let [b, b_] = b; - [(P254 + a - b) % P254, (P254 + a_ - b_) % P254] + [sub_fp(a, b), sub_fp(a_, b_)] } fn mul_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { let [a, a_] = a; let [b, b_] = b; [ - (P254 + (a * b) % P254 - (a_ * b_) % P254) % P254, - ((a * b_) % P254 + (a_ * b) % P254) % P254, + sub_fp(mul_fp(a, b), mul_fp(a_, b_)), + add_fp(mul_fp(a, b_), mul_fp(a_, b)), ] } fn i9(a: [u32; 2]) -> [u32; 2] { let [a, a_] = a; - [(P254 + 9 * a - a_) % P254, (a + 9 * a_) % P254] + [sub_fp(mul_fp(9, a), a_), add_fp(a, mul_fp(9, a_))] } fn add_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { From 9222dafe6e57e5c2b0daa7efaf87a99efa9974f2 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 10:37:40 -0400 Subject: [PATCH 19/58] clippy --- evm/src/cpu/kernel/interpreter.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 119e1f98..99156a3f 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -368,8 +368,9 @@ impl<'a> Interpreter<'a> { fn run_addfp254(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(U256::try_from((x + y) % 101).unwrap()); + self.push((x + y) % 101); } + fn run_mulfp254(&mut self) { let x = self.pop(); let y = self.pop(); @@ -379,7 +380,7 @@ impl<'a> Interpreter<'a> { fn run_subfp254(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(U256::try_from((U256::from(101) + x - y) % 101).unwrap()); + self.push((U256::from(101) + x - y) % 101); } fn run_div(&mut self) { From 0847d9885d169c23044158d350410e9094ff4e30 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 10:42:11 -0400 Subject: [PATCH 20/58] alphabetical --- evm/src/cpu/kernel/aggregator.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 27ff2975..17adb07e 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -32,9 +32,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/lift_x.asm"), include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), - include_str!("asm/halt.asm"), include_str!("asm/fields/fp6.asm"), include_str!("asm/fields/fp12.asm"), + include_str!("asm/halt.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), include_str!("asm/memory/memcpy.asm"), From 041fda134f6606641afad467fb12db3f79394527 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 10:57:20 -0400 Subject: [PATCH 21/58] capitalization?? --- evm/src/cpu/kernel/aggregator.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 17adb07e..bca94f0c 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -32,8 +32,8 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/lift_x.asm"), include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), - include_str!("asm/fields/fp6.asm"), - include_str!("asm/fields/fp12.asm"), + include_str!("asm/fields/Fp6.asm"), + include_str!("asm/fields/Fp12.asm"), include_str!("asm/halt.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), From 6fc34f6a3d030d99ce875e215fdb58bc3ff1ae29 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:06:31 -0400 Subject: [PATCH 22/58] lint --- evm/src/cpu/kernel/tests/fields.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index cf269bb8..9ebc1e75 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -124,7 +124,7 @@ fn gen_fp6() -> [[u32; 2]; 3] { fn as_stack(xs: Vec) -> Vec { xs.iter() - .map(|&x| U256::from(x as u32) % P254) + .map(|&x| U256::from(x) % P254) .rev() .collect() } From 625544565d7a29eae52e129bf0f1879052a6642b Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:07:43 -0400 Subject: [PATCH 23/58] change to 107 --- evm/src/cpu/kernel/interpreter.rs | 6 +++--- evm/src/cpu/kernel/tests/fields.rs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 99156a3f..c12459ab 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -368,19 +368,19 @@ impl<'a> Interpreter<'a> { fn run_addfp254(&mut self) { let x = self.pop(); let y = self.pop(); - self.push((x + y) % 101); + self.push((x + y) % 107); } fn run_mulfp254(&mut self) { let x = self.pop(); let y = self.pop(); - self.push(U256::try_from(x.full_mul(y) % 101).unwrap()); + self.push(U256::try_from(x.full_mul(y) % 107).unwrap()); } fn run_subfp254(&mut self) { let x = self.pop(); let y = self.pop(); - self.push((U256::from(101) + x - y) % 101); + self.push((U256::from(107) + x - y) % 107); } fn run_div(&mut self) { diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 9ebc1e75..1a45e0f7 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -5,7 +5,7 @@ use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; -const P254: u32 = 101; +const P254: u32 = 107; fn add_fp(x: u32, y: u32) -> u32 { (x + y) % P254 From dde24e6b307c09ddd93f4c967cc09248e1bd44b3 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:09:07 -0400 Subject: [PATCH 24/58] fmt --- evm/src/cpu/kernel/tests/fields.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 1a45e0f7..31f2dde5 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -123,10 +123,7 @@ fn gen_fp6() -> [[u32; 2]; 3] { } fn as_stack(xs: Vec) -> Vec { - xs.iter() - .map(|&x| U256::from(x) % P254) - .rev() - .collect() + xs.iter().map(|&x| U256::from(x) % P254).rev().collect() } #[test] From 1f39053d9adf37aa41f14c4e2fec688f607798a8 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:23:43 -0400 Subject: [PATCH 25/58] detailed accounting --- evm/src/cpu/kernel/asm/fields/Fp12.asm | 36 ++++++++++++++++++-------- evm/src/cpu/kernel/asm/fields/Fp6.asm | 2 +- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields/Fp12.asm index 19a9a5d2..c2173b55 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp12.asm @@ -1,14 +1,3 @@ -/// F = f + f'z -/// G = g + g'z -/// -/// h + h'z = FG -/// -/// h = fg + sh(f'g') -/// h' = (f+f')(g+g') - fg - f'g' -/// -/// Note: each symbol in the stack comments consists of six words - - global test_mul_Fp12: // stack: f, f', g, g' %store_fp6(0) @@ -26,6 +15,31 @@ return_on_stack: %jump(0xdeadbeef) +/// macro | num | ops | cost +/// ------------------------- +/// load | 8 | 40 | 320 +/// store | 5 | 40 | 200 +/// dup | 5 | 6 | 30 +/// swap | 4 | 16 | 64 +/// add | 3 | 16 | 48 +/// sub | 2 | 17 | 34 +/// mul | 3 | 156 | 468 +/// i9 | 1 | 9 | 9 +/// jump | 1 | 1 | 1 +/// +/// TOTAL: 1174 + + +/// F = f + f'z +/// G = g + g'z +/// +/// H = h + h'z = FG +/// +/// h = fg + sh(f'g') +/// h' = (f+f')(g+g') - fg - f'g' +/// +/// Note: each symbol in the stack comments consists of six words + global mul_Fp12: %load_fp6(6) %load_fp6(18) diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields/Fp6.asm index b39a8c24..739445e5 100644 --- a/evm/src/cpu/kernel/asm/fields/Fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/Fp6.asm @@ -54,7 +54,7 @@ // stack: %endmacro -// cost: 49 +// cost: store (40) + i9 (9) = 49 %macro store_fp6_sh(offset) // stack: x0, x1, x2, x3, x4, x5 PUSH $offset From 0c0775da3e528c34ef9f0c73d03867f49a1a4f5b Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:29:05 -0400 Subject: [PATCH 26/58] casing? --- evm/src/cpu/kernel/asm/{fields/Fp12.asm => fields2/fp12.asm} | 0 evm/src/cpu/kernel/asm/{fields/Fp6.asm => fields2/fp6.asm} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename evm/src/cpu/kernel/asm/{fields/Fp12.asm => fields2/fp12.asm} (100%) rename evm/src/cpu/kernel/asm/{fields/Fp6.asm => fields2/fp6.asm} (100%) diff --git a/evm/src/cpu/kernel/asm/fields/Fp12.asm b/evm/src/cpu/kernel/asm/fields2/fp12.asm similarity index 100% rename from evm/src/cpu/kernel/asm/fields/Fp12.asm rename to evm/src/cpu/kernel/asm/fields2/fp12.asm diff --git a/evm/src/cpu/kernel/asm/fields/Fp6.asm b/evm/src/cpu/kernel/asm/fields2/fp6.asm similarity index 100% rename from evm/src/cpu/kernel/asm/fields/Fp6.asm rename to evm/src/cpu/kernel/asm/fields2/fp6.asm From 3b8b812f46e58c23dacb9b6439630a99823ae0d9 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 11:30:21 -0400 Subject: [PATCH 27/58] aggregator --- evm/src/cpu/kernel/aggregator.rs | 4 ++-- evm/src/cpu/kernel/asm/{fields2 => fields}/fp12.asm | 0 evm/src/cpu/kernel/asm/{fields2 => fields}/fp6.asm | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename evm/src/cpu/kernel/asm/{fields2 => fields}/fp12.asm (100%) rename evm/src/cpu/kernel/asm/{fields2 => fields}/fp6.asm (100%) diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index bca94f0c..17adb07e 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -32,8 +32,8 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/lift_x.asm"), include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), - include_str!("asm/fields/Fp6.asm"), - include_str!("asm/fields/Fp12.asm"), + include_str!("asm/fields/fp6.asm"), + include_str!("asm/fields/fp12.asm"), include_str!("asm/halt.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), diff --git a/evm/src/cpu/kernel/asm/fields2/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm similarity index 100% rename from evm/src/cpu/kernel/asm/fields2/fp12.asm rename to evm/src/cpu/kernel/asm/fields/fp12.asm diff --git a/evm/src/cpu/kernel/asm/fields2/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm similarity index 100% rename from evm/src/cpu/kernel/asm/fields2/fp6.asm rename to evm/src/cpu/kernel/asm/fields/fp6.asm From eb4f8fec45201adc5010f276654f0c6c79519c54 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 12:04:26 -0400 Subject: [PATCH 28/58] minor --- evm/src/cpu/kernel/asm/fields/fp6.asm | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index 739445e5..92bca5c8 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -86,26 +86,26 @@ // cost: 6 %macro dup1_fp6 - // stack: F: 6 + // stack: f: 6 DUP6 DUP6 DUP6 DUP6 DUP6 DUP6 - // stack: F: 6, F: 6 + // stack: f: 6, g: 6 %endmacro // cost: 6 %macro dup2_fp6 - // stack: F: 6, G: 6 + // stack: f: 6, g: 6 DUP12 DUP12 DUP12 DUP12 DUP12 DUP12 - // stack: G: 6, F: 6, G: 6 + // stack: g: 6, f: 6, g: 6 %endmacro // cost: 16 @@ -293,12 +293,12 @@ // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ SWAP15 SWAP3 - // stack: CDX_ , CDX , C0D0_ + // stack: CDX_ , CDX , C0D0_ PUSH 9 MULFP254 ADDFP254 ADDFP254 - // stack: 9CDX_ + CDX + C0D0_ + // stack: 9CDX_ + CDX + C0D0_ SWAP9 /// E1 = C0D1 + C1D0 + i9(C2D2) @@ -379,6 +379,7 @@ ADDFP254 ADDFP254 SWAP13 + /// E2 = C0D2 + C1D1 + C2D0 /// /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i @@ -387,6 +388,7 @@ /// /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + // c0_d2_ + c1_d1_ + c2_d0_ DUP3 DUP11 From 6451190d764979a1398f2b57d7bde72cf6237862 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 18 Oct 2022 12:47:31 -0400 Subject: [PATCH 29/58] replace mul_const --- evm/src/cpu/kernel/asm/fields/fp12.asm | 18 ++++++------- evm/src/cpu/kernel/asm/fields/fp6.asm | 36 ++++++++++++++------------ 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index c2173b55..1e13d48b 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -17,15 +17,15 @@ return_on_stack: /// macro | num | ops | cost /// ------------------------- -/// load | 8 | 40 | 320 -/// store | 5 | 40 | 200 -/// dup | 5 | 6 | 30 -/// swap | 4 | 16 | 64 -/// add | 3 | 16 | 48 -/// sub | 2 | 17 | 34 -/// mul | 3 | 156 | 468 -/// i9 | 1 | 9 | 9 -/// jump | 1 | 1 | 1 +/// load | 8 | 40 | 320 +/// store | 5 | 40 | 200 +/// dup | 5 | 6 | 30 +/// swap | 4 | 16 | 64 +/// add | 3 | 16 | 48 +/// sub | 2 | 17 | 34 +/// mul | 3 | 156 | 468 +/// i9 | 1 | 9 | 9 +/// jump | 1 | 1 | 1 /// /// TOTAL: 1174 diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index 92bca5c8..a6e93a71 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -84,6 +84,24 @@ // stack: %endmacro +// cost: 9; note this returns y, x for x + yi +%macro i9 + // stack: a , b + DUP2 + DUP2 + // stack: a , b, a , b + PUSH 9 + MULFP254 + SUBFP254 + // stack: 9a - b, a , b + SWAP2 + // stack: b , a, 9a - b + PUSH 9 + MULFP254 + ADDFP254 + // stack: 9b + a, 9a - b +%endmacro + // cost: 6 %macro dup1_fp6 // stack: f: 6 @@ -190,22 +208,6 @@ // stack: h0, h1, h2, h3, h4, h5 %endmacro -// cost: 9; note this returns y, x for x + yi -%macro i9 - // stack: a , b - DUP2 - DUP2 - // stack: a , b, a , b - %mul_const(9) - SUBFP254 - // stack: 9a - b, a , b - SWAP2 - // stack: b , a, 9a - b - %mul_const(9) - ADDFP254 - // stack: 9b + a, 9a - b -%endmacro - // cost: 156 %macro mul_fp6 /// E = E0 + E1t + E2t^2 = CD @@ -379,7 +381,7 @@ ADDFP254 ADDFP254 SWAP13 - + /// E2 = C0D2 + C1D1 + C2D0 /// /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i From d7fdccfc8fce90703c0184b585c03120a1d8ec8f Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 19 Oct 2022 10:16:59 -0400 Subject: [PATCH 30/58] more comments --- evm/src/cpu/kernel/asm/fields/fp12.asm | 34 +++++++++++++++++--------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index 1e13d48b..76d0d967 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -42,33 +42,41 @@ return_on_stack: global mul_Fp12: %load_fp6(6) + // stack: f' %load_fp6(18) + // stack: g', f' %dup2_fp6 + // stack: f', g', f' %dup2_fp6 - // stack: g', f', g', f' + // stack: g', f', g', f' %mul_fp6 + // stack: f'g', g', f' %dup1_fp6 - // stack: f'g', f'g', g', f' + // stack: f'g', f'g', g', f' %store_fp6_sh(36) + // stack: f'g', g', f' %store_fp6(42) - // stack: g', f' + // stack: g', f' %load_fp6(12) - // stack: g , g', f' + // stack: g , g', f' %swap_fp6 - // stack: g', g , f' + // stack: g', g , f' %dup2_fp6 - // stack: g , g', g , f' + // stack: g, g', g , f' %add_fp6 - // stack: g + g', g , f' + // stack: g+g', g , f' %swap_fp6 - // stack: g , g + g', f' + // stack: g, g+g', f' %load_fp6(0) - // stack: f, g , g + g', f' + // stack: f, g , g+g', f' %mul_fp6 + // stack: fg , g+g', f' %store_fp6(48) - // stack: g + g', f' + // stack: g+g', f' %swap_fp6 + // stack: f', g+g' %load_fp6(0) + // stack: f,f', g+g' %add_fp6 // stack: f+f', g+g' %mul_fp6 @@ -76,11 +84,13 @@ global mul_Fp12: %load_fp6(42) // stack: f'g', (f+f')(g+g') %bus_fp6 - // stack: (f+f')(g+g') - f'g' + // stack: (f+f')(g+g') - f'g' %load_fp6(48) + // stack: fg, (f+f')(g+g') - f'g' %swap_fp6 - // stack: (f+f')(g+g') - f'g' , fg + // stack: (f+f')(g+g') - f'g', fg %dup2_fp6 + // stack: fg, (f+f')(g+g') - f'g', fg %bus_fp6 // stack: (f+f')(g+g') - f'g' - fg, fg %store_fp6(30) From 37e429c9437b8979c0fe25b223103e8ba765fc9e Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Wed, 19 Oct 2022 10:31:43 -0400 Subject: [PATCH 31/58] more comments --- evm/src/cpu/kernel/asm/fields/fp6.asm | 61 +++++++++++++++------------ 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index a6e93a71..d12322b3 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -180,7 +180,7 @@ // stack: h0, h1, h2, h3, h4, h5 %endmacro -// *backwards order subtraction* cost: 17 +// *reversed argument subtraction* cost: 17 %macro bus_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 SWAP7 @@ -210,14 +210,14 @@ // cost: 156 %macro mul_fp6 - /// E = E0 + E1t + E2t^2 = CD - /// /// C = C0 + C1t + C2t^2 /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 /// /// D = D0 + D1t + D2t^2 /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 /// + /// E = E0 + E1t + E2t^2 = CD + /// /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ /// final stack: e0, e0_, e1, e1_, e2, e2_ @@ -236,7 +236,7 @@ /// E0 = 9CDX - CDX_ + C0D0 /// E0_ = 9CDX_ + CDX + C0D0_ - // CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 + // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 DUP12 DUP4 MULFP254 @@ -252,7 +252,7 @@ DUP8 MULFP254 ADDFP254 - // C0D0_ = c0d0_ + c0_d0 + // make C0D0_ = c0d0_ + c0_d0 DUP9 DUP3 MULFP254 @@ -260,7 +260,7 @@ DUP5 MULFP254 ADDFP254 - // CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ DUP12 DUP9 MULFP254 @@ -276,7 +276,7 @@ MULFP254 ADDFP254 SUBFP254 - // C0D0 = c0d0 - c0_d0_ + // make C0D0 = c0d0 - c0_d0_ DUP11 DUP6 MULFP254 @@ -284,23 +284,24 @@ DUP6 MULFP254 SUBFP254 - // stack: C0D0 , CDX , C0D0_, CDX_ + + // stack: C0D0 , CDX , C0D0_, CDX_ DUP4 DUP3 - // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ + // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ PUSH 9 MULFP254 SUBFP254 ADDFP254 - // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ + // stack: E0 = 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ SWAP15 SWAP3 - // stack: CDX_ , CDX , C0D0_ + // stack: CDX_ , CDX , C0D0_ PUSH 9 MULFP254 ADDFP254 ADDFP254 - // stack: 9CDX_ + CDX + C0D0_ + // stack: E0_ = 9CDX_ + CDX + C0D0_ SWAP9 /// E1 = C0D1 + C1D0 + i9(C2D2) @@ -308,13 +309,16 @@ /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i /// + /// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) + /// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 + /// /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i /// - /// E1 = 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_) - /// E1_ = C2D2 + 9C2D2_ + c0d1_ + c0_d1 + c1d0_ + c1_d0 + /// E1 = 9C2D2 - C2D2_ + CD01 + /// E1_ = C2D2 + 9C2D2_ + CD01_ - // C2D2_ = c2d2_ + c2_d2 + // make C2D2_ = c2d2_ + c2_d2 DUP13 DUP9 MULFP254 @@ -322,7 +326,7 @@ DUP9 MULFP254 ADDFP254 - // C2D2 = c2d2 - c2_d2_ + // make C2D2 = c2d2 - c2_d2_ DUP3 DUP10 MULFP254 @@ -330,8 +334,7 @@ DUP10 MULFP254 SUBFP254 - // stack: C2D2, C2D2_ - // c0d1 + c1d0 - (c0_d1_ + c1_d0_) + // make C0D0 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) DUP3 DUP9 MULFP254 @@ -347,23 +350,23 @@ MULFP254 ADDFP254 SUBFP254 - // stack: c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + // stack: C0D0, C2D2, C2D2_ DUP3 DUP3 - // stack: C2D2 , C2D2_ , c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + // stack: C2D2 , C2D2_ , C0D0, C2D2, C2D2_ PUSH 9 MULFP254 SUBFP254 ADDFP254 - // stack: 9C2D2 - C2D2_ + c0d1 + c1d0 - (c0_d1_ + c1_d0_), C2D2, C2D2_ + // stack: E1 = 9C2D2 - C2D2_ + C0D0, C2D2, C2D2_ SWAP13 SWAP2 - // stack: C2D2_ , C2D2 + // stack: C2D2_, C2D2 PUSH 9 MULFP254 ADDFP254 // stack: 9C2D2_ + C2D2 - // c0d1_ + c0_d1 + c1d0_ + c1_d0 + // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 DUP11 DUP9 MULFP254 @@ -379,7 +382,9 @@ DUP7 MULFP254 ADDFP254 + // stack: CD01_ , 9C2D2_ + C2D2 ADDFP254 + // stack: E1_ = CD01_ + 9C2D2_ + C2D2 SWAP13 /// E2 = C0D2 + C1D1 + C2D0 @@ -391,7 +396,7 @@ /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - // c0_d2_ + c1_d1_ + c2_d0_ + // make c0_d2_ + c1_d1_ + c2_d0_ DUP3 DUP11 MULFP254 @@ -403,7 +408,7 @@ DUP8 MULFP254 ADDFP254 - // c0d2 + c1d1 + c2d0 + // make c0d2 + c1d1 + c2d0 DUP16 DUP7 MULFP254 @@ -415,10 +420,11 @@ DUP12 MULFP254 ADDFP254 - // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ + // stack: c0d2 + c1d1 + c2d0 , c0_d2_ + c1_d1_ + c2_d0_ SUBFP254 + // stack: E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) SWAP15 - // c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + // make c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 SWAP7 MULFP254 SWAP7 @@ -436,5 +442,6 @@ SWAP2 MULFP254 ADDFP254 + // stack: E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 SWAP5 %endmacro From dc59ed10a18819c8660c692f56a49d8cf63055cb Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 10:56:55 -0400 Subject: [PATCH 32/58] bus -> subr --- evm/src/cpu/kernel/asm/fields/fp12.asm | 4 ++-- evm/src/cpu/kernel/asm/fields/fp6.asm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index 76d0d967..23068e96 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -83,7 +83,7 @@ global mul_Fp12: // stack: (f+f')(g+g') %load_fp6(42) // stack: f'g', (f+f')(g+g') - %bus_fp6 + %subr_fp6 // stack: (f+f')(g+g') - f'g' %load_fp6(48) // stack: fg, (f+f')(g+g') - f'g' @@ -91,7 +91,7 @@ global mul_Fp12: // stack: (f+f')(g+g') - f'g', fg %dup2_fp6 // stack: fg, (f+f')(g+g') - f'g', fg - %bus_fp6 + %subr_fp6 // stack: (f+f')(g+g') - f'g' - fg, fg %store_fp6(30) // stack: fg diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index d12322b3..c3d73f5c 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -181,7 +181,7 @@ %endmacro // *reversed argument subtraction* cost: 17 -%macro bus_fp6 +%macro subr_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 SWAP7 SUBFP254 From b790af9075309b664dbe76b5452d571ee6c1c154 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 11:55:05 -0400 Subject: [PATCH 33/58] addr on stack --- evm/src/cpu/kernel/asm/fields/fp12.asm | 103 ++++++++++++++----------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index 23068e96..66b20925 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -38,66 +38,77 @@ return_on_stack: /// h = fg + sh(f'g') /// h' = (f+f')(g+g') - fg - f'g' /// -/// Note: each symbol in the stack comments consists of six words +/// Note: f, f', g, g' consist of six terms on the stack global mul_Fp12: - %load_fp6(6) - // stack: f' - %load_fp6(18) - // stack: g', f' - %dup2_fp6 - // stack: f', g', f' - %dup2_fp6 - // stack: g', f', g', f' - %mul_fp6 - // stack: f'g', g', f' + // stack: in1, in2, out + DUP1 %add_const(6) %load_fp6 + // stack: f', in1, in2, out + DUP7 %add_const(6) %load_fp6 + // stack: g', f', in1, in2, out + PUSH post_mul_1 + DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + // stack: f', post_mul_1, g', f', in1, in2, out + DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + // stack: g', f', post_mul_1, g', f', in1, in2, out + %jump(mul_fp6) +post_mul_1: + // stack: f'g', g' , f', in1, in2, out %dup1_fp6 - // stack: f'g', f'g', g', f' + // stack: f'g', f'g', g' , f', in1, in2, out %store_fp6_sh(36) - // stack: f'g', g', f' + // stack: f'g', g' , f', in1, in2, out %store_fp6(42) - // stack: g', f' - %load_fp6(12) - // stack: g , g', f' - %swap_fp6 - // stack: g', g , f' - %dup2_fp6 - // stack: g, g', g , f' + // stack: g' , f', in1, in2, out + DUP13 + // stack: in1, g' , f', in1, in2, out + DUP15 %load_fp6 + // stack: g , in1, g' , f', in1, in2, out + %swap_fp6_hole + // stack: g', in1, g , f', in1, in2, out + DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + // stack: g,g', in1, g , f', in1, in2, out %add_fp6 - // stack: g+g', g , f' - %swap_fp6 - // stack: g, g+g', f' - %load_fp6(0) - // stack: f, g , g+g', f' - %mul_fp6 - // stack: fg , g+g', f' + // stack: g+g', in1, g , f', in1, in2, out + %swap_fp6_hole + // stack: g, in1, g+g', f', in1, in2, out + PUSH post_mul_2 + SWAP7 + %load_fp6 + // stack: f, g, post_mul_2, g+g', f', in1, in2, out + %jump(mul_fp6) +post_mul_2: + // stack: fg, g+g', f', in1, in2, out %store_fp6(48) - // stack: g+g', f' + // stack: g+g', f', in1, in2, out %swap_fp6 - // stack: f', g+g' - %load_fp6(0) - // stack: f,f', g+g' + // stack: f', g+g', in1, in2, out + PUSH post_mul_3 + SWAP13 %load_fp6 + // stack: f,f', g+g', post_mul_3, in2, out %add_fp6 - // stack: f+f', g+g' - %mul_fp6 - // stack: (f+f')(g+g') + // stack: f+f', g+g', post_mul_3, in2, out + %jump(mul_fp6) +post_mul_3: + // stack: (f+f')(g+g'), in2, out %load_fp6(42) - // stack: f'g', (f+f')(g+g') + // stack: f'g', (f+f')(g+g'), in2, out %subr_fp6 - // stack: (f+f')(g+g') - f'g' + // stack: (f+f')(g+g') - f'g', in2, out %load_fp6(48) - // stack: fg, (f+f')(g+g') - f'g' + // stack: fg, (f+f')(g+g') - f'g', in2, out %swap_fp6 - // stack: (f+f')(g+g') - f'g', fg + // stack: (f+f')(g+g') - f'g', fg, in2, out %dup2_fp6 - // stack: fg, (f+f')(g+g') - f'g', fg + // stack: fg, (f+f')(g+g') - f'g', fg, in2, out %subr_fp6 - // stack: (f+f')(g+g') - f'g' - fg, fg - %store_fp6(30) - // stack: fg + // stack: (f+f')(g+g') - f'g' - fg, fg, in2, out + DUP14 add_const(6) %store_fp6 + // stack: fg, in2, out %load_fp6(36) - // stack: sh(f'g') , fg + // stack: sh(f'g') , fg, in2, out %add_fp6 - // stack: sh(f'g') + fg - %store_fp6(24) - JUMP + // stack: sh(f'g') + fg, in2, out + DUP8 %store_fp6(24) + // stack: in2, out + %pop2 JUMP From 05fa0490b843d637592ae980d556a98a3a244615 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 12:07:53 -0400 Subject: [PATCH 34/58] load/store macros --- evm/src/cpu/kernel/asm/fields/fp12.asm | 2 +- evm/src/cpu/kernel/asm/fields/fp6.asm | 72 +++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index 66b20925..26935eb6 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -109,6 +109,6 @@ post_mul_3: // stack: sh(f'g') , fg, in2, out %add_fp6 // stack: sh(f'g') + fg, in2, out - DUP8 %store_fp6(24) + DUP8 %store_fp6 // stack: in2, out %pop2 JUMP diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index c3d73f5c..995da662 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -1,4 +1,38 @@ -// cost: 6 loads + 6 offsets + 5 adds = 6*4 + 6*1 + 5*2 = 40 +// cost: 6 loads + 6 dup/swaps + 5 adds = 6*4 + 6*1 + 5*2 = 40 +%macro load_fp6 + // stack: offset + DUP1 + %add_const(4) + // stack: ind4, offset + %mload_kernel_general + // stack: x4, offset + DUP2 + %add_const(3) + // stack: ind3, x4, offset + %mload_kernel_general + // stack: x3, x4, offset + DUP3 + %add_const(2) + // stack: ind2, x3, x4, offset + %mload_kernel_general + // stack: x2, x3, x4, offset + DUP4 + %add_const(1) + // stack: ind1, x2, x3, x4, offset + %mload_kernel_general + // stack: x1, x2, x3, x4, offset + DUP5 + %add_const(5) + // stack: ind5, x1, x2, x3, x4, offset + %mload_kernel_general + // stack: x5, x1, x2, x3, x4, offset + SWAP5 + // stack: ind0, x1, x2, x3, x4, x5 + %mload_kernel_general + // stack: x0, x1, x2, x3, x4, x5 +%endmacro + +// cost: 6 loads + 6 pushes + 5 adds = 6*4 + 6*1 + 5*2 = 40 %macro load_fp6(offset) // stack: PUSH $offset @@ -26,7 +60,41 @@ // stack: x0, x1, x2, x3, x4, x5 %endmacro -// cost: 40 +// cost: 6 stores + 6 swaps/dups + 5 adds = 6*4 + 6*1 + 5*2 = 40 +%macro store_fp6 + // stack: offset, x0, x1, x2, x3, x4, x5 + SWAP5 + DUP6 + %add_const(4) + // stack: ind4, x4, x0, x1, x2, x3, offset, x5 + %mstore_kernel_general + // stack: x0, x1, x2, x3, offset, x5 + DUP5 + // stack: ind0, x0, x1, x2, x3, offset, x5 + %mstore_kernel_general + // stack: x1, x2, x3, offset, x5 + DUP4 + %add_const(1) + // stack: ind1, x1, x2, x3, offset, x5 + %mstore_kernel_general + // stack: x2, x3, offset, x5 + DUP3 + %add_const(2) + // stack: ind2, x2, x3, offset, x5 + %mstore_kernel_general + // stack: x3, offset, x5 + DUP2 + %add_const(3) + // stack: ind3, x3, offset, x5 + %mstore_kernel_general + // stack: offset, x5 + %add_const(5) + // stack: ind5, x5 + %mstore_kernel_general + // stack: +%endmacro + +// cost: 6 stores + 6 pushes + 5 adds = 6*4 + 6*1 + 5*2 = 40 %macro store_fp6(offset) // stack: x0, x1, x2, x3, x4, x5 PUSH $offset From cad27241c1c9df086191016c9869977ca2190cd4 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 16:07:39 -0400 Subject: [PATCH 35/58] finish macros --- evm/src/cpu/kernel/asm/fields/fp12.asm | 50 +++++++++++++++----------- evm/src/cpu/kernel/asm/fields/fp6.asm | 43 ++++++++++++++++++++-- 2 files changed, 71 insertions(+), 22 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12.asm index 26935eb6..ff7f064b 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12.asm @@ -41,20 +41,24 @@ return_on_stack: /// Note: f, f', g, g' consist of six terms on the stack global mul_Fp12: - // stack: in1, in2, out - DUP1 %add_const(6) %load_fp6 - // stack: f', in1, in2, out - DUP7 %add_const(6) %load_fp6 - // stack: g', f', in1, in2, out + // stack: in1, in2, out + DUP1 + %add_const(6) + %load_fp6 + // stack: f', in1, in2, out + DUP7 + %add_const(6) + %load_fp6 + // stack: g', f', in1, in2, out PUSH post_mul_1 - DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + %dup_fp6_7 // stack: f', post_mul_1, g', f', in1, in2, out - DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + %dup_fp6_7 // stack: g', f', post_mul_1, g', f', in1, in2, out %jump(mul_fp6) post_mul_1: // stack: f'g', g' , f', in1, in2, out - %dup1_fp6 + %dup_fp6_0 // stack: f'g', f'g', g' , f', in1, in2, out %store_fp6_sh(36) // stack: f'g', g' , f', in1, in2, out @@ -62,11 +66,12 @@ post_mul_1: // stack: g' , f', in1, in2, out DUP13 // stack: in1, g' , f', in1, in2, out - DUP15 %load_fp6 + DUP15 + %load_fp6 // stack: g , in1, g' , f', in1, in2, out %swap_fp6_hole // stack: g', in1, g , f', in1, in2, out - DUP13 DUP13 DUP13 DUP13 DUP13 DUP13 + dup_fp6_7 // stack: g,g', in1, g , f', in1, in2, out %add_fp6 // stack: g+g', in1, g , f', in1, in2, out @@ -78,16 +83,17 @@ post_mul_1: // stack: f, g, post_mul_2, g+g', f', in1, in2, out %jump(mul_fp6) post_mul_2: - // stack: fg, g+g', f', in1, in2, out + // stack: fg, g+g', f', in1, in2, out %store_fp6(48) - // stack: g+g', f', in1, in2, out + // stack: g+g', f', in1, in2, out %swap_fp6 - // stack: f', g+g', in1, in2, out + // stack: f', g+g', in1, in2, out PUSH post_mul_3 - SWAP13 %load_fp6 - // stack: f,f', g+g', post_mul_3, in2, out + SWAP13 + %load_fp6 + // stack: f,f', g+g', post_mul_3, in2, out %add_fp6 - // stack: f+f', g+g', post_mul_3, in2, out + // stack: f+f', g+g', post_mul_3, in2, out %jump(mul_fp6) post_mul_3: // stack: (f+f')(g+g'), in2, out @@ -99,16 +105,20 @@ post_mul_3: // stack: fg, (f+f')(g+g') - f'g', in2, out %swap_fp6 // stack: (f+f')(g+g') - f'g', fg, in2, out - %dup2_fp6 + %dup_fp6_6 // stack: fg, (f+f')(g+g') - f'g', fg, in2, out %subr_fp6 // stack: (f+f')(g+g') - f'g' - fg, fg, in2, out - DUP14 add_const(6) %store_fp6 + DUP14 + add_const(6) + %store_fp6 // stack: fg, in2, out %load_fp6(36) // stack: sh(f'g') , fg, in2, out %add_fp6 // stack: sh(f'g') + fg, in2, out - DUP8 %store_fp6 + DUP8 + %store_fp6 // stack: in2, out - %pop2 JUMP + %pop2 + JUMP diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6.asm index 995da662..b6f1950e 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6.asm @@ -171,7 +171,7 @@ %endmacro // cost: 6 -%macro dup1_fp6 +%macro dup_fp6_0 // stack: f: 6 DUP6 DUP6 @@ -183,7 +183,7 @@ %endmacro // cost: 6 -%macro dup2_fp6 +%macro dup_fp6_6 // stack: f: 6, g: 6 DUP12 DUP12 @@ -194,6 +194,18 @@ // stack: g: 6, f: 6, g: 6 %endmacro +// cost: 6 +%macro dup_fp6_7 + // stack: f: 6, g: 6 + DUP13 + DUP13 + DUP13 + DUP13 + DUP13 + DUP13 + // stack: g: 6, f: 6, g: 6 +%endmacro + // cost: 16 %macro swap_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 @@ -221,6 +233,33 @@ // stack: g0, g1, g2, g3, g4, g5, f0, f1, f2, f3, f4, f5 %endmacro +// cost: 16 +%macro swap_fp6_hole + // stack: f0, f1, f2, f3, f4, f5, X, g0, g1, g2, g3, g4, g5 + SWAP7 + // stack: g0, f1, f2, f3, f4, f5, X, f0, g1, g2, g3, g4, g5 + SWAP1 + SWAP8 + SWAP1 + // stack: g0, g1, f2, f3, f4, f5, X, f0, f1, g2, g3, g4, g5 + SWAP2 + SWAP9 + SWAP2 + // stack: g0, g1, g2, f3, f4, f5, X, f0, f1, f2, g3, g4, g5 + SWAP3 + SWAP10 + SWAP3 + // stack: g0, g1, g2, g3, f4, f5, X, f0, f1, f2, f3, g4, g5 + SWAP4 + SWAP11 + SWAP4 + // stack: g0, g1, g2, g3, g4, f5, X, f0, f1, f2, f3, f4, g5 + SWAP5 + SWAP12 + SWAP5 + // stack: g0, g1, g2, g3, g4, g5, X, f0, f1, f2, f3, f4, f5 +%endmacro + // cost: 16 %macro add_fp6 // stack: f0, f1, f2, f3, f4, f5, g0, g1, g2, g3, g4, g5 From 7d4cec55fba9572df4cb859d4750dcf78022f449 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 16:18:41 -0400 Subject: [PATCH 36/58] fp6 mul --- evm/src/cpu/kernel/aggregator.rs | 5 +- .../asm/fields/{fp12.asm => fp12_mul.asm} | 21 +- .../asm/fields/{fp6.asm => fp6_macros.asm} | 238 ------------------ evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 236 +++++++++++++++++ 4 files changed, 255 insertions(+), 245 deletions(-) rename evm/src/cpu/kernel/asm/fields/{fp12.asm => fp12_mul.asm} (90%) rename evm/src/cpu/kernel/asm/fields/{fp6.asm => fp6_macros.asm} (61%) create mode 100644 evm/src/cpu/kernel/asm/fields/fp6_mul.asm diff --git a/evm/src/cpu/kernel/aggregator.rs b/evm/src/cpu/kernel/aggregator.rs index 17adb07e..5488ab67 100644 --- a/evm/src/cpu/kernel/aggregator.rs +++ b/evm/src/cpu/kernel/aggregator.rs @@ -32,8 +32,9 @@ pub(crate) fn combined_kernel() -> Kernel { include_str!("asm/curve/secp256k1/lift_x.asm"), include_str!("asm/curve/secp256k1/moddiv.asm"), include_str!("asm/exp.asm"), - include_str!("asm/fields/fp6.asm"), - include_str!("asm/fields/fp12.asm"), + include_str!("asm/fields/fp6_macros.asm"), + include_str!("asm/fields/fp6_mul.asm"), + include_str!("asm/fields/fp12_mul.asm"), include_str!("asm/halt.asm"), include_str!("asm/main.asm"), include_str!("asm/memory/core.asm"), diff --git a/evm/src/cpu/kernel/asm/fields/fp12.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm similarity index 90% rename from evm/src/cpu/kernel/asm/fields/fp12.asm rename to evm/src/cpu/kernel/asm/fields/fp12_mul.asm index ff7f064b..6462f2cb 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -1,11 +1,13 @@ global test_mul_Fp12: - // stack: f, f', g, g' + // stack: f, f', g, g', in2, out, in1 %store_fp6(0) %store_fp6(6) %store_fp6(12) %store_fp6(18) + // stack: in2, out, in1 PUSH return_on_stack - // stack: return_on_stack + SWAP3 + // stack: in1, in2, out, return_on_stack %jump(mul_Fp12) return_on_stack: // stack: @@ -14,7 +16,7 @@ return_on_stack: // stack: h, h' %jump(0xdeadbeef) - +/// fp6 macros: /// macro | num | ops | cost /// ------------------------- /// load | 8 | 40 | 320 @@ -25,9 +27,18 @@ return_on_stack: /// sub | 2 | 17 | 34 /// mul | 3 | 156 | 468 /// i9 | 1 | 9 | 9 -/// jump | 1 | 1 | 1 /// -/// TOTAL: 1174 +/// lone stack operations: +/// op | num +/// ------------ +/// ADD | 3 +/// SWAP | 2 +/// DUP | 6 +/// PUSH | 6 +/// POP | 2 +/// JUMP | 1 +/// +/// TOTAL: 1194 /// F = f + f'z diff --git a/evm/src/cpu/kernel/asm/fields/fp6.asm b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm similarity index 61% rename from evm/src/cpu/kernel/asm/fields/fp6.asm rename to evm/src/cpu/kernel/asm/fields/fp6_macros.asm index b6f1950e..be213dc3 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm @@ -314,241 +314,3 @@ SUBFP254 // stack: h0, h1, h2, h3, h4, h5 %endmacro - -// cost: 156 -%macro mul_fp6 - /// C = C0 + C1t + C2t^2 - /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 - /// - /// D = D0 + D1t + D2t^2 - /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 - /// - /// E = E0 + E1t + E2t^2 = CD - /// - /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ - /// final stack: e0, e0_, e1, e1_, e2, e2_ - - /// E0 = C0D0 + i9(C1D2 + C2D1) - /// - /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i - /// - /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i - /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i - /// - /// CDX = C1D2 + C2D1 - /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i - /// - /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i - /// - /// E0 = 9CDX - CDX_ + C0D0 - /// E0_ = 9CDX_ + CDX + C0D0_ - - // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 - DUP12 - DUP4 - MULFP254 - DUP12 - DUP6 - MULFP254 - ADDFP254 - DUP11 - DUP7 - MULFP254 - ADDFP254 - DUP10 - DUP8 - MULFP254 - ADDFP254 - // make C0D0_ = c0d0_ + c0_d0 - DUP9 - DUP3 - MULFP254 - DUP9 - DUP5 - MULFP254 - ADDFP254 - // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP14 - DUP7 - MULFP254 - DUP13 - DUP10 - MULFP254 - ADDFP254 - SUBFP254 - // make C0D0 = c0d0 - c0_d0_ - DUP11 - DUP6 - MULFP254 - DUP11 - DUP6 - MULFP254 - SUBFP254 - - // stack: C0D0 , CDX , C0D0_, CDX_ - DUP4 - DUP3 - // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: E0 = 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ - SWAP15 - SWAP3 - // stack: CDX_ , CDX , C0D0_ - PUSH 9 - MULFP254 - ADDFP254 - ADDFP254 - // stack: E0_ = 9CDX_ + CDX + C0D0_ - SWAP9 - - /// E1 = C0D1 + C1D0 + i9(C2D2) - /// - /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i - /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i - /// - /// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) - /// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 - /// - /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i - /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i - /// - /// E1 = 9C2D2 - C2D2_ + CD01 - /// E1_ = C2D2 + 9C2D2_ + CD01_ - - // make C2D2_ = c2d2_ + c2_d2 - DUP13 - DUP9 - MULFP254 - DUP3 - DUP9 - MULFP254 - ADDFP254 - // make C2D2 = c2d2 - c2_d2_ - DUP3 - DUP10 - MULFP254 - DUP15 - DUP10 - MULFP254 - SUBFP254 - // make C0D0 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) - DUP3 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - SUBFP254 - // stack: C0D0, C2D2, C2D2_ - DUP3 - DUP3 - // stack: C2D2 , C2D2_ , C0D0, C2D2, C2D2_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: E1 = 9C2D2 - C2D2_ + C0D0, C2D2, C2D2_ - SWAP13 - SWAP2 - // stack: C2D2_, C2D2 - PUSH 9 - MULFP254 - ADDFP254 - // stack: 9C2D2_ + C2D2 - // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 - DUP11 - DUP9 - MULFP254 - DUP4 - DUP9 - MULFP254 - ADDFP254 - DUP3 - DUP8 - MULFP254 - ADDFP254 - DUP15 - DUP7 - MULFP254 - ADDFP254 - // stack: CD01_ , 9C2D2_ + C2D2 - ADDFP254 - // stack: E1_ = CD01_ + 9C2D2_ + C2D2 - SWAP13 - - /// E2 = C0D2 + C1D1 + C2D0 - /// - /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i - /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i - /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i - /// - /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) - /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - - // make c0_d2_ + c1_d1_ + c2_d0_ - DUP3 - DUP11 - MULFP254 - DUP2 - DUP10 - MULFP254 - ADDFP254 - DUP5 - DUP8 - MULFP254 - ADDFP254 - // make c0d2 + c1d1 + c2d0 - DUP16 - DUP7 - MULFP254 - DUP4 - DUP10 - MULFP254 - ADDFP254 - DUP13 - DUP12 - MULFP254 - ADDFP254 - // stack: c0d2 + c1d1 + c2d0 , c0_d2_ + c1_d1_ + c2_d0_ - SUBFP254 - // stack: E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) - SWAP15 - // make c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - SWAP7 - MULFP254 - SWAP7 - MULFP254 - SWAP7 - MULFP254 - SWAP2 - MULFP254 - ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - ADDFP254 - ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - // stack: E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - SWAP5 -%endmacro diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm new file mode 100644 index 00000000..d4d92689 --- /dev/null +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -0,0 +1,236 @@ +// cost: 156 +global mul_fp6: + /// C = C0 + C1t + C2t^2 + /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 + /// + /// D = D0 + D1t + D2t^2 + /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 + /// + /// E = E0 + E1t + E2t^2 = CD + /// + /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ + /// final stack: e0, e0_, e1, e1_, e2, e2_ + + /// E0 = C0D0 + i9(C1D2 + C2D1) + /// + /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i + /// + /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i + /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i + /// + /// CDX = C1D2 + C2D1 + /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i + /// + /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i + /// + /// E0 = 9CDX - CDX_ + C0D0 + /// E0_ = 9CDX_ + CDX + C0D0_ + + // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 + DUP12 + DUP4 + MULFP254 + DUP12 + DUP6 + MULFP254 + ADDFP254 + DUP11 + DUP7 + MULFP254 + ADDFP254 + DUP10 + DUP8 + MULFP254 + ADDFP254 + // make C0D0_ = c0d0_ + c0_d0 + DUP9 + DUP3 + MULFP254 + DUP9 + DUP5 + MULFP254 + ADDFP254 + // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP14 + DUP7 + MULFP254 + DUP13 + DUP10 + MULFP254 + ADDFP254 + SUBFP254 + // make C0D0 = c0d0 - c0_d0_ + DUP11 + DUP6 + MULFP254 + DUP11 + DUP6 + MULFP254 + SUBFP254 + + // stack: C0D0 , CDX , C0D0_, CDX_ + DUP4 + DUP3 + // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: E0 = 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ + SWAP15 + SWAP3 + // stack: CDX_ , CDX , C0D0_ + PUSH 9 + MULFP254 + ADDFP254 + ADDFP254 + // stack: E0_ = 9CDX_ + CDX + C0D0_ + SWAP9 + + /// E1 = C0D1 + C1D0 + i9(C2D2) + /// + /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i + /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i + /// + /// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) + /// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 + /// + /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i + /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i + /// + /// E1 = 9C2D2 - C2D2_ + CD01 + /// E1_ = C2D2 + 9C2D2_ + CD01_ + + // make C2D2_ = c2d2_ + c2_d2 + DUP13 + DUP9 + MULFP254 + DUP3 + DUP9 + MULFP254 + ADDFP254 + // make C2D2 = c2d2 - c2_d2_ + DUP3 + DUP10 + MULFP254 + DUP15 + DUP10 + MULFP254 + SUBFP254 + // make C0D0 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) + DUP3 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + DUP12 + DUP9 + MULFP254 + DUP15 + DUP8 + MULFP254 + ADDFP254 + SUBFP254 + // stack: C0D0, C2D2, C2D2_ + DUP3 + DUP3 + // stack: C2D2 , C2D2_ , C0D0, C2D2, C2D2_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: E1 = 9C2D2 - C2D2_ + C0D0, C2D2, C2D2_ + SWAP13 + SWAP2 + // stack: C2D2_, C2D2 + PUSH 9 + MULFP254 + ADDFP254 + // stack: 9C2D2_ + C2D2 + // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 + DUP11 + DUP9 + MULFP254 + DUP4 + DUP9 + MULFP254 + ADDFP254 + DUP3 + DUP8 + MULFP254 + ADDFP254 + DUP15 + DUP7 + MULFP254 + ADDFP254 + // stack: CD01_ , 9C2D2_ + C2D2 + ADDFP254 + // stack: E1_ = CD01_ + 9C2D2_ + C2D2 + SWAP13 + + /// E2 = C0D2 + C1D1 + C2D0 + /// + /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i + /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i + /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i + /// + /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) + /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + + // make c0_d2_ + c1_d1_ + c2_d0_ + DUP3 + DUP11 + MULFP254 + DUP2 + DUP10 + MULFP254 + ADDFP254 + DUP5 + DUP8 + MULFP254 + ADDFP254 + // make c0d2 + c1d1 + c2d0 + DUP16 + DUP7 + MULFP254 + DUP4 + DUP10 + MULFP254 + ADDFP254 + DUP13 + DUP12 + MULFP254 + ADDFP254 + // stack: c0d2 + c1d1 + c2d0 , c0_d2_ + c1_d1_ + c2_d0_ + SUBFP254 + // stack: E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) + SWAP15 + // make c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + SWAP7 + MULFP254 + SWAP7 + MULFP254 + SWAP7 + MULFP254 + SWAP2 + MULFP254 + ADDFP254 + SWAP2 + MULFP254 + ADDFP254 + ADDFP254 + ADDFP254 + SWAP2 + MULFP254 + ADDFP254 + // stack: E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + SWAP5 From 1c2fab6718a229e49cb6086cb158c8f5943b883e Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 16:48:31 -0400 Subject: [PATCH 37/58] richer comments --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 93 ++++++++++---------- evm/src/cpu/kernel/asm/fields/fp6_macros.asm | 2 +- 2 files changed, 49 insertions(+), 46 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 6462f2cb..2ff6a197 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -1,18 +1,21 @@ global test_mul_Fp12: - // stack: f, f', g, g', in2, out, in1 - %store_fp6(0) - %store_fp6(6) - %store_fp6(12) - %store_fp6(18) - // stack: in2, out, in1 + // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out + %store_fp6 + %store_fp6 + %store_fp6 + %store_fp6 + // stack: in1, out, in0, out PUSH return_on_stack SWAP3 - // stack: in1, in2, out, return_on_stack + // stack: in0, in1, out, return_on_stack, out %jump(mul_Fp12) return_on_stack: - // stack: - %load_fp6(30) - %load_fp6(24) + // stack: out + DUP1 + %add_const(6) + // stack: out', out + %load_fp6 + %load_fp6 // stack: h, h' %jump(0xdeadbeef) @@ -52,84 +55,84 @@ return_on_stack: /// Note: f, f', g, g' consist of six terms on the stack global mul_Fp12: - // stack: in1, in2, out + // stack: in0, in1, out DUP1 %add_const(6) %load_fp6 - // stack: f', in1, in2, out + // stack: f', in0, in1, out DUP7 %add_const(6) %load_fp6 - // stack: g', f', in1, in2, out + // stack: g', f', in0, in1, out PUSH post_mul_1 %dup_fp6_7 - // stack: f', post_mul_1, g', f', in1, in2, out + // stack: f', post_mul_1, g', f', in0, in1, out %dup_fp6_7 - // stack: g', f', post_mul_1, g', f', in1, in2, out + // stack: g', f', post_mul_1, g', f', in0, in1, out %jump(mul_fp6) post_mul_1: - // stack: f'g', g' , f', in1, in2, out + // stack: f'g', g' , f', in0, in1, out %dup_fp6_0 - // stack: f'g', f'g', g' , f', in1, in2, out - %store_fp6_sh(36) - // stack: f'g', g' , f', in1, in2, out + // stack: f'g', f'g', g' , f', in0, in1, out + %store_fp6_sh(36) + // stack: f'g', g' , f', in0, in1, out {36: sh(f'g')} %store_fp6(42) - // stack: g' , f', in1, in2, out + // stack: g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} DUP13 - // stack: in1, g' , f', in1, in2, out + // stack: in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} DUP15 %load_fp6 - // stack: g , in1, g' , f', in1, in2, out + // stack: g , in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %swap_fp6_hole - // stack: g', in1, g , f', in1, in2, out + // stack: g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} dup_fp6_7 - // stack: g,g', in1, g , f', in1, in2, out + // stack: g,g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %add_fp6 - // stack: g+g', in1, g , f', in1, in2, out + // stack: g+g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %swap_fp6_hole - // stack: g, in1, g+g', f', in1, in2, out + // stack: g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} PUSH post_mul_2 SWAP7 %load_fp6 - // stack: f, g, post_mul_2, g+g', f', in1, in2, out + // stack: f, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} %jump(mul_fp6) post_mul_2: - // stack: fg, g+g', f', in1, in2, out + // stack: fg, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} %store_fp6(48) - // stack: g+g', f', in1, in2, out + // stack: g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %swap_fp6 - // stack: f', g+g', in1, in2, out + // stack: f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} PUSH post_mul_3 SWAP13 %load_fp6 - // stack: f,f', g+g', post_mul_3, in2, out + // stack: f,f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %add_fp6 - // stack: f+f', g+g', post_mul_3, in2, out + // stack: f+f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %jump(mul_fp6) post_mul_3: - // stack: (f+f')(g+g'), in2, out - %load_fp6(42) - // stack: f'g', (f+f')(g+g'), in2, out - %subr_fp6 - // stack: (f+f')(g+g') - f'g', in2, out + // stack: (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6(48) - // stack: fg, (f+f')(g+g') - f'g', in2, out + // stack: fg, (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} %swap_fp6 - // stack: (f+f')(g+g') - f'g', fg, in2, out + // stack: (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %dup_fp6_6 - // stack: fg, (f+f')(g+g') - f'g', fg, in2, out + // stack: fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + %load_fp6(42) + // stack: f'g',fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + %add_fp6 + // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %subr_fp6 - // stack: (f+f')(g+g') - f'g' - fg, fg, in2, out + // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} DUP14 add_const(6) %store_fp6 - // stack: fg, in2, out + // stack: fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6(36) - // stack: sh(f'g') , fg, in2, out + // stack: sh(f'g') , fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %add_fp6 - // stack: sh(f'g') + fg, in2, out + // stack: sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} DUP8 %store_fp6 - // stack: in2, out + // stack: in1, out {36: sh(f'g'), 42: f'g', 48: fg} %pop2 JUMP diff --git a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm index be213dc3..70cc0e64 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm @@ -152,7 +152,7 @@ // stack: %endmacro -// cost: 9; note this returns y, x for x + yi +// cost: 9; note this returns y, x for the output x + yi %macro i9 // stack: a , b DUP2 From 3ccafd88d9fed2eccf7e70b6c31d6f4416dd3811 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 17:30:23 -0400 Subject: [PATCH 38/58] richer comments --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 83 ++++++++++++---------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 2ff6a197..6866a5f9 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -26,8 +26,8 @@ return_on_stack: /// store | 5 | 40 | 200 /// dup | 5 | 6 | 30 /// swap | 4 | 16 | 64 -/// add | 3 | 16 | 48 -/// sub | 2 | 17 | 34 +/// add | 4 | 16 | 64 +/// sub | 1 | 17 | 17 /// mul | 3 | 156 | 468 /// i9 | 1 | 9 | 9 /// @@ -41,7 +41,7 @@ return_on_stack: /// POP | 2 /// JUMP | 1 /// -/// TOTAL: 1194 +/// TOTAL: 1193 /// F = f + f'z @@ -56,83 +56,90 @@ return_on_stack: global mul_Fp12: // stack: in0, in1, out - DUP1 - %add_const(6) + DUP1 %add_const(6) + // stack: in0', in0, in1, out %load_fp6 // stack: f', in0, in1, out - DUP7 - %add_const(6) + DUP7 %add_const(6) + // stack: in1', f', in0, in1, out %load_fp6 // stack: g', f', in0, in1, out PUSH post_mul_1 + // stack: post_mul_1, g', f', in0, in1, out %dup_fp6_7 // stack: f', post_mul_1, g', f', in0, in1, out %dup_fp6_7 // stack: g', f', post_mul_1, g', f', in0, in1, out %jump(mul_fp6) post_mul_1: - // stack: f'g', g' , f', in0, in1, out + // stack: f'g', g' , f', in0, in1, out %dup_fp6_0 - // stack: f'g', f'g', g' , f', in0, in1, out + // stack: f'g', f'g', g' , f', in0, in1, out %store_fp6_sh(36) - // stack: f'g', g' , f', in0, in1, out {36: sh(f'g')} + // stack: f'g', g' , f', in0, in1, out {36: sh(f'g')} %store_fp6(42) - // stack: g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} DUP13 - // stack: in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} DUP15 + // stack: in1, in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %load_fp6 - // stack: g , in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g , in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %swap_fp6_hole - // stack: g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} dup_fp6_7 - // stack: g,g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g,g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %add_fp6 - // stack: g+g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g+g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %swap_fp6_hole - // stack: g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} PUSH post_mul_2 + // stack: post_mul_2, g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} SWAP7 + // stack: in0, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} %load_fp6 - // stack: f, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: f, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} %jump(mul_fp6) post_mul_2: - // stack: fg, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: fg, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} %store_fp6(48) - // stack: g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %swap_fp6 - // stack: f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} PUSH post_mul_3 - SWAP13 + // stack: post_mul_3, f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + SWAP13 + // stack: in0, f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6 - // stack: f,f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f,f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %add_fp6 - // stack: f+f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f+f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %jump(mul_fp6) post_mul_3: - // stack: (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6(48) - // stack: fg, (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: fg, (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} %swap_fp6 - // stack: (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %dup_fp6_6 - // stack: fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6(42) - // stack: f'g',fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f'g',fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %add_fp6 - // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %subr_fp6 - // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - DUP14 - add_const(6) + // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + DUP14 add_const(6) + // stack: out', (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %store_fp6 - // stack: fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %load_fp6(36) - // stack: sh(f'g') , fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: sh(f'g') , fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %add_fp6 - // stack: sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - DUP8 + // stack: sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + DUP8 + // stack: out, sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %store_fp6 - // stack: in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: in1, out {36: sh(f'g'), 42: f'g', 48: fg} %pop2 JUMP From 06e0dd643b36922a892a9483cfa35ca745b0584d Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Thu, 20 Oct 2022 17:35:43 -0400 Subject: [PATCH 39/58] fp6 as fn --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 5 ++++- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 6866a5f9..cc6ba5bd 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -1,3 +1,5 @@ +/// Note: uncomment this to test + global test_mul_Fp12: // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out %store_fp6 @@ -19,6 +21,7 @@ return_on_stack: // stack: h, h' %jump(0xdeadbeef) + /// fp6 macros: /// macro | num | ops | cost /// ------------------------- @@ -27,7 +30,7 @@ return_on_stack: /// dup | 5 | 6 | 30 /// swap | 4 | 16 | 64 /// add | 4 | 16 | 64 -/// sub | 1 | 17 | 17 +/// subr | 1 | 17 | 17 /// mul | 3 | 156 | 468 /// i9 | 1 | 9 | 9 /// diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index d4d92689..3ee0d600 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -84,7 +84,7 @@ global mul_fp6: SUBFP254 ADDFP254 // stack: E0 = 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ - SWAP15 + SWAP10 SWAP3 // stack: CDX_ , CDX , C0D0_ PUSH 9 @@ -234,3 +234,5 @@ global mul_fp6: ADDFP254 // stack: E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 SWAP5 + // stack: jumpdest, E0, E0_, E1, E1_, E2, E2_ + JUMP From 2d7f3e739b4c964512a3e9289bbd6d1e99984edc Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 09:53:16 -0400 Subject: [PATCH 40/58] new fp6 --- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 333 +++++++++++----------- 1 file changed, 169 insertions(+), 164 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 3ee0d600..3560a15f 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -25,75 +25,7 @@ global mul_fp6: /// /// E0 = 9CDX - CDX_ + C0D0 /// E0_ = 9CDX_ + CDX + C0D0_ - - // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 - DUP12 - DUP4 - MULFP254 - DUP12 - DUP6 - MULFP254 - ADDFP254 - DUP11 - DUP7 - MULFP254 - ADDFP254 - DUP10 - DUP8 - MULFP254 - ADDFP254 - // make C0D0_ = c0d0_ + c0_d0 - DUP9 - DUP3 - MULFP254 - DUP9 - DUP5 - MULFP254 - ADDFP254 - // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP14 - DUP7 - MULFP254 - DUP13 - DUP10 - MULFP254 - ADDFP254 - SUBFP254 - // make C0D0 = c0d0 - c0_d0_ - DUP11 - DUP6 - MULFP254 - DUP11 - DUP6 - MULFP254 - SUBFP254 - - // stack: C0D0 , CDX , C0D0_, CDX_ - DUP4 - DUP3 - // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: E0 = 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ - SWAP10 - SWAP3 - // stack: CDX_ , CDX , C0D0_ - PUSH 9 - MULFP254 - ADDFP254 - ADDFP254 - // stack: E0_ = 9CDX_ + CDX + C0D0_ - SWAP9 - + /// /// E1 = C0D1 + C1D0 + i9(C2D2) /// /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i @@ -107,76 +39,7 @@ global mul_fp6: /// /// E1 = 9C2D2 - C2D2_ + CD01 /// E1_ = C2D2 + 9C2D2_ + CD01_ - - // make C2D2_ = c2d2_ + c2_d2 - DUP13 - DUP9 - MULFP254 - DUP3 - DUP9 - MULFP254 - ADDFP254 - // make C2D2 = c2d2 - c2_d2_ - DUP3 - DUP10 - MULFP254 - DUP15 - DUP10 - MULFP254 - SUBFP254 - // make C0D0 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) - DUP3 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - DUP12 - DUP9 - MULFP254 - DUP15 - DUP8 - MULFP254 - ADDFP254 - SUBFP254 - // stack: C0D0, C2D2, C2D2_ - DUP3 - DUP3 - // stack: C2D2 , C2D2_ , C0D0, C2D2, C2D2_ - PUSH 9 - MULFP254 - SUBFP254 - ADDFP254 - // stack: E1 = 9C2D2 - C2D2_ + C0D0, C2D2, C2D2_ - SWAP13 - SWAP2 - // stack: C2D2_, C2D2 - PUSH 9 - MULFP254 - ADDFP254 - // stack: 9C2D2_ + C2D2 - // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 - DUP11 - DUP9 - MULFP254 - DUP4 - DUP9 - MULFP254 - ADDFP254 - DUP3 - DUP8 - MULFP254 - ADDFP254 - DUP15 - DUP7 - MULFP254 - ADDFP254 - // stack: CD01_ , 9C2D2_ + C2D2 - ADDFP254 - // stack: E1_ = CD01_ + 9C2D2_ + C2D2 - SWAP13 - + /// /// E2 = C0D2 + C1D1 + C2D0 /// /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i @@ -186,53 +49,195 @@ global mul_fp6: /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + // E2 // make c0_d2_ + c1_d1_ + c2_d0_ - DUP3 - DUP11 + DUP8 + DUP7 MULFP254 - DUP2 - DUP10 + DUP11 + DUP6 MULFP254 ADDFP254 - DUP5 + DUP13 + DUP4 + MULFP254 + ADDFP254 + // make c0d2 + c1d1 + c2d0 + DUP12 + DUP3 + MULFP254 + DUP11 + DUP6 + MULFP254 + ADDFP254 + DUP9 DUP8 MULFP254 ADDFP254 - // make c0d2 + c1d1 + c2d0 - DUP16 + // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ + SUBFP254 + SWAP12 + // E0, E0_ + // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 + DUP1 + DUP5 + MULFP254 + DUP13 DUP7 MULFP254 + ADDFP254 + DUP12 + DUP8 + MULFP254 + ADDFP254 + DUP11 + DUP9 + MULFP254 + ADDFP254 + // make C0D0_ = c0d0_ + c0_d0 + DUP10 + DUP4 + MULFP254 + DUP10 + DUP6 + MULFP254 + ADDFP254 + // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + DUP13 + DUP10 + MULFP254 + DUP4 + DUP9 + MULFP254 + ADDFP254 + DUP15 + DUP8 + MULFP254 + DUP14 + DUP11 + MULFP254 + ADDFP254 + SUBFP254 + // make C0D0 = c0d0 - c0_d0_ + DUP12 + DUP7 + MULFP254 + DUP12 + DUP7 + MULFP254 + SUBFP254 + // stack: C0D0 , CDX , C0D0_, CDX_ + DUP4 + DUP3 + // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ + SWAP12 + SWAP3 + // stack: CDX_ , CDX , C0D0_ + PUSH 9 + MULFP254 + ADDFP254 + ADDFP254 + // stack: 9CDX_ + CDX + C0D0_ + SWAP11 + // E1, E1_ + // make C2D2_ = c2d2_ + c2_d2 + DUP14 + DUP10 + MULFP254 DUP4 DUP10 MULFP254 ADDFP254 - DUP13 - DUP12 + // make C2D2 = c2d2 - c2_d2_ + DUP4 + DUP11 + MULFP254 + DUP16 + DUP11 MULFP254 - ADDFP254 - // stack: c0d2 + c1d1 + c2d0 , c0_d2_ + c1_d1_ + c2_d0_ SUBFP254 - // stack: E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) + // make CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) + DUP4 + DUP10 + MULFP254 + DUP16 + DUP9 + MULFP254 + ADDFP254 + DUP13 + DUP10 + MULFP254 + DUP5 + DUP9 + MULFP254 + ADDFP254 + SUBFP254 + // stack: CD01, C2D2, C2D2_ + DUP3 + DUP3 + // stack: C2D2 , C2D2_ , CD01, C2D2, C2D2_ + PUSH 9 + MULFP254 + SUBFP254 + ADDFP254 + // stack: E1 = 9C2D2 - C2D2_ + CD01, C2D2, C2D2_ SWAP15 - // make c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + SWAP2 + // stack: C2D2_ , C2D2 + PUSH 9 + MULFP254 + ADDFP254 + // stack: 9C2D2_ + C2D2 + // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 + DUP12 + DUP10 + MULFP254 + DUP5 + DUP10 + MULFP254 + ADDFP254 + DUP4 + DUP9 + MULFP254 + ADDFP254 + DUP3 + DUP8 + MULFP254 + ADDFP254 + // stack: CD01_ , 9C2D2_ + C2D2 + ADDFP254 + // stack: E1_ = CD01_ + 9C2D2_ + C2D2 + SWAP15 + // E2_ + // stack: d2, d1_, d1, d0_, d2_, c0, c0_, c1, c1_, c2, c2_, d0 SWAP7 MULFP254 + // stack: c1d1_, d1, d0_, d2_, c0, c0_, d2, c1_, c2, c2_, d0 SWAP7 MULFP254 + // stack: c1_d1, d0_, d2_, c0, c0_, d2, c1d1_, c2, c2_, d0 SWAP7 MULFP254 + // stack: c2d0_, d2_, c0, c0_, d2, c1d1_, c1_d1, c2_, d0 + SWAP2 + MULFP254 + // stack: c0d2_, c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + ADDFP254 + // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + SWAP2 + MULFP254 + // stack: c0_d2, c0d2_ + c2d0_, c1d1_, c1_d1, c2_, d0 + ADDFP254 + ADDFP254 + ADDFP254 + // stack: c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1, c2_, d0 SWAP2 MULFP254 ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - ADDFP254 - ADDFP254 - SWAP2 - MULFP254 - ADDFP254 - // stack: E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - SWAP5 - // stack: jumpdest, E0, E0_, E1, E1_, E2, E2_ - JUMP + SWAP6 + JUMP \ No newline at end of file From 32f1e679849c911e53943720f5a84a387d574c0a Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 13:16:07 -0400 Subject: [PATCH 41/58] fp6 test passes --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 4 +- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 12 ++--- evm/src/cpu/kernel/tests/fields.rs | 51 +++++++++++++++++++--- 3 files changed, 53 insertions(+), 14 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index cc6ba5bd..25745bbf 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -90,7 +90,7 @@ post_mul_1: // stack: g , in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %swap_fp6_hole // stack: g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} - dup_fp6_7 + %dup_fp6_7 // stack: g,g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} %add_fp6 // stack: g+g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} @@ -132,7 +132,7 @@ post_mul_3: // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %subr_fp6 // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - DUP14 add_const(6) + DUP14 %add_const(6) // stack: out', (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} %store_fp6 // stack: fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 3560a15f..879a63f9 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -1,5 +1,8 @@ // cost: 156 global mul_fp6: + /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest + /// final stack: e0, e0_, e1, e1_, e2, e2_ + /// C = C0 + C1t + C2t^2 /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 /// @@ -7,10 +10,7 @@ global mul_fp6: /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 /// /// E = E0 + E1t + E2t^2 = CD - /// - /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_ - /// final stack: e0, e0_, e1, e1_, e2, e2_ - + /// E0 = C0D0 + i9(C1D2 + C2D1) /// /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i @@ -77,6 +77,7 @@ global mul_fp6: // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ SUBFP254 SWAP12 + // E0, E0_ // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 DUP1 @@ -144,6 +145,7 @@ global mul_fp6: ADDFP254 // stack: 9CDX_ + CDX + C0D0_ SWAP11 + // E1, E1_ // make C2D2_ = c2d2_ + c2_d2 DUP14 @@ -240,4 +242,4 @@ global mul_fp6: MULFP254 ADDFP254 SWAP6 - JUMP \ No newline at end of file + JUMP diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 31f2dde5..762e321c 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -1,6 +1,7 @@ use anyhow::Result; use ethereum_types::U256; use rand::{thread_rng, Rng}; +use std::str::FromStr; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; @@ -123,25 +124,61 @@ fn gen_fp6() -> [[u32; 2]; 3] { } fn as_stack(xs: Vec) -> Vec { - xs.iter().map(|&x| U256::from(x) % P254).rev().collect() + xs.iter().map(|&x| U256::from(x)).rev().collect() } +// fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g1: [[u32; 2]; 3]) -> Vec { +// let f0: Vec = f0.into_iter().flatten().collect(); +// let f1: Vec = f1.into_iter().flatten().collect(); +// let g0: Vec = g0.into_iter().flatten().collect(); +// let g1: Vec = g1.into_iter().flatten().collect(); + +// // let mut input: Vec = vec![0]; + +// // vec![vec![0], f0, vec![6], f1, vec![12], g0, vec![18], g1, vec![12,24,0,24]] +// // let input: Vec = [vec![[0]], f0, [[6]], f1, [[12]], g0, [[18]], g1, [[12, 24, 0, 24]]].into_iter().flatten().flatten().flatten().collect(); +// as_stack(input) +// } + #[test] -fn test_fp12() -> Result<()> { - let f = [gen_fp6(), gen_fp6()]; - let g = [gen_fp6(), gen_fp6()]; - let input: Vec = [f, g].into_iter().flatten().flatten().flatten().collect(); - let output: Vec = mul_fp12(f, g).into_iter().flatten().flatten().collect(); +fn test_fp6() -> Result<()> { + let c = gen_fp6(); + let d = gen_fp6(); + + let mut input: Vec = [c, d].into_iter().flatten().flatten().collect(); + input.push(0xdeadbeef); let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["test_mul_Fp12"]; + let initial_offset = kernel.global_labels["mul_fp6"]; let initial_stack: Vec = as_stack(input); let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); + let output: Vec = mul_fp6(c, d).into_iter().flatten().collect(); let expected = as_stack(output); + assert_eq!(final_stack, expected); Ok(()) } +// fn test_fp12() -> Result<()> { +// let f0 = gen_fp6(); +// let f1 = gen_fp6(); +// let g0 = gen_fp6(); +// let g1 = gen_fp6(); + +// let output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); + +// let kernel = combined_kernel(); +// let initial_offset = kernel.global_labels["test_mul_Fp12"]; +// let initial_stack: Vec = make_initial_stack(f0,f1,g0,g1); +// let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? +// .stack() +// .to_vec(); + +// let expected = as_stack(output); +// assert_eq!(final_stack, expected); + +// Ok(()) +// } From 9a001487b4955422ae024515069e1ed969721517 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 13:28:12 -0400 Subject: [PATCH 42/58] better comments --- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 25 ++++++++++++----------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 879a63f9..65f8aad3 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -18,13 +18,13 @@ global mul_fp6: /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i /// - /// CDX = C1D2 + C2D1 + /// CD12 = C1D2 + C2D1 /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i /// - /// i9(CDX) = (9CDX - CDX_) + (CDX + 9CDX_)i + /// i9(CD12) = (9CD12 - CD12_) + (CD12 + 9CD12_)i /// - /// E0 = 9CDX - CDX_ + C0D0 - /// E0_ = 9CDX_ + CDX + C0D0_ + /// E0 = 9CD12 - CD12_ + C0D0 + /// E0_ = 9CD12_ + CD12 + C0D0_ /// /// E1 = C0D1 + C1D0 + i9(C2D2) /// @@ -79,7 +79,7 @@ global mul_fp6: SWAP12 // E0, E0_ - // make CDX_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 + // make CD12_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 DUP1 DUP5 MULFP254 @@ -103,7 +103,7 @@ global mul_fp6: DUP6 MULFP254 ADDFP254 - // make CDX = c1d2 + c2d1 - c1_d2_ - c2_d1_ + // make CD12 = c1d2 + c2d1 - c1_d2_ - c2_d1_ DUP13 DUP10 MULFP254 @@ -127,23 +127,23 @@ global mul_fp6: DUP7 MULFP254 SUBFP254 - // stack: C0D0 , CDX , C0D0_, CDX_ + // stack: C0D0 , CD12 , C0D0_, CD12_ DUP4 DUP3 - // stack: CDX , CDX_ , C0D0 , CDX , C0D0_, CDX_ + // stack: CD12 , CD12_ , C0D0 , CD12 , C0D0_, CD12_ PUSH 9 MULFP254 SUBFP254 ADDFP254 - // stack: 9CDX - CDX_ + C0D0 , CDX , C0D0_, CDX_ + // stack: 9CD12 - CD12_ + C0D0 , CD12 , C0D0_, CD12_ SWAP12 SWAP3 - // stack: CDX_ , CDX , C0D0_ + // stack: CD12_ , CD12 , C0D0_ PUSH 9 MULFP254 ADDFP254 ADDFP254 - // stack: 9CDX_ + CDX + C0D0_ + // stack: 9CD12_ + CD12 + C0D0_ SWAP11 // E1, E1_ @@ -194,7 +194,7 @@ global mul_fp6: PUSH 9 MULFP254 ADDFP254 - // stack: 9C2D2_ + C2D2 + // stack: 9C2D2_ + C2D2 // make CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 DUP12 DUP10 @@ -215,6 +215,7 @@ global mul_fp6: ADDFP254 // stack: E1_ = CD01_ + 9C2D2_ + C2D2 SWAP15 + // E2_ // stack: d2, d1_, d1, d0_, d2_, c0, c0_, c1, c1_, c2, c2_, d0 SWAP7 From a424916e9d4b46890ddff7ebf5e66f16997c446f Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 13:44:01 -0400 Subject: [PATCH 43/58] cleanup comments --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 116 ++++++++++----------- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 17 +-- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 25745bbf..df52c8b6 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -12,13 +12,13 @@ global test_mul_Fp12: // stack: in0, in1, out, return_on_stack, out %jump(mul_Fp12) return_on_stack: - // stack: out + // stack: out DUP1 %add_const(6) // stack: out', out %load_fp6 %load_fp6 - // stack: h, h' + // stack: h, h' %jump(0xdeadbeef) @@ -31,7 +31,7 @@ return_on_stack: /// swap | 4 | 16 | 64 /// add | 4 | 16 | 64 /// subr | 1 | 17 | 17 -/// mul | 3 | 156 | 468 +/// mul | 3 | 157 | 471 /// i9 | 1 | 9 | 9 /// /// lone stack operations: @@ -44,7 +44,7 @@ return_on_stack: /// POP | 2 /// JUMP | 1 /// -/// TOTAL: 1193 +/// TOTAL: 1196 /// F = f + f'z @@ -58,91 +58,91 @@ return_on_stack: /// Note: f, f', g, g' consist of six terms on the stack global mul_Fp12: - // stack: in0, in1, out + // stack: in0, in1, out DUP1 %add_const(6) - // stack: in0', in0, in1, out + // stack: in0', in0, in1, out %load_fp6 - // stack: f', in0, in1, out + // stack: f', in0, in1, out DUP7 %add_const(6) - // stack: in1', f', in0, in1, out + // stack: in1', f', in0, in1, out %load_fp6 - // stack: g', f', in0, in1, out - PUSH post_mul_1 - // stack: post_mul_1, g', f', in0, in1, out + // stack: g', f', in0, in1, out + PUSH ret_1 + // stack: ret_1, g', f', in0, in1, out %dup_fp6_7 - // stack: f', post_mul_1, g', f', in0, in1, out + // stack: f', ret_1, g', f', in0, in1, out %dup_fp6_7 - // stack: g', f', post_mul_1, g', f', in0, in1, out + // stack: g', f', ret_1, g', f', in0, in1, out %jump(mul_fp6) -post_mul_1: - // stack: f'g', g' , f', in0, in1, out +ret_1: + // stack: f'g', g' , f', in0, in1, out %dup_fp6_0 - // stack: f'g', f'g', g' , f', in0, in1, out - %store_fp6_sh(36) - // stack: f'g', g' , f', in0, in1, out {36: sh(f'g')} - %store_fp6(42) - // stack: g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: f'g', f'g', g' , f', in0, in1, out + %store_fp6_sh(100) + // stack: f'g', g' , f', in0, in1, out {100: sh(f'g')} + %store_fp6(106) + // stack: g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} DUP13 - // stack: in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} DUP15 - // stack: in1, in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: in1, in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %load_fp6 - // stack: g , in0, g' , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g , in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %swap_fp6_hole - // stack: g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %dup_fp6_7 - // stack: g,g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g,g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %add_fp6 - // stack: g+g', in0, g , f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g+g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %swap_fp6_hole - // stack: g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} - PUSH post_mul_2 - // stack: post_mul_2, g, in0, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + PUSH ret_2 + // stack: ret_2, g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} SWAP7 - // stack: in0, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: in0, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} %load_fp6 - // stack: f, g, post_mul_2, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} + // stack: f, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} %jump(mul_fp6) -post_mul_2: - // stack: fg, g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g'} - %store_fp6(48) - // stack: g+g', f', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} +ret_2: + // stack: fg, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + %store_fp6(112) + // stack: g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %swap_fp6 - // stack: f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - PUSH post_mul_3 - // stack: post_mul_3, f', g+g', in0, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + PUSH ret_3 + // stack: ret_3, f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} SWAP13 - // stack: in0, f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: in0, f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %load_fp6 - // stack: f,f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f,f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %add_fp6 - // stack: f+f', g+g', post_mul_3, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f+f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %jump(mul_fp6) -post_mul_3: - // stack: (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} - %load_fp6(48) - // stack: fg, (f+f')(g+g'), in1, out {36: sh(f'g'), 42: f'g', 48: fg} +ret_3: + // stack: (f+f')(g+g'), in1, out {100: sh(f'g'), 106: f'g', 112: fg} + %load_fp6(112) + // stack: fg, (f+f')(g+g'), in1, out {100: sh(f'g'), 106: f'g', 112: fg} %swap_fp6 - // stack: (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: (f+f')(g+g'), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %dup_fp6_6 - // stack: fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - %load_fp6(42) - // stack: f'g',fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: fg, (f+f')(g+g'), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + %load_fp6(106) + // stack: f'g',fg, (f+f')(g+g'), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %add_fp6 - // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: f'g'+fg, (f+f')(g+g'), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %subr_fp6 - // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: (f+f')(g+g') - (f'g'+fg), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} DUP14 %add_const(6) - // stack: out', (f+f')(g+g') - (f'g'+fg), fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: out', (f+f')(g+g') - (f'g'+fg), fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %store_fp6 - // stack: fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} - %load_fp6(36) - // stack: sh(f'g') , fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + %load_fp6(100) + // stack: sh(f'g') , fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %add_fp6 - // stack: sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: sh(f'g') + fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} DUP8 - // stack: out, sh(f'g') + fg, in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: out, sh(f'g') + fg, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %store_fp6 - // stack: in1, out {36: sh(f'g'), 42: f'g', 48: fg} + // stack: in1, out {100: sh(f'g'), 106: f'g', 112: fg} %pop2 JUMP diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 65f8aad3..cb87b8ea 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -215,32 +215,33 @@ global mul_fp6: ADDFP254 // stack: E1_ = CD01_ + 9C2D2_ + C2D2 SWAP15 - + // E2_ // stack: d2, d1_, d1, d0_, d2_, c0, c0_, c1, c1_, c2, c2_, d0 SWAP7 MULFP254 - // stack: c1d1_, d1, d0_, d2_, c0, c0_, d2, c1_, c2, c2_, d0 + // stack: c1d1_, d1, d0_, d2_, c0, c0_, d2, c1_, c2, c2_, d0 SWAP7 MULFP254 - // stack: c1_d1, d0_, d2_, c0, c0_, d2, c1d1_, c2, c2_, d0 + // stack: c1_d1, d0_, d2_, c0, c0_, d2, c1d1_, c2, c2_, d0 SWAP7 MULFP254 - // stack: c2d0_, d2_, c0, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c2d0_, d2_, c0, c0_, d2, c1d1_, c1_d1, c2_, d0 SWAP2 MULFP254 - // stack: c0d2_, c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c0d2_ , c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 ADDFP254 - // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 SWAP2 MULFP254 - // stack: c0_d2, c0d2_ + c2d0_, c1d1_, c1_d1, c2_, d0 + // stack: c0_d2 , c0d2_ + c2d0_ , c1d1_ , c1_d1 , c2_, d0 ADDFP254 ADDFP254 ADDFP254 - // stack: c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1, c2_, d0 + // stack: c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1, c2_, d0 SWAP2 MULFP254 ADDFP254 + // stack: E2_ = c2_d0 + c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1 SWAP6 JUMP From 058858096120e2989a775f9f4cfa02376030839c Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 14:42:50 -0400 Subject: [PATCH 44/58] fp12 passes tests! --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 11 ++-- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 2 +- evm/src/cpu/kernel/tests/fields.rs | 67 +++++++++++++--------- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index df52c8b6..c7a2b872 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -12,13 +12,16 @@ global test_mul_Fp12: // stack: in0, in1, out, return_on_stack, out %jump(mul_Fp12) return_on_stack: - // stack: out + // stack: out DUP1 %add_const(6) - // stack: out', out + // stack: out', out %load_fp6 + // stack: h', out + DUP7 + // stack: out, h', out %load_fp6 - // stack: h, h' + // stack: h, h', out %jump(0xdeadbeef) @@ -63,7 +66,7 @@ global mul_Fp12: // stack: in0', in0, in1, out %load_fp6 // stack: f', in0, in1, out - DUP7 %add_const(6) + DUP8 %add_const(6) // stack: in1', f', in0, in1, out %load_fp6 // stack: g', f', in0, in1, out diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index cb87b8ea..db1a7bf6 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -1,4 +1,4 @@ -// cost: 156 +// cost: 157 global mul_fp6: /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest /// final stack: e0, e0_, e1, e1_, e2, e2_ diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 762e321c..ced4df3e 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -1,7 +1,6 @@ use anyhow::Result; use ethereum_types::U256; use rand::{thread_rng, Rng}; -use std::str::FromStr; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; @@ -127,18 +126,25 @@ fn as_stack(xs: Vec) -> Vec { xs.iter().map(|&x| U256::from(x)).rev().collect() } -// fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g1: [[u32; 2]; 3]) -> Vec { -// let f0: Vec = f0.into_iter().flatten().collect(); -// let f1: Vec = f1.into_iter().flatten().collect(); -// let g0: Vec = g0.into_iter().flatten().collect(); -// let g1: Vec = g1.into_iter().flatten().collect(); +fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g1: [[u32; 2]; 3]) -> Vec { + // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out + let f0: Vec = f0.into_iter().flatten().collect(); + let f1: Vec = f1.into_iter().flatten().collect(); + let g0: Vec = g0.into_iter().flatten().collect(); + let g1: Vec = g1.into_iter().flatten().collect(); -// // let mut input: Vec = vec![0]; - -// // vec![vec![0], f0, vec![6], f1, vec![12], g0, vec![18], g1, vec![12,24,0,24]] -// // let input: Vec = [vec![[0]], f0, [[6]], f1, [[12]], g0, [[18]], g1, [[12, 24, 0, 24]]].into_iter().flatten().flatten().flatten().collect(); -// as_stack(input) -// } + let mut input = vec![0]; + input.extend(f0); + input.extend(vec![6]); + input.extend(f1); + input.extend(vec![12]); + input.extend(g0); + input.extend(vec![18]); + input.extend(g1); + input.extend(vec![12,24,0,24]); + + as_stack(input) +} #[test] fn test_fp6() -> Result<()> { @@ -162,23 +168,28 @@ fn test_fp6() -> Result<()> { Ok(()) } -// fn test_fp12() -> Result<()> { -// let f0 = gen_fp6(); -// let f1 = gen_fp6(); -// let g0 = gen_fp6(); -// let g1 = gen_fp6(); -// let output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); +#[test] +fn test_fp12() -> Result<()> { + let f0 = gen_fp6(); + let f1 = gen_fp6(); + let g0 = gen_fp6(); + let g1 = gen_fp6(); -// let kernel = combined_kernel(); -// let initial_offset = kernel.global_labels["test_mul_Fp12"]; -// let initial_stack: Vec = make_initial_stack(f0,f1,g0,g1); -// let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? -// .stack() -// .to_vec(); + let mut output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); + output.extend(vec![24]); -// let expected = as_stack(output); -// assert_eq!(final_stack, expected); + let kernel = combined_kernel(); + let initial_offset = kernel.global_labels["test_mul_Fp12"]; + let initial_stack: Vec = make_initial_stack(f0, f1, g0, g1); -// Ok(()) -// } + let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? + .stack() + .to_vec(); + + let expected = as_stack(output); + + assert_eq!(final_stack, expected); + + Ok(()) +} From b3ddccda3320c53c0843d57d3459ce81ee50431e Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 15:46:45 -0400 Subject: [PATCH 45/58] cleanup --- evm/src/cpu/kernel/tests/fields.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index ced4df3e..999690fd 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -176,17 +176,15 @@ fn test_fp12() -> Result<()> { let g0 = gen_fp6(); let g1 = gen_fp6(); - let mut output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); - output.extend(vec![24]); - let kernel = combined_kernel(); let initial_offset = kernel.global_labels["test_mul_Fp12"]; let initial_stack: Vec = make_initial_stack(f0, f1, g0, g1); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? .stack() .to_vec(); + let mut output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); + output.extend(vec![24]); let expected = as_stack(output); assert_eq!(final_stack, expected); From cddc22e996f9dc60d6f853f0e2a5a18ada29fefe Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 16:17:51 -0400 Subject: [PATCH 46/58] better comments --- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 130 +++++++++++----------- 1 file changed, 68 insertions(+), 62 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index db1a7bf6..6ec69192 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -1,55 +1,58 @@ +/// C = C0 + C1t + C2t^2 +/// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 +/// +/// D = D0 + D1t + D2t^2 +/// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 +/// +/// E = e0 + e1t + e2t^2 = CD +/// +/// +/// e0 = C0D0 + i9(C1D2 + C2D1) +/// +/// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i +/// +/// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i +/// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i +/// +/// CD12 = C1D2 + C2D1 +/// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i +/// +/// i9(CD12) = (9CD12 - CD12_) + (CD12 + 9CD12_)i +/// +/// e0 = 9CD12 - CD12_ + C0D0 +/// e0_ = 9CD12_ + CD12 + C0D0_ +/// +/// +/// e1 = C0D1 + C1D0 + i9(C2D2) +/// +/// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i +/// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i +/// +/// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) +/// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 +/// +/// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i +/// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i +/// +/// e1 = 9C2D2 - C2D2_ + CD01 +/// e1_ = C2D2 + 9C2D2_ + CD01_ +/// +/// +/// e2 = C0D2 + C1D1 + C2D0 +/// +/// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i +/// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i +/// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i +/// +/// e2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) +/// e2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 + +/// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest +/// final stack: e0, e0_, e1, e1_, e2, e2_ + // cost: 157 global mul_fp6: - /// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest - /// final stack: e0, e0_, e1, e1_, e2, e2_ - - /// C = C0 + C1t + C2t^2 - /// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 - /// - /// D = D0 + D1t + D2t^2 - /// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 - /// - /// E = E0 + E1t + E2t^2 = CD - - /// E0 = C0D0 + i9(C1D2 + C2D1) - /// - /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i - /// - /// C1D2 = (c1d2 - c1_d2_) + (c1d2_ + c1_d2)i - /// C2D1 = (c2d1 - c2_d1_) + (c2d1_ + c2_d1)i - /// - /// CD12 = C1D2 + C2D1 - /// = (c1d2 + c2d1 - c1_d2_ - c2_d1_) + (c1d2_ + c1_d2 + c2d1_ + c2_d1)i - /// - /// i9(CD12) = (9CD12 - CD12_) + (CD12 + 9CD12_)i - /// - /// E0 = 9CD12 - CD12_ + C0D0 - /// E0_ = 9CD12_ + CD12 + C0D0_ - /// - /// E1 = C0D1 + C1D0 + i9(C2D2) - /// - /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i - /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i - /// - /// CD01 = c0d1 + c1d0 - (c0_d1_ + c1_d0_) - /// CD01_ = c0d1_ + c0_d1 + c1d0_ + c1_d0 - /// - /// C2D2 = (c2d2 - c2_d2_) + (c2d2_ + c2_d2)i - /// i9(C2D2) = (9C2D2 - C2D2_) + (C2D2 + 9C2D2_)i - /// - /// E1 = 9C2D2 - C2D2_ + CD01 - /// E1_ = C2D2 + 9C2D2_ + CD01_ - /// - /// E2 = C0D2 + C1D1 + C2D0 - /// - /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i - /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i - /// C2D0 = (c2d0 - c2_d0_) + (c2d0_ + c2_d0)i - /// - /// E2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) - /// E2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 - - // E2 + // e2 // make c0_d2_ + c1_d1_ + c2_d0_ DUP8 DUP7 @@ -74,11 +77,12 @@ global mul_fp6: DUP8 MULFP254 ADDFP254 - // stack: c0d2 + c1d1 + c2d0, c0_d2_ + c1_d1_ + c2_d0_ + // stack: c0d2 + c1d1 + c2d0 , c0_d2_ + c1_d1_ + c2_d0_ SUBFP254 + // stack: e2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) SWAP12 - // E0, E0_ + // e0, e0_ // make CD12_ = c1d2_ + c1_d2 + c2d1_ + c2_d1 DUP1 DUP5 @@ -127,26 +131,26 @@ global mul_fp6: DUP7 MULFP254 SUBFP254 - // stack: C0D0 , CD12 , C0D0_, CD12_ + // stack: C0D0 , CD12 , C0D0_, CD12_ DUP4 DUP3 - // stack: CD12 , CD12_ , C0D0 , CD12 , C0D0_, CD12_ + // stack: CD12 , CD12_ , C0D0 , CD12 , C0D0_, CD12_ PUSH 9 MULFP254 SUBFP254 ADDFP254 - // stack: 9CD12 - CD12_ + C0D0 , CD12 , C0D0_, CD12_ + // stack: e0 = 9CD12 - CD12_ + C0D0 , CD12 , C0D0_, CD12_ SWAP12 SWAP3 - // stack: CD12_ , CD12 , C0D0_ + // stack: CD12_ , CD12 , C0D0_ PUSH 9 MULFP254 ADDFP254 ADDFP254 - // stack: 9CD12_ + CD12 + C0D0_ + // stack: e0_ = 9CD12_ + CD12 + C0D0_ SWAP11 - // E1, E1_ + // e1, e1_ // make C2D2_ = c2d2_ + c2_d2 DUP14 DUP10 @@ -187,7 +191,7 @@ global mul_fp6: MULFP254 SUBFP254 ADDFP254 - // stack: E1 = 9C2D2 - C2D2_ + CD01, C2D2, C2D2_ + // stack: e1 = 9C2D2 - C2D2_ + CD01, C2D2, C2D2_ SWAP15 SWAP2 // stack: C2D2_ , C2D2 @@ -213,10 +217,10 @@ global mul_fp6: ADDFP254 // stack: CD01_ , 9C2D2_ + C2D2 ADDFP254 - // stack: E1_ = CD01_ + 9C2D2_ + C2D2 + // stack: e1_ = CD01_ + 9C2D2_ + C2D2 SWAP15 - // E2_ + // e2_ // stack: d2, d1_, d1, d0_, d2_, c0, c0_, c1, c1_, c2, c2_, d0 SWAP7 MULFP254 @@ -242,6 +246,8 @@ global mul_fp6: SWAP2 MULFP254 ADDFP254 - // stack: E2_ = c2_d0 + c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1 + // stack: e2_ = c2_d0 + c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1 SWAP6 + + // stack: retdest, e0, e0_, e1, e1_, e2, e2_ JUMP From 11c232a81092085a30e7731f4a172a98fa02b252 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Sat, 22 Oct 2022 16:19:23 -0400 Subject: [PATCH 47/58] fmt --- evm/src/cpu/kernel/tests/fields.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 999690fd..c5328a94 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -126,7 +126,12 @@ fn as_stack(xs: Vec) -> Vec { xs.iter().map(|&x| U256::from(x)).rev().collect() } -fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g1: [[u32; 2]; 3]) -> Vec { +fn make_initial_stack( + f0: [[u32; 2]; 3], + f1: [[u32; 2]; 3], + g0: [[u32; 2]; 3], + g1: [[u32; 2]; 3], +) -> Vec { // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out let f0: Vec = f0.into_iter().flatten().collect(); let f1: Vec = f1.into_iter().flatten().collect(); @@ -141,7 +146,7 @@ fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g input.extend(g0); input.extend(vec![18]); input.extend(g1); - input.extend(vec![12,24,0,24]); + input.extend(vec![12, 24, 0, 24]); as_stack(input) } @@ -150,7 +155,7 @@ fn make_initial_stack(f0: [[u32; 2]; 3], f1: [[u32; 2]; 3], g0: [[u32; 2]; 3], g fn test_fp6() -> Result<()> { let c = gen_fp6(); let d = gen_fp6(); - + let mut input: Vec = [c, d].into_iter().flatten().flatten().collect(); input.push(0xdeadbeef); @@ -163,7 +168,7 @@ fn test_fp6() -> Result<()> { let output: Vec = mul_fp6(c, d).into_iter().flatten().collect(); let expected = as_stack(output); - + assert_eq!(final_stack, expected); Ok(()) @@ -183,7 +188,11 @@ fn test_fp12() -> Result<()> { .stack() .to_vec(); - let mut output: Vec = mul_fp12([f0, f1], [g0, g1]).into_iter().flatten().flatten().collect(); + let mut output: Vec = mul_fp12([f0, f1], [g0, g1]) + .into_iter() + .flatten() + .flatten() + .collect(); output.extend(vec![24]); let expected = as_stack(output); From 59dc9b2d8e80e71ccb0cb4c4c2012bbf99561feb Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 25 Oct 2022 16:59:32 -0400 Subject: [PATCH 48/58] clean up test --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 22 +++++++--- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 2 +- evm/src/cpu/kernel/tests/fields.rs | 48 +++++++++++----------- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index c7a2b872..328c53df 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -1,17 +1,29 @@ /// Note: uncomment this to test global test_mul_Fp12: - // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out + // stack: f, in0 , f', g, in1 , g', in1, out, in0, out + DUP7 + // stack: in0, f, in0 , f', g, in1 , g', in1, out, in0, out %store_fp6 + // stack: in0 , f', g, in1 , g', in1, out, in0, out + %add_const(6) + // stack: in0', f', g, in1 , g', in1, out, in0, out %store_fp6 + // stack: g, in1 , g', in1, out, in0, out + DUP7 + // stack: in1, g, in1 , g', in1, out, in0, out %store_fp6 + // stack: in1 , g', in1, out, in0, out + %add_const(6) + // stack: in1', g', in1, out, in0, out %store_fp6 - // stack: in1, out, in0, out - PUSH return_on_stack + // stack: in1, out, in0, out + PUSH ret_stack + // stack: ret_stack, in1, out, in0, out SWAP3 - // stack: in0, in1, out, return_on_stack, out + // stack: in0, in1, out, ret_stack, out %jump(mul_Fp12) -return_on_stack: +ret_stack: // stack: out DUP1 %add_const(6) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 6ec69192..21368bd2 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -238,7 +238,7 @@ global mul_fp6: // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 SWAP2 MULFP254 - // stack: c0_d2 , c0d2_ + c2d0_ , c1d1_ , c1_d1 , c2_, d0 + // stack: c0_d2 , c0d2_ + c2d0_ , c1d1_ , c1_d1 , c2_, d0 ADDFP254 ADDFP254 ADDFP254 diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index c5328a94..718c337f 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -126,31 +126,6 @@ fn as_stack(xs: Vec) -> Vec { xs.iter().map(|&x| U256::from(x)).rev().collect() } -fn make_initial_stack( - f0: [[u32; 2]; 3], - f1: [[u32; 2]; 3], - g0: [[u32; 2]; 3], - g1: [[u32; 2]; 3], -) -> Vec { - // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out - let f0: Vec = f0.into_iter().flatten().collect(); - let f1: Vec = f1.into_iter().flatten().collect(); - let g0: Vec = g0.into_iter().flatten().collect(); - let g1: Vec = g1.into_iter().flatten().collect(); - - let mut input = vec![0]; - input.extend(f0); - input.extend(vec![6]); - input.extend(f1); - input.extend(vec![12]); - input.extend(g0); - input.extend(vec![18]); - input.extend(g1); - input.extend(vec![12, 24, 0, 24]); - - as_stack(input) -} - #[test] fn test_fp6() -> Result<()> { let c = gen_fp6(); @@ -174,6 +149,29 @@ fn test_fp6() -> Result<()> { Ok(()) } +fn make_initial_stack( + f0: [[u32; 2]; 3], + f1: [[u32; 2]; 3], + g0: [[u32; 2]; 3], + g1: [[u32; 2]; 3], +) -> Vec { + // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out + let f0: Vec = f0.into_iter().flatten().collect(); + let f1: Vec = f1.into_iter().flatten().collect(); + let g0: Vec = g0.into_iter().flatten().collect(); + let g1: Vec = g1.into_iter().flatten().collect(); + + let mut input = f0; + input.extend(vec![0]); + input.extend(f1); + input.extend(g0); + input.extend(vec![12]); + input.extend(g1); + input.extend(vec![12, 24, 0, 24]); + + as_stack(input) +} + #[test] fn test_fp12() -> Result<()> { let f0 = gen_fp6(); From f6a30cba7c6acfa0a72ac6f66936011783869da7 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 25 Oct 2022 17:09:25 -0400 Subject: [PATCH 49/58] better comments --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 80 ++++++++++++---------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 328c53df..6d9518b2 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -37,8 +37,8 @@ ret_stack: %jump(0xdeadbeef) -/// fp6 macros: -/// macro | num | ops | cost +/// fp6 functions: +/// fn | num | ops | cost /// ------------------------- /// load | 8 | 40 | 320 /// store | 5 | 40 | 200 @@ -61,77 +61,81 @@ ret_stack: /// /// TOTAL: 1196 - -/// F = f + f'z -/// G = g + g'z +/// inputs: +/// F = f + f'z +/// G = g + g'z /// -/// H = h + h'z = FG +/// output: +/// H = h + h'z = FG /// -/// h = fg + sh(f'g') -/// h' = (f+f')(g+g') - fg - f'g' +/// h = fg + sh(f'g') +/// h' = (f+f')(g+g') - fg - f'g' /// -/// Note: f, f', g, g' consist of six terms on the stack +/// memory offsets [ind' = ind+6] +/// {in0: f, in0: f', in1: g, in1':g', out: h, out': h'} +/// +/// f, f', g, g' consist of six elements on the stack global mul_Fp12: - // stack: in0, in1, out + // stack: in0, in1, out DUP1 %add_const(6) - // stack: in0', in0, in1, out + // stack: in0', in0, in1, out %load_fp6 - // stack: f', in0, in1, out + // stack: f', in0, in1, out DUP8 %add_const(6) - // stack: in1', f', in0, in1, out + // stack: in1', f', in0, in1, out %load_fp6 - // stack: g', f', in0, in1, out + // stack: g', f', in0, in1, out PUSH ret_1 - // stack: ret_1, g', f', in0, in1, out + // stack: ret_1, g', f', in0, in1, out %dup_fp6_7 - // stack: f', ret_1, g', f', in0, in1, out + // stack: f', ret_1, g', f', in0, in1, out %dup_fp6_7 - // stack: g', f', ret_1, g', f', in0, in1, out + // stack: g', f', ret_1, g', f', in0, in1, out %jump(mul_fp6) ret_1: - // stack: f'g', g' , f', in0, in1, out + // stack: f'g', g' , f', in0, in1, out %dup_fp6_0 - // stack: f'g', f'g', g' , f', in0, in1, out + // stack: f'g', f'g', g' , f', in0, in1, out %store_fp6_sh(100) - // stack: f'g', g' , f', in0, in1, out {100: sh(f'g')} + // stack: f'g', g' , f', in0, in1, out {100: sh(f'g')} %store_fp6(106) - // stack: g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} DUP13 - // stack: in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} DUP15 - // stack: in1, in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: in1, in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %load_fp6 - // stack: g , in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g , in0, g' , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %swap_fp6_hole - // stack: g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %dup_fp6_7 - // stack: g,g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g,g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %add_fp6 - // stack: g+g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g+g', in0, g , f', in0, in1, out {100: sh(f'g'), 106: f'g'} %swap_fp6_hole - // stack: g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} PUSH ret_2 - // stack: ret_2, g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: ret_2, g, in0, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} SWAP7 - // stack: in0, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: in0, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} %load_fp6 - // stack: f, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: f, g, ret_2, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} %jump(mul_fp6) ret_2: - // stack: fg, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} + // stack: fg, g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g'} %store_fp6(112) - // stack: g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: g+g', f', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %swap_fp6 - // stack: f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} PUSH ret_3 - // stack: ret_3, f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: ret_3, f', g+g', in0, in1, out {100: sh(f'g'), 106: f'g', 112: fg} SWAP13 - // stack: in0, f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: in0, f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %load_fp6 - // stack: f,f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: f,f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %add_fp6 - // stack: f+f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} + // stack: f+f', g+g', ret_3, in1, out {100: sh(f'g'), 106: f'g', 112: fg} %jump(mul_fp6) ret_3: // stack: (f+f')(g+g'), in1, out {100: sh(f'g'), 106: f'g', 112: fg} From 71587146188b152f46c3f85f9ac3a4775c26e5d0 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 25 Oct 2022 17:11:33 -0400 Subject: [PATCH 50/58] minor --- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 21368bd2..89376428 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -230,19 +230,19 @@ global mul_fp6: // stack: c1_d1, d0_, d2_, c0, c0_, d2, c1d1_, c2, c2_, d0 SWAP7 MULFP254 - // stack: c2d0_, d2_, c0, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c2d0_, d2_, c0, c0_, d2, c1d1_, c1_d1 , c2_, d0 SWAP2 MULFP254 - // stack: c0d2_ , c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c0d2_ , c2d0_, c0_, d2, c1d1_, c1_d1 , c2_, d0 ADDFP254 - // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1, c2_, d0 + // stack: c0d2_ + c2d0_, c0_, d2, c1d1_, c1_d1 , c2_, d0 SWAP2 MULFP254 // stack: c0_d2 , c0d2_ + c2d0_ , c1d1_ , c1_d1 , c2_, d0 ADDFP254 ADDFP254 ADDFP254 - // stack: c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1, c2_, d0 + // stack: c0_d2 + c0d2_ + c2d0_ + c1d1_ + c1_d1 , c2_, d0 SWAP2 MULFP254 ADDFP254 From faeb6e0bb09aec2baf7057409f673882c02f3566 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Tue, 25 Oct 2022 17:14:15 -0400 Subject: [PATCH 51/58] comments --- evm/src/cpu/kernel/asm/fields/fp6_mul.asm | 25 ++++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm index 89376428..0fc6dbdf 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_mul.asm @@ -1,13 +1,20 @@ -/// C = C0 + C1t + C2t^2 -/// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 +/// inputs: +/// C = C0 + C1t + C2t^2 +/// = (c0 + c0_i) + (c1 + c1_i)t + (c2 + c2_i)t^2 /// -/// D = D0 + D1t + D2t^2 -/// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 +/// D = D0 + D1t + D2t^2 +/// = (d0 + d0_i) + (d1 + d1_i)t + (d2 + d2_i)t^2 /// -/// E = e0 + e1t + e2t^2 = CD +/// output: +/// E = E0 + E1t + E2t^2 = CD +/// = (e0 + e0_i) + (e1 + e1_i)t + (e2 + e2_i)t^2 /// +/// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest +/// final stack: e0, e0_, e1, e1_, e2, e2_ + +/// computations: /// -/// e0 = C0D0 + i9(C1D2 + C2D1) +/// E0 = C0D0 + i9(C1D2 + C2D1) /// /// C0D0 = (c0d0 - c0_d0_) + (c0d0_ + c0_d0)i /// @@ -23,7 +30,7 @@ /// e0_ = 9CD12_ + CD12 + C0D0_ /// /// -/// e1 = C0D1 + C1D0 + i9(C2D2) +/// E1 = C0D1 + C1D0 + i9(C2D2) /// /// C0D1 = (c0d1 - c0_d1_) + (c0d1_ + c0_d1)i /// C1D0 = (c1d0 - c1_d0_) + (c1d0_ + c1_d0)i @@ -38,7 +45,7 @@ /// e1_ = C2D2 + 9C2D2_ + CD01_ /// /// -/// e2 = C0D2 + C1D1 + C2D0 +/// E2 = C0D2 + C1D1 + C2D0 /// /// C0D2 = (c0d2 - c0_d2_) + (c0d2_ + c0_d2)i /// C1D1 = (c1d1 - c1_d1_) + (c1d1_ + c1_d1)i @@ -47,8 +54,6 @@ /// e2 = c0d2 + c1d1 + c2d0 - (c0_d2_ + c1_d1_ + c2_d0_) /// e2_ = c0d2_ + c0_d2 + c1d1_ + c1_d1 + c2d0_ + c2_d0 -/// initial stack: c0, c0_, c1, c1_, c2, c2_, d0, d0_, d1, d1_, d2, d2_, retdest -/// final stack: e0, e0_, e1, e1_, e2, e2_ // cost: 157 global mul_fp6: From a8ecdc0f690e7741d7a1538f80dcf090365018f8 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:01:04 -0700 Subject: [PATCH 52/58] improve comments --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 2 +- evm/src/cpu/kernel/asm/fields/fp6_macros.asm | 198 +++++++++---------- 2 files changed, 99 insertions(+), 101 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 6d9518b2..71e1f8f7 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -71,7 +71,7 @@ ret_stack: /// h = fg + sh(f'g') /// h' = (f+f')(g+g') - fg - f'g' /// -/// memory offsets [ind' = ind+6] +/// memory pointers [ind' = ind+6] /// {in0: f, in0: f', in1: g, in1':g', out: h, out': h'} /// /// f, f', g, g' consist of six elements on the stack diff --git a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm index 70cc0e64..3a45958f 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm @@ -1,31 +1,26 @@ // cost: 6 loads + 6 dup/swaps + 5 adds = 6*4 + 6*1 + 5*2 = 40 %macro load_fp6 - // stack: offset - DUP1 - %add_const(4) - // stack: ind4, offset + // stack: ptr + DUP1 %add_const(4) + // stack: ind4, ptr %mload_kernel_general - // stack: x4, offset - DUP2 - %add_const(3) - // stack: ind3, x4, offset + // stack: x4, ptr + DUP2 %add_const(3) + // stack: ind3, x4, ptr %mload_kernel_general - // stack: x3, x4, offset - DUP3 - %add_const(2) - // stack: ind2, x3, x4, offset + // stack: x3, x4, ptr + DUP3 %add_const(2) + // stack: ind2, x3, x4, ptr %mload_kernel_general - // stack: x2, x3, x4, offset - DUP4 - %add_const(1) - // stack: ind1, x2, x3, x4, offset + // stack: x2, x3, x4, ptr + DUP4 %add_const(1) + // stack: ind1, x2, x3, x4, ptr %mload_kernel_general - // stack: x1, x2, x3, x4, offset - DUP5 - %add_const(5) - // stack: ind5, x1, x2, x3, x4, offset + // stack: x1, x2, x3, x4, ptr + DUP5 %add_const(5) + // stack: ind5, x1, x2, x3, x4, ptr %mload_kernel_general - // stack: x5, x1, x2, x3, x4, offset + // stack: x5, x1, x2, x3, x4, ptr SWAP5 // stack: ind0, x1, x2, x3, x4, x5 %mload_kernel_general @@ -33,121 +28,121 @@ %endmacro // cost: 6 loads + 6 pushes + 5 adds = 6*4 + 6*1 + 5*2 = 40 -%macro load_fp6(offset) +%macro load_fp6(ptr) // stack: - PUSH $offset - %add_const(5) + PUSH $ptr %add_const(5) + // stack: ind5 %mload_kernel_general - // stack: x5 - PUSH $offset - %add_const(4) + // stack: x5 + PUSH $ptr %add_const(4) + // stack: ind4, x5 %mload_kernel_general - // stack: x4, x5 - PUSH $offset - %add_const(3) + // stack: x4, x5 + PUSH $ptr %add_const(3) + // stack: ind3, x4, x5 %mload_kernel_general - // stack: x3, x4, x5 - PUSH $offset - %add_const(2) + // stack: x3, x4, x5 + PUSH $ptr %add_const(2) + // stack: ind2, x3, x4, x5 %mload_kernel_general - // stack: x2, x3, x4, x5 - PUSH $offset - %add_const(1) + // stack: x2, x3, x4, x5 + PUSH $ptr %add_const(1) + // stack: ind1, x2, x3, x4, x5 %mload_kernel_general - // stack: x1, x2, x3, x4, x5 - PUSH $offset + // stack: x1, x2, x3, x4, x5 + PUSH $ptr + // stack: ind0, x1, x2, x3, x4, x5 %mload_kernel_general - // stack: x0, x1, x2, x3, x4, x5 + // stack: x0, x1, x2, x3, x4, x5 %endmacro // cost: 6 stores + 6 swaps/dups + 5 adds = 6*4 + 6*1 + 5*2 = 40 %macro store_fp6 - // stack: offset, x0, x1, x2, x3, x4, x5 + // stack: ptr, x0, x1, x2, x3, x4 , x5 SWAP5 - DUP6 - %add_const(4) - // stack: ind4, x4, x0, x1, x2, x3, offset, x5 + // stack: x4, x0, x1, x2, x3, ptr, x5 + DUP6 %add_const(4) + // stack: ind4, x4, x0, x1, x2, x3, ptr, x5 %mstore_kernel_general - // stack: x0, x1, x2, x3, offset, x5 + // stack: x0, x1, x2, x3, ptr, x5 DUP5 - // stack: ind0, x0, x1, x2, x3, offset, x5 + // stack: ind0, x0, x1, x2, x3, ptr, x5 %mstore_kernel_general - // stack: x1, x2, x3, offset, x5 - DUP4 - %add_const(1) - // stack: ind1, x1, x2, x3, offset, x5 + // stack: x1, x2, x3, ptr, x5 + DUP4 %add_const(1) + // stack: ind1, x1, x2, x3, ptr, x5 %mstore_kernel_general - // stack: x2, x3, offset, x5 - DUP3 - %add_const(2) - // stack: ind2, x2, x3, offset, x5 + // stack: x2, x3, ptr, x5 + DUP3 %add_const(2) + // stack: ind2, x2, x3, ptr, x5 %mstore_kernel_general - // stack: x3, offset, x5 - DUP2 - %add_const(3) - // stack: ind3, x3, offset, x5 + // stack: x3, ptr, x5 + DUP2 %add_const(3) + // stack: ind3, x3, ptr, x5 %mstore_kernel_general - // stack: offset, x5 + // stack: ptr, x5 %add_const(5) - // stack: ind5, x5 + // stack: ind5, x5 %mstore_kernel_general // stack: %endmacro // cost: 6 stores + 6 pushes + 5 adds = 6*4 + 6*1 + 5*2 = 40 -%macro store_fp6(offset) - // stack: x0, x1, x2, x3, x4, x5 - PUSH $offset +%macro store_fp6(ptr) + // stack: x0, x1, x2, x3, x4, x5 + PUSH $ptr + // stack: ind0, x0, x1, x2, x3, x4, x5 %mstore_kernel_general - // stack: x1, x2, x3, x4, x5 - PUSH $offset - %add_const(1) + // stack: x1, x2, x3, x4, x5 + PUSH $ptr %add_const(1) + // stack: ind1, x1, x2, x3, x4, x5 %mstore_kernel_general - // stack: x2, x3, x4, x5 - PUSH $offset - %add_const(2) + // stack: x2, x3, x4, x5 + PUSH $ptr %add_const(2) + // stack: ind2, x2, x3, x4, x5 %mstore_kernel_general - // stack: x3, x4, x5 - PUSH $offset - %add_const(3) + // stack: x3, x4, x5 + PUSH $ptr %add_const(3) + // stack: ind3, x3, x4, x5 %mstore_kernel_general - // stack: x4, x5 - PUSH $offset - %add_const(4) + // stack: x4, x5 + PUSH $ptr %add_const(4) + // stack: ind4, x4, x5 %mstore_kernel_general - // stack: x5 - PUSH $offset - %add_const(5) + // stack: x5 + PUSH $ptr %add_const(5) + // stack: ind5, x5 %mstore_kernel_general // stack: %endmacro // cost: store (40) + i9 (9) = 49 -%macro store_fp6_sh(offset) - // stack: x0, x1, x2, x3, x4, x5 - PUSH $offset - %add_const(2) +%macro store_fp6_sh(ptr) + // stack: x0, x1, x2, x3, x4, x5 + PUSH $ptr %add_const(2) + // stack: ind2, x0, x1, x2, x3, x4, x5 %mstore_kernel_general - // stack: x1, x2, x3, x4, x5 - PUSH $offset - %add_const(3) + // stack: x1, x2, x3, x4, x5 + PUSH $ptr %add_const(3) + // stack: ind3, x1, x2, x3, x4, x5 %mstore_kernel_general - // stack: x2, x3, x4, x5 - PUSH $offset - %add_const(4) + // stack: x2, x3, x4, x5 + PUSH $ptr %add_const(4) + // stack: ind4, x2, x3, x4, x5 %mstore_kernel_general - // stack: x3, x4, x5 - PUSH $offset - %add_const(5) + // stack: x3, x4, x5 + PUSH $ptr %add_const(5) + // stack: ind5, x3, x4, x5 %mstore_kernel_general - // stack: x4, x5 + // stack: x4, x5 %i9 - // stack: y5, y4 - PUSH $offset - %add_const(1) + // stack: y5, y4 + PUSH $ptr %add_const(1) + // stack: ind1, y5, y4 %mstore_kernel_general - // stack: y4 - PUSH $offset + // stack: y4 + PUSH $ptr + // stack: ind0, y4 %mstore_kernel_general // stack: %endmacro @@ -156,16 +151,17 @@ %macro i9 // stack: a , b DUP2 + // stack: b, a, b DUP2 // stack: a , b, a , b - PUSH 9 - MULFP254 + PUSH 9 MULFP254 + // stack: 9a , b, a , b SUBFP254 // stack: 9a - b, a , b SWAP2 // stack: b , a, 9a - b - PUSH 9 - MULFP254 + PUSH 9 MULFP254 + // stack 9b , a, 9a - b ADDFP254 // stack: 9b + a, 9a - b %endmacro @@ -234,6 +230,8 @@ %endmacro // cost: 16 +// swap two fp6 elements with a stack term separating them +// (f: 6, x, g: 6) -> (g: 6, x, f: 6) %macro swap_fp6_hole // stack: f0, f1, f2, f3, f4, f5, X, g0, g1, g2, g3, g4, g5 SWAP7 From 7d78916a6f50a485cff1b8148763805691b02a64 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:03:52 -0700 Subject: [PATCH 53/58] merge --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 70 +++++++++--------- evm/src/cpu/kernel/tests/fields.rs | 84 +++++++++++----------- 2 files changed, 77 insertions(+), 77 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 71e1f8f7..0037f832 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -1,40 +1,40 @@ /// Note: uncomment this to test -global test_mul_Fp12: - // stack: f, in0 , f', g, in1 , g', in1, out, in0, out - DUP7 - // stack: in0, f, in0 , f', g, in1 , g', in1, out, in0, out - %store_fp6 - // stack: in0 , f', g, in1 , g', in1, out, in0, out - %add_const(6) - // stack: in0', f', g, in1 , g', in1, out, in0, out - %store_fp6 - // stack: g, in1 , g', in1, out, in0, out - DUP7 - // stack: in1, g, in1 , g', in1, out, in0, out - %store_fp6 - // stack: in1 , g', in1, out, in0, out - %add_const(6) - // stack: in1', g', in1, out, in0, out - %store_fp6 - // stack: in1, out, in0, out - PUSH ret_stack - // stack: ret_stack, in1, out, in0, out - SWAP3 - // stack: in0, in1, out, ret_stack, out - %jump(mul_Fp12) -ret_stack: - // stack: out - DUP1 - %add_const(6) - // stack: out', out - %load_fp6 - // stack: h', out - DUP7 - // stack: out, h', out - %load_fp6 - // stack: h, h', out - %jump(0xdeadbeef) +/// global test_mul_Fp12: +/// // stack: f, in0 , f', g, in1 , g', in1, out, in0, out +/// DUP7 +/// // stack: in0, f, in0 , f', g, in1 , g', in1, out, in0, out +/// %store_fp6 +/// // stack: in0 , f', g, in1 , g', in1, out, in0, out +/// %add_const(6) +/// // stack: in0', f', g, in1 , g', in1, out, in0, out +/// %store_fp6 +/// // stack: g, in1 , g', in1, out, in0, out +/// DUP7 +/// // stack: in1, g, in1 , g', in1, out, in0, out +/// %store_fp6 +/// // stack: in1 , g', in1, out, in0, out +/// %add_const(6) +/// // stack: in1', g', in1, out, in0, out +/// %store_fp6 +/// // stack: in1, out, in0, out +/// PUSH ret_stack +/// // stack: ret_stack, in1, out, in0, out +/// SWAP3 +/// // stack: in0, in1, out, ret_stack, out +/// %jump(mul_Fp12) +/// ret_stack: +/// // stack: out +/// DUP1 +/// %add_const(6) +/// // stack: out', out +/// %load_fp6 +/// // stack: h', out +/// DUP7 +/// // stack: out, h', out +/// %load_fp6 +/// // stack: h, h', out +/// %jump(0xdeadbeef) /// fp6 functions: diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 718c337f..bb57cb2a 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -149,52 +149,52 @@ fn test_fp6() -> Result<()> { Ok(()) } -fn make_initial_stack( - f0: [[u32; 2]; 3], - f1: [[u32; 2]; 3], - g0: [[u32; 2]; 3], - g1: [[u32; 2]; 3], -) -> Vec { - // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out - let f0: Vec = f0.into_iter().flatten().collect(); - let f1: Vec = f1.into_iter().flatten().collect(); - let g0: Vec = g0.into_iter().flatten().collect(); - let g1: Vec = g1.into_iter().flatten().collect(); +// fn make_initial_stack( +// f0: [[u32; 2]; 3], +// f1: [[u32; 2]; 3], +// g0: [[u32; 2]; 3], +// g1: [[u32; 2]; 3], +// ) -> Vec { +// // stack: in0, f, in0', f', in1, g, in1', g', in1, out, in0, out +// let f0: Vec = f0.into_iter().flatten().collect(); +// let f1: Vec = f1.into_iter().flatten().collect(); +// let g0: Vec = g0.into_iter().flatten().collect(); +// let g1: Vec = g1.into_iter().flatten().collect(); - let mut input = f0; - input.extend(vec![0]); - input.extend(f1); - input.extend(g0); - input.extend(vec![12]); - input.extend(g1); - input.extend(vec![12, 24, 0, 24]); +// let mut input = f0; +// input.extend(vec![0]); +// input.extend(f1); +// input.extend(g0); +// input.extend(vec![12]); +// input.extend(g1); +// input.extend(vec![12, 24, 0, 24]); - as_stack(input) -} +// as_stack(input) +// } -#[test] -fn test_fp12() -> Result<()> { - let f0 = gen_fp6(); - let f1 = gen_fp6(); - let g0 = gen_fp6(); - let g1 = gen_fp6(); +// #[test] +// fn test_fp12() -> Result<()> { +// let f0 = gen_fp6(); +// let f1 = gen_fp6(); +// let g0 = gen_fp6(); +// let g1 = gen_fp6(); - let kernel = combined_kernel(); - let initial_offset = kernel.global_labels["test_mul_Fp12"]; - let initial_stack: Vec = make_initial_stack(f0, f1, g0, g1); - let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? - .stack() - .to_vec(); +// let kernel = combined_kernel(); +// let initial_offset = kernel.global_labels["test_mul_Fp12"]; +// let initial_stack: Vec = make_initial_stack(f0, f1, g0, g1); +// let final_stack: Vec = run_with_kernel(&kernel, initial_offset, initial_stack)? +// .stack() +// .to_vec(); - let mut output: Vec = mul_fp12([f0, f1], [g0, g1]) - .into_iter() - .flatten() - .flatten() - .collect(); - output.extend(vec![24]); - let expected = as_stack(output); +// let mut output: Vec = mul_fp12([f0, f1], [g0, g1]) +// .into_iter() +// .flatten() +// .flatten() +// .collect(); +// output.extend(vec![24]); +// let expected = as_stack(output); - assert_eq!(final_stack, expected); +// assert_eq!(final_stack, expected); - Ok(()) -} +// Ok(()) +// } From ad067d1e527ffc92b18e1338b6582b34c040e975 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:08:56 -0700 Subject: [PATCH 54/58] comment about 107 --- evm/src/cpu/kernel/interpreter.rs | 3 +++ evm/src/cpu/kernel/tests/fields.rs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 5c2329e5..89a4341d 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -370,6 +370,9 @@ impl<'a> Interpreter<'a> { self.push(x.overflowing_sub(y).0); } +// TODO: 107 is hardcoded as a dummy prime for testing +// should be changed to the proper implementation prime + fn run_addfp254(&mut self) { let x = self.pop(); let y = self.pop(); diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index bb57cb2a..0a490983 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -5,6 +5,9 @@ use rand::{thread_rng, Rng}; use crate::cpu::kernel::aggregator::combined_kernel; use crate::cpu::kernel::interpreter::run_with_kernel; +// TODO: 107 is hardcoded as a dummy prime for testing +// should be changed to the proper implementation prime +// once the run_{add, mul, sub}fp254 fns are implemented const P254: u32 = 107; fn add_fp(x: u32, y: u32) -> u32 { From f90c058a52226eb242926681ced35c81233989c8 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:09:56 -0700 Subject: [PATCH 55/58] minor --- evm/src/cpu/kernel/asm/fields/fp12_mul.asm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm index 0037f832..2f4b9024 100644 --- a/evm/src/cpu/kernel/asm/fields/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/fields/fp12_mul.asm @@ -25,8 +25,7 @@ /// %jump(mul_Fp12) /// ret_stack: /// // stack: out -/// DUP1 -/// %add_const(6) +/// DUP1 %add_const(6) /// // stack: out', out /// %load_fp6 /// // stack: h', out From ccf5cda122a6f1c73ac40e261cb7830a72d65880 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:11:22 -0700 Subject: [PATCH 56/58] spacing --- evm/src/cpu/kernel/asm/fields/fp6_macros.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm index 3a45958f..b575c234 100644 --- a/evm/src/cpu/kernel/asm/fields/fp6_macros.asm +++ b/evm/src/cpu/kernel/asm/fields/fp6_macros.asm @@ -31,7 +31,7 @@ %macro load_fp6(ptr) // stack: PUSH $ptr %add_const(5) - // stack: ind5 + // stack: ind5 %mload_kernel_general // stack: x5 PUSH $ptr %add_const(4) From aebeb7ac99341da1fe4b100699501f9d45ef33e8 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:12:57 -0700 Subject: [PATCH 57/58] fmt --- evm/src/cpu/kernel/interpreter.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 89a4341d..fe95d04c 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -370,8 +370,8 @@ impl<'a> Interpreter<'a> { self.push(x.overflowing_sub(y).0); } -// TODO: 107 is hardcoded as a dummy prime for testing -// should be changed to the proper implementation prime + // TODO: 107 is hardcoded as a dummy prime for testing + // should be changed to the proper implementation prime fn run_addfp254(&mut self) { let x = self.pop(); From 4380a037d2fda8e6c1bf9216133bfdacdc927278 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 28 Oct 2022 02:23:42 -0700 Subject: [PATCH 58/58] comment dead code --- evm/src/cpu/kernel/tests/fields.rs | 66 +++++++++++++++--------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 0a490983..b8a38887 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -39,11 +39,11 @@ fn add3_fp2(a: [u32; 2], b: [u32; 2], c: [u32; 2]) -> [u32; 2] { [add3_fp(a, b, c), add3_fp(a_, b_, c_)] } -fn sub_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { - let [a, a_] = a; - let [b, b_] = b; - [sub_fp(a, b), sub_fp(a_, b_)] -} +// fn sub_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { +// let [a, a_] = a; +// let [b, b_] = b; +// [sub_fp(a, b), sub_fp(a_, b_)] +// } fn mul_fp2(a: [u32; 2], b: [u32; 2]) -> [u32; 2] { let [a, a_] = a; @@ -59,25 +59,25 @@ fn i9(a: [u32; 2]) -> [u32; 2] { [sub_fp(mul_fp(9, a), a_), add_fp(a, mul_fp(9, a_))] } -fn add_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { - let [c0, c1, c2] = c; - let [d0, d1, d2] = d; +// fn add_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { +// let [c0, c1, c2] = c; +// let [d0, d1, d2] = d; - let e0 = add_fp2(c0, d0); - let e1 = add_fp2(c1, d1); - let e2 = add_fp2(c2, d2); - [e0, e1, e2] -} +// let e0 = add_fp2(c0, d0); +// let e1 = add_fp2(c1, d1); +// let e2 = add_fp2(c2, d2); +// [e0, e1, e2] +// } -fn sub_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { - let [c0, c1, c2] = c; - let [d0, d1, d2] = d; +// fn sub_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { +// let [c0, c1, c2] = c; +// let [d0, d1, d2] = d; - let e0 = sub_fp2(c0, d0); - let e1 = sub_fp2(c1, d1); - let e2 = sub_fp2(c2, d2); - [e0, e1, e2] -} +// let e0 = sub_fp2(c0, d0); +// let e1 = sub_fp2(c1, d1); +// let e2 = sub_fp2(c2, d2); +// [e0, e1, e2] +// } fn mul_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { let [c0, c1, c2] = c; @@ -101,20 +101,20 @@ fn mul_fp6(c: [[u32; 2]; 3], d: [[u32; 2]; 3]) -> [[u32; 2]; 3] { ] } -fn sh(c: [[u32; 2]; 3]) -> [[u32; 2]; 3] { - let [c0, c1, c2] = c; - [i9(c2), c0, c1] -} +// fn sh(c: [[u32; 2]; 3]) -> [[u32; 2]; 3] { +// let [c0, c1, c2] = c; +// [i9(c2), c0, c1] +// } -fn mul_fp12(f: [[[u32; 2]; 3]; 2], g: [[[u32; 2]; 3]; 2]) -> [[[u32; 2]; 3]; 2] { - let [f0, f1] = f; - let [g0, g1] = g; +// fn mul_fp12(f: [[[u32; 2]; 3]; 2], g: [[[u32; 2]; 3]; 2]) -> [[[u32; 2]; 3]; 2] { +// let [f0, f1] = f; +// let [g0, g1] = g; - let h0 = mul_fp6(f0, g0); - let h1 = mul_fp6(f1, g1); - let h01 = mul_fp6(add_fp6(f0, f1), add_fp6(g0, g1)); - [add_fp6(h0, sh(h1)), sub_fp6(h01, add_fp6(h0, h1))] -} +// let h0 = mul_fp6(f0, g0); +// let h1 = mul_fp6(f1, g1); +// let h01 = mul_fp6(add_fp6(f0, f1), add_fp6(g0, g1)); +// [add_fp6(h0, sh(h1)), sub_fp6(h01, add_fp6(h0, h1))] +// } fn gen_fp6() -> [[u32; 2]; 3] { let mut rng = thread_rng();