From e1c0dca87d4c06bec8f680c1c76cf4ab763e6cd7 Mon Sep 17 00:00:00 2001 From: mii8080 <39086319+morioka22@users.noreply.github.com> Date: Fri, 27 May 2022 08:01:34 +0000 Subject: [PATCH] fix pow --- src/common/finite_field.rs | 137 +++++++++++++++---------------------- src/main.rs | 17 +++-- 2 files changed, 65 insertions(+), 89 deletions(-) diff --git a/src/common/finite_field.rs b/src/common/finite_field.rs index f445bf5..39a5ed5 100644 --- a/src/common/finite_field.rs +++ b/src/common/finite_field.rs @@ -1,48 +1,40 @@ use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Rem}, fmt::Debug}; +use primitive_types::U512; + #[derive(PartialEq, Debug, Copy, Clone)] -pub struct FiniteFieldElement -where - T: PartialEq + Copy -{ - pub value: T, - pub p: T, - pub one: T +pub struct FiniteFieldElement { + pub value: U512, + pub p: U512 } -impl FiniteFieldElement -where - T: PartialEq + Copy -{ - pub fn new(value: T, p: T, one: T) -> Self { - Self { value, p, one } +impl FiniteFieldElement { + pub fn new(value: U512, p: U512) -> Self { + Self { value, p } } } -impl FiniteFieldElement -where - T: Rem + Add + Sub + Div + PartialEq + PartialOrd + Copy + Debug -{ - fn pow(self, e: T) -> Self { - let one = self.one; - let two = one + one; - let mut r = Self::new(one, self.p, self.one); - let mut i = e; - let zero = self.value - self.value; - while i > zero { - if i % two != zero { - r = r * self; +impl FiniteFieldElement { + fn pow(self, e: U512) -> Self { + let k = e.bits(); + let mut a1 = self.value; + let mut a2 = self.value * self.value; + let mut i = (k - 2) as i64; + + while i >= 0 { + if e.bit(i as usize) { + a1 = (a1 * a2) % self.p; + } else { + a2 = (a1 * a2) % self.p; + a1 = (a1 * a1) % self.p; } - i = i / two; + i -= 1; } - r * self + Self::new(a1, self.p) } } -impl Add for FiniteFieldElement -where - T: Add + Sub + PartialEq + PartialOrd + Copy -{ +impl Add for FiniteFieldElement { type Output = Self; fn add(self, rhs: Self) -> Self::Output { @@ -51,26 +43,20 @@ where } let sum = self.value + rhs.value; if sum >= self.p { - Self::new(sum - self.p, self.p, self.one) + Self::new(sum - self.p, self.p) } else { - Self::new(sum, self.p, self.one) + Self::new(sum, self.p) } } } -impl AddAssign for FiniteFieldElement -where - T: Add + Sub + PartialEq + PartialOrd + Copy -{ +impl AddAssign for FiniteFieldElement { fn add_assign(&mut self, rhs: Self) { *self = (*self) + rhs } } -impl Sub for FiniteFieldElement -where - T: Add + Sub + PartialEq + PartialOrd + Copy -{ +impl Sub for FiniteFieldElement { type Output = Self; fn sub(self, rhs: Self) -> Self::Output { @@ -78,58 +64,47 @@ where panic!("Cannot sub different field value."); } if self.value < rhs.value { - Self::new(self.p - rhs.value + self.value , self.p, self.one) + Self::new(self.p - rhs.value + self.value , self.p) } else { - Self::new(self.value - rhs.value, self.p, self.one) + Self::new(self.value - rhs.value, self.p) } } } -impl SubAssign for FiniteFieldElement -where - T: Add + Sub + PartialEq + PartialOrd + Copy -{ +impl SubAssign for FiniteFieldElement { fn sub_assign(&mut self, rhs: Self) { *self = (*self) - rhs } } -impl Mul for FiniteFieldElement -where - T: Add + Sub + Div + Rem + PartialEq + PartialOrd + Copy + Debug -{ +impl Mul for FiniteFieldElement { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { if self.p != rhs.p { panic!("Cannot mul different field value."); } - let one = self.one; - let two = one + one; - let zero = self.value - self.value; let mut tmp = self; let mut i = rhs.value; - let mut r = Self::new(zero, self.p, self.one); - while i > zero { - if i % two != zero { + let mut r = Self::new(U512::from(0), self.p); + while i > U512::from(0) { + if i & U512::from(1) == U512::from(1) { r += tmp; } - i = i / two; + i = i >> 1; tmp = tmp + tmp; } r } } -impl Div for FiniteFieldElement -where - T: Add + Sub + Rem + Div + PartialEq + PartialOrd + Copy + Debug -{ +impl Div for FiniteFieldElement { type Output = Self; fn div(self, rhs: Self) -> Self::Output { - let one = self.one; - self * rhs.pow(self.p - one - one) + let rhs = rhs.pow(self.p - U512::from(2)); + println!("{:?} * {:?}", self, rhs); + self * rhs } } @@ -141,40 +116,42 @@ mod tests { #[test] fn add() { - let a = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1)); - let b = FiniteFieldElement::new(U512::from(1), U512::from(7), U512::from(1)); - let c = FiniteFieldElement::new(U512::from(3), U512::from(7), U512::from(1)); + let a = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8)); + let b = FiniteFieldElement::new(U512::from(1u8), U512::from(7u8)); + let c = FiniteFieldElement::new(U512::from(3u8), U512::from(7u8)); assert_eq!(a + b, c); } #[test] fn sub() { - let a = FiniteFieldElement::new(U512::from(6), U512::from(7), U512::from(1)); - let b = FiniteFieldElement::new(U512::from(4), U512::from(7), U512::from(1)); - let c = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1)); + let a = FiniteFieldElement::new(U512::from(6u8), U512::from(7u8)); + let b = FiniteFieldElement::new(U512::from(4u8), U512::from(7u8)); + let c = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8)); assert_eq!(a - b, c); } #[test] fn mul() { - let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1)); - let b = FiniteFieldElement::new(U512::from(12), U512::from(13), U512::from(1)); - let c = FiniteFieldElement::new(U512::from(10), U512::from(13), U512::from(1)); + let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8)); + let b = FiniteFieldElement::new(U512::from(12u8), U512::from(13u8)); + let c = FiniteFieldElement::new(U512::from(10u8), U512::from(13u8)); assert_eq!(a * b, c); } #[test] fn pow() { - let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1)); - let b = FiniteFieldElement::new(U512::from(1), U512::from(13), U512::from(1)); + let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8)); + let b = FiniteFieldElement::new(U512::from(1u8), U512::from(13u8)); assert_eq!(a.pow(U512::from(3)), b); + + println!("{:?}", FiniteFieldElement::new(U512::from(5u8), U512::from(19u8)).pow(U512::from(17))); } #[test] fn div() { - let a = FiniteFieldElement::new(U512::from(7), U512::from(19), U512::from(1)); - let b = FiniteFieldElement::new(U512::from(5), U512::from(19), U512::from(1)); - let c = FiniteFieldElement::new(U512::from(9), U512::from(19), U512::from(1)); + let a = FiniteFieldElement::new(U512::from(7u8), U512::from(19u8)); + let b = FiniteFieldElement::new(U512::from(5u8), U512::from(19u8)); + let c = FiniteFieldElement::new(U512::from(9u8), U512::from(19u8)); assert_eq!(a / b, c); } -} \ No newline at end of file +} diff --git a/src/main.rs b/src/main.rs index c741c6f..a6bc4a9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use primitive_types::U512; // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 fn main() { println!("Encryption Library"); -/* + let p = U512::from_str_radix("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10).unwrap(); let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p); @@ -12,16 +12,15 @@ fn main() { let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("32670510020758816978083085130507043184471273380659243275938904335757337482424", 10).unwrap(), p); let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10).unwrap(), p); -*/ +/* let p = U512::from_str_radix("5", 10).unwrap(); - let one = U512::from(1u8); - - let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p, one); - let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p, one); - let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p, one); - let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p, one); - let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p, one); + let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p); + let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p); + let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p); + let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p); + let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p); +*/ let ec = EllipticCurve { a: secp256_k1_a, b: secp256_k1_b