arcium-primitives 0.8.1

Arcium primitives
Documentation
use ff::PrimeField;
use serde::{Deserialize, Serialize};

#[derive(PrimeField, Serialize, Deserialize)]
#[PrimeFieldModulus = "39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319"]
#[PrimeFieldGenerator = "19"]
#[PrimeFieldReprEndianness = "little"]
#[repr(C)]
pub struct BaseFieldP384([u64; 7]);

impl_p384_field!(BaseFieldP384, BaseFieldP384Repr, "P384_BaseField");

#[cfg(test)]
mod tests {
    use ff::Field;

    use super::*;
    use crate::{
        algebra::field::FieldExtension,
        random::{test_rng, Random},
    };

    #[test]
    fn test_le_bytes_roundtrip() {
        let mut rng = test_rng();
        let element: BaseFieldP384 = Random::random(&mut rng);
        let bytes = element.to_le_bytes();
        assert_eq!(BaseFieldP384::from_le_bytes(&bytes), Some(element));

        // Non-canonical (>= modulus) encodings are rejected.
        assert_eq!(BaseFieldP384::from_le_bytes(&[0xFF; 48]), None);
    }

    #[test]
    fn test_sqrt() {
        let mut rng = test_rng();
        for _ in 0..20 {
            let element: BaseFieldP384 = Random::random(&mut rng);
            let square = element.square();
            let root = square.sqrt().unwrap();
            assert_eq!(root * root, square);
        }
    }

    #[test]
    fn test_from_uniform_bytes_matches_bigint_reduction() {
        use rand::RngCore;

        use crate::algebra::uniform_bytes::FromUniformBytes;
        let mut rng = test_rng();
        let modulus = num_bigint::BigUint::from_bytes_be(&hex::decode(
            "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
        ).unwrap());
        for _ in 0..20 {
            let mut bytes = [0u8; 64];
            rng.fill_bytes(&mut bytes);
            let result = BaseFieldP384::from_uniform_bytes(&hybrid_array::Array::from(bytes));
            let expected = num_bigint::BigUint::from_bytes_le(&bytes) % &modulus;
            let mut expected_le = expected.to_bytes_le();
            expected_le.resize(48, 0);
            assert_eq!(BaseFieldP384::from_le_bytes(&expected_le), Some(result));
        }
    }
}