mirror of
https://github.com/serai-dex/serai.git
synced 2025-03-12 09:26:51 +00:00
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:
parent
0aeab04c70
commit
94bd30083b
4 changed files with 54 additions and 60 deletions
|
@ -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>(
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue