mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Respond to 1.1 A1
This commit is contained in:
@@ -100,7 +100,7 @@ fn core(
|
||||
ring: &[[EdwardsPoint; 2]],
|
||||
I: &EdwardsPoint,
|
||||
pseudo_out: &EdwardsPoint,
|
||||
msg: &[u8; 32],
|
||||
msg_hash: &[u8; 32],
|
||||
D: &EdwardsPoint,
|
||||
s: &[Scalar],
|
||||
A_c1: &Mode,
|
||||
@@ -156,7 +156,7 @@ fn core(
|
||||
// Unfortunately, it's I D pseudo_out instead of pseudo_out I D, meaning this needs to be
|
||||
// truncated just to add it back
|
||||
to_hash.extend(pseudo_out.compress().to_bytes());
|
||||
to_hash.extend(msg);
|
||||
to_hash.extend(msg_hash);
|
||||
|
||||
// Configure the loop based on if we're signing or verifying
|
||||
let start;
|
||||
@@ -245,7 +245,7 @@ impl Clsag {
|
||||
I: &EdwardsPoint,
|
||||
input: &ClsagContext,
|
||||
mask: Scalar,
|
||||
msg: &[u8; 32],
|
||||
msg_hash: &[u8; 32],
|
||||
A: EdwardsPoint,
|
||||
AH: EdwardsPoint,
|
||||
) -> ClsagSignCore {
|
||||
@@ -261,7 +261,7 @@ impl Clsag {
|
||||
s.push(Scalar::random(rng));
|
||||
}
|
||||
let ((D, c_p, c_c), c1) =
|
||||
core(input.decoys.ring(), I, &pseudo_out, msg, &D, &s, &Mode::Sign(r, A, AH));
|
||||
core(input.decoys.ring(), I, &pseudo_out, msg_hash, &D, &s, &Mode::Sign(r, A, AH));
|
||||
|
||||
ClsagSignCore {
|
||||
incomplete_clsag: Clsag { D, s, c1 },
|
||||
@@ -288,11 +288,15 @@ impl Clsag {
|
||||
/// `inputs` is of the form (discrete logarithm of the key, context).
|
||||
///
|
||||
/// `sum_outputs` is for the sum of the output commitments' masks.
|
||||
///
|
||||
/// WARNING: This follows the Fiat-Shamir transcript format used by the Monero protocol, which
|
||||
/// makes assumptions on what has already been transcripted and bound to within `msg_hash`. Do
|
||||
/// not use this if you don't know what you're doing.
|
||||
pub fn sign<R: RngCore + CryptoRng>(
|
||||
rng: &mut R,
|
||||
mut inputs: Vec<(Zeroizing<Scalar>, ClsagContext)>,
|
||||
sum_outputs: Scalar,
|
||||
msg: [u8; 32],
|
||||
msg_hash: [u8; 32],
|
||||
) -> Result<Vec<(Clsag, EdwardsPoint)>, ClsagError> {
|
||||
// Create the key images
|
||||
let mut key_image_generators = vec![];
|
||||
@@ -329,7 +333,7 @@ impl Clsag {
|
||||
&key_images[i],
|
||||
&inputs[i].1,
|
||||
mask,
|
||||
&msg,
|
||||
&msg_hash,
|
||||
nonce.deref() * ED25519_BASEPOINT_TABLE,
|
||||
nonce.deref() * key_image_generators[i],
|
||||
);
|
||||
@@ -345,7 +349,7 @@ impl Clsag {
|
||||
nonce.zeroize();
|
||||
|
||||
debug_assert!(clsag
|
||||
.verify(inputs[i].1.decoys.ring(), &key_images[i], &pseudo_out, &msg)
|
||||
.verify(inputs[i].1.decoys.ring(), &key_images[i], &pseudo_out, &msg_hash)
|
||||
.is_ok());
|
||||
|
||||
res.push((clsag, pseudo_out));
|
||||
@@ -360,7 +364,7 @@ impl Clsag {
|
||||
ring: &[[EdwardsPoint; 2]],
|
||||
I: &EdwardsPoint,
|
||||
pseudo_out: &EdwardsPoint,
|
||||
msg: &[u8; 32],
|
||||
msg_hash: &[u8; 32],
|
||||
) -> Result<(), ClsagError> {
|
||||
// Preliminary checks
|
||||
// s, c1, and points must also be encoded canonically, which is checked at time of decode
|
||||
@@ -379,7 +383,7 @@ impl Clsag {
|
||||
Err(ClsagError::InvalidD)?;
|
||||
}
|
||||
|
||||
let (_, c1) = core(ring, I, pseudo_out, msg, &D, &self.s, &Mode::Verify(self.c1));
|
||||
let (_, c1) = core(ring, I, pseudo_out, msg_hash, &D, &self.s, &Mode::Verify(self.c1));
|
||||
if c1 != self.c1 {
|
||||
Err(ClsagError::InvalidC1)?;
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ pub struct ClsagMultisig {
|
||||
mask_recv: Option<ClsagMultisigMaskReceiver>,
|
||||
mask: Option<Scalar>,
|
||||
|
||||
msg: Option<[u8; 32]>,
|
||||
msg_hash: Option<[u8; 32]>,
|
||||
interim: Option<Interim>,
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ impl ClsagMultisig {
|
||||
mask_recv: Some(mask_recv),
|
||||
mask: None,
|
||||
|
||||
msg: None,
|
||||
msg_hash: None,
|
||||
interim: None,
|
||||
},
|
||||
mask_send,
|
||||
@@ -253,7 +253,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
||||
view: &ThresholdView<Ed25519>,
|
||||
nonce_sums: &[Vec<dfg::EdwardsPoint>],
|
||||
nonces: Vec<Zeroizing<dfg::Scalar>>,
|
||||
msg: &[u8],
|
||||
msg_hash: &[u8],
|
||||
) -> dfg::Scalar {
|
||||
// Use the transcript to get a seeded random number generator
|
||||
//
|
||||
@@ -264,14 +264,14 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
||||
// opening of the commitment being re-randomized (and what it's re-randomized to)
|
||||
let mut rng = ChaCha20Rng::from_seed(self.transcript.rng_seed(b"decoy_responses"));
|
||||
|
||||
self.msg = Some(msg.try_into().expect("CLSAG message should be 32-bytes"));
|
||||
self.msg_hash = Some(msg_hash.try_into().expect("CLSAG message hash should be 32-bytes"));
|
||||
|
||||
let sign_core = Clsag::sign_core(
|
||||
&mut rng,
|
||||
&self.image.expect("verifying a share despite never processing any addendums").0,
|
||||
&self.context,
|
||||
self.mask.expect("mask wasn't set"),
|
||||
self.msg.as_ref().unwrap(),
|
||||
self.msg_hash.as_ref().unwrap(),
|
||||
nonce_sums[0][0].0,
|
||||
nonce_sums[0][1].0,
|
||||
);
|
||||
@@ -303,7 +303,7 @@ impl Algorithm<Ed25519> for ClsagMultisig {
|
||||
self.context.decoys.ring(),
|
||||
&self.image.expect("verifying a signature despite never processing any addendums").0,
|
||||
&interim.pseudo_out,
|
||||
self.msg.as_ref().unwrap(),
|
||||
self.msg_hash.as_ref().unwrap(),
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
|
||||
@@ -31,7 +31,7 @@ const RING_INDEX: u8 = 3;
|
||||
#[test]
|
||||
fn clsag() {
|
||||
for real in 0 .. RING_LEN {
|
||||
let msg = [1; 32];
|
||||
let msg_hash = [1; 32];
|
||||
|
||||
let mut secrets = (Zeroizing::new(Scalar::ZERO), Scalar::ZERO);
|
||||
let mut ring = vec![];
|
||||
@@ -61,18 +61,18 @@ fn clsag() {
|
||||
.unwrap(),
|
||||
)],
|
||||
Scalar::random(&mut OsRng),
|
||||
msg,
|
||||
msg_hash,
|
||||
)
|
||||
.unwrap()
|
||||
.swap_remove(0);
|
||||
|
||||
let image =
|
||||
hash_to_point((ED25519_BASEPOINT_TABLE * secrets.0.deref()).compress().0) * secrets.0.deref();
|
||||
clsag.verify(&ring, &image, &pseudo_out, &msg).unwrap();
|
||||
clsag.verify(&ring, &image, &pseudo_out, &msg_hash).unwrap();
|
||||
|
||||
// make sure verification fails if we throw a random `c1` at it.
|
||||
clsag.c1 = Scalar::random(&mut OsRng);
|
||||
assert!(clsag.verify(&ring, &image, &pseudo_out, &msg).is_err());
|
||||
assert!(clsag.verify(&ring, &image, &pseudo_out, &msg_hash).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user