mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2024-10-01 01:45:40 -04:00
Almost finish Adaptor CLSAG
This commit is contained in:
parent
52f30a6637
commit
752cf85ae3
72
Cargo.lock
generated
72
Cargo.lock
generated
@ -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",
|
||||
]
|
||||
|
@ -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"
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2021-01-31"
|
||||
channel = "nightly-2021-04-15"
|
||||
components = ["rustfmt", "clippy"]
|
||||
targets = ["armv7-unknown-linux-gnueabihf"]
|
||||
|
Loading…
Reference in New Issue
Block a user