mirror of
https://github.com/pseXperiments/ff-Goldilocks.git
synced 2026-01-09 04:57:59 -05:00
feat: inversion function for Ext2
This commit is contained in:
52
src/fp2.rs
52
src/fp2.rs
@@ -126,7 +126,21 @@ impl Field for GoldilocksExt2 {
|
||||
/// Computes the multiplicative inverse of this element,
|
||||
/// failing if the element is zero.
|
||||
fn invert(&self) -> CtOption<Self> {
|
||||
unimplemented!()
|
||||
if self.is_zero_vartime() {
|
||||
return CtOption::new(Self::default(), (false as u8).into());
|
||||
}
|
||||
|
||||
let a_pow_r_minus_1 = self.frobenius();
|
||||
let a_pow_r = a_pow_r_minus_1 * *self;
|
||||
debug_assert!(a_pow_r.0[1] == Goldilocks::ZERO);
|
||||
let a_pow_r_inv = a_pow_r.0[0].invert().expect("inverse does not exist");
|
||||
|
||||
let res = [
|
||||
a_pow_r_minus_1.0[0] * a_pow_r_inv,
|
||||
a_pow_r_minus_1.0[1] * a_pow_r_inv,
|
||||
];
|
||||
|
||||
CtOption::new(Self(res), Choice::from(1))
|
||||
}
|
||||
|
||||
/// Returns the square root of the field element, if it is
|
||||
@@ -333,3 +347,39 @@ impl FromUniformBytes<64> for GoldilocksExt2 {
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
impl GoldilocksExt2 {
|
||||
/// FrobeniusField automorphisms: x -> x^p, where p is the order of BaseField.
|
||||
fn frobenius(&self) -> Self {
|
||||
self.repeated_frobenius(1)
|
||||
}
|
||||
|
||||
/// Repeated Frobenius automorphisms: x -> x^(p^count).
|
||||
///
|
||||
/// Follows precomputation suggestion in Section 11.3.3 of the
|
||||
/// Handbook of Elliptic and Hyperelliptic Curve Cryptography.
|
||||
fn repeated_frobenius(&self, count: usize) -> Self {
|
||||
if count == 0 {
|
||||
return *self;
|
||||
} else if count >= 2 {
|
||||
// x |-> x^(p^D) is the identity, so x^(p^count) ==
|
||||
// x^(p^(count % D))
|
||||
return self.repeated_frobenius(count % 2);
|
||||
}
|
||||
let arr = self.0;
|
||||
|
||||
// z0 = DTH_ROOT^count = W^(k * count) where k = floor((p^D-1)/D)
|
||||
let mut z0 = Goldilocks(18446744069414584320);
|
||||
for _ in 1..count {
|
||||
z0 *= Goldilocks(18446744069414584320);
|
||||
}
|
||||
let z0square = z0 * z0;
|
||||
|
||||
let mut res = [Goldilocks::ZERO; 2];
|
||||
|
||||
res[0] = arr[0] * z0;
|
||||
res[1] = arr[1] * z0square;
|
||||
|
||||
Self(res)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +164,12 @@ fn random_squaring_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
|
||||
end_timer!(start);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn random_inversion_tests<F: Field, R: RngCore>(mut rng: R, type_name: String) {
|
||||
pub fn random_inversion_tests<F: Field>(type_name: String) {
|
||||
let mut rng = XorShiftRng::from_seed([
|
||||
0x59, 0x62, 0xbe, 0x5d, 0x76, 0x3d, 0x31, 0x8d, 0x17, 0xdb, 0x37, 0x32, 0x54, 0x06, 0xbc,
|
||||
0xe5,
|
||||
]);
|
||||
|
||||
assert!(bool::from(F::ZERO.invert().is_none()));
|
||||
|
||||
let message = format!("inversion {}", type_name);
|
||||
|
||||
@@ -5,6 +5,7 @@ use rand_core::SeedableRng;
|
||||
use rand_xorshift::XorShiftRng;
|
||||
|
||||
use super::random_field_tests;
|
||||
use super::random_inversion_tests;
|
||||
use super::random_prime_field_tests;
|
||||
use crate::fp::Goldilocks;
|
||||
use crate::fp::LegendreSymbol;
|
||||
@@ -54,4 +55,5 @@ fn test_sqrt_fq() {
|
||||
fn test_field() {
|
||||
random_field_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
random_prime_field_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
random_inversion_tests::<Goldilocks>("Goldilocks".to_string());
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
use super::random_field_tests;
|
||||
use super::random_inversion_tests;
|
||||
use super::random_prime_field_tests;
|
||||
use crate::fp::Goldilocks;
|
||||
use crate::fp2::GoldilocksExt2;
|
||||
|
||||
#[test]
|
||||
fn test_field() {
|
||||
random_field_tests::<GoldilocksExt2>("GoldilocksExt3".to_string());
|
||||
random_prime_field_tests::<GoldilocksExt2>("GoldilocksExt3".to_string());
|
||||
random_field_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
random_prime_field_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
random_inversion_tests::<GoldilocksExt2>("GoldilocksExt2".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user