diff --git a/api/src/lib.rs b/api/src/lib.rs index 157fee7..22f12fa 100644 --- a/api/src/lib.rs +++ b/api/src/lib.rs @@ -3,7 +3,6 @@ pub mod response; pub mod transfer; extern crate crypto; extern crate identity; -extern crate core; use crypto::qubic_identities::get_public_key_from_identity; use crate::header::{ EntityType, RequestResponseHeader }; @@ -112,8 +111,10 @@ pub mod api_formatting_tests { let mut req = QubicApiPacket::get_identity_balance("EPYWDREDNLHXOFYVGQUKPHJGOMPBSLDDGZDPKVQUMFXAIQYMZGEHPZTAAWON"); req.header.zero_dejavu(); //Dejavu is random 3 byte value let bytes = req.as_bytes(); - assert_eq!(bytes.len(), 68); + println!("{:?}", &bytes); + assert_eq!(bytes.len(), 40); assert_eq!(bytes.as_slice(), - vec![68, 0, 0, 0, 0, 0, 0, 31, 69, 80, 89, 87, 68, 82, 69, 68, 78, 76, 72, 88, 79, 70, 89, 86, 71, 81, 85, 75, 80, 72, 74, 71, 79, 77, 80, 66, 83, 76, 68, 68, 71, 90, 68, 80, 75, 86, 81, 85, 77, 70, 88, 65, 73, 81, 89, 77, 90, 71, 69, 72, 80, 90, 84, 65, 65, 87, 79, 78]); + vec![40, 0, 0, 31, 0, 0, 0, 0, 170, 135, 62, 76, 253, 55, 228, 191, 82, 138, 42, 160, 30, 236, 239, 54, 84, 124, 153, 202, 170, 189, 27, 189, 247, 37, 58, 101, 176, 65, 119, 26] + ); } } \ No newline at end of file diff --git a/api/src/transfer.rs b/api/src/transfer.rs index b126a7c..03470fe 100644 --- a/api/src/transfer.rs +++ b/api/src/transfer.rs @@ -1,17 +1,7 @@ -use std::ffi::c_uchar; use identity::Identity; use crypto::hash::k12_bytes; -use crypto::qubic_identities::{ get_subseed, get_public_key_from_identity }; +use crypto::qubic_identities::{get_subseed, get_public_key_from_identity, sign_raw}; use logger::info; -extern { - //extern ECCRYPTO_STATUS SchnorrQ_Sign(const unsigned char* SecretKey, const unsigned char* PublicKey, const unsigned char* Message, const unsigned int SizeMessage, unsigned char* Signature); - fn sign(subseed: *const u8, publicKey: *const c_uchar, messageDigest: *const c_uchar, signature: *mut c_uchar); - //fn SchnorrQ_Sign(subseed: *const u8, publicKey: *const c_uchar, messageDigest: *const c_uchar, SizeMessage: u32, signature: *mut c_uchar); - fn getSubseed(seed: *const c_uchar, subseed: *mut c_uchar) -> bool; - //bool getSubseed(const unsigned char* seed, unsigned char* subseed) - //void sign(const unsigned char* subseed, const unsigned char* publicKey, const unsigned char* messageDigest, unsigned char* signature) -} - #[derive(Debug, Clone)] pub struct TransferTransaction { @@ -38,6 +28,7 @@ impl TransferTransaction { Ok(pub_key) => pub_key, Err(err) => panic!("{:?}", err) }; + println!("{} -> {:?}", source_identity.identity.as_str(), &pub_key_src); let pub_key_dest = match get_public_key_from_identity(&String::from(dest)) { Ok(pub_key) => pub_key, Err(err) => panic!("{:?}", err) @@ -56,14 +47,10 @@ impl TransferTransaction { let digest: Vec = k12_bytes(&t.as_bytes_without_signature()); //let mut sub_seed: [u8; 32] = [0; 32]; let mut sub_seed: Vec = get_subseed(source_identity.seed.as_str()).expect("Failed To Get SubSeed!"); - unsafe { - getSubseed(source_identity.seed.as_str().as_ptr(), sub_seed.as_mut_ptr()); - } let mut sig: [u8; 64] = [0; 64]; - unsafe { - sign(sub_seed.as_slice().as_ptr(), pub_key_src.as_ptr(), digest.as_ptr(), sig.as_mut_ptr()); - //SchnorrQ_Sign(sub_seed.as_ptr(), pub_key_src.as_ptr(), digest.as_ptr(), 32, sig.as_mut_ptr()); - } + + sig = sign_raw(&sub_seed, &pub_key_src, digest.as_slice().try_into().unwrap()); + println!("Signed Signature: {:?}", sig); t._signature = sig.to_vec(); t } @@ -132,9 +119,27 @@ impl TransferTransaction { #[test] fn create_transfer() { let id: Identity = Identity::new("lcehvbvddggkjfnokduyjuiyvkklrvrmsaozwbvjlzvgvfipqpnkkuf"); - let t: TransferTransaction = TransferTransaction::from_vars(&id, "EPYWDREDNLHXOFYVGQUKPHJGOMPBSLDDGZDPKVQUMFXAIQYMZGEHPZTAAWON", 100, 100); - let expected: Vec = vec![170, 135, 62, 76, 253, 55, 228, 191, 82, 138, 42, 160, 30, 236, 239, 54, 84, 124, 153, 202, 170, 189, 27, 189, 247, 37, 58, 101, 176, 65, 119, 26, 170, 135, 62, 76, 253, 55, 228, 191, 82, 138, 42, 160, 30, 236, 239, 54, 84, 124, 153, 202, 170, 189, 27, 189, 247, 37, 58, 101, 176, 65, 119, 26, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 110, 0, 0, 0, 105, 55, 108, 214, 255, 246, 151, 81, 6, 214, 129, 65, 96, 14, 146, 66, 206, 140, 212, 149, 217, 230, 189, 217, 106, 16, 216, 3, 208, 51, 185, 179, 25, 89, 215, 168, 85, 62, 9, 204, 52, 238, 245, 199, 48, 2, 43, 52, 117, 72, 109, 119, 84, 236, 135, 240, 56, 179, 194, 36, 96, 124, 32, 0]; + let t: TransferTransaction = TransferTransaction::from_vars(&id, "EPYWDREDNLHXOFYVGQUKPHJGOMPBSLDDGZDPKVQUMFXAIQYMZGEHPZTAAWON", 100, 80); + let expected: Vec = vec![ + //source pub key: u32 + 170, 135, 62, 76, 253, 55, 228, 191, 82, 138, 42, 160, 30, 236, 239, 54, 84, 124, 153, 202, 170, 189, 27, 189, 247, 37, 58, 101, 176, 65, 119, 26, + //dest pub key: u32 + 170, 135, 62, 76, 253, 55, 228, 191, 82, 138, 42, 160, 30, 236, 239, 54, 84, 124, 153, 202, 170, 189, 27, 189, 247, 37, 58, 101, 176, 65, 119, 26, + //amount: u64 + 100, 0, 0, 0, 0, 0, 0, 0, + //tick: u32 + 110, 0, 0, 0, + //input type: u16 + 0, 0, + //input size: u16 + 0, 0, + //signature: u64 + 179, 108, 100, 1, 209, 21, 45, 198, 110, 190, 137, 194, 107, 157, 36, 76, 124, 94, 142, 45, 125, 220, 238, 70, 17, 253, 181, 125, 147, 192, 126, + 93, 7, 155, 196, 186, 185, 143, 220, 131, 215, 170, 241, 92, 83, 71, 181, 143, 107, 62, 90, 232, 10, 164, 55, 202, 24, 189, 84, 156, 203, 51, 27, 0 + ]; + assert_eq!(t.as_bytes().as_slice(), expected.as_slice()); + } diff --git a/crypto/src/fourq/ops.rs b/crypto/src/fourq/ops.rs index afde1a3..9aab9cb 100644 --- a/crypto/src/fourq/ops.rs +++ b/crypto/src/fourq/ops.rs @@ -35,7 +35,7 @@ use crate::{ }}; #[inline(always)] -fn addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { +pub fn addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { #[cfg(target_arch = "x86_64")] unsafe { _addcarry_u64(c_in, a, b, out) @@ -53,7 +53,7 @@ fn addcarry_u64(c_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { } #[inline(always)] -fn subborrow_u64(b_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { +pub fn subborrow_u64(b_in: u8, a: u64, b: u64, out: &mut u64) -> u8 { #[cfg(target_arch = "x86_64")] unsafe { _subborrow_u64(b_in, a, b, out) @@ -212,7 +212,7 @@ pub fn fp2div1271(a: &mut F2elmT) { let mut mask: u64; let mut temp = [0u64; 2]; - mask = 0 - (1 & a[0][0]); + mask = 0u64.wrapping_sub((1 & a[0][0])); addcarry_u64(addcarry_u64(0, a[0][0], mask, &mut temp[0]), a[0][1], mask >> 1, &mut temp[1]); a[0][0] = __shiftright128(temp[0], temp[1], 1); a[0][1] = temp[1] >> 1; diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs index d358737..cc60066 100644 --- a/crypto/src/lib.rs +++ b/crypto/src/lib.rs @@ -1,6 +1,5 @@ #![feature(ascii_char)] #![feature(ascii_char_variants)] - mod fourq; const A_LOWERCASE_ASCII: u8 = 97u8; @@ -37,9 +36,12 @@ pub mod hash { pub mod qubic_identities { + use core::{ptr::copy_nonoverlapping, fmt::{Debug, Display}, str::FromStr}; + use tiny_keccak::{Hasher, IntoXof, KangarooTwelve, Xof}; use crate::{A_LOWERCASE_ASCII, hash}; use hash::k12_bytes; - use crate::fourq::ops::{ecc_mul_fixed, encode}; + use crate::fourq::consts::{CURVE_ORDER_0, CURVE_ORDER_1, CURVE_ORDER_2, CURVE_ORDER_3, MONTGOMERY_R_PRIME, ONE}; + use crate::fourq::ops::{addcarry_u64, ecc_mul_fixed, encode, montgomery_multiply_mod_order, subborrow_u64}; use crate::fourq::types::{PointAffine}; // fn getPublicKey(privateKey: *const u8, publicKey: *mut u8); @@ -142,9 +144,81 @@ pub mod qubic_identities { Ok(public_key) } + pub fn sign_raw(subseed: &Vec, public_key: &[u8; 32], message_digest: [u8; 32]) -> [u8; 64] { + + println!("Got Subseed: {:?}", subseed); + println!("Got Public Key: {:?}", public_key); + println!("Got Message Digest: {:?}", &message_digest); + + let mut r_a = PointAffine::default(); + let (mut k, mut h, mut temp) = ([0u8; 64], [0u8; 64], [0u8; 96]); + let mut r = [0u8; 64]; + + + let mut kg = KangarooTwelve::new(b""); + kg.update(subseed.as_slice()); + kg.into_xof().squeeze(&mut k); + + let mut signature = [0u8; 64]; + + unsafe { + copy_nonoverlapping(k.as_ptr().offset(32), temp.as_mut_ptr().offset(32), 32); + copy_nonoverlapping(message_digest.as_ptr(), temp.as_mut_ptr().offset(64), 32); + + + let mut kg = KangarooTwelve::new(b""); + kg.update(&temp[32..]); + let mut im = [0u8; 64]; + kg.into_xof().squeeze(&mut im); + + copy_nonoverlapping(im.as_ptr(), r.as_mut_ptr(), 64); + let k: [u64; 8] = k.chunks_exact(8).map(|c| u64::from_le_bytes(c.try_into().unwrap())).collect::>().try_into().unwrap(); + let mut r: [u64; 8] = r.chunks_exact(8).map(|c| u64::from_le_bytes(c.try_into().unwrap())).collect::>().try_into().unwrap(); + ecc_mul_fixed(&r, &mut r_a); + + encode(&mut r_a, &mut signature); + let mut signature_i: [u64; 8] = signature.chunks_exact(8).map(|c| u64::from_le_bytes(c.try_into().unwrap())).collect::>().try_into().unwrap(); + + copy_nonoverlapping(signature_i.as_ptr() as *mut u8, temp.as_mut_ptr(), 32); + copy_nonoverlapping(public_key.as_ptr(), temp.as_mut_ptr().offset(32), 32); + + + let mut kg = KangarooTwelve::new(b""); + kg.update(&temp); + kg.into_xof().squeeze(&mut h); + + let mut h: [u64; 8] = h.chunks_exact(8).map(|c| u64::from_le_bytes(c.try_into().unwrap())).collect::>().try_into().unwrap(); + let r_i = r; + montgomery_multiply_mod_order(&r_i, &MONTGOMERY_R_PRIME, &mut r); + let r_i = r; + montgomery_multiply_mod_order(&r_i, &ONE, &mut r); + let h_i = h; + montgomery_multiply_mod_order(&h_i, &MONTGOMERY_R_PRIME, &mut h); + let h_i = h; + montgomery_multiply_mod_order(&h_i, &ONE, &mut h); + montgomery_multiply_mod_order(&k, &MONTGOMERY_R_PRIME, &mut signature_i[4..]); + let h_i = h; + montgomery_multiply_mod_order(&h_i, &MONTGOMERY_R_PRIME, &mut h); + let mut s_i = [0u64; 4]; + s_i.copy_from_slice(&signature_i[4..]); + montgomery_multiply_mod_order(&s_i, &h, &mut signature_i[4..]); + s_i.copy_from_slice(&signature_i[4..]); + montgomery_multiply_mod_order(&s_i, &ONE, &mut signature_i[4..]); + + if subborrow_u64(subborrow_u64(subborrow_u64(subborrow_u64(0, r[0], signature_i[4], &mut signature_i[4]), r[1], signature_i[5], &mut signature_i[5]), r[2], signature_i[6], &mut signature_i[6]), r[3], signature_i[7], &mut signature_i[7]) != 0 { + addcarry_u64(addcarry_u64(addcarry_u64(addcarry_u64(0, signature_i[4], CURVE_ORDER_0, &mut signature_i[4]), signature_i[5], CURVE_ORDER_1, &mut signature_i[5]), signature_i[6], CURVE_ORDER_2, &mut signature_i[6]),signature_i[7], CURVE_ORDER_3, &mut signature_i[7]); + } + + signature = signature_i.into_iter().flat_map(u64::to_le_bytes).collect::>().try_into().unwrap(); + } + signature + } + + #[cfg(test)] pub mod qubic_identity_primitive_tests { - use crate::qubic_identities::{get_identity, get_private_key, get_public_key, get_public_key_from_identity, get_subseed}; + use crate::hash::k12_bytes; + use crate::qubic_identities::{get_identity, get_private_key, get_public_key, get_public_key_from_identity, get_subseed, sign_raw}; #[test] fn get_a_subseed() { let seed = "lcehvbvddggkjfnokduyjuiyvkklrvrmsaozwbvjlzvgvfipqpnkkuf"; @@ -189,6 +263,23 @@ pub mod qubic_identities { assert_eq!(public_key, pub_key_from_id) } + + #[test] + fn test_sign_a_message() { + let seed = "lcehvbvddggkjfnokduyjuiyvkklrvrmsaozwbvjlzvgvfipqpnkkuf"; + let message: [u8; 32] = [1; 32]; + let digest = k12_bytes(&message.to_vec()); + let subseed = get_subseed(seed).unwrap(); + let private_key = get_private_key(&subseed); + let public_key = get_public_key(&private_key); + let identity = get_identity(&public_key); + let pub_key_from_id = get_public_key_from_identity(&identity).unwrap(); + let result = sign_raw(&subseed, &public_key, <[u8; 32]>::try_from(digest.as_slice()).expect("Failed!")); + println!("{:?}", result); + assert_eq!(public_key, pub_key_from_id) + } + + } } diff --git a/network/src/bin/bin.rs b/network/src/bin/bin.rs deleted file mode 100644 index 820c243..0000000 --- a/network/src/bin/bin.rs +++ /dev/null @@ -1,35 +0,0 @@ -use std::time::Duration; -use std::thread::sleep; -use std::io::prelude::*; -use std::net::TcpStream; -extern crate api; -extern crate network; -extern crate crypto; -use api::qubic_api_t; -use network::peers::{PeerStrategy, PeerSet}; - -fn main() { - //let peer_ips = vec!["85.10.199.154:21841", "148.251.184.163:21841"]; - let peer_ips = vec!["85.10.199.154:21841"]; - println!("Creating Peer Set"); - let mut peer_set = PeerSet::new(PeerStrategy::RANDOM); - for ip in peer_ips { - println!("Adding Peer {}", ip); - peer_set.add_peer(ip); - println!("Peer Added"); - } - println!("Number Of Peers: {}", peer_set.num_peers()); - let delay = Duration::from_secs(3); - - - loop { - let mut request = qubic_api_t::get_identity_balance("BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARMID"); - match peer_set.make_request(request) { - Ok(_) => {}, - //Ok(_) => println!("{:?}", request.response_data), - Err(err) => println!("{}", err) - } - sleep(delay); - } - -} \ No newline at end of file