From 32cb801fc7b28b195bbf176b70bc50363af47e88 Mon Sep 17 00:00:00 2001 From: Lucas Soriano del Pino Date: Tue, 11 May 2021 21:14:13 +1000 Subject: [PATCH] Add 0 bytes to end of domain tags (and other debugging) --- monero-adaptor/Cargo.toml | 1 + monero-adaptor/src/clsag.rs | 99 ++++++++++++++++++++---- monero-adaptor/tests/integration_test.rs | 69 +++++++++++------ 3 files changed, 130 insertions(+), 39 deletions(-) diff --git a/monero-adaptor/Cargo.toml b/monero-adaptor/Cargo.toml index f9d283cc..e97f1fba 100644 --- a/monero-adaptor/Cargo.toml +++ b/monero-adaptor/Cargo.toml @@ -11,6 +11,7 @@ rand = "0.7" tiny-keccak = { version = "2", features = ["keccak"] } hash_edwards_to_edwards = { git = "https://github.com/comit-network/hash_edwards_to_edwards" } monero = "0.12" +hex = "0.4" [dev-dependencies] hex = "0.4" diff --git a/monero-adaptor/src/clsag.rs b/monero-adaptor/src/clsag.rs index 494c2063..98312024 100644 --- a/monero-adaptor/src/clsag.rs +++ b/monero-adaptor/src/clsag.rs @@ -32,24 +32,41 @@ pub fn sign( let commitment_ring = Ring::new(commitment_ring); let mu_P = hash_to_scalar!( - b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment + b"CLSAG_agg_0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + || ring + || commitment_ring + || I + || D_inv_8 + || pseudo_output_commitment ); let mu_C = hash_to_scalar!( - b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment + b"CLSAG_agg_1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + || ring + || commitment_ring + || I + || D_inv_8 + || pseudo_output_commitment ); + dbg!(hex::encode(mu_P.as_bytes())); + dbg!(hex::encode(mu_C.as_bytes())); + let adjusted_commitment_ring = &commitment_ring - pseudo_output_commitment; let compute_ring_element = |L: EdwardsPoint, R: EdwardsPoint| { hash_to_scalar!( - b"CLSAG_round" || ring || commitment_ring || pseudo_output_commitment || msg || L || R + b"CLSAG_round\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + || ring + || commitment_ring + || pseudo_output_commitment + || msg + || L + || R ) }; let h_0 = compute_ring_element(L_0, R_0); - dbg!(h_0); - let h_last = fake_responses .iter() .enumerate() @@ -66,7 +83,13 @@ pub fn sign( ); let R_i = compute_R(h_prev, mu_P, mu_C, *s_i, pk_i, I, D_inv_8); - compute_ring_element(L_i, R_i) + dbg!(hex::encode(L_i.compress().as_bytes())); + dbg!(hex::encode(R_i.compress().as_bytes())); + + let h = compute_ring_element(L_i, R_i); + dbg!(hex::encode(h.as_bytes())); + + h }); let s_last = alpha - h_last * ((mu_P * signing_key) + (mu_C * z)); @@ -110,10 +133,20 @@ pub fn verify( let D = D_inv_8 * Scalar::from(8u8); let mu_P = hash_to_scalar!( - b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment + b"CLSAG_agg_0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + || ring + || commitment_ring + || I + || D_inv_8 + || pseudo_output_commitment ); let mu_C = hash_to_scalar!( - b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment + b"CLSAG_agg_1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + || ring + || commitment_ring + || I + || D_inv_8 + || pseudo_output_commitment ); let adjusted_commitment_ring = &commitment_ring - pseudo_output_commitment; @@ -134,7 +167,7 @@ pub fn verify( let R_i = compute_R(h, mu_P, mu_C, *s_i, pk_i, I, D); h = hash_to_scalar!( - b"CLSAG_round" + b"CLSAG_round\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" || ring || commitment_ring || pseudo_output_commitment @@ -147,6 +180,7 @@ pub fn verify( h == h_0 } +#[derive(Clone, Debug)] pub struct Signature { pub responses: [Scalar; RING_SIZE], pub h_0: Scalar, @@ -257,7 +291,9 @@ impl<'a> Index for Ring<'a> { #[cfg(test)] mod tests { use super::*; + use itertools::Itertools; use rand::rngs::OsRng; + use rand::SeedableRng; #[test] fn const_is_inv_eight() { @@ -268,21 +304,23 @@ mod tests { #[test] fn sign_and_verify() { + let mut rng = rand::rngs::StdRng::from_seed([0u8; 32]); + let msg_to_sign = b"hello world, monero is amazing!!"; - let signing_key = Scalar::random(&mut OsRng); + let signing_key = Scalar::random(&mut rng); let signing_pk = signing_key * ED25519_BASEPOINT_POINT; let H_p_pk = hash_point_to_point(signing_pk); - let alpha = Scalar::random(&mut OsRng); + let alpha = Scalar::random(&mut rng); - let mut ring = random_array(|| Scalar::random(&mut OsRng) * ED25519_BASEPOINT_POINT); + let mut ring = random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT); ring[0] = signing_pk; - let real_commitment_blinding = Scalar::random(&mut OsRng); + let real_commitment_blinding = Scalar::random(&mut rng); let mut commitment_ring = - random_array(|| Scalar::random(&mut OsRng) * ED25519_BASEPOINT_POINT); - commitment_ring[0] = real_commitment_blinding * ED25519_BASEPOINT_POINT; /* + 0 * H */ + random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT); + commitment_ring[0] = real_commitment_blinding * ED25519_BASEPOINT_POINT; // + 0 * H // TODO: document let pseudo_output_commitment = commitment_ring[0]; @@ -294,7 +332,7 @@ mod tests { alpha, &ring, &commitment_ring, - random_array(|| Scalar::random(&mut OsRng)), + random_array(|| Scalar::random(&mut rng)), Scalar::zero(), pseudo_output_commitment, alpha * ED25519_BASEPOINT_POINT, @@ -302,6 +340,35 @@ mod tests { signing_key * H_p_pk, ); + signature.responses.iter().enumerate().for_each(|(i, res)| { + println!( + r#"epee::string_tools::hex_to_pod("{}", clsag.s[{}]);"#, + hex::encode(res.as_bytes()), + i + ); + }); + println!("{}", hex::encode(signature.h_0.as_bytes())); + println!("{}", hex::encode(signature.D.compress().as_bytes())); + + let I = hex::encode(signature.I.compress().to_bytes()); + println!("{}", I); + + let msg = hex::encode(msg_to_sign); + println!("{}", msg); + + ring.iter().zip(commitment_ring.iter()).for_each(|(pk, c)| { + println!( + "std::make_tuple(\"{}\",\"{}\"),", + hex::encode(pk.compress().to_bytes()), + hex::encode(c.compress().to_bytes()) + ); + }); + + println!( + "{}", + hex::encode(pseudo_output_commitment.compress().to_bytes()) + ); + assert!(verify( &signature, msg_to_sign, diff --git a/monero-adaptor/tests/integration_test.rs b/monero-adaptor/tests/integration_test.rs index 3e63e060..404e981f 100644 --- a/monero-adaptor/tests/integration_test.rs +++ b/monero-adaptor/tests/integration_test.rs @@ -1,7 +1,7 @@ #![allow(non_snake_case)] use curve25519_dalek::constants::ED25519_BASEPOINT_POINT; -use curve25519_dalek::edwards::{CompressedEdwardsY}; +use curve25519_dalek::edwards::CompressedEdwardsY; use curve25519_dalek::scalar::Scalar; use hash_edwards_to_edwards::hash_point_to_point; use monero::blockdata::transaction::{ExtraField, KeyImage, SubField, TxOutTarget}; @@ -145,11 +145,10 @@ async fn monerod_integration_test() { let ecdh_key_1 = PrivateKey::random(&mut rng); let (ecdh_info_1, out_blinding_1) = EcdhInfo::new_bulletproof(spend_amount, ecdh_key_1.scalar); - let (bulletproof, out_pk) = monero::make_bulletproof( - &mut rng, - &[spend_amount, 0], - &[out_blinding_0, out_blinding_1], - ) + let (bulletproof, out_pk) = monero::make_bulletproof(&mut rng, &[spend_amount, 0], &[ + out_blinding_0, + out_blinding_1, + ]) .unwrap(); let k_image = { @@ -241,13 +240,40 @@ async fn monerod_integration_test() { &ring, &commitment_ring, random_array(|| Scalar::random(&mut rng)), - real_commitment_blinder - (out_blinding_0 + out_blinding_1) * Scalar::from(MONERO_MUL_FACTOR), + real_commitment_blinder + - (out_blinding_0 + out_blinding_1) * Scalar::from(MONERO_MUL_FACTOR), pseudo_out, alpha * ED25519_BASEPOINT_POINT, alpha * H_p_pk, signing_key * H_p_pk, ); + sig.responses.iter().enumerate().for_each(|(i, res)| { + println!( + r#"epee::string_tools::hex_to_pod("{}", clsag.s[{}]);"#, + hex::encode(res.as_bytes()), + i + ); + }); + println!("{}", hex::encode(sig.h_0.as_bytes())); + println!("{}", hex::encode(sig.D.compress().as_bytes())); + + let I = hex::encode(sig.I.compress().to_bytes()); + println!("{}", I); + + let msg = hex::encode(&prefix.hash().to_bytes()); + println!("{}", msg); + + ring.iter().zip(commitment_ring.iter()).for_each(|(pk, c)| { + println!( + "std::make_tuple(\"{}\",\"{}\"),", + hex::encode(pk.compress().to_bytes()), + hex::encode(c.compress().to_bytes()) + ); + }); + + println!("{}", hex::encode(pseudo_out.compress().to_bytes())); + let out_pk = out_pk .iter() .map(|c| monero::util::ringct::CtKey { @@ -320,21 +346,18 @@ mod tests { let relative_offsets = to_relative_offsets(&key_offsets); - assert_eq!( - &relative_offsets, - &[ - VarInt(78), - VarInt(3), - VarInt(10), - VarInt(0), - VarInt(5), - VarInt(2), - VarInt(3), - VarInt(11), - VarInt(1), - VarInt(1), - VarInt(3), - ] - ) + assert_eq!(&relative_offsets, &[ + VarInt(78), + VarInt(3), + VarInt(10), + VarInt(0), + VarInt(5), + VarInt(2), + VarInt(3), + VarInt(11), + VarInt(1), + VarInt(1), + VarInt(3), + ]) } }