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 ecdh_ed25519(mut rng: &mut RAND) {
use amcl::ed25519::ecdh;
use amcl::ed25519::ecp;
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]; 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
}
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);
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;
}
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;
}
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 ")
}
}
}
fn ecdh_nist256(mut rng: &mut RAND) {
use amcl::nist256::ecdh;
use amcl::nist256::ecp;
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]; 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
}
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);
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;
}
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;
}
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 ")
}
}
}
fn ecdh_goldilocks(mut rng: &mut RAND) {
use amcl::goldilocks::ecdh;
use amcl::goldilocks::ecp;
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]; 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
}
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);
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;
}
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;
}
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 ")
}
}
}
fn mpin_bn254(mut rng: &mut RAND) {
use amcl::bn254::ecp;
use amcl::bn254::mpin;
pub const PERMITS: bool = true;
pub const PINERROR: bool = true;
pub const FULL: bool = true;
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;
const G2S: usize = 4 * EFS;
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");
mpin::random_generate(&mut rng, &mut s);
print!("Master Secret s: 0x");
printbinary(&s);
let name = "testUser@miracl.com";
let client_id = name.as_bytes();
print!("Client ID= ");
printbinary(&client_id);
mpin::hash_id(sha, &client_id, &mut hcid);
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);
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();
mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
print!("Time Permit TP: 0x");
printbinary(&permit);
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");
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);
}
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[..]);
}
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);
}
rtn = mpin::client_2(&x, &y, &mut sec);
if rtn != 0 {
println!("FAILURE: CLIENT_2 rtn: {}", rtn);
}
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);
}
}
fn mpin_bls383(mut rng: &mut RAND) {
use amcl::bls383::ecp;
use amcl::bls383::mpin;
pub const PERMITS: bool = true;
pub const PINERROR: bool = true;
pub const FULL: bool = true;
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;
const G2S: usize = 4 * EFS;
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");
mpin::random_generate(&mut rng, &mut s);
print!("Master Secret s: 0x");
printbinary(&s);
let name = "testUser@miracl.com";
let client_id = name.as_bytes();
print!("Client ID= ");
printbinary(&client_id);
mpin::hash_id(sha, &client_id, &mut hcid);
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);
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();
mpin::get_client_permit(sha, date, &s, &hcid, &mut permit);
print!("Time Permit TP: 0x");
printbinary(&permit);
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");
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);
}
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[..]);
}
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);
}
rtn = mpin::client_2(&x, &y, &mut sec);
if rtn != 0 {
println!("FAILURE: CLIENT_2 rtn: {}", rtn);
}
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);
}
}
fn mpin_bls24(mut rng: &mut RAND) {
use amcl::bls24::ecp;
use amcl::bls24::mpin192;
pub const PERMITS: bool = true;
pub const PINERROR: bool = true;
pub const FULL: bool = true;
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;
const G2S: usize = 8 * EFS;
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");
mpin192::random_generate(&mut rng, &mut s);
print!("Master Secret s: 0x");
printbinary(&s);
let name = "testUser@miracl.com";
let client_id = name.as_bytes();
print!("Client ID= ");
printbinary(&client_id);
mpin192::hash_id(sha, &client_id, &mut hcid);
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);
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();
mpin192::get_client_permit(sha, date, &s, &hcid, &mut permit);
print!("Time Permit TP: 0x");
printbinary(&permit);
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");
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);
}
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[..]);
}
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);
}
rtn = mpin192::client_2(&x, &y, &mut sec);
if rtn != 0 {
println!("FAILURE: CLIENT_2 rtn: {}", rtn);
}
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);
}
}
fn mpin_bls48(mut rng: &mut RAND) {
use amcl::bls48::ecp;
use amcl::bls48::mpin256;
pub const PERMITS: bool = true;
pub const PINERROR: bool = true;
pub const FULL: bool = true;
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;
const G2S: usize = 16 * EFS;
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");
mpin256::random_generate(&mut rng, &mut s);
print!("Master Secret s: 0x");
printbinary(&s);
let name = "testUser@miracl.com";
let client_id = name.as_bytes();
print!("Client ID= ");
printbinary(&client_id);
mpin256::hash_id(sha, &client_id, &mut hcid);
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);
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();
mpin256::get_client_permit(sha, date, &s, &hcid, &mut permit);
print!("Time Permit TP: 0x");
printbinary(&permit);
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");
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);
}
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[..]);
}
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);
}
rtn = mpin256::client_2(&x, &y, &mut sec);
if rtn != 0 {
println!("FAILURE: CLIENT_2 rtn: {}", rtn);
}
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);
}
}
fn rsa_2048(mut rng: &mut RAND) {
use amcl::rsa2048::ff;
use amcl::rsa2048::rsa;
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);
rsa::encrypt(&pbc, &e, &mut c);
print!("Ciphertext= 0x");
printbinary(&c);
println!("Decrypting test string");
rsa::decrypt(&prv, &c, &mut ml);
let mlen = rsa::oaep_decode(sha, None, &mut ml);
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);
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);
}
fn main() {
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);
ecdh_ed25519(&mut rng);
ecdh_nist256(&mut rng);
ecdh_goldilocks(&mut rng);
mpin_bn254(&mut rng);
mpin_bls383(&mut rng);
mpin_bls24(&mut rng);
mpin_bls48(&mut rng);
rsa_2048(&mut rng);
}