Pull to_bytes() into FieldElement.
This commit is contained in:
@@ -76,6 +76,85 @@ impl FieldElement
|
||||
h4 as i32, h5 as i32, h6 as i32, h7 as i32,
|
||||
h8 as i32, h9 as i32] }
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Vec<u8>
|
||||
{
|
||||
let mut h0 = self.value[0];
|
||||
let mut h1 = self.value[1];
|
||||
let mut h2 = self.value[2];
|
||||
let mut h3 = self.value[3];
|
||||
let mut h4 = self.value[4];
|
||||
let mut h5 = self.value[5];
|
||||
let mut h6 = self.value[6];
|
||||
let mut h7 = self.value[7];
|
||||
let mut h8 = self.value[8];
|
||||
let mut h9 = self.value[9];
|
||||
|
||||
let mut q = (19 * h9 + ((1i32) << 24)) >> 25;
|
||||
q = (h0 + q) >> 26;
|
||||
q = (h1 + q) >> 25;
|
||||
q = (h2 + q) >> 26;
|
||||
q = (h3 + q) >> 25;
|
||||
q = (h4 + q) >> 26;
|
||||
q = (h5 + q) >> 25;
|
||||
q = (h6 + q) >> 26;
|
||||
q = (h7 + q) >> 25;
|
||||
q = (h8 + q) >> 26;
|
||||
q = (h9 + q) >> 25;
|
||||
|
||||
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
|
||||
h0 += 19 * q;
|
||||
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
|
||||
h1 += h0 >> 26; h0 &= KBOTTOM_26BITS as i32;
|
||||
h2 += h1 >> 25; h1 &= KBOTTOM_25BITS as i32;
|
||||
h3 += h2 >> 26; h2 &= KBOTTOM_26BITS as i32;
|
||||
h4 += h3 >> 25; h3 &= KBOTTOM_25BITS as i32;
|
||||
h5 += h4 >> 26; h4 &= KBOTTOM_26BITS as i32;
|
||||
h6 += h5 >> 25; h5 &= KBOTTOM_25BITS as i32;
|
||||
h7 += h6 >> 26; h6 &= KBOTTOM_26BITS as i32;
|
||||
h8 += h7 >> 25; h7 &= KBOTTOM_25BITS as i32;
|
||||
h9 += h8 >> 26; h8 &= KBOTTOM_26BITS as i32;
|
||||
h9 &= KBOTTOM_25BITS as i32;
|
||||
/* h10 = carry9 */
|
||||
|
||||
/* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
* Have h0+...+2^230 h9 between 0 and 2^255-1;
|
||||
* evidently 2^255 h10-2^255 q = 0.
|
||||
* Goal: Output h0+...+2^230 h9. */
|
||||
vec![ (h0 >> 0) as u8,
|
||||
(h0 >> 8) as u8,
|
||||
(h0 >> 16) as u8,
|
||||
((h0 >> 24) | (((h1 as u32) << 2) as i32)) as u8,
|
||||
(h1 >> 6) as u8,
|
||||
(h1 >> 14) as u8,
|
||||
((h1 >> 22) | (((h2 as u32) << 3) as i32)) as u8,
|
||||
(h2 >> 5) as u8,
|
||||
(h2 >> 13) as u8,
|
||||
((h2 >> 21) | (((h3 as u32) << 5) as i32)) as u8,
|
||||
(h3 >> 3) as u8,
|
||||
(h3 >> 11) as u8,
|
||||
((h3 >> 19) | (((h4 as u32) << 6) as i32)) as u8,
|
||||
(h4 >> 2) as u8,
|
||||
(h4 >> 10) as u8,
|
||||
(h4 >> 18) as u8,
|
||||
(h5 >> 0) as u8,
|
||||
(h5 >> 8) as u8,
|
||||
(h5 >> 16) as u8,
|
||||
((h5 >> 24) | (((h6 as u32) << 1) as i32)) as u8,
|
||||
(h6 >> 7) as u8,
|
||||
(h6 >> 15) as u8,
|
||||
((h6 >> 23) | (((h7 as u32) << 3) as i32)) as u8,
|
||||
(h7 >> 5) as u8,
|
||||
(h7 >> 13) as u8,
|
||||
((h7 >> 21) | (((h8 as u32) << 4) as i32)) as u8,
|
||||
(h8 >> 4) as u8,
|
||||
(h8 >> 12) as u8,
|
||||
((h8 >> 20) | (((h9 as u32) << 6) as i32)) as u8,
|
||||
(h9 >> 2) as u8,
|
||||
(h9 >> 10) as u8,
|
||||
(h9 >> 18) as u8
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub const KBOTTOM_25BITS : i64 = 0x1ffffffi64;
|
||||
@@ -111,85 +190,6 @@ fn loads() {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn fe_tobytes(s: &mut [u8], h: &FieldElement)
|
||||
{
|
||||
assert!(s.len() >= 32);
|
||||
let mut h0 = h.value[0];
|
||||
let mut h1 = h.value[1];
|
||||
let mut h2 = h.value[2];
|
||||
let mut h3 = h.value[3];
|
||||
let mut h4 = h.value[4];
|
||||
let mut h5 = h.value[5];
|
||||
let mut h6 = h.value[6];
|
||||
let mut h7 = h.value[7];
|
||||
let mut h8 = h.value[8];
|
||||
let mut h9 = h.value[9];
|
||||
|
||||
let mut q = (19 * h9 + ((1i32) << 24)) >> 25;
|
||||
q = (h0 + q) >> 26;
|
||||
q = (h1 + q) >> 25;
|
||||
q = (h2 + q) >> 26;
|
||||
q = (h3 + q) >> 25;
|
||||
q = (h4 + q) >> 26;
|
||||
q = (h5 + q) >> 25;
|
||||
q = (h6 + q) >> 26;
|
||||
q = (h7 + q) >> 25;
|
||||
q = (h8 + q) >> 26;
|
||||
q = (h9 + q) >> 25;
|
||||
|
||||
/* Goal: Output h-(2^255-19)q, which is between 0 and 2^255-20. */
|
||||
h0 += 19 * q;
|
||||
/* Goal: Output h-2^255 q, which is between 0 and 2^255-20. */
|
||||
h1 += h0 >> 26; h0 &= KBOTTOM_26BITS as i32;
|
||||
h2 += h1 >> 25; h1 &= KBOTTOM_25BITS as i32;
|
||||
h3 += h2 >> 26; h2 &= KBOTTOM_26BITS as i32;
|
||||
h4 += h3 >> 25; h3 &= KBOTTOM_25BITS as i32;
|
||||
h5 += h4 >> 26; h4 &= KBOTTOM_26BITS as i32;
|
||||
h6 += h5 >> 25; h5 &= KBOTTOM_25BITS as i32;
|
||||
h7 += h6 >> 26; h6 &= KBOTTOM_26BITS as i32;
|
||||
h8 += h7 >> 25; h7 &= KBOTTOM_25BITS as i32;
|
||||
h9 += h8 >> 26; h8 &= KBOTTOM_26BITS as i32;
|
||||
h9 &= KBOTTOM_25BITS as i32;
|
||||
/* h10 = carry9 */
|
||||
|
||||
/* Goal: Output h0+...+2^255 h10-2^255 q, which is between 0 and 2^255-20.
|
||||
* Have h0+...+2^230 h9 between 0 and 2^255-1;
|
||||
* evidently 2^255 h10-2^255 q = 0.
|
||||
* Goal: Output h0+...+2^230 h9. */
|
||||
s[0] = (h0 >> 0) as u8;
|
||||
s[1] = (h0 >> 8) as u8;
|
||||
s[2] = (h0 >> 16) as u8;
|
||||
s[3] = ((h0 >> 24) | (((h1 as u32) << 2) as i32)) as u8;
|
||||
s[4] = (h1 >> 6) as u8;
|
||||
s[5] = (h1 >> 14) as u8;
|
||||
s[6] = ((h1 >> 22) | (((h2 as u32) << 3) as i32)) as u8;
|
||||
s[7] = (h2 >> 5) as u8;
|
||||
s[8] = (h2 >> 13) as u8;
|
||||
s[9] = ((h2 >> 21) | (((h3 as u32) << 5) as i32)) as u8;
|
||||
s[10] = (h3 >> 3) as u8;
|
||||
s[11] = (h3 >> 11) as u8;
|
||||
s[12] = ((h3 >> 19) | (((h4 as u32) << 6) as i32)) as u8;
|
||||
s[13] = (h4 >> 2) as u8;
|
||||
s[14] = (h4 >> 10) as u8;
|
||||
s[15] = (h4 >> 18) as u8;
|
||||
s[16] = (h5 >> 0) as u8;
|
||||
s[17] = (h5 >> 8) as u8;
|
||||
s[18] = (h5 >> 16) as u8;
|
||||
s[19] = ((h5 >> 24) | (((h6 as u32) << 1) as i32)) as u8;
|
||||
s[20] = (h6 >> 7) as u8;
|
||||
s[21] = (h6 >> 15) as u8;
|
||||
s[22] = ((h6 >> 23) | (((h7 as u32) << 3) as i32)) as u8;
|
||||
s[23] = (h7 >> 5) as u8;
|
||||
s[24] = (h7 >> 13) as u8;
|
||||
s[25] = ((h7 >> 21) | (((h8 as u32) << 4) as i32)) as u8;
|
||||
s[26] = (h8 >> 4) as u8;
|
||||
s[27] = (h8 >> 12) as u8;
|
||||
s[28] = ((h8 >> 20) | (((h9 as u32) << 6) as i32)) as u8;
|
||||
s[29] = (h9 >> 2) as u8;
|
||||
s[30] = (h9 >> 10) as u8;
|
||||
s[31] = (h9 >> 18) as u8;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[test]
|
||||
fn from_to_bytes() {
|
||||
@@ -204,9 +204,8 @@ fn from_to_bytes() {
|
||||
let mut cursor = Cursor::new(bbytes);
|
||||
cursor.read_i32_into::<NativeEndian>(&mut target.value).unwrap();
|
||||
assert_eq!(e, target, "from bytes");
|
||||
let mut bytes = [0; 32];
|
||||
fe_tobytes(&mut bytes, &e);
|
||||
assert_eq!(&bytes.to_vec(), abytes, "to bytes");
|
||||
let bytes = e.to_bytes();
|
||||
assert_eq!(&bytes, abytes, "to bytes");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -243,8 +242,7 @@ quickcheck! {
|
||||
// this is somewhat self referential, given the definition of arbitrary,
|
||||
// but more testing is more good
|
||||
fn from_to_bytes_roundtrip(e: ValidFieldElement) -> bool {
|
||||
let mut bytes = [0; 32];
|
||||
fe_tobytes(&mut bytes, &e.values);
|
||||
let bytes = e.values.to_bytes();
|
||||
let trans = FieldElement::from_bytes(&bytes);
|
||||
trans == e.values
|
||||
}
|
||||
@@ -822,9 +820,8 @@ fn cmov() {
|
||||
|
||||
pub fn fe_isnonzero(f: &FieldElement) -> bool
|
||||
{
|
||||
let mut s = [0; 32];
|
||||
let s = f.to_bytes();
|
||||
let mut res = false;
|
||||
fe_tobytes(&mut s, &f);
|
||||
for i in 0..32 {
|
||||
res |= s[i] != 0;
|
||||
}
|
||||
@@ -833,8 +830,7 @@ pub fn fe_isnonzero(f: &FieldElement) -> bool
|
||||
|
||||
pub fn fe_isnegative(f: &FieldElement) -> bool
|
||||
{
|
||||
let mut s = [0; 32];
|
||||
fe_tobytes(&mut s, &f);
|
||||
let s = f.to_bytes();
|
||||
s[0] & 1 == 1
|
||||
}
|
||||
|
||||
|
||||
@@ -75,13 +75,12 @@ impl ED25519Private {
|
||||
curve25519_scalar_mask(&mut result.private);
|
||||
let mut a = Point::new();
|
||||
x25519_ge_scalarmult_base(&mut a, &result.private);
|
||||
a.encode_to(&mut result.public);
|
||||
result.public.copy_from_slice(&a.encode());
|
||||
result
|
||||
}
|
||||
|
||||
pub fn sign(&self, msg: &[u8]) -> Vec<u8>
|
||||
{
|
||||
let mut signature_r = [0u8; 32];
|
||||
let mut signature_s = [0u8; 32];
|
||||
|
||||
let mut ctx = Sha512::new();
|
||||
@@ -95,7 +94,7 @@ impl ED25519Private {
|
||||
println!("ME:r.y: {:?}", r.y);
|
||||
println!("ME:r.z: {:?}", r.z);
|
||||
println!("ME:r.t: {:?}", r.t);
|
||||
r.encode_to(&mut signature_r);
|
||||
let signature_r = r.encode();
|
||||
println!("ME:signature_r: {:?}", signature_r);
|
||||
let hram_digest = eddsa_digest(&signature_r, &self.public, &msg);
|
||||
let hram = digest_scalar(&hram_digest);
|
||||
@@ -139,9 +138,8 @@ impl ED25519Public {
|
||||
let h = digest_scalar(&h_digest);
|
||||
let mut r = Point2::new();
|
||||
ge_double_scalarmult_vartime(&mut r, &h, &a, &signature_s);
|
||||
let mut r_check = [0; 32];
|
||||
r.encode_to(&mut r_check);
|
||||
signature_r == r_check
|
||||
let r_check = r.encode();
|
||||
signature_r.to_vec() == r_check
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,9 +95,9 @@ impl Point {
|
||||
return Some(Point{ x: hx, y: hy, z: hz, t: ht });
|
||||
}
|
||||
|
||||
pub fn encode_to(&self, target: &mut [u8])
|
||||
pub fn encode(&self) -> Vec<u8>
|
||||
{
|
||||
into_encoded_point(target, &self.x, &self.y, &self.z);
|
||||
into_encoded_point(&self.x, &self.y, &self.z)
|
||||
}
|
||||
|
||||
pub fn invert(&mut self)
|
||||
@@ -173,9 +173,9 @@ impl Point2 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn encode_to(&self, target: &mut [u8])
|
||||
pub fn encode(&self) -> Vec<u8>
|
||||
{
|
||||
into_encoded_point(target, &self.x, &self.y, &self.z);
|
||||
into_encoded_point(&self.x, &self.y, &self.z)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1840,19 +1840,18 @@ pub fn curve25519_scalar_mask(a: &mut [u8])
|
||||
// });
|
||||
//}
|
||||
//
|
||||
fn into_encoded_point(bytes: &mut [u8], x: &FieldElement, y: &FieldElement, z: &FieldElement)
|
||||
fn into_encoded_point(x: &FieldElement, y: &FieldElement, z: &FieldElement) -> Vec<u8>
|
||||
{
|
||||
let mut x_over_z = FieldElement::new();
|
||||
let mut y_over_z = FieldElement::new();
|
||||
assert!(bytes.len() >= 32);
|
||||
|
||||
let recip = fe_invert(z);
|
||||
fe_mul(&mut x_over_z, x, &recip);
|
||||
fe_mul(&mut y_over_z, y, &recip);
|
||||
fe_tobytes(bytes, &y_over_z);
|
||||
let mut bytes = y_over_z.to_bytes();
|
||||
let sign_bit = if fe_isnegative(&x_over_z) { 1 } else { 0 };
|
||||
|
||||
// The preceding computations must execute in constant time, but this
|
||||
// doesn't need to.
|
||||
bytes[31] ^= sign_bit << 7;
|
||||
bytes
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user