type Element --> struct FieldElement
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -14,8 +14,38 @@ use testing::run_test;
|
|||||||
// This is all an extremely straightforward translation of the usual C
|
// This is all an extremely straightforward translation of the usual C
|
||||||
// implementation, as linked in ring and other libraries.
|
// implementation, as linked in ring and other libraries.
|
||||||
|
|
||||||
pub const NUM_ELEMENT_LIMBS: usize = 10;
|
const NUM_ELEMENT_LIMBS: usize = 10;
|
||||||
pub type Element = [i32; NUM_ELEMENT_LIMBS];
|
|
||||||
|
#[derive(Clone,Debug,PartialEq)]
|
||||||
|
pub struct FieldElement
|
||||||
|
{
|
||||||
|
pub(crate) value: [i32; NUM_ELEMENT_LIMBS]
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FieldElement
|
||||||
|
{
|
||||||
|
pub fn new() -> FieldElement
|
||||||
|
{
|
||||||
|
FieldElement{ value: [0; NUM_ELEMENT_LIMBS] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn zero() -> FieldElement
|
||||||
|
{
|
||||||
|
FieldElement{ value: [0; NUM_ELEMENT_LIMBS] }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn one() -> FieldElement
|
||||||
|
{
|
||||||
|
let mut res = FieldElement::zero();
|
||||||
|
res.value[0] = 1;
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn overwrite_with(&mut self, other: &FieldElement)
|
||||||
|
{
|
||||||
|
self.value.copy_from_slice(&other.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const KBOTTOM_25BITS : i64 = 0x1ffffffi64;
|
pub const KBOTTOM_25BITS : i64 = 0x1ffffffi64;
|
||||||
pub const KBOTTOM_26BITS : i64 = 0x3ffffffi64;
|
pub const KBOTTOM_26BITS : i64 = 0x3ffffffi64;
|
||||||
@@ -50,7 +80,7 @@ fn loads() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_frombytes(h: &mut Element, s: &[u8])
|
pub fn fe_frombytes(h: &mut FieldElement, s: &[u8])
|
||||||
{
|
{
|
||||||
/* Ignores top bit of h. */
|
/* Ignores top bit of h. */
|
||||||
let mut h0 = load4(s) as i64;
|
let mut h0 = load4(s) as i64;
|
||||||
@@ -76,23 +106,31 @@ pub fn fe_frombytes(h: &mut Element, s: &[u8])
|
|||||||
let carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & KTOP_38BITS;
|
let carry6 = h6 + (1 << 25); h7 += carry6 >> 26; h6 -= carry6 & KTOP_38BITS;
|
||||||
let carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & KTOP_38BITS;
|
let carry8 = h8 + (1 << 25); h9 += carry8 >> 26; h8 -= carry8 & KTOP_38BITS;
|
||||||
|
|
||||||
h[0] = h0 as i32; h[1] = h1 as i32; h[2] = h2 as i32; h[3] = h3 as i32; h[4] = h4 as i32;
|
h.value[0] = h0 as i32;
|
||||||
h[5] = h5 as i32; h[6] = h6 as i32; h[7] = h7 as i32; h[8] = h8 as i32; h[9] = h9 as i32;
|
h.value[1] = h1 as i32;
|
||||||
|
h.value[2] = h2 as i32;
|
||||||
|
h.value[3] = h3 as i32;
|
||||||
|
h.value[4] = h4 as i32;
|
||||||
|
h.value[5] = h5 as i32;
|
||||||
|
h.value[6] = h6 as i32;
|
||||||
|
h.value[7] = h7 as i32;
|
||||||
|
h.value[8] = h8 as i32;
|
||||||
|
h.value[9] = h9 as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_tobytes(s: &mut [u8], h: &Element)
|
pub fn fe_tobytes(s: &mut [u8], h: &FieldElement)
|
||||||
{
|
{
|
||||||
assert!(s.len() >= 32);
|
assert!(s.len() >= 32);
|
||||||
let mut h0 = h[0];
|
let mut h0 = h.value[0];
|
||||||
let mut h1 = h[1];
|
let mut h1 = h.value[1];
|
||||||
let mut h2 = h[2];
|
let mut h2 = h.value[2];
|
||||||
let mut h3 = h[3];
|
let mut h3 = h.value[3];
|
||||||
let mut h4 = h[4];
|
let mut h4 = h.value[4];
|
||||||
let mut h5 = h[5];
|
let mut h5 = h.value[5];
|
||||||
let mut h6 = h[6];
|
let mut h6 = h.value[6];
|
||||||
let mut h7 = h[7];
|
let mut h7 = h.value[7];
|
||||||
let mut h8 = h[8];
|
let mut h8 = h.value[8];
|
||||||
let mut h9 = h[9];
|
let mut h9 = h.value[9];
|
||||||
|
|
||||||
let mut q = (19 * h9 + ((1i32) << 24)) >> 25;
|
let mut q = (19 * h9 + ((1i32) << 24)) >> 25;
|
||||||
q = (h0 + q) >> 26;
|
q = (h0 + q) >> 26;
|
||||||
@@ -168,11 +206,11 @@ fn from_to_bytes() {
|
|||||||
let (negb, bbytes) = case.get("b").unwrap();
|
let (negb, bbytes) = case.get("b").unwrap();
|
||||||
|
|
||||||
assert!(!nega && !negb);
|
assert!(!nega && !negb);
|
||||||
let mut e = [0; NUM_ELEMENT_LIMBS];
|
let mut e = FieldElement::new();
|
||||||
let mut target = [0; NUM_ELEMENT_LIMBS];
|
let mut target = FieldElement::new();
|
||||||
fe_frombytes(&mut e, abytes);
|
fe_frombytes(&mut e, abytes);
|
||||||
let mut cursor = Cursor::new(bbytes);
|
let mut cursor = Cursor::new(bbytes);
|
||||||
cursor.read_i32_into::<NativeEndian>(&mut target).unwrap();
|
cursor.read_i32_into::<NativeEndian>(&mut target.value).unwrap();
|
||||||
assert_eq!(e, target, "from bytes");
|
assert_eq!(e, target, "from bytes");
|
||||||
let mut bytes = [0; 32];
|
let mut bytes = [0; 32];
|
||||||
fe_tobytes(&mut bytes, &e);
|
fe_tobytes(&mut bytes, &e);
|
||||||
@@ -182,29 +220,29 @@ fn from_to_bytes() {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[derive(Clone,Debug)]
|
#[derive(Clone,Debug)]
|
||||||
struct ValidElement {
|
struct ValidFieldElement {
|
||||||
values: Element
|
values: FieldElement
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl Arbitrary for ValidElement {
|
impl Arbitrary for ValidFieldElement {
|
||||||
fn arbitrary<G: Gen>(g: &mut G) -> ValidElement
|
fn arbitrary<G: Gen>(g: &mut G) -> ValidFieldElement
|
||||||
{
|
{
|
||||||
let mut bytes = [0; 32];
|
let mut bytes = [0; 32];
|
||||||
g.fill_bytes(&mut bytes);
|
g.fill_bytes(&mut bytes);
|
||||||
curve25519_scalar_mask(&mut bytes);
|
curve25519_scalar_mask(&mut bytes);
|
||||||
let mut res = ValidElement{ values: [0; NUM_ELEMENT_LIMBS] };
|
let mut res = ValidFieldElement{ values: FieldElement::new() };
|
||||||
fe_frombytes(&mut res.values, &bytes);
|
fe_frombytes(&mut res.values, &bytes);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn test_from_bytes(x: &[u8]) -> Element
|
pub fn test_from_bytes(x: &[u8]) -> FieldElement
|
||||||
{
|
{
|
||||||
let mut res = [0; NUM_ELEMENT_LIMBS];
|
let mut res = FieldElement::new();
|
||||||
let mut helper = Cursor::new(x);
|
let mut helper = Cursor::new(x);
|
||||||
helper.read_i32_into::<LittleEndian>(&mut res).unwrap();
|
helper.read_i32_into::<LittleEndian>(&mut res.value).unwrap();
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,64 +250,26 @@ pub fn test_from_bytes(x: &[u8]) -> Element
|
|||||||
quickcheck! {
|
quickcheck! {
|
||||||
// this is somewhat self referential, given the definition of arbitrary,
|
// this is somewhat self referential, given the definition of arbitrary,
|
||||||
// but more testing is more good
|
// but more testing is more good
|
||||||
fn from_to_bytes_roundtrip(e: ValidElement) -> bool {
|
fn from_to_bytes_roundtrip(e: ValidFieldElement) -> bool {
|
||||||
let mut bytes = [0; 32];
|
let mut bytes = [0; 32];
|
||||||
fe_tobytes(&mut bytes, &e.values);
|
fe_tobytes(&mut bytes, &e.values);
|
||||||
let mut trans = [0; NUM_ELEMENT_LIMBS];
|
let mut trans = FieldElement::new();
|
||||||
fe_frombytes(&mut trans, &bytes);
|
fe_frombytes(&mut trans, &bytes);
|
||||||
trans == e.values
|
trans == e.values
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pub fn fe_zero() -> Element
|
pub fn fe_add(h: &mut FieldElement, f: &FieldElement, g: &FieldElement)
|
||||||
// {
|
|
||||||
// [0; NUM_ELEMENT_LIMBS]
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn fe0(x: &mut Element)
|
|
||||||
{
|
|
||||||
x[0] = 0;
|
|
||||||
x[1] = 0;
|
|
||||||
x[2] = 0;
|
|
||||||
x[3] = 0;
|
|
||||||
x[4] = 0;
|
|
||||||
x[5] = 0;
|
|
||||||
x[6] = 0;
|
|
||||||
x[7] = 0;
|
|
||||||
x[8] = 0;
|
|
||||||
x[9] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// pub fn fe_one() -> Element
|
|
||||||
// {
|
|
||||||
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn fe1(x: &mut Element)
|
|
||||||
{
|
|
||||||
x[0] = 1;
|
|
||||||
x[1] = 0;
|
|
||||||
x[2] = 0;
|
|
||||||
x[3] = 0;
|
|
||||||
x[4] = 0;
|
|
||||||
x[5] = 0;
|
|
||||||
x[6] = 0;
|
|
||||||
x[7] = 0;
|
|
||||||
x[8] = 0;
|
|
||||||
x[9] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fe_add(h: &mut Element, f: &Element, g: &Element)
|
|
||||||
{
|
{
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
h[i] = f[i] + g[i]
|
h.value[i] = f.value[i] + g.value[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_sub(h: &mut Element, f: &Element, g: &Element)
|
pub fn fe_sub(h: &mut FieldElement, f: &FieldElement, g: &FieldElement)
|
||||||
{
|
{
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
h[i] = f[i] - g[i]
|
h.value[i] = f.value[i] - g.value[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,8 +288,8 @@ fn addsub() {
|
|||||||
let b = test_from_bytes(&bbytes);
|
let b = test_from_bytes(&bbytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let d = test_from_bytes(&dbytes);
|
let d = test_from_bytes(&dbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
let mut s = [0; NUM_ELEMENT_LIMBS];
|
let mut s = FieldElement::new();
|
||||||
fe_add(&mut r, &a, &b);
|
fe_add(&mut r, &a, &b);
|
||||||
fe_sub(&mut s, &a, &b);
|
fe_sub(&mut s, &a, &b);
|
||||||
assert_eq!(r, c, "field addition");
|
assert_eq!(r, c, "field addition");
|
||||||
@@ -297,28 +297,28 @@ fn addsub() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_mul(h: &mut Element, f: &Element, g: &Element)
|
pub fn fe_mul(h: &mut FieldElement, f: &FieldElement, g: &FieldElement)
|
||||||
{
|
{
|
||||||
let f0 : i32 = f[0];
|
let f0 : i32 = f.value[0];
|
||||||
let f1 : i32 = f[1];
|
let f1 : i32 = f.value[1];
|
||||||
let f2 : i32 = f[2];
|
let f2 : i32 = f.value[2];
|
||||||
let f3 : i32 = f[3];
|
let f3 : i32 = f.value[3];
|
||||||
let f4 : i32 = f[4];
|
let f4 : i32 = f.value[4];
|
||||||
let f5 : i32 = f[5];
|
let f5 : i32 = f.value[5];
|
||||||
let f6 : i32 = f[6];
|
let f6 : i32 = f.value[6];
|
||||||
let f7 : i32 = f[7];
|
let f7 : i32 = f.value[7];
|
||||||
let f8 : i32 = f[8];
|
let f8 : i32 = f.value[8];
|
||||||
let f9 : i32 = f[9];
|
let f9 : i32 = f.value[9];
|
||||||
let g0 : i32 = g[0];
|
let g0 : i32 = g.value[0];
|
||||||
let g1 : i32 = g[1];
|
let g1 : i32 = g.value[1];
|
||||||
let g2 : i32 = g[2];
|
let g2 : i32 = g.value[2];
|
||||||
let g3 : i32 = g[3];
|
let g3 : i32 = g.value[3];
|
||||||
let g4 : i32 = g[4];
|
let g4 : i32 = g.value[4];
|
||||||
let g5 : i32 = g[5];
|
let g5 : i32 = g.value[5];
|
||||||
let g6 : i32 = g[6];
|
let g6 : i32 = g.value[6];
|
||||||
let g7 : i32 = g[7];
|
let g7 : i32 = g.value[7];
|
||||||
let g8 : i32 = g[8];
|
let g8 : i32 = g.value[8];
|
||||||
let g9 : i32 = g[9];
|
let g9 : i32 = g.value[9];
|
||||||
let g1_19 : i32 = 19 * g1; /* 1.959375*2^29 */
|
let g1_19 : i32 = 19 * g1; /* 1.959375*2^29 */
|
||||||
let g2_19 : i32 = 19 * g2; /* 1.959375*2^30; still ok */
|
let g2_19 : i32 = 19 * g2; /* 1.959375*2^30; still ok */
|
||||||
let g3_19 : i32 = 19 * g3;
|
let g3_19 : i32 = 19 * g3;
|
||||||
@@ -503,16 +503,16 @@ pub fn fe_mul(h: &mut Element, f: &Element, g: &Element)
|
|||||||
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
/* |h0| <= 2^25; from now on fits into int32 unchanged */
|
||||||
/* |h1| <= 1.01*2^24 */
|
/* |h1| <= 1.01*2^24 */
|
||||||
|
|
||||||
h[0] = h0 as i32;
|
h.value[0] = h0 as i32;
|
||||||
h[1] = h1 as i32;
|
h.value[1] = h1 as i32;
|
||||||
h[2] = h2 as i32;
|
h.value[2] = h2 as i32;
|
||||||
h[3] = h3 as i32;
|
h.value[3] = h3 as i32;
|
||||||
h[4] = h4 as i32;
|
h.value[4] = h4 as i32;
|
||||||
h[5] = h5 as i32;
|
h.value[5] = h5 as i32;
|
||||||
h[6] = h6 as i32;
|
h.value[6] = h6 as i32;
|
||||||
h[7] = h7 as i32;
|
h.value[7] = h7 as i32;
|
||||||
h[8] = h8 as i32;
|
h.value[8] = h8 as i32;
|
||||||
h[9] = h9 as i32;
|
h.value[9] = h9 as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -528,24 +528,24 @@ fn mul() {
|
|||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let b = test_from_bytes(&bbytes);
|
let b = test_from_bytes(&bbytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_mul(&mut r, &a, &b);
|
fe_mul(&mut r, &a, &b);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_square(h: &mut Element, f: &Element)
|
pub fn fe_square(h: &mut FieldElement, f: &FieldElement)
|
||||||
{
|
{
|
||||||
let f0 : i32 = f[0];
|
let f0 : i32 = f.value[0];
|
||||||
let f1 : i32 = f[1];
|
let f1 : i32 = f.value[1];
|
||||||
let f2 : i32 = f[2];
|
let f2 : i32 = f.value[2];
|
||||||
let f3 : i32 = f[3];
|
let f3 : i32 = f.value[3];
|
||||||
let f4 : i32 = f[4];
|
let f4 : i32 = f.value[4];
|
||||||
let f5 : i32 = f[5];
|
let f5 : i32 = f.value[5];
|
||||||
let f6 : i32 = f[6];
|
let f6 : i32 = f.value[6];
|
||||||
let f7 : i32 = f[7];
|
let f7 : i32 = f.value[7];
|
||||||
let f8 : i32 = f[8];
|
let f8 : i32 = f.value[8];
|
||||||
let f9 : i32 = f[9];
|
let f9 : i32 = f.value[9];
|
||||||
let f0_2 : i32 = 2 * f0;
|
let f0_2 : i32 = 2 * f0;
|
||||||
let f1_2 : i32 = 2 * f1;
|
let f1_2 : i32 = 2 * f1;
|
||||||
let f2_2 : i32 = 2 * f2;
|
let f2_2 : i32 = 2 * f2;
|
||||||
@@ -648,16 +648,16 @@ pub fn fe_square(h: &mut Element, f: &Element)
|
|||||||
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & KTOP_39BITS;
|
carry9 = h9 + (1 << 24); h0 += (carry9 >> 25) * 19; h9 -= carry9 & KTOP_39BITS;
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & KTOP_38BITS;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & KTOP_38BITS;
|
||||||
|
|
||||||
h[0] = h0 as i32;
|
h.value[0] = h0 as i32;
|
||||||
h[1] = h1 as i32;
|
h.value[1] = h1 as i32;
|
||||||
h[2] = h2 as i32;
|
h.value[2] = h2 as i32;
|
||||||
h[3] = h3 as i32;
|
h.value[3] = h3 as i32;
|
||||||
h[4] = h4 as i32;
|
h.value[4] = h4 as i32;
|
||||||
h[5] = h5 as i32;
|
h.value[5] = h5 as i32;
|
||||||
h[6] = h6 as i32;
|
h.value[6] = h6 as i32;
|
||||||
h[7] = h7 as i32;
|
h.value[7] = h7 as i32;
|
||||||
h[8] = h8 as i32;
|
h.value[8] = h8 as i32;
|
||||||
h[9] = h9 as i32;
|
h.value[9] = h9 as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -671,89 +671,89 @@ fn square() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_square(&mut r, &a);
|
fe_square(&mut r, &a);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_invert(z: &Element) -> Element
|
pub fn fe_invert(z: &FieldElement) -> FieldElement
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut t1 = [0; NUM_ELEMENT_LIMBS];
|
let mut t1 = FieldElement::new();
|
||||||
let mut t2 = [0; NUM_ELEMENT_LIMBS];
|
let mut t2 = FieldElement::new();
|
||||||
let mut t3 = [0; NUM_ELEMENT_LIMBS];
|
let mut t3 = FieldElement::new();
|
||||||
let mut temp = [0; NUM_ELEMENT_LIMBS];
|
let mut temp = FieldElement::new();
|
||||||
let mut out = [0; NUM_ELEMENT_LIMBS];
|
let mut out = FieldElement::new();
|
||||||
|
|
||||||
fe_square(&mut t0, &z);
|
fe_square(&mut t0, &z);
|
||||||
fe_square(&mut t1, &t0);
|
fe_square(&mut t1, &t0);
|
||||||
for _ in 1..2 {
|
for _ in 1..2 {
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_square(&mut t1, &temp);
|
fe_square(&mut t1, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_mul(&mut t1, &z, &temp);
|
fe_mul(&mut t1, &z, &temp);
|
||||||
temp.copy_from_slice(&t0);
|
temp.overwrite_with(&t0);
|
||||||
fe_mul(&mut t0, &temp, &t1);
|
fe_mul(&mut t0, &temp, &t1);
|
||||||
fe_square(&mut t2, &t0);
|
fe_square(&mut t2, &t0);
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_mul(&mut t1, &temp, &t2);
|
fe_mul(&mut t1, &temp, &t2);
|
||||||
fe_square(&mut t2, &t1);
|
fe_square(&mut t2, &t1);
|
||||||
for _ in 1..5 {
|
for _ in 1..5 {
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_mul(&mut t1, &t2, &temp);
|
fe_mul(&mut t1, &t2, &temp);
|
||||||
fe_square(&mut t2, &t1);
|
fe_square(&mut t2, &t1);
|
||||||
for _ in 1..10 {
|
for _ in 1..10 {
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_mul(&mut t2, &temp, &t1);
|
fe_mul(&mut t2, &temp, &t1);
|
||||||
fe_square(&mut t3, &t2);
|
fe_square(&mut t3, &t2);
|
||||||
for _ in 1..20 {
|
for _ in 1..20 {
|
||||||
temp.copy_from_slice(&t3);
|
temp.overwrite_with(&t3);
|
||||||
fe_square(&mut t3, &temp);
|
fe_square(&mut t3, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_mul(&mut t2, &t3, &temp);
|
fe_mul(&mut t2, &t3, &temp);
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
for _ in 1..10 {
|
for _ in 1..10 {
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_mul(&mut t1, &t2, &temp);
|
fe_mul(&mut t1, &t2, &temp);
|
||||||
fe_square(&mut t2, &t1);
|
fe_square(&mut t2, &t1);
|
||||||
for _ in 1..50 {
|
for _ in 1..50 {
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_mul(&mut t2, &temp, &t1);
|
fe_mul(&mut t2, &temp, &t1);
|
||||||
fe_square(&mut t3, &t2);
|
fe_square(&mut t3, &t2);
|
||||||
for _ in 1..100 {
|
for _ in 1..100 {
|
||||||
temp.copy_from_slice(&t3);
|
temp.overwrite_with(&t3);
|
||||||
fe_square(&mut t3, &temp);
|
fe_square(&mut t3, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_mul(&mut t2, &t3, &temp);
|
fe_mul(&mut t2, &t3, &temp);
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
for _ in 1..50 {
|
for _ in 1..50 {
|
||||||
temp.copy_from_slice(&t2);
|
temp.overwrite_with(&t2);
|
||||||
fe_square(&mut t2, &temp);
|
fe_square(&mut t2, &temp);
|
||||||
}
|
}
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_mul(&mut t1, &t2, &temp);
|
fe_mul(&mut t1, &t2, &temp);
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_square(&mut t1, &temp);
|
fe_square(&mut t1, &temp);
|
||||||
for _ in 1..5 {
|
for _ in 1..5 {
|
||||||
temp.copy_from_slice(&t1);
|
temp.overwrite_with(&t1);
|
||||||
fe_square(&mut t1, &temp);
|
fe_square(&mut t1, &temp);
|
||||||
}
|
}
|
||||||
fe_mul(&mut out, &t1, &t0);
|
fe_mul(&mut out, &t1, &t0);
|
||||||
@@ -776,10 +776,10 @@ fn invert() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_neg(h: &mut Element, f: &Element)
|
pub fn fe_neg(h: &mut FieldElement, f: &FieldElement)
|
||||||
{
|
{
|
||||||
for i in 0..NUM_ELEMENT_LIMBS {
|
for i in 0..NUM_ELEMENT_LIMBS {
|
||||||
h[i] = -f[i];
|
h.value[i] = -f.value[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -794,19 +794,19 @@ fn negate() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_neg(&mut r, &a);
|
fe_neg(&mut r, &a);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_cmov(f: &mut Element, g: &Element, bl: bool)
|
pub fn fe_cmov(f: &mut FieldElement, g: &FieldElement, bl: bool)
|
||||||
{
|
{
|
||||||
let b = if bl { -1 } else { 0 };
|
let b = if bl { -1 } else { 0 };
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
let mut x = f[i] ^ g[i];
|
let mut x = f.value[i] ^ g.value[i];
|
||||||
x &= b;
|
x &= b;
|
||||||
f[i] ^= x;
|
f.value[i] ^= x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -823,13 +823,13 @@ fn cmov() {
|
|||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let b = bbytes.len() > 1;
|
let b = bbytes.len() > 1;
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_cmov(&mut r, &a, b);
|
fe_cmov(&mut r, &a, b);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_isnonzero(f: &Element) -> bool
|
pub fn fe_isnonzero(f: &FieldElement) -> bool
|
||||||
{
|
{
|
||||||
let mut s = [0; 32];
|
let mut s = [0; 32];
|
||||||
let mut res = false;
|
let mut res = false;
|
||||||
@@ -840,7 +840,7 @@ pub fn fe_isnonzero(f: &Element) -> bool
|
|||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_isnegative(f: &Element) -> bool
|
pub fn fe_isnegative(f: &FieldElement) -> bool
|
||||||
{
|
{
|
||||||
let mut s = [0; 32];
|
let mut s = [0; 32];
|
||||||
fe_tobytes(&mut s, &f);
|
fe_tobytes(&mut s, &f);
|
||||||
@@ -866,18 +866,18 @@ fn is_tests() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_sq2(h: &mut Element, f: &Element)
|
pub fn fe_sq2(h: &mut FieldElement, f: &FieldElement)
|
||||||
{
|
{
|
||||||
let f0 = f[0];
|
let f0 = f.value[0];
|
||||||
let f1 = f[1];
|
let f1 = f.value[1];
|
||||||
let f2 = f[2];
|
let f2 = f.value[2];
|
||||||
let f3 = f[3];
|
let f3 = f.value[3];
|
||||||
let f4 = f[4];
|
let f4 = f.value[4];
|
||||||
let f5 = f[5];
|
let f5 = f.value[5];
|
||||||
let f6 = f[6];
|
let f6 = f.value[6];
|
||||||
let f7 = f[7];
|
let f7 = f.value[7];
|
||||||
let f8 = f[8];
|
let f8 = f.value[8];
|
||||||
let f9 = f[9];
|
let f9 = f.value[9];
|
||||||
let f0_2 = 2 * f0;
|
let f0_2 = 2 * f0;
|
||||||
let f1_2 = 2 * f1;
|
let f1_2 = 2 * f1;
|
||||||
let f2_2 = 2 * f2;
|
let f2_2 = 2 * f2;
|
||||||
@@ -997,16 +997,16 @@ pub fn fe_sq2(h: &mut Element, f: &Element)
|
|||||||
|
|
||||||
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & KTOP_38BITS;
|
carry0 = h0 + (1 << 25); h1 += carry0 >> 26; h0 -= carry0 & KTOP_38BITS;
|
||||||
|
|
||||||
h[0] = h0 as i32;
|
h.value[0] = h0 as i32;
|
||||||
h[1] = h1 as i32;
|
h.value[1] = h1 as i32;
|
||||||
h[2] = h2 as i32;
|
h.value[2] = h2 as i32;
|
||||||
h[3] = h3 as i32;
|
h.value[3] = h3 as i32;
|
||||||
h[4] = h4 as i32;
|
h.value[4] = h4 as i32;
|
||||||
h[5] = h5 as i32;
|
h.value[5] = h5 as i32;
|
||||||
h[6] = h6 as i32;
|
h.value[6] = h6 as i32;
|
||||||
h[7] = h7 as i32;
|
h.value[7] = h7 as i32;
|
||||||
h[8] = h8 as i32;
|
h.value[8] = h8 as i32;
|
||||||
h[9] = h9 as i32;
|
h.value[9] = h9 as i32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -1020,16 +1020,16 @@ fn square2() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_sq2(&mut r, &a);
|
fe_sq2(&mut r, &a);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fe_pow22523(out: &mut Element, z: &Element) {
|
pub fn fe_pow22523(out: &mut FieldElement, z: &FieldElement) {
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut t1 = [0; NUM_ELEMENT_LIMBS];
|
let mut t1 = FieldElement::new();
|
||||||
let mut t2 = [0; NUM_ELEMENT_LIMBS];
|
let mut t2 = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_square(&mut t0, &z);
|
fe_square(&mut t0, &z);
|
||||||
@@ -1117,9 +1117,8 @@ fn pow22523() {
|
|||||||
assert!(!nega && !negc);
|
assert!(!nega && !negc);
|
||||||
let a = test_from_bytes(&abytes);
|
let a = test_from_bytes(&abytes);
|
||||||
let c = test_from_bytes(&cbytes);
|
let c = test_from_bytes(&cbytes);
|
||||||
let mut r = [0; NUM_ELEMENT_LIMBS];
|
let mut r = FieldElement::new();
|
||||||
fe_pow22523(&mut r, &a);
|
fe_pow22523(&mut r, &a);
|
||||||
assert_eq!(r, c);
|
assert_eq!(r, c);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ impl ED25519Public {
|
|||||||
|
|
||||||
let mut a = Point::new();
|
let mut a = Point::new();
|
||||||
x25519_ge_frombytes_vartime(&mut a, &self.public);
|
x25519_ge_frombytes_vartime(&mut a, &self.public);
|
||||||
invert_vartime(&mut a);
|
a.invert();
|
||||||
let h_digest = eddsa_digest(signature_r, &self.public, msg);
|
let h_digest = eddsa_digest(signature_r, &self.public, msg);
|
||||||
let h = digest_scalar(&h_digest);
|
let h = digest_scalar(&h_digest);
|
||||||
let mut r = Point2::new();
|
let mut r = Point2::new();
|
||||||
@@ -164,14 +164,6 @@ fn digest_scalar(digest: &[u8]) -> Vec<u8> {
|
|||||||
copy[..32].to_vec()
|
copy[..32].to_vec()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invert_vartime(v: &mut Point)
|
|
||||||
{
|
|
||||||
for i in 0..NUM_ELEMENT_LIMBS {
|
|
||||||
v.x[i] = -v.x[i];
|
|
||||||
v.t[i] = -v.t[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
fn run_signing_testcase(case: HashMap<String,(bool,Vec<u8>)>)
|
fn run_signing_testcase(case: HashMap<String,(bool,Vec<u8>)>)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,22 +5,22 @@ use ed25519::fe::*;
|
|||||||
use ed25519::constants::*;
|
use ed25519::constants::*;
|
||||||
|
|
||||||
// This is ge_p3 in the original source code
|
// This is ge_p3 in the original source code
|
||||||
#[derive(Debug,PartialEq)]
|
#[derive(Clone,Debug,PartialEq)]
|
||||||
pub struct Point {
|
pub struct Point {
|
||||||
pub x: Element,
|
pub x: FieldElement,
|
||||||
pub y: Element,
|
pub y: FieldElement,
|
||||||
pub z: Element,
|
pub z: FieldElement,
|
||||||
pub t: Element
|
pub t: FieldElement
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
pub fn new() -> Point
|
pub fn new() -> Point
|
||||||
{
|
{
|
||||||
Point {
|
Point {
|
||||||
x: [0; NUM_ELEMENT_LIMBS],
|
x: FieldElement::new(),
|
||||||
y: [0; NUM_ELEMENT_LIMBS],
|
y: FieldElement::new(),
|
||||||
z: [0; NUM_ELEMENT_LIMBS],
|
z: FieldElement::new(),
|
||||||
t: [0; NUM_ELEMENT_LIMBS]
|
t: FieldElement::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,25 +39,36 @@ impl Point {
|
|||||||
{
|
{
|
||||||
into_encoded_point(target, &self.x, &self.y, &self.z);
|
into_encoded_point(target, &self.x, &self.y, &self.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn invert(&mut self)
|
||||||
|
{
|
||||||
|
let tmp = self.clone();
|
||||||
|
fe_neg(&mut self.x, &tmp.x);
|
||||||
|
fe_neg(&mut self.t, &tmp.t);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const D: Element = [-10913610, 13857413, -15372611, 6949391, 114729,
|
const D: FieldElement = FieldElement {
|
||||||
-8787816, -6275908, -3247719, -18696448, -12055116];
|
value: [-10913610, 13857413, -15372611, 6949391, 114729,
|
||||||
|
-8787816, -6275908, -3247719, -18696448, -12055116]
|
||||||
|
};
|
||||||
|
|
||||||
const SQRTM1: Element = [-32595792, -7943725, 9377950, 3500415, 12389472,
|
const SQRTM1: FieldElement = FieldElement {
|
||||||
-272473, -25146209, -2005654, 326686, 11406482];
|
value: [-32595792, -7943725, 9377950, 3500415, 12389472,
|
||||||
|
-272473, -25146209, -2005654, 326686, 11406482]
|
||||||
|
};
|
||||||
|
|
||||||
pub fn x25519_ge_frombytes_vartime(h: &mut Point, s: &[u8]) -> bool
|
pub fn x25519_ge_frombytes_vartime(h: &mut Point, s: &[u8]) -> bool
|
||||||
{
|
{
|
||||||
let mut u = [0; NUM_ELEMENT_LIMBS];
|
let mut u = FieldElement::new();
|
||||||
let mut v = [0; NUM_ELEMENT_LIMBS];
|
let mut v = FieldElement::new();
|
||||||
let mut v3 = [0; NUM_ELEMENT_LIMBS];
|
let mut v3 = FieldElement::new();
|
||||||
let mut vxx = [0; NUM_ELEMENT_LIMBS];
|
let mut vxx = FieldElement::new();
|
||||||
let mut check = [0; NUM_ELEMENT_LIMBS];
|
let mut check = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_frombytes(&mut h.y, s);
|
fe_frombytes(&mut h.y, s);
|
||||||
fe1(&mut h.z);
|
h.z.overwrite_with(&FieldElement::one());
|
||||||
fe_square(&mut u, &h.y);
|
fe_square(&mut u, &h.y);
|
||||||
fe_mul(&mut v, &u, &D);
|
fe_mul(&mut v, &u, &D);
|
||||||
temp = u.clone();
|
temp = u.clone();
|
||||||
@@ -121,26 +132,26 @@ fn from_bytes_vartime() {
|
|||||||
|
|
||||||
fn ge_p3_0(h: &mut Point)
|
fn ge_p3_0(h: &mut Point)
|
||||||
{
|
{
|
||||||
fe0(&mut h.x);
|
h.x.overwrite_with(&FieldElement::zero());
|
||||||
fe1(&mut h.y);
|
h.y.overwrite_with(&FieldElement::one());
|
||||||
fe1(&mut h.z);
|
h.z.overwrite_with(&FieldElement::one());
|
||||||
fe0(&mut h.t);
|
h.t.overwrite_with(&FieldElement::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,PartialEq)]
|
#[derive(Debug,PartialEq)]
|
||||||
pub struct Point2 {
|
pub struct Point2 {
|
||||||
pub x: Element,
|
pub x: FieldElement,
|
||||||
pub y: Element,
|
pub y: FieldElement,
|
||||||
pub z: Element,
|
pub z: FieldElement,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Point2 {
|
impl Point2 {
|
||||||
pub fn new() -> Point2
|
pub fn new() -> Point2
|
||||||
{
|
{
|
||||||
Point2 {
|
Point2 {
|
||||||
x: [0; NUM_ELEMENT_LIMBS],
|
x: FieldElement::new(),
|
||||||
y: [0; NUM_ELEMENT_LIMBS],
|
y: FieldElement::new(),
|
||||||
z: [0; NUM_ELEMENT_LIMBS]
|
z: FieldElement::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,34 +173,34 @@ impl Point2 {
|
|||||||
|
|
||||||
fn ge_p2_0(h: &mut Point2)
|
fn ge_p2_0(h: &mut Point2)
|
||||||
{
|
{
|
||||||
fe0(&mut h.x);
|
h.x.overwrite_with(&FieldElement::zero());
|
||||||
fe1(&mut h.y);
|
h.y.overwrite_with(&FieldElement::one());
|
||||||
fe1(&mut h.z);
|
h.z.overwrite_with(&FieldElement::one());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ge_p3_to_p2(r: &mut Point2, p: &Point)
|
fn ge_p3_to_p2(r: &mut Point2, p: &Point)
|
||||||
{
|
{
|
||||||
r.x.copy_from_slice(&p.x);
|
r.x.overwrite_with(&p.x);
|
||||||
r.y.copy_from_slice(&p.y);
|
r.y.overwrite_with(&p.y);
|
||||||
r.z.copy_from_slice(&p.z);
|
r.z.overwrite_with(&p.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug,PartialEq)]
|
#[derive(Debug,PartialEq)]
|
||||||
struct PointP1P1 {
|
struct PointP1P1 {
|
||||||
x: Element,
|
x: FieldElement,
|
||||||
y: Element,
|
y: FieldElement,
|
||||||
z: Element,
|
z: FieldElement,
|
||||||
t: Element
|
t: FieldElement
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PointP1P1 {
|
impl PointP1P1 {
|
||||||
fn new() -> PointP1P1
|
fn new() -> PointP1P1
|
||||||
{
|
{
|
||||||
PointP1P1 {
|
PointP1P1 {
|
||||||
x: [0; NUM_ELEMENT_LIMBS],
|
x: FieldElement::new(),
|
||||||
y: [0; NUM_ELEMENT_LIMBS],
|
y: FieldElement::new(),
|
||||||
z: [0; NUM_ELEMENT_LIMBS],
|
z: FieldElement::new(),
|
||||||
t: [0; NUM_ELEMENT_LIMBS],
|
t: FieldElement::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,10 +218,10 @@ impl PointP1P1 {
|
|||||||
|
|
||||||
#[derive(Debug,PartialEq)]
|
#[derive(Debug,PartialEq)]
|
||||||
struct Cached {
|
struct Cached {
|
||||||
yplusx: Element,
|
yplusx: FieldElement,
|
||||||
yminusx: Element,
|
yminusx: FieldElement,
|
||||||
z: Element,
|
z: FieldElement,
|
||||||
t2d: Element
|
t2d: FieldElement
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Cached
|
impl Cached
|
||||||
@@ -218,10 +229,10 @@ impl Cached
|
|||||||
fn new() -> Cached
|
fn new() -> Cached
|
||||||
{
|
{
|
||||||
Cached {
|
Cached {
|
||||||
yplusx: [0; NUM_ELEMENT_LIMBS],
|
yplusx: FieldElement::new(),
|
||||||
yminusx: [0; NUM_ELEMENT_LIMBS],
|
yminusx: FieldElement::new(),
|
||||||
z: [0; NUM_ELEMENT_LIMBS],
|
z: FieldElement::new(),
|
||||||
t2d: [0; NUM_ELEMENT_LIMBS]
|
t2d: FieldElement::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,14 +248,16 @@ impl Cached
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const D2: Element = [-21827239, -5839606, -30745221, 13898782, 229458,
|
const D2: FieldElement = FieldElement {
|
||||||
15978800, -12551817, -6495438, 29715968, 9444199];
|
value: [-21827239, -5839606, -30745221, 13898782, 229458,
|
||||||
|
15978800, -12551817, -6495438, 29715968, 9444199]
|
||||||
|
};
|
||||||
|
|
||||||
fn x25519_ge_p3_to_cached(r: &mut Cached, p: &Point)
|
fn x25519_ge_p3_to_cached(r: &mut Cached, p: &Point)
|
||||||
{
|
{
|
||||||
fe_add(&mut r.yplusx, &p.y, &p.x);
|
fe_add(&mut r.yplusx, &p.y, &p.x);
|
||||||
fe_sub(&mut r.yminusx, &p.y, &p.x);
|
fe_sub(&mut r.yminusx, &p.y, &p.x);
|
||||||
r.z.copy_from_slice(&p.z);
|
r.z.overwrite_with(&p.z);
|
||||||
fe_mul(&mut r.t2d, &p.t, &D2);
|
fe_mul(&mut r.t2d, &p.t, &D2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +324,7 @@ fn conversion() {
|
|||||||
/* r = 2 * p */
|
/* r = 2 * p */
|
||||||
fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2)
|
fn ge_p2_dbl(r: &mut PointP1P1, p: &Point2)
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
|
|
||||||
fe_square(&mut r.x, &p.x);
|
fe_square(&mut r.x, &p.x);
|
||||||
fe_square(&mut r.z, &p.y);
|
fe_square(&mut r.z, &p.y);
|
||||||
@@ -361,7 +374,7 @@ fn double() {
|
|||||||
/* r = p + q */
|
/* r = p + q */
|
||||||
fn ge_madd(r: &mut PointP1P1, p: &Point, q: &Precomp)
|
fn ge_madd(r: &mut PointP1P1, p: &Point, q: &Precomp)
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_add(&mut r.x, &p.y, &p.x);
|
fe_add(&mut r.x, &p.y, &p.x);
|
||||||
@@ -382,7 +395,7 @@ fn ge_madd(r: &mut PointP1P1, p: &Point, q: &Precomp)
|
|||||||
/* r = p - q */
|
/* r = p - q */
|
||||||
fn ge_msub(r: &mut PointP1P1, p: &Point, q: &Precomp)
|
fn ge_msub(r: &mut PointP1P1, p: &Point, q: &Precomp)
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_add(&mut r.x, &p.y, &p.x);
|
fe_add(&mut r.x, &p.y, &p.x);
|
||||||
@@ -427,7 +440,7 @@ fn maddsub() {
|
|||||||
/* r = p + q */
|
/* r = p + q */
|
||||||
fn x25519_ge_add(r: &mut PointP1P1, p: &Point, q: &Cached)
|
fn x25519_ge_add(r: &mut PointP1P1, p: &Point, q: &Cached)
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_add(&mut r.x, &p.y, &p.x);
|
fe_add(&mut r.x, &p.y, &p.x);
|
||||||
@@ -449,7 +462,7 @@ fn x25519_ge_add(r: &mut PointP1P1, p: &Point, q: &Cached)
|
|||||||
/* r = p - q */
|
/* r = p - q */
|
||||||
fn x25519_ge_sub(r: &mut PointP1P1, p: &Point, q: &Cached)
|
fn x25519_ge_sub(r: &mut PointP1P1, p: &Point, q: &Cached)
|
||||||
{
|
{
|
||||||
let mut t0 = [0; NUM_ELEMENT_LIMBS];
|
let mut t0 = FieldElement::new();
|
||||||
let mut temp;
|
let mut temp;
|
||||||
|
|
||||||
fe_add(&mut r.x, &p.y, &p.x);
|
fe_add(&mut r.x, &p.y, &p.x);
|
||||||
@@ -529,8 +542,8 @@ fn table_select(t: &mut Precomp, pos: i32, b: i8)
|
|||||||
cmov(t, &K25519_PRECOMP[pos as usize][5], equal(babs, 6));
|
cmov(t, &K25519_PRECOMP[pos as usize][5], equal(babs, 6));
|
||||||
cmov(t, &K25519_PRECOMP[pos as usize][6], equal(babs, 7));
|
cmov(t, &K25519_PRECOMP[pos as usize][6], equal(babs, 7));
|
||||||
cmov(t, &K25519_PRECOMP[pos as usize][7], equal(babs, 8));
|
cmov(t, &K25519_PRECOMP[pos as usize][7], equal(babs, 8));
|
||||||
minust.yplusx.copy_from_slice(&t.yminusx);
|
minust.yplusx.overwrite_with(&t.yminusx);
|
||||||
minust.yminusx.copy_from_slice(&t.yplusx);
|
minust.yminusx.overwrite_with(&t.yplusx);
|
||||||
fe_neg(&mut minust.xy2d, &t.xy2d);
|
fe_neg(&mut minust.xy2d, &t.xy2d);
|
||||||
cmov(t, &minust, bnegative != 0);
|
cmov(t, &minust, bnegative != 0);
|
||||||
}
|
}
|
||||||
@@ -1640,7 +1653,7 @@ pub fn curve25519_scalar_mask(a: &mut [u8])
|
|||||||
* replace (f,g) with (f,g) if b == 0.
|
* replace (f,g) with (f,g) if b == 0.
|
||||||
*
|
*
|
||||||
* Preconditions: b in {0,1}. */
|
* Preconditions: b in {0,1}. */
|
||||||
//fn fe_cswap(f: &mut Element, g: &mut Element, inb: bool) {
|
//fn fe_cswap(f: &mut FieldElement, g: &mut FieldElement, inb: bool) {
|
||||||
// let b = if inb { 0xFFFFFFFFu32 as i32 } else { 0x00000000 };
|
// let b = if inb { 0xFFFFFFFFu32 as i32 } else { 0x00000000 };
|
||||||
// for i in 0..NUM_ELEMENT_LIMBS {
|
// for i in 0..NUM_ELEMENT_LIMBS {
|
||||||
// let mut x = f[i] ^ g[i];
|
// let mut x = f[i] ^ g[i];
|
||||||
@@ -1658,7 +1671,7 @@ pub fn curve25519_scalar_mask(a: &mut [u8])
|
|||||||
*
|
*
|
||||||
* Postconditions:
|
* Postconditions:
|
||||||
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
|
* |h| bounded by 1.1*2^25,1.1*2^24,1.1*2^25,1.1*2^24,etc. */
|
||||||
//fn fe_mul121666(h: &mut Element, f: &Element)
|
//fn fe_mul121666(h: &mut FieldElement, f: &FieldElement)
|
||||||
//{
|
//{
|
||||||
// let f0 = f[0];
|
// let f0 = f[0];
|
||||||
// let f1 = f[1];
|
// let f1 = f[1];
|
||||||
@@ -1711,13 +1724,13 @@ pub fn curve25519_scalar_mask(a: &mut [u8])
|
|||||||
// assert_eq!(scalar.len(), 32);
|
// assert_eq!(scalar.len(), 32);
|
||||||
// assert_eq!(point.len(), 32);
|
// assert_eq!(point.len(), 32);
|
||||||
//
|
//
|
||||||
// let mut x1 = [0; NUM_ELEMENT_LIMBS];
|
// let mut x1 = FieldElement::new();
|
||||||
// let mut x2 = [0; NUM_ELEMENT_LIMBS];
|
// let mut x2 = FieldElement::new();
|
||||||
// let mut z2 = [0; NUM_ELEMENT_LIMBS];
|
// let mut z2 = FieldElement::new();
|
||||||
// let mut x3 = [0; NUM_ELEMENT_LIMBS];
|
// let mut x3 = FieldElement::new();
|
||||||
// let mut z3 = [0; NUM_ELEMENT_LIMBS];
|
// let mut z3 = FieldElement::new();
|
||||||
// let mut tmp0 = [0; NUM_ELEMENT_LIMBS];
|
// let mut tmp0 = FieldElement::new();
|
||||||
// let mut tmp1 = [0; NUM_ELEMENT_LIMBS];
|
// let mut tmp1 = FieldElement::new();
|
||||||
// let mut tmp2;
|
// let mut tmp2;
|
||||||
// let mut e = [0; 32];
|
// let mut e = [0; 32];
|
||||||
//
|
//
|
||||||
@@ -1792,8 +1805,8 @@ pub fn x25519_public_from_private(public: &mut [u8], private: &[u8])
|
|||||||
|
|
||||||
/* We only need the u-coordinate of the curve25519 point. The map is
|
/* We only need the u-coordinate of the curve25519 point. The map is
|
||||||
* u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
|
* u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). */
|
||||||
let mut zplusy = [0; NUM_ELEMENT_LIMBS];
|
let mut zplusy = FieldElement::new();
|
||||||
let mut zminusy = [0; NUM_ELEMENT_LIMBS];
|
let mut zminusy = FieldElement::new();
|
||||||
fe_add(&mut zplusy, &A.z, &A.y);
|
fe_add(&mut zplusy, &A.z, &A.y);
|
||||||
fe_sub(&mut zminusy, &A.z, &A.y);
|
fe_sub(&mut zminusy, &A.z, &A.y);
|
||||||
let zminusy_inv = fe_invert(&zminusy);
|
let zminusy_inv = fe_invert(&zminusy);
|
||||||
@@ -1819,10 +1832,10 @@ fn public_from_private() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn into_encoded_point(bytes: &mut [u8], x: &Element, y: &Element, z: &Element)
|
fn into_encoded_point(bytes: &mut [u8], x: &FieldElement, y: &FieldElement, z: &FieldElement)
|
||||||
{
|
{
|
||||||
let mut x_over_z = [0; NUM_ELEMENT_LIMBS];
|
let mut x_over_z = FieldElement::new();
|
||||||
let mut y_over_z = [0; NUM_ELEMENT_LIMBS];
|
let mut y_over_z = FieldElement::new();
|
||||||
assert!(bytes.len() >= 32);
|
assert!(bytes.len() >= 32);
|
||||||
|
|
||||||
let recip = fe_invert(z);
|
let recip = fe_invert(z);
|
||||||
|
|||||||
Reference in New Issue
Block a user