diff --git a/Cargo.lock b/Cargo.lock index 3e0853da..e7b62682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -639,15 +639,6 @@ dependencies = [ "vec_map", ] -[[package]] -name = "clear_on_drop" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9cc5db465b294c3fa986d5bbb0f3017cd850bff6dd6c52f9ccff8b4d21b7b08" -dependencies = [ - "cc", -] - [[package]] name = "cloudabi" version = "0.0.3" @@ -657,18 +648,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "clsag" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ea6461bc0d5e7e762be243266e621318b4ff6740415ab0190d60cd07385e64" -dependencies = [ - "curve25519-dalek 1.2.6", - "merlin", - "rand 0.6.5", - "sha2 0.8.2", -] - [[package]] name = "config" version = "0.11.0" @@ -836,20 +815,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "curve25519-dalek" -version = "1.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d59fed08e452f286b251f88b2fc64a01f50a7b263aa09557ad7285d9e7fa" -dependencies = [ - "byteorder", - "clear_on_drop", - "digest 0.8.1", - "rand_core 0.3.1", - "serde", - "subtle 2.4.0", -] - [[package]] name = "curve25519-dalek" version = "3.0.2" @@ -976,7 +941,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "ed25519", "rand 0.7.3", "serde", @@ -1681,12 +1646,6 @@ dependencies = [ "syn", ] -[[package]] -name = "keccak" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" - [[package]] name = "keccak-hash" version = "0.7.0" @@ -1835,7 +1794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36db0f0db3b0433f5b9463f1c0cd9eadc0a3734a9170439ce501ff99733a88bd" dependencies = [ "bytes 1.0.1", - "curve25519-dalek 3.0.2", + "curve25519-dalek", "futures", "lazy_static", "libp2p-core", @@ -2052,18 +2011,6 @@ dependencies = [ "autocfg 1.0.1", ] -[[package]] -name = "merlin" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e" -dependencies = [ - "byteorder", - "keccak", - "rand_core 0.4.2", - "zeroize", -] - [[package]] name = "mime" version = "0.2.6" @@ -2148,7 +2095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dad9cdd100bffa1b21e9b1052394dd78246c6977b9e6f801b4acfd53ba62311e" dependencies = [ "base58-monero", - "curve25519-dalek 3.0.2", + "curve25519-dalek", "fixed-hash", "hex 0.4.3", "hex-literal", @@ -2163,8 +2110,7 @@ name = "monero-adaptor" version = "0.1.0" dependencies = [ "anyhow", - "clsag", - "curve25519-dalek 3.0.2", + "curve25519-dalek", "hex 0.4.3", "monero", "nazgul", @@ -2205,7 +2151,7 @@ dependencies = [ name = "monero-wallet" version = "0.1.0" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "hex 0.4.3", "monero", "monero-harness", @@ -2267,7 +2213,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9dff2f512a99611eb14f9bbdcc69e900c93952c4cc94656d2278ea5aa294cec2" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "digest 0.9.0", "rand_core 0.5.1", ] @@ -3406,7 +3352,7 @@ name = "sigma_fun" version = "0.1.3-alpha.0" source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "digest 0.9.0", "generic-array 0.14.4", "rand_core 0.5.1", @@ -3678,7 +3624,7 @@ dependencies = [ "bmrng", "config", "conquer-once", - "curve25519-dalek 3.0.2", + "curve25519-dalek", "dialoguer", "directories-next", "ecdsa_fun", @@ -4609,7 +4555,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088" dependencies = [ - "curve25519-dalek 3.0.2", + "curve25519-dalek", "rand_core 0.5.1", "zeroize", ] diff --git a/monero-adaptor/Cargo.toml b/monero-adaptor/Cargo.toml index 8d4f66ae..de53a651 100644 --- a/monero-adaptor/Cargo.toml +++ b/monero-adaptor/Cargo.toml @@ -12,5 +12,4 @@ tokio = { version = "1", features = ["rt-multi-thread", "time", "macros", "sync" curve25519-dalek = "3" rand = "0.7" nazgul = "0.1" -clsag = "0.3" sha2 = "0.9" diff --git a/monero-adaptor/src/lib.rs b/monero-adaptor/src/lib.rs index 01013a37..2ec7f827 100644 --- a/monero-adaptor/src/lib.rs +++ b/monero-adaptor/src/lib.rs @@ -1,5 +1,7 @@ #![allow(non_snake_case)] +use std::convert::TryInto; + use anyhow::{bail, Result}; use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT; use curve25519_dalek::digest::Digest; @@ -27,9 +29,16 @@ fn final_challenge( let I = I_a + I_b; let R = fake_responses[i] * H_pk_i + I; + let tag = "CLSAG_0".to_string(); + let mut ring_concat = ring + .iter() + .flat_map(|pk| pk.compress().as_bytes().to_vec()) + .collect::>(); + let mut bytes = vec![]; - // todo: add tag and ring + bytes.append(&mut tag.as_bytes().to_vec()); + bytes.append(&mut ring_concat); bytes.append(&mut msg.to_vec()); bytes.append(&mut L.compress().as_bytes().to_vec()); bytes.append(&mut R.compress().as_bytes().to_vec()); @@ -44,7 +53,7 @@ fn final_challenge( } } -pub struct AdaptorSig { +pub struct AdaptorSignature { s_0_a: Scalar, s_0_b: Scalar, fake_responses: [Scalar; RING_SIZE - 1], @@ -53,6 +62,47 @@ pub struct AdaptorSig { I: RistrettoPoint, } +impl AdaptorSignature { + pub fn adapt(self, y: Scalar) -> Signature { + let r_0 = self.s_0_a + self.s_0_b + y; + + let responses = [r_0] + .iter() + .chain(self.fake_responses.iter()) + .copied() + .collect::>() + .try_into() + .expect("correct response size"); + + Signature { + responses, + h_0: self.h_0, + I: self.I, + } + } +} + +pub struct Signature { + pub responses: [Scalar; RING_SIZE], + pub h_0: Scalar, + /// Key image of the real key in the ring. + pub I: RistrettoPoint, +} + +impl Signature { + #[cfg(test)] + fn to_nazgul_signature(&self, ring: &[RistrettoPoint; RING_SIZE]) -> nazgul::clsag::CLSAG { + let ring = ring.iter().map(|pk| vec![*pk]).collect(); + + nazgul::clsag::CLSAG { + challenge: self.h_0, + responses: self.responses.to_vec(), + ring, + key_images: vec![self.I], + } + } +} + pub struct Alice0 { // secret index is always 0 ring: [RistrettoPoint; RING_SIZE], @@ -109,7 +159,7 @@ impl Alice0 { T_a, base_key_hashed_to_point, I_hat_a, - self.s_prime_a, + self.alpha_a, ), c_a: Commitment::new(self.fake_responses, I_a, I_hat_a, T_a), } @@ -130,7 +180,15 @@ impl Alice0 { let I_hat_a = self.alpha_a * base_key_hashed_to_point; let h_0 = { + let ring = self + .ring + .iter() + .flat_map(|pk| pk.compress().as_bytes().to_vec()) + .collect::>(); + let h_0 = Sha512::new() + .chain("CLSAG_0".to_string()) + .chain(ring) .chain(self.msg) .chain((T_a + msg.T_b + self.R_a).compress().as_bytes()) .chain( @@ -157,9 +215,6 @@ impl Alice0 { Ok(Alice1 { ring: self.ring, fake_responses: self.fake_responses, - msg: self.msg, - R_a: self.R_a, - R_prime_a: self.R_prime_a, s_prime_a: self.s_prime_a, alpha_a: self.alpha_a, h_0, @@ -173,11 +228,6 @@ pub struct Alice1 { // secret index is always 0 ring: [RistrettoPoint; RING_SIZE], fake_responses: [Scalar; RING_SIZE - 1], - msg: [u8; 32], - // encryption key - R_a: RistrettoPoint, - // R'a = r_a*H_p(p_k) where p_k is the signing public key - R_prime_a: RistrettoPoint, // this is not s_a cos of something to with one-time-address?? s_prime_a: Scalar, // secret value: @@ -207,7 +257,7 @@ impl Alice1 { ); let I_a = self.s_prime_a * base_key_hashed_to_point; - let adaptor_sig = AdaptorSig { + let adaptor_sig = AdaptorSignature { s_0_a: self.s_0_a, s_0_b: msg.s_0_b, fake_responses: self.fake_responses, @@ -220,7 +270,7 @@ impl Alice1 { } pub struct Alice2 { - pub adaptor_sig: AdaptorSig, + pub adaptor_sig: AdaptorSignature, } pub struct Bob0 { @@ -304,7 +354,7 @@ impl Bob1 { T_b, base_key_hashed_to_point, I_hat_b, - self.s_b, + self.alpha_b, ), } } @@ -339,7 +389,7 @@ impl Bob1 { let s_0_b = self.alpha_b - h_last * self.s_b; - let adaptor_sig = AdaptorSig { + let adaptor_sig = AdaptorSignature { s_0_a: msg.s_0_a, s_0_b, fake_responses, @@ -353,7 +403,7 @@ impl Bob1 { pub struct Bob2 { s_0_b: Scalar, - pub adaptor_sig: AdaptorSig, + pub adaptor_sig: AdaptorSignature, } impl Bob2 { @@ -380,18 +430,19 @@ impl DleqProof { let rH = r * H; let hash = Sha512::new() - .chain(dbg!(G.compress()).as_bytes()) - .chain(dbg!(xG.compress()).as_bytes()) - .chain(dbg!(H.compress()).as_bytes()) - .chain(dbg!(xH.compress()).as_bytes()) - .chain(dbg!(rG.compress()).as_bytes()) - .chain(dbg!(rH.compress()).as_bytes()); + .chain(G.compress().as_bytes()) + .chain(xG.compress().as_bytes()) + .chain(H.compress().as_bytes()) + .chain(xH.compress().as_bytes()) + .chain(rG.compress().as_bytes()) + .chain(rH.compress().as_bytes()); let c = Scalar::from_hash(hash); let s = r + c * x; Self { s, c } } + fn verify( &self, G: RistrettoPoint, @@ -402,25 +453,16 @@ impl DleqProof { let s = self.s; let c = self.c; - let rG = { - let sG = s * G; - - sG - c * xG - }; - - let rH = { - let sH = s * H; - - sH - c * xH - }; + let rG = (s * G) + (-c * xG); + let rH = (s * H) + (-c * xH); let hash = Sha512::new() - .chain(dbg!(G.compress()).as_bytes()) - .chain(dbg!(xG.compress()).as_bytes()) - .chain(dbg!(H.compress()).as_bytes()) - .chain(dbg!(xH.compress()).as_bytes()) - .chain(dbg!(rG.compress()).as_bytes()) - .chain(dbg!(rH.compress()).as_bytes()); + .chain(G.compress().as_bytes()) + .chain(xG.compress().as_bytes()) + .chain(H.compress().as_bytes()) + .chain(xH.compress().as_bytes()) + .chain(rG.compress().as_bytes()) + .chain(rH.compress().as_bytes()); let c_prime = Scalar::from_hash(hash); if c != c_prime { @@ -530,10 +572,12 @@ pub struct Message3 { #[cfg(test)] mod tests { use super::*; + use nazgul::clsag::CLSAG; + use nazgul::traits::Verify; #[test] fn sign_and_verify_success() { - let msg = b"hello world, monero is amazing!!"; + let msg_to_sign = b"hello world, monero is amazing!!"; let s_prime_a = Scalar::random(&mut OsRng); let s_b = Scalar::random(&mut OsRng); @@ -554,12 +598,10 @@ mod tests { let mut ring = [RistrettoPoint::default(); RING_SIZE]; ring[0] = pk; - for member in ring[1..].iter_mut().take(RING_SIZE - 1) { - *member = RistrettoPoint::random(&mut OsRng); - } + ring[1..].fill_with(|| RistrettoPoint::random(&mut OsRng)); - let alice = Alice0::new(ring, *msg, R_a, R_prime_a, s_prime_a); - let bob = Bob0::new(ring, *msg, R_a, R_prime_a, s_b); + let alice = Alice0::new(ring, *msg_to_sign, R_a, R_prime_a, s_prime_a); + let bob = Bob0::new(ring, *msg_to_sign, R_a, R_prime_a, s_b); let msg = alice.next_message(); let bob = bob.receive(msg); @@ -572,5 +614,10 @@ mod tests { let msg = bob.next_message(); let alice = alice.receive(msg); + + let sig = alice.adaptor_sig.adapt(r_a); + let sig = sig.to_nazgul_signature(&ring); + + assert!(CLSAG::verify::(sig, &msg_to_sign.to_vec())); } } diff --git a/rust-toolchain b/rust-toolchain index 6a154529..ade228cc 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -1,4 +1,4 @@ [toolchain] -channel = "nightly-2021-01-31" +channel = "nightly-2021-04-15" components = ["rustfmt", "clippy"] targets = ["armv7-unknown-linux-gnueabihf"]