ペアリング実装

This commit is contained in:
mii8080
2022-06-28 12:07:38 +00:00
committed by GitHub
parent c6bf1dac99
commit 519696e135
3 changed files with 144 additions and 76 deletions

View File

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

View File

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

View File

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