mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 20:59:23 +00:00
Port common, and most of crypto, to a more aggressive clippy
This commit is contained in:
@@ -37,12 +37,12 @@ pub(crate) enum Re<G0: PrimeGroup, G1: PrimeGroup> {
|
||||
|
||||
impl<G0: PrimeGroup, G1: PrimeGroup> Re<G0, G1> {
|
||||
#[allow(non_snake_case)]
|
||||
pub(crate) fn R_default() -> Re<G0, G1> {
|
||||
Re::R(G0::identity(), G1::identity())
|
||||
pub(crate) fn R_default() -> Self {
|
||||
Self::R(G0::identity(), G1::identity())
|
||||
}
|
||||
|
||||
pub(crate) fn e_default() -> Re<G0, G1> {
|
||||
Re::e(G0::Scalar::ZERO)
|
||||
pub(crate) const fn e_default() -> Self {
|
||||
Self::e(G0::Scalar::ZERO)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,13 +122,13 @@ where
|
||||
#[allow(non_snake_case)]
|
||||
let mut R = original_R;
|
||||
|
||||
for i in ((actual + 1) .. (actual + RING_LEN + 1)).map(|i| i % RING_LEN) {
|
||||
for i in ((actual + 1) ..= (actual + RING_LEN)).map(|i| i % RING_LEN) {
|
||||
let e = Self::nonces(transcript.clone(), R);
|
||||
if i == 0 {
|
||||
match Re_0 {
|
||||
Re::R(ref mut R0_0, ref mut R1_0) => {
|
||||
*R0_0 = R.0;
|
||||
*R1_0 = R.1
|
||||
*R1_0 = R.1;
|
||||
}
|
||||
Re::e(ref mut e_0) => *e_0 = e.0,
|
||||
}
|
||||
@@ -144,15 +144,15 @@ where
|
||||
r.0.zeroize();
|
||||
r.1.zeroize();
|
||||
break;
|
||||
// Generate a decoy response
|
||||
} else {
|
||||
s[i] = (G0::Scalar::random(&mut *rng), G1::Scalar::random(&mut *rng));
|
||||
}
|
||||
|
||||
// Generate a decoy response
|
||||
s[i] = (G0::Scalar::random(&mut *rng), G1::Scalar::random(&mut *rng));
|
||||
|
||||
R = Self::R(generators, s[i], ring[i], e);
|
||||
}
|
||||
|
||||
Aos { Re_0, s }
|
||||
Self { Re_0, s }
|
||||
}
|
||||
|
||||
// Assumes the ring has already been transcripted in some form. Critically insecure if it hasn't
|
||||
@@ -234,7 +234,7 @@ where
|
||||
match Re_0 {
|
||||
Re::R(ref mut R0, ref mut R1) => {
|
||||
*R0 = read_point(r)?;
|
||||
*R1 = read_point(r)?
|
||||
*R1 = read_point(r)?;
|
||||
}
|
||||
Re::e(ref mut e) => *e = read_scalar(r)?,
|
||||
}
|
||||
@@ -244,6 +244,6 @@ where
|
||||
*s = (read_scalar(r)?, read_scalar(r)?);
|
||||
}
|
||||
|
||||
Ok(Aos { Re_0, s })
|
||||
Ok(Self { Re_0, s })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,42 +28,39 @@ pub(crate) enum BitSignature {
|
||||
impl BitSignature {
|
||||
pub(crate) const fn to_u8(&self) -> u8 {
|
||||
match self {
|
||||
BitSignature::ClassicLinear => 0,
|
||||
BitSignature::ConciseLinear => 1,
|
||||
BitSignature::EfficientLinear => 2,
|
||||
BitSignature::CompromiseLinear => 3,
|
||||
Self::ClassicLinear => 0,
|
||||
Self::ConciseLinear => 1,
|
||||
Self::EfficientLinear => 2,
|
||||
Self::CompromiseLinear => 3,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn from(algorithm: u8) -> BitSignature {
|
||||
pub(crate) const fn from(algorithm: u8) -> Self {
|
||||
match algorithm {
|
||||
0 => BitSignature::ClassicLinear,
|
||||
1 => BitSignature::ConciseLinear,
|
||||
2 => BitSignature::EfficientLinear,
|
||||
3 => BitSignature::CompromiseLinear,
|
||||
0 => Self::ClassicLinear,
|
||||
1 => Self::ConciseLinear,
|
||||
2 => Self::EfficientLinear,
|
||||
3 => Self::CompromiseLinear,
|
||||
_ => panic!("Unknown algorithm"),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn bits(&self) -> usize {
|
||||
match self {
|
||||
BitSignature::ClassicLinear => 1,
|
||||
BitSignature::ConciseLinear => 2,
|
||||
BitSignature::EfficientLinear => 1,
|
||||
BitSignature::CompromiseLinear => 2,
|
||||
Self::ClassicLinear | Self::EfficientLinear => 1,
|
||||
Self::ConciseLinear | Self::CompromiseLinear => 2,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) const fn ring_len(&self) -> usize {
|
||||
#[allow(clippy::as_conversions, clippy::cast_possible_truncation)] // Needed for const
|
||||
2_usize.pow(self.bits() as u32)
|
||||
}
|
||||
|
||||
fn aos_form<G0: PrimeGroup, G1: PrimeGroup>(&self) -> Re<G0, G1> {
|
||||
match self {
|
||||
BitSignature::ClassicLinear => Re::e_default(),
|
||||
BitSignature::ConciseLinear => Re::e_default(),
|
||||
BitSignature::EfficientLinear => Re::R_default(),
|
||||
BitSignature::CompromiseLinear => Re::R_default(),
|
||||
Self::ClassicLinear | Self::ConciseLinear => Re::e_default(),
|
||||
Self::EfficientLinear | Self::CompromiseLinear => Re::R_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,7 +136,7 @@ where
|
||||
bits.zeroize();
|
||||
|
||||
Self::shift(pow_2);
|
||||
Bits { commitments, signature }
|
||||
Self { commitments, signature }
|
||||
}
|
||||
|
||||
pub(crate) fn verify<R: RngCore + CryptoRng, T: Clone + Transcript>(
|
||||
@@ -174,7 +171,7 @@ where
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
pub(crate) fn read<R: Read>(r: &mut R) -> std::io::Result<Self> {
|
||||
Ok(Bits {
|
||||
Ok(Self {
|
||||
commitments: (read_point(r)?, read_point(r)?),
|
||||
signature: Aos::read(r, BitSignature::from(SIGNATURE).aos_form())?,
|
||||
})
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
use core::ops::{Deref, DerefMut};
|
||||
#[cfg(feature = "serialize")]
|
||||
use std::io::{Read, Write};
|
||||
|
||||
use thiserror::Error;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
@@ -42,6 +40,7 @@ fn u8_from_bool(bit_ref: &mut bool) -> u8 {
|
||||
let bit_ref = black_box(bit_ref);
|
||||
|
||||
let mut bit = black_box(*bit_ref);
|
||||
#[allow(clippy::as_conversions, clippy::cast_lossless)]
|
||||
let res = black_box(bit as u8);
|
||||
bit.zeroize();
|
||||
debug_assert!((res | 1) == 1);
|
||||
@@ -51,15 +50,15 @@ fn u8_from_bool(bit_ref: &mut bool) -> u8 {
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
pub(crate) fn read_point<R: Read, G: PrimeGroup>(r: &mut R) -> std::io::Result<G> {
|
||||
pub(crate) fn read_point<R: Read, G: PrimeGroup>(r: &mut R) -> io::Result<G> {
|
||||
let mut repr = G::Repr::default();
|
||||
r.read_exact(repr.as_mut())?;
|
||||
let point = G::from_bytes(&repr);
|
||||
let Some(point) = Option::<G>::from(point) else {
|
||||
Err(std::io::Error::new(std::io::ErrorKind::Other, "invalid point"))?
|
||||
Err(io::Error::new(io::ErrorKind::Other, "invalid point"))?
|
||||
};
|
||||
if point.to_bytes().as_ref() != repr.as_ref() {
|
||||
Err(std::io::Error::new(std::io::ErrorKind::Other, "non-canonical point"))?;
|
||||
Err(io::Error::new(io::ErrorKind::Other, "non-canonical point"))?;
|
||||
}
|
||||
Ok(point)
|
||||
}
|
||||
@@ -78,11 +77,11 @@ pub struct Generators<G: PrimeGroup> {
|
||||
|
||||
impl<G: PrimeGroup> Generators<G> {
|
||||
/// Create a new set of generators.
|
||||
pub fn new(primary: G, alt: G) -> Option<Generators<G>> {
|
||||
pub fn new(primary: G, alt: G) -> Option<Self> {
|
||||
if primary == alt {
|
||||
None?;
|
||||
}
|
||||
Some(Generators { primary, alt })
|
||||
Some(Self { primary, alt })
|
||||
}
|
||||
|
||||
fn transcript<T: Transcript>(&self, transcript: &mut T) {
|
||||
@@ -93,21 +92,27 @@ impl<G: PrimeGroup> Generators<G> {
|
||||
}
|
||||
|
||||
/// Error for cross-group DLEq proofs.
|
||||
#[derive(Error, PartialEq, Eq, Debug)]
|
||||
pub enum DLEqError {
|
||||
/// Invalid proof of knowledge.
|
||||
#[error("invalid proof of knowledge")]
|
||||
InvalidProofOfKnowledge,
|
||||
/// Invalid proof length.
|
||||
#[error("invalid proof length")]
|
||||
InvalidProofLength,
|
||||
/// Invalid challenge.
|
||||
#[error("invalid challenge")]
|
||||
InvalidChallenge,
|
||||
/// Invalid proof.
|
||||
#[error("invalid proof")]
|
||||
InvalidProof,
|
||||
#[allow(clippy::std_instead_of_core)]
|
||||
mod dleq_error {
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Error, PartialEq, Eq, Debug)]
|
||||
pub enum DLEqError {
|
||||
/// Invalid proof of knowledge.
|
||||
#[error("invalid proof of knowledge")]
|
||||
InvalidProofOfKnowledge,
|
||||
/// Invalid proof length.
|
||||
#[error("invalid proof length")]
|
||||
InvalidProofLength,
|
||||
/// Invalid challenge.
|
||||
#[error("invalid challenge")]
|
||||
InvalidChallenge,
|
||||
/// Invalid proof.
|
||||
#[error("invalid proof")]
|
||||
InvalidProof,
|
||||
}
|
||||
}
|
||||
pub use dleq_error::DLEqError;
|
||||
|
||||
// This should never be directly instantiated and uses a u8 to represent internal values
|
||||
// Any external usage is likely invalid
|
||||
@@ -335,7 +340,7 @@ where
|
||||
|
||||
these_bits.zeroize();
|
||||
|
||||
let proof = __DLEqProof { bits, remainder, poks };
|
||||
let proof = Self { bits, remainder, poks };
|
||||
debug_assert_eq!(
|
||||
proof.reconstruct_keys(),
|
||||
(generators.0.primary * f.0.deref(), generators.1.primary * f.1.deref())
|
||||
@@ -412,10 +417,8 @@ where
|
||||
Self::transcript(transcript, generators, keys);
|
||||
|
||||
let batch_capacity = match BitSignature::from(SIGNATURE) {
|
||||
BitSignature::ClassicLinear => 3,
|
||||
BitSignature::ConciseLinear => 3,
|
||||
BitSignature::EfficientLinear => (self.bits.len() + 1) * 3,
|
||||
BitSignature::CompromiseLinear => (self.bits.len() + 1) * 3,
|
||||
BitSignature::ClassicLinear | BitSignature::ConciseLinear => 3,
|
||||
BitSignature::EfficientLinear | BitSignature::CompromiseLinear => (self.bits.len() + 1) * 3,
|
||||
};
|
||||
let mut batch = (BatchVerifier::new(batch_capacity), BatchVerifier::new(batch_capacity));
|
||||
|
||||
@@ -439,7 +442,7 @@ where
|
||||
|
||||
/// Write a Cross-Group Discrete Log Equality proof to a type satisfying std::io::Write.
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
for bit in &self.bits {
|
||||
bit.write(w)?;
|
||||
}
|
||||
@@ -452,7 +455,7 @@ where
|
||||
|
||||
/// Read a Cross-Group Discrete Log Equality proof from a type satisfying std::io::Read.
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn read<R: Read>(r: &mut R) -> std::io::Result<Self> {
|
||||
pub fn read<R: Read>(r: &mut R) -> io::Result<Self> {
|
||||
let capacity = usize::try_from(G0::Scalar::CAPACITY.min(G1::Scalar::CAPACITY)).unwrap();
|
||||
let bits_per_group = BitSignature::from(SIGNATURE).bits();
|
||||
|
||||
@@ -466,6 +469,6 @@ where
|
||||
remainder = Some(Bits::read(r)?);
|
||||
}
|
||||
|
||||
Ok(__DLEqProof { bits, remainder, poks: (SchnorrPoK::read(r)?, SchnorrPoK::read(r)?) })
|
||||
Ok(Self { bits, remainder, poks: (SchnorrPoK::read(r)?, SchnorrPoK::read(r)?) })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use zeroize::Zeroize;
|
||||
use crate::cross_group::u8_from_bool;
|
||||
|
||||
/// Convert a uniform scalar into one usable on both fields, clearing the top bits as needed.
|
||||
#[must_use]
|
||||
pub fn scalar_normalize<F0: PrimeFieldBits + Zeroize, F1: PrimeFieldBits>(
|
||||
mut scalar: F0,
|
||||
) -> (F0, F1) {
|
||||
@@ -49,6 +50,7 @@ pub fn scalar_normalize<F0: PrimeFieldBits + Zeroize, F1: PrimeFieldBits>(
|
||||
}
|
||||
|
||||
/// Helper to convert a scalar between fields. Returns None if the scalar isn't mutually valid.
|
||||
#[must_use]
|
||||
pub fn scalar_convert<F0: PrimeFieldBits + Zeroize, F1: PrimeFieldBits>(
|
||||
mut scalar: F0,
|
||||
) -> Option<F1> {
|
||||
@@ -60,6 +62,7 @@ pub fn scalar_convert<F0: PrimeFieldBits + Zeroize, F1: PrimeFieldBits>(
|
||||
}
|
||||
|
||||
/// Create a mutually valid scalar from bytes via bit truncation to not introduce bias.
|
||||
#[must_use]
|
||||
pub fn mutual_scalar_from_bytes<F0: PrimeFieldBits + Zeroize, F1: PrimeFieldBits>(
|
||||
bytes: &[u8],
|
||||
) -> (F0, F1) {
|
||||
|
||||
@@ -47,13 +47,13 @@ where
|
||||
transcript: &mut T,
|
||||
generator: G,
|
||||
private_key: &Zeroizing<G::Scalar>,
|
||||
) -> SchnorrPoK<G> {
|
||||
) -> Self {
|
||||
let nonce = Zeroizing::new(G::Scalar::random(rng));
|
||||
#[allow(non_snake_case)]
|
||||
let R = generator * nonce.deref();
|
||||
SchnorrPoK {
|
||||
Self {
|
||||
R,
|
||||
s: (SchnorrPoK::hra(transcript, generator, R, generator * private_key.deref()) *
|
||||
s: (Self::hra(transcript, generator, R, generator * private_key.deref()) *
|
||||
private_key.deref()) +
|
||||
nonce.deref(),
|
||||
}
|
||||
@@ -85,7 +85,7 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn read<R: Read>(r: &mut R) -> std::io::Result<SchnorrPoK<G>> {
|
||||
Ok(SchnorrPoK { R: read_point(r)?, s: read_scalar(r)? })
|
||||
pub fn read<R: Read>(r: &mut R) -> std::io::Result<Self> {
|
||||
Ok(Self { R: read_point(r)?, s: read_scalar(r)? })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ where
|
||||
transcript: &mut T,
|
||||
generators: &[G],
|
||||
scalar: &Zeroizing<G::Scalar>,
|
||||
) -> DLEqProof<G> {
|
||||
) -> Self {
|
||||
let r = Zeroizing::new(G::Scalar::random(rng));
|
||||
|
||||
transcript.domain_separate(b"dleq");
|
||||
@@ -144,7 +144,7 @@ where
|
||||
// r + ca
|
||||
let s = (c * scalar.deref()) + r.deref();
|
||||
|
||||
DLEqProof { c, s }
|
||||
Self { c, s }
|
||||
}
|
||||
|
||||
// Transcript a specific generator/nonce/point (G/R/A), as used when verifying a proof.
|
||||
@@ -194,8 +194,8 @@ where
|
||||
|
||||
/// Read a DLEq proof from something implementing Read.
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn read<R: Read>(r: &mut R) -> io::Result<DLEqProof<G>> {
|
||||
Ok(DLEqProof { c: read_scalar(r)?, s: read_scalar(r)? })
|
||||
pub fn read<R: Read>(r: &mut R) -> io::Result<Self> {
|
||||
Ok(Self { c: read_scalar(r)?, s: read_scalar(r)? })
|
||||
}
|
||||
|
||||
/// Serialize a DLEq proof to a `Vec<u8>`.
|
||||
@@ -235,7 +235,7 @@ where
|
||||
transcript: &mut T,
|
||||
generators: &[Vec<G>],
|
||||
scalars: &[Zeroizing<G::Scalar>],
|
||||
) -> MultiDLEqProof<G> {
|
||||
) -> Self {
|
||||
assert_eq!(
|
||||
generators.len(),
|
||||
scalars.len(),
|
||||
@@ -268,7 +268,7 @@ where
|
||||
s.push((c * scalar.deref()) + nonce.deref());
|
||||
}
|
||||
|
||||
MultiDLEqProof { c, s }
|
||||
Self { c, s }
|
||||
}
|
||||
|
||||
/// Verify each series of points share a discrete logarithm against their matching series of
|
||||
@@ -317,13 +317,13 @@ where
|
||||
|
||||
/// Read a multi-DLEq proof from something implementing Read.
|
||||
#[cfg(feature = "serialize")]
|
||||
pub fn read<R: Read>(r: &mut R, discrete_logs: usize) -> io::Result<MultiDLEqProof<G>> {
|
||||
pub fn read<R: Read>(r: &mut R, discrete_logs: usize) -> io::Result<Self> {
|
||||
let c = read_scalar(r)?;
|
||||
let mut s = vec![];
|
||||
for _ in 0 .. discrete_logs {
|
||||
s.push(read_scalar(r)?);
|
||||
}
|
||||
Ok(MultiDLEqProof { c, s })
|
||||
Ok(Self { c, s })
|
||||
}
|
||||
|
||||
/// Serialize a multi-DLEq proof to a `Vec<u8>`.
|
||||
|
||||
@@ -27,7 +27,7 @@ fn test_scalar() {
|
||||
// The initial scalar should equal the new scalar with Ed25519's capacity
|
||||
let mut initial_bytes = initial.to_repr().to_vec();
|
||||
// Drop the first 4 bits to hit 252
|
||||
initial_bytes[0] &= 0b00001111;
|
||||
initial_bytes[0] &= 0b0000_1111;
|
||||
let k_bytes = k.to_repr().to_vec();
|
||||
assert_eq!(initial_bytes, k_bytes);
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ fn test_dleq() {
|
||||
assert!(proof
|
||||
.verify(
|
||||
&mut transcript(),
|
||||
generators[.. i].iter().cloned().rev().collect::<Vec<_>>().as_ref(),
|
||||
generators[.. i].iter().copied().rev().collect::<Vec<_>>().as_ref(),
|
||||
&keys[.. i]
|
||||
)
|
||||
.is_err());
|
||||
@@ -86,7 +86,7 @@ fn test_dleq() {
|
||||
.verify(
|
||||
&mut transcript(),
|
||||
&generators[.. i],
|
||||
keys[.. i].iter().cloned().rev().collect::<Vec<_>>().as_ref()
|
||||
keys[.. i].iter().copied().rev().collect::<Vec<_>>().as_ref()
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
@@ -117,7 +117,7 @@ fn test_multi_dleq() {
|
||||
// 0: 0
|
||||
// 1: 1, 2
|
||||
// 2: 2, 3, 4
|
||||
let key_generators = generators[i .. (i + i + 1)].to_vec();
|
||||
let key_generators = generators[i ..= i + i].to_vec();
|
||||
let mut these_pub_keys = vec![];
|
||||
for generator in &key_generators {
|
||||
these_pub_keys.push(generator * key.deref());
|
||||
|
||||
Reference in New Issue
Block a user