mirror of
https://github.com/mii443/encrypt.git
synced 2025-08-22 15:05:33 +00:00
com
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
use std::{ops::{Add, Sub, Mul}, fmt::{self, Display}};
|
use std::{ops::{Add, Sub, Mul, Div, Neg}, fmt::{self, Display}};
|
||||||
|
|
||||||
use bigdecimal::{BigDecimal, Zero};
|
use bigdecimal::{BigDecimal, Zero};
|
||||||
|
|
||||||
@ -16,10 +16,17 @@ macro_rules! ffe {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! ffeb {
|
||||||
|
( $value: expr, $p: expr ) => {
|
||||||
|
FiniteFieldElement::new($value, $p)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct FiniteFieldElement {
|
pub struct FiniteFieldElement {
|
||||||
pub value: BigDecimal,
|
pub value: BigDecimal,
|
||||||
p: BigDecimal
|
pub p: BigDecimal
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pmod(x: BigDecimal, y: BigDecimal) -> BigDecimal {
|
fn pmod(x: BigDecimal, y: BigDecimal) -> BigDecimal {
|
||||||
@ -73,6 +80,22 @@ impl Mul for FiniteFieldElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Div for FiniteFieldElement {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn div(self, rhs: Self) -> Self::Output {
|
||||||
|
Self::new(self.value / rhs.value, self.p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Neg for FiniteFieldElement {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn neg(self) -> Self::Output {
|
||||||
|
Self::new(-self.value, self.p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -1,23 +1,85 @@
|
|||||||
use bigdecimal::BigDecimal;
|
use bigdecimal::{BigDecimal, FromPrimitive};
|
||||||
use crate::common::finite_field::*;
|
use crate::{common::finite_field::*, b, ffeb, ffe};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct EllipticCurve {
|
pub struct EllipticCurve {
|
||||||
pub a: BigDecimal,
|
pub a: BigDecimal,
|
||||||
pub b: BigDecimal,
|
pub b: BigDecimal,
|
||||||
pub p: BigDecimal
|
pub p: BigDecimal
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct EllipticCurvePoint {
|
pub struct EllipticCurvePoint {
|
||||||
pub x: FiniteFieldElement,
|
pub x: FiniteFieldElement,
|
||||||
pub y: FiniteFieldElement
|
pub y: FiniteFieldElement,
|
||||||
|
pub infinity: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EllipticCurve {
|
impl EllipticCurve {
|
||||||
pub fn add(lhs: EllipticCurvePoint, rhs: EllipticCurvePoint) -> EllipticCurvePoint {
|
pub fn add(self, lhs: EllipticCurvePoint, rhs: EllipticCurvePoint) -> EllipticCurvePoint {
|
||||||
lhs
|
if lhs.clone().x == rhs.x && rhs.y == -lhs.clone().y {
|
||||||
|
return EllipticCurvePoint {
|
||||||
|
x: ffe!(0, 1),
|
||||||
|
y: ffe!(0, 1),
|
||||||
|
infinity: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if lhs.infinity {
|
||||||
|
return rhs
|
||||||
|
}
|
||||||
|
|
||||||
|
if rhs.infinity {
|
||||||
|
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)
|
||||||
|
} else {
|
||||||
|
let phi = Self::add_phi(lhs.clone(), rhs.clone());
|
||||||
|
let psi = Self::add_psi(lhs.clone(), rhs.clone());
|
||||||
|
|
||||||
|
(phi, psi)
|
||||||
|
};
|
||||||
|
|
||||||
|
EllipticCurvePoint {
|
||||||
|
x: phi.clone() * phi - lhs.x.clone() - rhs.x.clone(),
|
||||||
|
y: todo!(),
|
||||||
|
infinity: todo!(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_phi(a: EllipticCurvePoint, b: EllipticCurvePoint) -> FiniteFieldElement {
|
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
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user