Skip to content

Commit c45e470

Browse files
rename structs and switch to num-bigint
1 parent 87757aa commit c45e470

File tree

12 files changed

+136
-63
lines changed

12 files changed

+136
-63
lines changed

Cargo.lock

Lines changed: 0 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/algebra/openvm/app.vmexe

146 KB
Binary file not shown.

examples/i256/openvm/app.vmexe

254 KB
Binary file not shown.

extensions/ecc/circuit/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ openvm-rv32-adapters = { workspace = true }
2121
openvm-ecc-transpiler = { workspace = true }
2222

2323
num-bigint = { workspace = true }
24-
num-bigint-dig = { workspace = true }
2524
num-traits = { workspace = true }
2625
strum = { workspace = true }
2726
derive_more = { workspace = true }

extensions/ecc/circuit/src/ecc_extension.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use serde::{Deserialize, Serialize};
2525
use serde_with::{serde_as, DisplayFromStr};
2626
use strum::EnumCount;
2727

28-
use super::{EcAddNeChip, EcDoubleChip, TeEcAddChip};
28+
use super::{SwAddNeChip, SwDoubleChip, TeAddChip};
2929

3030
#[serde_as]
3131
#[derive(Clone, Debug, derive_new::new, Serialize, Deserialize)]
@@ -95,15 +95,15 @@ pub struct EccExtension {
9595
#[derive(Chip, ChipUsageGetter, InstructionExecutor, AnyEnum, BytesStateful)]
9696
pub enum EccExtensionExecutor<F: PrimeField32> {
9797
// 32 limbs prime
98-
SwEcAddNeRv32_32(EcAddNeChip<F, 2, 32>),
99-
SwEcDoubleRv32_32(EcDoubleChip<F, 2, 32>),
98+
SwEcAddNeRv32_32(SwAddNeChip<F, 2, 32>),
99+
SwEcDoubleRv32_32(SwDoubleChip<F, 2, 32>),
100100
// 48 limbs prime
101-
SwEcAddNeRv32_48(EcAddNeChip<F, 6, 16>),
102-
SwEcDoubleRv32_48(EcDoubleChip<F, 6, 16>),
101+
SwEcAddNeRv32_48(SwAddNeChip<F, 6, 16>),
102+
SwEcDoubleRv32_48(SwDoubleChip<F, 6, 16>),
103103
// 32 limbs prime
104-
TeEcAddRv32_32(TeEcAddChip<F, 2, 32>),
104+
TeEcAddRv32_32(TeAddChip<F, 2, 32>),
105105
// 48 limbs prime
106-
TeEcAddRv32_48(TeEcAddChip<F, 6, 16>),
106+
TeEcAddRv32_48(TeAddChip<F, 6, 16>),
107107
}
108108

109109
#[derive(ChipUsageGetter, Chip, AnyEnum, From, BytesStateful)]
@@ -170,7 +170,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
170170
if bytes <= 32 {
171171
match curve.coeffs.clone() {
172172
CurveCoeffs::SwCurve(SwCurveConfig { a, b: _ }) => {
173-
let sw_add_ne_chip = EcAddNeChip::new(
173+
let sw_add_ne_chip = SwAddNeChip::new(
174174
Rv32VecHeapAdapterChip::<F, 2, 2, 2, 32, 32>::new(
175175
execution_bus,
176176
program_bus,
@@ -189,7 +189,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
189189
.clone()
190190
.map(|x| VmOpcode::from_usize(x + sw_start_offset)),
191191
)?;
192-
let sw_double_chip = EcDoubleChip::new(
192+
let sw_double_chip = SwDoubleChip::new(
193193
Rv32VecHeapAdapterChip::<F, 1, 2, 2, 32, 32>::new(
194194
execution_bus,
195195
program_bus,
@@ -212,7 +212,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
212212
}
213213

214214
CurveCoeffs::TeCurve(TeCurveConfig { a, d }) => {
215-
let te_add_chip = TeEcAddChip::new(
215+
let te_add_chip = TeAddChip::new(
216216
Rv32VecHeapAdapterChip::<F, 2, 2, 2, 32, 32>::new(
217217
execution_bus,
218218
program_bus,
@@ -238,7 +238,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
238238
} else if bytes <= 48 {
239239
match curve.coeffs.clone() {
240240
CurveCoeffs::SwCurve(SwCurveConfig { a, b: _ }) => {
241-
let sw_add_ne_chip = EcAddNeChip::new(
241+
let sw_add_ne_chip = SwAddNeChip::new(
242242
Rv32VecHeapAdapterChip::<F, 2, 6, 6, 16, 16>::new(
243243
execution_bus,
244244
program_bus,
@@ -257,7 +257,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
257257
.clone()
258258
.map(|x| VmOpcode::from_usize(x + sw_start_offset)),
259259
)?;
260-
let sw_double_chip = EcDoubleChip::new(
260+
let sw_double_chip = SwDoubleChip::new(
261261
Rv32VecHeapAdapterChip::<F, 1, 6, 6, 16, 16>::new(
262262
execution_bus,
263263
program_bus,
@@ -280,7 +280,7 @@ impl<F: PrimeField32> VmExtension<F> for EccExtension {
280280
}
281281

282282
CurveCoeffs::TeCurve(TeCurveConfig { a, d }) => {
283-
let te_add_chip = TeEcAddChip::new(
283+
let te_add_chip = TeAddChip::new(
284284
Rv32VecHeapAdapterChip::<F, 2, 6, 6, 16, 16>::new(
285285
execution_bus,
286286
program_bus,

extensions/ecc/circuit/src/edwards_chip/mod.rs

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
mod add;
22
pub use add::*;
33

4+
mod utils;
5+
46
#[cfg(test)]
57
mod tests;
68

79
use std::sync::{Arc, Mutex};
810

11+
use num_bigint::{BigInt, BigUint};
912
use openvm_circuit::{arch::VmChipWrapper, system::memory::OfflineMemory};
1013
use openvm_circuit_derive::InstructionExecutor;
1114
use openvm_circuit_primitives::var_range::SharedVariableRangeCheckerChip;
@@ -14,27 +17,23 @@ use openvm_ecc_transpiler::Rv32EdwardsOpcode;
1417
use openvm_mod_circuit_builder::{ExprBuilderConfig, FieldExpressionCoreChip};
1518
use openvm_rv32_adapters::Rv32VecHeapAdapterChip;
1619
use openvm_stark_backend::p3_field::PrimeField32;
20+
use utils::jacobi;
1721

1822
/// BLOCK_SIZE: how many cells do we read at a time, must be a power of 2.
1923
/// BLOCKS: how many blocks do we need to represent one input or output
2024
/// For example, for bls12_381, BLOCK_SIZE = 16, each element has 3 blocks and with two elements per input AffinePoint, BLOCKS = 6.
2125
/// For secp256k1, BLOCK_SIZE = 32, BLOCKS = 2.
2226
#[derive(Chip, ChipUsageGetter, InstructionExecutor, BytesStateful)]
23-
pub struct TeEcAddChip<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>(
27+
pub struct TeAddChip<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>(
2428
VmChipWrapper<
2529
F,
2630
Rv32VecHeapAdapterChip<F, 2, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
2731
FieldExpressionCoreChip,
2832
>,
2933
);
3034

31-
// converts from num_bigint::BigUint to num_bigint_dig::BigInt in order to use num_bigint_dig::algorithms::jacobi
32-
fn num_bigint_to_num_bigint_dig(x: &num_bigint::BigUint) -> num_bigint_dig::BigInt {
33-
num_bigint_dig::BigInt::from_bytes_le(num_bigint_dig::Sign::Plus, &x.to_bytes_le())
34-
}
35-
3635
impl<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>
37-
TeEcAddChip<F, BLOCKS, BLOCK_SIZE>
36+
TeAddChip<F, BLOCKS, BLOCK_SIZE>
3837
{
3938
pub fn new(
4039
adapter: Rv32VecHeapAdapterChip<F, 2, BLOCKS, BLOCKS, BLOCK_SIZE, BLOCK_SIZE>,
@@ -46,18 +45,8 @@ impl<F: PrimeField32, const BLOCKS: usize, const BLOCK_SIZE: usize>
4645
offline_memory: Arc<Mutex<OfflineMemory<F>>>,
4746
) -> Self {
4847
// Ensure that the addition operation is complete
49-
assert!(
50-
num_bigint_dig::algorithms::jacobi(
51-
&num_bigint_to_num_bigint_dig(&a),
52-
&num_bigint_to_num_bigint_dig(&config.modulus)
53-
) == 1
54-
);
55-
assert!(
56-
num_bigint_dig::algorithms::jacobi(
57-
&num_bigint_to_num_bigint_dig(&d),
58-
&num_bigint_to_num_bigint_dig(&config.modulus)
59-
) == -1
60-
);
48+
assert!(jacobi(&a.clone().into(), &config.modulus.clone().into()) == 1);
49+
assert!(jacobi(&d.clone().into(), &config.modulus.clone().into()) == -1);
6150

6251
let expr = ec_add_expr(config, range_checker.bus(), a, d);
6352
let core = FieldExpressionCoreChip::new(

extensions/ecc/circuit/src/edwards_chip/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use openvm_rv32_adapters::{rv32_write_heap_default, Rv32VecHeapAdapterChip};
1414
use openvm_stark_backend::p3_field::FieldAlgebra;
1515
use openvm_stark_sdk::p3_baby_bear::BabyBear;
1616

17-
use super::TeEcAddChip;
17+
use super::TeAddChip;
1818

1919
const NUM_LIMBS: usize = 32;
2020
const LIMB_BITS: usize = 8;
@@ -118,7 +118,7 @@ fn test_add() {
118118
tester.address_bits(),
119119
bitwise_chip.clone(),
120120
);
121-
let mut chip = TeEcAddChip::new(
121+
let mut chip = TeAddChip::new(
122122
adapter,
123123
config,
124124
Rv32EdwardsOpcode::CLASS_OFFSET,
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use num_bigint::BigInt;
2+
use num_integer::Integer;
3+
use num_traits::{sign::Signed, One, Zero};
4+
5+
/// Jacobi returns the Jacobi symbol (x/y), either +1, -1, or 0.
6+
/// The y argument must be an odd integer.
7+
pub fn jacobi(x: &BigInt, y: &BigInt) -> isize {
8+
if !y.is_odd() {
9+
panic!(
10+
"invalid arguments, y must be an odd integer,but got {:?}",
11+
y
12+
);
13+
}
14+
15+
let mut a = x.clone();
16+
let mut b = y.clone();
17+
let mut j = 1;
18+
19+
if b.is_negative() {
20+
if a.is_negative() {
21+
j = -1;
22+
}
23+
b = -b;
24+
}
25+
26+
loop {
27+
if b.is_one() {
28+
return j;
29+
}
30+
if a.is_zero() {
31+
return 0;
32+
}
33+
34+
a = a.mod_floor(&b);
35+
if a.is_zero() {
36+
return 0;
37+
}
38+
39+
// a > 0
40+
41+
// handle factors of 2 in a
42+
let s = a.trailing_zeros().unwrap();
43+
if s & 1 != 0 {
44+
//let bmod8 = b.get_limb(0) & 7;
45+
let bmod8 = mod_2_to_the_k(&b, 3);
46+
if bmod8 == BigInt::from(3) || bmod8 == BigInt::from(5) {
47+
j = -j;
48+
}
49+
}
50+
51+
let c = &a >> s; // a = 2^s*c
52+
53+
// swap numerator and denominator
54+
if mod_2_to_the_k(&b, 2) == BigInt::from(3) && mod_2_to_the_k(&c, 2) == BigInt::from(3) {
55+
j = -j
56+
}
57+
58+
a = b;
59+
b = c;
60+
}
61+
}
62+
63+
fn mod_2_to_the_k(x: &BigInt, k: u32) -> BigInt {
64+
x & BigInt::from(2u32.pow(k) - 1)
65+
}
66+
#[cfg(test)]
67+
mod tests {
68+
use num_traits::FromPrimitive;
69+
70+
use super::*;
71+
72+
#[test]
73+
fn test_jacobi() {
74+
let cases = [
75+
[0, 1, 1],
76+
[0, -1, 1],
77+
[1, 1, 1],
78+
[1, -1, 1],
79+
[0, 5, 0],
80+
[1, 5, 1],
81+
[2, 5, -1],
82+
[-2, 5, -1],
83+
[2, -5, -1],
84+
[-2, -5, 1],
85+
[3, 5, -1],
86+
[5, 5, 0],
87+
[-5, 5, 0],
88+
[6, 5, 1],
89+
[6, -5, 1],
90+
[-6, 5, 1],
91+
[-6, -5, -1],
92+
];
93+
94+
for case in cases.iter() {
95+
let x = BigInt::from_i64(case[0]).unwrap();
96+
let y = BigInt::from_i64(case[1]).unwrap();
97+
98+
assert_eq!(case[2] as isize, jacobi(&x, &y), "jacobi({}, {})", x, y);
99+
}
100+
}
101+
}

extensions/ecc/circuit/src/weierstrass_chip/add_ne.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{cell::RefCell, rc::Rc};
33
use openvm_circuit_primitives::var_range::VariableRangeCheckerBus;
44
use openvm_mod_circuit_builder::{ExprBuilder, ExprBuilderConfig, FieldExpr};
55

6-
pub fn ec_add_ne_expr(
6+
pub fn sw_add_ne_expr(
77
config: ExprBuilderConfig, // The coordinate field.
88
range_bus: VariableRangeCheckerBus,
99
) -> FieldExpr {

extensions/ecc/circuit/src/weierstrass_chip/double.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use num_traits::One;
55
use openvm_circuit_primitives::var_range::VariableRangeCheckerBus;
66
use openvm_mod_circuit_builder::{ExprBuilder, ExprBuilderConfig, FieldExpr, FieldVariable};
77

8-
pub fn ec_double_ne_expr(
8+
pub fn sw_double_ne_expr(
99
config: ExprBuilderConfig, // The coordinate field.
1010
range_bus: VariableRangeCheckerBus,
1111
a_biguint: BigUint,

0 commit comments

Comments
 (0)