Almost finish Adaptor CLSAG

This commit is contained in:
Lucas Soriano del Pino 2021-04-15 15:50:38 +10:00
parent 52f30a6637
commit 752cf85ae3
No known key found for this signature in database
GPG Key ID: EE611E973A1530E7
4 changed files with 102 additions and 110 deletions

72
Cargo.lock generated
View File

@ -639,15 +639,6 @@ dependencies = [
"vec_map", "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]] [[package]]
name = "cloudabi" name = "cloudabi"
version = "0.0.3" version = "0.0.3"
@ -657,18 +648,6 @@ dependencies = [
"bitflags", "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]] [[package]]
name = "config" name = "config"
version = "0.11.0" version = "0.11.0"
@ -836,20 +815,6 @@ dependencies = [
"memchr", "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]] [[package]]
name = "curve25519-dalek" name = "curve25519-dalek"
version = "3.0.2" version = "3.0.2"
@ -976,7 +941,7 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d"
dependencies = [ dependencies = [
"curve25519-dalek 3.0.2", "curve25519-dalek",
"ed25519", "ed25519",
"rand 0.7.3", "rand 0.7.3",
"serde", "serde",
@ -1681,12 +1646,6 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "keccak"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7"
[[package]] [[package]]
name = "keccak-hash" name = "keccak-hash"
version = "0.7.0" version = "0.7.0"
@ -1835,7 +1794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36db0f0db3b0433f5b9463f1c0cd9eadc0a3734a9170439ce501ff99733a88bd" checksum = "36db0f0db3b0433f5b9463f1c0cd9eadc0a3734a9170439ce501ff99733a88bd"
dependencies = [ dependencies = [
"bytes 1.0.1", "bytes 1.0.1",
"curve25519-dalek 3.0.2", "curve25519-dalek",
"futures", "futures",
"lazy_static", "lazy_static",
"libp2p-core", "libp2p-core",
@ -2052,18 +2011,6 @@ dependencies = [
"autocfg 1.0.1", "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]] [[package]]
name = "mime" name = "mime"
version = "0.2.6" version = "0.2.6"
@ -2148,7 +2095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dad9cdd100bffa1b21e9b1052394dd78246c6977b9e6f801b4acfd53ba62311e" checksum = "dad9cdd100bffa1b21e9b1052394dd78246c6977b9e6f801b4acfd53ba62311e"
dependencies = [ dependencies = [
"base58-monero", "base58-monero",
"curve25519-dalek 3.0.2", "curve25519-dalek",
"fixed-hash", "fixed-hash",
"hex 0.4.3", "hex 0.4.3",
"hex-literal", "hex-literal",
@ -2163,8 +2110,7 @@ name = "monero-adaptor"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"clsag", "curve25519-dalek",
"curve25519-dalek 3.0.2",
"hex 0.4.3", "hex 0.4.3",
"monero", "monero",
"nazgul", "nazgul",
@ -2205,7 +2151,7 @@ dependencies = [
name = "monero-wallet" name = "monero-wallet"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"curve25519-dalek 3.0.2", "curve25519-dalek",
"hex 0.4.3", "hex 0.4.3",
"monero", "monero",
"monero-harness", "monero-harness",
@ -2267,7 +2213,7 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dff2f512a99611eb14f9bbdcc69e900c93952c4cc94656d2278ea5aa294cec2" checksum = "9dff2f512a99611eb14f9bbdcc69e900c93952c4cc94656d2278ea5aa294cec2"
dependencies = [ dependencies = [
"curve25519-dalek 3.0.2", "curve25519-dalek",
"digest 0.9.0", "digest 0.9.0",
"rand_core 0.5.1", "rand_core 0.5.1",
] ]
@ -3406,7 +3352,7 @@ name = "sigma_fun"
version = "0.1.3-alpha.0" version = "0.1.3-alpha.0"
source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd" source = "git+https://github.com/LLFourn/secp256kfun#8538ef22498170960a9769df2700c1986cc540fd"
dependencies = [ dependencies = [
"curve25519-dalek 3.0.2", "curve25519-dalek",
"digest 0.9.0", "digest 0.9.0",
"generic-array 0.14.4", "generic-array 0.14.4",
"rand_core 0.5.1", "rand_core 0.5.1",
@ -3678,7 +3624,7 @@ dependencies = [
"bmrng", "bmrng",
"config", "config",
"conquer-once", "conquer-once",
"curve25519-dalek 3.0.2", "curve25519-dalek",
"dialoguer", "dialoguer",
"directories-next", "directories-next",
"ecdsa_fun", "ecdsa_fun",
@ -4609,7 +4555,7 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088" checksum = "bc614d95359fd7afc321b66d2107ede58b246b844cf5d8a0adcca413e439f088"
dependencies = [ dependencies = [
"curve25519-dalek 3.0.2", "curve25519-dalek",
"rand_core 0.5.1", "rand_core 0.5.1",
"zeroize", "zeroize",
] ]

View File

@ -12,5 +12,4 @@ tokio = { version = "1", features = ["rt-multi-thread", "time", "macros", "sync"
curve25519-dalek = "3" curve25519-dalek = "3"
rand = "0.7" rand = "0.7"
nazgul = "0.1" nazgul = "0.1"
clsag = "0.3"
sha2 = "0.9" sha2 = "0.9"

View File

@ -1,5 +1,7 @@
#![allow(non_snake_case)] #![allow(non_snake_case)]
use std::convert::TryInto;
use anyhow::{bail, Result}; use anyhow::{bail, Result};
use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT; use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
use curve25519_dalek::digest::Digest; use curve25519_dalek::digest::Digest;
@ -27,9 +29,16 @@ fn final_challenge(
let I = I_a + I_b; let I = I_a + I_b;
let R = fake_responses[i] * H_pk_i + I; 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::<Vec<u8>>();
let mut bytes = vec![]; 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 msg.to_vec());
bytes.append(&mut L.compress().as_bytes().to_vec()); bytes.append(&mut L.compress().as_bytes().to_vec());
bytes.append(&mut R.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_a: Scalar,
s_0_b: Scalar, s_0_b: Scalar,
fake_responses: [Scalar; RING_SIZE - 1], fake_responses: [Scalar; RING_SIZE - 1],
@ -53,6 +62,47 @@ pub struct AdaptorSig {
I: RistrettoPoint, 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::<Vec<_>>()
.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 { pub struct Alice0 {
// secret index is always 0 // secret index is always 0
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
@ -109,7 +159,7 @@ impl Alice0 {
T_a, T_a,
base_key_hashed_to_point, base_key_hashed_to_point,
I_hat_a, I_hat_a,
self.s_prime_a, self.alpha_a,
), ),
c_a: Commitment::new(self.fake_responses, I_a, I_hat_a, T_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 I_hat_a = self.alpha_a * base_key_hashed_to_point;
let h_0 = { let h_0 = {
let ring = self
.ring
.iter()
.flat_map(|pk| pk.compress().as_bytes().to_vec())
.collect::<Vec<u8>>();
let h_0 = Sha512::new() let h_0 = Sha512::new()
.chain("CLSAG_0".to_string())
.chain(ring)
.chain(self.msg) .chain(self.msg)
.chain((T_a + msg.T_b + self.R_a).compress().as_bytes()) .chain((T_a + msg.T_b + self.R_a).compress().as_bytes())
.chain( .chain(
@ -157,9 +215,6 @@ impl Alice0 {
Ok(Alice1 { Ok(Alice1 {
ring: self.ring, ring: self.ring,
fake_responses: self.fake_responses, 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, s_prime_a: self.s_prime_a,
alpha_a: self.alpha_a, alpha_a: self.alpha_a,
h_0, h_0,
@ -173,11 +228,6 @@ pub struct Alice1 {
// secret index is always 0 // secret index is always 0
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
fake_responses: [Scalar; RING_SIZE - 1], 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?? // this is not s_a cos of something to with one-time-address??
s_prime_a: Scalar, s_prime_a: Scalar,
// secret value: // secret value:
@ -207,7 +257,7 @@ impl Alice1 {
); );
let I_a = self.s_prime_a * base_key_hashed_to_point; 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_a: self.s_0_a,
s_0_b: msg.s_0_b, s_0_b: msg.s_0_b,
fake_responses: self.fake_responses, fake_responses: self.fake_responses,
@ -220,7 +270,7 @@ impl Alice1 {
} }
pub struct Alice2 { pub struct Alice2 {
pub adaptor_sig: AdaptorSig, pub adaptor_sig: AdaptorSignature,
} }
pub struct Bob0 { pub struct Bob0 {
@ -304,7 +354,7 @@ impl Bob1 {
T_b, T_b,
base_key_hashed_to_point, base_key_hashed_to_point,
I_hat_b, 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 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_a: msg.s_0_a,
s_0_b, s_0_b,
fake_responses, fake_responses,
@ -353,7 +403,7 @@ impl Bob1 {
pub struct Bob2 { pub struct Bob2 {
s_0_b: Scalar, s_0_b: Scalar,
pub adaptor_sig: AdaptorSig, pub adaptor_sig: AdaptorSignature,
} }
impl Bob2 { impl Bob2 {
@ -380,18 +430,19 @@ impl DleqProof {
let rH = r * H; let rH = r * H;
let hash = Sha512::new() let hash = Sha512::new()
.chain(dbg!(G.compress()).as_bytes()) .chain(G.compress().as_bytes())
.chain(dbg!(xG.compress()).as_bytes()) .chain(xG.compress().as_bytes())
.chain(dbg!(H.compress()).as_bytes()) .chain(H.compress().as_bytes())
.chain(dbg!(xH.compress()).as_bytes()) .chain(xH.compress().as_bytes())
.chain(dbg!(rG.compress()).as_bytes()) .chain(rG.compress().as_bytes())
.chain(dbg!(rH.compress()).as_bytes()); .chain(rH.compress().as_bytes());
let c = Scalar::from_hash(hash); let c = Scalar::from_hash(hash);
let s = r + c * x; let s = r + c * x;
Self { s, c } Self { s, c }
} }
fn verify( fn verify(
&self, &self,
G: RistrettoPoint, G: RistrettoPoint,
@ -402,25 +453,16 @@ impl DleqProof {
let s = self.s; let s = self.s;
let c = self.c; let c = self.c;
let rG = { let rG = (s * G) + (-c * xG);
let sG = s * G; let rH = (s * H) + (-c * xH);
sG - c * xG
};
let rH = {
let sH = s * H;
sH - c * xH
};
let hash = Sha512::new() let hash = Sha512::new()
.chain(dbg!(G.compress()).as_bytes()) .chain(G.compress().as_bytes())
.chain(dbg!(xG.compress()).as_bytes()) .chain(xG.compress().as_bytes())
.chain(dbg!(H.compress()).as_bytes()) .chain(H.compress().as_bytes())
.chain(dbg!(xH.compress()).as_bytes()) .chain(xH.compress().as_bytes())
.chain(dbg!(rG.compress()).as_bytes()) .chain(rG.compress().as_bytes())
.chain(dbg!(rH.compress()).as_bytes()); .chain(rH.compress().as_bytes());
let c_prime = Scalar::from_hash(hash); let c_prime = Scalar::from_hash(hash);
if c != c_prime { if c != c_prime {
@ -530,10 +572,12 @@ pub struct Message3 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use nazgul::clsag::CLSAG;
use nazgul::traits::Verify;
#[test] #[test]
fn sign_and_verify_success() { 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_prime_a = Scalar::random(&mut OsRng);
let s_b = Scalar::random(&mut OsRng); let s_b = Scalar::random(&mut OsRng);
@ -554,12 +598,10 @@ mod tests {
let mut ring = [RistrettoPoint::default(); RING_SIZE]; let mut ring = [RistrettoPoint::default(); RING_SIZE];
ring[0] = pk; ring[0] = pk;
for member in ring[1..].iter_mut().take(RING_SIZE - 1) { ring[1..].fill_with(|| RistrettoPoint::random(&mut OsRng));
*member = RistrettoPoint::random(&mut OsRng);
}
let alice = Alice0::new(ring, *msg, R_a, R_prime_a, s_prime_a); let alice = Alice0::new(ring, *msg_to_sign, R_a, R_prime_a, s_prime_a);
let bob = Bob0::new(ring, *msg, R_a, R_prime_a, s_b); let bob = Bob0::new(ring, *msg_to_sign, R_a, R_prime_a, s_b);
let msg = alice.next_message(); let msg = alice.next_message();
let bob = bob.receive(msg); let bob = bob.receive(msg);
@ -572,5 +614,10 @@ mod tests {
let msg = bob.next_message(); let msg = bob.next_message();
let alice = alice.receive(msg); let alice = alice.receive(msg);
let sig = alice.adaptor_sig.adapt(r_a);
let sig = sig.to_nazgul_signature(&ring);
assert!(CLSAG::verify::<Sha512>(sig, &msg_to_sign.to_vec()));
} }
} }

View File

@ -1,4 +1,4 @@
[toolchain] [toolchain]
channel = "nightly-2021-01-31" channel = "nightly-2021-04-15"
components = ["rustfmt", "clippy"] components = ["rustfmt", "clippy"]
targets = ["armv7-unknown-linux-gnueabihf"] targets = ["armv7-unknown-linux-gnueabihf"]