Skip to content

Commit a2d4d66

Browse files
z-techweikengchen
andauthored
Fix SmallFp from_random_bytes inconsistency with Fp (#1082)
* smallfp from random bytes fix * update comment, changelog * fmt * Update CHANGELOG.md --------- Co-authored-by: Weikeng Chen <w.k@berkeley.edu>
1 parent c402d0c commit a2d4d66

File tree

4 files changed

+42
-4
lines changed

4 files changed

+42
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
### Bugfixes
2828

29+
- [\#1082](https://github.com/arkworks-rs/algebra/pull/1082) (`ark-ff`) Fix `SmallFp::from_random_bytes` / `from_be_bytes_mod_order` silently producing incorrect field elements by treating plaintext bytes as Montgomery-encoded.
30+
2931
## v0.5.0
3032

3133
- [\#772](https://github.com/arkworks-rs/algebra/pull/772) (`ark-ff`) Implementation of `mul` method for `BigInteger`.

ff/src/fields/models/small_fp/field.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::fields::models::small_fp::small_fp_backend::{SmallFp, SmallFpConfig};
22
use crate::{Field, LegendreSymbol, One, PrimeField, SqrtPrecomputation, Zero};
3-
use ark_serialize::{buffer_byte_size, CanonicalDeserialize, EmptyFlags, Flags};
3+
use ark_serialize::{buffer_byte_size, EmptyFlags, Flags};
44
use core::iter;
55

66
impl<P: SmallFpConfig> Field for SmallFp<P> {
@@ -86,9 +86,9 @@ impl<P: SmallFpConfig> Field for SmallFp<P> {
8686
}
8787
*b &= m;
8888
}
89-
Self::deserialize_compressed(&result_bytes.as_slice()[..(P::NUM_BIG_INT_LIMBS * 8)])
90-
.ok()
91-
.and_then(|f| F::from_u8(flags).map(|flag| (f, flag)))
89+
// Use from_bigint (not deserialize_compressed) since these are plaintext bytes, not Montgomery-encoded.
90+
let bigint = result_bytes.to_bigint();
91+
Self::from_bigint(bigint).and_then(|f| F::from_u8(flags).map(|flag| (f, flag)))
9292
}
9393
}
9494

ff/src/fields/models/small_fp/small_fp_backend.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ impl<P: SmallFpConfig> ark_std::rand::distributions::Distribution<SmallFp<P>>
326326
}
327327
}
328328

329+
#[derive(Debug)]
329330
pub enum ParseSmallFpError {
330331
Empty,
331332
InvalidFormat,

test-templates/src/fields.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,41 @@ macro_rules! __test_small_field {
647647
},
648648
}
649649
}
650+
651+
#[test]
652+
fn test_from_be_bytes_mod_order() {
653+
use ark_ff::BigInteger;
654+
use ark_std::str::FromStr;
655+
use $crate::num_bigint::BigUint;
656+
use ark_std::{rand::Rng, string::ToString, vec};
657+
658+
let ref_modulus = BigUint::from_bytes_be(&<$field>::MODULUS.to_bytes_be());
659+
660+
let mut test_vectors = vec![
661+
vec![0u8],
662+
vec![1u8],
663+
vec![255u8],
664+
vec![1u8, 0u8],
665+
vec![1u8, 0u8, 255u8],
666+
];
667+
668+
// Add random bytestrings of various lengths
669+
for i in 1..64 {
670+
let mut rng = ark_std::test_rng();
671+
let data: Vec<u8> = (0..i).map(|_| rng.gen()).collect();
672+
test_vectors.push(data);
673+
}
674+
675+
for bytes in test_vectors {
676+
let mut expected_biguint = BigUint::from_bytes_be(&bytes);
677+
expected_biguint =
678+
expected_biguint.modpow(&BigUint::from_bytes_be(&[1u8]), &ref_modulus);
679+
let expected_string = expected_biguint.to_string();
680+
let expected = <$field>::from_str(&expected_string).unwrap();
681+
let actual = <$field>::from_be_bytes_mod_order(&bytes);
682+
assert_eq!(expected, actual, "from_be_bytes_mod_order failed on {:?}", bytes);
683+
}
684+
}
650685
};
651686
}
652687

0 commit comments

Comments
 (0)