2022-06-30 05:42:29 -04:00
|
|
|
use std::{convert::TryInto, io::Cursor};
|
2022-04-21 21:36:18 -04:00
|
|
|
|
2022-04-28 03:31:09 -04:00
|
|
|
use thiserror::Error;
|
2022-05-03 07:20:24 -04:00
|
|
|
use rand_core::{RngCore, CryptoRng};
|
2022-04-21 21:36:18 -04:00
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
use curve25519_dalek::{scalar::Scalar, edwards::EdwardsPoint};
|
2022-06-28 01:25:26 -04:00
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
use group::{Group, GroupEncoding};
|
2022-04-21 21:36:18 -04:00
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
use transcript::RecommendedTranscript;
|
2022-05-03 08:49:46 -04:00
|
|
|
use dalek_ff_group as dfg;
|
2022-06-30 05:42:29 -04:00
|
|
|
use dleq::{Generators, DLEqProof};
|
2022-04-28 03:31:09 -04:00
|
|
|
|
2022-05-28 05:08:37 -04:00
|
|
|
#[derive(Clone, Error, Debug)]
|
2022-04-28 03:31:09 -04:00
|
|
|
pub enum MultisigError {
|
|
|
|
|
#[error("internal error ({0})")]
|
|
|
|
|
InternalError(String),
|
2022-04-29 22:03:34 -04:00
|
|
|
#[error("invalid discrete log equality proof")]
|
2022-05-24 21:41:14 -04:00
|
|
|
InvalidDLEqProof(u16),
|
2022-04-28 03:31:09 -04:00
|
|
|
#[error("invalid key image {0}")]
|
2022-05-24 21:41:14 -04:00
|
|
|
InvalidKeyImage(u16)
|
2022-04-28 03:31:09 -04:00
|
|
|
}
|
2022-04-21 21:36:18 -04:00
|
|
|
|
|
|
|
|
#[allow(non_snake_case)]
|
2022-06-30 05:42:29 -04:00
|
|
|
pub(crate) fn write_dleq<R: RngCore + CryptoRng>(
|
|
|
|
|
rng: &mut R,
|
|
|
|
|
H: EdwardsPoint,
|
|
|
|
|
x: Scalar
|
|
|
|
|
) -> Vec<u8> {
|
|
|
|
|
let mut res = Vec::with_capacity(64);
|
|
|
|
|
DLEqProof::prove(
|
|
|
|
|
rng,
|
2022-05-23 03:24:33 -04:00
|
|
|
// Doesn't take in a larger transcript object due to the usage of this
|
|
|
|
|
// Every prover would immediately write their own DLEq proof, when they can only do so in
|
|
|
|
|
// the proper order if they want to reach consensus
|
|
|
|
|
// It'd be a poor API to have CLSAG define a new transcript solely to pass here, just to try to
|
|
|
|
|
// merge later in some form, when it should instead just merge xH (as it does)
|
2022-06-30 05:42:29 -04:00
|
|
|
&mut RecommendedTranscript::new(b"DLEq Proof"),
|
|
|
|
|
Generators::new(dfg::EdwardsPoint::generator(), dfg::EdwardsPoint(H)),
|
|
|
|
|
dfg::Scalar(x)
|
|
|
|
|
).serialize(&mut res).unwrap();
|
|
|
|
|
res
|
2022-04-21 21:36:18 -04:00
|
|
|
}
|
2022-05-17 19:15:53 -04:00
|
|
|
|
|
|
|
|
#[allow(non_snake_case)]
|
2022-06-28 01:25:26 -04:00
|
|
|
pub(crate) fn read_dleq(
|
2022-05-17 19:15:53 -04:00
|
|
|
serialized: &[u8],
|
|
|
|
|
start: usize,
|
2022-06-30 05:42:29 -04:00
|
|
|
H: EdwardsPoint,
|
2022-05-24 21:41:14 -04:00
|
|
|
l: u16,
|
2022-06-30 05:42:29 -04:00
|
|
|
xG: dfg::EdwardsPoint
|
2022-05-17 19:15:53 -04:00
|
|
|
) -> Result<dfg::EdwardsPoint, MultisigError> {
|
2022-06-28 01:25:26 -04:00
|
|
|
if serialized.len() < start + 96 {
|
|
|
|
|
Err(MultisigError::InvalidDLEqProof(l))?;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let bytes = (&serialized[(start + 0) .. (start + 32)]).try_into().unwrap();
|
|
|
|
|
// dfg ensures the point is torsion free
|
2022-06-30 05:42:29 -04:00
|
|
|
let xH = Option::<dfg::EdwardsPoint>::from(
|
2022-06-28 01:25:26 -04:00
|
|
|
dfg::EdwardsPoint::from_bytes(&bytes)).ok_or(MultisigError::InvalidDLEqProof(l)
|
|
|
|
|
)?;
|
|
|
|
|
// Ensure this is a canonical point
|
2022-06-30 05:42:29 -04:00
|
|
|
if xH.to_bytes() != bytes {
|
2022-06-28 01:25:26 -04:00
|
|
|
Err(MultisigError::InvalidDLEqProof(l))?;
|
|
|
|
|
}
|
2022-05-17 19:15:53 -04:00
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
let proof = DLEqProof::<dfg::EdwardsPoint>::deserialize(
|
|
|
|
|
&mut Cursor::new(&serialized[(start + 32) .. (start + 96)])
|
|
|
|
|
).map_err(|_| MultisigError::InvalidDLEqProof(l))?;
|
|
|
|
|
|
|
|
|
|
let mut transcript = RecommendedTranscript::new(b"DLEq Proof");
|
|
|
|
|
proof.verify(&mut transcript, Generators::new(dfg::EdwardsPoint::generator(), dfg::EdwardsPoint(H)), (xG, xH))
|
|
|
|
|
.map_err(|_| MultisigError::InvalidDLEqProof(l))?;
|
2022-05-17 19:15:53 -04:00
|
|
|
|
2022-06-30 05:42:29 -04:00
|
|
|
Ok(xH)
|
2022-05-17 19:15:53 -04:00
|
|
|
}
|