This is an automated email from the ASF dual-hosted git repository. kmccusker pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/incubator-milagro-crypto-rust.git
commit de198225b44463a96b48e3bc6b5fc4494e86628d Author: Kirk Baird <[email protected]> AuthorDate: Fri Dec 13 17:18:41 2019 +1100 Duplicate tests in cargo test Signed-off-by: Kirk Baird <[email protected]> --- tests/test_all.rs | 1473 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/test_bls.rs | 190 +++++++ tests/test_nhs.rs | 71 +++ 3 files changed, 1734 insertions(+) diff --git a/tests/test_all.rs b/tests/test_all.rs new file mode 100644 index 0000000..c543dac --- /dev/null +++ b/tests/test_all.rs @@ -0,0 +1,1473 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +extern crate amcl; + +use std::io; +use std::str; + +use amcl::rand::RAND; +use amcl::types::CurveType; + +pub fn printbinary(array: &[u8]) { + for i in 0..array.len() { + print!("{:02X}", array[i]) + } + println!("") +} + +fn create_rng() -> RAND { + let mut raw: [u8; 100] = [0; 100]; + + let mut rng = RAND::new(); + rng.clean(); + for i in 0..100 { + raw[i] = i as u8 + } + + rng.seed(100, &raw); + rng +} + +#[test] +fn ecdh_ed25519() { + //use amcl::ed25519; + use amcl::ed25519::ecdh; + use amcl::ed25519::ecp; + + let mut rng = create_rng(); + + let pw = "M0ng00se"; + let pp: &[u8] = b"M0ng00se"; + const EFS: usize = ecdh::EFS; + const EGS: usize = ecdh::EGS; + const EAS: usize = ecp::AESKEY; + + let sha = ecp::HASH_TYPE; + let mut salt: [u8; 8] = [0; 8]; + let mut s1: [u8; EGS] = [0; EGS]; + let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut z0: [u8; EFS] = [0; EFS]; + let mut z1: [u8; EFS] = [0; EFS]; + let mut key: [u8; EAS] = [0; EAS]; + let mut cs: [u8; EGS] = [0; EGS]; + let mut ds: [u8; EGS] = [0; EGS]; + let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap. + let mut p1: [u8; 3] = [0; 3]; + let mut p2: [u8; 4] = [0; 4]; + let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut t: [u8; 12] = [0; 12]; + + for i in 0..8 { + salt[i] = (i + 1) as u8 + } // set Salt + + println!("\nTesting ECDH/ECDSA/ECIES"); + println!("Alice's Passphrase= {}", pw); + + let mut s0: [u8; EFS] = [0; EGS]; + ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0); + + print!("Alice's private key= 0x"); + printbinary(&s0); + + /* Generate Key pair S/W */ + ecdh::key_pair_generate(None, &mut s0, &mut w0); + + print!("Alice's public key= 0x"); + printbinary(&w0); + + let mut res = ecdh::public_key_validate(&w0); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + + /* Random private key for other party */ + ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1); + + print!("Servers private key= 0x"); + printbinary(&s1); + + print!("Servers public key= 0x"); + printbinary(&w1); + + res = ecdh::public_key_validate(&w1); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + /* Calculate common key using DH - IEEE 1363 method */ + + ecdh::ecpsvdp_dh(&s0, &w1, &mut z0); + ecdh::ecpsvdp_dh(&s1, &w0, &mut z1); + + let mut same = true; + for i in 0..EFS { + if z0[i] != z1[i] { + same = false + } + } + + if !same { + println!("*** ECPSVDP-DH Failed"); + return; + } + + ecdh::kdf2(sha, &z0, None, EAS, &mut key); + + print!("Alice's DH Key= 0x"); + printbinary(&key); + print!("Servers DH Key= 0x"); + printbinary(&key); + + if ecp::CURVETYPE != CurveType::Montgomery { + for i in 0..17 { + m[i] = i as u8 + } + + println!("Testing ECIES"); + + p1[0] = 0x0; + p1[1] = 0x1; + p1[2] = 0x2; + p2[0] = 0x0; + p2[1] = 0x1; + p2[2] = 0x2; + p2[3] = 0x3; + + let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t); + + if let Some(mut c) = cc { + println!("Ciphertext= "); + print!("V= 0x"); + printbinary(&v); + print!("C= 0x"); + printbinary(&c); + print!("T= 0x"); + printbinary(&t); + + let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1); + if let Some(rm) = mm { + println!("Decryption succeeded"); + print!("Message is 0x"); + printbinary(&rm); + } else { + println!("*** ECIES Decryption Failed"); + return; + } + } else { + println!("*** ECIES Encryption Failed"); + return; + } + + println!("Testing ECDSA"); + + if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 { + println!("***ECDSA Signature Failed"); + return; + } + println!("Signature= "); + print!("C= 0x"); + printbinary(&cs); + print!("D= 0x"); + printbinary(&ds); + + if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 { + println!("***ECDSA Verification Failed"); + return; + } else { + println!("ECDSA Signature/Verification succeeded ") + } + } +} + +#[test] +fn ecdh_nist256() { + use amcl::nist256::ecdh; + use amcl::nist256::ecp; + + let mut rng = create_rng(); + + let pw = "M0ng00se"; + let pp: &[u8] = b"M0ng00se"; + const EFS: usize = ecdh::EFS; + const EGS: usize = ecdh::EGS; + const EAS: usize = ecp::AESKEY; + + let sha = ecp::HASH_TYPE; + let mut salt: [u8; 8] = [0; 8]; + let mut s1: [u8; EGS] = [0; EGS]; + let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut z0: [u8; EFS] = [0; EFS]; + let mut z1: [u8; EFS] = [0; EFS]; + let mut key: [u8; EAS] = [0; EAS]; + let mut cs: [u8; EGS] = [0; EGS]; + let mut ds: [u8; EGS] = [0; EGS]; + let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap. + let mut p1: [u8; 3] = [0; 3]; + let mut p2: [u8; 4] = [0; 4]; + let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut t: [u8; 12] = [0; 12]; + + for i in 0..8 { + salt[i] = (i + 1) as u8 + } // set Salt + + println!("\nTesting ECDH/ECDSA/ECIES"); + println!("Alice's Passphrase= {}", pw); + + let mut s0: [u8; EFS] = [0; EGS]; + ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0); + + print!("Alice's private key= 0x"); + printbinary(&s0); + + /* Generate Key pair S/W */ + ecdh::key_pair_generate(None, &mut s0, &mut w0); + + print!("Alice's public key= 0x"); + printbinary(&w0); + + let mut res = ecdh::public_key_validate(&w0); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + + /* Random private key for other party */ + ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1); + + print!("Servers private key= 0x"); + printbinary(&s1); + + print!("Servers public key= 0x"); + printbinary(&w1); + + res = ecdh::public_key_validate(&w1); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + /* Calculate common key using DH - IEEE 1363 method */ + + ecdh::ecpsvdp_dh(&s0, &w1, &mut z0); + ecdh::ecpsvdp_dh(&s1, &w0, &mut z1); + + let mut same = true; + for i in 0..EFS { + if z0[i] != z1[i] { + same = false + } + } + + if !same { + println!("*** ECPSVDP-DH Failed"); + return; + } + + ecdh::kdf2(sha, &z0, None, EAS, &mut key); + + print!("Alice's DH Key= 0x"); + printbinary(&key); + print!("Servers DH Key= 0x"); + printbinary(&key); + + if ecp::CURVETYPE != CurveType::Montgomery { + for i in 0..17 { + m[i] = i as u8 + } + + println!("Testing ECIES"); + + p1[0] = 0x0; + p1[1] = 0x1; + p1[2] = 0x2; + p2[0] = 0x0; + p2[1] = 0x1; + p2[2] = 0x2; + p2[3] = 0x3; + + let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t); + + if let Some(mut c) = cc { + println!("Ciphertext= "); + print!("V= 0x"); + printbinary(&v); + print!("C= 0x"); + printbinary(&c); + print!("T= 0x"); + printbinary(&t); + + let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1); + if let Some(rm) = mm { + println!("Decryption succeeded"); + print!("Message is 0x"); + printbinary(&rm); + } else { + println!("*** ECIES Decryption Failed"); + return; + } + } else { + println!("*** ECIES Encryption Failed"); + return; + } + + println!("Testing ECDSA"); + + if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 { + println!("***ECDSA Signature Failed"); + return; + } + println!("Signature= "); + print!("C= 0x"); + printbinary(&cs); + print!("D= 0x"); + printbinary(&ds); + + if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 { + println!("***ECDSA Verification Failed"); + return; + } else { + println!("ECDSA Signature/Verification succeeded ") + } + } +} + +#[test] +fn ecdh_goldilocks() { + use amcl::goldilocks::ecdh; + use amcl::goldilocks::ecp; + + let mut rng = create_rng(); + + let pw = "M0ng00se"; + let pp: &[u8] = b"M0ng00se"; + const EFS: usize = ecdh::EFS; + const EGS: usize = ecdh::EGS; + const EAS: usize = ecp::AESKEY; + + let sha = ecp::HASH_TYPE; + let mut salt: [u8; 8] = [0; 8]; + let mut s1: [u8; EGS] = [0; EGS]; + let mut w0: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut w1: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut z0: [u8; EFS] = [0; EFS]; + let mut z1: [u8; EFS] = [0; EFS]; + let mut key: [u8; EAS] = [0; EAS]; + let mut cs: [u8; EGS] = [0; EGS]; + let mut ds: [u8; EGS] = [0; EGS]; + let mut m: Vec<u8> = vec![0; 32]; // array that could be of any length. So use heap. + let mut p1: [u8; 3] = [0; 3]; + let mut p2: [u8; 4] = [0; 4]; + let mut v: [u8; 2 * EFS + 1] = [0; 2 * EFS + 1]; + let mut t: [u8; 12] = [0; 12]; + + for i in 0..8 { + salt[i] = (i + 1) as u8 + } // set Salt + + println!("\nTesting ECDH/ECDSA/ECIES"); + println!("Alice's Passphrase= {}", pw); + + let mut s0: [u8; EFS] = [0; EGS]; + ecdh::pbkdf2(sha, pp, &salt, 1000, EGS, &mut s0); + + print!("Alice's private key= 0x"); + printbinary(&s0); + + /* Generate Key pair S/W */ + ecdh::key_pair_generate(None, &mut s0, &mut w0); + + print!("Alice's public key= 0x"); + printbinary(&w0); + + let mut res = ecdh::public_key_validate(&w0); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + + /* Random private key for other party */ + ecdh::key_pair_generate(Some(&mut rng), &mut s1, &mut w1); + + print!("Servers private key= 0x"); + printbinary(&s1); + + print!("Servers public key= 0x"); + printbinary(&w1); + + res = ecdh::public_key_validate(&w1); + if res != 0 { + println!("ECP Public Key is invalid!"); + return; + } + /* Calculate common key using DH - IEEE 1363 method */ + + ecdh::ecpsvdp_dh(&s0, &w1, &mut z0); + ecdh::ecpsvdp_dh(&s1, &w0, &mut z1); + + let mut same = true; + for i in 0..EFS { + if z0[i] != z1[i] { + same = false + } + } + + if !same { + println!("*** ECPSVDP-DH Failed"); + return; + } + + ecdh::kdf2(sha, &z0, None, EAS, &mut key); + + print!("Alice's DH Key= 0x"); + printbinary(&key); + print!("Servers DH Key= 0x"); + printbinary(&key); + + if ecp::CURVETYPE != CurveType::Montgomery { + for i in 0..17 { + m[i] = i as u8 + } + + println!("Testing ECIES"); + + p1[0] = 0x0; + p1[1] = 0x1; + p1[2] = 0x2; + p2[0] = 0x0; + p2[1] = 0x1; + p2[2] = 0x2; + p2[3] = 0x3; + + let cc = ecdh::ecies_encrypt(sha, &p1, &p2, &mut rng, &w1, &m[0..17], &mut v, &mut t); + + if let Some(mut c) = cc { + println!("Ciphertext= "); + print!("V= 0x"); + printbinary(&v); + print!("C= 0x"); + printbinary(&c); + print!("T= 0x"); + printbinary(&t); + + let mm = ecdh::ecies_decrypt(sha, &p1, &p2, &v, &mut c, &t, &s1); + if let Some(rm) = mm { + println!("Decryption succeeded"); + print!("Message is 0x"); + printbinary(&rm); + } else { + println!("*** ECIES Decryption Failed"); + return; + } + } else { + println!("*** ECIES Encryption Failed"); + return; + } + + println!("Testing ECDSA"); + + if ecdh::ecpsp_dsa(sha, &mut rng, &s0, &m[0..17], &mut cs, &mut ds) != 0 { + println!("***ECDSA Signature Failed"); + return; + } + println!("Signature= "); + print!("C= 0x"); + printbinary(&cs); + print!("D= 0x"); + printbinary(&ds); + + if ecdh::ecpvp_dsa(sha, &w0, &m[0..17], &cs, &ds) != 0 { + println!("***ECDSA Verification Failed"); + return; + } else { + println!("ECDSA Signature/Verification succeeded ") + } + } +} + +#[test] +fn mpin_bn254() { + use amcl::bn254::ecp; + use amcl::bn254::mpin; + + let mut rng = create_rng(); + + pub const PERMITS: bool = true; + pub const PINERROR: bool = true; + pub const FULL: bool = true; + //pub const SINGLE_PASS:bool=false; + + const EFS: usize = mpin::EFS; + const EGS: usize = mpin::EGS; + + let mut s: [u8; EGS] = [0; EGS]; + const RM: usize = EFS as usize; + let mut hcid: [u8; RM] = [0; RM]; + let mut hsid: [u8; RM] = [0; RM]; + + const G1S: usize = 2 * EFS + 1; /* Group 1 Size */ + const G2S: usize = 4 * EFS; /* Group 2 Size */ + const EAS: usize = ecp::AESKEY; + + let mut sst: [u8; G2S] = [0; G2S]; + let mut token: [u8; G1S] = [0; G1S]; + let mut permit: [u8; G1S] = [0; G1S]; + let mut g1: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut g2: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut xid: [u8; G1S] = [0; G1S]; + let mut xcid: [u8; G1S] = [0; G1S]; + let mut x: [u8; EGS] = [0; EGS]; + let mut y: [u8; EGS] = [0; EGS]; + let mut sec: [u8; G1S] = [0; G1S]; + let mut r: [u8; EGS] = [0; EGS]; + let mut z: [u8; G1S] = [0; G1S]; + let mut hid: [u8; G1S] = [0; G1S]; + let mut htid: [u8; G1S] = [0; G1S]; + let mut rhid: [u8; G1S] = [0; G1S]; + let mut w: [u8; EGS] = [0; EGS]; + let mut t: [u8; G1S] = [0; G1S]; + let mut e: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut f: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut h: [u8; RM] = [0; RM]; + let mut ck: [u8; EAS] = [0; EAS]; + let mut sk: [u8; EAS] = [0; EAS]; + + let sha = ecp::HASH_TYPE; + + println!("\nTesting MPIN - PIN is 1234"); + /* Trusted Authority set-up */ + + mpin::random_generate(&mut rng, &mut s); + print!("Master Secret s: 0x"); + printbinary(&s); + + /* Create Client Identity */ + let name = "[email protected]"; + let client_id = name.as_bytes(); + + print!("Client ID= "); + printbinary(&client_id); + + mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */ + + /* Client and Server are issued secrets by DTA */ + mpin::get_server_secret(&s, &mut sst); + print!("Server Secret SS: 0x"); + printbinary(&sst); + + mpin::get_client_secret(&mut s, &hcid, &mut token); + print!("Client Secret CS: 0x"); + printbinary(&token); + + /* Client extracts PIN from secret to create Token */ + let pin: i32 = 1234; + println!("Client extracts PIN= {}", pin); + let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token); + if rtn != 0 { + println!("FAILURE: EXTRACT_PIN rtn: {}", rtn); + } + + print!("Client Token TK: 0x"); + printbinary(&token); + + if FULL { + mpin::precompute(&token, &hcid, &mut g1, &mut g2); + } + + let mut date = 0; + if PERMITS { + date = mpin::today(); + /* Client gets "Time Token" permit from DTA */ + + mpin::get_client_permit(sha, date, &s, &hcid, &mut permit); + print!("Time Permit TP: 0x"); + printbinary(&permit); + + /* This encoding makes Time permit look random - Elligator squared */ + mpin::encoding(&mut rng, &mut permit); + print!("Encoded Time Permit TP: 0x"); + printbinary(&permit); + mpin::decoding(&mut permit); + print!("Decoded Time Permit TP: 0x"); + printbinary(&permit); + } + + print!("\nPIN= "); + let _ = io::Write::flush(&mut io::stdout()); + let mut input_text = String::new(); + let _ = io::stdin().read_line(&mut input_text); + + let pin = input_text.trim().parse::<usize>().unwrap(); + + println!("MPIN Multi Pass"); + /* Send U=x.ID to server, and recreate secret from token and pin */ + rtn = mpin::client_1( + sha, + date, + &client_id, + Some(&mut rng), + &mut x, + pin, + &token, + &mut sec, + Some(&mut xid[..]), + Some(&mut xcid[..]), + Some(&permit[..]), + ); + if rtn != 0 { + println!("FAILURE: CLIENT_1 rtn: {}", rtn); + } + + if FULL { + mpin::hash_id(sha, &client_id, &mut hcid); + mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */ + } + + /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */ + + mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..])); + + if date != 0 { + rhid.clone_from_slice(&htid[..]); + } else { + rhid.clone_from_slice(&hid[..]); + } + + /* Server generates Random number Y and sends it to Client */ + mpin::random_generate(&mut rng, &mut y); + + if FULL { + mpin::hash_id(sha, &client_id, &mut hsid); + mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w */ + } + + /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */ + rtn = mpin::client_2(&x, &y, &mut sec); + if rtn != 0 { + println!("FAILURE: CLIENT_2 rtn: {}", rtn); + } + + /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */ + /* If PIN error not required, set E and F = null */ + + if !PINERROR { + rtn = mpin::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + None, + None, + ); + } else { + rtn = mpin::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + Some(&mut e), + Some(&mut f), + ); + } + + if rtn == mpin::BAD_PIN { + println!("Server says - Bad Pin. I don't know you. Feck off."); + if PINERROR { + let err = mpin::kangaroo(&e, &f); + if err != 0 { + println!("(Client PIN is out by {})", err) + } + } + return; + } else { + println!("Server says - PIN is good! You really are {}", name); + } + + if FULL { + let mut pxcid = None; + if PERMITS { + pxcid = Some(&xcid[..]) + }; + + mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck); + print!("Client Key = 0x"); + printbinary(&ck); + + mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk); + print!("Server Key = 0x"); + printbinary(&sk); + } +} + +#[test] +fn mpin_bls383() { + //use amcl::bls383; + use amcl::bls383::ecp; + use amcl::bls383::mpin; + + let mut rng = create_rng(); + + pub const PERMITS: bool = true; + pub const PINERROR: bool = true; + pub const FULL: bool = true; + //pub const SINGLE_PASS:bool=false; + + const EFS: usize = mpin::EFS; + const EGS: usize = mpin::EGS; + + let mut s: [u8; EGS] = [0; EGS]; + const RM: usize = EFS as usize; + let mut hcid: [u8; RM] = [0; RM]; + let mut hsid: [u8; RM] = [0; RM]; + + const G1S: usize = 2 * EFS + 1; /* Group 1 Size */ + const G2S: usize = 4 * EFS; /* Group 2 Size */ + const EAS: usize = ecp::AESKEY; + + let mut sst: [u8; G2S] = [0; G2S]; + let mut token: [u8; G1S] = [0; G1S]; + let mut permit: [u8; G1S] = [0; G1S]; + let mut g1: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut g2: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut xid: [u8; G1S] = [0; G1S]; + let mut xcid: [u8; G1S] = [0; G1S]; + let mut x: [u8; EGS] = [0; EGS]; + let mut y: [u8; EGS] = [0; EGS]; + let mut sec: [u8; G1S] = [0; G1S]; + let mut r: [u8; EGS] = [0; EGS]; + let mut z: [u8; G1S] = [0; G1S]; + let mut hid: [u8; G1S] = [0; G1S]; + let mut htid: [u8; G1S] = [0; G1S]; + let mut rhid: [u8; G1S] = [0; G1S]; + let mut w: [u8; EGS] = [0; EGS]; + let mut t: [u8; G1S] = [0; G1S]; + let mut e: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut f: [u8; 12 * EFS] = [0; 12 * EFS]; + let mut h: [u8; RM] = [0; RM]; + let mut ck: [u8; EAS] = [0; EAS]; + let mut sk: [u8; EAS] = [0; EAS]; + + let sha = ecp::HASH_TYPE; + + println!("\nTesting MPIN - PIN is 1234"); + /* Trusted Authority set-up */ + + mpin::random_generate(&mut rng, &mut s); + print!("Master Secret s: 0x"); + printbinary(&s); + + /* Create Client Identity */ + let name = "[email protected]"; + let client_id = name.as_bytes(); + + print!("Client ID= "); + printbinary(&client_id); + + mpin::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */ + + /* Client and Server are issued secrets by DTA */ + mpin::get_server_secret(&s, &mut sst); + print!("Server Secret SS: 0x"); + printbinary(&sst); + + mpin::get_client_secret(&mut s, &hcid, &mut token); + print!("Client Secret CS: 0x"); + printbinary(&token); + + /* Client extracts PIN from secret to create Token */ + let pin: i32 = 1234; + println!("Client extracts PIN= {}", pin); + let mut rtn = mpin::extract_pin(sha, &client_id, pin, &mut token); + if rtn != 0 { + println!("FAILURE: EXTRACT_PIN rtn: {}", rtn); + } + + print!("Client Token TK: 0x"); + printbinary(&token); + + if FULL { + mpin::precompute(&token, &hcid, &mut g1, &mut g2); + } + + let mut date = 0; + if PERMITS { + date = mpin::today(); + /* Client gets "Time Token" permit from DTA */ + + mpin::get_client_permit(sha, date, &s, &hcid, &mut permit); + print!("Time Permit TP: 0x"); + printbinary(&permit); + + /* This encoding makes Time permit look random - Elligator squared */ + mpin::encoding(&mut rng, &mut permit); + print!("Encoded Time Permit TP: 0x"); + printbinary(&permit); + mpin::decoding(&mut permit); + print!("Decoded Time Permit TP: 0x"); + printbinary(&permit); + } + + print!("\nPIN= "); + let _ = io::Write::flush(&mut io::stdout()); + let mut input_text = String::new(); + let _ = io::stdin().read_line(&mut input_text); + + let pin = input_text.trim().parse::<usize>().unwrap(); + + println!("MPIN Multi Pass"); + /* Send U=x.ID to server, and recreate secret from token and pin */ + rtn = mpin::client_1( + sha, + date, + &client_id, + Some(&mut rng), + &mut x, + pin, + &token, + &mut sec, + Some(&mut xid[..]), + Some(&mut xcid[..]), + Some(&permit[..]), + ); + if rtn != 0 { + println!("FAILURE: CLIENT_1 rtn: {}", rtn); + } + + if FULL { + mpin::hash_id(sha, &client_id, &mut hcid); + mpin::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */ + } + + /* Server calculates H(ID) and H(T|H(ID)) (if time mpin::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */ + + mpin::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..])); + + if date != 0 { + rhid.clone_from_slice(&htid[..]); + } else { + rhid.clone_from_slice(&hid[..]); + } + + /* Server generates Random number Y and sends it to Client */ + mpin::random_generate(&mut rng, &mut y); + + if FULL { + mpin::hash_id(sha, &client_id, &mut hsid); + mpin::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w */ + } + + /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */ + rtn = mpin::client_2(&x, &y, &mut sec); + if rtn != 0 { + println!("FAILURE: CLIENT_2 rtn: {}", rtn); + } + + /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */ + /* If PIN error not required, set E and F = null */ + + if !PINERROR { + rtn = mpin::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + None, + None, + ); + } else { + rtn = mpin::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + Some(&mut e), + Some(&mut f), + ); + } + + if rtn == mpin::BAD_PIN { + println!("Server says - Bad Pin. I don't know you. Feck off."); + if PINERROR { + let err = mpin::kangaroo(&e, &f); + if err != 0 { + println!("(Client PIN is out by {})", err) + } + } + return; + } else { + println!("Server says - PIN is good! You really are {}", name); + } + + if FULL { + let mut pxcid = None; + if PERMITS { + pxcid = Some(&xcid[..]) + }; + + mpin::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck); + print!("Client Key = 0x"); + printbinary(&ck); + + mpin::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk); + print!("Server Key = 0x"); + printbinary(&sk); + } +} + +#[test] +fn mpin_bls24() { + //use amcl::bls24; + use amcl::bls24::ecp; + use amcl::bls24::mpin192; + + let mut rng = create_rng(); + + pub const PERMITS: bool = true; + pub const PINERROR: bool = true; + pub const FULL: bool = true; + //pub const SINGLE_PASS:bool=false; + + const EFS: usize = mpin192::EFS; + const EGS: usize = mpin192::EGS; + + let mut s: [u8; EGS] = [0; EGS]; + const RM: usize = EFS as usize; + let mut hcid: [u8; RM] = [0; RM]; + let mut hsid: [u8; RM] = [0; RM]; + + const G1S: usize = 2 * EFS + 1; /* Group 1 Size */ + const G2S: usize = 8 * EFS; /* Group 2 Size */ + const EAS: usize = ecp::AESKEY; + + let mut sst: [u8; G2S] = [0; G2S]; + let mut token: [u8; G1S] = [0; G1S]; + let mut permit: [u8; G1S] = [0; G1S]; + let mut g1: [u8; 24 * EFS] = [0; 24 * EFS]; + let mut g2: [u8; 24 * EFS] = [0; 24 * EFS]; + let mut xid: [u8; G1S] = [0; G1S]; + let mut xcid: [u8; G1S] = [0; G1S]; + let mut x: [u8; EGS] = [0; EGS]; + let mut y: [u8; EGS] = [0; EGS]; + let mut sec: [u8; G1S] = [0; G1S]; + let mut r: [u8; EGS] = [0; EGS]; + let mut z: [u8; G1S] = [0; G1S]; + let mut hid: [u8; G1S] = [0; G1S]; + let mut htid: [u8; G1S] = [0; G1S]; + let mut rhid: [u8; G1S] = [0; G1S]; + let mut w: [u8; EGS] = [0; EGS]; + let mut t: [u8; G1S] = [0; G1S]; + let mut e: [u8; 24 * EFS] = [0; 24 * EFS]; + let mut f: [u8; 24 * EFS] = [0; 24 * EFS]; + let mut h: [u8; RM] = [0; RM]; + let mut ck: [u8; EAS] = [0; EAS]; + let mut sk: [u8; EAS] = [0; EAS]; + + let sha = ecp::HASH_TYPE; + + println!("\nTesting MPIN - PIN is 1234"); + /* Trusted Authority set-up */ + + mpin192::random_generate(&mut rng, &mut s); + print!("Master Secret s: 0x"); + printbinary(&s); + + /* Create Client Identity */ + let name = "[email protected]"; + let client_id = name.as_bytes(); + + print!("Client ID= "); + printbinary(&client_id); + + mpin192::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */ + + /* Client and Server are issued secrets by DTA */ + mpin192::get_server_secret(&s, &mut sst); + print!("Server Secret SS: 0x"); + printbinary(&sst); + + mpin192::get_client_secret(&mut s, &hcid, &mut token); + print!("Client Secret CS: 0x"); + printbinary(&token); + + /* Client extracts PIN from secret to create Token */ + let pin: i32 = 1234; + println!("Client extracts PIN= {}", pin); + let mut rtn = mpin192::extract_pin(sha, &client_id, pin, &mut token); + if rtn != 0 { + println!("FAILURE: EXTRACT_PIN rtn: {}", rtn); + } + + print!("Client Token TK: 0x"); + printbinary(&token); + + if FULL { + mpin192::precompute(&token, &hcid, &mut g1, &mut g2); + } + + let mut date = 0; + if PERMITS { + date = mpin192::today(); + /* Client gets "Time Token" permit from DTA */ + + mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit); + print!("Time Permit TP: 0x"); + printbinary(&permit); + + /* This encoding makes Time permit look random - Elligator squared */ + mpin192::encoding(&mut rng, &mut permit); + print!("Encoded Time Permit TP: 0x"); + printbinary(&permit); + mpin192::decoding(&mut permit); + print!("Decoded Time Permit TP: 0x"); + printbinary(&permit); + } + + print!("\nPIN= "); + let _ = io::Write::flush(&mut io::stdout()); + let mut input_text = String::new(); + let _ = io::stdin().read_line(&mut input_text); + + let pin = input_text.trim().parse::<usize>().unwrap(); + + println!("MPIN Multi Pass"); + /* Send U=x.ID to server, and recreate secret from token and pin */ + rtn = mpin192::client_1( + sha, + date, + &client_id, + Some(&mut rng), + &mut x, + pin, + &token, + &mut sec, + Some(&mut xid[..]), + Some(&mut xcid[..]), + Some(&permit[..]), + ); + if rtn != 0 { + println!("FAILURE: CLIENT_1 rtn: {}", rtn); + } + + if FULL { + mpin192::hash_id(sha, &client_id, &mut hcid); + mpin192::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */ + } + + /* Server calculates H(ID) and H(T|H(ID)) (if time mpin192::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */ + + mpin192::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..])); + + if date != 0 { + rhid.clone_from_slice(&htid[..]); + } else { + rhid.clone_from_slice(&hid[..]); + } + + /* Server generates Random number Y and sends it to Client */ + mpin192::random_generate(&mut rng, &mut y); + + if FULL { + mpin192::hash_id(sha, &client_id, &mut hsid); + mpin192::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w */ + } + + /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */ + rtn = mpin192::client_2(&x, &y, &mut sec); + if rtn != 0 { + println!("FAILURE: CLIENT_2 rtn: {}", rtn); + } + + /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */ + /* If PIN error not required, set E and F = null */ + + if !PINERROR { + rtn = mpin192::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + None, + None, + ); + } else { + rtn = mpin192::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + Some(&mut e), + Some(&mut f), + ); + } + + if rtn == mpin192::BAD_PIN { + println!("Server says - Bad Pin. I don't know you. Feck off."); + if PINERROR { + let err = mpin192::kangaroo(&e, &f); + if err != 0 { + println!("(Client PIN is out by {})", err) + } + } + return; + } else { + println!("Server says - PIN is good! You really are {}", name); + } + + if FULL { + let mut pxcid = None; + if PERMITS { + pxcid = Some(&xcid[..]) + }; + + mpin192::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin192::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck); + print!("Client Key = 0x"); + printbinary(&ck); + + mpin192::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin192::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk); + print!("Server Key = 0x"); + printbinary(&sk); + } +} + +#[test] +fn mpin_bls48() { + //use amcl::bls48; + use amcl::bls48::ecp; + use amcl::bls48::mpin256; + + let mut rng = create_rng(); + + pub const PERMITS: bool = true; + pub const PINERROR: bool = true; + pub const FULL: bool = true; + //pub const SINGLE_PASS:bool=false; + + const EFS: usize = mpin256::EFS; + const EGS: usize = mpin256::EGS; + + let mut s: [u8; EGS] = [0; EGS]; + const RM: usize = EFS as usize; + let mut hcid: [u8; RM] = [0; RM]; + let mut hsid: [u8; RM] = [0; RM]; + + const G1S: usize = 2 * EFS + 1; /* Group 1 Size */ + const G2S: usize = 16 * EFS; /* Group 2 Size */ + const EAS: usize = ecp::AESKEY; + + let mut sst: [u8; G2S] = [0; G2S]; + let mut token: [u8; G1S] = [0; G1S]; + let mut permit: [u8; G1S] = [0; G1S]; + let mut g1: [u8; 48 * EFS] = [0; 48 * EFS]; + let mut g2: [u8; 48 * EFS] = [0; 48 * EFS]; + let mut xid: [u8; G1S] = [0; G1S]; + let mut xcid: [u8; G1S] = [0; G1S]; + let mut x: [u8; EGS] = [0; EGS]; + let mut y: [u8; EGS] = [0; EGS]; + let mut sec: [u8; G1S] = [0; G1S]; + let mut r: [u8; EGS] = [0; EGS]; + let mut z: [u8; G1S] = [0; G1S]; + let mut hid: [u8; G1S] = [0; G1S]; + let mut htid: [u8; G1S] = [0; G1S]; + let mut rhid: [u8; G1S] = [0; G1S]; + let mut w: [u8; EGS] = [0; EGS]; + let mut t: [u8; G1S] = [0; G1S]; + let mut e: [u8; 48 * EFS] = [0; 48 * EFS]; + let mut f: [u8; 48 * EFS] = [0; 48 * EFS]; + let mut h: [u8; RM] = [0; RM]; + let mut ck: [u8; EAS] = [0; EAS]; + let mut sk: [u8; EAS] = [0; EAS]; + + let sha = ecp::HASH_TYPE; + + println!("\nTesting MPIN - PIN is 1234"); + /* Trusted Authority set-up */ + + mpin256::random_generate(&mut rng, &mut s); + print!("Master Secret s: 0x"); + printbinary(&s); + + /* Create Client Identity */ + let name = "[email protected]"; + let client_id = name.as_bytes(); + + print!("Client ID= "); + printbinary(&client_id); + + mpin256::hash_id(sha, &client_id, &mut hcid); /* Either Client or TA calculates Hash(ID) - you decide! */ + + /* Client and Server are issued secrets by DTA */ + mpin256::get_server_secret(&s, &mut sst); + print!("Server Secret SS: 0x"); + printbinary(&sst); + + mpin256::get_client_secret(&mut s, &hcid, &mut token); + print!("Client Secret CS: 0x"); + printbinary(&token); + + /* Client extracts PIN from secret to create Token */ + let pin: i32 = 1234; + println!("Client extracts PIN= {}", pin); + let mut rtn = mpin256::extract_pin(sha, &client_id, pin, &mut token); + if rtn != 0 { + println!("FAILURE: EXTRACT_PIN rtn: {}", rtn); + } + + print!("Client Token TK: 0x"); + printbinary(&token); + + if FULL { + mpin256::precompute(&token, &hcid, &mut g1, &mut g2); + } + + let mut date = 0; + if PERMITS { + date = mpin256::today(); + /* Client gets "Time Token" permit from DTA */ + + mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit); + print!("Time Permit TP: 0x"); + printbinary(&permit); + + /* This encoding makes Time permit look random - Elligator squared */ + mpin256::encoding(&mut rng, &mut permit); + print!("Encoded Time Permit TP: 0x"); + printbinary(&permit); + mpin256::decoding(&mut permit); + print!("Decoded Time Permit TP: 0x"); + printbinary(&permit); + } + + print!("\nPIN= "); + let _ = io::Write::flush(&mut io::stdout()); + let mut input_text = String::new(); + let _ = io::stdin().read_line(&mut input_text); + + let pin = input_text.trim().parse::<usize>().unwrap(); + + println!("MPIN Multi Pass"); + /* Send U=x.ID to server, and recreate secret from token and pin */ + rtn = mpin256::client_1( + sha, + date, + &client_id, + Some(&mut rng), + &mut x, + pin, + &token, + &mut sec, + Some(&mut xid[..]), + Some(&mut xcid[..]), + Some(&permit[..]), + ); + if rtn != 0 { + println!("FAILURE: CLIENT_1 rtn: {}", rtn); + } + + if FULL { + mpin256::hash_id(sha, &client_id, &mut hcid); + mpin256::get_g1_multiple(Some(&mut rng), 1, &mut r, &hcid, &mut z); /* Also Send Z=r.ID to Server, remember random r */ + } + + /* Server calculates H(ID) and H(T|H(ID)) (if time mpin256::PERMITS enabled), and maps them to points on the curve HID and HTID resp. */ + + mpin256::server_1(sha, date, &client_id, &mut hid, Some(&mut htid[..])); + + if date != 0 { + rhid.clone_from_slice(&htid[..]); + } else { + rhid.clone_from_slice(&hid[..]); + } + + /* Server generates Random number Y and sends it to Client */ + mpin256::random_generate(&mut rng, &mut y); + + if FULL { + mpin256::hash_id(sha, &client_id, &mut hsid); + mpin256::get_g1_multiple(Some(&mut rng), 0, &mut w, &rhid, &mut t); /* Also send T=w.ID to client, remember random w */ + } + + /* Client Second Pass: Inputs Client secret SEC, x and y. Outputs -(x+y)*SEC */ + rtn = mpin256::client_2(&x, &y, &mut sec); + if rtn != 0 { + println!("FAILURE: CLIENT_2 rtn: {}", rtn); + } + + /* Server Second pass. Inputs hashed client id, random Y, -(x+y)*SEC, xID and xCID and Server secret SST. E and F help kangaroos to find error. */ + /* If PIN error not required, set E and F = null */ + + if !PINERROR { + rtn = mpin256::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + None, + None, + ); + } else { + rtn = mpin256::server_2( + date, + &hid, + Some(&htid[..]), + &y, + &sst, + Some(&xid[..]), + Some(&xcid[..]), + &sec, + Some(&mut e), + Some(&mut f), + ); + } + + if rtn == mpin256::BAD_PIN { + println!("Server says - Bad Pin. I don't know you. Feck off."); + if PINERROR { + let err = mpin256::kangaroo(&e, &f); + if err != 0 { + println!("(Client PIN is out by {})", err) + } + } + return; + } else { + println!("Server says - PIN is good! You really are {}", name); + } + + if FULL { + let mut pxcid = None; + if PERMITS { + pxcid = Some(&xcid[..]) + }; + + mpin256::hash_all(sha, &hcid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin256::client_key(sha, &g1, &g2, pin, &r, &x, &h, &t, &mut ck); + print!("Client Key = 0x"); + printbinary(&ck); + + mpin256::hash_all(sha, &hsid, &xid, pxcid, &sec, &y, &z, &t, &mut h); + mpin256::server_key(sha, &z, &sst, &w, &h, &hid, &xid, pxcid, &mut sk); + print!("Server Key = 0x"); + printbinary(&sk); + } +} + +#[test] +fn rsa_2048() { + //use amcl::rsa2048; + use amcl::rsa2048::ff; + use amcl::rsa2048::rsa; + + let mut rng = create_rng(); + + let sha = rsa::HASH_TYPE; + let message: &[u8] = b"Hello World\n"; + const RFS: usize = rsa::RFS; + + let mut pbc = rsa::new_public_key(ff::FFLEN); + let mut prv = rsa::new_private_key(ff::HFLEN); + + let mut ml: [u8; RFS] = [0; RFS]; + let mut ms: [u8; RFS] = [0; RFS]; + let mut c: [u8; RFS] = [0; RFS]; + let mut s: [u8; RFS] = [0; RFS]; + let mut e: [u8; RFS] = [0; RFS]; + + println!("\nTesting RSA"); + println!("Generating public/private key pair"); + rsa::key_pair(&mut rng, 65537, &mut prv, &mut pbc); + + println!("Encrypting test string\n"); + rsa::oaep_encode(sha, &message, &mut rng, None, &mut e); /* OAEP encode message M to E */ + + rsa::encrypt(&pbc, &e, &mut c); /* encrypt encoded message */ + print!("Ciphertext= 0x"); + printbinary(&c); + + println!("Decrypting test string"); + rsa::decrypt(&prv, &c, &mut ml); + let mlen = rsa::oaep_decode(sha, None, &mut ml); /* OAEP decode message */ + + let mess = str::from_utf8(&ml[0..mlen]).unwrap(); + print!("{}", &mess); + + println!("Signing message"); + rsa::pkcs15(sha, message, &mut c); + + rsa::decrypt(&prv, &c, &mut s); /* create signature in S */ + + print!("Signature= 0x"); + printbinary(&s); + + rsa::encrypt(&pbc, &s, &mut ms); + + let mut cmp = true; + if c.len() != ms.len() { + cmp = false; + } else { + for j in 0..c.len() { + if c[j] != ms[j] { + cmp = false + } + } + } + if cmp { + println!("Signature is valid"); + } else { + println!("Signature is INVALID"); + } + + rsa::private_key_kill(&mut prv); +} diff --git a/tests/test_bls.rs b/tests/test_bls.rs new file mode 100644 index 0000000..20cf73b --- /dev/null +++ b/tests/test_bls.rs @@ -0,0 +1,190 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +extern crate amcl; + +use amcl::rand::RAND; + +pub fn printbinary(array: &[u8]) { + for i in 0..array.len() { + print!("{:02X}", array[i]) + } + println!("") +} + +fn create_rng() -> RAND { + let mut raw: [u8; 100] = [0; 100]; + + let mut rng = RAND::new(); + rng.clean(); + for i in 0..100 { + raw[i] = i as u8 + } + + rng.seed(100, &raw); + rng +} + +#[test] +fn bls_bn254() { + use amcl::bn254::bls; + + let mut rng = create_rng(); + + const BFS: usize = bls::BFS; + const BGS: usize = bls::BGS; + + let mut s: [u8; BGS] = [0; BGS]; + + const G1S: usize = BFS + 1; /* Group 1 Size */ + const G2S: usize = 4 * BFS; /* Group 2 Size */ + + let mut w: [u8; G2S] = [0; G2S]; + let mut sig: [u8; G1S] = [0; G1S]; + + let m = String::from("This is a test message"); + + bls::key_pair_generate(&mut rng, &mut s, &mut w); + print!("Private key : 0x"); + printbinary(&s); + print!("Public key : 0x"); + printbinary(&w); + + bls::sign(&mut sig, &m, &s); + print!("Signature : 0x"); + printbinary(&sig); + + let res = bls::verify(&sig, &m, &w); + if res == 0 { + println!("Signature is OK"); + } else { + println!("Signature is *NOT* OK"); + } +} + +#[test] +fn bls_bls383() { + use amcl::bls383::bls; + + let mut rng = create_rng(); + + const BFS: usize = bls::BFS; + const BGS: usize = bls::BGS; + + let mut s: [u8; BGS] = [0; BGS]; + + const G1S: usize = BFS + 1; /* Group 1 Size */ + const G2S: usize = 4 * BFS; /* Group 2 Size */ + + let mut w: [u8; G2S] = [0; G2S]; + let mut sig: [u8; G1S] = [0; G1S]; + + let m = String::from("This is a test message"); + + bls::key_pair_generate(&mut rng, &mut s, &mut w); + print!("Private key : 0x"); + printbinary(&s); + print!("Public key : 0x"); + printbinary(&w); + + bls::sign(&mut sig, &m, &s); + print!("Signature : 0x"); + printbinary(&sig); + + let res = bls::verify(&sig, &m, &w); + if res == 0 { + println!("Signature is OK"); + } else { + println!("Signature is *NOT* OK"); + } +} + +#[test] +fn bls_bls24() { + use amcl::bls24::bls192; + + let mut rng = create_rng(); + + const BFS: usize = bls192::BFS; + const BGS: usize = bls192::BGS; + + let mut s: [u8; BGS] = [0; BGS]; + + const G1S: usize = BFS + 1; /* Group 1 Size */ + const G2S: usize = 8 * BFS; /* Group 2 Size */ + + let mut w: [u8; G2S] = [0; G2S]; + let mut sig: [u8; G1S] = [0; G1S]; + + let m = String::from("This is a test message"); + + bls192::key_pair_generate(&mut rng, &mut s, &mut w); + print!("Private key : 0x"); + printbinary(&s); + print!("Public key : 0x"); + printbinary(&w); + + bls192::sign(&mut sig, &m, &s); + print!("Signature : 0x"); + printbinary(&sig); + + let res = bls192::verify(&sig, &m, &w); + if res == 0 { + println!("Signature is OK"); + } else { + println!("Signature is *NOT* OK"); + } +} + +#[test] +fn bls_bls48() { + use amcl::bls48::bls256; + + let mut rng = create_rng(); + + const BFS: usize = bls256::BFS; + const BGS: usize = bls256::BGS; + + let mut s: [u8; BGS] = [0; BGS]; + + const G1S: usize = BFS + 1; /* Group 1 Size */ + const G2S: usize = 16 * BFS; /* Group 2 Size */ + + let mut w: [u8; G2S] = [0; G2S]; + let mut sig: [u8; G1S] = [0; G1S]; + + let m = String::from("This is a test message"); + + bls256::key_pair_generate(&mut rng, &mut s, &mut w); + print!("Private key : 0x"); + printbinary(&s); + print!("Public key : 0x"); + printbinary(&w); + + bls256::sign(&mut sig, &m, &s); + print!("Signature : 0x"); + printbinary(&sig); + + let res = bls256::verify(&sig, &m, &w); + if res == 0 { + println!("Signature is OK"); + } else { + println!("Signature is *NOT* OK"); + } +} diff --git a/tests/test_nhs.rs b/tests/test_nhs.rs new file mode 100644 index 0000000..f272291 --- /dev/null +++ b/tests/test_nhs.rs @@ -0,0 +1,71 @@ +/* +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +*/ + +// Tests NewHope Simple API + +// See https://eprint.iacr.org/2016/1157 (Alkim, Ducas, Popplemann and Schwabe) + +extern crate amcl; + +use amcl::nhs; +use amcl::rand::RAND; + +#[test] +fn test_nhs() { + let mut raw: [u8; 100] = [0; 100]; + + let mut srng = RAND::new(); + srng.clean(); + for i in 0..100 { + raw[i] = (i + 1) as u8 + } + + srng.seed(100, &raw); + + let mut crng = RAND::new(); + crng.clean(); + for i in 0..100 { + raw[i] = (i + 2) as u8 + } + + crng.seed(100, &raw); + + let mut ss: [u8; 1792] = [0; 1792]; + let mut sb: [u8; 1824] = [0; 1824]; + let mut uc: [u8; 2176] = [0; 2176]; + + let mut keya: [u8; 32] = [0; 32]; + let mut keyb: [u8; 32] = [0; 32]; + + nhs::server_1(&mut srng, &mut sb, &mut ss); + + nhs::client(&mut crng, &sb, &mut uc, &mut keyb); + + nhs::server_2(&ss, &uc, &mut keya); + + for i in 0..keya.len() { + print!("{:02X}", keya[i]); + } + println!(""); + + for i in 0..keyb.len() { + print!("{:02X}", keyb[i]); + } + println!(""); +}
