diff --git a/Cargo.toml b/Cargo.toml index 01709efc..aee4ce1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,6 @@ license = "MIT OR Apache-2.0" [dependencies] num = "0.1.32" rand = "0.3.14" + +[dev-dependencies] +sodiumoxide = "*" diff --git a/examples/agg_sigs.rs b/examples/agg_sigs.rs new file mode 100644 index 00000000..371eb852 --- /dev/null +++ b/examples/agg_sigs.rs @@ -0,0 +1,66 @@ + +extern crate rand; +extern crate bn; + +use bn::{Field, Scalar, G1, G2, Gt, Fq12, pairing}; +mod sighash; +use std::collections::HashMap; + + +fn verify_aggregate_sig(agg_sig: &G1, msg_key_pairs: &[(&str, &G2)]) -> bool { + let mut unique = HashMap::new(); + let mut agg_verifier = Gt::new(Fq12::one()); + for &(msg, ref pub_key) in msg_key_pairs { + match unique.get(msg) { + Some(&true) => return false, //fail on duplicate messages + _ => {} // do nothing + } + unique.insert(msg, true); + let msg_e = G1::random(&mut sighash::SignatureHash::from(msg)); + agg_verifier = agg_verifier * pairing(&msg_e, &pub_key); + } + if pairing(agg_sig, &G2::one()) != agg_verifier { + return false; + } + return true; +} + +fn main() { + let rng = &mut rand::thread_rng(); + + const MSG1: &'static str = "Hello!"; + const MSG2: &'static str = "Hello!2"; + + // Generate Keys + let alice_sk = Scalar::random(rng); + let bob_sk = Scalar::random(rng); + + // Generate Public Keys + let alice_pk = G2::one() * &alice_sk; + let bob_pk = G2::one() * &bob_sk; + // Generate Signatures + let msgm1 = G1::random(&mut sighash::SignatureHash::from(MSG1)); + let sigm1_a = &msgm1 * &alice_sk; + + let msgm2 = G1::random(&mut sighash::SignatureHash::from(MSG2)); + let sigm2_b = &msgm2 * &bob_sk; + + // Verify single signatures + assert_eq!(pairing(&sigm1_a, &G2::one()), pairing(&msgm1, &alice_pk)); + assert_eq!(pairing(&sigm2_b, &G2::one()), pairing(&msgm2, &bob_pk)); + + // Generate Aggregate Signature + let sig_m1m2 = &sigm1_a + &sigm2_b; + + // Verify the Aggregate Signature + assert!(verify_aggregate_sig(&sig_m1m2, &[(MSG1, &alice_pk), (MSG2, &bob_pk)])); + + //Test duplicate messages + //Generate bob's sig of MSG + let sigm1_b = &msgm1 * &bob_sk; + + //Generate duplicate aggregate signature + let sig_m1_dup = &sigm1_a + &sigm1_b; + assert!(!verify_aggregate_sig(&sig_m1_dup, &[(MSG1, &alice_pk), (MSG1, &bob_pk)])); + +} diff --git a/examples/bls_sigs.rs b/examples/bls_sigs.rs new file mode 100644 index 00000000..15c394fb --- /dev/null +++ b/examples/bls_sigs.rs @@ -0,0 +1,22 @@ + extern crate rand; + extern crate bn; + + use bn::{Field, Scalar, G1, G2, pairing}; + mod sighash; + + fn main() { + let rng = &mut rand::thread_rng(); + + // Generate Keys + let alice_sk = Scalar::random(rng); + + // Generate Public Keys + let alice_pk = G2::one() * &alice_sk; + // Generate Signature + let msgm1 = G1::random(&mut sighash::SignatureHash::from("Hello!")); + let sigm1_a = &msgm1 * &alice_sk; + + // Verify single signature + assert_eq!(pairing(&sigm1_a, &G2::one()), pairing(&msgm1, &alice_pk)); + + } diff --git a/examples/ibe.rs b/examples/ibe.rs new file mode 100644 index 00000000..d72735b0 --- /dev/null +++ b/examples/ibe.rs @@ -0,0 +1,61 @@ +extern crate bn; +extern crate rand; +extern crate sodiumoxide; + +mod sighash; + +use bn::*; +use sodiumoxide::crypto::stream::chacha20; +use sodiumoxide::crypto::hash::sha256; +use std::str; + +fn main() { + ibe(); +} + +fn ibe() { + let rng = &mut rand::thread_rng(); + let master_sk = Scalar::random(rng); + // do we need another generator than G1::one() here? + // we use G1 since Ppub is used in the first arg of pairing + let master_pk = G1::one() * &master_sk; + + let id = b"test"; + + let derived = G2::random(&mut sighash::SignatureHash::from(&id[..])); + println!("derived: {:?}", derived); + + let id_sk = &derived * &master_sk; + + //encrypting with BasicIdent + let r = Scalar::random(rng); + let g_id = pairing(&master_pk, &derived) ^ &r; + println!("g_id: {:?}", g_id); + let badly_serialized = format!("{:?}", g_id); + let hash = sha256::hash(badly_serialized.as_bytes()); + + println!("hash: {:?}", hash); + let sym_key = chacha20::Key::from_slice(&hash[..32]).unwrap(); + let nonce = chacha20::gen_nonce(); + + let plaintext = "We propose a fully functional identity-based encryption scheme (IBE). The scheme has chosen ciphertext security in the random oracle model assuming a variant of the computational Diffie-Hellman problem"; + let ciphertext = chacha20::stream_xor(plaintext.as_bytes(), &nonce, &sym_key); + + // do we need another generator than G1::one() here? + let result = (G1::one() * &r, ciphertext); + println!("ciphertext: {:?}", result); + + //decrypting + let decrypting_seed = pairing(&result.0, &id_sk); + let badly_serialized_again = format!("{:?}", decrypting_seed); + println!("seed: {:?}", decrypting_seed); + assert_eq!(g_id, decrypting_seed); + let hash2 = sha256::hash(badly_serialized_again.as_bytes()); + println!("hash2: {:?}", hash2); + let sym_key_2 = chacha20::Key::from_slice(&hash2[..32]).unwrap(); + let decrypted = chacha20::stream_xor(&result.1, &nonce, &sym_key_2); + println!("decrypted: \"{}\"", str::from_utf8(&decrypted).unwrap()); + assert_eq!(plaintext.as_bytes(), &decrypted[..]); + +} + diff --git a/examples/sighash.rs b/examples/sighash.rs new file mode 100644 index 00000000..ade88da4 --- /dev/null +++ b/examples/sighash.rs @@ -0,0 +1,34 @@ +extern crate rand; +extern crate sodiumoxide; + +pub struct SignatureHash(rand::ChaChaRng); + +impl rand::Rng for SignatureHash { + fn next_u32(&mut self) -> u32 { + self.0.next_u32() + } +} + +impl<'a> From<&'a str> for SignatureHash { + fn from(v: &str) -> SignatureHash { + SignatureHash::from(v.as_bytes()) + } +} + +impl<'a> From<&'a [u8]> for SignatureHash { + fn from(v: &[u8]) -> SignatureHash { + use rand::SeedableRng; + use std::slice; + use std::mem; + + let hash = sodiumoxide::crypto::hash::sha256::hash(v); + assert_eq!(hash.0.len(), 32); + + SignatureHash(rand::ChaChaRng::from_seed(unsafe { + slice::from_raw_parts(mem::transmute::<&u8, &u32>(&hash.0[0]), 8) + })) + } +} + +fn main() { +} diff --git a/src/fields/fp.rs b/src/fields/fp.rs index 5ab6ca2b..58f467e1 100644 --- a/src/fields/fp.rs +++ b/src/fields/fp.rs @@ -42,7 +42,7 @@ impl Field for Fp

{ } } fn random(rng: &mut R) -> Self { - use num::num_bigint::RandBigInt; + use num::bigint::RandBigInt; use num::Zero; Fp {