Skip to content

Commit a67e46d

Browse files
Merge branch 'main' into feat/edwards-curve-support
2 parents d4beb7e + 9ef822c commit a67e46d

File tree

45 files changed

+748
-192
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+748
-192
lines changed

Cargo.lock

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

benchmarks/guest/kitchen-sink/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ pub fn main() {
9797

9898
let mut bytes = [0u8; 32];
9999
bytes[7] = 1 << 5; // 2^61 = modulus + 1
100-
let mut res = Mersenne61::from_le_bytes(&bytes); // No need to start from reduced representation
100+
let mut res = Mersenne61::from_le_bytes_unchecked(&bytes); // No need to start from reduced representation
101101
for _ in 0..61 {
102102
res += res.clone();
103103
}

benchmarks/guest/pairing/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ pub fn main() {
4343
// SAFETY: We're reading `6 * 32 == PAIR_ELEMENT_LEN` bytes from `input[idx..]`
4444
// per iteration. This is guaranteed to be in-bounds.
4545
let slice = unsafe { input.get_unchecked(start..start + 32) };
46-
Fp::from_be_bytes(&slice[..32])
46+
Fp::from_be_bytes_unchecked(&slice[..32])
4747
};
4848
// https://eips.ethereum.org/EIPS/eip-197, Fp2 is encoded as (a, b) where a * i + b
4949
let g1_x = read_fq_at(0);

book/src/custom-extensions/algebra.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ The functional part is provided by the `openvm-algebra-guest` crate, which is a
1212
- `Repr` typically is `[u8; NUM_LIMBS]`, representing the number's underlying storage.
1313
- `MODULUS` is the compile-time known modulus.
1414
- `ZERO` and `ONE` represent the additive and multiplicative identities, respectively.
15-
- Constructors include `from_repr`, `from_le_bytes`, `from_be_bytes`, `from_u8`, `from_u32`, and `from_u64`.
15+
- Constructors include `from_repr`, `from_le_bytes`, `from_be_bytes`, `from_le_bytes_unchecked`, `from_be_bytes_unchecked`, `from_u8`, `from_u32`, and `from_u64`.
1616

1717
- `Field` trait:
1818
Provides constants `ZERO` and `ONE` and methods for basic arithmetic operations within a field.

examples/ecc/src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@ openvm_ecc_guest::te_macros::te_init! { Ed25519Point }
2424
// ANCHOR: main
2525
pub fn main() {
2626
let x1 = Secp256k1Coord::from_u32(1);
27-
let y1 = Secp256k1Coord::from_le_bytes(&hex!(
27+
let y1 = Secp256k1Coord::from_le_bytes_unchecked(&hex!(
2828
"EEA7767E580D75BC6FDD7F58D2A84C2614FB22586068DB63B346C6E60AF21842"
2929
));
3030
let p1 = Secp256k1Point::from_xy_nonidentity(x1, y1).unwrap();
3131

3232
let x2 = Secp256k1Coord::from_u32(2);
33-
let y2 = Secp256k1Coord::from_le_bytes(&hex!(
33+
let y2 = Secp256k1Coord::from_le_bytes_unchecked(&hex!(
3434
"D1A847A8F879E0AEE32544DA5BA0B3BD1703A1F52867A5601FF6454DD8180499"
3535
));
3636
let p2 = Secp256k1Point::from_xy_nonidentity(x2, y2).unwrap();

examples/pairing/src/main.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,31 @@ openvm_algebra_complex_macros::complex_init! {
2727
// ANCHOR: main
2828
pub fn main() {
2929
let p0 = AffinePoint::new(
30-
Fp::from_be_bytes(&hex!("17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb")),
31-
Fp::from_be_bytes(&hex!("08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"))
30+
Fp::from_be_bytes_unchecked(&hex!("17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb")),
31+
Fp::from_be_bytes_unchecked(&hex!("08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"))
3232
);
3333
let p1 = AffinePoint::new(
3434
Fp2::from_coeffs([
35-
Fp::from_be_bytes(&hex!("1638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053")),
36-
Fp::from_be_bytes(&hex!("0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"))
35+
Fp::from_be_bytes_unchecked(&hex!("1638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a053")),
36+
Fp::from_be_bytes_unchecked(&hex!("0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c33577"))
3737
]),
3838
Fp2::from_coeffs([
39-
Fp::from_be_bytes(&hex!("0468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899")),
40-
Fp::from_be_bytes(&hex!("0f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"))
39+
Fp::from_be_bytes_unchecked(&hex!("0468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899")),
40+
Fp::from_be_bytes_unchecked(&hex!("0f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf3"))
4141
]),
4242
);
4343
let q0 = AffinePoint::new(
44-
Fp::from_be_bytes(&hex!("0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e")),
45-
Fp::from_be_bytes(&hex!("166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"))
44+
Fp::from_be_bytes_unchecked(&hex!("0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e")),
45+
Fp::from_be_bytes_unchecked(&hex!("166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"))
4646
);
4747
let q1 = AffinePoint::new(
4848
Fp2::from_coeffs([
49-
Fp::from_be_bytes(&hex!("024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8")),
50-
Fp::from_be_bytes(&hex!("13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e"))
49+
Fp::from_be_bytes_unchecked(&hex!("024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8")),
50+
Fp::from_be_bytes_unchecked(&hex!("13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e"))
5151
]),
5252
Fp2::from_coeffs([
53-
Fp::from_be_bytes(&hex!("0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801")),
54-
Fp::from_be_bytes(&hex!("0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"))
53+
Fp::from_be_bytes_unchecked(&hex!("0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801")),
54+
Fp::from_be_bytes_unchecked(&hex!("0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be"))
5555
]),
5656
);
5757

extensions/algebra/guest/src/lib.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,21 @@ pub trait IntMod:
151151
/// Does not enforce the integer value of `bytes` must be less than the modulus.
152152
fn from_repr(repr: Self::Repr) -> Self;
153153

154+
/// Creates a new IntMod from an array of bytes, little endian.
155+
/// Returns `None` if the integer value of `bytes` is greater than or equal to the modulus.
156+
fn from_le_bytes(bytes: &[u8]) -> Option<Self>;
157+
158+
/// Creates a new IntMod from an array of bytes, big endian.
159+
/// Returns `None` if the integer value of `bytes` is greater than or equal to the modulus.
160+
fn from_be_bytes(bytes: &[u8]) -> Option<Self>;
161+
154162
/// Creates a new IntMod from an array of bytes, little endian.
155163
/// Does not enforce the integer value of `bytes` must be less than the modulus.
156-
fn from_le_bytes(bytes: &[u8]) -> Self;
164+
fn from_le_bytes_unchecked(bytes: &[u8]) -> Self;
157165

158166
/// Creates a new IntMod from an array of bytes, big endian.
159167
/// Does not enforce the integer value of `bytes` must be less than the modulus.
160-
fn from_be_bytes(bytes: &[u8]) -> Self;
168+
fn from_be_bytes_unchecked(bytes: &[u8]) -> Self;
161169

162170
/// Creates a new IntMod from a u8.
163171
/// Does not enforce the integer value of `bytes` must be less than the modulus.

extensions/algebra/moduli-macros/src/lib.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -391,13 +391,31 @@ pub fn moduli_declare(input: TokenStream) -> TokenStream {
391391
Self(repr)
392392
}
393393

394-
fn from_le_bytes(bytes: &[u8]) -> Self {
394+
fn from_le_bytes(bytes: &[u8]) -> Option<Self> {
395+
let elt = Self::from_le_bytes_unchecked(bytes);
396+
if elt.is_reduced() {
397+
Some(elt)
398+
} else {
399+
None
400+
}
401+
}
402+
403+
fn from_be_bytes(bytes: &[u8]) -> Option<Self> {
404+
let elt = Self::from_be_bytes_unchecked(bytes);
405+
if elt.is_reduced() {
406+
Some(elt)
407+
} else {
408+
None
409+
}
410+
}
411+
412+
fn from_le_bytes_unchecked(bytes: &[u8]) -> Self {
395413
let mut arr = [0u8; #limbs];
396414
arr.copy_from_slice(bytes);
397415
Self(arr)
398416
}
399417

400-
fn from_be_bytes(bytes: &[u8]) -> Self {
418+
fn from_be_bytes_unchecked(bytes: &[u8]) -> Self {
401419
let mut arr = [0u8; #limbs];
402420
for (a, b) in arr.iter_mut().zip(bytes.iter().rev()) {
403421
*a = *b;
@@ -761,11 +779,12 @@ pub fn moduli_declare(input: TokenStream) -> TokenStream {
761779
fn reduce_le_bytes(bytes: &[u8]) -> Self {
762780
let mut res = <Self as openvm_algebra_guest::IntMod>::ZERO;
763781
// base should be 2 ^ #limbs which exceeds what Self can represent
764-
let mut base = <Self as openvm_algebra_guest::IntMod>::from_le_bytes(&[255u8; #limbs]);
782+
let mut base = <Self as openvm_algebra_guest::IntMod>::from_le_bytes_unchecked(&[255u8; #limbs]);
765783
base += <Self as openvm_algebra_guest::IntMod>::ONE;
766784
for chunk in bytes.chunks(#limbs).rev() {
767-
res = res * &base + <Self as openvm_algebra_guest::IntMod>::from_le_bytes(chunk);
785+
res = res * &base + <Self as openvm_algebra_guest::IntMod>::from_le_bytes_unchecked(chunk);
768786
}
787+
openvm_algebra_guest::IntMod::assert_reduced(&res);
769788
res
770789
}
771790
}

extensions/algebra/tests/programs/examples/little.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn main() {
3434
assert_eq!(res, inv);
3535

3636
let two = Secp256k1Coord::from_u32(2);
37-
let minus_two = Secp256k1Coord::from_le_bytes(&pow);
37+
let minus_two = Secp256k1Coord::from_le_bytes_unchecked(&pow);
3838

3939
assert_eq!(res - &minus_two, inv + &two);
4040

extensions/algebra/tests/programs/examples/moduli_setup.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,18 @@ pub fn main() {
3232
}
3333
assert_eq!(res, Mersenne61::from_u32(1));
3434

35-
let mut non_reduced = Mersenne61::from_le_bytes(&[0xff; 32]);
35+
let mut non_reduced = Mersenne61::from_le_bytes_unchecked(&[0xff; 32]);
3636
assert!(!non_reduced.is_reduced());
3737
let reduced = &non_reduced + &Mersenne61::ZERO;
3838
reduced.assert_reduced();
3939

4040
assert_eq!(&non_reduced + &non_reduced, reduced.double());
4141

42-
non_reduced = Mersenne61::from_le_bytes(&Mersenne61::MODULUS);
42+
non_reduced = Mersenne61::from_le_bytes_unchecked(&Mersenne61::MODULUS);
4343
assert!(!non_reduced.is_reduced());
4444

4545
let mut bytes = [0u8; 32];
4646
bytes[7] = 1 << 5; // 2^61 = 2^{8*7 + 5} = modulus + 1
47-
non_reduced = Mersenne61::from_le_bytes(&bytes);
47+
non_reduced = Mersenne61::from_le_bytes_unchecked(&bytes);
4848
assert!(!non_reduced.is_reduced());
4949
}

0 commit comments

Comments
 (0)