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",
]
[[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",
]

View File

@ -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"

View File

@ -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::<Vec<u8>>();
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::<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 {
// 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::<Vec<u8>>();
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::<Sha512>(sig, &msg_to_sign.to_vec()));
}
}

View File

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