diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/glv.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/glv.asm index bd903b21..32eb5b6c 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/glv.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/glv.asm @@ -97,9 +97,9 @@ contd: underflowed: // stack: underflow, k, s*k2, N, k2 - // Compute (k-s*k2)%N. TODO: Use SUBMOD here when ready - %stack (u, k, x, N, k2) -> (N, x, k, N, k2, u) - SUB ADDMOD + // Compute (k-s*k2)%N. + %stack (u, k, x, N, k2) -> (k, x, N, k2, u) + SUBMOD %stack (k1, k2, underflow, retdest) -> (retdest, underflow, k1, k2) JUMP diff --git a/evm/src/cpu/kernel/asm/curve/secp256k1/curve_add.asm b/evm/src/cpu/kernel/asm/curve/secp256k1/curve_add.asm index 9e416e66..8664b3e2 100644 --- a/evm/src/cpu/kernel/asm/curve/secp256k1/curve_add.asm +++ b/evm/src/cpu/kernel/asm/curve/secp256k1/curve_add.asm @@ -208,11 +208,10 @@ global secp_double: %endmacro // Modular subtraction. -// TODO: Use SUBMOD when it's ready %macro submod_secp_base // stack: x, y - %stack (x, y) -> (@SECP_BASE, y, x, @SECP_BASE) - SUB ADDMOD + %stack (x, y) -> (x, y, @SECP_BASE) + SUBMOD %endmacro // Check if (x,y) is a valid curve point. diff --git a/evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm b/evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm index eee0dc63..26d887f2 100644 --- a/evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm +++ b/evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm @@ -84,9 +84,9 @@ global secp_glv_decompose: underflowed: // stack: underflow, k, s*k2, N, k2 - // Compute (k-s*k2)%N. TODO: Use SUBMOD here when ready - %stack (u, k, x, N, k2) -> (N, x, k, N, k2, u) - SUB ADDMOD + // Compute (k-s*k2)%N. + %stack (u, k, x, N, k2) -> (k, x, N, k2, u) + SUBMOD %stack (k1, k2, underflow, retdest) -> (retdest, underflow, k1, k2) JUMP diff --git a/evm/src/cpu/kernel/interpreter.rs b/evm/src/cpu/kernel/interpreter.rs index 315e93f1..4ba6e9dc 100644 --- a/evm/src/cpu/kernel/interpreter.rs +++ b/evm/src/cpu/kernel/interpreter.rs @@ -349,6 +349,7 @@ impl<'a> Interpreter<'a> { 0x0c => self.run_addfp254(), // "ADDFP254", 0x0d => self.run_mulfp254(), // "MULFP254", 0x0e => self.run_subfp254(), // "SUBFP254", + 0x0f => self.run_submod(), // "SUBMOD", 0x10 => self.run_lt(), // "LT", 0x11 => self.run_gt(), // "GT", 0x12 => self.run_slt(), // "SLT", @@ -583,6 +584,17 @@ impl<'a> Interpreter<'a> { }); } + fn run_submod(&mut self) { + let x = U512::from(self.pop()); + let y = U512::from(self.pop()); + let z = U512::from(self.pop()); + self.push(if z.is_zero() { + U256::zero() + } else { + U256::try_from((z + x - y) % z).unwrap() + }); + } + fn run_mulmod(&mut self) { let x = self.pop(); let y = self.pop(); @@ -1220,6 +1232,7 @@ fn get_mnemonic(opcode: u8) -> &'static str { 0x0c => "ADDFP254", 0x0d => "MULFP254", 0x0e => "SUBFP254", + 0x0f => "SUBMOD", 0x10 => "LT", 0x11 => "GT", 0x12 => "SLT", diff --git a/evm/src/cpu/kernel/opcodes.rs b/evm/src/cpu/kernel/opcodes.rs index 2503a92e..b8732079 100644 --- a/evm/src/cpu/kernel/opcodes.rs +++ b/evm/src/cpu/kernel/opcodes.rs @@ -22,6 +22,7 @@ pub fn get_opcode(mnemonic: &str) -> u8 { "ADDFP254" => 0x0c, "MULFP254" => 0x0d, "SUBFP254" => 0x0e, + "SUBMOD" => 0x0f, "LT" => 0x10, "GT" => 0x11, "SLT" => 0x12, diff --git a/evm/src/witness/gas.rs b/evm/src/witness/gas.rs index aa312078..6f63a979 100644 --- a/evm/src/witness/gas.rs +++ b/evm/src/witness/gas.rs @@ -10,6 +10,7 @@ const G_HIGH: u64 = 10; pub(crate) fn gas_to_charge(op: Operation) -> u64 { use crate::arithmetic::BinaryOperator::*; + use crate::arithmetic::TernaryOperator::*; use crate::witness::operation::Operation::*; match op { Iszero => G_VERYLOW, @@ -30,7 +31,9 @@ pub(crate) fn gas_to_charge(op: Operation) -> u64 { BinaryArithmetic(AddFp254) => KERNEL_ONLY_INSTR, BinaryArithmetic(MulFp254) => KERNEL_ONLY_INSTR, BinaryArithmetic(SubFp254) => KERNEL_ONLY_INSTR, - TernaryArithmetic(_) => G_MID, + TernaryArithmetic(AddMod) => G_MID, + TernaryArithmetic(MulMod) => G_MID, + TernaryArithmetic(SubMod) => KERNEL_ONLY_INSTR, KeccakGeneral => KERNEL_ONLY_INSTR, ProverInput => KERNEL_ONLY_INSTR, Pop => G_BASE,