From 62640ba448dbef14b9cc6ff1fbef926a41566e78 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Tue, 10 May 2022 12:15:35 +0900 Subject: [PATCH] implement add function --- src/common/finite_field.rs | 19 +++++--- src/common/math.rs | 27 ++++++++---- src/elliptic_curve/elliptic_curve.rs | 65 ++++++++-------------------- src/main.rs | 9 +++- 4 files changed, 57 insertions(+), 63 deletions(-) diff --git a/src/common/finite_field.rs b/src/common/finite_field.rs index 640563f..d134b78 100644 --- a/src/common/finite_field.rs +++ b/src/common/finite_field.rs @@ -1,8 +1,8 @@ -use std::{ops::{Add, Sub, Mul, Div, Neg}, fmt::{self, Display}}; +use std::{ops::{Add, Sub, Mul, Neg}, fmt::{self, Display}}; use bigdecimal::{BigDecimal, Zero}; -use super::math::{self, modInv, plusMod}; +use super::math::{self, mod_inv, plus_mod}; #[macro_export] macro_rules! b { @@ -45,16 +45,15 @@ impl FiniteFieldElement { } pub fn floor_div(self, rhs: FiniteFieldElement) -> Self { - self * FiniteFieldElement { value: modInv(rhs.value, self.p.clone()), p: self.p } + self.clone() * FiniteFieldElement { value: mod_inv(rhs.value, self.p.clone()), p: self.p } } pub fn rem(self, rhs: FiniteFieldElement) -> FiniteFieldElement { - FiniteFieldElement { value: plusMod(self.value, rhs.value), p: self.p } + FiniteFieldElement { value: plus_mod(self.value, rhs.value), p: self.p } } pub fn pow(self, rhs: FiniteFieldElement) -> FiniteFieldElement { - - FiniteFieldElement { value: plusMod(self.value.), p: () } + FiniteFieldElement { value: plus_mod(math::pow(self.value, rhs.value), self.p.clone()), p: self.p } } } @@ -128,4 +127,12 @@ mod tests { let b = ffe!(3, 5); assert_eq!(a * b, ffe!(1, 5)); } + + #[test] + fn pow() { + let a = ffe!(3, 50); + let b = ffe!(4, 50); + println!("{:?}", math::pow(a.clone().value, b.clone().value)); + assert_eq!(a.pow(b), ffe!(31, 50)); + } } diff --git a/src/common/math.rs b/src/common/math.rs index e17b16b..8ba0b48 100644 --- a/src/common/math.rs +++ b/src/common/math.rs @@ -1,8 +1,6 @@ -use std::ops::Div; - use bigdecimal::{BigDecimal, FromPrimitive, Zero, One}; -fn extGCD(a: BigDecimal, b: BigDecimal) -> (BigDecimal, BigDecimal, BigDecimal) { +pub fn ext_gcd(a: BigDecimal, b: BigDecimal) -> (BigDecimal, BigDecimal, BigDecimal) { let mut a = a; let mut b = b; let mut x0 = BigDecimal::from_i32(1).unwrap(); @@ -13,7 +11,8 @@ fn extGCD(a: BigDecimal, b: BigDecimal) -> (BigDecimal, BigDecimal, BigDecimal) while b != BigDecimal::zero() { let q = down(a.clone() / b.clone()); let at = a.clone(); - a = plusMod(at, b.clone()); + a = b.clone(); + b = plus_mod(at, b.clone()); let x0t = x0.clone(); x0 = x1.clone(); @@ -26,20 +25,30 @@ fn extGCD(a: BigDecimal, b: BigDecimal) -> (BigDecimal, BigDecimal, BigDecimal) return (a, x0, y0); } -pub fn plusMod(a: BigDecimal, b: BigDecimal) -> BigDecimal { +pub fn plus_mod(a: BigDecimal, b: BigDecimal) -> BigDecimal { a.clone() - floor(a / b.clone()) * b } -pub fn modInv(a: BigDecimal, m: BigDecimal) -> BigDecimal { - let r = extGCD(a, m); +pub fn mod_inv(a: BigDecimal, m: BigDecimal) -> BigDecimal { + let r = ext_gcd(a, m.clone()); if r.0 != BigDecimal::one() { panic!("Moduler inverse does not exist."); } else { - - return plusMod(r.1, m); + return plus_mod(r.1, m); } } +pub fn pow(a: BigDecimal, b: BigDecimal) -> BigDecimal { + let mut i = BigDecimal::one(); + let mut a = a; + let oa = a.clone(); + while i < b { + a = a.clone() * oa.clone(); + i += BigDecimal::one(); + } + a +} + pub fn down(a: BigDecimal) -> BigDecimal { return a.clone() - a % BigDecimal::one(); } diff --git a/src/elliptic_curve/elliptic_curve.rs b/src/elliptic_curve/elliptic_curve.rs index 1d2824c..9f32933 100644 --- a/src/elliptic_curve/elliptic_curve.rs +++ b/src/elliptic_curve/elliptic_curve.rs @@ -17,7 +17,11 @@ pub struct EllipticCurvePoint { impl EllipticCurve { pub fn add(self, lhs: EllipticCurvePoint, rhs: EllipticCurvePoint) -> EllipticCurvePoint { - if lhs.clone().x == rhs.x && rhs.y == -lhs.clone().y { + let (x1, y1) = (rhs.x.clone(), rhs.y.clone()); + let (x2, y2) = (lhs.x.clone(), lhs.y.clone()); + let p = x1.p.clone(); + + if x1.clone() == x2.clone() && y2.clone() == -y1.clone() { return EllipticCurvePoint { x: ffe!(0, 1), y: ffe!(0, 1), @@ -33,58 +37,25 @@ impl EllipticCurve { return lhs } - let (psi, phi) = if lhs == rhs { - let phi = Self::twice_phi(lhs.clone(), self.clone()); - let psi = Self::twice_psi(lhs.clone(), self); - - (phi, psi) + let l = if x1.clone() == x2.clone() && y1.clone() == y2.clone() { + ( + x1.clone().pow(ffeb!(b!(2), p.clone())) + * ffeb!(b!(3), p.clone()) + + ffeb!(self.a, p.clone()) + ).floor_div( + y1.clone() * ffeb!(b!(2), p.clone()) + ) } else { - let phi = Self::add_phi(lhs.clone(), rhs.clone()); - let psi = Self::add_psi(lhs.clone(), rhs.clone()); - - (phi, psi) + (y2 - y1.clone()).floor_div(x2.clone() - x1.clone()) }; - println!("{}, {}", phi, psi); - - let x = phi.clone() * phi.clone() - lhs.x.clone() - rhs.x.clone(); - let y = - phi * x.clone() - psi; + let x3 = l.clone().pow(ffeb!(b!(2), p.clone())) - x1.clone() - x2.clone(); + let y3 = l * (x1 - x3.clone()) - y1; EllipticCurvePoint { - x, - y, + x: x3, + y: y3, infinity: false } } - - fn add_phi(a: EllipticCurvePoint, b: EllipticCurvePoint) -> FiniteFieldElement { - (a.y - b.y) / (a.x - b.x) - } - - fn add_psi(a: EllipticCurvePoint, b: EllipticCurvePoint) -> FiniteFieldElement { - (a.x.clone() * b.y - b.x.clone() * a.y) / (a.x - b.x) - } - - fn twice_phi(a: EllipticCurvePoint, c: EllipticCurve) -> FiniteFieldElement { - let x = a.x.clone(); - let y = a.y.clone(); - let p = a.x.p.clone(); - ( - ffeb!(b!(3), p.clone()) * x.clone() * x - + ffeb!(c.a, p.clone()) - ) / ( - ffeb!(b!(2), p) * y - ) - } - - fn twice_psi(a: EllipticCurvePoint, c: EllipticCurve) -> FiniteFieldElement { - let p = a.x.p.clone(); - ( - ffeb!(b!(3), p.clone()) * a.x.clone() * a.x.clone() - + ffeb!(c.a, p.clone()) * a.x.clone() - - ffeb!(b!(2), p.clone()) * a.y.clone() * a.y.clone() - ) / ( - ffeb!(b!(2), p) * a.y - ) - } } diff --git a/src/main.rs b/src/main.rs index 24c0e50..f2be8dc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,8 +16,14 @@ fn main() { infinity: false }; - println!("{:?}", ec.add(ecp1.clone(), ecp1)); + let ecp2 = EllipticCurvePoint { + x: ffe!(4, 5), + y: ffe!(2, 5), + infinity: false + }; + println!("{:?}", ec.add(ecp1.clone(), ecp2)); +/* for x in 1..101 { for y in 1..101 { println!("{}, {}: {}", x, y, encrypt::common::math::plusMod(BigDecimal::from_i32(x).unwrap(), BigDecimal::from_i32(y).unwrap())); @@ -25,4 +31,5 @@ fn main() { } println!("{}", encrypt::common::math::plusMod(BigDecimal::from_i32(100).unwrap(), BigDecimal::from_i32(50).unwrap())); +*/ }