|
| 1 | +#![no_main] |
| 2 | + |
| 3 | +use libfuzzer_sys::fuzz_target; |
| 4 | +use lambdaworks_math::field::{ |
| 5 | + element::FieldElement |
| 6 | +}; |
| 7 | +use ibig::{modular::ModuloRing, UBig}; |
| 8 | +use lambdaworks_math::traits::ByteConversion; |
| 9 | +use lambdaworks_math::field::fields::montgomery_backed_prime_fields::U256PrimeField; |
| 10 | +use lambdaworks_math::unsigned_integer::element::U256; |
| 11 | +use lambdaworks_math::field::fields::montgomery_backed_prime_fields::IsModulus; |
| 12 | + |
| 13 | +#[derive(Clone, Debug, Hash, Copy)] |
| 14 | +pub struct MontgomeryConfigSecpPrimeField; |
| 15 | + |
| 16 | +impl IsModulus<U256> for MontgomeryConfigSecpPrimeField { |
| 17 | + const MODULUS: U256 = |
| 18 | + U256::from_hex_unchecked("0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F"); |
| 19 | +} |
| 20 | + |
| 21 | +pub type SecpPrimeField = U256PrimeField<MontgomeryConfigSecpPrimeField>; |
| 22 | + |
| 23 | +fuzz_target!(|bytes: ([u8;32], [u8;32])| { |
| 24 | + |
| 25 | + let secp256k1_prime = |
| 26 | + UBig::from_str_radix("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16).unwrap(); |
| 27 | + |
| 28 | + let secp256k1_ring_prime = ModuloRing::new(&secp256k1_prime); |
| 29 | + |
| 30 | + let (bytes_a, bytes_b) = bytes; |
| 31 | + let a = FieldElement::<SecpPrimeField>::from_bytes_be(&bytes_a).unwrap(); |
| 32 | + let b = FieldElement::<SecpPrimeField>::from_bytes_be(&bytes_b).unwrap(); |
| 33 | + |
| 34 | + let a_hex = a.to_string()[2..].to_string(); |
| 35 | + let b_hex = b.to_string()[2..].to_string(); |
| 36 | + |
| 37 | + let a_ring = secp256k1_ring_prime.from(&UBig::from_str_radix(&a_hex, 16).unwrap()); |
| 38 | + let b_ring = secp256k1_ring_prime.from(&UBig::from_str_radix(&b_hex, 16).unwrap()); |
| 39 | + |
| 40 | + let add = &a + &b; |
| 41 | + let addition = &a_ring + &b_ring; |
| 42 | + |
| 43 | + assert_eq!(&(add.to_string())[2..], addition.residue().in_radix(16).to_string()); |
| 44 | + |
| 45 | + let sub = &a - &b; |
| 46 | + let substraction = &a_ring - &b_ring; |
| 47 | + assert_eq!(&(sub.to_string())[2..], substraction.residue().in_radix(16).to_string()); |
| 48 | + |
| 49 | + let mul = &a * &b; |
| 50 | + let multiplication = &a_ring * &b_ring; |
| 51 | + assert_eq!(&(mul.to_string())[2..], multiplication.residue().in_radix(16).to_string()); |
| 52 | + |
| 53 | + let pow = &a.pow(b.representative()); |
| 54 | + let expected_pow = a_ring.pow(&b_ring.residue()); |
| 55 | + assert_eq!(&(pow.to_string())[2..], expected_pow.residue().in_radix(16).to_string()); |
| 56 | + |
| 57 | + if b != FieldElement::zero() { |
| 58 | + |
| 59 | + let div = &a / &b; |
| 60 | + assert_eq!(&div * &b, a.clone()); |
| 61 | + let expected_div = &a_ring / &b_ring; |
| 62 | + assert_eq!(&(div.to_string())[2..], expected_div.residue().in_radix(16).to_string()); |
| 63 | + } |
| 64 | + |
| 65 | + for n in [&a, &b] { |
| 66 | + match n.sqrt() { |
| 67 | + Some((fst_sqrt, snd_sqrt)) => { |
| 68 | + assert_eq!(fst_sqrt.square(), snd_sqrt.square(), "Squared roots don't match each other"); |
| 69 | + assert_eq!(n, &fst_sqrt.square(), "Squared roots don't match original number"); |
| 70 | + } |
| 71 | + None => {} |
| 72 | + }; |
| 73 | + } |
| 74 | + |
| 75 | + // Axioms soundness |
| 76 | + |
| 77 | + let one = FieldElement::<SecpPrimeField>::one(); |
| 78 | + let zero = FieldElement::<SecpPrimeField>::zero(); |
| 79 | + |
| 80 | + assert_eq!(&a + &zero, a, "Neutral add element a failed"); |
| 81 | + assert_eq!(&b + &zero, b, "Neutral mul element b failed"); |
| 82 | + assert_eq!(&a * &one, a, "Neutral add element a failed"); |
| 83 | + assert_eq!(&b * &one, b, "Neutral mul element b failed"); |
| 84 | + |
| 85 | + assert_eq!(&a + &b, &b + &a, "Commutative add property failed"); |
| 86 | + assert_eq!(&a * &b, &b * &a, "Commutative mul property failed"); |
| 87 | + |
| 88 | + let c = &a * &b; |
| 89 | + assert_eq!((&a + &b) + &c, &a + (&b + &c), "Associative add property failed"); |
| 90 | + assert_eq!((&a * &b) * &c, &a * (&b * &c), "Associative mul property failed"); |
| 91 | + |
| 92 | + assert_eq!(&a * (&b + &c), &a * &b + &a * &c, "Distributive property failed"); |
| 93 | + |
| 94 | + assert_eq!(&a - &a, zero, "Inverse add a failed"); |
| 95 | + assert_eq!(&b - &b, zero, "Inverse add b failed"); |
| 96 | + |
| 97 | + if a != zero { |
| 98 | + assert_eq!(&a * a.inv().unwrap(), one, "Inverse mul a failed"); |
| 99 | + } |
| 100 | + if b != zero { |
| 101 | + assert_eq!(&b * b.inv().unwrap(), one, "Inverse mul b failed"); |
| 102 | + } |
| 103 | +}); |
0 commit comments