mirror of
https://github.com/Qortal/pirate-librustzcash.git
synced 2025-07-30 20:11:23 +00:00
Constant-time field inversion
WARNING: THIS IS NOT ACTUALLY CONSTANT TIME YET! The jubjub and bls12_381 crates will replace our constant-time usages, but we NEED to fix ff_derive because other users will expect it to implement the Field trait correctly.
This commit is contained in:
@@ -73,11 +73,11 @@ impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
||||
coeffs,
|
||||
exp,
|
||||
omega,
|
||||
omegainv: omega.inverse().unwrap(),
|
||||
geninv: E::Fr::multiplicative_generator().inverse().unwrap(),
|
||||
omegainv: omega.invert().unwrap(),
|
||||
geninv: E::Fr::multiplicative_generator().invert().unwrap(),
|
||||
minv: E::Fr::from_str(&format!("{}", m))
|
||||
.unwrap()
|
||||
.inverse()
|
||||
.invert()
|
||||
.unwrap(),
|
||||
})
|
||||
}
|
||||
@@ -141,10 +141,7 @@ impl<E: ScalarEngine, G: Group<E>> EvaluationDomain<E, G> {
|
||||
/// evaluation domain, so we must perform division over
|
||||
/// a coset.
|
||||
pub fn divide_by_z_on_coset(&mut self, worker: &Worker) {
|
||||
let i = self
|
||||
.z(&E::Fr::multiplicative_generator())
|
||||
.inverse()
|
||||
.unwrap();
|
||||
let i = self.z(&E::Fr::multiplicative_generator()).invert().unwrap();
|
||||
|
||||
worker.scope(self.coeffs.len(), |scope, chunk| {
|
||||
for v in self.coeffs.chunks_mut(chunk) {
|
||||
|
@@ -288,7 +288,7 @@ impl<E: ScalarEngine> AllocatedNum<E> {
|
||||
if tmp.is_zero() {
|
||||
Err(SynthesisError::DivisionByZero)
|
||||
} else {
|
||||
Ok(tmp.inverse().unwrap())
|
||||
Ok(tmp.invert().unwrap())
|
||||
}
|
||||
},
|
||||
)?;
|
||||
|
@@ -215,8 +215,22 @@ where
|
||||
assembly.num_inputs + assembly.num_aux
|
||||
});
|
||||
|
||||
let gamma_inverse = gamma.inverse().ok_or(SynthesisError::UnexpectedIdentity)?;
|
||||
let delta_inverse = delta.inverse().ok_or(SynthesisError::UnexpectedIdentity)?;
|
||||
let gamma_inverse = {
|
||||
let inverse = gamma.invert();
|
||||
if bool::from(inverse.is_some()) {
|
||||
Ok(inverse.unwrap())
|
||||
} else {
|
||||
Err(SynthesisError::UnexpectedIdentity)
|
||||
}
|
||||
}?;
|
||||
let delta_inverse = {
|
||||
let inverse = delta.invert();
|
||||
if bool::from(inverse.is_some()) {
|
||||
Ok(inverse.unwrap())
|
||||
} else {
|
||||
Err(SynthesisError::UnexpectedIdentity)
|
||||
}
|
||||
}?;
|
||||
|
||||
let worker = Worker::new();
|
||||
|
||||
|
@@ -10,13 +10,19 @@ use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::num::Wrapping;
|
||||
use std::ops::{Add, AddAssign, Mul, MulAssign, Neg, Sub, SubAssign};
|
||||
use subtle::{Choice, ConditionallySelectable};
|
||||
use subtle::{Choice, ConditionallySelectable, CtOption};
|
||||
|
||||
const MODULUS_R: Wrapping<u32> = Wrapping(64513);
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Fr(Wrapping<u32>);
|
||||
|
||||
impl Default for Fr {
|
||||
fn default() -> Self {
|
||||
<Fr as Field>::zero()
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Fr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||
write!(f, "{}", (self.0).0)
|
||||
@@ -159,11 +165,11 @@ impl Field for Fr {
|
||||
Fr((self.0 << 1) % MODULUS_R)
|
||||
}
|
||||
|
||||
fn inverse(&self) -> Option<Self> {
|
||||
fn invert(&self) -> CtOption<Self> {
|
||||
if <Fr as Field>::is_zero(self) {
|
||||
None
|
||||
CtOption::new(<Fr as Field>::zero(), Choice::from(0))
|
||||
} else {
|
||||
Some(self.pow(&[(MODULUS_R.0 as u64) - 2]))
|
||||
CtOption::new(self.pow(&[(MODULUS_R.0 as u64) - 2]), Choice::from(1))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -382,8 +388,8 @@ impl Engine for DummyEngine {
|
||||
}
|
||||
|
||||
/// Perform final exponentiation of the result of a miller loop.
|
||||
fn final_exponentiation(this: &Self::Fqk) -> Option<Self::Fqk> {
|
||||
Some(*this)
|
||||
fn final_exponentiation(this: &Self::Fqk) -> CtOption<Self::Fqk> {
|
||||
CtOption::new(*this, Choice::from(1))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -156,8 +156,8 @@ fn test_xordemo() {
|
||||
|
||||
// We expect our H query to be 7 elements of the form...
|
||||
// {tau^i t(tau) / delta}
|
||||
let delta_inverse = delta.inverse().unwrap();
|
||||
let gamma_inverse = gamma.inverse().unwrap();
|
||||
let delta_inverse = delta.invert().unwrap();
|
||||
let gamma_inverse = gamma.invert().unwrap();
|
||||
{
|
||||
let mut coeff = delta_inverse;
|
||||
coeff.mul_assign(&t_at_tau);
|
||||
|
Reference in New Issue
Block a user