Implementation of inversion for Fp

This commit is contained in:
Sean Bowe 2018-08-31 19:47:53 -06:00
parent c582e80157
commit cf210fe586
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
3 changed files with 47 additions and 0 deletions

View File

@ -11,3 +11,8 @@ version = "0.0.0"
[dependencies.byteorder]
version = "1"
default-features = false
[dependencies.subtle]
version = "0.7"
default-features = false
features = ["generic-impls"]

View File

@ -1,6 +1,7 @@
use core::ops::{AddAssign, SubAssign, MulAssign, Neg};
use byteorder::{ByteOrder, LittleEndian};
use subtle::{Choice, ConditionallySelectable, ConditionallyAssignable};
/// Represents an element of `GF(q)`.
// The internal representation of this type is four 64-bit unsigned
@ -9,6 +10,17 @@ use byteorder::{ByteOrder, LittleEndian};
#[derive(Clone, Copy)]
pub struct Fq([u64; 4]);
impl ConditionallySelectable for Fq {
fn conditional_select(a: &Self, b: &Self, choice: Choice) -> Self {
Fq([
u64::conditional_select(&a.0[0], &b.0[0], choice),
u64::conditional_select(&a.0[1], &b.0[1], choice),
u64::conditional_select(&a.0[2], &b.0[2], choice),
u64::conditional_select(&a.0[3], &b.0[3], choice)
])
}
}
// Constant representing the modulus
// q = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001
const MODULUS: Fq = Fq([
@ -198,6 +210,35 @@ impl Fq {
res
}
/// Squares this element.
pub fn square_assign(&mut self) {
let tmp = *self;
self.mul_assign(&tmp);
}
/// Exponentiates `self` by `by`, where `by` is a
/// little-endian order integer exponent.
pub fn pow(&self, by: &[u64; 4]) -> Self {
let mut res = Self::one();
for e in by.iter().rev() {
res.square_assign();
let mut e = *e;
for i in (0..64).rev() {
let mut tmp = res;
tmp.mul_assign(self);
res.conditional_assign(&tmp, (((e >> i) & 0x1) as u8).into());
}
}
res
}
/// Exponentiates `self` by q - 2, which has the
/// effect of inverting the element if it is
/// nonzero.
pub fn pow_q_minus_2(&self) -> Self {
self.pow(&[0xfffffffeffffffff, 0x53bda402fffe5bfe, 0x3339d80809a1d805, 0x73eda753299d7d48])
}
#[inline(always)]
fn montgomery_reduce(
&mut self,

View File

@ -8,6 +8,7 @@
extern crate core;
extern crate byteorder;
extern crate subtle;
mod fq;
pub use fq::*;