implement add function

This commit is contained in:
Masato Imai
2022-05-10 12:15:35 +09:00
parent d82a7778b8
commit 62640ba448
4 changed files with 57 additions and 63 deletions

View File

@ -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));
}
}

View File

@ -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();
}

View File

@ -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
)
}
}

View File

@ -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()));
*/
}