Fixing some stuff

This commit is contained in:
Lucas Soriano del Pino 2021-04-15 12:39:11 +10:00
parent a64a114bec
commit 52f30a6637
No known key found for this signature in database
GPG Key ID: EE611E973A1530E7

View File

@ -1,5 +1,6 @@
use anyhow::Result; #![allow(non_snake_case)]
use curve25519_dalek;
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;
use curve25519_dalek::ristretto::RistrettoPoint; use curve25519_dalek::ristretto::RistrettoPoint;
@ -33,7 +34,7 @@ fn final_challenge(
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());
let mut hasher = Sha512::new().chain(bytes); let hasher = Sha512::new().chain(bytes);
let h = Scalar::from_hash(hasher); let h = Scalar::from_hash(hasher);
if i >= RING_SIZE - 2 { if i >= RING_SIZE - 2 {
@ -43,25 +44,16 @@ fn final_challenge(
} }
} }
struct AdaptorSig; pub struct AdaptorSig {
fn adaptor_sig(
s_0_a: Scalar, s_0_a: Scalar,
s_0_b: Scalar, s_0_b: Scalar,
fake_responses: [Scalar; RING_SIZE - 1],
h_0: Scalar, h_0: Scalar,
pk: RistrettoPoint, /// Key image of the real key in the ring.
I: RistrettoPoint, I: RistrettoPoint,
) -> AdaptorSig {
let s_prime_0 = s_0_a + s_0_b;
let l_0 = s_prime_0 * RISTRETTO_BASEPOINT_POINT + h_0 * pk;
let H_pk: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>(pk.compress().as_bytes());
let r_0 = s_prime_0 * H_pk + h_0 * I;
AdaptorSig
} }
struct Alice0 { pub struct Alice0 {
// 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],
@ -77,7 +69,7 @@ struct Alice0 {
} }
impl Alice0 { impl Alice0 {
fn new( pub fn new(
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
msg: [u8; 32], msg: [u8; 32],
R_a: RistrettoPoint, R_a: RistrettoPoint,
@ -85,9 +77,8 @@ impl Alice0 {
s_prime_a: Scalar, s_prime_a: Scalar,
) -> Self { ) -> Self {
let mut fake_responses = [Scalar::zero(); RING_SIZE - 1]; let mut fake_responses = [Scalar::zero(); RING_SIZE - 1];
for response in fake_responses.iter_mut().take(RING_SIZE - 1) {
for i in 0..(RING_SIZE - 1) { *response = Scalar::random(&mut OsRng);
fake_responses[i] = Scalar::random(&mut OsRng);
} }
Alice0 { Alice0 {
@ -100,7 +91,8 @@ impl Alice0 {
alpha_a: Scalar::random(&mut OsRng), alpha_a: Scalar::random(&mut OsRng),
} }
} }
fn next_message(&self) -> Message0 {
pub fn next_message(&self) -> Message0 {
let p_k = self.ring.first().unwrap().compress(); let p_k = self.ring.first().unwrap().compress();
// H_p(p_k) // H_p(p_k)
let base_key_hashed_to_point: RistrettoPoint = let base_key_hashed_to_point: RistrettoPoint =
@ -109,7 +101,7 @@ impl Alice0 {
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 I_hat_a = self.alpha_a * base_key_hashed_to_point; let I_hat_a = self.alpha_a * base_key_hashed_to_point;
let T_a = self.s_prime_a * RISTRETTO_BASEPOINT_POINT; let T_a = self.alpha_a * RISTRETTO_BASEPOINT_POINT;
Message0 { Message0 {
pi_a: DleqProof::new( pi_a: DleqProof::new(
@ -123,7 +115,7 @@ impl Alice0 {
} }
} }
fn receive(self, msg: Message1) -> Result<Alice1> { pub fn receive(self, msg: Message1) -> Result<Alice1> {
let p_k = self.ring.first().unwrap().compress(); let p_k = self.ring.first().unwrap().compress();
let base_key_hashed_to_point: RistrettoPoint = let base_key_hashed_to_point: RistrettoPoint =
RistrettoPoint::hash_from_bytes::<Sha512>(p_k.as_bytes()); RistrettoPoint::hash_from_bytes::<Sha512>(p_k.as_bytes());
@ -134,27 +126,33 @@ impl Alice0 {
msg.I_hat_b, msg.I_hat_b,
)?; )?;
let I_a = self.s_prime_a * base_key_hashed_to_point; let T_a = self.alpha_a * RISTRETTO_BASEPOINT_POINT;
let T_a = self.s_prime_a * RISTRETTO_BASEPOINT_POINT; let I_hat_a = self.alpha_a * base_key_hashed_to_point;
let h_1 = { let h_0 = {
Sha512::new() let h_0 = Sha512::new()
.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((I_a + msg.I_b + self.R_prime_a).compress().as_bytes()) .chain(
(I_hat_a + msg.I_hat_b + self.R_prime_a)
.compress()
.as_bytes(),
);
Scalar::from_hash(h_0)
}; };
let h_0 = final_challenge( let I_a = self.s_prime_a * base_key_hashed_to_point;
let h_last = final_challenge(
1, 1,
self.fake_responses, self.fake_responses,
self.ring, self.ring,
Scalar::from_hash(h_1), h_0,
I_a, I_a,
msg.I_b, msg.I_b,
self.msg, self.msg,
); );
let s_0_a = self.alpha_a - h_0 * self.s_prime_a; let s_0_a = self.alpha_a - h_last * self.s_prime_a;
Ok(Alice1 { Ok(Alice1 {
ring: self.ring, ring: self.ring,
@ -164,12 +162,14 @@ impl Alice0 {
R_prime_a: self.R_prime_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,
I_b: msg.I_b,
s_0_a, s_0_a,
}) })
} }
} }
struct Alice1 { 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],
@ -182,25 +182,48 @@ struct Alice1 {
s_prime_a: Scalar, s_prime_a: Scalar,
// secret value: // secret value:
alpha_a: Scalar, alpha_a: Scalar,
h_0: Scalar,
I_b: RistrettoPoint,
s_0_a: Scalar, s_0_a: Scalar,
} }
impl Alice1 { impl Alice1 {
fn next_message(&self) -> Message2 { pub fn next_message(&self) -> Message2 {
let base_key_hashed_to_point: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>( let base_key_hashed_to_point: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>(
self.ring.first().unwrap().compress().as_bytes(), self.ring.first().unwrap().compress().as_bytes(),
); );
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 T_a = self.s_prime_a * RISTRETTO_BASEPOINT_POINT; let T_a = self.alpha_a * RISTRETTO_BASEPOINT_POINT;
let I_hat_a = self.alpha_a * base_key_hashed_to_point; let I_hat_a = self.alpha_a * base_key_hashed_to_point;
Message2 { Message2 {
d_a: Opening::new(self.fake_responses, I_a, I_hat_a, T_a), d_a: Opening::new(self.fake_responses, I_a, I_hat_a, T_a),
s_0_a: self.s_0_a, s_0_a: self.s_0_a,
} }
} }
pub fn receive(self, msg: Message3) -> Alice2 {
let base_key_hashed_to_point: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>(
self.ring.first().unwrap().compress().as_bytes(),
);
let I_a = self.s_prime_a * base_key_hashed_to_point;
let adaptor_sig = AdaptorSig {
s_0_a: self.s_0_a,
s_0_b: msg.s_0_b,
fake_responses: self.fake_responses,
h_0: self.h_0,
I: I_a + self.I_b,
};
Alice2 { adaptor_sig }
}
} }
struct Bob0 { pub struct Alice2 {
pub adaptor_sig: AdaptorSig,
}
pub struct Bob0 {
// secret index is always 0 // secret index is always 0
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
msg: [u8; 32], msg: [u8; 32],
@ -214,24 +237,24 @@ struct Bob0 {
} }
impl Bob0 { impl Bob0 {
fn new( pub fn new(
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
msg: [u8; 32], msg: [u8; 32],
R_b: RistrettoPoint, R_a: RistrettoPoint,
R_prime_b: RistrettoPoint, R_prime_a: RistrettoPoint,
s_b: Scalar, s_b: Scalar,
) -> Self { ) -> Self {
Bob0 { Bob0 {
ring, ring,
msg, msg,
R_a: R_b, R_a,
R_prime_a: R_prime_b, R_prime_a,
alpha_b: Scalar::random(&mut OsRng), alpha_b: Scalar::random(&mut OsRng),
s_b, s_b,
} }
} }
fn receive(self, msg: Message0) -> Bob1 { pub fn receive(self, msg: Message0) -> Bob1 {
Bob1 { Bob1 {
ring: self.ring, ring: self.ring,
msg: self.msg, msg: self.msg,
@ -245,7 +268,7 @@ impl Bob0 {
} }
} }
struct Bob1 { pub struct Bob1 {
// secret index is always 0 // secret index is always 0
ring: [RistrettoPoint; RING_SIZE], ring: [RistrettoPoint; RING_SIZE],
msg: [u8; 32], msg: [u8; 32],
@ -261,7 +284,7 @@ struct Bob1 {
} }
impl Bob1 { impl Bob1 {
fn next_message(&self) -> Message1 { pub fn next_message(&self) -> Message1 {
let p_k = self.ring.first().unwrap().compress(); let p_k = self.ring.first().unwrap().compress();
// H_p(p_k) // H_p(p_k)
let base_key_hashed_to_point: RistrettoPoint = let base_key_hashed_to_point: RistrettoPoint =
@ -270,7 +293,7 @@ impl Bob1 {
let I_b = self.s_b * base_key_hashed_to_point; let I_b = self.s_b * base_key_hashed_to_point;
let I_hat_b = self.alpha_b * base_key_hashed_to_point; let I_hat_b = self.alpha_b * base_key_hashed_to_point;
let T_b = self.s_b * RISTRETTO_BASEPOINT_POINT; let T_b = self.alpha_b * RISTRETTO_BASEPOINT_POINT;
Message1 { Message1 {
I_b, I_b,
@ -286,78 +309,59 @@ impl Bob1 {
} }
} }
fn receive(self, msg: Message2) -> Result<Bob2> { pub fn receive(self, msg: Message2) -> Result<Bob2> {
let (fake_responses, I_a, I_hat_a, T_a) = msg.d_a.open(self.c_a)?; let (fake_responses, I_a, I_hat_a, T_a) = msg.d_a.open(self.c_a)?;
let base_key_hashed_to_point: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>( let base_key_hashed_to_point: RistrettoPoint = RistrettoPoint::hash_from_bytes::<Sha512>(
self.ring.first().unwrap().compress().as_bytes(), self.ring.first().unwrap().compress().as_bytes(),
); );
let I_b = self.s_b * base_key_hashed_to_point; self.pi_a.verify(
let T_b = self.s_b * RISTRETTO_BASEPOINT_POINT; RISTRETTO_BASEPOINT_POINT,
T_a,
base_key_hashed_to_point,
I_hat_a,
)?;
let h_1 = { let T_b = self.alpha_b * RISTRETTO_BASEPOINT_POINT;
Sha512::new() let I_hat_b = self.alpha_b * base_key_hashed_to_point;
let h_0 = {
let h_0 = Sha512::new()
.chain(self.msg) .chain(self.msg)
.chain((T_a + T_b + self.R_a).compress().as_bytes()) .chain((T_a + T_b + self.R_a).compress().as_bytes())
.chain((I_a + I_b + self.R_prime_a).compress().as_bytes()) .chain((I_hat_a + I_hat_b + self.R_prime_a).compress().as_bytes());
Scalar::from_hash(h_0)
}; };
let h_0 = final_challenge( let I_b = self.s_b * base_key_hashed_to_point;
1, let h_last = final_challenge(1, fake_responses, self.ring, h_0, I_a, I_b, self.msg);
fake_responses,
self.ring,
Scalar::from_hash(h_1),
I_a,
I_b,
self.msg,
);
let s_0_b = self.alpha_b - h_0 * self.s_b; let s_0_b = self.alpha_b - h_last * self.s_b;
Ok(Bob2 { let adaptor_sig = AdaptorSig {
ring: self.ring,
msg: self.msg,
R_b: self.R_a,
R_prime_b: self.R_prime_a,
s_b: self.s_b,
alpha_b: self.alpha_b,
pi_a: self.pi_a,
fake_responses,
I_a: I_b,
I_hat_a,
T_a: T_b,
s_0_a: msg.s_0_a, s_0_a: msg.s_0_a,
s_0_b, s_0_b,
}) fake_responses,
h_0,
I: I_a + I_b,
};
Ok(Bob2 { s_0_b, adaptor_sig })
} }
} }
struct Bob2 { pub struct Bob2 {
// secret index is always 0
ring: [RistrettoPoint; RING_SIZE],
msg: [u8; 32],
// encryption key
R_b: RistrettoPoint,
// R'a = r_a*H_p(p_k) where p_k is the signing public key
R_prime_b: RistrettoPoint,
s_b: Scalar,
alpha_b: Scalar,
// secret value:
s_0_b: Scalar, s_0_b: Scalar,
s_0_a: Scalar, pub adaptor_sig: AdaptorSig,
pi_a: DleqProof,
fake_responses: [Scalar; RING_SIZE - 1],
I_a: RistrettoPoint,
I_hat_a: RistrettoPoint,
T_a: RistrettoPoint,
} }
impl Bob2 { impl Bob2 {
fn next_message(&self) -> Message3 { pub fn next_message(&self) -> Message3 {
Message3 { s_0_b: self.s_0_b } Message3 { s_0_b: self.s_0_b }
} }
} }
struct DleqProof { struct DleqProof {
s: Scalar, s: Scalar,
c: Scalar, c: Scalar,
@ -371,7 +375,22 @@ impl DleqProof {
xH: RistrettoPoint, xH: RistrettoPoint,
x: Scalar, x: Scalar,
) -> Self { ) -> Self {
todo!() let r = Scalar::random(&mut OsRng);
let rG = r * G;
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());
let c = Scalar::from_hash(hash);
let s = r + c * x;
Self { s, c }
} }
fn verify( fn verify(
&self, &self,
@ -380,11 +399,40 @@ impl DleqProof {
H: RistrettoPoint, H: RistrettoPoint,
xH: RistrettoPoint, xH: RistrettoPoint,
) -> Result<()> { ) -> Result<()> {
todo!() 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 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());
let c_prime = Scalar::from_hash(hash);
if c != c_prime {
bail!("invalid DLEQ proof")
}
Ok(())
} }
} }
struct Commitment([u8; 32]); #[derive(PartialEq)]
struct Commitment([u8; 64]);
impl Commitment { impl Commitment {
fn new( fn new(
@ -393,7 +441,22 @@ impl Commitment {
I_hat_a: RistrettoPoint, I_hat_a: RistrettoPoint,
T_a: RistrettoPoint, T_a: RistrettoPoint,
) -> Self { ) -> Self {
todo!() let fake_responses = fake_responses
.iter()
.flat_map(|r| r.as_bytes().to_vec())
.collect::<Vec<u8>>();
let hash = Sha512::new()
.chain(fake_responses)
.chain(I_a.compress().as_bytes())
.chain(I_hat_a.compress().as_bytes())
.chain(T_a.compress().as_bytes())
.finalize();
let mut commitment = [0u8; 64];
commitment.copy_from_slice(&hash);
Self(commitment)
} }
} }
@ -418,27 +481,35 @@ impl Opening {
T_a, T_a,
} }
} }
fn open( fn open(
self, self,
c_a: Commitment, commitment: Commitment,
) -> Result<( ) -> Result<(
[Scalar; RING_SIZE - 1], [Scalar; RING_SIZE - 1],
RistrettoPoint, RistrettoPoint,
RistrettoPoint, RistrettoPoint,
RistrettoPoint, RistrettoPoint,
)> { )> {
Ok((todo!())) let self_commitment =
Commitment::new(self.fake_responses, self.I_a, self.I_hat_a, self.T_a);
if self_commitment == commitment {
Ok((self.fake_responses, self.I_a, self.I_hat_a, self.T_a))
} else {
bail!("opening does not match commitment")
}
} }
} }
// Alice Sends this to Bob // Alice Sends this to Bob
struct Message0 { pub struct Message0 {
c_a: Commitment, c_a: Commitment,
pi_a: DleqProof, pi_a: DleqProof,
} }
// Bob sends this to ALice // Bob sends this to ALice
struct Message1 { pub struct Message1 {
I_b: RistrettoPoint, I_b: RistrettoPoint,
T_b: RistrettoPoint, T_b: RistrettoPoint,
I_hat_b: RistrettoPoint, I_hat_b: RistrettoPoint,
@ -446,13 +517,13 @@ struct Message1 {
} }
// Alice sends this to Bob // Alice sends this to Bob
struct Message2 { pub struct Message2 {
d_a: Opening, d_a: Opening,
s_0_a: Scalar, s_0_a: Scalar,
} }
// Bob sends this to Alice // Bob sends this to Alice
struct Message3 { pub struct Message3 {
s_0_b: Scalar, s_0_b: Scalar,
} }
@ -462,7 +533,44 @@ mod tests {
#[test] #[test]
fn sign_and_verify_success() { fn sign_and_verify_success() {
let mut fake_responses = [Scalar::random(&mut OsRng); RING_SIZE - 1]; let msg = b"hello world, monero is amazing!!";
dbg!(fake_responses);
let s_prime_a = Scalar::random(&mut OsRng);
let s_b = Scalar::random(&mut OsRng);
let pk = (s_prime_a + s_b) * RISTRETTO_BASEPOINT_POINT;
let (r_a, R_a, R_prime_a) = {
let r_a = Scalar::random(&mut OsRng);
let R_a = r_a * RISTRETTO_BASEPOINT_POINT;
let pk_hashed_to_point: RistrettoPoint =
RistrettoPoint::hash_from_bytes::<Sha512>(pk.compress().as_bytes());
let R_prime_a = r_a * pk_hashed_to_point;
(r_a, R_a, R_prime_a)
};
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);
}
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 msg = alice.next_message();
let bob = bob.receive(msg);
let msg = bob.next_message();
let alice = alice.receive(msg).unwrap();
let msg = alice.next_message();
let bob = bob.receive(msg).unwrap();
let msg = bob.next_message();
let alice = alice.receive(msg);
} }
} }