diff --git a/coins/monero/src/clsag/mod.rs b/coins/monero/src/clsag/mod.rs index 7359c5f5..3ff2acba 100644 --- a/coins/monero/src/clsag/mod.rs +++ b/coins/monero/src/clsag/mod.rs @@ -140,36 +140,32 @@ fn core( to_hash.extend(pseudo_out.compress().to_bytes()); to_hash.extend(msg); - let mut c; - let mut c1 = Scalar::zero(); - + let start; let end; - let mut i; - + let mut c; match A_c1 { Mode::Sign(r, A, AH) => { + start = r + 1; + end = r + n; to_hash.extend(A.compress().to_bytes()); to_hash.extend(AH.compress().to_bytes()); c = hash_to_scalar(&to_hash); - - end = r; - i = (end + 1) % n; - if i == 0 { - c1 = c; - } }, #[cfg(feature = "experimental")] Mode::Verify(c1) => { - end = 0; - i = 0; + start = 0; + end = n; c = c1; } } - let mut first = true; - while (i != end) || first { - first = false; + let mut c1 = None; + for i in (start .. end).map(|i| i % n) { + if i == 0 { + c1 = Some(c); + } + let c_p = mu_P * c; let c_c = mu_C * c; @@ -182,14 +178,9 @@ fn core( to_hash.extend(L.compress().to_bytes()); to_hash.extend(R.compress().to_bytes()); c = hash_to_scalar(&to_hash); - - i = (i + 1) % n; - if i == 0 { - c1 = c; - } } - ((D_bytes, c * mu_P, c * mu_C), c1) + ((D_bytes, c * mu_P, c * mu_C), c1.unwrap_or(c)) } pub(crate) fn sign_core( diff --git a/coins/monero/src/clsag/multisig.rs b/coins/monero/src/clsag/multisig.rs index 1ec79821..5b0b8cc8 100644 --- a/coins/monero/src/clsag/multisig.rs +++ b/coins/monero/src/clsag/multisig.rs @@ -260,7 +260,6 @@ impl Algorithm for Multisig { sum: dfg::Scalar ) -> Option { let interim = self.interim.as_ref().unwrap(); - let mut clsag = interim.clsag.clone(); clsag.s[usize::from(self.input().decoys.i)] = Key { key: (sum.0 - interim.c).to_bytes() }; if verify(&clsag, &self.input().decoys.ring, &self.image, &interim.pseudo_out, &self.msg()).is_ok() { diff --git a/coins/monero/tests/clsag.rs b/coins/monero/tests/clsag.rs index 7d69b7af..75d5a324 100644 --- a/coins/monero/tests/clsag.rs +++ b/coins/monero/tests/clsag.rs @@ -16,50 +16,54 @@ mod frost; #[cfg(feature = "multisig")] use crate::frost::{THRESHOLD, generate_keys, sign}; -const RING_INDEX: u8 = 3; const RING_LEN: u64 = 11; const AMOUNT: u64 = 1337; +#[cfg(feature = "multisig")] +const RING_INDEX: u8 = 3; + #[test] fn clsag() { - let msg = [1; 32]; + for real in 0 .. RING_LEN { + let msg = [1; 32]; - let mut secrets = [Scalar::zero(), Scalar::zero()]; - let mut ring = vec![]; - for i in 0 .. RING_LEN { - let dest = random_scalar(&mut OsRng); - let mask = random_scalar(&mut OsRng); - let amount; - if i == u64::from(RING_INDEX) { - secrets = [dest, mask]; - amount = AMOUNT; - } else { - amount = OsRng.next_u64(); + let mut secrets = [Scalar::zero(), Scalar::zero()]; + let mut ring = vec![]; + for i in 0 .. RING_LEN { + let dest = random_scalar(&mut OsRng); + let mask = random_scalar(&mut OsRng); + let amount; + if i == u64::from(real) { + secrets = [dest, mask]; + amount = AMOUNT; + } else { + amount = OsRng.next_u64(); + } + ring.push([&dest * &ED25519_BASEPOINT_TABLE, Commitment::new(mask, amount).calculate()]); } - ring.push([&dest * &ED25519_BASEPOINT_TABLE, Commitment::new(mask, amount).calculate()]); - } - let image = key_image::generate(&secrets[0]); - let (clsag, pseudo_out) = clsag::sign( - &mut OsRng, - &vec![( - secrets[0], - image, - clsag::Input::new( - Commitment::new(secrets[1], AMOUNT), - Decoys { - i: RING_INDEX, - offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(), - ring: ring.clone() - } - ).unwrap() - )], - random_scalar(&mut OsRng), - msg - ).unwrap().swap_remove(0); - clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap(); - #[cfg(feature = "experimental")] - clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap(); + let image = key_image::generate(&secrets[0]); + let (clsag, pseudo_out) = clsag::sign( + &mut OsRng, + &vec![( + secrets[0], + image, + clsag::Input::new( + Commitment::new(secrets[1], AMOUNT), + Decoys { + i: u8::try_from(real).unwrap(), + offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(), + ring: ring.clone() + } + ).unwrap() + )], + random_scalar(&mut OsRng), + msg + ).unwrap().swap_remove(0); + clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap(); + #[cfg(feature = "experimental")] + clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap(); + } } #[cfg(feature = "multisig")] diff --git a/coins/monero/tests/key_image.rs b/coins/monero/tests/key_image.rs index 0bd1b8c7..0fa1c8d6 100644 --- a/coins/monero/tests/key_image.rs +++ b/coins/monero/tests/key_image.rs @@ -10,7 +10,7 @@ mod frost; use crate::frost::{THRESHOLD, PARTICIPANTS, generate_keys}; #[test] -fn test() { +fn key_image() { let (keys, group_private) = generate_keys(); let image = key_image::generate(&group_private);