mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-02-22 07:39:56 -05:00
Use upstreamed functionality for clsag and signature hash
This commit is contained in:
parent
04e7d1c111
commit
91f54bf6b5
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2265,7 +2265,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "monero"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/comit-network/monero-rs?branch=ecdh_recover_mask#103dc4d3353f46870c5a3405d27e961f4b195350"
|
||||
source = "git+https://github.com/comit-network/monero-rs?branch=clsag#4c3b87d562f4b4119eff2739894a91e8c6e5381d"
|
||||
dependencies = [
|
||||
"base58-monero",
|
||||
"clear_on_drop",
|
||||
@ -2275,6 +2275,7 @@ dependencies = [
|
||||
"hex 0.4.3",
|
||||
"hex-literal",
|
||||
"integer-encoding",
|
||||
"itertools 0.10.0",
|
||||
"keccak-hash",
|
||||
"lazy_static",
|
||||
"rand 0.7.3",
|
||||
@ -2282,6 +2283,7 @@ dependencies = [
|
||||
"serde-big-array",
|
||||
"subtle 2.4.0",
|
||||
"thiserror",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3,4 +3,4 @@ members = ["monero-adaptor", "monero-harness", "monero-rpc", "swap", "monero-wal
|
||||
|
||||
[patch.crates-io]
|
||||
torut = { git = "https://github.com/bonomat/torut/", branch = "feature-flag-tor-secret-keys", default-features = false, features = [ "v3", "control" ] }
|
||||
monero = { git = "https://github.com/comit-network/monero-rs", branch = "ecdh_recover_mask" }
|
||||
monero = { git = "https://github.com/comit-network/monero-rs", branch = "clsag" }
|
||||
|
@ -1,323 +0,0 @@
|
||||
use curve25519_dalek::constants::ED25519_BASEPOINT_POINT;
|
||||
use curve25519_dalek::edwards::EdwardsPoint;
|
||||
use curve25519_dalek::scalar::Scalar;
|
||||
use hash_edwards_to_edwards::hash_point_to_point;
|
||||
use std::iter::{Cycle, Skip, Take};
|
||||
|
||||
pub const RING_SIZE: usize = 11;
|
||||
|
||||
const INV_EIGHT: Scalar = Scalar::from_bits([
|
||||
121, 47, 220, 226, 41, 229, 6, 97, 208, 218, 28, 125, 179, 157, 211, 7, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 6,
|
||||
]);
|
||||
|
||||
pub fn sign(
|
||||
msg: &[u8; 32],
|
||||
signing_key: Scalar,
|
||||
signing_key_index: usize,
|
||||
H_p_pk: EdwardsPoint,
|
||||
alpha: Scalar,
|
||||
ring: &[EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: &[EdwardsPoint; RING_SIZE],
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
z: Scalar,
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
L: EdwardsPoint,
|
||||
R: EdwardsPoint,
|
||||
I: EdwardsPoint,
|
||||
) -> Signature {
|
||||
let D = z * H_p_pk;
|
||||
let D_inv_8 = D * INV_EIGHT;
|
||||
|
||||
let mu_P = hash_to_scalar!(
|
||||
b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
|
||||
);
|
||||
let mu_C = hash_to_scalar!(
|
||||
b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
|
||||
);
|
||||
|
||||
let adjusted_commitment_ring = commitment_ring.map(|point| point - pseudo_output_commitment);
|
||||
|
||||
let compute_ring_element = |L: EdwardsPoint, R: EdwardsPoint| {
|
||||
hash_to_scalar!(
|
||||
b"CLSAG_round" || ring || commitment_ring || pseudo_output_commitment || msg || L || R
|
||||
)
|
||||
};
|
||||
|
||||
let h_signing_index = compute_ring_element(L, R);
|
||||
|
||||
let mut h_prev = h_signing_index;
|
||||
let mut i = (signing_key_index + 1) % RING_SIZE;
|
||||
let mut h_0 = Scalar::zero();
|
||||
|
||||
if i == 0 {
|
||||
h_0 = h_signing_index
|
||||
}
|
||||
|
||||
let mut responses = [Scalar::zero(); 11];
|
||||
|
||||
while i != signing_key_index {
|
||||
let s_i = fake_responses[i % 10];
|
||||
responses[i] = s_i;
|
||||
|
||||
let L_i = compute_L(
|
||||
h_prev,
|
||||
mu_P,
|
||||
mu_C,
|
||||
s_i,
|
||||
ring[i],
|
||||
adjusted_commitment_ring[i],
|
||||
);
|
||||
let R_i = compute_R(h_prev, mu_P, mu_C, s_i, ring[i], I, D);
|
||||
|
||||
let h = compute_ring_element(L_i, R_i);
|
||||
|
||||
i = (i + 1) % RING_SIZE;
|
||||
if i == 0 {
|
||||
h_0 = h
|
||||
}
|
||||
|
||||
h_prev = h
|
||||
}
|
||||
|
||||
responses[signing_key_index] = alpha - h_prev * ((mu_P * signing_key) + (mu_C * z));
|
||||
|
||||
Signature {
|
||||
responses,
|
||||
h_0,
|
||||
I,
|
||||
D: D_inv_8,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn verify(
|
||||
&Signature {
|
||||
I,
|
||||
h_0,
|
||||
D: D_inv_8,
|
||||
responses,
|
||||
..
|
||||
}: &Signature,
|
||||
msg: &[u8; 32],
|
||||
ring: &[EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: &[EdwardsPoint; RING_SIZE],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
) -> bool {
|
||||
let D = D_inv_8 * Scalar::from(8u8);
|
||||
|
||||
let mu_P = hash_to_scalar!(
|
||||
b"CLSAG_agg_0" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
|
||||
);
|
||||
let mu_C = hash_to_scalar!(
|
||||
b"CLSAG_agg_1" || ring || commitment_ring || I || D_inv_8 || pseudo_output_commitment
|
||||
);
|
||||
|
||||
let adjusted_commitment_ring = commitment_ring.map(|point| point - pseudo_output_commitment);
|
||||
|
||||
let h_0_computed = itertools::izip!(responses, ring, adjusted_commitment_ring).fold(
|
||||
h_0,
|
||||
|h, (s_i, pk_i, adjusted_commitment_i)| {
|
||||
let L_i = compute_L(h, mu_P, mu_C, s_i, *pk_i, adjusted_commitment_i);
|
||||
let R_i = compute_R(h, mu_P, mu_C, s_i, *pk_i, I, D);
|
||||
|
||||
hash_to_scalar!(
|
||||
b"CLSAG_round"
|
||||
|| ring
|
||||
|| commitment_ring
|
||||
|| pseudo_output_commitment
|
||||
|| msg
|
||||
|| L_i
|
||||
|| R_i
|
||||
)
|
||||
},
|
||||
);
|
||||
|
||||
h_0_computed == h_0
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct Signature {
|
||||
pub responses: [Scalar; RING_SIZE],
|
||||
pub h_0: Scalar,
|
||||
/// Key image of the real key in the ring.
|
||||
pub I: EdwardsPoint,
|
||||
pub D: EdwardsPoint,
|
||||
}
|
||||
|
||||
// L_i = s_i * G + c_p * pk_i + c_c * (commitment_i - pseudoutcommitment)
|
||||
fn compute_L(
|
||||
h_prev: Scalar,
|
||||
mu_P: Scalar,
|
||||
mu_C: Scalar,
|
||||
s_i: Scalar,
|
||||
pk_i: EdwardsPoint,
|
||||
adjusted_commitment_i: EdwardsPoint,
|
||||
) -> EdwardsPoint {
|
||||
let c_p = h_prev * mu_P;
|
||||
let c_c = h_prev * mu_C;
|
||||
|
||||
(s_i * ED25519_BASEPOINT_POINT) + (c_p * pk_i) + c_c * adjusted_commitment_i
|
||||
}
|
||||
|
||||
// R_i = s_i * H_p_pk_i + c_p * I + c_c * (z * hash_to_point(signing pk))
|
||||
fn compute_R(
|
||||
h_prev: Scalar,
|
||||
mu_P: Scalar,
|
||||
mu_C: Scalar,
|
||||
s_i: Scalar,
|
||||
pk_i: EdwardsPoint,
|
||||
I: EdwardsPoint,
|
||||
D: EdwardsPoint,
|
||||
) -> EdwardsPoint {
|
||||
let c_p = h_prev * mu_P;
|
||||
let c_c = h_prev * mu_C;
|
||||
|
||||
let H_p_pk_i = hash_point_to_point(pk_i);
|
||||
|
||||
(s_i * H_p_pk_i) + (c_p * I) + c_c * D
|
||||
}
|
||||
|
||||
impl From<Signature> for monero::util::ringct::Clsag {
|
||||
fn from(from: Signature) -> Self {
|
||||
Self {
|
||||
s: from
|
||||
.responses
|
||||
.iter()
|
||||
.map(|s| monero::util::ringct::Key { key: s.to_bytes() })
|
||||
.collect(),
|
||||
c1: monero::util::ringct::Key {
|
||||
key: from.h_0.to_bytes(),
|
||||
},
|
||||
D: monero::util::ringct::Key {
|
||||
key: from.D.compress().to_bytes(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait IteratorExt {
|
||||
fn shift_by(self, num: usize) -> ShiftBy<Self>
|
||||
where
|
||||
Self: ExactSizeIterator + Sized + Clone,
|
||||
{
|
||||
let length = self.len();
|
||||
|
||||
ShiftBy::new(self, num, length)
|
||||
}
|
||||
}
|
||||
|
||||
struct ShiftBy<I> {
|
||||
inner: Take<Skip<Cycle<I>>>,
|
||||
}
|
||||
|
||||
impl<I: Iterator + Clone> ShiftBy<I> {
|
||||
fn new(iter: I, num: usize, length: usize) -> Self {
|
||||
Self {
|
||||
inner: iter.cycle().skip(num).take(length),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> IteratorExt for I where I: ExactSizeIterator {}
|
||||
|
||||
impl<I> Iterator for ShiftBy<I>
|
||||
where
|
||||
I: Iterator + Clone,
|
||||
{
|
||||
type Item = I::Item;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
self.inner.next()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use monero::util::key::H;
|
||||
use rand::SeedableRng;
|
||||
|
||||
#[test]
|
||||
fn test_shift_by() {
|
||||
let array = ["a", "b", "c", "d", "e"];
|
||||
|
||||
let shifted = array.iter().copied().shift_by(2).collect::<Vec<_>>();
|
||||
|
||||
assert_eq!(shifted, vec!["c", "d", "e", "a", "b"])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn const_is_inv_eight() {
|
||||
let inv_eight = Scalar::from(8u8).invert();
|
||||
|
||||
assert_eq!(inv_eight, INV_EIGHT);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sign_and_verify_at_every_index() {
|
||||
for signing_key_index in 0..11 {
|
||||
let mut rng = rand::rngs::StdRng::from_seed([0u8; 32]);
|
||||
|
||||
let msg_to_sign = b"hello world, monero is amazing!!";
|
||||
|
||||
let signing_key = Scalar::random(&mut rng);
|
||||
let signing_pk = signing_key * ED25519_BASEPOINT_POINT;
|
||||
let H_p_pk = hash_point_to_point(signing_pk);
|
||||
|
||||
let alpha = Scalar::random(&mut rng);
|
||||
|
||||
let amount_to_spend = 1000000u32;
|
||||
let fee = 10000u32;
|
||||
let output_amount = amount_to_spend - fee;
|
||||
|
||||
let mut ring = random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT);
|
||||
ring[signing_key_index] = signing_pk;
|
||||
|
||||
let real_commitment_blinding = Scalar::random(&mut rng);
|
||||
let mut commitment_ring =
|
||||
random_array(|| Scalar::random(&mut rng) * ED25519_BASEPOINT_POINT);
|
||||
commitment_ring[signing_key_index] = real_commitment_blinding * ED25519_BASEPOINT_POINT
|
||||
+ Scalar::from(amount_to_spend) * H.point.decompress().unwrap();
|
||||
|
||||
let fee_key = Scalar::from(fee) * H.point.decompress().unwrap();
|
||||
|
||||
let out_pk_blinding = Scalar::random(&mut rng);
|
||||
let out_pk = out_pk_blinding * ED25519_BASEPOINT_POINT
|
||||
+ Scalar::from(output_amount) * H.point.decompress().unwrap();
|
||||
|
||||
let pseudo_output_commitment = fee_key + out_pk;
|
||||
|
||||
let signature = sign(
|
||||
msg_to_sign,
|
||||
signing_key,
|
||||
signing_key_index,
|
||||
H_p_pk,
|
||||
alpha,
|
||||
&ring,
|
||||
&commitment_ring,
|
||||
random_array(|| Scalar::random(&mut rng)),
|
||||
real_commitment_blinding - out_pk_blinding,
|
||||
pseudo_output_commitment,
|
||||
alpha * ED25519_BASEPOINT_POINT,
|
||||
alpha * H_p_pk,
|
||||
signing_key * H_p_pk,
|
||||
);
|
||||
|
||||
assert!(verify(
|
||||
&signature,
|
||||
msg_to_sign,
|
||||
&ring,
|
||||
&commitment_ring,
|
||||
pseudo_output_commitment
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
fn random_array<T: Default + Copy, const N: usize>(rng: impl FnMut() -> T) -> [T; N] {
|
||||
let mut ring = [T::default(); N];
|
||||
ring[..].fill_with(rng);
|
||||
|
||||
ring
|
||||
}
|
||||
}
|
@ -1,4 +1,3 @@
|
||||
#![feature(array_map)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
@ -14,15 +13,11 @@ use hash_edwards_to_edwards::hash_point_to_point;
|
||||
use rand::{CryptoRng, Rng};
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
|
||||
use clsag::{Signature, RING_SIZE};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
pub mod clsag;
|
||||
use monero::util::ringct::Clsag;
|
||||
|
||||
pub struct AdaptorSignature {
|
||||
s_0: Scalar,
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
h_0: Scalar,
|
||||
/// Key image of the real key in the ring.
|
||||
I: EdwardsPoint,
|
||||
@ -32,7 +27,7 @@ pub struct AdaptorSignature {
|
||||
|
||||
pub struct HalfAdaptorSignature {
|
||||
s_0_half: Scalar,
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
h_0: Scalar,
|
||||
/// Key image of the real key in the ring.
|
||||
I: EdwardsPoint,
|
||||
@ -53,10 +48,10 @@ impl HalfAdaptorSignature {
|
||||
}
|
||||
|
||||
impl AdaptorSignature {
|
||||
pub fn adapt(self, y: Scalar) -> Signature {
|
||||
pub fn adapt(self, y: Scalar) -> Clsag {
|
||||
let r_last = self.s_0 + y;
|
||||
|
||||
let responses = self
|
||||
let _responses: [Scalar; 11] = self
|
||||
.fake_responses
|
||||
.iter()
|
||||
.chain([r_last].iter())
|
||||
@ -65,20 +60,21 @@ impl AdaptorSignature {
|
||||
.try_into()
|
||||
.expect("correct response size");
|
||||
|
||||
Signature {
|
||||
responses,
|
||||
h_0: self.h_0,
|
||||
I: self.I,
|
||||
D: self.D,
|
||||
}
|
||||
todo!()
|
||||
// Signature {
|
||||
// responses,
|
||||
// h_0: self.h_0,
|
||||
// I: self.I,
|
||||
// D: self.D,
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Alice0 {
|
||||
// secret index is always 0
|
||||
ring: [EdwardsPoint; RING_SIZE],
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
commitment_ring: [EdwardsPoint; RING_SIZE],
|
||||
ring: [EdwardsPoint; 11],
|
||||
fake_responses: [Scalar; 10],
|
||||
commitment_ring: [EdwardsPoint; 11],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
msg: [u8; 32],
|
||||
// encryption key
|
||||
@ -97,17 +93,17 @@ pub struct Alice0 {
|
||||
|
||||
impl Alice0 {
|
||||
pub fn new(
|
||||
ring: [EdwardsPoint; RING_SIZE],
|
||||
ring: [EdwardsPoint; 11],
|
||||
msg: [u8; 32],
|
||||
commitment_ring: [EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: [EdwardsPoint; 11],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
R_a: EdwardsPoint,
|
||||
R_prime_a: EdwardsPoint,
|
||||
s_prime_a: Scalar,
|
||||
rng: &mut (impl Rng + CryptoRng),
|
||||
) -> Result<Self> {
|
||||
let mut fake_responses = [Scalar::zero(); RING_SIZE - 1];
|
||||
for response in fake_responses.iter_mut().take(RING_SIZE - 1) {
|
||||
let mut fake_responses = [Scalar::zero(); 10];
|
||||
for response in fake_responses.iter_mut().take(10) {
|
||||
*response = Scalar::random(rng);
|
||||
}
|
||||
let alpha_a = Scalar::random(rng);
|
||||
@ -155,7 +151,8 @@ impl Alice0 {
|
||||
msg.pi_b
|
||||
.verify(ED25519_BASEPOINT_POINT, msg.T_b, self.H_p_pk, msg.I_hat_b)?;
|
||||
|
||||
let sig = clsag::sign(
|
||||
let I = self.I_a + msg.I_b;
|
||||
let sig = monero::clsag::sign(
|
||||
&self.msg,
|
||||
self.s_prime_a,
|
||||
0,
|
||||
@ -168,15 +165,15 @@ impl Alice0 {
|
||||
self.pseudo_output_commitment,
|
||||
self.T_a + msg.T_b + self.R_a,
|
||||
self.I_hat_a + msg.I_hat_b + self.R_prime_a,
|
||||
self.I_a + msg.I_b,
|
||||
I,
|
||||
);
|
||||
|
||||
let sig = HalfAdaptorSignature {
|
||||
s_0_half: sig.responses[10],
|
||||
s_0_half: todo!(),
|
||||
fake_responses: self.fake_responses,
|
||||
h_0: sig.h_0,
|
||||
I: sig.I,
|
||||
D: sig.D,
|
||||
h_0: todo!(),
|
||||
I,
|
||||
D: todo!(),
|
||||
};
|
||||
|
||||
Ok(Alice1 {
|
||||
@ -190,7 +187,7 @@ impl Alice0 {
|
||||
}
|
||||
|
||||
pub struct Alice1 {
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
I_a: EdwardsPoint,
|
||||
I_hat_a: EdwardsPoint,
|
||||
T_a: EdwardsPoint,
|
||||
@ -217,9 +214,9 @@ pub struct Alice2 {
|
||||
}
|
||||
|
||||
pub struct Bob0 {
|
||||
ring: [EdwardsPoint; RING_SIZE],
|
||||
ring: [EdwardsPoint; 11],
|
||||
msg: [u8; 32],
|
||||
commitment_ring: [EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: [EdwardsPoint; 11],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
R_a: EdwardsPoint,
|
||||
R_prime_a: EdwardsPoint,
|
||||
@ -233,9 +230,9 @@ pub struct Bob0 {
|
||||
|
||||
impl Bob0 {
|
||||
pub fn new(
|
||||
ring: [EdwardsPoint; RING_SIZE],
|
||||
ring: [EdwardsPoint; 11],
|
||||
msg: [u8; 32],
|
||||
commitment_ring: [EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: [EdwardsPoint; 11],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
R_a: EdwardsPoint,
|
||||
R_prime_a: EdwardsPoint,
|
||||
@ -288,9 +285,9 @@ impl Bob0 {
|
||||
}
|
||||
|
||||
pub struct Bob1 {
|
||||
ring: [EdwardsPoint; RING_SIZE],
|
||||
ring: [EdwardsPoint; 11],
|
||||
msg: [u8; 32],
|
||||
commitment_ring: [EdwardsPoint; RING_SIZE],
|
||||
commitment_ring: [EdwardsPoint; 11],
|
||||
pseudo_output_commitment: EdwardsPoint,
|
||||
R_a: EdwardsPoint,
|
||||
R_prime_a: EdwardsPoint,
|
||||
@ -329,7 +326,7 @@ impl Bob1 {
|
||||
.verify(ED25519_BASEPOINT_POINT, T_a, self.H_p_pk, I_hat_a)?;
|
||||
|
||||
let I = I_a + self.I_b;
|
||||
let sig = clsag::sign(
|
||||
let sig = monero::clsag::sign(
|
||||
&self.msg,
|
||||
self.s_b,
|
||||
0,
|
||||
@ -345,13 +342,13 @@ impl Bob1 {
|
||||
I,
|
||||
);
|
||||
|
||||
let s_0_b = sig.responses[10];
|
||||
let s_0_b = todo!();
|
||||
let sig = HalfAdaptorSignature {
|
||||
s_0_half: s_0_b,
|
||||
fake_responses,
|
||||
h_0: sig.h_0,
|
||||
I: sig.I,
|
||||
D: sig.D,
|
||||
h_0: todo!(),
|
||||
I,
|
||||
D: todo!(),
|
||||
};
|
||||
let adaptor_sig = sig.complete(msg.s_0_a);
|
||||
|
||||
@ -445,7 +442,7 @@ struct Commitment([u8; 32]);
|
||||
|
||||
impl Commitment {
|
||||
fn new(
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
I_a: EdwardsPoint,
|
||||
I_hat_a: EdwardsPoint,
|
||||
T_a: EdwardsPoint,
|
||||
@ -469,7 +466,7 @@ impl Commitment {
|
||||
}
|
||||
|
||||
struct Opening {
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
I_a: EdwardsPoint,
|
||||
I_hat_a: EdwardsPoint,
|
||||
T_a: EdwardsPoint,
|
||||
@ -477,7 +474,7 @@ struct Opening {
|
||||
|
||||
impl Opening {
|
||||
fn new(
|
||||
fake_responses: [Scalar; RING_SIZE - 1],
|
||||
fake_responses: [Scalar; 10],
|
||||
I_a: EdwardsPoint,
|
||||
I_hat_a: EdwardsPoint,
|
||||
T_a: EdwardsPoint,
|
||||
@ -493,12 +490,7 @@ impl Opening {
|
||||
fn open(
|
||||
self,
|
||||
commitment: Commitment,
|
||||
) -> Result<(
|
||||
[Scalar; RING_SIZE - 1],
|
||||
EdwardsPoint,
|
||||
EdwardsPoint,
|
||||
EdwardsPoint,
|
||||
)> {
|
||||
) -> Result<([Scalar; 10], EdwardsPoint, EdwardsPoint, EdwardsPoint)> {
|
||||
let self_commitment =
|
||||
Commitment::new(self.fake_responses, self.I_a, self.I_hat_a, self.T_a);
|
||||
|
||||
@ -562,7 +554,7 @@ mod tests {
|
||||
(r_a, R_a, R_prime_a)
|
||||
};
|
||||
|
||||
let mut ring = [EdwardsPoint::default(); RING_SIZE];
|
||||
let mut ring = [EdwardsPoint::default(); 11];
|
||||
ring[0] = pk;
|
||||
|
||||
ring[1..].fill_with(|| {
|
||||
@ -570,7 +562,7 @@ mod tests {
|
||||
x * ED25519_BASEPOINT_POINT
|
||||
});
|
||||
|
||||
let mut commitment_ring = [EdwardsPoint::default(); RING_SIZE];
|
||||
let mut commitment_ring = [EdwardsPoint::default(); 11];
|
||||
|
||||
let real_commitment_blinding = Scalar::random(&mut OsRng);
|
||||
commitment_ring[0] = real_commitment_blinding * ED25519_BASEPOINT_POINT; // + 0 * H
|
||||
@ -618,13 +610,15 @@ mod tests {
|
||||
let msg = bob.next_message();
|
||||
let alice = alice.receive(msg);
|
||||
|
||||
let I = alice.adaptor_sig.I;
|
||||
let sig = alice.adaptor_sig.adapt(r_a);
|
||||
|
||||
assert!(clsag::verify(
|
||||
assert!(monero::clsag::verify(
|
||||
&sig,
|
||||
msg_to_sign,
|
||||
&ring,
|
||||
&commitment_ring,
|
||||
I,
|
||||
pseudo_output_commitment,
|
||||
));
|
||||
}
|
||||
|
@ -1,77 +0,0 @@
|
||||
use curve25519_dalek::edwards::{CompressedEdwardsY, EdwardsPoint};
|
||||
use std::borrow::Cow;
|
||||
|
||||
macro_rules! hash_to_scalar {
|
||||
($($e:tt) || +) => {
|
||||
{
|
||||
use crate::macros::ToCowBytes as _;
|
||||
use tiny_keccak::Hasher as _;
|
||||
|
||||
let mut hasher = tiny_keccak::Keccak::v256();
|
||||
|
||||
$(
|
||||
let bytes_vec = $e.to_cow_bytes();
|
||||
|
||||
for el in bytes_vec {
|
||||
hasher.update(el.as_ref());
|
||||
}
|
||||
)+
|
||||
|
||||
let mut hash = [0u8; 32];
|
||||
hasher.finalize(&mut hash);
|
||||
|
||||
Scalar::from_bytes_mod_order(hash)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
type CowBytes<'a> = Cow<'a, [u8; 32]>;
|
||||
|
||||
pub(crate) trait ToCowBytes {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>>;
|
||||
}
|
||||
|
||||
impl ToCowBytes for CompressedEdwardsY {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
|
||||
vec![CowBytes::Borrowed(&self.0)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCowBytes for EdwardsPoint {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
|
||||
vec![CowBytes::Owned(self.compress().0)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCowBytes for [u8; 32] {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
|
||||
vec![CowBytes::Borrowed(&self)]
|
||||
}
|
||||
}
|
||||
|
||||
impl ToCowBytes for [u8; 11] {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
|
||||
let mut bytes = [0u8; 32];
|
||||
bytes[0..11].copy_from_slice(self);
|
||||
|
||||
vec![CowBytes::Owned(bytes)]
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ToCowBytes for [EdwardsPoint; 11] {
|
||||
fn to_cow_bytes(&self) -> Vec<CowBytes<'_>> {
|
||||
vec![
|
||||
CowBytes::Owned(self[0].compress().0),
|
||||
CowBytes::Owned(self[1].compress().0),
|
||||
CowBytes::Owned(self[2].compress().0),
|
||||
CowBytes::Owned(self[3].compress().0),
|
||||
CowBytes::Owned(self[4].compress().0),
|
||||
CowBytes::Owned(self[5].compress().0),
|
||||
CowBytes::Owned(self[6].compress().0),
|
||||
CowBytes::Owned(self[7].compress().0),
|
||||
CowBytes::Owned(self[8].compress().0),
|
||||
CowBytes::Owned(self[9].compress().0),
|
||||
CowBytes::Owned(self[10].compress().0),
|
||||
]
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ use curve25519_dalek::scalar::Scalar;
|
||||
use hash_edwards_to_edwards::hash_point_to_point;
|
||||
use itertools::{izip, Itertools};
|
||||
use monero::blockdata::transaction::{ExtraField, KeyImage, SubField, TxOutTarget};
|
||||
use monero::cryptonote::hash::Hashable;
|
||||
use monero::cryptonote::onetime_key::{KeyGenerator, MONERO_MUL_FACTOR};
|
||||
use monero::util::key::H;
|
||||
use monero::util::ringct::{EcdhInfo, RctSig, RctSigBase, RctSigPrunable, RctType};
|
||||
@ -20,7 +19,6 @@ use rand::{Rng, SeedableRng};
|
||||
use std::convert::TryInto;
|
||||
use std::iter;
|
||||
use testcontainers::clients::Cli;
|
||||
use tiny_keccak::{Hasher, Keccak};
|
||||
|
||||
#[tokio::test]
|
||||
async fn monerod_integration_test() {
|
||||
@ -42,7 +40,7 @@ async fn monerod_integration_test() {
|
||||
|
||||
let lock_address = monero::Address::from_keypair(monero::Network::Mainnet, &lock_kp);
|
||||
|
||||
dbg!(lock_address.to_string()); // 45BcRKAHaA4b5A9SdamF2f1w7zk1mKkBPhaqVoDWzuAtMoSAytzm5A6b2fE6ruupkAFmStrQzdojUExt96mR3oiiSKp8Exf
|
||||
dbg!(lock_address.to_string());
|
||||
|
||||
monero.init_miner().await.unwrap();
|
||||
let wallet = monero.wallet("miner").expect("wallet to exist");
|
||||
@ -245,62 +243,33 @@ async fn monerod_integration_test() {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let rct_sig_base = RctSigBase {
|
||||
let mut transaction = Transaction {
|
||||
prefix,
|
||||
signatures: Vec::new(),
|
||||
rct_signatures: RctSig {
|
||||
sig: Some(RctSigBase {
|
||||
rct_type: RctType::Clsag,
|
||||
txn_fee: VarInt(fee),
|
||||
pseudo_outs: Vec::new(),
|
||||
ecdh_info: vec![ecdh_info_0, ecdh_info_1],
|
||||
out_pk,
|
||||
}),
|
||||
p: Some(RctSigPrunable {
|
||||
range_sigs: Vec::new(),
|
||||
bulletproofs: vec![bulletproof],
|
||||
MGs: Vec::new(),
|
||||
Clsags: Vec::new(),
|
||||
pseudo_outs: vec![monero::util::ringct::Key {
|
||||
key: pseudo_out.compress().0,
|
||||
}],
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
let message = {
|
||||
let tx_prefix_hash = prefix.hash().to_bytes();
|
||||
let message = transaction.signature_hash().unwrap();
|
||||
|
||||
let mut rct_sig_base_hash = [0u8; 32];
|
||||
let mut keccak = Keccak::v256();
|
||||
keccak.update(&monero::consensus::serialize(&rct_sig_base));
|
||||
keccak.finalize(&mut rct_sig_base_hash);
|
||||
|
||||
let bp_hash = {
|
||||
let mut keccak = Keccak::v256();
|
||||
keccak.update(&bulletproof.A.key);
|
||||
keccak.update(&bulletproof.S.key);
|
||||
keccak.update(&bulletproof.T1.key);
|
||||
keccak.update(&bulletproof.T2.key);
|
||||
keccak.update(&bulletproof.taux.key);
|
||||
keccak.update(&bulletproof.mu.key);
|
||||
|
||||
for i in &bulletproof.L {
|
||||
keccak.update(&i.key);
|
||||
}
|
||||
|
||||
for i in &bulletproof.R {
|
||||
keccak.update(&i.key);
|
||||
}
|
||||
|
||||
keccak.update(&bulletproof.a.key);
|
||||
keccak.update(&bulletproof.b.key);
|
||||
keccak.update(&bulletproof.t.key);
|
||||
|
||||
let mut hash = [0u8; 32];
|
||||
keccak.finalize(&mut hash);
|
||||
|
||||
hash
|
||||
};
|
||||
|
||||
let mut keccak = Keccak::v256();
|
||||
keccak.update(&tx_prefix_hash);
|
||||
keccak.update(&rct_sig_base_hash);
|
||||
keccak.update(&bp_hash);
|
||||
|
||||
let mut hash = [0u8; 32];
|
||||
keccak.finalize(&mut hash);
|
||||
|
||||
hash
|
||||
};
|
||||
|
||||
let sig = monero_adaptor::clsag::sign(
|
||||
&message,
|
||||
let sig = monero::clsag::sign(
|
||||
message.as_fixed_bytes(),
|
||||
actual_signing_key,
|
||||
signing_index,
|
||||
H_p_pk,
|
||||
@ -314,75 +283,15 @@ async fn monerod_integration_test() {
|
||||
alpha * H_p_pk,
|
||||
I,
|
||||
);
|
||||
assert!(monero_adaptor::clsag::verify(
|
||||
assert!(monero::clsag::verify(
|
||||
&sig,
|
||||
&message,
|
||||
message.as_fixed_bytes(),
|
||||
&ring,
|
||||
&commitment_ring,
|
||||
I,
|
||||
pseudo_out
|
||||
));
|
||||
|
||||
sig.responses.iter().enumerate().for_each(|(i, res)| {
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", clsag.s[{}]);"#,
|
||||
hex::encode(res.as_bytes()),
|
||||
i
|
||||
);
|
||||
});
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", clsag.c1);"#,
|
||||
hex::encode(sig.h_0.as_bytes())
|
||||
);
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", clsag.D);"#,
|
||||
hex::encode(sig.D.compress().as_bytes())
|
||||
);
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", clsag.I);"#,
|
||||
hex::encode(sig.I.compress().to_bytes())
|
||||
);
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", msg);"#,
|
||||
hex::encode(&message)
|
||||
);
|
||||
|
||||
ring.iter()
|
||||
.zip(commitment_ring.iter())
|
||||
.enumerate()
|
||||
.for_each(|(i, (pk, c))| {
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", pubs[{}].dest);"#,
|
||||
hex::encode(&pk.compress().to_bytes()),
|
||||
i
|
||||
);
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", pubs[{}].mask);"#,
|
||||
hex::encode(&c.compress().to_bytes()),
|
||||
i
|
||||
);
|
||||
});
|
||||
|
||||
println!(
|
||||
r#"epee::string_tools::hex_to_pod("{}", Cout);"#,
|
||||
hex::encode(pseudo_out.compress().to_bytes())
|
||||
);
|
||||
|
||||
let transaction = Transaction {
|
||||
prefix,
|
||||
signatures: Vec::new(),
|
||||
rct_signatures: RctSig {
|
||||
sig: Some(rct_sig_base),
|
||||
p: Some(RctSigPrunable {
|
||||
range_sigs: Vec::new(),
|
||||
bulletproofs: vec![bulletproof],
|
||||
MGs: Vec::new(),
|
||||
Clsags: vec![sig.into()],
|
||||
pseudo_outs: vec![monero::util::ringct::Key {
|
||||
key: pseudo_out.compress().0,
|
||||
}],
|
||||
}),
|
||||
},
|
||||
};
|
||||
transaction.rct_signatures.p.as_mut().unwrap().Clsags.push(sig);
|
||||
|
||||
client.send_raw_transaction(transaction).await.unwrap();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user