Never mind. Just implemented it in rust-lang.
And this is my code. Just simply implemented. Need further work & don't take it seriously
use curv::arithmetic::Converter;
use curv::elliptic::curves::{ Point, Scalar, Secp256k1};
use curv::BigInt;
use openssl::hash::{Hasher, MessageDigest};
fn main() {
let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap();
// Attacker's private key
let v = Scalar::<Secp256k1>::random();
// Attacker's public key
let V = Point::generator() * v.clone();
// User's private key
let D = Scalar::<Secp256k1>::random();
println!("{:?}", D.to_bigint());
// User's public key
let Q = Point::generator() * D.clone();
let message1 = String::from("First message to sign");
let message2 = String::from("Second message to sign");
hasher.update(message1.as_bytes()).expect("Hash error");
let m1: Scalar<Secp256k1> =
Scalar::from_bigint(&(BigInt::from_bytes(hasher.finish().unwrap().as_ref())));
let k1 = Scalar::<Secp256k1>::random();
let signaturePoint1 = Point::generator() * k1.clone();
let r1 = Scalar::from_bigint(&(signaturePoint1.x_coord().unwrap()));
let s1 = k1.clone().invert().unwrap() * (m1.clone() + D.clone() * r1.clone());
println!("r1: {:?}", r1.to_bigint());
println!("s1: {:?}", s1.to_bigint());
hasher.update(message2.as_bytes()).expect("Hash error");
let m2: Scalar<Secp256k1> =
Scalar::from_bigint(&(BigInt::from_bytes(hasher.finish().unwrap().as_ref())));
let a: Scalar<Secp256k1> = Scalar::random();
let b: Scalar<Secp256k1> = Scalar::random();
let h: Scalar<Secp256k1> = Scalar::random();
let e: Scalar<Secp256k1> = Scalar::random();
let u: Scalar<Secp256k1> = Scalar::from(0 as u16);
let j: Scalar<Secp256k1> = Scalar::from(0 as u16);
let Z = a.clone() * k1.clone() * Point::generator()
+ b.clone() * k1.clone() * V.clone()
+ j.clone() * h.clone() * Point::generator()
+ u.clone() * e.clone() * V.clone();
let zX = Z.x_coord().unwrap();
hasher.update(&zX.to_bytes()).expect("Hash error");
let hash =
Scalar::<Secp256k1>::from_bigint(&(BigInt::from_bytes(hasher.finish().unwrap().as_ref())));
let k2 = hash;
let signaturePoint2 = k2.clone() * Point::generator();
let r2 = Scalar::<Secp256k1>::from_bigint(&signaturePoint2.x_coord().unwrap());
let s2 = k2.clone().invert().unwrap() * (m2.clone() + r2.clone() * D.clone());
println!("r2: {:?}", r2.to_bigint());
println!("s2: {:?}", s2.to_bigint());
let recovered = ExtractUsersPrivateKey(message1, message2, a, b, h, e, r1, s1, r2, s2, v, V, Q);
println!("{:?}", recovered.to_bigint());
}
fn ExtractUsersPrivateKey(
message1: String,
message2: String,
a: Scalar<Secp256k1>,
b: Scalar<Secp256k1>,
h: Scalar<Secp256k1>,
e: Scalar<Secp256k1>,
r1: Scalar<Secp256k1>,
s1: Scalar<Secp256k1>,
r2: Scalar<Secp256k1>,
s2: Scalar<Secp256k1>,
attackerPrivate: Scalar<Secp256k1>,
attackerPublic: Point<Secp256k1>,
userPublic: Point<Secp256k1>,
) -> Scalar<Secp256k1> {
let mut hasher = Hasher::new(MessageDigest::sha256()).unwrap();
hasher.update(message1.as_bytes()).expect("Hash error");
let m1: Scalar<Secp256k1> =
Scalar::from_bigint(&(BigInt::from_bytes(hasher.finish().unwrap().as_ref())));
hasher.update(message2.as_bytes()).expect("Hash error");
let m2: Scalar<Secp256k1> =
Scalar::from_bigint(&(BigInt::from_bytes(hasher.finish().unwrap().as_ref())));
let w = s1.invert().unwrap();
let u1 = m1.clone() * w.clone();
let u2 = r1.clone() * w.clone();
let verifyPoint = u1.clone() * Point::generator() + u2.clone() * userPublic.clone();
let Z1 = verifyPoint.clone() * a.clone()
+ (verifyPoint.clone() * b.clone() * attackerPrivate.clone());
let u: Scalar<Secp256k1> = Scalar::from(0 as u16);
let j: Scalar<Secp256k1> = Scalar::from(0 as u16);
let Z2 = Z1.clone()
+ j.clone() * h.clone() * Point::generator()
+ u.clone() * e.clone() * attackerPublic.clone();
let zX: Scalar<Secp256k1> = Scalar::from_bigint(&Z2.x_coord().unwrap());
hasher.update(&zX.to_bigint().to_bytes()).expect("Hash error");
let hash: Scalar<Secp256k1> =
Scalar::from_bigint(&BigInt::from_bytes(hasher.finish().unwrap().as_ref()));
let kCandiate = hash.clone();
let verifyPointCandiate = kCandiate.clone() * Point::generator();
let rCandiate = verifyPointCandiate.x_coord().unwrap();
if rCandiate == r2.to_bigint() {
return (s2.clone() * kCandiate.clone() - m2) * (r2.invert().unwrap());
}
Scalar::random()
}
This is the library I'm using
[dependencies]
curv-kzen = "0.8"
openssl = "0.10"
openssl-sys = "0.9"