| 
					
				 | 
			
			
				@@ -1,120 +1,167 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 //! Diffie-Hellmann key exchange 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use std::str::FromStr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use std::ops::{Add, Mul, Neg}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use bitcoin_hashes::sha256; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use bitcoin_hashes::Hash; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use secp256k1::rand::rngs::OsRng; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-use secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// use secp256k1::rand::rngs::OsRng; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// use secp256k1::{PublicKey, Scalar, Secp256k1, SecretKey}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use k256::Scalar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use k256::{AffinePoint, ProjectivePoint, PublicKey, Secp256k1, SecretKey}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+use rand::rngs::OsRng; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use crate::error::Error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use crate::types::MintKeys; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use crate::types::Promise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 use crate::types::Proof; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/// Hash to Curve 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-pub fn hash_to_curve(secret_message: &[u8]) -> Result<PublicKey, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let mut msg = secret_message.to_vec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn hash_to_curve(message: &[u8]) -> PublicKey { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let mut msg_to_hash = message.to_vec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     loop { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let hash = sha256::Hash::hash(&msg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let mut pubkey_bytes = vec![0x02]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pubkey_bytes.extend_from_slice(&hash[..]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        match PublicKey::from_slice(&pubkey_bytes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Ok(pubkey) => return Ok(pubkey), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            Err(_) => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                msg = hash.to_byte_array().to_vec(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let hash = sha256::Hash::hash(&msg_to_hash); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        match PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &[0x02u8] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .iter() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .chain(&hash.to_byte_array()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .cloned() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .collect::<Vec<u8>>(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Ok(pubkey) => return pubkey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            Err(_) => msg_to_hash = hash.to_byte_array().to_vec(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/// Blind Message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Blind Message Alice Step one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub fn blind_message( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     secret: &[u8], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     blinding_factor: Option<SecretKey>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) -> Result<(PublicKey, SecretKey), Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let y = hash_to_curve(secret)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let y = hash_to_curve(secret); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let secp = Secp256k1::new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     let r: SecretKey = match blinding_factor { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Some(sec_key) => sec_key, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        None => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            let (secret_key, _public_key) = secp.generate_keypair(&mut OsRng); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            secret_key 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        None => SecretKey::random(&mut rand::thread_rng()), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let b = y.combine(&r.public_key(&secp))?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let b = ProjectivePoint::from(y) + ProjectivePoint::from(&r.public_key()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Ok((b, r)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ok((PublicKey::try_from(b).unwrap(), r)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/// Unblind Message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Unblind Message (Alice Step 3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub fn unblind_message( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // C_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     blinded_key: PublicKey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     r: SecretKey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    a: PublicKey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // A 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mint_pubkey: PublicKey, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) -> Result<PublicKey, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let secp = Secp256k1::new(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let a_neg = a.negate(&secp); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let blinded_key = blinded_key.combine(&a_neg).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    let unblinded_key = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        blinded_key.mul_tweak(&secp, &Scalar::from_be_bytes(r.secret_bytes()).unwrap())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Ok(unblinded_key) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Unblinded message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let c = ProjectivePoint::from(blinded_key.as_affine()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        - mint_pubkey 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .as_affine() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .mul(Scalar::from(r.as_scalar_primitive())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ok(PublicKey::try_from(c).unwrap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Sign Blinded Message (Step2 bob) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Really only needed for mint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Used here for testing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn _sign_message(a: SecretKey, blinded_message: PublicKey) -> Result<PublicKey, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ok(PublicKey::try_from( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        blinded_message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .as_affine() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .mul(Scalar::from(a.as_scalar_primitive())), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    .unwrap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/// Verify Message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Really only needed for mint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// used for testing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+fn _verify_message(a: SecretKey, unblinded_message: PublicKey, msg: &str) -> Result<bool, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    let y = hash_to_curve(msg.as_bytes()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ok(unblinded_message 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        == PublicKey::try_from(*y.as_affine() * Scalar::from(a.as_scalar_primitive())).unwrap()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /// Construct Proof 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 pub fn construct_proof( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     promises: Vec<Promise>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     rs: Vec<SecretKey>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    secrets: Vec<Vec<u8>>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    secrets: Vec<String>, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     keys: &MintKeys, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ) -> Result<Vec<Proof>, Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     let mut proofs = vec![]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     for (i, promise) in promises.into_iter().enumerate() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let blinded_c = PublicKey::from_str(&promise.c)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let a: PublicKey = PublicKey::from_str(keys.0.get(&promise.amount.to_sat()).unwrap())?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let blinded_c = promise.c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let a: PublicKey = PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            keys.0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .get(&promise.amount.to_sat()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .to_owned() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .as_bytes(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // println!("Construct proof Pub {:?}", serde_json::to_string(&a)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        todo!(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let unblinded_signature = unblind_message(blinded_c, rs[i], a)?; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let proof = Proof { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             id: Some(promise.id), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             amount: promise.amount, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            secret: hex::encode(&secrets[i]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            c: unblinded_signature.to_string(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            secret: secrets[i].clone(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            c: unblinded_signature, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             script: None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         proofs.push(proof); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    println!("proofs: {:?}", proofs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Ok(proofs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+pub fn verify_proof(proof: Proof, keys: &MintKeys) -> Result<(), Error> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Ok(()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 #[cfg(test)] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 mod tests { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use hex::decode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    use std::str::FromStr; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    use k256::elliptic_curve::scalar::ScalarPrimitive; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     use super::*; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    use crate::utils::generate_secret; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn test_hash_to_curve() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let secret = "0000000000000000000000000000000000000000000000000000000000000000"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let sec_hex = decode(secret).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let y = hash_to_curve(&sec_hex).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let expected_y = PublicKey::from_str( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "0266687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let y = hash_to_curve(&sec_hex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expected_y = PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &hex::decode("0266687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq!(y, expected_y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let secret = "0000000000000000000000000000000000000000000000000000000000000001"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let sec_hex = decode(secret).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let y = hash_to_curve(&sec_hex).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let expected_y = PublicKey::from_str( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "02ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let y = hash_to_curve(&sec_hex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let expected_y = PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &hex::decode("02ec4916dd28fc4c10d78e287ca5d9cc51ee1ae73cbfde08c6b37324cbfaac8bc5") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq!(y, expected_y); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -123,42 +170,96 @@ mod tests { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn test_blind_message() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let message = "test_message"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let blinding_factor = "0000000000000000000000000000000000000000000000000000000000000001"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let sec = SecretKey::from_str(blinding_factor).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let sec = SecretKey::new(ScalarPrimitive::ONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let (b, r) = blind_message(message.as_bytes(), Some(sec)).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (b, r) = blind_message(message.as_bytes(), Some(sec.clone())).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            b.to_string(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2".to_string() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            b, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq!(r, sec); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn test_sign_message() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let message = "test_message"; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let sec = SecretKey::new(ScalarPrimitive::ONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let (blinded_message, _r) = blind_message(message.as_bytes(), Some(sec)).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // A 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let bob_sec = SecretKey::new(ScalarPrimitive::ONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // C_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let signed = _sign_message(bob_sec, blinded_message).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            signed, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     fn test_unblind_message() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let blinded_key = PublicKey::from_str( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let blinded_key = PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &hex::decode("02a9acc1e48c25eeeb9289b5031cc57da9fe72f3fe2861d264bdc074209b107ba2") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let r = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            SecretKey::from_str("0000000000000000000000000000000000000000000000000000000000000001") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        let a = PublicKey::from_str( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            "020000000000000000000000000000000000000000000000000000000000000001", 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let r = SecretKey::new(ScalarPrimitive::ONE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let a = PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            &hex::decode("020000000000000000000000000000000000000000000000000000000000000001") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                .unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         .unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         let unblinded = unblind_message(blinded_key, r, a).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert_eq!( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            PublicKey::from_str( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                "03c724d7e6a5443b39ac8acf11f40420adc4f99a02e7cc1b57703d9391f6d129cd" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            PublicKey::from_sec1_bytes( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                &hex::decode("03c724d7e6a5443b39ac8acf11f40420adc4f99a02e7cc1b57703d9391f6d129cd") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    .unwrap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             .unwrap(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             unblinded 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    #[test] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fn test_blinded_dhke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let bob_sec = SecretKey::random(&mut rand::thread_rng()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // A 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let bob_pub = bob_sec.public_key(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // let alice_sec = SecretKey::random(&mut rand::thread_rng()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let x = generate_secret(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let y = hash_to_curve(x.as_bytes()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // B_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let blinded = blind_message(&y.to_sec1_bytes(), None).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // C_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let signed = _sign_message(bob_sec.clone(), blinded.0).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        let c = unblind_message(signed, blinded.1, bob_pub).unwrap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        assert!(_verify_message(bob_sec, c, &x).unwrap()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 |