From 0e6664f2326f50c87f89e8d84e9c06cfacabf52c Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Sun, 26 May 2019 16:15:24 -0700 Subject: [PATCH] Split out files for loading and scalars, clean up mod imports. --- src/ed25519/fe.rs | 33 +- src/ed25519/loads.rs | 33 ++ src/ed25519/mod.rs | 5 +- src/ed25519/point.rs | 877 ---------------------------------------- src/ed25519/scalars.rs | 881 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 920 insertions(+), 909 deletions(-) create mode 100644 src/ed25519/loads.rs diff --git a/src/ed25519/fe.rs b/src/ed25519/fe.rs index b0d1822..b620000 100644 --- a/src/ed25519/fe.rs +++ b/src/ed25519/fe.rs @@ -1,9 +1,7 @@ #[cfg(test)] use byteorder::{LittleEndian,NativeEndian,ReadBytesExt}; #[cfg(test)] -use cryptonum::unsigned::{Decoder,U192}; -#[cfg(test)] -use ed25519::point::curve25519_scalar_mask; +use ed25519::scalars::curve25519_scalar_mask; #[cfg(test)] use quickcheck::{Arbitrary,Gen}; #[cfg(test)] @@ -11,6 +9,7 @@ use std::io::Cursor; #[cfg(test)] use testing::run_test; +use ed25519::loads::{load3,load4}; use std::ops::*; // This is all an extremely straightforward translation of the usual C @@ -164,34 +163,6 @@ pub const KBOTTOM_26BITS : i64 = 0x3ffffffi64; pub const KTOP_39BITS : i64 = 0xfffffffffe000000u64 as i64; pub const KTOP_38BITS : i64 = 0xfffffffffc000000u64 as i64; -pub fn load3(x: &[u8]) -> u64 -{ - (x[0] as u64) | ((x[1] as u64) << 8) | ((x[2] as u64) << 16) -} - -pub fn load4(x: &[u8]) -> u64 -{ - (x[0] as u64) | ((x[1] as u64) << 8) | - ((x[2] as u64) << 16) | ((x[3] as u64) << 24) -} - -#[cfg(test)] -#[test] -fn loads() { - let fname = "testdata/ed25519/load.test"; - run_test(fname.to_string(), 3, |case| { - let (negx, xbytes) = case.get("x").unwrap(); - let (nega, abytes) = case.get("a").unwrap(); - let (negb, bbytes) = case.get("b").unwrap(); - - assert!(!negx && !nega && !negb); - let res3 = u64::from(U192::from_bytes(abytes)); - let res4 = u64::from(U192::from_bytes(bbytes)); - assert_eq!(res3, load3(&xbytes), "load3"); - assert_eq!(res4, load4(&xbytes), "load4"); - }); -} - #[cfg(test)] #[test] fn from_to_bytes() { diff --git a/src/ed25519/loads.rs b/src/ed25519/loads.rs new file mode 100644 index 0000000..568af70 --- /dev/null +++ b/src/ed25519/loads.rs @@ -0,0 +1,33 @@ +#[cfg(test)] +use cryptonum::unsigned::{Decoder,U192}; +#[cfg(test)] +use testing::run_test; + +pub fn load3(x: &[u8]) -> u64 +{ + (x[0] as u64) | ((x[1] as u64) << 8) | ((x[2] as u64) << 16) +} + +pub fn load4(x: &[u8]) -> u64 +{ + (x[0] as u64) | ((x[1] as u64) << 8) | + ((x[2] as u64) << 16) | ((x[3] as u64) << 24) +} + +#[cfg(test)] +#[test] +fn loads() { + let fname = "testdata/ed25519/load.test"; + run_test(fname.to_string(), 3, |case| { + let (negx, xbytes) = case.get("x").unwrap(); + let (nega, abytes) = case.get("a").unwrap(); + let (negb, bbytes) = case.get("b").unwrap(); + + assert!(!negx && !nega && !negb); + let res3 = u64::from(U192::from_bytes(abytes)); + let res4 = u64::from(U192::from_bytes(bbytes)); + assert_eq!(res3, load3(&xbytes), "load3"); + assert_eq!(res4, load4(&xbytes), "load4"); + }); +} + diff --git a/src/ed25519/mod.rs b/src/ed25519/mod.rs index 6947f2a..b462833 100644 --- a/src/ed25519/mod.rs +++ b/src/ed25519/mod.rs @@ -1,11 +1,14 @@ mod constants; mod fe; +mod loads; mod point; +mod scalars; use digest::Digest; use rand::Rng; use sha2::Sha512; -use self::point::*; +use self::scalars::{curve25519_scalar_mask,x25519_sc_muladd,x25519_sc_reduce}; +use self::point::{Point,Point2}; #[cfg(test)] use testing::run_test; #[cfg(test)] diff --git a/src/ed25519/point.rs b/src/ed25519/point.rs index 49d5c8d..14f491b 100644 --- a/src/ed25519/point.rs +++ b/src/ed25519/point.rs @@ -715,883 +715,6 @@ fn double_scalarmult() { }); } -/* The set of scalars is \Z/l - * where l = 2^252 + 27742317777372353535851937790883648493. */ - -/* Input: - * s[0]+256*s[1]+...+256^63*s[63] = s - * - * Output: - * s[0]+256*s[1]+...+256^31*s[31] = s mod l - * where l = 2^252 + 27742317777372353535851937790883648493. - * Overwrites s in place. */ -pub fn x25519_sc_reduce(s: &mut [u8]) -{ - let mut s0 : i64 = 2097151 & load3(s) as i64; - let mut s1 : i64 = 2097151 & (load4(&s[2..]) >> 5) as i64; - let mut s2 : i64 = 2097151 & (load3(&s[5..]) >> 2) as i64; - let mut s3 : i64 = 2097151 & (load4(&s[7..]) >> 7) as i64; - let mut s4 : i64 = 2097151 & (load4(&s[10..]) >> 4) as i64; - let mut s5 : i64 = 2097151 & (load3(&s[13..]) >> 1) as i64; - let mut s6 : i64 = 2097151 & (load4(&s[15..]) >> 6) as i64; - let mut s7 : i64 = 2097151 & (load3(&s[18..]) >> 3) as i64; - let mut s8 : i64 = 2097151 & load3(&s[21..]) as i64; - let mut s9 : i64 = 2097151 & (load4(&s[23..]) >> 5) as i64; - let mut s10 : i64 = 2097151 & (load3(&s[26..]) >> 2) as i64; - let mut s11 : i64 = 2097151 & (load4(&s[28..]) >> 7) as i64; - let mut s12 : i64 = 2097151 & (load4(&s[31..]) >> 4) as i64; - let mut s13 : i64 = 2097151 & (load3(&s[34..]) >> 1) as i64; - let mut s14 : i64 = 2097151 & (load4(&s[36..]) >> 6) as i64; - let mut s15 : i64 = 2097151 & (load3(&s[39..]) >> 3) as i64; - let mut s16 : i64 = 2097151 & load3(&s[42..]) as i64; - let mut s17 : i64 = 2097151 & (load4(&s[44..]) >> 5) as i64; - let s18 : i64 = 2097151 & (load3(&s[47..]) >> 2) as i64; - let s19 : i64 = 2097151 & (load4(&s[49..]) >> 7) as i64; - let s20 : i64 = 2097151 & (load4(&s[52..]) >> 4) as i64; - let s21 : i64 = 2097151 & (load3(&s[55..]) >> 1) as i64; - let s22 : i64 = 2097151 & (load4(&s[57..]) >> 6) as i64; - let s23 : i64 = (load4(&s[60..]) >> 3) as i64 as i64; - let mut carry0 : i64; - let mut carry1 : i64; - let mut carry2 : i64; - let mut carry3 : i64; - let mut carry4 : i64; - let mut carry5 : i64; - let mut carry6 : i64; - let mut carry7 : i64; - let mut carry8 : i64; - let mut carry9 : i64; - let mut carry10 : i64; - let mut carry11 : i64; - let carry12 : i64; - let carry13 : i64; - let carry14 : i64; - let carry15 : i64; - let carry16 : i64; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - //s23 = 0; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - //s22 = 0; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - //s21 = 0; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - //s20 = 0; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - //s19 = 0; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - //s18 = 0; - - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= carry10 << 21; - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= carry12 << 21; - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= carry14 << 21; - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= carry16 << 21; - - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= carry11 << 21; - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= carry13 << 21; - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - //s17 = 0; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - //s16 = 0; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - //s15 = 0; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - //s14 = 0; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - //s13 = 0; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= carry10 << 21; - - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry1 = s1 >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry2 = s2 >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry3 = s3 >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry4 = s4 >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry5 = s5 >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry6 = s6 >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry7 = s7 >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry8 = s8 >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry9 = s9 >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry10 = s10 >> 21; - s11 += carry10; - s10 -= carry10 << 21; - carry11 = s11 >> 21; - s12 += carry11; - s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - //s12 = 0; - - carry0 = s0 >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry1 = s1 >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry2 = s2 >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry3 = s3 >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry4 = s4 >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry5 = s5 >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry6 = s6 >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry7 = s7 >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry8 = s8 >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry9 = s9 >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry10 = s10 >> 21; - s11 += carry10; - s10 -= carry10 << 21; - - s[0] = (s0 >> 0) as u8; - s[1] = (s0 >> 8) as u8; - s[2] = ((s0 >> 16) | (s1 << 5)) as u8; - s[3] = (s1 >> 3) as u8; - s[4] = (s1 >> 11) as u8; - s[5] = ((s1 >> 19) | (s2 << 2)) as u8; - s[6] = (s2 >> 6) as u8; - s[7] = ((s2 >> 14) | (s3 << 7)) as u8; - s[8] = (s3 >> 1) as u8; - s[9] = (s3 >> 9) as u8; - s[10] = ((s3 >> 17) | (s4 << 4)) as u8; - s[11] = (s4 >> 4) as u8; - s[12] = (s4 >> 12) as u8; - s[13] = ((s4 >> 20) | (s5 << 1)) as u8; - s[14] = (s5 >> 7) as u8; - s[15] = ((s5 >> 15) | (s6 << 6)) as u8; - s[16] = (s6 >> 2) as u8; - s[17] = (s6 >> 10) as u8; - s[18] = ((s6 >> 18) | (s7 << 3)) as u8; - s[19] = (s7 >> 5) as u8; - s[20] = (s7 >> 13) as u8; - s[21] = (s8 >> 0) as u8; - s[22] = (s8 >> 8) as u8; - s[23] = ((s8 >> 16) | (s9 << 5)) as u8; - s[24] = (s9 >> 3) as u8; - s[25] = (s9 >> 11) as u8; - s[26] = ((s9 >> 19) | (s10 << 2)) as u8; - s[27] = (s10 >> 6) as u8; - s[28] = ((s10 >> 14) | (s11 << 7)) as u8; - s[29] = (s11 >> 1) as u8; - s[30] = (s11 >> 9) as u8; - s[31] = (s11 >> 17) as u8; -} - -#[cfg(test)] -#[test] -fn reduce() { - let fname = "testdata/ed25519/reduce.test"; - run_test(fname.to_string(), 2, |case| { - let (nega, abytes) = case.get("a").unwrap(); - let (negb, bbytes) = case.get("b").unwrap(); - - assert!(!nega && !negb); - assert_eq!(abytes.len(), 64); - assert_eq!(bbytes.len(), 32); - let mut copy = abytes.clone(); - x25519_sc_reduce(&mut copy); - assert_eq!(©[0..32], &bbytes[0..]); - }); -} - -/* Input: - * a[0]+256*a[1]+...+256^31*a[31] = a - * b[0]+256*b[1]+...+256^31*b[31] = b - * c[0]+256*c[1]+...+256^31*c[31] = c - * - * Output: - * s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l - * where l = 2^252 + 27742317777372353535851937790883648493. */ -pub fn x25519_sc_muladd(s: &mut [u8], a: &[u8], b: &[u8], c: &[u8]) -{ - let a0 : i64 = 2097151 & load3(a) as i64; - let a1 : i64 = 2097151 & (load4(&a[2..]) >> 5) as i64; - let a2 : i64 = 2097151 & (load3(&a[5..]) >> 2) as i64; - let a3 : i64 = 2097151 & (load4(&a[7..]) >> 7) as i64; - let a4 : i64 = 2097151 & (load4(&a[10..]) >> 4) as i64; - let a5 : i64 = 2097151 & (load3(&a[13..]) >> 1) as i64; - let a6 : i64 = 2097151 & (load4(&a[15..]) >> 6) as i64; - let a7 : i64 = 2097151 & (load3(&a[18..]) >> 3) as i64; - let a8 : i64 = 2097151 & load3(&a[21..]) as i64; - let a9 : i64 = 2097151 & (load4(&a[23..]) >> 5) as i64; - let a10 : i64 = 2097151 & (load3(&a[26..]) >> 2) as i64; - let a11 : i64 = (load4(&a[28..]) >> 7) as i64; - let b0 : i64 = 2097151 & load3(b) as i64; - let b1 : i64 = 2097151 & (load4(&b[2..]) >> 5) as i64; - let b2 : i64 = 2097151 & (load3(&b[5..]) >> 2) as i64; - let b3 : i64 = 2097151 & (load4(&b[7..]) >> 7) as i64; - let b4 : i64 = 2097151 & (load4(&b[10..]) >> 4) as i64; - let b5 : i64 = 2097151 & (load3(&b[13..]) >> 1) as i64; - let b6 : i64 = 2097151 & (load4(&b[15..]) >> 6) as i64; - let b7 : i64 = 2097151 & (load3(&b[18..]) >> 3) as i64; - let b8 : i64 = 2097151 & load3(&b[21..]) as i64; - let b9 : i64 = 2097151 & (load4(&b[23..]) >> 5) as i64; - let b10 : i64 = 2097151 & (load3(&b[26..]) >> 2) as i64; - let b11 : i64 = (load4(&b[28..]) >> 7) as i64; - let c0 : i64 = 2097151 & load3(c) as i64; - let c1 : i64 = 2097151 & (load4(&c[2..]) >> 5) as i64; - let c2 : i64 = 2097151 & (load3(&c[5..]) >> 2) as i64; - let c3 : i64 = 2097151 & (load4(&c[7..]) >> 7) as i64; - let c4 : i64 = 2097151 & (load4(&c[10..]) >> 4) as i64; - let c5 : i64 = 2097151 & (load3(&c[13..]) >> 1) as i64; - let c6 : i64 = 2097151 & (load4(&c[15..]) >> 6) as i64; - let c7 : i64 = 2097151 & (load3(&c[18..]) >> 3) as i64; - let c8 : i64 = 2097151 & load3(&c[21..]) as i64; - let c9 : i64 = 2097151 & (load4(&c[23..]) >> 5) as i64; - let c10 : i64 = 2097151 & (load3(&c[26..]) >> 2) as i64; - let c11 : i64 = (load4(&c[28..]) >> 7) as i64; - let mut s0 : i64; - let mut s1 : i64; - let mut s2 : i64; - let mut s3 : i64; - let mut s4 : i64; - let mut s5 : i64; - let mut s6 : i64; - let mut s7 : i64; - let mut s8 : i64; - let mut s9 : i64; - let mut s10 : i64; - let mut s11 : i64; - let mut s12 : i64; - let mut s13 : i64; - let mut s14 : i64; - let mut s15 : i64; - let mut s16 : i64; - let mut s17 : i64; - let mut s18 : i64; - let mut s19 : i64; - let mut s20 : i64; - let mut s21 : i64; - let mut s22 : i64; - let mut s23 : i64; - let mut carry0 : i64; - let mut carry1 : i64; - let mut carry2 : i64; - let mut carry3 : i64; - let mut carry4 : i64; - let mut carry5 : i64; - let mut carry6 : i64; - let mut carry7 : i64; - let mut carry8 : i64; - let mut carry9 : i64; - let mut carry10 : i64; - let mut carry11 : i64; - let mut carry12 : i64; - let mut carry13 : i64; - let mut carry14 : i64; - let mut carry15 : i64; - let mut carry16 : i64; - let carry17 : i64; - let carry18 : i64; - let carry19 : i64; - let carry20 : i64; - let carry21 : i64; - let carry22 : i64; - - s0 = c0 + a0 * b0; - s1 = c1 + a0 * b1 + a1 * b0; - s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; - s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; - s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; - s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; - s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; - s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + - a6 * b1 + a7 * b0; - s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + - a6 * b2 + a7 * b1 + a8 * b0; - s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + - a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; - s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + - a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; - s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + - a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; - s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + - a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; - s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + - a9 * b4 + a10 * b3 + a11 * b2; - s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + - a10 * b4 + a11 * b3; - s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + - a11 * b4; - s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; - s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; - s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; - s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; - s20 = a9 * b11 + a10 * b10 + a11 * b9; - s21 = a10 * b11 + a11 * b10; - s22 = a11 * b11; - s23 = 0; - - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= carry10 << 21; - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= carry12 << 21; - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= carry14 << 21; - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= carry16 << 21; - carry18 = (s18 + (1 << 20)) >> 21; - s19 += carry18; - s18 -= carry18 << 21; - carry20 = (s20 + (1 << 20)) >> 21; - s21 += carry20; - s20 -= carry20 << 21; - carry22 = (s22 + (1 << 20)) >> 21; - s23 += carry22; - s22 -= carry22 << 21; - - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= carry11 << 21; - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= carry13 << 21; - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= carry15 << 21; - carry17 = (s17 + (1 << 20)) >> 21; - s18 += carry17; - s17 -= carry17 << 21; - carry19 = (s19 + (1 << 20)) >> 21; - s20 += carry19; - s19 -= carry19 << 21; - carry21 = (s21 + (1 << 20)) >> 21; - s22 += carry21; - s21 -= carry21 << 21; - - s11 += s23 * 666643; - s12 += s23 * 470296; - s13 += s23 * 654183; - s14 -= s23 * 997805; - s15 += s23 * 136657; - s16 -= s23 * 683901; - //s23 = 0; - - s10 += s22 * 666643; - s11 += s22 * 470296; - s12 += s22 * 654183; - s13 -= s22 * 997805; - s14 += s22 * 136657; - s15 -= s22 * 683901; - //s22 = 0; - - s9 += s21 * 666643; - s10 += s21 * 470296; - s11 += s21 * 654183; - s12 -= s21 * 997805; - s13 += s21 * 136657; - s14 -= s21 * 683901; - //s21 = 0; - - s8 += s20 * 666643; - s9 += s20 * 470296; - s10 += s20 * 654183; - s11 -= s20 * 997805; - s12 += s20 * 136657; - s13 -= s20 * 683901; - //s20 = 0; - - s7 += s19 * 666643; - s8 += s19 * 470296; - s9 += s19 * 654183; - s10 -= s19 * 997805; - s11 += s19 * 136657; - s12 -= s19 * 683901; - //s19 = 0; - - s6 += s18 * 666643; - s7 += s18 * 470296; - s8 += s18 * 654183; - s9 -= s18 * 997805; - s10 += s18 * 136657; - s11 -= s18 * 683901; - //s18 = 0; - - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= carry10 << 21; - carry12 = (s12 + (1 << 20)) >> 21; - s13 += carry12; - s12 -= carry12 << 21; - carry14 = (s14 + (1 << 20)) >> 21; - s15 += carry14; - s14 -= carry14 << 21; - carry16 = (s16 + (1 << 20)) >> 21; - s17 += carry16; - s16 -= carry16 << 21; - - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= carry11 << 21; - carry13 = (s13 + (1 << 20)) >> 21; - s14 += carry13; - s13 -= carry13 << 21; - carry15 = (s15 + (1 << 20)) >> 21; - s16 += carry15; - s15 -= carry15 << 21; - - s5 += s17 * 666643; - s6 += s17 * 470296; - s7 += s17 * 654183; - s8 -= s17 * 997805; - s9 += s17 * 136657; - s10 -= s17 * 683901; - //s17 = 0; - - s4 += s16 * 666643; - s5 += s16 * 470296; - s6 += s16 * 654183; - s7 -= s16 * 997805; - s8 += s16 * 136657; - s9 -= s16 * 683901; - //s16 = 0; - - s3 += s15 * 666643; - s4 += s15 * 470296; - s5 += s15 * 654183; - s6 -= s15 * 997805; - s7 += s15 * 136657; - s8 -= s15 * 683901; - //s15 = 0; - - s2 += s14 * 666643; - s3 += s14 * 470296; - s4 += s14 * 654183; - s5 -= s14 * 997805; - s6 += s14 * 136657; - s7 -= s14 * 683901; - //s14 = 0; - - s1 += s13 * 666643; - s2 += s13 * 470296; - s3 += s13 * 654183; - s4 -= s13 * 997805; - s5 += s13 * 136657; - s6 -= s13 * 683901; - //s13 = 0; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = (s0 + (1 << 20)) >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry2 = (s2 + (1 << 20)) >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry4 = (s4 + (1 << 20)) >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry6 = (s6 + (1 << 20)) >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry8 = (s8 + (1 << 20)) >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry10 = (s10 + (1 << 20)) >> 21; - s11 += carry10; - s10 -= carry10 << 21; - - carry1 = (s1 + (1 << 20)) >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry3 = (s3 + (1 << 20)) >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry5 = (s5 + (1 << 20)) >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry7 = (s7 + (1 << 20)) >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry9 = (s9 + (1 << 20)) >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry11 = (s11 + (1 << 20)) >> 21; - s12 += carry11; - s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - s12 = 0; - - carry0 = s0 >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry1 = s1 >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry2 = s2 >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry3 = s3 >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry4 = s4 >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry5 = s5 >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry6 = s6 >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry7 = s7 >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry8 = s8 >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry9 = s9 >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry10 = s10 >> 21; - s11 += carry10; - s10 -= carry10 << 21; - carry11 = s11 >> 21; - s12 += carry11; - s11 -= carry11 << 21; - - s0 += s12 * 666643; - s1 += s12 * 470296; - s2 += s12 * 654183; - s3 -= s12 * 997805; - s4 += s12 * 136657; - s5 -= s12 * 683901; - //s12 = 0; - - carry0 = s0 >> 21; - s1 += carry0; - s0 -= carry0 << 21; - carry1 = s1 >> 21; - s2 += carry1; - s1 -= carry1 << 21; - carry2 = s2 >> 21; - s3 += carry2; - s2 -= carry2 << 21; - carry3 = s3 >> 21; - s4 += carry3; - s3 -= carry3 << 21; - carry4 = s4 >> 21; - s5 += carry4; - s4 -= carry4 << 21; - carry5 = s5 >> 21; - s6 += carry5; - s5 -= carry5 << 21; - carry6 = s6 >> 21; - s7 += carry6; - s6 -= carry6 << 21; - carry7 = s7 >> 21; - s8 += carry7; - s7 -= carry7 << 21; - carry8 = s8 >> 21; - s9 += carry8; - s8 -= carry8 << 21; - carry9 = s9 >> 21; - s10 += carry9; - s9 -= carry9 << 21; - carry10 = s10 >> 21; - s11 += carry10; - s10 -= carry10 << 21; - - s[0] = (s0 >> 0) as u8; - s[1] = (s0 >> 8) as u8; - s[2] = ((s0 >> 16) | (s1 << 5)) as u8; - s[3] = (s1 >> 3) as u8; - s[4] = (s1 >> 11) as u8; - s[5] = ((s1 >> 19) | (s2 << 2)) as u8; - s[6] = (s2 >> 6) as u8; - s[7] = ((s2 >> 14) | (s3 << 7)) as u8; - s[8] = (s3 >> 1) as u8; - s[9] = (s3 >> 9) as u8; - s[10] = ((s3 >> 17) | (s4 << 4)) as u8; - s[11] = (s4 >> 4) as u8; - s[12] = (s4 >> 12) as u8; - s[13] = ((s4 >> 20) | (s5 << 1)) as u8; - s[14] = (s5 >> 7) as u8; - s[15] = ((s5 >> 15) | (s6 << 6)) as u8; - s[16] = (s6 >> 2) as u8; - s[17] = (s6 >> 10) as u8; - s[18] = ((s6 >> 18) | (s7 << 3)) as u8; - s[19] = (s7 >> 5) as u8; - s[20] = (s7 >> 13) as u8; - s[21] = (s8 >> 0) as u8; - s[22] = (s8 >> 8) as u8; - s[23] = ((s8 >> 16) | (s9 << 5)) as u8; - s[24] = (s9 >> 3) as u8; - s[25] = (s9 >> 11) as u8; - s[26] = ((s9 >> 19) | (s10 << 2)) as u8; - s[27] = (s10 >> 6) as u8; - s[28] = ((s10 >> 14) | (s11 << 7)) as u8; - s[29] = (s11 >> 1) as u8; - s[30] = (s11 >> 9) as u8; - s[31] = (s11 >> 17) as u8; -} - -#[cfg(test)] -#[test] -fn muladd() { - let fname = "testdata/ed25519/muladd.test"; - run_test(fname.to_string(), 4, |case| { - let (nega, abytes) = case.get("a").unwrap(); - let (negb, bbytes) = case.get("b").unwrap(); - let (negc, cbytes) = case.get("c").unwrap(); - let (negd, dbytes) = case.get("d").unwrap(); - - assert!(!nega && !negb && !negc && !negd); - let mut mine = [0; 32]; - x25519_sc_muladd(&mut mine, abytes, bbytes, cbytes); - for i in 0..32 { - assert_eq!(&mine[i], &dbytes[i]); - } - }); -} - -pub fn curve25519_scalar_mask(a: &mut [u8]) -{ - assert_eq!(a.len(), 32); - a[0] &= 248; - a[31] &= 127; - a[31] |= 64; -} - fn into_encoded_point(x: &FieldElement, y: &FieldElement, z: &FieldElement) -> Vec { let recip = z.invert(); diff --git a/src/ed25519/scalars.rs b/src/ed25519/scalars.rs index e69de29..6e6f54b 100644 --- a/src/ed25519/scalars.rs +++ b/src/ed25519/scalars.rs @@ -0,0 +1,881 @@ +use ed25519::loads::{load3,load4}; +#[cfg(test)] +use testing::run_test; + +/* The set of scalars is \Z/l + * where l = 2^252 + 27742317777372353535851937790883648493. */ + +/* Input: + * s[0]+256*s[1]+...+256^63*s[63] = s + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = s mod l + * where l = 2^252 + 27742317777372353535851937790883648493. + * Overwrites s in place. */ +pub fn x25519_sc_reduce(s: &mut [u8]) +{ + let mut s0 : i64 = 2097151 & load3(s) as i64; + let mut s1 : i64 = 2097151 & (load4(&s[2..]) >> 5) as i64; + let mut s2 : i64 = 2097151 & (load3(&s[5..]) >> 2) as i64; + let mut s3 : i64 = 2097151 & (load4(&s[7..]) >> 7) as i64; + let mut s4 : i64 = 2097151 & (load4(&s[10..]) >> 4) as i64; + let mut s5 : i64 = 2097151 & (load3(&s[13..]) >> 1) as i64; + let mut s6 : i64 = 2097151 & (load4(&s[15..]) >> 6) as i64; + let mut s7 : i64 = 2097151 & (load3(&s[18..]) >> 3) as i64; + let mut s8 : i64 = 2097151 & load3(&s[21..]) as i64; + let mut s9 : i64 = 2097151 & (load4(&s[23..]) >> 5) as i64; + let mut s10 : i64 = 2097151 & (load3(&s[26..]) >> 2) as i64; + let mut s11 : i64 = 2097151 & (load4(&s[28..]) >> 7) as i64; + let mut s12 : i64 = 2097151 & (load4(&s[31..]) >> 4) as i64; + let mut s13 : i64 = 2097151 & (load3(&s[34..]) >> 1) as i64; + let mut s14 : i64 = 2097151 & (load4(&s[36..]) >> 6) as i64; + let mut s15 : i64 = 2097151 & (load3(&s[39..]) >> 3) as i64; + let mut s16 : i64 = 2097151 & load3(&s[42..]) as i64; + let mut s17 : i64 = 2097151 & (load4(&s[44..]) >> 5) as i64; + let s18 : i64 = 2097151 & (load3(&s[47..]) >> 2) as i64; + let s19 : i64 = 2097151 & (load4(&s[49..]) >> 7) as i64; + let s20 : i64 = 2097151 & (load4(&s[52..]) >> 4) as i64; + let s21 : i64 = 2097151 & (load3(&s[55..]) >> 1) as i64; + let s22 : i64 = 2097151 & (load4(&s[57..]) >> 6) as i64; + let s23 : i64 = (load4(&s[60..]) >> 3) as i64 as i64; + let mut carry0 : i64; + let mut carry1 : i64; + let mut carry2 : i64; + let mut carry3 : i64; + let mut carry4 : i64; + let mut carry5 : i64; + let mut carry6 : i64; + let mut carry7 : i64; + let mut carry8 : i64; + let mut carry9 : i64; + let mut carry10 : i64; + let mut carry11 : i64; + let carry12 : i64; + let carry13 : i64; + let carry14 : i64; + let carry15 : i64; + let carry16 : i64; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + //s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + //s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + //s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + //s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + //s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + //s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + //s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + //s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + //s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + //s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + //s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + //s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = (s0 >> 0) as u8; + s[1] = (s0 >> 8) as u8; + s[2] = ((s0 >> 16) | (s1 << 5)) as u8; + s[3] = (s1 >> 3) as u8; + s[4] = (s1 >> 11) as u8; + s[5] = ((s1 >> 19) | (s2 << 2)) as u8; + s[6] = (s2 >> 6) as u8; + s[7] = ((s2 >> 14) | (s3 << 7)) as u8; + s[8] = (s3 >> 1) as u8; + s[9] = (s3 >> 9) as u8; + s[10] = ((s3 >> 17) | (s4 << 4)) as u8; + s[11] = (s4 >> 4) as u8; + s[12] = (s4 >> 12) as u8; + s[13] = ((s4 >> 20) | (s5 << 1)) as u8; + s[14] = (s5 >> 7) as u8; + s[15] = ((s5 >> 15) | (s6 << 6)) as u8; + s[16] = (s6 >> 2) as u8; + s[17] = (s6 >> 10) as u8; + s[18] = ((s6 >> 18) | (s7 << 3)) as u8; + s[19] = (s7 >> 5) as u8; + s[20] = (s7 >> 13) as u8; + s[21] = (s8 >> 0) as u8; + s[22] = (s8 >> 8) as u8; + s[23] = ((s8 >> 16) | (s9 << 5)) as u8; + s[24] = (s9 >> 3) as u8; + s[25] = (s9 >> 11) as u8; + s[26] = ((s9 >> 19) | (s10 << 2)) as u8; + s[27] = (s10 >> 6) as u8; + s[28] = ((s10 >> 14) | (s11 << 7)) as u8; + s[29] = (s11 >> 1) as u8; + s[30] = (s11 >> 9) as u8; + s[31] = (s11 >> 17) as u8; +} + +#[cfg(test)] +#[test] +fn reduce() { + let fname = "testdata/ed25519/reduce.test"; + run_test(fname.to_string(), 2, |case| { + let (nega, abytes) = case.get("a").unwrap(); + let (negb, bbytes) = case.get("b").unwrap(); + + assert!(!nega && !negb); + assert_eq!(abytes.len(), 64); + assert_eq!(bbytes.len(), 32); + let mut copy = abytes.clone(); + x25519_sc_reduce(&mut copy); + assert_eq!(©[0..32], &bbytes[0..]); + }); +} + +/* Input: + * a[0]+256*a[1]+...+256^31*a[31] = a + * b[0]+256*b[1]+...+256^31*b[31] = b + * c[0]+256*c[1]+...+256^31*c[31] = c + * + * Output: + * s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l + * where l = 2^252 + 27742317777372353535851937790883648493. */ +pub fn x25519_sc_muladd(s: &mut [u8], a: &[u8], b: &[u8], c: &[u8]) +{ + let a0 : i64 = 2097151 & load3(a) as i64; + let a1 : i64 = 2097151 & (load4(&a[2..]) >> 5) as i64; + let a2 : i64 = 2097151 & (load3(&a[5..]) >> 2) as i64; + let a3 : i64 = 2097151 & (load4(&a[7..]) >> 7) as i64; + let a4 : i64 = 2097151 & (load4(&a[10..]) >> 4) as i64; + let a5 : i64 = 2097151 & (load3(&a[13..]) >> 1) as i64; + let a6 : i64 = 2097151 & (load4(&a[15..]) >> 6) as i64; + let a7 : i64 = 2097151 & (load3(&a[18..]) >> 3) as i64; + let a8 : i64 = 2097151 & load3(&a[21..]) as i64; + let a9 : i64 = 2097151 & (load4(&a[23..]) >> 5) as i64; + let a10 : i64 = 2097151 & (load3(&a[26..]) >> 2) as i64; + let a11 : i64 = (load4(&a[28..]) >> 7) as i64; + let b0 : i64 = 2097151 & load3(b) as i64; + let b1 : i64 = 2097151 & (load4(&b[2..]) >> 5) as i64; + let b2 : i64 = 2097151 & (load3(&b[5..]) >> 2) as i64; + let b3 : i64 = 2097151 & (load4(&b[7..]) >> 7) as i64; + let b4 : i64 = 2097151 & (load4(&b[10..]) >> 4) as i64; + let b5 : i64 = 2097151 & (load3(&b[13..]) >> 1) as i64; + let b6 : i64 = 2097151 & (load4(&b[15..]) >> 6) as i64; + let b7 : i64 = 2097151 & (load3(&b[18..]) >> 3) as i64; + let b8 : i64 = 2097151 & load3(&b[21..]) as i64; + let b9 : i64 = 2097151 & (load4(&b[23..]) >> 5) as i64; + let b10 : i64 = 2097151 & (load3(&b[26..]) >> 2) as i64; + let b11 : i64 = (load4(&b[28..]) >> 7) as i64; + let c0 : i64 = 2097151 & load3(c) as i64; + let c1 : i64 = 2097151 & (load4(&c[2..]) >> 5) as i64; + let c2 : i64 = 2097151 & (load3(&c[5..]) >> 2) as i64; + let c3 : i64 = 2097151 & (load4(&c[7..]) >> 7) as i64; + let c4 : i64 = 2097151 & (load4(&c[10..]) >> 4) as i64; + let c5 : i64 = 2097151 & (load3(&c[13..]) >> 1) as i64; + let c6 : i64 = 2097151 & (load4(&c[15..]) >> 6) as i64; + let c7 : i64 = 2097151 & (load3(&c[18..]) >> 3) as i64; + let c8 : i64 = 2097151 & load3(&c[21..]) as i64; + let c9 : i64 = 2097151 & (load4(&c[23..]) >> 5) as i64; + let c10 : i64 = 2097151 & (load3(&c[26..]) >> 2) as i64; + let c11 : i64 = (load4(&c[28..]) >> 7) as i64; + let mut s0 : i64; + let mut s1 : i64; + let mut s2 : i64; + let mut s3 : i64; + let mut s4 : i64; + let mut s5 : i64; + let mut s6 : i64; + let mut s7 : i64; + let mut s8 : i64; + let mut s9 : i64; + let mut s10 : i64; + let mut s11 : i64; + let mut s12 : i64; + let mut s13 : i64; + let mut s14 : i64; + let mut s15 : i64; + let mut s16 : i64; + let mut s17 : i64; + let mut s18 : i64; + let mut s19 : i64; + let mut s20 : i64; + let mut s21 : i64; + let mut s22 : i64; + let mut s23 : i64; + let mut carry0 : i64; + let mut carry1 : i64; + let mut carry2 : i64; + let mut carry3 : i64; + let mut carry4 : i64; + let mut carry5 : i64; + let mut carry6 : i64; + let mut carry7 : i64; + let mut carry8 : i64; + let mut carry9 : i64; + let mut carry10 : i64; + let mut carry11 : i64; + let mut carry12 : i64; + let mut carry13 : i64; + let mut carry14 : i64; + let mut carry15 : i64; + let mut carry16 : i64; + let carry17 : i64; + let carry18 : i64; + let carry19 : i64; + let carry20 : i64; + let carry21 : i64; + let carry22 : i64; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + //s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + //s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + //s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + //s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + //s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + //s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + //s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + //s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + //s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + //s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + //s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + //s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = (s0 >> 0) as u8; + s[1] = (s0 >> 8) as u8; + s[2] = ((s0 >> 16) | (s1 << 5)) as u8; + s[3] = (s1 >> 3) as u8; + s[4] = (s1 >> 11) as u8; + s[5] = ((s1 >> 19) | (s2 << 2)) as u8; + s[6] = (s2 >> 6) as u8; + s[7] = ((s2 >> 14) | (s3 << 7)) as u8; + s[8] = (s3 >> 1) as u8; + s[9] = (s3 >> 9) as u8; + s[10] = ((s3 >> 17) | (s4 << 4)) as u8; + s[11] = (s4 >> 4) as u8; + s[12] = (s4 >> 12) as u8; + s[13] = ((s4 >> 20) | (s5 << 1)) as u8; + s[14] = (s5 >> 7) as u8; + s[15] = ((s5 >> 15) | (s6 << 6)) as u8; + s[16] = (s6 >> 2) as u8; + s[17] = (s6 >> 10) as u8; + s[18] = ((s6 >> 18) | (s7 << 3)) as u8; + s[19] = (s7 >> 5) as u8; + s[20] = (s7 >> 13) as u8; + s[21] = (s8 >> 0) as u8; + s[22] = (s8 >> 8) as u8; + s[23] = ((s8 >> 16) | (s9 << 5)) as u8; + s[24] = (s9 >> 3) as u8; + s[25] = (s9 >> 11) as u8; + s[26] = ((s9 >> 19) | (s10 << 2)) as u8; + s[27] = (s10 >> 6) as u8; + s[28] = ((s10 >> 14) | (s11 << 7)) as u8; + s[29] = (s11 >> 1) as u8; + s[30] = (s11 >> 9) as u8; + s[31] = (s11 >> 17) as u8; +} + +#[cfg(test)] +#[test] +fn muladd() { + let fname = "testdata/ed25519/muladd.test"; + run_test(fname.to_string(), 4, |case| { + let (nega, abytes) = case.get("a").unwrap(); + let (negb, bbytes) = case.get("b").unwrap(); + let (negc, cbytes) = case.get("c").unwrap(); + let (negd, dbytes) = case.get("d").unwrap(); + + assert!(!nega && !negb && !negc && !negd); + let mut mine = [0; 32]; + x25519_sc_muladd(&mut mine, abytes, bbytes, cbytes); + for i in 0..32 { + assert_eq!(&mine[i], &dbytes[i]); + } + }); +} + +pub fn curve25519_scalar_mask(a: &mut [u8]) +{ + assert_eq!(a.len(), 32); + a[0] &= 248; + a[31] &= 127; + a[31] |= 64; +} +