Slightly simplify CLSAG signing

Expands its test to test all possible ring indexes, though just 0 and a 
single n would be sufficient.
This commit is contained in:
Luke Parker 2022-05-14 00:45:13 -04:00
parent 0aeab04c70
commit 94bd30083b
No known key found for this signature in database
GPG key ID: F9F1386DB1E119B6
4 changed files with 54 additions and 60 deletions

View file

@ -140,36 +140,32 @@ fn core(
to_hash.extend(pseudo_out.compress().to_bytes());
to_hash.extend(msg);
let mut c;
let mut c1 = Scalar::zero();
let start;
let end;
let mut i;
let mut c;
match A_c1 {
Mode::Sign(r, A, AH) => {
start = r + 1;
end = r + n;
to_hash.extend(A.compress().to_bytes());
to_hash.extend(AH.compress().to_bytes());
c = hash_to_scalar(&to_hash);
end = r;
i = (end + 1) % n;
if i == 0 {
c1 = c;
}
},
#[cfg(feature = "experimental")]
Mode::Verify(c1) => {
end = 0;
i = 0;
start = 0;
end = n;
c = c1;
}
}
let mut first = true;
while (i != end) || first {
first = false;
let mut c1 = None;
for i in (start .. end).map(|i| i % n) {
if i == 0 {
c1 = Some(c);
}
let c_p = mu_P * c;
let c_c = mu_C * c;
@ -182,14 +178,9 @@ fn core(
to_hash.extend(L.compress().to_bytes());
to_hash.extend(R.compress().to_bytes());
c = hash_to_scalar(&to_hash);
i = (i + 1) % n;
if i == 0 {
c1 = c;
}
}
((D_bytes, c * mu_P, c * mu_C), c1)
((D_bytes, c * mu_P, c * mu_C), c1.unwrap_or(c))
}
pub(crate) fn sign_core<R: RngCore + CryptoRng>(

View file

@ -260,7 +260,6 @@ impl Algorithm<Ed25519> for Multisig {
sum: dfg::Scalar
) -> Option<Self::Signature> {
let interim = self.interim.as_ref().unwrap();
let mut clsag = interim.clsag.clone();
clsag.s[usize::from(self.input().decoys.i)] = Key { key: (sum.0 - interim.c).to_bytes() };
if verify(&clsag, &self.input().decoys.ring, &self.image, &interim.pseudo_out, &self.msg()).is_ok() {

View file

@ -16,50 +16,54 @@ mod frost;
#[cfg(feature = "multisig")]
use crate::frost::{THRESHOLD, generate_keys, sign};
const RING_INDEX: u8 = 3;
const RING_LEN: u64 = 11;
const AMOUNT: u64 = 1337;
#[cfg(feature = "multisig")]
const RING_INDEX: u8 = 3;
#[test]
fn clsag() {
let msg = [1; 32];
for real in 0 .. RING_LEN {
let msg = [1; 32];
let mut secrets = [Scalar::zero(), Scalar::zero()];
let mut ring = vec![];
for i in 0 .. RING_LEN {
let dest = random_scalar(&mut OsRng);
let mask = random_scalar(&mut OsRng);
let amount;
if i == u64::from(RING_INDEX) {
secrets = [dest, mask];
amount = AMOUNT;
} else {
amount = OsRng.next_u64();
let mut secrets = [Scalar::zero(), Scalar::zero()];
let mut ring = vec![];
for i in 0 .. RING_LEN {
let dest = random_scalar(&mut OsRng);
let mask = random_scalar(&mut OsRng);
let amount;
if i == u64::from(real) {
secrets = [dest, mask];
amount = AMOUNT;
} else {
amount = OsRng.next_u64();
}
ring.push([&dest * &ED25519_BASEPOINT_TABLE, Commitment::new(mask, amount).calculate()]);
}
ring.push([&dest * &ED25519_BASEPOINT_TABLE, Commitment::new(mask, amount).calculate()]);
}
let image = key_image::generate(&secrets[0]);
let (clsag, pseudo_out) = clsag::sign(
&mut OsRng,
&vec![(
secrets[0],
image,
clsag::Input::new(
Commitment::new(secrets[1], AMOUNT),
Decoys {
i: RING_INDEX,
offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(),
ring: ring.clone()
}
).unwrap()
)],
random_scalar(&mut OsRng),
msg
).unwrap().swap_remove(0);
clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
#[cfg(feature = "experimental")]
clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
let image = key_image::generate(&secrets[0]);
let (clsag, pseudo_out) = clsag::sign(
&mut OsRng,
&vec![(
secrets[0],
image,
clsag::Input::new(
Commitment::new(secrets[1], AMOUNT),
Decoys {
i: u8::try_from(real).unwrap(),
offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(),
ring: ring.clone()
}
).unwrap()
)],
random_scalar(&mut OsRng),
msg
).unwrap().swap_remove(0);
clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
#[cfg(feature = "experimental")]
clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
}
}
#[cfg(feature = "multisig")]

View file

@ -10,7 +10,7 @@ mod frost;
use crate::frost::{THRESHOLD, PARTICIPANTS, generate_keys};
#[test]
fn test() {
fn key_image() {
let (keys, group_private) = generate_keys();
let image = key_image::generate(&group_private);