Skip to main content

primitives/algebra/elliptic_curve/p384/
base_field.rs

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