2022-06-29 11:56:48 +10:00
|
|
|
//! Arithmetic unit
|
|
|
|
|
|
2024-02-01 07:16:28 -05:00
|
|
|
use core::ops::Range;
|
2022-10-12 02:39:13 +11:00
|
|
|
|
2023-11-17 15:45:38 -05:00
|
|
|
pub(crate) const LIMB_BITS: usize = 16;
|
2022-06-29 11:56:48 +10:00
|
|
|
const EVM_REGISTER_BITS: usize = 256;
|
|
|
|
|
|
|
|
|
|
/// Return the number of LIMB_BITS limbs that are in an EVM
|
|
|
|
|
/// register-sized number, panicking if LIMB_BITS doesn't divide in
|
|
|
|
|
/// the EVM register size.
|
|
|
|
|
const fn n_limbs() -> usize {
|
|
|
|
|
if EVM_REGISTER_BITS % LIMB_BITS != 0 {
|
|
|
|
|
panic!("limb size must divide EVM register size");
|
|
|
|
|
}
|
2022-12-02 17:11:31 +11:00
|
|
|
let n = EVM_REGISTER_BITS / LIMB_BITS;
|
|
|
|
|
if n % 2 == 1 {
|
|
|
|
|
panic!("number of limbs must be even");
|
|
|
|
|
}
|
|
|
|
|
n
|
2022-06-29 11:56:48 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Number of LIMB_BITS limbs that are in on EVM register-sized number.
|
2023-11-17 15:45:38 -05:00
|
|
|
pub(crate) const N_LIMBS: usize = n_limbs();
|
2022-06-29 11:56:48 +10:00
|
|
|
|
Cross-table lookup for arithmetic stark (#905)
* First draft of linking arithmetic Stark into the CTL mechanism.
* Handle {ADD,SUB,MUL}FP254 operations explicitly in `modular.rs`.
* Adjust argument order; add tests.
* Add CTLs for ADD, MUL, SUB, LT and GT.
* Add CTLs for {ADD,MUL,SUB}MOD, DIV and MOD.
* Add CTLs for {ADD,MUL,SUB}FP254 operations.
* Refactor the CPU/arithmetic CTL mapping; add some documentation.
* Minor comment fixes.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Merge `*FP254` CTL into main CTL; rename some registers.
* Connect extra argument from CPU in binary ops to facilitate combining with ternary ops.
* Merge modular ops CTL into main CTL.
* Refactor DIV and MOD code into its own module.
* Merge DIV and MOD into arithmetic CTL.
* Clippy.
* Fixes related to merge.
* Simplify register naming.
* Generate u16 BN254 modulus limbs at compile time.
* Clippy.
* Add degree bits ranges for Arithmetic table.
2023-05-11 03:29:06 +10:00
|
|
|
pub(crate) const IS_ADD: usize = 0;
|
|
|
|
|
pub(crate) const IS_MUL: usize = IS_ADD + 1;
|
|
|
|
|
pub(crate) const IS_SUB: usize = IS_MUL + 1;
|
|
|
|
|
pub(crate) const IS_DIV: usize = IS_SUB + 1;
|
|
|
|
|
pub(crate) const IS_MOD: usize = IS_DIV + 1;
|
|
|
|
|
pub(crate) const IS_ADDMOD: usize = IS_MOD + 1;
|
|
|
|
|
pub(crate) const IS_MULMOD: usize = IS_ADDMOD + 1;
|
|
|
|
|
pub(crate) const IS_ADDFP254: usize = IS_MULMOD + 1;
|
|
|
|
|
pub(crate) const IS_MULFP254: usize = IS_ADDFP254 + 1;
|
|
|
|
|
pub(crate) const IS_SUBFP254: usize = IS_MULFP254 + 1;
|
|
|
|
|
pub(crate) const IS_SUBMOD: usize = IS_SUBFP254 + 1;
|
|
|
|
|
pub(crate) const IS_LT: usize = IS_SUBMOD + 1;
|
|
|
|
|
pub(crate) const IS_GT: usize = IS_LT + 1;
|
2023-06-03 02:16:45 +10:00
|
|
|
pub(crate) const IS_BYTE: usize = IS_GT + 1;
|
2023-09-14 10:36:48 -04:00
|
|
|
pub(crate) const IS_SHL: usize = IS_BYTE + 1;
|
|
|
|
|
pub(crate) const IS_SHR: usize = IS_SHL + 1;
|
2023-11-07 15:52:00 -05:00
|
|
|
pub(crate) const IS_RANGE_CHECK: usize = IS_SHR + 1;
|
|
|
|
|
/// Column that stores the opcode if the operation is a range check.
|
|
|
|
|
pub(crate) const OPCODE_COL: usize = IS_RANGE_CHECK + 1;
|
|
|
|
|
pub(crate) const START_SHARED_COLS: usize = OPCODE_COL + 1;
|
2022-06-29 11:56:48 +10:00
|
|
|
|
2024-01-09 17:35:31 +01:00
|
|
|
pub(crate) const fn op_flags() -> Range<usize> {
|
|
|
|
|
IS_ADD..IS_RANGE_CHECK + 1
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-29 11:56:48 +10:00
|
|
|
/// Within the Arithmetic Unit, there are shared columns which can be
|
|
|
|
|
/// used by any arithmetic circuit, depending on which one is active
|
2022-12-02 17:11:31 +11:00
|
|
|
/// this cycle.
|
|
|
|
|
///
|
2023-01-31 02:23:24 +11:00
|
|
|
/// Modular arithmetic takes 11 * N_LIMBS columns which is split across
|
|
|
|
|
/// two rows, the first with 6 * N_LIMBS columns and the second with
|
|
|
|
|
/// 5 * N_LIMBS columns. (There are hence N_LIMBS "wasted columns" in
|
2022-12-02 17:11:31 +11:00
|
|
|
/// the second row.)
|
2023-01-31 02:23:24 +11:00
|
|
|
pub(crate) const NUM_SHARED_COLS: usize = 6 * N_LIMBS;
|
|
|
|
|
pub(crate) const SHARED_COLS: Range<usize> = START_SHARED_COLS..START_SHARED_COLS + NUM_SHARED_COLS;
|
2022-10-12 02:39:13 +11:00
|
|
|
|
Cross-table lookup for arithmetic stark (#905)
* First draft of linking arithmetic Stark into the CTL mechanism.
* Handle {ADD,SUB,MUL}FP254 operations explicitly in `modular.rs`.
* Adjust argument order; add tests.
* Add CTLs for ADD, MUL, SUB, LT and GT.
* Add CTLs for {ADD,MUL,SUB}MOD, DIV and MOD.
* Add CTLs for {ADD,MUL,SUB}FP254 operations.
* Refactor the CPU/arithmetic CTL mapping; add some documentation.
* Minor comment fixes.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Merge `*FP254` CTL into main CTL; rename some registers.
* Connect extra argument from CPU in binary ops to facilitate combining with ternary ops.
* Merge modular ops CTL into main CTL.
* Refactor DIV and MOD code into its own module.
* Merge DIV and MOD into arithmetic CTL.
* Clippy.
* Fixes related to merge.
* Simplify register naming.
* Generate u16 BN254 modulus limbs at compile time.
* Clippy.
* Add degree bits ranges for Arithmetic table.
2023-05-11 03:29:06 +10:00
|
|
|
pub(crate) const INPUT_REGISTER_0: Range<usize> = START_SHARED_COLS..START_SHARED_COLS + N_LIMBS;
|
|
|
|
|
pub(crate) const INPUT_REGISTER_1: Range<usize> =
|
|
|
|
|
INPUT_REGISTER_0.end..INPUT_REGISTER_0.end + N_LIMBS;
|
|
|
|
|
pub(crate) const INPUT_REGISTER_2: Range<usize> =
|
|
|
|
|
INPUT_REGISTER_1.end..INPUT_REGISTER_1.end + N_LIMBS;
|
|
|
|
|
pub(crate) const OUTPUT_REGISTER: Range<usize> =
|
|
|
|
|
INPUT_REGISTER_2.end..INPUT_REGISTER_2.end + N_LIMBS;
|
|
|
|
|
|
|
|
|
|
// NB: Only one of AUX_INPUT_REGISTER_[01] or AUX_INPUT_REGISTER_DBL
|
|
|
|
|
// will be used for a given operation since they overlap
|
|
|
|
|
pub(crate) const AUX_INPUT_REGISTER_0: Range<usize> =
|
|
|
|
|
OUTPUT_REGISTER.end..OUTPUT_REGISTER.end + N_LIMBS;
|
|
|
|
|
pub(crate) const AUX_INPUT_REGISTER_1: Range<usize> =
|
|
|
|
|
AUX_INPUT_REGISTER_0.end..AUX_INPUT_REGISTER_0.end + N_LIMBS;
|
|
|
|
|
pub(crate) const AUX_INPUT_REGISTER_DBL: Range<usize> =
|
|
|
|
|
OUTPUT_REGISTER.end..OUTPUT_REGISTER.end + 2 * N_LIMBS;
|
2022-12-02 17:11:31 +11:00
|
|
|
|
|
|
|
|
// The auxiliary input columns overlap the general input columns
|
|
|
|
|
// because they correspond to the values in the second row for modular
|
|
|
|
|
// operations.
|
2023-02-07 23:52:58 +11:00
|
|
|
const AUX_REGISTER_0: Range<usize> = START_SHARED_COLS..START_SHARED_COLS + N_LIMBS;
|
|
|
|
|
const AUX_REGISTER_1: Range<usize> = AUX_REGISTER_0.end..AUX_REGISTER_0.end + 2 * N_LIMBS;
|
|
|
|
|
const AUX_REGISTER_2: Range<usize> = AUX_REGISTER_1.end..AUX_REGISTER_1.end + 2 * N_LIMBS - 1;
|
2023-01-31 02:23:24 +11:00
|
|
|
|
2023-02-07 23:52:58 +11:00
|
|
|
// Each element c of {MUL,MODULAR}_AUX_REGISTER is -2^20 <= c <= 2^20;
|
2023-01-31 02:23:24 +11:00
|
|
|
// this value is used as an offset so that everything is positive in
|
|
|
|
|
// the range checks.
|
|
|
|
|
pub(crate) const AUX_COEFF_ABS_MAX: i64 = 1 << 20;
|
2022-10-12 02:39:13 +11:00
|
|
|
|
2023-01-31 02:23:24 +11:00
|
|
|
// MUL takes 5 * N_LIMBS = 80 columns
|
Cross-table lookup for arithmetic stark (#905)
* First draft of linking arithmetic Stark into the CTL mechanism.
* Handle {ADD,SUB,MUL}FP254 operations explicitly in `modular.rs`.
* Adjust argument order; add tests.
* Add CTLs for ADD, MUL, SUB, LT and GT.
* Add CTLs for {ADD,MUL,SUB}MOD, DIV and MOD.
* Add CTLs for {ADD,MUL,SUB}FP254 operations.
* Refactor the CPU/arithmetic CTL mapping; add some documentation.
* Minor comment fixes.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Merge `*FP254` CTL into main CTL; rename some registers.
* Connect extra argument from CPU in binary ops to facilitate combining with ternary ops.
* Merge modular ops CTL into main CTL.
* Refactor DIV and MOD code into its own module.
* Merge DIV and MOD into arithmetic CTL.
* Clippy.
* Fixes related to merge.
* Simplify register naming.
* Generate u16 BN254 modulus limbs at compile time.
* Clippy.
* Add degree bits ranges for Arithmetic table.
2023-05-11 03:29:06 +10:00
|
|
|
pub(crate) const MUL_AUX_INPUT_LO: Range<usize> = AUX_INPUT_REGISTER_0;
|
|
|
|
|
pub(crate) const MUL_AUX_INPUT_HI: Range<usize> = AUX_INPUT_REGISTER_1;
|
2022-10-12 02:39:13 +11:00
|
|
|
|
2023-01-31 02:23:24 +11:00
|
|
|
// MULMOD takes 4 * N_LIMBS + 3 * 2*N_LIMBS + N_LIMBS = 176 columns
|
|
|
|
|
// but split over two rows of 96 columns and 80 columns.
|
2022-12-02 17:11:31 +11:00
|
|
|
//
|
|
|
|
|
// ADDMOD, SUBMOD, MOD and DIV are currently implemented in terms of
|
|
|
|
|
// the general modular code, so they also take 144 columns (also split
|
|
|
|
|
// over two rows).
|
Cross-table lookup for arithmetic stark (#905)
* First draft of linking arithmetic Stark into the CTL mechanism.
* Handle {ADD,SUB,MUL}FP254 operations explicitly in `modular.rs`.
* Adjust argument order; add tests.
* Add CTLs for ADD, MUL, SUB, LT and GT.
* Add CTLs for {ADD,MUL,SUB}MOD, DIV and MOD.
* Add CTLs for {ADD,MUL,SUB}FP254 operations.
* Refactor the CPU/arithmetic CTL mapping; add some documentation.
* Minor comment fixes.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Combine addcy CTLs at the expense of repeated constraint evaluation.
* Merge `*FP254` CTL into main CTL; rename some registers.
* Connect extra argument from CPU in binary ops to facilitate combining with ternary ops.
* Merge modular ops CTL into main CTL.
* Refactor DIV and MOD code into its own module.
* Merge DIV and MOD into arithmetic CTL.
* Clippy.
* Fixes related to merge.
* Simplify register naming.
* Generate u16 BN254 modulus limbs at compile time.
* Clippy.
* Add degree bits ranges for Arithmetic table.
2023-05-11 03:29:06 +10:00
|
|
|
pub(crate) const MODULAR_INPUT_0: Range<usize> = INPUT_REGISTER_0;
|
|
|
|
|
pub(crate) const MODULAR_INPUT_1: Range<usize> = INPUT_REGISTER_1;
|
|
|
|
|
pub(crate) const MODULAR_MODULUS: Range<usize> = INPUT_REGISTER_2;
|
|
|
|
|
pub(crate) const MODULAR_OUTPUT: Range<usize> = OUTPUT_REGISTER;
|
|
|
|
|
pub(crate) const MODULAR_QUO_INPUT: Range<usize> = AUX_INPUT_REGISTER_DBL;
|
2023-02-07 23:52:58 +11:00
|
|
|
pub(crate) const MODULAR_OUT_AUX_RED: Range<usize> = AUX_REGISTER_0;
|
2022-10-12 02:39:13 +11:00
|
|
|
// NB: Last value is not used in AUX, it is used in MOD_IS_ZERO
|
2023-02-07 23:52:58 +11:00
|
|
|
pub(crate) const MODULAR_MOD_IS_ZERO: usize = AUX_REGISTER_1.start;
|
|
|
|
|
pub(crate) const MODULAR_AUX_INPUT_LO: Range<usize> = AUX_REGISTER_1.start + 1..AUX_REGISTER_1.end;
|
|
|
|
|
pub(crate) const MODULAR_AUX_INPUT_HI: Range<usize> = AUX_REGISTER_2;
|
2023-10-05 09:56:56 -04:00
|
|
|
// Must be set to MOD_IS_ZERO for DIV and SHR operations i.e. MOD_IS_ZERO * (lv[IS_DIV] + lv[IS_SHR]).
|
2023-02-07 23:52:58 +11:00
|
|
|
pub(crate) const MODULAR_DIV_DENOM_IS_ZERO: usize = AUX_REGISTER_2.end;
|
2022-08-26 09:13:47 +10:00
|
|
|
|
2023-09-29 11:24:36 -04:00
|
|
|
/// The counter column (used for the range check) starts from 0 and increments.
|
2023-01-31 02:23:24 +11:00
|
|
|
pub(crate) const RANGE_COUNTER: usize = START_SHARED_COLS + NUM_SHARED_COLS;
|
2023-09-29 11:24:36 -04:00
|
|
|
/// The frequencies column used in logUp.
|
2023-02-13 15:58:26 +01:00
|
|
|
pub(crate) const RC_FREQUENCIES: usize = RANGE_COUNTER + 1;
|
2023-01-31 02:23:24 +11:00
|
|
|
|
2023-10-30 14:28:24 -04:00
|
|
|
/// Number of columns in `ArithmeticStark`.
|
2023-11-17 15:45:38 -05:00
|
|
|
pub(crate) const NUM_ARITH_COLUMNS: usize = START_SHARED_COLS + NUM_SHARED_COLS + 2;
|