mirror of
https://github.com/mii443/encrypt.git
synced 2025-12-03 11:08:20 +00:00
ペアリング実装
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Neg}, fmt::Debug};
|
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Neg}, fmt::{Debug, Display}};
|
||||||
|
|
||||||
use bigdecimal::{num_bigint::BigInt, Num};
|
use bigdecimal::{num_bigint::BigInt, Num};
|
||||||
use primitive_types::U512;
|
use primitive_types::U512;
|
||||||
@@ -15,6 +15,12 @@ impl FiniteFieldElement {
|
|||||||
pub fn new(value: U512, p: U512) -> Self {
|
pub fn new(value: U512, p: U512) -> Self {
|
||||||
Self { value, p }
|
Self { value, p }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn inverse(&self) -> Self {
|
||||||
|
let left = BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap();
|
||||||
|
let right = BigInt::from_str_radix(&format!("{}", self.p), 10).unwrap();
|
||||||
|
Self::new(U512::from_str_radix(&format!("{}", mod_inv(left, right)), 10).unwrap(), self.p)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FiniteFieldElement {
|
impl FiniteFieldElement {
|
||||||
@@ -37,6 +43,12 @@ impl FiniteFieldElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for FiniteFieldElement {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Add for FiniteFieldElement {
|
impl Add for FiniteFieldElement {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,41 @@ pub enum EllipticCurvePoint {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl EllipticCurvePoint {
|
impl EllipticCurvePoint {
|
||||||
|
|
||||||
|
pub fn exp(&self, k: U512) -> Self {
|
||||||
|
if k == U512::zero() {
|
||||||
|
return Self::Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut g = self.clone();
|
||||||
|
let s = k.bits();
|
||||||
|
let mut i = 1usize;
|
||||||
|
while i < s {
|
||||||
|
println!("{}, {}", i, k.bit(i));
|
||||||
|
g = g + g;
|
||||||
|
if k.bit(i) {
|
||||||
|
g = g + (*self);
|
||||||
|
}
|
||||||
|
println!("{}", g);
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
g
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_inf(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
EllipticCurvePoint::Point { .. } => false,
|
||||||
|
EllipticCurvePoint::Infinity => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn extract(&self) -> (FiniteFieldElement, FiniteFieldElement, FiniteFieldElement, FiniteFieldElement) {
|
||||||
|
match self {
|
||||||
|
EllipticCurvePoint::Point { x, y, a, b } => (*x,*y,*a,*b),
|
||||||
|
_ => panic!("inifinity")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lambda(p: EllipticCurvePoint, q: EllipticCurvePoint) -> FiniteFieldElement {
|
pub fn lambda(p: EllipticCurvePoint, q: EllipticCurvePoint) -> FiniteFieldElement {
|
||||||
let (x1, y1) = match p {
|
let (x1, y1) = match p {
|
||||||
EllipticCurvePoint::Point { x, y, .. } => (x,y),
|
EllipticCurvePoint::Point { x, y, .. } => (x,y),
|
||||||
@@ -42,33 +77,89 @@ impl EllipticCurvePoint {
|
|||||||
(y2 - y1) / (x2 - x1)
|
(y2 - y1) / (x2 - x1)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn l(p: EllipticCurvePoint, q: EllipticCurvePoint, x: FiniteFieldElement, y: FiniteFieldElement) -> FiniteFieldElement {
|
pub fn l(g: EllipticCurvePoint, h: EllipticCurvePoint, var: EllipticCurvePoint) -> FiniteFieldElement {
|
||||||
let (x1, y1) = match p {
|
//println!("L g: {}, h: {}, var: {}", g, h, var);
|
||||||
EllipticCurvePoint::Point { x, y, .. } => (x,y),
|
let (gx, gy, a, _) = g.extract();
|
||||||
_ => panic!("P is inifinity.")
|
let (hx, hy, _, _) = h.extract();
|
||||||
};
|
let (varx, vary, _, _) = var.extract();
|
||||||
|
|
||||||
y - (Self::lambda(p, q) * (x - x1) + y1)
|
let v = if g == h {
|
||||||
|
(FiniteFieldElement::new(U512::from(3u8), gx.p) * gx * gx + a) * (FiniteFieldElement::new(U512::from(2u8), gx.p) * gy).inverse()
|
||||||
|
} else {
|
||||||
|
(hy - gy) * (hx - gx).inverse()
|
||||||
|
};
|
||||||
|
//println!("result: {}", vary - (v * (varx - gx) + gy));
|
||||||
|
vary - (v * (varx - gx) + gy)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn v(r: EllipticCurvePoint, x: FiniteFieldElement) -> FiniteFieldElement {
|
pub fn v(r: EllipticCurvePoint, v: EllipticCurvePoint) -> FiniteFieldElement {
|
||||||
let xr = match r {
|
let (rx, _, _, _) = r.extract();
|
||||||
EllipticCurvePoint::Point { x, .. } => x,
|
let (vx, _, _, _) = v.extract();
|
||||||
_ => panic!("R is inifinity.")
|
|
||||||
};
|
|
||||||
|
|
||||||
x - xr
|
//println!("V g: {}, var: {}, result: {}", r, v, vx - rx);
|
||||||
|
vx - rx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn g(p: EllipticCurvePoint, q: EllipticCurvePoint, x: FiniteFieldElement, y: FiniteFieldElement) -> FiniteFieldElement {
|
pub fn g(p: EllipticCurvePoint, q: EllipticCurvePoint, v: EllipticCurvePoint) -> FiniteFieldElement {
|
||||||
Self::l(p, q, x, y) / Self::v(p + q, x)
|
let (px, py, _, _) = p.extract();
|
||||||
|
let (qx, qy, _, _) = q.extract();
|
||||||
|
let (vx, vy, _, _) = v.extract();
|
||||||
|
if px == qx && py == -qy {
|
||||||
|
vx - px
|
||||||
|
} else if p == q {
|
||||||
|
let vinv = Self::v(p + p, v).inverse();
|
||||||
|
Self::l(p, p, v) * vinv
|
||||||
|
} else {
|
||||||
|
let vinv = Self::v(p + q, v).inverse();
|
||||||
|
Self::l(p, q, v) * vinv
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn miller(p: EllipticCurvePoint, q: EllipticCurvePoint, m: U512) -> FiniteFieldElement {
|
||||||
|
//println!("Miller Start: {}, {}, {}", p, q, m);
|
||||||
|
let (px, _, _, _) = p.extract();
|
||||||
|
let prime = px.p;
|
||||||
|
|
||||||
|
let mut f = FiniteFieldElement::new(U512::from(1u8), prime);
|
||||||
|
let mut t = p.clone();
|
||||||
|
|
||||||
|
let mut s = m.bits();
|
||||||
|
let mut i = 1usize;
|
||||||
|
//println!("1 to {}", s);
|
||||||
|
while i < s {
|
||||||
|
//println!("ARR: {}", m.bit(i));
|
||||||
|
//println!("I: {}", i);
|
||||||
|
let gf = Self::g(t,t,q);
|
||||||
|
f = f * f * gf;
|
||||||
|
//println!("Miller g: {}", gf);
|
||||||
|
t = t + t;
|
||||||
|
if m.bit(i) {
|
||||||
|
f = f * Self::g(t, p,q);
|
||||||
|
t = t + p;
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
f
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn weil(p: EllipticCurvePoint, q: EllipticCurvePoint, m: U512) -> FiniteFieldElement {
|
||||||
|
let (px, _, _, _) = p.extract();
|
||||||
|
if p == q {
|
||||||
|
FiniteFieldElement::new(U512::one(), px.p)
|
||||||
|
} else if p.is_inf() || q.is_inf() {
|
||||||
|
FiniteFieldElement::new(U512::one(), px.p)
|
||||||
|
} else {
|
||||||
|
let minv = Self::miller(q, p, m).inverse();
|
||||||
|
-Self::miller(p, q, m) * minv
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for EllipticCurvePoint {
|
impl Display for EllipticCurvePoint {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
if let EllipticCurvePoint::Point { x, y, .. } = self {
|
if let EllipticCurvePoint::Point { x, y, .. } = self {
|
||||||
write!(f, "({:x}, {:x})", x.value, y.value)
|
write!(f, "({}, {})", x.value, y.value)
|
||||||
} else {
|
} else {
|
||||||
write!(f, "Infinity")
|
write!(f, "Infinity")
|
||||||
}
|
}
|
||||||
|
|||||||
81
src/main.rs
81
src/main.rs
@@ -1,70 +1,35 @@
|
|||||||
use bigdecimal::num_bigint::BigInt;
|
|
||||||
use encrypt::{elliptic_curve::{elliptic_curve::EllipticCurve, encryption::Encryption}, common::{finite_field::FiniteFieldElement, math::{random_n_q, mod_sqrt}}};
|
use encrypt::{elliptic_curve::elliptic_curve::EllipticCurvePoint, common::finite_field::FiniteFieldElement};
|
||||||
use primitive_types::U512;
|
use primitive_types::U512;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Encryption Library");
|
let p = U512::from_str_radix("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", 16).unwrap();
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p);
|
let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p);
|
||||||
let secp256_k1_b = FiniteFieldElement::new(U512::from(7u8), p);
|
let secp256_k1_b = FiniteFieldElement::new(U512::from(3u8), p);
|
||||||
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("55066263022277343669578718895168534326250603453777594175500187360389116729240", 10).unwrap(), p);
|
|
||||||
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 g = {
|
||||||
let p = U512::from_str_radix("5", 10).unwrap();
|
let x = FiniteFieldElement::new(U512::from_str_radix("DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D", 16).unwrap(), p);
|
||||||
|
let y = FiniteFieldElement::new(U512::from_str_radix("9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D", 16).unwrap(), p);
|
||||||
let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p);
|
EllipticCurvePoint::Point { x, y, a: secp256_k1_a, b: secp256_k1_b }
|
||||||
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::nimage.pngew(U512::from_str_radix("2", 10).unwrap(), p);
|
|
||||||
*/
|
|
||||||
let ec = EllipticCurve {
|
|
||||||
a: secp256_k1_a,
|
|
||||||
b: secp256_k1_b
|
|
||||||
};
|
};
|
||||||
|
let p = g * U512::from_str_radix("2343432432243", 10).unwrap();
|
||||||
|
let q = g * U512::from_str_radix("4233434343432443243", 10).unwrap();
|
||||||
|
let r = U512::from_str_radix("FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D", 16).unwrap();
|
||||||
|
|
||||||
let encryption = Encryption {
|
let f = EllipticCurvePoint::weil(p, q, r);
|
||||||
ellictic_curve: ec,
|
let f1 = EllipticCurvePoint::weil(p.exp(U512::from(2u8)), q.exp(U512::from(1u8)), r);
|
||||||
base_point: ec.point(
|
|
||||||
secp256_k1_base_x,
|
|
||||||
secp256_k1_base_y,
|
|
||||||
),
|
|
||||||
order: secp256_k1_order,
|
|
||||||
plain_mapping: vec![]
|
|
||||||
};
|
|
||||||
|
|
||||||
let private_key = Encryption::get_private_key();
|
println!("{}", search(f, f1));
|
||||||
println!("private_key: {:x}", private_key);
|
|
||||||
let public_key = encryption.get_public_key(private_key);
|
|
||||||
println!("public_key: {}", public_key);
|
|
||||||
|
|
||||||
for x in 0..10 {
|
|
||||||
let ten = encryption.plain_to_ec_point(U512::from(10u32));
|
|
||||||
let e_ten = encryption.encrypt(ten, public_key, None);
|
|
||||||
println!("10 -> {}", e_ten.data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let two = encryption.plain_to_ec_point(U512::from(2u32));
|
pub fn search(base: FiniteFieldElement, target: FiniteFieldElement) -> U512 {
|
||||||
let e_two = encryption.encrypt(two, public_key, None);
|
let mut i = U512::one();
|
||||||
println!("2 -> {}", e_two.data);
|
let mut b = base;
|
||||||
/*
|
println!("{}, {}", base, target);
|
||||||
println!("10 + 2 -> {}", (e_ten + e_two).data);
|
while b != target {
|
||||||
println!("decrypt: {:?}", encryption.ec_point_to_plain(Encryption::decrypt(e_ten + e_two, private_key)));
|
b = b * base;
|
||||||
*/
|
i += U512::one();
|
||||||
/*
|
}
|
||||||
let twenty = encryption.plain_to_ec_point(U512::from(12u8));
|
i
|
||||||
let ten = encryption.plain_to_ec_point(U512::from(10u8));
|
|
||||||
let two = encryption.plain_to_ec_point(U512::from(2u8));
|
|
||||||
println!("{:?}", twenty);
|
|
||||||
println!("{:?}", encryption.ec_point_to_plain(twenty));
|
|
||||||
println!("{:?}", ten + two);
|
|
||||||
println!("{:?}", encryption.ec_point_to_plain(ten + two));
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user