Skip to content

Commit

Permalink
Make derive work for all odd primes.
Browse files Browse the repository at this point in the history
  • Loading branch information
VictorArcium committed Oct 10, 2024
1 parent b853db2 commit f5cbd49
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 8 deletions.
10 changes: 2 additions & 8 deletions ff_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ fn prime_field_constants_and_sqrt(
(sqrt * &sqrt).ct_eq(self), // Only return Some if it's the square root.
)
}
} else if (modulus % BigUint::from_str("16").unwrap()) == BigUint::from_str("1").unwrap() {
} else {
// Addition chain for (t - 1) // 2
let t_minus_1_over_2 = if t == BigUint::one() {
quote!( #name::ONE )
Expand All @@ -538,7 +538,7 @@ fn prime_field_constants_and_sqrt(
};

quote! {
// Tonelli-Shank's algorithm for q mod 16 = 1
// Tonelli-Shank's algorithm works for every odd prime.
// https://eprint.iacr.org/2012/685.pdf (page 12, algorithm 5)
use ::ff::derive::subtle::{ConditionallySelectable, ConstantTimeEq};

Expand Down Expand Up @@ -581,12 +581,6 @@ fn prime_field_constants_and_sqrt(
(x * &x).ct_eq(self), // Only return Some if it's the square root.
)
}
} else {
syn::Error::new_spanned(
&name,
"ff_derive can't generate a square root function for this field.",
)
.to_compile_error()
};

// Compute R^2 mod m
Expand Down
21 changes: 21 additions & 0 deletions tests/derive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,24 @@ fn batch_inversion() {
}
}
}

#[test]
fn sqrt() {
use ff::{Field, PrimeField};
// A field modulo a prime such that p = 1 mod 4 and p != 1 mod 16
#[derive(PrimeField)]
#[PrimeFieldModulus = "357686312646216567629137"]
#[PrimeFieldGenerator = "5"]
#[PrimeFieldReprEndianness = "little"]
struct Fp([u64; 2]);
fn test(square_root: Fp) {
let square = square_root.square();
let square_root = square.sqrt().unwrap();
assert_eq!(square_root.square(), square);
}

test(Fp::ZERO);
test(Fp::ONE);
use rand::rngs::OsRng;
test(Fp::random(OsRng));
}

0 comments on commit f5cbd49

Please sign in to comment.