mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 12:49:23 +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:
@@ -140,36 +140,32 @@ fn core(
|
|||||||
to_hash.extend(pseudo_out.compress().to_bytes());
|
to_hash.extend(pseudo_out.compress().to_bytes());
|
||||||
to_hash.extend(msg);
|
to_hash.extend(msg);
|
||||||
|
|
||||||
let mut c;
|
let start;
|
||||||
let mut c1 = Scalar::zero();
|
|
||||||
|
|
||||||
let end;
|
let end;
|
||||||
let mut i;
|
let mut c;
|
||||||
|
|
||||||
match A_c1 {
|
match A_c1 {
|
||||||
Mode::Sign(r, A, AH) => {
|
Mode::Sign(r, A, AH) => {
|
||||||
|
start = r + 1;
|
||||||
|
end = r + n;
|
||||||
to_hash.extend(A.compress().to_bytes());
|
to_hash.extend(A.compress().to_bytes());
|
||||||
to_hash.extend(AH.compress().to_bytes());
|
to_hash.extend(AH.compress().to_bytes());
|
||||||
c = hash_to_scalar(&to_hash);
|
c = hash_to_scalar(&to_hash);
|
||||||
|
|
||||||
end = r;
|
|
||||||
i = (end + 1) % n;
|
|
||||||
if i == 0 {
|
|
||||||
c1 = c;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
Mode::Verify(c1) => {
|
Mode::Verify(c1) => {
|
||||||
end = 0;
|
start = 0;
|
||||||
i = 0;
|
end = n;
|
||||||
c = c1;
|
c = c1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut first = true;
|
let mut c1 = None;
|
||||||
while (i != end) || first {
|
for i in (start .. end).map(|i| i % n) {
|
||||||
first = false;
|
if i == 0 {
|
||||||
|
c1 = Some(c);
|
||||||
|
}
|
||||||
|
|
||||||
let c_p = mu_P * c;
|
let c_p = mu_P * c;
|
||||||
let c_c = mu_C * c;
|
let c_c = mu_C * c;
|
||||||
|
|
||||||
@@ -182,14 +178,9 @@ fn core(
|
|||||||
to_hash.extend(L.compress().to_bytes());
|
to_hash.extend(L.compress().to_bytes());
|
||||||
to_hash.extend(R.compress().to_bytes());
|
to_hash.extend(R.compress().to_bytes());
|
||||||
c = hash_to_scalar(&to_hash);
|
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>(
|
pub(crate) fn sign_core<R: RngCore + CryptoRng>(
|
||||||
|
|||||||
@@ -260,7 +260,6 @@ impl Algorithm<Ed25519> for Multisig {
|
|||||||
sum: dfg::Scalar
|
sum: dfg::Scalar
|
||||||
) -> Option<Self::Signature> {
|
) -> Option<Self::Signature> {
|
||||||
let interim = self.interim.as_ref().unwrap();
|
let interim = self.interim.as_ref().unwrap();
|
||||||
|
|
||||||
let mut clsag = interim.clsag.clone();
|
let mut clsag = interim.clsag.clone();
|
||||||
clsag.s[usize::from(self.input().decoys.i)] = Key { key: (sum.0 - interim.c).to_bytes() };
|
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() {
|
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")]
|
#[cfg(feature = "multisig")]
|
||||||
use crate::frost::{THRESHOLD, generate_keys, sign};
|
use crate::frost::{THRESHOLD, generate_keys, sign};
|
||||||
|
|
||||||
const RING_INDEX: u8 = 3;
|
|
||||||
const RING_LEN: u64 = 11;
|
const RING_LEN: u64 = 11;
|
||||||
const AMOUNT: u64 = 1337;
|
const AMOUNT: u64 = 1337;
|
||||||
|
|
||||||
|
#[cfg(feature = "multisig")]
|
||||||
|
const RING_INDEX: u8 = 3;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn clsag() {
|
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 secrets = [Scalar::zero(), Scalar::zero()];
|
||||||
let mut ring = vec![];
|
let mut ring = vec![];
|
||||||
for i in 0 .. RING_LEN {
|
for i in 0 .. RING_LEN {
|
||||||
let dest = random_scalar(&mut OsRng);
|
let dest = random_scalar(&mut OsRng);
|
||||||
let mask = random_scalar(&mut OsRng);
|
let mask = random_scalar(&mut OsRng);
|
||||||
let amount;
|
let amount;
|
||||||
if i == u64::from(RING_INDEX) {
|
if i == u64::from(real) {
|
||||||
secrets = [dest, mask];
|
secrets = [dest, mask];
|
||||||
amount = AMOUNT;
|
amount = AMOUNT;
|
||||||
} else {
|
} else {
|
||||||
amount = OsRng.next_u64();
|
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 image = key_image::generate(&secrets[0]);
|
||||||
let (clsag, pseudo_out) = clsag::sign(
|
let (clsag, pseudo_out) = clsag::sign(
|
||||||
&mut OsRng,
|
&mut OsRng,
|
||||||
&vec![(
|
&vec![(
|
||||||
secrets[0],
|
secrets[0],
|
||||||
image,
|
image,
|
||||||
clsag::Input::new(
|
clsag::Input::new(
|
||||||
Commitment::new(secrets[1], AMOUNT),
|
Commitment::new(secrets[1], AMOUNT),
|
||||||
Decoys {
|
Decoys {
|
||||||
i: RING_INDEX,
|
i: u8::try_from(real).unwrap(),
|
||||||
offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(),
|
offsets: (1 ..= RING_LEN).into_iter().map(|o| VarInt(o)).collect(),
|
||||||
ring: ring.clone()
|
ring: ring.clone()
|
||||||
}
|
}
|
||||||
).unwrap()
|
).unwrap()
|
||||||
)],
|
)],
|
||||||
random_scalar(&mut OsRng),
|
random_scalar(&mut OsRng),
|
||||||
msg
|
msg
|
||||||
).unwrap().swap_remove(0);
|
).unwrap().swap_remove(0);
|
||||||
clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
|
clsag::verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
|
||||||
#[cfg(feature = "experimental")]
|
#[cfg(feature = "experimental")]
|
||||||
clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
|
clsag::rust_verify(&clsag, &ring, &image, &pseudo_out, &msg).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ mod frost;
|
|||||||
use crate::frost::{THRESHOLD, PARTICIPANTS, generate_keys};
|
use crate::frost::{THRESHOLD, PARTICIPANTS, generate_keys};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test() {
|
fn key_image() {
|
||||||
let (keys, group_private) = generate_keys();
|
let (keys, group_private) = generate_keys();
|
||||||
let image = key_image::generate(&group_private);
|
let image = key_image::generate(&group_private);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user