signature & verification done

This commit is contained in:
2019-08-04 14:13:51 +02:00
parent fffcb66143
commit 9bc3000898
3 changed files with 46 additions and 26 deletions

View File

@@ -13,3 +13,4 @@ blake2 = "0.8"
generic-array = "0.13.2" generic-array = "0.13.2"
tiny-keccak = "1.5" tiny-keccak = "1.5"
rustc-hex = "1.0.0" rustc-hex = "1.0.0"
mimc-rs = "0.0.1"

View File

@@ -1,15 +1,17 @@
# babyjubjub-rs # babyjubjub-rs
BabyJubJub elliptic curve implementation in Rust BabyJubJub elliptic curve implementation in Rust
Uses MiMC7 hash function: https://github.com/arnaucube/mimc-rs
## Warning ## Warning
Doing this in my free time to get familiar with Rust, do not use in production Doing this in my free time to get familiar with Rust, do not use in production
- [x] point addition - [x] point addition
- [x] point scalar multiplication - [x] point scalar multiplication
- [ ] point compress&decompress parsers - [ ] {point, pk, signature} compress&decompress parsers
- [x] eddsa keys generation - [x] eddsa keys generation
- [ ] eddsa signature - [x] eddsa signature
- [ ] eddsa signature verification - [x] eddsa signature verification

View File

@@ -1,10 +1,12 @@
extern crate generic_array; extern crate generic_array;
extern crate mimc_rs;
extern crate num; extern crate num;
extern crate num_bigint; extern crate num_bigint;
extern crate num_traits; extern crate num_traits;
extern crate rand; extern crate rand;
use blake2::{Blake2b, Digest}; use blake2::{Blake2b, Digest};
use mimc_rs::Mimc7;
use num_bigint::RandBigInt; use num_bigint::RandBigInt;
@@ -30,7 +32,7 @@ pub struct Babyjubjub {
a: BigInt, a: BigInt,
q: BigInt, q: BigInt,
b8: Point, b8: Point,
order: BigInt, // order: BigInt,
sub_order: BigInt, sub_order: BigInt,
} }
@@ -67,7 +69,7 @@ impl Babyjubjub {
a: a, a: a,
q: q, q: q,
b8: b8, b8: b8,
order: order, // order: order,
sub_order: sub_order, sub_order: sub_order,
} }
} }
@@ -115,6 +117,8 @@ impl Babyjubjub {
exp = self.add(&exp, &exp); exp = self.add(&exp, &exp);
rem = rem >> 1; rem = rem >> 1;
} }
r.x = utils::modulus(&r.x, &self.q);
r.y = utils::modulus(&r.y, &self.q);
r r
} }
@@ -122,10 +126,9 @@ impl Babyjubjub {
// https://tools.ietf.org/html/rfc8032#section-5.1.5 // https://tools.ietf.org/html/rfc8032#section-5.1.5
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap(); let sk_raw = rng.gen_biguint(1024).to_bigint().unwrap();
println!("sk {:?}", sk_raw.to_string());
let mut hasher = Blake2b::new(); let mut hasher = Blake2b::new();
let (_, sk_raw_bytes) = sk_raw.to_bytes_le(); let (_, sk_raw_bytes) = sk_raw.to_bytes_be();
hasher.input(sk_raw_bytes); hasher.input(sk_raw_bytes);
let mut h = hasher.result(); let mut h = hasher.result();
@@ -147,28 +150,22 @@ impl Babyjubjub {
pub fn sign(&self, sk: BigInt, msg: BigInt) -> Signature { pub fn sign(&self, sk: BigInt, msg: BigInt) -> Signature {
// https://tools.ietf.org/html/rfc8032#section-5.1.6 // https://tools.ietf.org/html/rfc8032#section-5.1.6
let mut hasher = Blake2b::new(); let mut hasher = Blake2b::new();
let (_, sk_bytes) = sk.to_bytes_le(); let (_, sk_bytes) = sk.to_bytes_be();
hasher.input(sk_bytes); hasher.input(sk_bytes);
let mut h = hasher.result(); // h: hash(sk) let mut h = hasher.result(); // h: hash(sk)
// s: h[32:64] // s: h[32:64]
let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]); let s = GenericArray::<u8, generic_array::typenum::U32>::from_mut_slice(&mut h[32..64]);
let (_, msg_bytes) = msg.to_bytes_be();
let (_, msg_bytes) = msg.to_bytes_le();
let r_bytes = utils::concatenate_arrays(s, &msg_bytes); let r_bytes = utils::concatenate_arrays(s, &msg_bytes);
let mut r = BigInt::from_bytes_le(Sign::Plus, &r_bytes[..]); let mut r = BigInt::from_bytes_be(Sign::Plus, &r_bytes[..]);
r = r & &self.sub_order; r = utils::modulus(&r, &self.sub_order);
let r8: Point = self.mul_scalar(self.b8.clone(), r.clone()); let r8: Point = self.mul_scalar(self.b8.clone(), r.clone());
println!("r8 {:?}", r8);
let a = &self.sk_to_pk(sk.clone()); let a = &self.sk_to_pk(sk.clone());
// TODO WARNING!!! [TEMP] use MIMC7 hash function (MIMC7 to be implemented) let hm_input = vec![r8.x.clone(), r8.y.clone(), a.x.clone(), a.y.clone(), msg];
let hm_input = r8.x + r8.y + &a.x + &a.y + msg; // TEMP let mimc7 = Mimc7::new();
let mut hasher = Blake2b::new(); let hm = mimc7.hash(hm_input);
let (_, sk_bytes) = sk.to_bytes_le();
hasher.input(sk_bytes);
let hm = BigInt::from_bytes_le(Sign::Plus, &hasher.result()[..]);
let mut s = sk << 3; let mut s = sk << 3;
s = hm * s; s = hm * s;
@@ -176,10 +173,28 @@ impl Babyjubjub {
s = s % &self.sub_order; s = s % &self.sub_order;
Signature { Signature {
r_b8: self.b8.clone(), r_b8: r8.clone(),
s: s, s: s,
} }
} }
pub fn verify(&self, pk: Point, sig: Signature, msg: BigInt) -> bool {
let hm_input = vec![
sig.r_b8.x.clone(),
sig.r_b8.y.clone(),
pk.x.clone(),
pk.y.clone(),
msg,
];
let mimc7 = Mimc7::new();
let hm = mimc7.hash(hm_input);
let l = self.mul_scalar(self.b8.clone(), sig.s);
let r = self.add(&sig.r_b8, &self.mul_scalar(pk, 8.to_bigint().unwrap() * hm));
if l.x == r.x && l.y == r.y {
return true;
}
false
}
} }
#[cfg(test)] #[cfg(test)]
@@ -304,13 +319,15 @@ mod tests {
"4014745322800118607127020275658861516666525056516280575712425373174125159339" "4014745322800118607127020275658861516666525056516280575712425373174125159339"
); );
} }
#[test] #[test]
fn test_new_key_sign() { fn test_new_key_sign_verify() {
let bbjj = Babyjubjub::new(); let bbjj = Babyjubjub::new();
let sk = bbjj.new_key(); let sk = bbjj.new_key();
println!("sk {:?}", sk); let pk = bbjj.sk_to_pk(sk.clone());
let sig = bbjj.sign(sk, 5.to_bigint().unwrap()); let msg = 5.to_bigint().unwrap();
println!("sig {:?}", sig.r_b8); let sig = bbjj.sign(sk, msg.clone());
println!("sig {:?}", sig.s); let v = bbjj.verify(pk, sig, msg);
assert_eq!(v, true);
} }
} }