| /* |
| 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 ecdh_ed25519(mut rng: &mut RAND) { |
| //use amcl::ed25519; |
| 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]; // 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 ") |
| } |
| } |
| } |
| |
| fn ecdh_nist256(mut rng: &mut RAND) { |
| //use amcl::nist256; |
| 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]; // 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 ") |
| } |
| } |
| } |
| |
| fn ecdh_goldilocks(mut rng: &mut RAND) { |
| //use amcl::goldilocks; |
| 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]; // 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 ") |
| } |
| } |
| } |
| |
| fn mpin_bn254(mut rng: &mut RAND) { |
| //use amcl::bn254; |
| use amcl::bn254::ecp; |
| use amcl::bn254::mpin; |
| 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 = "testUser@miracl.com"; |
| 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); |
| } |
| } |
| |
| fn mpin_bls383(mut rng: &mut RAND) { |
| //use amcl::bls383; |
| use amcl::bls383::ecp; |
| use amcl::bls383::mpin; |
| 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 = "testUser@miracl.com"; |
| 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); |
| } |
| } |
| |
| fn mpin_bls24(mut rng: &mut RAND) { |
| //use amcl::bls24; |
| use amcl::bls24::ecp; |
| use amcl::bls24::mpin192; |
| |
| 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 = "testUser@miracl.com"; |
| 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); |
| } |
| } |
| |
| fn mpin_bls48(mut rng: &mut RAND) { |
| //use amcl::bls48; |
| use amcl::bls48::ecp; |
| use amcl::bls48::mpin256; |
| |
| 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 = "testUser@miracl.com"; |
| 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); |
| } |
| } |
| |
| fn rsa_2048(mut rng: &mut RAND) { |
| //use amcl::rsa2048; |
| 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); /* 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); |
| } |
| |
| //#[test] |
| 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); |
| } |