From c6bf1dac99102e8c47cc5ad99c69db63199f94b6 Mon Sep 17 00:00:00 2001 From: mii8080 <39086319+morioka22@users.noreply.github.com> Date: Tue, 14 Jun 2022 01:27:12 +0000 Subject: [PATCH] =?UTF-8?q?Miller=E6=BA=96=E5=82=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/math.rs | 22 ++++++++++- src/elliptic_curve/elliptic_curve.rs | 56 +++++++++++++++++++++------- src/main.rs | 3 +- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/common/math.rs b/src/common/math.rs index a1c7054..5a36acc 100644 --- a/src/common/math.rs +++ b/src/common/math.rs @@ -44,7 +44,6 @@ pub fn random_n_q(p: BigInt) -> BigInt { let mut i = BigInt::one(); let k = (p.clone() - BigInt::one()) >> 1i32; while i < p { - println!("pm {:?}", FiniteFieldElement::new(bigint_to_u512(i.clone()), bigint_to_u512(p.clone())).pow(bigint_to_u512(k.clone())).value); if bigint_to_u512(pow_mod(i.clone(),k.clone(),p.clone())) != U512::one() { break; } @@ -53,6 +52,27 @@ pub fn random_n_q(p: BigInt) -> BigInt { i } +pub fn mod_sqrt(a: BigInt, p: BigInt) -> BigInt { + if pow_mod(a.clone(), (p.clone() - BigInt::one()) >> 1u8, p.clone()) != BigInt::one() { + return -BigInt::one(); + } + + let r = (p.clone() - BigInt::one()) >> 1u8; + let b = random_n_q(p.clone()); + let mut x = r.clone(); + let mut y = BigInt::zero(); + + while (x.clone() & BigInt::one()) != BigInt::one() { + x = x >> 1u8; + y = y >> 1u8; + if abs(pow_mod(a.clone(), x.clone(), p.clone()) * pow_mod(b.clone(), y.clone(), p.clone()), p.clone()) != BigInt::one() { + y += r.clone(); + } + } + + abs(pow_mod(a.clone(), (x.clone() + BigInt::one()) >> 1u8, p.clone()) * pow_mod(b.clone(), y.clone() >> 1u8, p.clone()), p.clone()) +} + pub fn mod_inv(a: BigInt, m: BigInt) -> BigInt { let mut a = a; if a < BigInt::zero() { diff --git a/src/elliptic_curve/elliptic_curve.rs b/src/elliptic_curve/elliptic_curve.rs index c60d4f6..9da1ff0 100644 --- a/src/elliptic_curve/elliptic_curve.rs +++ b/src/elliptic_curve/elliptic_curve.rs @@ -1,4 +1,4 @@ -use std::{ops::{Add, Mul, Neg}, fmt::Display, sync::mpsc}; +use std::{ops::{Add, Mul, Neg}, fmt::Display}; use primitive_types::U512; @@ -27,9 +27,47 @@ pub enum EllipticCurvePoint { Infinity } +impl EllipticCurvePoint { + pub fn lambda(p: EllipticCurvePoint, q: EllipticCurvePoint) -> FiniteFieldElement { + let (x1, y1) = match p { + EllipticCurvePoint::Point { x, y, .. } => (x,y), + _ => panic!("P is inifinity.") + }; + + let (x2, y2) = match q { + EllipticCurvePoint::Point { x, y, .. } => (x,y), + _ => panic!("Q is inifinity.") + }; + + (y2 - y1) / (x2 - x1) + } + + pub fn l(p: EllipticCurvePoint, q: EllipticCurvePoint, x: FiniteFieldElement, y: FiniteFieldElement) -> FiniteFieldElement { + let (x1, y1) = match p { + EllipticCurvePoint::Point { x, y, .. } => (x,y), + _ => panic!("P is inifinity.") + }; + + y - (Self::lambda(p, q) * (x - x1) + y1) + } + + pub fn v(r: EllipticCurvePoint, x: FiniteFieldElement) -> FiniteFieldElement { + let xr = match r { + EllipticCurvePoint::Point { x, .. } => x, + _ => panic!("R is inifinity.") + }; + + x - xr + } + + pub fn g(p: EllipticCurvePoint, q: EllipticCurvePoint, x: FiniteFieldElement, y: FiniteFieldElement) -> FiniteFieldElement { + Self::l(p, q, x, y) / Self::v(p + q, x) + } +} + impl Display for EllipticCurvePoint { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - if let EllipticCurvePoint::Point { x, y, a, b } = self { + if let EllipticCurvePoint::Point { x, y, .. } = self { write!(f, "({:x}, {:x})", x.value, y.value) } else { write!(f, "Infinity") @@ -79,18 +117,8 @@ impl Add for EllipticCurvePoint { } let l = if x1 == x2 && y1 == y2 { - let (t_tx, t_rx) = mpsc::channel(); - let (u_tx, u_rx) = mpsc::channel(); - std::thread::spawn(move || { - let val = x1 * x1 * FiniteFieldElement::new(U512::from(3u8), p) + a; - t_tx.send(val).unwrap(); - }); - std::thread::spawn(move || { - let val = y1 * FiniteFieldElement::new(U512::from(2), p); - u_tx.send(val).unwrap(); - }); - let t = t_rx.recv().unwrap(); - let u = u_rx.recv().unwrap(); + let t = x1 * x1 * FiniteFieldElement::new(U512::from(3u8), p) + a; + let u = y1 * FiniteFieldElement::new(U512::from(2), p); let a = t / u; a } else { diff --git a/src/main.rs b/src/main.rs index fddf71e..9560be1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,12 @@ use bigdecimal::num_bigint::BigInt; -use encrypt::{elliptic_curve::{elliptic_curve::EllipticCurve, encryption::Encryption}, common::{finite_field::FiniteFieldElement, math::random_n_q}}; +use encrypt::{elliptic_curve::{elliptic_curve::EllipticCurve, encryption::Encryption}, common::{finite_field::FiniteFieldElement, math::{random_n_q, mod_sqrt}}}; use primitive_types::U512; fn main() { println!("Encryption Library"); println!("{}", random_n_q(BigInt::from(23))); + println!("{}", mod_sqrt(BigInt::from(4), BigInt::from(23))); let p = U512::from_str_radix("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10).unwrap();