mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Finish updating crypto to new clippy
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
use core::{ops::Deref, fmt};
|
||||
use std::{io, collections::HashMap};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use zeroize::{Zeroize, Zeroizing};
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
@@ -70,7 +68,7 @@ impl<C: Ciphersuite, M: Message> EncryptionKeyMessage<C, M> {
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "tests"))]
|
||||
pub(crate) fn enc_key(&self) -> C::G {
|
||||
pub(crate) const fn enc_key(&self) -> C::G {
|
||||
self.enc_key
|
||||
}
|
||||
}
|
||||
@@ -110,6 +108,7 @@ fn cipher<C: Ciphersuite>(context: &str, ecdh: &Zeroizing<C::G>) -> ChaCha20 {
|
||||
transcript.append_message(b"shared_key", ecdh.as_ref());
|
||||
ecdh.as_mut().zeroize();
|
||||
|
||||
#[allow(clippy::redundant_closure_for_method_calls)] // Not redundant due to typing
|
||||
let zeroize = |buf: &mut [u8]| buf.zeroize();
|
||||
|
||||
let mut key = Cc20Key::default();
|
||||
@@ -329,13 +328,19 @@ fn encryption_key_transcript(context: &str) -> RecommendedTranscript {
|
||||
transcript
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
|
||||
pub(crate) enum DecryptionError {
|
||||
#[error("accused provided an invalid signature")]
|
||||
InvalidSignature,
|
||||
#[error("accuser provided an invalid decryption key")]
|
||||
InvalidProof,
|
||||
#[allow(clippy::std_instead_of_core)]
|
||||
mod decryption_error {
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
|
||||
pub(crate) enum DecryptionError {
|
||||
#[error("accused provided an invalid signature")]
|
||||
InvalidSignature,
|
||||
#[error("accuser provided an invalid decryption key")]
|
||||
InvalidProof,
|
||||
}
|
||||
}
|
||||
pub(crate) use decryption_error::DecryptionError;
|
||||
|
||||
// A simple box for managing encryption.
|
||||
#[derive(Clone)]
|
||||
@@ -381,7 +386,7 @@ impl<C: Ciphersuite> Encryption<C> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn registration<M: Message>(&self, msg: M) -> EncryptionKeyMessage<C, M> {
|
||||
pub(crate) const fn registration<M: Message>(&self, msg: M) -> EncryptionKeyMessage<C, M> {
|
||||
EncryptionKeyMessage { msg, enc_key: self.enc_pub_key }
|
||||
}
|
||||
|
||||
@@ -390,9 +395,10 @@ impl<C: Ciphersuite> Encryption<C> {
|
||||
participant: Participant,
|
||||
msg: EncryptionKeyMessage<C, M>,
|
||||
) -> M {
|
||||
if self.enc_keys.contains_key(&participant) {
|
||||
panic!("Re-registering encryption key for a participant");
|
||||
}
|
||||
assert!(
|
||||
!self.enc_keys.contains_key(&participant),
|
||||
"Re-registering encryption key for a participant"
|
||||
);
|
||||
self.enc_keys.insert(participant, msg.enc_key);
|
||||
msg.msg
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ impl<C: Ciphersuite> ReadWrite for Commitments<C> {
|
||||
commitments.push(read_G()?);
|
||||
}
|
||||
|
||||
Ok(Commitments { commitments, cached_msg, sig: SchnorrSignature::read(reader)? })
|
||||
Ok(Self { commitments, cached_msg, sig: SchnorrSignature::read(reader)? })
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
@@ -87,14 +87,16 @@ impl<C: Ciphersuite> ReadWrite for Commitments<C> {
|
||||
pub struct KeyGenMachine<C: Ciphersuite> {
|
||||
params: ThresholdParams,
|
||||
context: String,
|
||||
_curve: PhantomData<C>,
|
||||
curve: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C: Ciphersuite> KeyGenMachine<C> {
|
||||
/// Create a new machine to generate a key.
|
||||
// The context string should be unique among multisigs.
|
||||
pub fn new(params: ThresholdParams, context: String) -> KeyGenMachine<C> {
|
||||
KeyGenMachine { params, context, _curve: PhantomData }
|
||||
///
|
||||
/// The context string should be unique among multisigs.
|
||||
#[must_use]
|
||||
pub const fn new(params: ThresholdParams, context: String) -> Self {
|
||||
Self { params, context, curve: PhantomData }
|
||||
}
|
||||
|
||||
/// Start generating a key according to the FROST DKG spec.
|
||||
@@ -171,7 +173,6 @@ fn polynomial<F: PrimeField + Zeroize>(
|
||||
/// channel.
|
||||
///
|
||||
/// If any participant sends multiple secret shares to another participant, they are faulty.
|
||||
|
||||
// This should presumably be written as SecretShare(Zeroizing<F::Repr>).
|
||||
// It's unfortunately not possible as F::Repr doesn't have Zeroize as a bound.
|
||||
// The encryption system also explicitly uses Zeroizing<M> so it can ensure anything being
|
||||
@@ -195,7 +196,7 @@ impl<F: PrimeField> fmt::Debug for SecretShare<F> {
|
||||
}
|
||||
impl<F: PrimeField> Zeroize for SecretShare<F> {
|
||||
fn zeroize(&mut self) {
|
||||
self.0.as_mut().zeroize()
|
||||
self.0.as_mut().zeroize();
|
||||
}
|
||||
}
|
||||
// Still manually implement ZeroizeOnDrop to ensure these don't stick around.
|
||||
@@ -213,7 +214,7 @@ impl<F: PrimeField> ReadWrite for SecretShare<F> {
|
||||
fn read<R: Read>(reader: &mut R, _: ThresholdParams) -> io::Result<Self> {
|
||||
let mut repr = F::Repr::default();
|
||||
reader.read_exact(repr.as_mut())?;
|
||||
Ok(SecretShare(repr))
|
||||
Ok(Self(repr))
|
||||
}
|
||||
|
||||
fn write<W: Write>(&self, writer: &mut W) -> io::Result<()> {
|
||||
@@ -353,7 +354,7 @@ impl<C: Ciphersuite> Zeroize for KeyMachine<C> {
|
||||
fn zeroize(&mut self) {
|
||||
self.params.zeroize();
|
||||
self.secret.zeroize();
|
||||
for (_, commitments) in self.commitments.iter_mut() {
|
||||
for commitments in self.commitments.values_mut() {
|
||||
commitments.zeroize();
|
||||
}
|
||||
self.encryption.zeroize();
|
||||
@@ -466,7 +467,7 @@ impl<C: Ciphersuite> KeyMachine<C> {
|
||||
);
|
||||
}
|
||||
|
||||
let KeyMachine { commitments, encryption, params, secret } = self;
|
||||
let Self { commitments, encryption, params, secret } = self;
|
||||
Ok(BlameMachine {
|
||||
commitments,
|
||||
encryption,
|
||||
@@ -499,7 +500,7 @@ impl<C: Ciphersuite> fmt::Debug for BlameMachine<C> {
|
||||
|
||||
impl<C: Ciphersuite> Zeroize for BlameMachine<C> {
|
||||
fn zeroize(&mut self) {
|
||||
for (_, commitments) in self.commitments.iter_mut() {
|
||||
for commitments in self.commitments.values_mut() {
|
||||
commitments.zeroize();
|
||||
}
|
||||
self.encryption.zeroize();
|
||||
@@ -517,6 +518,7 @@ impl<C: Ciphersuite> BlameMachine<C> {
|
||||
/// territory of consensus protocols. This library does not handle that nor does it provide any
|
||||
/// tooling to do so. This function is solely intended to force users to acknowledge they're
|
||||
/// completing the protocol, not processing any blame.
|
||||
#[allow(clippy::missing_const_for_fn)] // False positive
|
||||
pub fn complete(self) -> ThresholdCore<C> {
|
||||
self.result
|
||||
}
|
||||
@@ -536,10 +538,9 @@ impl<C: Ciphersuite> BlameMachine<C> {
|
||||
Err(DecryptionError::InvalidProof) => return recipient,
|
||||
};
|
||||
|
||||
let share = match Option::<C::F>::from(C::F::from_repr(share_bytes.0)) {
|
||||
Some(share) => share,
|
||||
let Some(share) = Option::<C::F>::from(C::F::from_repr(share_bytes.0)) else {
|
||||
// If this isn't a valid scalar, the sender is faulty
|
||||
None => return sender,
|
||||
return sender;
|
||||
};
|
||||
|
||||
// If this isn't a valid share, the sender is faulty
|
||||
|
||||
@@ -3,9 +3,7 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use core::fmt::{self, Debug};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use thiserror::Error;
|
||||
extern crate alloc;
|
||||
|
||||
use zeroize::Zeroize;
|
||||
|
||||
@@ -35,23 +33,25 @@ pub mod tests;
|
||||
pub struct Participant(pub(crate) u16);
|
||||
impl Participant {
|
||||
/// Create a new Participant identifier from a u16.
|
||||
pub fn new(i: u16) -> Option<Participant> {
|
||||
#[must_use]
|
||||
pub const fn new(i: u16) -> Option<Self> {
|
||||
if i == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(Participant(i))
|
||||
Some(Self(i))
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a Participant identifier to bytes.
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn to_bytes(&self) -> [u8; 2] {
|
||||
#[must_use]
|
||||
pub const fn to_bytes(&self) -> [u8; 2] {
|
||||
self.0.to_le_bytes()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Participant> for u16 {
|
||||
fn from(participant: Participant) -> u16 {
|
||||
fn from(participant: Participant) -> Self {
|
||||
participant.0
|
||||
}
|
||||
}
|
||||
@@ -63,49 +63,58 @@ impl fmt::Display for Participant {
|
||||
}
|
||||
|
||||
/// Various errors possible during key generation.
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "std", derive(Error))]
|
||||
pub enum DkgError<B: Clone + PartialEq + Eq + Debug> {
|
||||
/// A parameter was zero.
|
||||
#[cfg_attr(feature = "std", error("a parameter was 0 (threshold {0}, participants {1})"))]
|
||||
ZeroParameter(u16, u16),
|
||||
/// The threshold exceeded the amount of participants.
|
||||
#[cfg_attr(feature = "std", error("invalid threshold (max {1}, got {0})"))]
|
||||
InvalidThreshold(u16, u16),
|
||||
/// Invalid participant identifier.
|
||||
#[cfg_attr(
|
||||
feature = "std",
|
||||
error("invalid participant (0 < participant <= {0}, yet participant is {1})")
|
||||
)]
|
||||
InvalidParticipant(u16, Participant),
|
||||
#[allow(clippy::std_instead_of_core)]
|
||||
mod dkg_error {
|
||||
use core::fmt::Debug;
|
||||
use thiserror::Error;
|
||||
use super::Participant;
|
||||
|
||||
/// Invalid signing set.
|
||||
#[cfg_attr(feature = "std", error("invalid signing set"))]
|
||||
InvalidSigningSet,
|
||||
/// Invalid amount of participants.
|
||||
#[cfg_attr(feature = "std", error("invalid participant quantity (expected {0}, got {1})"))]
|
||||
InvalidParticipantQuantity(usize, usize),
|
||||
/// A participant was duplicated.
|
||||
#[cfg_attr(feature = "std", error("duplicated participant ({0})"))]
|
||||
DuplicatedParticipant(Participant),
|
||||
/// A participant was missing.
|
||||
#[cfg_attr(feature = "std", error("missing participant {0}"))]
|
||||
MissingParticipant(Participant),
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
#[cfg_attr(feature = "std", derive(Error))]
|
||||
pub enum DkgError<B: Clone + PartialEq + Eq + Debug> {
|
||||
/// A parameter was zero.
|
||||
#[cfg_attr(feature = "std", error("a parameter was 0 (threshold {0}, participants {1})"))]
|
||||
ZeroParameter(u16, u16),
|
||||
/// The threshold exceeded the amount of participants.
|
||||
#[cfg_attr(feature = "std", error("invalid threshold (max {1}, got {0})"))]
|
||||
InvalidThreshold(u16, u16),
|
||||
/// Invalid participant identifier.
|
||||
#[cfg_attr(
|
||||
feature = "std",
|
||||
error("invalid participant (0 < participant <= {0}, yet participant is {1})")
|
||||
)]
|
||||
InvalidParticipant(u16, Participant),
|
||||
|
||||
/// An invalid proof of knowledge was provided.
|
||||
#[cfg_attr(feature = "std", error("invalid proof of knowledge (participant {0})"))]
|
||||
InvalidProofOfKnowledge(Participant),
|
||||
/// An invalid DKG share was provided.
|
||||
#[cfg_attr(feature = "std", error("invalid share (participant {participant}, blame {blame})"))]
|
||||
InvalidShare { participant: Participant, blame: Option<B> },
|
||||
/// Invalid signing set.
|
||||
#[cfg_attr(feature = "std", error("invalid signing set"))]
|
||||
InvalidSigningSet,
|
||||
/// Invalid amount of participants.
|
||||
#[cfg_attr(feature = "std", error("invalid participant quantity (expected {0}, got {1})"))]
|
||||
InvalidParticipantQuantity(usize, usize),
|
||||
/// A participant was duplicated.
|
||||
#[cfg_attr(feature = "std", error("duplicated participant ({0})"))]
|
||||
DuplicatedParticipant(Participant),
|
||||
/// A participant was missing.
|
||||
#[cfg_attr(feature = "std", error("missing participant {0}"))]
|
||||
MissingParticipant(Participant),
|
||||
|
||||
/// An invalid proof of knowledge was provided.
|
||||
#[cfg_attr(feature = "std", error("invalid proof of knowledge (participant {0})"))]
|
||||
InvalidProofOfKnowledge(Participant),
|
||||
/// An invalid DKG share was provided.
|
||||
#[cfg_attr(feature = "std", error("invalid share (participant {participant}, blame {blame})"))]
|
||||
InvalidShare { participant: Participant, blame: Option<B> },
|
||||
}
|
||||
}
|
||||
pub use dkg_error::DkgError;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
mod lib {
|
||||
pub use super::*;
|
||||
|
||||
use core::ops::Deref;
|
||||
use std::{io, sync::Arc, collections::HashMap};
|
||||
use alloc::sync::Arc;
|
||||
use std::{io, collections::HashMap};
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
@@ -158,7 +167,7 @@ mod lib {
|
||||
|
||||
impl ThresholdParams {
|
||||
/// Create a new set of parameters.
|
||||
pub fn new(t: u16, n: u16, i: Participant) -> Result<ThresholdParams, DkgError<()>> {
|
||||
pub fn new(t: u16, n: u16, i: Participant) -> Result<Self, DkgError<()>> {
|
||||
if (t == 0) || (n == 0) {
|
||||
Err(DkgError::ZeroParameter(t, n))?;
|
||||
}
|
||||
@@ -170,24 +179,28 @@ mod lib {
|
||||
Err(DkgError::InvalidParticipant(n, i))?;
|
||||
}
|
||||
|
||||
Ok(ThresholdParams { t, n, i })
|
||||
Ok(Self { t, n, i })
|
||||
}
|
||||
|
||||
/// Return the threshold for a multisig with these parameters.
|
||||
pub fn t(&self) -> u16 {
|
||||
#[must_use]
|
||||
pub const fn t(&self) -> u16 {
|
||||
self.t
|
||||
}
|
||||
/// Return the amount of participants for a multisig with these parameters.
|
||||
pub fn n(&self) -> u16 {
|
||||
#[must_use]
|
||||
pub const fn n(&self) -> u16 {
|
||||
self.n
|
||||
}
|
||||
/// Return the participant index of the share with these parameters.
|
||||
pub fn i(&self) -> Participant {
|
||||
#[must_use]
|
||||
pub const fn i(&self) -> Participant {
|
||||
self.i
|
||||
}
|
||||
}
|
||||
|
||||
/// Calculate the lagrange coefficient for a signing set.
|
||||
#[must_use]
|
||||
pub fn lagrange<F: PrimeField>(i: Participant, included: &[Participant]) -> F {
|
||||
let i_f = F::from(u64::from(u16::from(i)));
|
||||
|
||||
@@ -239,20 +252,21 @@ mod lib {
|
||||
self.params.zeroize();
|
||||
self.secret_share.zeroize();
|
||||
self.group_key.zeroize();
|
||||
for (_, share) in self.verification_shares.iter_mut() {
|
||||
for share in self.verification_shares.values_mut() {
|
||||
share.zeroize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Ciphersuite> ThresholdCore<C> {
|
||||
#[must_use]
|
||||
pub(crate) fn new(
|
||||
params: ThresholdParams,
|
||||
secret_share: Zeroizing<C::F>,
|
||||
verification_shares: HashMap<Participant, C::G>,
|
||||
) -> ThresholdCore<C> {
|
||||
) -> Self {
|
||||
let t = (1 ..= params.t()).map(Participant).collect::<Vec<_>>();
|
||||
ThresholdCore {
|
||||
Self {
|
||||
params,
|
||||
secret_share,
|
||||
group_key: t.iter().map(|i| verification_shares[i] * lagrange::<C::F>(*i, &t)).sum(),
|
||||
@@ -261,17 +275,17 @@ mod lib {
|
||||
}
|
||||
|
||||
/// Parameters for these keys.
|
||||
pub fn params(&self) -> ThresholdParams {
|
||||
pub const fn params(&self) -> ThresholdParams {
|
||||
self.params
|
||||
}
|
||||
|
||||
/// Secret share for these keys.
|
||||
pub fn secret_share(&self) -> &Zeroizing<C::F> {
|
||||
pub const fn secret_share(&self) -> &Zeroizing<C::F> {
|
||||
&self.secret_share
|
||||
}
|
||||
|
||||
/// Group key for these keys.
|
||||
pub fn group_key(&self) -> C::G {
|
||||
pub const fn group_key(&self) -> C::G {
|
||||
self.group_key
|
||||
}
|
||||
|
||||
@@ -304,7 +318,7 @@ mod lib {
|
||||
}
|
||||
|
||||
/// Read keys from a type satisfying std::io::Read.
|
||||
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<ThresholdCore<C>> {
|
||||
pub fn read<R: io::Read>(reader: &mut R) -> io::Result<Self> {
|
||||
{
|
||||
let different =
|
||||
|| io::Error::new(io::ErrorKind::Other, "deserializing ThresholdCore for another curve");
|
||||
@@ -332,7 +346,7 @@ mod lib {
|
||||
read_u16()?,
|
||||
read_u16()?,
|
||||
Participant::new(read_u16()?)
|
||||
.ok_or(io::Error::new(io::ErrorKind::Other, "invalid participant index"))?,
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid participant index"))?,
|
||||
)
|
||||
};
|
||||
|
||||
@@ -343,7 +357,7 @@ mod lib {
|
||||
verification_shares.insert(l, <C as Ciphersuite>::read_G(reader)?);
|
||||
}
|
||||
|
||||
Ok(ThresholdCore::new(
|
||||
Ok(Self::new(
|
||||
ThresholdParams::new(t, n, i)
|
||||
.map_err(|_| io::Error::new(io::ErrorKind::Other, "invalid parameters"))?,
|
||||
secret_share,
|
||||
@@ -395,10 +409,10 @@ mod lib {
|
||||
self.group_key.zeroize();
|
||||
self.included.zeroize();
|
||||
self.secret_share.zeroize();
|
||||
for (_, share) in self.original_verification_shares.iter_mut() {
|
||||
for share in self.original_verification_shares.values_mut() {
|
||||
share.zeroize();
|
||||
}
|
||||
for (_, share) in self.verification_shares.iter_mut() {
|
||||
for share in self.verification_shares.values_mut() {
|
||||
share.zeroize();
|
||||
}
|
||||
}
|
||||
@@ -406,8 +420,9 @@ mod lib {
|
||||
|
||||
impl<C: Ciphersuite> ThresholdKeys<C> {
|
||||
/// Create a new set of ThresholdKeys from a ThresholdCore.
|
||||
pub fn new(core: ThresholdCore<C>) -> ThresholdKeys<C> {
|
||||
ThresholdKeys { core: Arc::new(core), offset: None }
|
||||
#[must_use]
|
||||
pub fn new(core: ThresholdCore<C>) -> Self {
|
||||
Self { core: Arc::new(core), offset: None }
|
||||
}
|
||||
|
||||
/// Offset the keys by a given scalar to allow for various account and privacy schemes.
|
||||
@@ -415,7 +430,7 @@ mod lib {
|
||||
/// This offset is ephemeral and will not be included when these keys are serialized. It also
|
||||
/// accumulates, so calling offset multiple times will produce a offset of the offsets' sum.
|
||||
#[must_use]
|
||||
pub fn offset(&self, offset: C::F) -> ThresholdKeys<C> {
|
||||
pub fn offset(&self, offset: C::F) -> Self {
|
||||
let mut res = self.clone();
|
||||
// Carry any existing offset
|
||||
// Enables schemes like Monero's subaddresses which have a per-subaddress offset and then a
|
||||
@@ -425,7 +440,7 @@ mod lib {
|
||||
}
|
||||
|
||||
/// Return the current offset in-use for these keys.
|
||||
pub fn current_offset(&self) -> Option<C::F> {
|
||||
pub const fn current_offset(&self) -> Option<C::F> {
|
||||
self.offset
|
||||
}
|
||||
|
||||
@@ -469,7 +484,7 @@ mod lib {
|
||||
);
|
||||
|
||||
let mut verification_shares = self.verification_shares();
|
||||
for (i, share) in verification_shares.iter_mut() {
|
||||
for (i, share) in &mut verification_shares {
|
||||
*share *= lagrange::<C::F>(*i, &included);
|
||||
}
|
||||
|
||||
@@ -492,19 +507,19 @@ mod lib {
|
||||
}
|
||||
|
||||
impl<C: Ciphersuite> From<ThresholdCore<C>> for ThresholdKeys<C> {
|
||||
fn from(keys: ThresholdCore<C>) -> ThresholdKeys<C> {
|
||||
ThresholdKeys::new(keys)
|
||||
fn from(keys: ThresholdCore<C>) -> Self {
|
||||
Self::new(keys)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Ciphersuite> ThresholdView<C> {
|
||||
/// Return the offset for this view.
|
||||
pub fn offset(&self) -> C::F {
|
||||
pub const fn offset(&self) -> C::F {
|
||||
self.offset
|
||||
}
|
||||
|
||||
/// Return the group key.
|
||||
pub fn group_key(&self) -> C::G {
|
||||
pub const fn group_key(&self) -> C::G {
|
||||
self.group_key
|
||||
}
|
||||
|
||||
@@ -514,7 +529,7 @@ mod lib {
|
||||
}
|
||||
|
||||
/// Return the interpolated, offset secret share.
|
||||
pub fn secret_share(&self) -> &Zeroizing<C::F> {
|
||||
pub const fn secret_share(&self) -> &Zeroizing<C::F> {
|
||||
&self.secret_share
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use core::{marker::PhantomData, ops::Deref};
|
||||
use alloc::sync::Arc;
|
||||
use std::{
|
||||
io::{self, Read, Write},
|
||||
sync::Arc,
|
||||
collections::HashMap,
|
||||
};
|
||||
|
||||
@@ -45,11 +45,8 @@ impl<C: Ciphersuite> GeneratorProof<C> {
|
||||
self.proof.write(writer)
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(reader: &mut R) -> io::Result<GeneratorProof<C>> {
|
||||
Ok(GeneratorProof {
|
||||
share: <C as Ciphersuite>::read_G(reader)?,
|
||||
proof: DLEqProof::read(reader)?,
|
||||
})
|
||||
pub fn read<R: Read>(reader: &mut R) -> io::Result<Self> {
|
||||
Ok(Self { share: <C as Ciphersuite>::read_G(reader)?, proof: DLEqProof::read(reader)? })
|
||||
}
|
||||
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
@@ -70,16 +67,13 @@ pub struct GeneratorPromotion<C1: Ciphersuite, C2: Ciphersuite> {
|
||||
_c2: PhantomData<C2>,
|
||||
}
|
||||
|
||||
impl<C1: Ciphersuite, C2: Ciphersuite> GeneratorPromotion<C1, C2>
|
||||
where
|
||||
C2: Ciphersuite<F = C1::F, G = C1::G>,
|
||||
{
|
||||
impl<C1: Ciphersuite, C2: Ciphersuite<F = C1::F, G = C1::G>> GeneratorPromotion<C1, C2> {
|
||||
/// Begin promoting keys from one generator to another. Returns a proof this share was properly
|
||||
/// promoted.
|
||||
pub fn promote<R: RngCore + CryptoRng>(
|
||||
rng: &mut R,
|
||||
base: ThresholdKeys<C1>,
|
||||
) -> (GeneratorPromotion<C1, C2>, GeneratorProof<C1>) {
|
||||
) -> (Self, GeneratorProof<C1>) {
|
||||
// Do a DLEqProof for the new generator
|
||||
let proof = GeneratorProof {
|
||||
share: C2::generator() * base.secret_share().deref(),
|
||||
@@ -91,7 +85,7 @@ where
|
||||
),
|
||||
};
|
||||
|
||||
(GeneratorPromotion { base, proof, _c2: PhantomData::<C2> }, proof)
|
||||
(Self { base, proof, _c2: PhantomData::<C2> }, proof)
|
||||
}
|
||||
|
||||
/// Complete promotion by taking in the proofs from all other participants.
|
||||
|
||||
@@ -25,7 +25,7 @@ pub const PARTICIPANTS: u16 = 5;
|
||||
pub const THRESHOLD: u16 = ((PARTICIPANTS * 2) / 3) + 1;
|
||||
|
||||
/// Clone a map without a specific value.
|
||||
pub fn clone_without<K: Clone + std::cmp::Eq + std::hash::Hash, V: Clone>(
|
||||
pub fn clone_without<K: Clone + core::cmp::Eq + core::hash::Hash, V: Clone>(
|
||||
map: &HashMap<K, V>,
|
||||
without: &K,
|
||||
) -> HashMap<K, V> {
|
||||
@@ -40,7 +40,7 @@ pub fn clone_without<K: Clone + std::cmp::Eq + std::hash::Hash, V: Clone>(
|
||||
pub fn recover_key<C: Ciphersuite>(keys: &HashMap<Participant, ThresholdKeys<C>>) -> C::F {
|
||||
let first = keys.values().next().expect("no keys provided");
|
||||
assert!(keys.len() >= first.params().t().into(), "not enough keys provided");
|
||||
let included = keys.keys().cloned().collect::<Vec<_>>();
|
||||
let included = keys.keys().copied().collect::<Vec<_>>();
|
||||
|
||||
let group_private = keys.iter().fold(C::F::ZERO, |accum, (i, keys)| {
|
||||
accum + (lagrange::<C::F>(*i, &included) * keys.secret_share().deref())
|
||||
@@ -95,6 +95,7 @@ pub fn test_ciphersuite<R: RngCore + CryptoRng, C: Ciphersuite>(rng: &mut R) {
|
||||
test_generator_promotion::<_, C>(rng);
|
||||
}
|
||||
|
||||
#[allow(clippy::tests_outside_test_module)]
|
||||
#[test]
|
||||
fn test_with_ristretto() {
|
||||
test_ciphersuite::<_, ciphersuite::Ristretto>(&mut rand_core::OsRng);
|
||||
|
||||
@@ -24,9 +24,9 @@ pub fn test_musig<R: RngCore + CryptoRng, C: Ciphersuite>(rng: &mut R) {
|
||||
const CONTEXT: &[u8] = b"MuSig Test";
|
||||
|
||||
// Empty signing set
|
||||
assert!(musig::<C>(CONTEXT, &Zeroizing::new(C::F::ZERO), &[]).is_err());
|
||||
musig::<C>(CONTEXT, &Zeroizing::new(C::F::ZERO), &[]).unwrap_err();
|
||||
// Signing set we're not part of
|
||||
assert!(musig::<C>(CONTEXT, &Zeroizing::new(C::F::ZERO), &[C::generator()]).is_err());
|
||||
musig::<C>(CONTEXT, &Zeroizing::new(C::F::ZERO), &[C::generator()]).unwrap_err();
|
||||
|
||||
// Test with n keys
|
||||
{
|
||||
@@ -55,7 +55,8 @@ pub fn test_musig<R: RngCore + CryptoRng, C: Ciphersuite>(rng: &mut R) {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::tests_outside_test_module)]
|
||||
#[test]
|
||||
fn musig_literal() {
|
||||
test_musig::<_, ciphersuite::Ristretto>(&mut rand_core::OsRng)
|
||||
test_musig::<_, ciphersuite::Ristretto>(&mut rand_core::OsRng);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::{
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
|
||||
struct AltGenerator<C: Ciphersuite> {
|
||||
_curve: PhantomData<C>,
|
||||
curve: PhantomData<C>,
|
||||
}
|
||||
|
||||
impl<C: Ciphersuite> Ciphersuite for AltGenerator<C> {
|
||||
|
||||
Reference in New Issue
Block a user