Port common, and most of crypto, to a more aggressive clippy

This commit is contained in:
Luke Parker
2023-07-07 22:05:07 -04:00
parent 3c6cc42c23
commit 3a626cc51e
34 changed files with 367 additions and 282 deletions

View File

@@ -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 })
}
}

View File

@@ -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())?,
})

View File

@@ -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)?) })
}
}

View File

@@ -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) {

View File

@@ -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)? })
}
}

View File

@@ -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>`.

View File

@@ -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);

View File

@@ -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());