diff --git a/Cargo.lock b/Cargo.lock index 3db18a5f..0a54df40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2265,7 +2265,7 @@ dependencies = [ [[package]] name = "monero" version = "0.12.0" -source = "git+https://github.com/comit-network/monero-rs?branch=ecdh_recover_mask#103dc4d3353f46870c5a3405d27e961f4b195350" +source = "git+https://github.com/comit-network/monero-rs?branch=clsag#4c3b87d562f4b4119eff2739894a91e8c6e5381d" dependencies = [ "base58-monero", "clear_on_drop", @@ -2275,6 +2275,7 @@ dependencies = [ "hex 0.4.3", "hex-literal", "integer-encoding", + "itertools 0.10.0", "keccak-hash", "lazy_static", "rand 0.7.3", @@ -2282,6 +2283,7 @@ dependencies = [ "serde-big-array", "subtle 2.4.0", "thiserror", + "tiny-keccak", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f85149a6..0aaff619 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,4 +3,4 @@ members = ["monero-adaptor", "monero-harness", "monero-rpc", "swap", "monero-wal [patch.crates-io] torut = { git = "https://github.com/bonomat/torut/", branch = "feature-flag-tor-secret-keys", default-features = false, features = [ "v3", "control" ] } -monero = { git = "https://github.com/comit-network/monero-rs", branch = "ecdh_recover_mask" } +monero = { git = "https://github.com/comit-network/monero-rs", branch = "clsag" } diff --git a/monero-adaptor/src/clsag.rs b/monero-adaptor/src/clsag.rs deleted file mode 100644 index f0dd566d..00000000 --- a/monero-adaptor/src/clsag.rs +++ /dev/null @@ -1,323 +0,0 @@ -use curve25519_dalek::constants::ED25519_BASEPOINT_POINT; -use curve25519_dalek::edwards::EdwardsPoint; -use curve25519_dalek::scalar::Scalar; -use hash_edwards_to_edwards::hash_point_to_point; -use std::iter::{Cycle, Skip, Take}; - -pub const RING_SIZE: usize = 11; - -const INV_EIGHT: Scalar = Scalar::from_bits([ - 121, 47, 220, 226, 41, 229, 6, 97, 208, 218, 28, 125, 179, 157, 211, 7, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 6, -]); - -pub fn sign( - msg: &[u8; 32], - signing_key: Scalar, - signing_key_index: usize, - H_p_pk: EdwardsPoint, - alpha: Scalar, - ring: &[EdwardsPoint; RING_SIZE], - commitment_ring: &[EdwardsPoint; RING_SIZE], - fake_responses: [Scalar; RING_SIZE - 1], - z: Scalar, - pseudo_output_commitment: EdwardsPoint, - L: EdwardsPoint, - R: EdwardsPoint, - I: EdwardsPoint, -) -> Signature { - let D = z * H_p_pk; - let D_inv_8 = D * INV_EIGHT; - - let mu_P = hash_to_scalar!( - b"CLSAG_agg_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 - ); - - let adjusted_commitment_ring = commitment_ring.map(|point| point - 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 - ) - }; - - let h_signing_index = compute_ring_element(L, R); - - let mut h_prev = h_signing_index; - let mut i = (signing_key_index + 1) % RING_SIZE; - let mut h_0 = Scalar::zero(); - - if i == 0 { - h_0 = h_signing_index - } - - let mut responses = [Scalar::zero(); 11]; - - while i != signing_key_index { - let s_i = fake_responses[i % 10]; - responses[i] = s_i; - - let L_i = compute_L( - h_prev, - mu_P, - mu_C, - s_i, - ring[i], - adjusted_commitment_ring[i], - ); - let R_i = compute_R(h_prev, mu_P, mu_C, s_i, ring[i], I, D); - - let h = compute_ring_element(L_i, R_i); - - i = (i + 1) % RING_SIZE; - if i == 0 { - h_0 = h - } - - h_prev = h - } - - responses[signing_key_index] = alpha - h_prev * ((mu_P * signing_key) + (mu_C * z)); - - Signature { - responses, - h_0, - I, - D: D_inv_8, - } -} - -#[must_use] -pub fn verify( - &Signature { - I, - h_0, - D: D_inv_8, - responses, - .. - }: &Signature, - msg: &[u8; 32], - ring: &[EdwardsPoint; RING_SIZE], - commitment_ring: &[EdwardsPoint; RING_SIZE], - pseudo_output_commitment: EdwardsPoint, -) -> bool { - 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 - ); - let mu_C = hash_to_scalar!( - b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment - ); - - let adjusted_commitment_ring = commitment_ring.map(|point| point - pseudo_output_commitment); - - let h_0_computed = itertools::izip!(responses, ring, adjusted_commitment_ring).fold( - h_0, - |h, (s_i, pk_i, adjusted_commitment_i)| { - let L_i = compute_L(h, mu_P, mu_C, s_i, *pk_i, adjusted_commitment_i); - let R_i = compute_R(h, mu_P, mu_C, s_i, *pk_i, I, D); - - hash_to_scalar!( - b"CLSAG_round" - || ring - || commitment_ring - || pseudo_output_commitment - || msg - || L_i - || R_i - ) - }, - ); - - h_0_computed == h_0 -} - -#[derive(Clone, Debug, PartialEq)] -pub struct Signature { - pub responses: [Scalar; RING_SIZE], - pub h_0: Scalar, - /// Key image of the real key in the ring. - pub I: EdwardsPoint, - pub D: EdwardsPoint, -} - -// L_i = s_i * G + c_p * pk_i + c_c * (commitment_i - pseudoutcommitment) -fn compute_L( - h_prev: Scalar, - mu_P: Scalar, - mu_C: Scalar, - s_i: Scalar, - pk_i: EdwardsPoint, - adjusted_commitment_i: EdwardsPoint, -) -> EdwardsPoint { - let c_p = h_prev * mu_P; - let c_c = h_prev * mu_C; - - (s_i * ED25519_BASEPOINT_POINT) + (c_p * pk_i) + c_c * adjusted_commitment_i -} - -// R_i = s_i * H_p_pk_i + c_p * I + c_c * (z * hash_to_point(signing pk)) -fn compute_R( - h_prev: Scalar, - mu_P: Scalar, - mu_C: Scalar, - s_i: Scalar, - pk_i: EdwardsPoint, - I: EdwardsPoint, - D: EdwardsPoint, -) -> EdwardsPoint { - let c_p = h_prev * mu_P; - let c_c = h_prev * mu_C; - - let H_p_pk_i = hash_point_to_point(pk_i); - - (s_i * H_p_pk_i) + (c_p * I) + c_c * D -} - -impl From for monero::util::ringct::Clsag { - fn from(from: Signature) -> Self { - Self { - s: from - .responses - .iter() - .map(|s| monero::util::ringct::Key { key: s.to_bytes() }) - .collect(), - c1: monero::util::ringct::Key { - key: from.h_0.to_bytes(), - }, - D: monero::util::ringct::Key { - key: from.D.compress().to_bytes(), - }, - } - } -} - -trait IteratorExt { - fn shift_by(self, num: usize) -> ShiftBy - where - Self: ExactSizeIterator + Sized + Clone, - { - let length = self.len(); - - ShiftBy::new(self, num, length) - } -} - -struct ShiftBy { - inner: Take>>, -} - -impl ShiftBy { - fn new(iter: I, num: usize, length: usize) -> Self { - Self { - inner: iter.cycle().skip(num).take(length), - } - } -} - -impl IteratorExt for I where I: ExactSizeIterator {} - -impl Iterator for ShiftBy -where - I: Iterator + Clone, -{ - type Item = I::Item; - - fn next(&mut self) -> Option { - self.inner.next() - } -} - -#[cfg(test)] -mod tests { - use super::*; - use monero::util::key::H; - use rand::SeedableRng; - - #[test] - fn test_shift_by() { - let array = ["a", "b", "c", "d", "e"]; - - let shifted = array.iter().copied().shift_by(2).collect::>(); - - assert_eq!(shifted, vec!["c", "d", "e", "a", "b"]) - } - - #[test] - fn const_is_inv_eight() { - let inv_eight = Scalar::from(8u8).invert(); - - assert_eq!(inv_eight, INV_EIGHT); - } - - #[test] - fn sign_and_verify_at_every_index() { - for signing_key_index in 0..11 { - 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 rng); - let signing_pk = signing_key * ED25519_BASEPOINT_POINT; - let H_p_pk = hash_point_to_point(signing_pk); - - let alpha = Scalar::random(&mut rng); - - let amount_to_spend = 1000000u32; - let fee = 10000u32; - let output_amount = amount_to_spend - fee; - - let mut ring = random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT); - ring[signing_key_index] = signing_pk; - - let real_commitment_blinding = Scalar::random(&mut rng); - let mut commitment_ring = - random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT); - commitment_ring[signing_key_index] = real_commitment_blinding * ED25519_BASEPOINT_POINT - + Scalar::from(amount_to_spend) * H.point.decompress().unwrap(); - - let fee_key = Scalar::from(fee) * H.point.decompress().unwrap(); - - let out_pk_blinding = Scalar::random(&mut rng); - let out_pk = out_pk_blinding * ED25519_BASEPOINT_POINT - + Scalar::from(output_amount) * H.point.decompress().unwrap(); - - let pseudo_output_commitment = fee_key + out_pk; - - let signature = sign( - msg_to_sign, - signing_key, - signing_key_index, - H_p_pk, - alpha, - &ring, - &commitment_ring, - random_array(|| Scalar::random(&mut rng)), - real_commitment_blinding - out_pk_blinding, - pseudo_output_commitment, - alpha * ED25519_BASEPOINT_POINT, - alpha * H_p_pk, - signing_key * H_p_pk, - ); - - assert!(verify( - &signature, - msg_to_sign, - &ring, - &commitment_ring, - pseudo_output_commitment - )) - } - } - - fn random_array(rng: impl FnMut() -> T) -> [T; N] { - let mut ring = [T::default(); N]; - ring[..].fill_with(rng); - - ring - } -} diff --git a/monero-adaptor/src/lib.rs b/monero-adaptor/src/lib.rs index 512be26a..0667a593 100644 --- a/monero-adaptor/src/lib.rs +++ b/monero-adaptor/src/lib.rs @@ -1,4 +1,3 @@ -#![feature(array_map)] #![allow(non_snake_case)] #![allow(non_upper_case_globals)] #![allow(non_camel_case_types)] @@ -14,15 +13,11 @@ use hash_edwards_to_edwards::hash_point_to_point; use rand::{CryptoRng, Rng}; use tiny_keccak::{Hasher, Keccak}; -use clsag::{Signature, RING_SIZE}; - -#[macro_use] -mod macros; -pub mod clsag; +use monero::util::ringct::Clsag; pub struct AdaptorSignature { s_0: Scalar, - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], h_0: Scalar, /// Key image of the real key in the ring. I: EdwardsPoint, @@ -32,7 +27,7 @@ pub struct AdaptorSignature { pub struct HalfAdaptorSignature { s_0_half: Scalar, - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], h_0: Scalar, /// Key image of the real key in the ring. I: EdwardsPoint, @@ -53,10 +48,10 @@ impl HalfAdaptorSignature { } impl AdaptorSignature { - pub fn adapt(self, y: Scalar) -> Signature { + pub fn adapt(self, y: Scalar) -> Clsag { let r_last = self.s_0 + y; - let responses = self + let _responses: [Scalar; 11] = self .fake_responses .iter() .chain([r_last].iter()) @@ -65,20 +60,21 @@ impl AdaptorSignature { .try_into() .expect("correct response size"); - Signature { - responses, - h_0: self.h_0, - I: self.I, - D: self.D, - } + todo!() + // Signature { + // responses, + // h_0: self.h_0, + // I: self.I, + // D: self.D, + // } } } pub struct Alice0 { // secret index is always 0 - ring: [EdwardsPoint; RING_SIZE], - fake_responses: [Scalar; RING_SIZE - 1], - commitment_ring: [EdwardsPoint; RING_SIZE], + ring: [EdwardsPoint; 11], + fake_responses: [Scalar; 10], + commitment_ring: [EdwardsPoint; 11], pseudo_output_commitment: EdwardsPoint, msg: [u8; 32], // encryption key @@ -97,17 +93,17 @@ pub struct Alice0 { impl Alice0 { pub fn new( - ring: [EdwardsPoint; RING_SIZE], + ring: [EdwardsPoint; 11], msg: [u8; 32], - commitment_ring: [EdwardsPoint; RING_SIZE], + commitment_ring: [EdwardsPoint; 11], pseudo_output_commitment: EdwardsPoint, R_a: EdwardsPoint, R_prime_a: EdwardsPoint, s_prime_a: Scalar, rng: &mut (impl Rng + CryptoRng), ) -> Result { - let mut fake_responses = [Scalar::zero(); RING_SIZE - 1]; - for response in fake_responses.iter_mut().take(RING_SIZE - 1) { + let mut fake_responses = [Scalar::zero(); 10]; + for response in fake_responses.iter_mut().take(10) { *response = Scalar::random(rng); } let alpha_a = Scalar::random(rng); @@ -155,7 +151,8 @@ impl Alice0 { msg.pi_b .verify(ED25519_BASEPOINT_POINT, msg.T_b, self.H_p_pk, msg.I_hat_b)?; - let sig = clsag::sign( + let I = self.I_a + msg.I_b; + let sig = monero::clsag::sign( &self.msg, self.s_prime_a, 0, @@ -168,15 +165,15 @@ impl Alice0 { self.pseudo_output_commitment, self.T_a + msg.T_b + self.R_a, self.I_hat_a + msg.I_hat_b + self.R_prime_a, - self.I_a + msg.I_b, + I, ); let sig = HalfAdaptorSignature { - s_0_half: sig.responses[10], + s_0_half: todo!(), fake_responses: self.fake_responses, - h_0: sig.h_0, - I: sig.I, - D: sig.D, + h_0: todo!(), + I, + D: todo!(), }; Ok(Alice1 { @@ -190,7 +187,7 @@ impl Alice0 { } pub struct Alice1 { - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], I_a: EdwardsPoint, I_hat_a: EdwardsPoint, T_a: EdwardsPoint, @@ -217,9 +214,9 @@ pub struct Alice2 { } pub struct Bob0 { - ring: [EdwardsPoint; RING_SIZE], + ring: [EdwardsPoint; 11], msg: [u8; 32], - commitment_ring: [EdwardsPoint; RING_SIZE], + commitment_ring: [EdwardsPoint; 11], pseudo_output_commitment: EdwardsPoint, R_a: EdwardsPoint, R_prime_a: EdwardsPoint, @@ -233,9 +230,9 @@ pub struct Bob0 { impl Bob0 { pub fn new( - ring: [EdwardsPoint; RING_SIZE], + ring: [EdwardsPoint; 11], msg: [u8; 32], - commitment_ring: [EdwardsPoint; RING_SIZE], + commitment_ring: [EdwardsPoint; 11], pseudo_output_commitment: EdwardsPoint, R_a: EdwardsPoint, R_prime_a: EdwardsPoint, @@ -288,9 +285,9 @@ impl Bob0 { } pub struct Bob1 { - ring: [EdwardsPoint; RING_SIZE], + ring: [EdwardsPoint; 11], msg: [u8; 32], - commitment_ring: [EdwardsPoint; RING_SIZE], + commitment_ring: [EdwardsPoint; 11], pseudo_output_commitment: EdwardsPoint, R_a: EdwardsPoint, R_prime_a: EdwardsPoint, @@ -329,7 +326,7 @@ impl Bob1 { .verify(ED25519_BASEPOINT_POINT, T_a, self.H_p_pk, I_hat_a)?; let I = I_a + self.I_b; - let sig = clsag::sign( + let sig = monero::clsag::sign( &self.msg, self.s_b, 0, @@ -345,13 +342,13 @@ impl Bob1 { I, ); - let s_0_b = sig.responses[10]; + let s_0_b = todo!(); let sig = HalfAdaptorSignature { s_0_half: s_0_b, fake_responses, - h_0: sig.h_0, - I: sig.I, - D: sig.D, + h_0: todo!(), + I, + D: todo!(), }; let adaptor_sig = sig.complete(msg.s_0_a); @@ -445,7 +442,7 @@ struct Commitment([u8; 32]); impl Commitment { fn new( - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], I_a: EdwardsPoint, I_hat_a: EdwardsPoint, T_a: EdwardsPoint, @@ -469,7 +466,7 @@ impl Commitment { } struct Opening { - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], I_a: EdwardsPoint, I_hat_a: EdwardsPoint, T_a: EdwardsPoint, @@ -477,7 +474,7 @@ struct Opening { impl Opening { fn new( - fake_responses: [Scalar; RING_SIZE - 1], + fake_responses: [Scalar; 10], I_a: EdwardsPoint, I_hat_a: EdwardsPoint, T_a: EdwardsPoint, @@ -493,12 +490,7 @@ impl Opening { fn open( self, commitment: Commitment, - ) -> Result<( - [Scalar; RING_SIZE - 1], - EdwardsPoint, - EdwardsPoint, - EdwardsPoint, - )> { + ) -> Result<([Scalar; 10], EdwardsPoint, EdwardsPoint, EdwardsPoint)> { let self_commitment = Commitment::new(self.fake_responses, self.I_a, self.I_hat_a, self.T_a); @@ -562,7 +554,7 @@ mod tests { (r_a, R_a, R_prime_a) }; - let mut ring = [EdwardsPoint::default(); RING_SIZE]; + let mut ring = [EdwardsPoint::default(); 11]; ring[0] = pk; ring[1..].fill_with(|| { @@ -570,7 +562,7 @@ mod tests { x * ED25519_BASEPOINT_POINT }); - let mut commitment_ring = [EdwardsPoint::default(); RING_SIZE]; + let mut commitment_ring = [EdwardsPoint::default(); 11]; let real_commitment_blinding = Scalar::random(&mut OsRng); commitment_ring[0] = real_commitment_blinding * ED25519_BASEPOINT_POINT; // + 0 * H @@ -618,13 +610,15 @@ mod tests { let msg = bob.next_message(); let alice = alice.receive(msg); + let I = alice.adaptor_sig.I; let sig = alice.adaptor_sig.adapt(r_a); - assert!(clsag::verify( + assert!(monero::clsag::verify( &sig, msg_to_sign, &ring, &commitment_ring, + I, pseudo_output_commitment, )); } diff --git a/monero-adaptor/src/macros.rs b/monero-adaptor/src/macros.rs deleted file mode 100644 index a4325493..00000000 --- a/monero-adaptor/src/macros.rs +++ /dev/null @@ -1,77 +0,0 @@ -use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint}; -use std::borrow::Cow; - -macro_rules! hash_to_scalar { - ($($e:tt) || +) => { - { - use crate::macros::ToCowBytes as _; - use tiny_keccak::Hasher as _; - - let mut hasher = tiny_keccak::Keccak::v256(); - - $( - let bytes_vec = $e.to_cow_bytes(); - - for el in bytes_vec { - hasher.update(el.as_ref()); - } - )+ - - let mut hash = [0u8; 32]; - hasher.finalize(&mut hash); - - Scalar::from_bytes_mod_order(hash) - } - }; -} - -type CowBytes<'a> = Cow<'a, [u8; 32]>; - -pub(crate) trait ToCowBytes { - fn to_cow_bytes(&self) -> Vec>; -} - -impl ToCowBytes for CompressedEdwardsY { - fn to_cow_bytes(&self) -> Vec> { - vec![CowBytes::Borrowed(&self.0)] - } -} - -impl ToCowBytes for EdwardsPoint { - fn to_cow_bytes(&self) -> Vec> { - vec![CowBytes::Owned(self.compress().0)] - } -} - -impl ToCowBytes for [u8; 32] { - fn to_cow_bytes(&self) -> Vec> { - vec![CowBytes::Borrowed(&self)] - } -} - -impl ToCowBytes for [u8; 11] { - fn to_cow_bytes(&self) -> Vec> { - let mut bytes = [0u8; 32]; - bytes[0..11].copy_from_slice(self); - - vec![CowBytes::Owned(bytes)] - } -} - -impl<'a> ToCowBytes for [EdwardsPoint; 11] { - fn to_cow_bytes(&self) -> Vec> { - vec![ - CowBytes::Owned(self[0].compress().0), - CowBytes::Owned(self[1].compress().0), - CowBytes::Owned(self[2].compress().0), - CowBytes::Owned(self[3].compress().0), - CowBytes::Owned(self[4].compress().0), - CowBytes::Owned(self[5].compress().0), - CowBytes::Owned(self[6].compress().0), - CowBytes::Owned(self[7].compress().0), - CowBytes::Owned(self[8].compress().0), - CowBytes::Owned(self[9].compress().0), - CowBytes::Owned(self[10].compress().0), - ] - } -} diff --git a/monero-adaptor/tests/integration_test.rs b/monero-adaptor/tests/integration_test.rs index 52944a4b..ab4c55d2 100644 --- a/monero-adaptor/tests/integration_test.rs +++ b/monero-adaptor/tests/integration_test.rs @@ -6,7 +6,6 @@ use curve25519_dalek::scalar::Scalar; use hash_edwards_to_edwards::hash_point_to_point; use itertools::{izip, Itertools}; use monero::blockdata::transaction::{ExtraField, KeyImage, SubField, TxOutTarget}; -use monero::cryptonote::hash::Hashable; use monero::cryptonote::onetime_key::{KeyGenerator, MONERO_MUL_FACTOR}; use monero::util::key::H; use monero::util::ringct::{EcdhInfo, RctSig, RctSigBase, RctSigPrunable, RctType}; @@ -20,7 +19,6 @@ use rand::{Rng, SeedableRng}; use std::convert::TryInto; use std::iter; use testcontainers::clients::Cli; -use tiny_keccak::{Hasher, Keccak}; #[tokio::test] async fn monerod_integration_test() { @@ -42,7 +40,7 @@ async fn monerod_integration_test() { let lock_address = monero::Address::from_keypair(monero::Network::Mainnet, &lock_kp); - dbg!(lock_address.to_string()); // 45BcRKAHaA4b5A9SdamF2f1w7zk1mKkBPhaqVoDWzuAtMoSAytzm5A6b2fE6ruupkAFmStrQzdojUExt96mR3oiiSKp8Exf + dbg!(lock_address.to_string()); monero.init_miner().await.unwrap(); let wallet = monero.wallet("miner").expect("wallet to exist"); @@ -245,62 +243,33 @@ async fn monerod_integration_test() { }) .collect::>(); - let rct_sig_base = RctSigBase { - rct_type: RctType::Clsag, - txn_fee: VarInt(fee), - pseudo_outs: Vec::new(), - ecdh_info: vec![ecdh_info_0, ecdh_info_1], - out_pk, + let mut transaction = Transaction { + prefix, + signatures: Vec::new(), + rct_signatures: RctSig { + sig: Some(RctSigBase { + rct_type: RctType::Clsag, + txn_fee: VarInt(fee), + pseudo_outs: Vec::new(), + ecdh_info: vec![ecdh_info_0, ecdh_info_1], + out_pk, + }), + p: Some(RctSigPrunable { + range_sigs: Vec::new(), + bulletproofs: vec![bulletproof], + MGs: Vec::new(), + Clsags: Vec::new(), + pseudo_outs: vec![monero::util::ringct::Key { + key: pseudo_out.compress().0, + }], + }), + }, }; - let message = { - let tx_prefix_hash = prefix.hash().to_bytes(); + let message = transaction.signature_hash().unwrap(); - let mut rct_sig_base_hash = [0u8; 32]; - let mut keccak = Keccak::v256(); - keccak.update(&monero::consensus::serialize(&rct_sig_base)); - keccak.finalize(&mut rct_sig_base_hash); - - let bp_hash = { - let mut keccak = Keccak::v256(); - keccak.update(&bulletproof.A.key); - keccak.update(&bulletproof.S.key); - keccak.update(&bulletproof.T1.key); - keccak.update(&bulletproof.T2.key); - keccak.update(&bulletproof.taux.key); - keccak.update(&bulletproof.mu.key); - - for i in &bulletproof.L { - keccak.update(&i.key); - } - - for i in &bulletproof.R { - keccak.update(&i.key); - } - - keccak.update(&bulletproof.a.key); - keccak.update(&bulletproof.b.key); - keccak.update(&bulletproof.t.key); - - let mut hash = [0u8; 32]; - keccak.finalize(&mut hash); - - hash - }; - - let mut keccak = Keccak::v256(); - keccak.update(&tx_prefix_hash); - keccak.update(&rct_sig_base_hash); - keccak.update(&bp_hash); - - let mut hash = [0u8; 32]; - keccak.finalize(&mut hash); - - hash - }; - - let sig = monero_adaptor::clsag::sign( - &message, + let sig = monero::clsag::sign( + message.as_fixed_bytes(), actual_signing_key, signing_index, H_p_pk, @@ -314,75 +283,15 @@ async fn monerod_integration_test() { alpha * H_p_pk, I, ); - assert!(monero_adaptor::clsag::verify( + assert!(monero::clsag::verify( &sig, - &message, + message.as_fixed_bytes(), &ring, &commitment_ring, + I, pseudo_out )); - - 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!( - r#"epee::string_tools::hex_to_pod("{}", clsag.c1);"#, - hex::encode(sig.h_0.as_bytes()) - ); - println!( - r#"epee::string_tools::hex_to_pod("{}", clsag.D);"#, - hex::encode(sig.D.compress().as_bytes()) - ); - println!( - r#"epee::string_tools::hex_to_pod("{}", clsag.I);"#, - hex::encode(sig.I.compress().to_bytes()) - ); - println!( - r#"epee::string_tools::hex_to_pod("{}", msg);"#, - hex::encode(&message) - ); - - ring.iter() - .zip(commitment_ring.iter()) - .enumerate() - .for_each(|(i, (pk, c))| { - println!( - r#"epee::string_tools::hex_to_pod("{}", pubs[{}].dest);"#, - hex::encode(&pk.compress().to_bytes()), - i - ); - println!( - r#"epee::string_tools::hex_to_pod("{}", pubs[{}].mask);"#, - hex::encode(&c.compress().to_bytes()), - i - ); - }); - - println!( - r#"epee::string_tools::hex_to_pod("{}", Cout);"#, - hex::encode(pseudo_out.compress().to_bytes()) - ); - - let transaction = Transaction { - prefix, - signatures: Vec::new(), - rct_signatures: RctSig { - sig: Some(rct_sig_base), - p: Some(RctSigPrunable { - range_sigs: Vec::new(), - bulletproofs: vec![bulletproof], - MGs: Vec::new(), - Clsags: vec![sig.into()], - pseudo_outs: vec![monero::util::ringct::Key { - key: pseudo_out.compress().0, - }], - }), - }, - }; + transaction.rct_signatures.p.as_mut().unwrap().Clsags.push(sig); client.send_raw_transaction(transaction).await.unwrap(); }