From 82839ccbee988a3d8fe147162ca8a30c84062a9a Mon Sep 17 00:00:00 2001 From: "J. Ayo Akinyele" Date: Fri, 29 Nov 2019 12:49:05 -0500 Subject: [PATCH] add more routines to wtp_utils --- src/cl.rs | 18 ++++++++++++++-- src/lib.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 73 insertions(+), 5 deletions(-) diff --git a/src/cl.rs b/src/cl.rs index 59054c3..c00d255 100644 --- a/src/cl.rs +++ b/src/cl.rs @@ -26,10 +26,11 @@ impl PublicParams { where ::G1: serde::Deserialize<'de>, ::G2: serde::Deserialize<'de> { + // TODO: handle malformed input errors let g1: E::G1 = serde_json::from_slice(ser_g1).unwrap(); let g2: E::G2 = serde_json::from_slice(ser_g2).unwrap(); - return PublicParams { g1, g2 }; + PublicParams { g1, g2 } } } @@ -99,7 +100,7 @@ impl PublicKey { end_pos += y_len; Y.push(y); } - return PublicKey { X, Y }; + PublicKey { X, Y } } } @@ -147,6 +148,19 @@ impl PartialEq for Signature { } } +impl Signature { + pub fn from_slice<'de>(ser_h: &'de [u8], ser_H: &'de [u8]) -> Self + where ::G1: serde::Deserialize<'de> + { + // TODO: handle malformed input errors + let h: E::G1 = serde_json::from_slice(ser_h).unwrap(); + let H: E::G1 = serde_json::from_slice(ser_H).unwrap(); + + Signature { h, H } + } +} + + #[derive(Clone)] pub struct KeyPair { pub secret: SecretKey, diff --git a/src/lib.rs b/src/lib.rs index f40dea3..9aa7a17 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -509,8 +509,9 @@ pub mod wtp_utils { // Useful routines that simplify the Bolt WTP implementation for Zcash use pairing::bls12_381::Bls12; use ::{util, BoltResult}; - use cl::{PublicKey, PublicParams}; + use cl; use ped92::CSMultiParams; + pub use cl::Signature; pub use channels::ChannelToken; pub use wallet::Wallet; @@ -532,6 +533,28 @@ pub mod wtp_utils { } } + pub fn reconstruct_signature_bls12(sig: &Vec) -> BoltResult> { + if (sig.len() != BLS12_381_G1_LEN * 2) { + return Err(String::from("signature has invalid length")); + } + + let mut cur_index = 0; + let mut end_index = BLS12_381_G1_LEN; + let ser_cl_h = sig[cur_index .. end_index].to_vec(); + let str_cl_h = util::encode_as_hexstring(&ser_cl_h); + let h = str_cl_h.as_bytes(); + + cur_index = end_index; + end_index += BLS12_381_G1_LEN; + let ser_cl_H = sig[cur_index .. end_index].to_vec(); + let str_cl_H = util::encode_as_hexstring(&ser_cl_H); + let H = str_cl_H.as_bytes(); + + let cl_sig = cl::Signature::::from_slice(&h, &H); + + Ok(Some(cl_sig)) + } + pub fn reconstruct_channel_token_bls12(channel_token: &Vec) -> BoltResult> { // parse pkc, pkm, pkM, mpk and comParams @@ -565,7 +588,7 @@ pub mod wtp_utils { let str_cl_y = ser_cl_y.as_bytes(); Y.extend(str_cl_y); } - let cl_pk= PublicKey::::from_slice(&X, &Y.as_slice(), str_cl_x.len(), num_y_elems); + let cl_pk= cl::PublicKey::::from_slice(&X, &Y.as_slice(), str_cl_x.len(), num_y_elems); cur_index = end_index; end_index += BLS12_381_G1_LEN; @@ -580,7 +603,7 @@ pub mod wtp_utils { let ser_g1 = ser_mpk_g1.as_bytes(); let ser_g2 = ser_mpk_g2.as_bytes(); - let mpk = PublicParams::::from_slice(&ser_g1, &ser_g2); + let mpk = cl::PublicParams::::from_slice(&ser_g1, &ser_g2); let mut comparams = Vec::new(); for _ in 0 .. num_com_params { @@ -599,6 +622,24 @@ pub mod wtp_utils { })) } + /// + /// Used in open-channel WTP for validating that a close_token is a valid signature + /// + pub fn wtp_verify_cust_close_message(channel_token: &ChannelToken, wpk: &secp256k1::PublicKey, + close_msg: &Wallet, close_token: &cl::Signature) -> bool { + // close_msg => || || || || CLOSE + // close_token = regular CL signature on close_msg + // channel_token => + + // (1) check that channel token and close msg are consistent (e.g., close_msg.channelId == H(channel_token.pk_c) && + let chan_token_cid = channel_token.compute_channel_id(); // util::hash_pubkey_to_fr::(&pk_c); + let chan_token_wpk = util::hash_pubkey_to_fr::(&wpk); + + let cid_thesame = (close_msg.channelId == chan_token_cid); + // (2) check that wpk matches what's in the close msg + let wpk_thesame = (close_msg.wpk == chan_token_wpk); + return cid_thesame && wpk_thesame && channel_token.cl_pk_m.verify(&channel_token.mpk, &close_msg.as_fr_vec(), &close_token); + } } #[cfg(all(test, feature = "unstable"))] @@ -1032,5 +1073,18 @@ mod tests { println!("pkm: {:?}", channel_token.pk_m); assert_eq!(original_channelId, computed_channelId); + + // reconstruct signature + let _ser_signature = "93f26490b4576c38dfb8dceae547f4b49aeb945ecc9cccc528c39068c78177bda68aaf45743f09c48ad99b6007fe415b\ + aee9eafd51cfdb0dc567a5d152bc37861727e85088b417cf3ff57c108d0156eee56aff810f1e5f9e76cd6a3590d6db5e"; + let ser_signature = hex::decode(_ser_signature).unwrap(); + + let option_sig = wtp_utils::reconstruct_signature_bls12(&ser_signature); + + let sig = match option_sig { + Ok(n) => n.unwrap(), + Err(e) => panic!("Error reconstructing compact rep of signature: {}", e) + }; + } }