forked from privacy-scaling-explorations/zkevm-circuits
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exponentiation circuit and EXP opcode (privacy-scaling-explorations#700)
* feat: simple muladd gadget * feat: muladd gadget fewer columns, more rows * feat: basic structure of EXP and exp_table/circuit * feat: bus-mapping for EXP with exponentiation by squaring steps * fix: interface for exp table lookup * feat: basic constraints for exp circuit, refactor circuit layout * feat: additional constraints for exponentiation circuit * feat: assignments for exponentiation table * fix: minor fixes in exp circuit and exp gadget. NOT TESTED * fix: handle exponent cases 0,1 and fix constraints for tests * chore: comments and minor refactoring * fix: constraints for exponentiation circuit, first tests * test: more test cases for exp circuit * chore: add exp circuit/table to super circuit * use array of 33 boolean cells to determine byte size of exponent * make clippy happy * fix: fetching most significant byte fixed, tests passing * chore: refactor into byte size gadget * chore: remove unnecessary LoC, some doc * fix: minor constraint fix, add constraints for multiplicand value * chore: add a TODO * fix: constraints to verify division by 2 was correct * fix: updates based on recent upstream changes * fix: add missing constraints for a and b (exp by squaring updates) * fix: intermediate steps generated in exp by squaring * fix: ensure last step is included (verification through idx transition) * feat: enforce is_last exists (additional lookup) and some TODOs * chore: refactor constraint into the same condition * feat: add identifier (some todos) * feat: padding row at the end of exp trace * feat: validate odd/even parity with conditional fixed lookup * fix: exponent hi was not taken into account for is_zero and is_one comparison * fix: identifier | is_pad constraints, 2*n + k parity check using mul gadget * tests: add the previously failing test, verify that parity check is OK * fix: remove redundant column (not used anymore) * chore: rename field to concise * fix: assignment to exp table matches exp circuit block assignment * fix: is_pad added to lookup, no need for mul gadget in exp gadget * fix: no overflow in parity check gadget * fix: exp circuit layout * fix: compilation after rebase * fix negative tests * remove redundant addition * fix: c == 0 and is_last bool check * fix: comment on the correct line Co-authored-by: adria0.eth <[email protected]> * fix: formatting * fix: uncomment tests * refactoring for better encapsulation * fix: avoid conditional assignment * chore: rebase and fmt * fix: more efficient check for boolean formula Co-authored-by: z2trillion <[email protected]> Co-authored-by: Zhang Zhuo <[email protected]> Co-authored-by: adria0.eth <[email protected]>
- Loading branch information
1 parent
103ddd7
commit 247bcff
Showing
23 changed files
with
1,905 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use crate::{ | ||
circuit_input_builder::{CircuitInputStateRef, ExecStep, ExpEvent, ExpStep}, | ||
Error, | ||
}; | ||
use eth_types::{GethExecStep, U256}; | ||
|
||
use super::Opcode; | ||
|
||
#[derive(Clone, Copy, Debug)] | ||
pub(crate) struct Exponentiation; | ||
|
||
fn exp_by_squaring(base: U256, exponent: U256, steps: &mut Vec<ExpStep>) -> U256 { | ||
if exponent.is_zero() { | ||
return U256::one(); | ||
} | ||
if exponent == U256::one() { | ||
return base; | ||
} | ||
|
||
let (exponent_div2, odd) = exponent.div_mod(U256::from(2)); | ||
let exp1 = exp_by_squaring(base, exponent_div2, steps); | ||
let (exp2, _) = exp1.overflowing_mul(exp1); | ||
steps.push((exp1, exp1, exp2).into()); | ||
|
||
if odd.is_zero() { | ||
// exponent is even | ||
exp2 | ||
} else { | ||
// exponent is odd | ||
let (exp, _) = base.overflowing_mul(exp2); | ||
steps.push((exp2, base, exp).into()); | ||
exp | ||
} | ||
} | ||
|
||
impl Opcode for Exponentiation { | ||
fn gen_associated_ops( | ||
state: &mut CircuitInputStateRef, | ||
geth_steps: &[GethExecStep], | ||
) -> Result<Vec<ExecStep>, Error> { | ||
let geth_step = &geth_steps[0]; | ||
let mut exec_step = state.new_step(geth_step)?; | ||
|
||
let base = geth_step.stack.nth_last(0)?; | ||
state.stack_read(&mut exec_step, geth_step.stack.nth_last_filled(0), base)?; | ||
let exponent = geth_step.stack.nth_last(1)?; | ||
state.stack_read(&mut exec_step, geth_step.stack.nth_last_filled(1), exponent)?; | ||
|
||
let (exponentiation, _) = base.overflowing_pow(exponent); | ||
state.stack_write( | ||
&mut exec_step, | ||
geth_steps[1].stack.last_filled(), | ||
exponentiation, | ||
)?; | ||
|
||
let mut steps = Vec::new(); | ||
let exponentiation_calc = exp_by_squaring(base, exponent, &mut steps); | ||
debug_assert_eq!(exponentiation, exponentiation_calc); | ||
state.push_exponentiation(ExpEvent { | ||
identifier: state.block_ctx.rwc.0, | ||
base, | ||
exponent, | ||
exponentiation, | ||
steps, | ||
}); | ||
|
||
Ok(vec![exec_step]) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
use eth_types::U256; | ||
|
||
use super::exp_by_squaring; | ||
|
||
#[test] | ||
fn test_exp_by_squaring() { | ||
let mut steps = Vec::new(); | ||
let exp = exp_by_squaring(23u64.into(), 123u64.into(), &mut steps); | ||
assert_eq!( | ||
exp, | ||
U256::from_dec_str( | ||
"87180413255890732361416772728849128389641993872302935967571352892955279939527" | ||
) | ||
.unwrap() | ||
); | ||
|
||
let mut steps = Vec::new(); | ||
let exp = exp_by_squaring(3u64.into(), 13u64.into(), &mut steps); | ||
assert_eq!(exp, 1594323u64.into()); | ||
assert_eq!( | ||
steps, | ||
vec![ | ||
(3.into(), 3.into(), 9.into()).into(), | ||
(9.into(), 3.into(), 27.into()).into(), | ||
(27.into(), 27.into(), 729.into()).into(), | ||
(729.into(), 729.into(), 531441.into()).into(), | ||
(531441.into(), 3.into(), 1594323.into()).into(), | ||
] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.