Skip to main content

primitives/algebra/elliptic_curve/p384/
base_field.rs

1use ff::PrimeField;
2use serde::{Deserialize, Serialize};
3
4#[derive(PrimeField, Serialize, Deserialize)]
5#[PrimeFieldModulus = "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319"]
6#[PrimeFieldGenerator = "19"]
7#[PrimeFieldReprEndianness = "little"]
8#[repr(C)]
9pub struct BaseFieldP384([u64; 7]);
10
11impl_p384_field!(BaseFieldP384, BaseFieldP384Repr, "P384_BaseField");
12
13#[cfg(test)]
14mod tests {
15    use ff::Field;
16
17    use super::*;
18    use crate::{
19        algebra::field::FieldExtension,
20        random::{test_rng, Random},
21    };
22
23    #[test]
24    fn test_le_bytes_roundtrip() {
25        let mut rng = test_rng();
26        let element: BaseFieldP384 = Random::random(&mut rng);
27        let bytes = element.to_le_bytes();
28        assert_eq!(BaseFieldP384::from_le_bytes(&bytes), Some(element));
29
30        // Non-canonical (>= modulus) encodings are rejected.
31        assert_eq!(BaseFieldP384::from_le_bytes(&[0xFF; 48]), None);
32    }
33
34    #[test]
35    fn test_sqrt() {
36        let mut rng = test_rng();
37        for _ in 0..20 {
38            let element: BaseFieldP384 = Random::random(&mut rng);
39            let square = element.square();
40            let root = square.sqrt().unwrap();
41            assert_eq!(root * root, square);
42        }
43    }
44
45    #[test]
46    fn test_from_uniform_bytes_matches_bigint_reduction() {
47        use rand::RngCore;
48
49        use crate::algebra::uniform_bytes::FromUniformBytes;
50        let mut rng = test_rng();
51        let modulus = num_bigint::BigUint::from_bytes_be(&hex::decode(
52            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
53        ).unwrap());
54        for _ in 0..20 {
55            let mut bytes = [0u8; 64];
56            rng.fill_bytes(&mut bytes);
57            let result = BaseFieldP384::from_uniform_bytes(&hybrid_array::Array::from(bytes));
58            let expected = num_bigint::BigUint::from_bytes_le(&bytes) % &modulus;
59            let mut expected_le = expected.to_bytes_le();
60            expected_le.resize(48, 0);
61            assert_eq!(BaseFieldP384::from_le_bytes(&expected_le), Some(result));
62        }
63    }
64}