Refine from pedantic, remove erratic consts

This commit is contained in:
Luke Parker 2023-07-08 01:26:08 -04:00
parent 286e96ccd8
commit 3ca76c51e4
No known key found for this signature in database
36 changed files with 192 additions and 335 deletions

View file

@ -1,42 +1,26 @@
# No warnings allowed
-D warnings
# Non-default groups
# nursery
-D clippy::nursery
-D clippy::pedantic
# Not worth the effort
-A clippy::implicit_hasher
# Stylistic preferrence
-A clippy::option_if_let_else
# Erratic and unhelpful
-A clippy::missing_const_for_fn
# Too many false/irrelevant positives
-A clippy::redundant_pub_crate
-A clippy::similar_names
# Flags on any debug_assert using an RNG
-A clippy::debug_assert_with_mut_call
# Stylistic preference
-A clippy::option_if_let_else
# Frequently used
-A clippy::large_types_passed_by_value
-A clippy::wildcard_imports
-A clippy::too_many_lines
# pedantic
-D clippy::unnecessary_wraps
-D clippy::unused_async
-D clippy::unused_self
# Used to avoid doing &* on copy-able items, with the * being the concern
-A clippy::explicit_deref_methods
# Lints from clippy::restrictions
# These are relevant for crates we want to be no-std, eventually, and aren't
# relevant for the rest
-D clippy::std_instead_of_alloc
-D clippy::std_instead_of_core
-D clippy::alloc_instead_of_core
# restrictions
# Safety
-D clippy::as_conversions
-D clippy::float_cmp_const
-D clippy::disallowed_script_idents
-D clippy::wildcard_enum_match_arm
@ -54,19 +38,10 @@
-D clippy::format_push_string
-D clippy::string_to_string
# Flagged on tests being named test_
-A clippy::module_name_repetitions
# Flagged on items passed by value which implemented Copy
-A clippy::needless_pass_by_value
# Flagged on embedded functions defined when needed/relevant
-A clippy::items_after_statements
# These potentially should be enabled in the future
-A clippy::missing_errors_doc
-A clippy::missing_panics_doc
-A clippy::doc_markdown
# -D clippy::missing_errors_doc
# -D clippy::missing_panics_doc
# -D clippy::doc_markdown
# TODO: Enable this
# -D clippy::cargo

View file

@ -9,7 +9,6 @@ use crate::hash;
/// Monero's hash to point function, as named `ge_fromfe_frombytes_vartime`.
#[allow(clippy::many_single_char_names)]
#[must_use]
pub fn hash_to_point(bytes: [u8; 32]) -> EdwardsPoint {
#[allow(non_snake_case, clippy::unreadable_literal)]
let A = FieldElement::from(486662u64);

View file

@ -61,7 +61,6 @@ pub struct Generators {
}
/// Generate generators as needed for Bulletproofs(+), as Monero does.
#[must_use]
pub fn bulletproofs_generators(dst: &'static [u8]) -> Generators {
let mut res =
Generators { G: [EdwardsPoint::identity(); MAX_MN], H: [EdwardsPoint::identity(); MAX_MN] };

View file

@ -33,7 +33,6 @@ impl BlockHeader {
w.write_all(&self.nonce.to_le_bytes())
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();
@ -59,7 +58,6 @@ pub struct Block {
}
impl Block {
#[must_use]
pub fn number(&self) -> usize {
match self.miner_tx.prefix.inputs.get(0) {
Some(Input::Gen(number)) => (*number).try_into().unwrap(),
@ -93,7 +91,6 @@ impl Block {
out
}
#[must_use]
pub fn hash(&self) -> [u8; 32] {
let hash = hash(&self.serialize_hashable());
if hash == CORRECT_BLOCK_HASH_202612 {
@ -103,7 +100,6 @@ impl Block {
hash
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();

View file

@ -60,7 +60,6 @@ pub enum Protocol {
impl Protocol {
/// Amount of ring members under this protocol version.
#[must_use]
pub const fn ring_len(&self) -> usize {
match self {
Self::v14 => 11,
@ -72,7 +71,6 @@ impl Protocol {
/// Whether or not the specified version uses Bulletproofs or Bulletproofs+.
///
/// This method will likely be reworked when versions not using Bulletproofs at all are added.
#[must_use]
pub const fn bp_plus(&self) -> bool {
match self {
Self::v14 => false,
@ -82,7 +80,6 @@ impl Protocol {
}
// TODO: Make this an Option when we support pre-RCT protocols
#[must_use]
pub const fn optimal_rct_type(&self) -> RctType {
match self {
Self::v14 => RctType::Clsag,
@ -144,25 +141,21 @@ pub struct Commitment {
impl Commitment {
/// A commitment to zero, defined with a mask of 1 (as to not be the identity).
#[must_use]
pub fn zero() -> Self {
Self { mask: Scalar::one(), amount: 0 }
}
#[must_use]
pub const fn new(mask: Scalar, amount: u64) -> Self {
pub fn new(mask: Scalar, amount: u64) -> Self {
Self { mask, amount }
}
/// Calculate a Pedersen commitment, as a point, from the transparent structure.
#[must_use]
pub fn calculate(&self) -> EdwardsPoint {
(&self.mask * &ED25519_BASEPOINT_TABLE) + (Scalar::from(self.amount) * H())
}
}
/// Support generating a random scalar using a modern rand, as dalek's is notoriously dated.
#[must_use]
pub fn random_scalar<R: RngCore + CryptoRng>(rng: &mut R) -> Scalar {
let mut r = [0; 64];
rng.fill_bytes(&mut r);
@ -174,7 +167,6 @@ pub(crate) fn hash(data: &[u8]) -> [u8; 32] {
}
/// Hash the provided data to a scalar via keccak256(data) % l.
#[must_use]
pub fn hash_to_scalar(data: &[u8]) -> Scalar {
let scalar = Scalar::from_bytes_mod_order(hash(data));
// Monero will explicitly error in this case

View file

@ -2,7 +2,6 @@ use std_shims::vec::Vec;
use crate::hash;
#[must_use]
pub(crate) fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] {
match leafs.len() {
0 => root,

View file

@ -56,7 +56,7 @@ pub(crate) fn hash_cache(cache: &mut Scalar, mash: &[[u8; 32]]) -> Scalar {
*cache
}
pub(crate) const fn MN(outputs: usize) -> (usize, usize, usize) {
pub(crate) fn MN(outputs: usize) -> (usize, usize, usize) {
let mut logM = 0;
let mut M;
while {

View file

@ -140,7 +140,6 @@ impl Bulletproofs {
self.write_core(w, |points, w| write_vec(write_point, points, w))
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();

View file

@ -6,10 +6,9 @@ use std_shims::{
io::{self, Read, Write},
};
use rand_core::{RngCore, CryptoRng};
use zeroize::{Zeroize, ZeroizeOnDrop, Zeroizing};
use subtle::{ConstantTimeEq, Choice, CtOption};
use rand_core::{RngCore, CryptoRng};
use curve25519_dalek::{
constants::ED25519_BASEPOINT_TABLE,
@ -30,31 +29,27 @@ pub use multisig::{ClsagDetails, ClsagAddendum, ClsagMultisig};
#[cfg(feature = "multisig")]
pub(crate) use multisig::add_key_image_share;
#[allow(clippy::std_instead_of_core)]
mod clsag_error {
/// Errors returned when CLSAG signing fails.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum ClsagError {
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(&'static str),
#[cfg_attr(feature = "std", error("invalid ring"))]
InvalidRing,
#[cfg_attr(feature = "std", error("invalid ring member (member {0}, ring size {1})"))]
InvalidRingMember(u8, u8),
#[cfg_attr(feature = "std", error("invalid commitment"))]
InvalidCommitment,
#[cfg_attr(feature = "std", error("invalid key image"))]
InvalidImage,
#[cfg_attr(feature = "std", error("invalid D"))]
InvalidD,
#[cfg_attr(feature = "std", error("invalid s"))]
InvalidS,
#[cfg_attr(feature = "std", error("invalid c1"))]
InvalidC1,
}
/// Errors returned when CLSAG signing fails.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum ClsagError {
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(&'static str),
#[cfg_attr(feature = "std", error("invalid ring"))]
InvalidRing,
#[cfg_attr(feature = "std", error("invalid ring member (member {0}, ring size {1})"))]
InvalidRingMember(u8, u8),
#[cfg_attr(feature = "std", error("invalid commitment"))]
InvalidCommitment,
#[cfg_attr(feature = "std", error("invalid key image"))]
InvalidImage,
#[cfg_attr(feature = "std", error("invalid D"))]
InvalidD,
#[cfg_attr(feature = "std", error("invalid s"))]
InvalidS,
#[cfg_attr(feature = "std", error("invalid c1"))]
InvalidC1,
}
pub use clsag_error::ClsagError;
/// Input being signed for.
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, ZeroizeOnDrop)]
@ -239,7 +234,6 @@ impl Clsag {
/// Generate CLSAG signatures for the given inputs.
/// inputs is of the form (private key, key image, input).
/// sum_outputs is for the sum of the outputs' commitment masks.
#[must_use]
pub fn sign<R: RngCore + CryptoRng>(
rng: &mut R,
mut inputs: Vec<(Zeroizing<Scalar>, EdwardsPoint, ClsagInput)>,
@ -249,11 +243,12 @@ impl Clsag {
let mut res = Vec::with_capacity(inputs.len());
let mut sum_pseudo_outs = Scalar::zero();
for i in 0 .. inputs.len() {
let mut mask = random_scalar(rng);
if i == (inputs.len() - 1) {
mask = sum_outputs - sum_pseudo_outs;
let mask = if i == (inputs.len() - 1) {
sum_outputs - sum_pseudo_outs
} else {
let mask = random_scalar(rng);
sum_pseudo_outs += mask;
mask
}
let mut nonce = Zeroizing::new(random_scalar(rng));
@ -314,7 +309,7 @@ impl Clsag {
Ok(())
}
pub(crate) const fn fee_weight(ring_len: usize) -> usize {
pub(crate) fn fee_weight(ring_len: usize) -> usize {
(ring_len * 32) + 32 + 32
}

View file

@ -68,7 +68,6 @@ pub struct ClsagDetails {
}
impl ClsagDetails {
#[must_use]
pub fn new(input: ClsagInput, mask: Scalar) -> Self {
Self { input, mask }
}
@ -116,7 +115,6 @@ pub struct ClsagMultisig {
}
impl ClsagMultisig {
#[must_use]
pub fn new(
transcript: RecommendedTranscript,
output_key: EdwardsPoint,

View file

@ -3,7 +3,6 @@ use curve25519_dalek::edwards::EdwardsPoint;
pub use monero_generators::{hash_to_point as raw_hash_to_point};
/// Monero's hash to point function, as named `ge_fromfe_frombytes_vartime`.
#[must_use]
pub fn hash_to_point(key: EdwardsPoint) -> EdwardsPoint {
raw_hash_to_point(key.compress().to_bytes())
}

View file

@ -27,7 +27,6 @@ use crate::{
};
/// Generate a key image for a given key. Defined as `x * hash_to_point(xG)`.
#[must_use]
pub fn generate_key_image(secret: &Zeroizing<Scalar>) -> EdwardsPoint {
hash_to_point(&ED25519_BASEPOINT_TABLE * secret.deref()) * secret.deref()
}
@ -78,8 +77,7 @@ pub enum RctType {
}
impl RctType {
#[must_use]
pub const fn to_byte(self) -> u8 {
pub fn to_byte(self) -> u8 {
match self {
Self::Null => 0,
Self::MlsagAggregate => 1,
@ -91,7 +89,6 @@ impl RctType {
}
}
#[must_use]
pub fn from_byte(byte: u8) -> Option<Self> {
Some(match byte {
0 => Self::Null,
@ -105,8 +102,7 @@ impl RctType {
})
}
#[must_use]
pub const fn compact_encrypted_amounts(&self) -> bool {
pub fn compact_encrypted_amounts(&self) -> bool {
match self {
Self::Null | Self::MlsagAggregate | Self::MlsagIndividual | Self::Bulletproofs => false,
Self::BulletproofsCompactAmount | Self::Clsag | Self::BulletproofsPlus => true,
@ -123,7 +119,7 @@ pub struct RctBase {
}
impl RctBase {
pub(crate) const fn fee_weight(outputs: usize) -> usize {
pub(crate) fn fee_weight(outputs: usize) -> usize {
1 + 8 + (outputs * (8 + 32))
}
@ -245,7 +241,6 @@ impl RctPrunable {
}
}
#[must_use]
pub fn serialize(&self, rct_type: RctType) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized, rct_type).unwrap();
@ -312,7 +307,6 @@ pub struct RctSignatures {
impl RctSignatures {
/// RctType for a given RctSignatures struct.
#[must_use]
pub fn rct_type(&self) -> RctType {
match &self.prunable {
RctPrunable::Null => RctType::Null,
@ -376,7 +370,6 @@ impl RctSignatures {
self.prunable.write(w, rct_type)
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();

View file

@ -47,31 +47,26 @@ struct TransactionsResponse {
txs: Vec<TransactionResponse>,
}
#[allow(clippy::std_instead_of_core)]
mod rpc_error {
use std_shims::{vec::Vec, string::String};
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum RpcError {
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(&'static str),
#[cfg_attr(feature = "std", error("connection error"))]
ConnectionError,
#[cfg_attr(feature = "std", error("invalid node"))]
InvalidNode,
#[cfg_attr(feature = "std", error("unsupported protocol version ({0})"))]
UnsupportedProtocol(usize),
#[cfg_attr(feature = "std", error("transactions not found"))]
TransactionsNotFound(Vec<[u8; 32]>),
#[cfg_attr(feature = "std", error("invalid point ({0})"))]
InvalidPoint(String),
#[cfg_attr(feature = "std", error("pruned transaction"))]
PrunedTransaction,
#[cfg_attr(feature = "std", error("invalid transaction ({0:?})"))]
InvalidTransaction([u8; 32]),
}
#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum RpcError {
#[cfg_attr(feature = "std", error("internal error ({0})"))]
InternalError(&'static str),
#[cfg_attr(feature = "std", error("connection error"))]
ConnectionError,
#[cfg_attr(feature = "std", error("invalid node"))]
InvalidNode,
#[cfg_attr(feature = "std", error("unsupported protocol version ({0})"))]
UnsupportedProtocol(usize),
#[cfg_attr(feature = "std", error("transactions not found"))]
TransactionsNotFound(Vec<[u8; 32]>),
#[cfg_attr(feature = "std", error("invalid point ({0})"))]
InvalidPoint(String),
#[cfg_attr(feature = "std", error("pruned transaction"))]
PrunedTransaction,
#[cfg_attr(feature = "std", error("invalid transaction ({0:?})"))]
InvalidTransaction([u8; 32]),
}
pub use rpc_error::RpcError;
fn rpc_hex(value: &str) -> Result<Vec<u8>, RpcError> {
hex::decode(value).map_err(|_| RpcError::InvalidNode)

View file

@ -25,7 +25,7 @@ pub enum Input {
impl Input {
// Worst-case predictive len
pub(crate) const fn fee_weight(ring_len: usize) -> usize {
pub(crate) fn fee_weight(ring_len: usize) -> usize {
// Uses 1 byte for the VarInt amount due to amount being 0
// Uses 1 byte for the VarInt encoding of the length of the ring as well
1 + 1 + 1 + (8 * ring_len) + 32
@ -47,7 +47,6 @@ impl Input {
}
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut res = vec![];
self.write(&mut res).unwrap();
@ -82,7 +81,7 @@ pub struct Output {
}
impl Output {
pub(crate) const fn fee_weight() -> usize {
pub(crate) fn fee_weight() -> usize {
1 + 1 + 32 + 1
}
@ -96,7 +95,6 @@ impl Output {
Ok(())
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut res = Vec::with_capacity(8 + 1 + 32);
self.write(&mut res).unwrap();
@ -202,7 +200,6 @@ impl TransactionPrefix {
w.write_all(&self.extra)
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut res = vec![];
self.write(&mut res).unwrap();
@ -235,7 +232,6 @@ impl TransactionPrefix {
Ok(prefix)
}
#[must_use]
pub fn hash(&self) -> [u8; 32] {
hash(&self.serialize())
}
@ -277,7 +273,6 @@ impl Transaction {
}
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut res = Vec::with_capacity(2048);
self.write(&mut res).unwrap();
@ -336,7 +331,6 @@ impl Transaction {
Ok(Self { prefix, signatures, rct_signatures })
}
#[must_use]
pub fn hash(&self) -> [u8; 32] {
let mut buf = Vec::with_capacity(2048);
if self.prefix.version == 1 {
@ -365,7 +359,6 @@ impl Transaction {
}
/// Calculate the hash of this transaction as needed for signing it.
#[must_use]
pub fn signature_hash(&self) -> [u8; 32] {
let mut buf = Vec::with_capacity(2048);
let mut sig_hash = Vec::with_capacity(96);

View file

@ -32,7 +32,6 @@ pub struct SubaddressIndex {
}
impl SubaddressIndex {
#[must_use]
pub const fn new(account: u32, address: u32) -> Option<Self> {
if (account == 0) && (address == 0) {
return None;
@ -40,12 +39,10 @@ impl SubaddressIndex {
Some(Self { account, address })
}
#[must_use]
pub const fn account(&self) -> u32 {
self.account
}
#[must_use]
pub const fn address(&self) -> u32 {
self.address
}
@ -61,12 +58,10 @@ pub enum AddressSpec {
}
impl AddressType {
#[must_use]
pub const fn is_subaddress(&self) -> bool {
matches!(self, Self::Subaddress) || matches!(self, Self::Featured { subaddress: true, .. })
}
#[must_use]
pub const fn payment_id(&self) -> Option<[u8; 8]> {
if let Self::Integrated(id) = self {
Some(*id)
@ -77,7 +72,6 @@ impl AddressType {
}
}
#[must_use]
pub const fn is_guaranteed(&self) -> bool {
matches!(self, Self::Featured { guaranteed: true, .. })
}
@ -147,7 +141,6 @@ impl<B: AddressBytes> AddressMeta<B> {
}
/// Create an address's metadata.
#[must_use]
pub const fn new(network: Network, kind: AddressType) -> Self {
Self { _bytes: PhantomData, network, kind }
}
@ -174,17 +167,14 @@ impl<B: AddressBytes> AddressMeta<B> {
meta.ok_or(AddressError::InvalidByte)
}
#[must_use]
pub const fn is_subaddress(&self) -> bool {
self.kind.is_subaddress()
}
#[must_use]
pub const fn payment_id(&self) -> Option<[u8; 8]> {
self.kind.payment_id()
}
#[must_use]
pub const fn is_guaranteed(&self) -> bool {
self.kind.is_guaranteed()
}
@ -225,7 +215,6 @@ impl<B: AddressBytes> ToString for Address<B> {
}
impl<B: AddressBytes> Address<B> {
#[must_use]
pub const fn new(meta: AddressMeta<B>, spend: EdwardsPoint, view: EdwardsPoint) -> Self {
Self { meta, spend, view }
}
@ -290,22 +279,18 @@ impl<B: AddressBytes> Address<B> {
})
}
#[must_use]
pub const fn network(&self) -> Network {
self.meta.network
}
#[must_use]
pub const fn is_subaddress(&self) -> bool {
self.meta.is_subaddress()
}
#[must_use]
pub const fn payment_id(&self) -> Option<[u8; 8]> {
self.meta.payment_id()
}
#[must_use]
pub const fn is_guaranteed(&self) -> bool {
self.meta.is_guaranteed()
}
@ -316,7 +301,6 @@ pub type MoneroAddress = Address<MoneroAddressBytes>;
// Allow re-interpreting of an arbitrary address as a Monero address so it can be used with the
// rest of this library. Doesn't use From as it was conflicting with From<T> for T.
impl MoneroAddress {
#[must_use]
pub const fn from<B: AddressBytes>(address: Address<B>) -> Self {
Self::new(
AddressMeta::new(address.meta.network, address.meta.kind),

View file

@ -24,6 +24,7 @@ const MATURITY: u64 = 60;
const RECENT_WINDOW: usize = 15;
const BLOCK_TIME: usize = 120;
const BLOCKS_PER_YEAR: usize = 365 * 24 * 60 * 60 / BLOCK_TIME;
#[allow(clippy::as_conversions)]
const TIP_APPLICATION: f64 = (LOCK_WINDOW * BLOCK_TIME) as f64;
// TODO: Expose an API to reset this in case a reorg occurs/the RPC fails/returns garbage
@ -74,9 +75,11 @@ async fn select_n<'a, R: RngCore + CryptoRng, RPC: RpcConnection>(
age -= TIP_APPLICATION;
} else {
// f64 does not have try_from available, which is why these are written with `as`
#[allow(clippy::as_conversions)]
age = (rng.next_u64() % u64::try_from(RECENT_WINDOW * BLOCK_TIME).unwrap()) as f64;
}
#[allow(clippy::as_conversions)]
let o = (age * per_second) as u64;
if o < high {
let i = distribution.partition_point(|s| *s < (high - 1 - o));
@ -141,7 +144,6 @@ pub struct Decoys {
}
impl Decoys {
#[must_use]
pub fn len(&self) -> usize {
self.offsets.len()
}
@ -181,6 +183,7 @@ impl Decoys {
let per_second = {
let blocks = distribution.len().min(BLOCKS_PER_YEAR);
let outputs = high - distribution[distribution.len().saturating_sub(blocks + 1)];
#[allow(clippy::as_conversions)]
(outputs as f64) / ((blocks * BLOCK_TIME) as f64)
};

View file

@ -124,7 +124,6 @@ impl ExtraField {
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
pub struct Extra(Vec<ExtraField>);
impl Extra {
#[must_use]
pub fn keys(&self) -> Option<(EdwardsPoint, Option<Vec<EdwardsPoint>>)> {
let mut key = None;
let mut additional = None;
@ -141,7 +140,6 @@ impl Extra {
key.map(|key| (key, additional))
}
#[must_use]
pub fn payment_id(&self) -> Option<PaymentId> {
for field in &self.0 {
if let ExtraField::Nonce(data) = field {
@ -151,7 +149,6 @@ impl Extra {
None
}
#[must_use]
pub fn data(&self) -> Vec<Vec<u8>> {
let mut res = vec![];
for field in &self.0 {
@ -201,7 +198,6 @@ impl Extra {
Ok(())
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = vec![];
self.write(&mut buf).unwrap();

View file

@ -141,17 +141,14 @@ pub struct ViewPair {
}
impl ViewPair {
#[must_use]
pub const fn new(spend: EdwardsPoint, view: Zeroizing<Scalar>) -> Self {
Self { spend, view }
}
#[must_use]
pub const fn spend(&self) -> EdwardsPoint {
self.spend
}
#[must_use]
pub fn view(&self) -> EdwardsPoint {
self.view.deref() * &ED25519_BASEPOINT_TABLE
}
@ -176,7 +173,6 @@ impl ViewPair {
}
/// Returns an address with the provided specification.
#[must_use]
pub fn address(&self, network: Network, spec: AddressSpec) -> MoneroAddress {
let mut spend = self.spend;
let mut view: EdwardsPoint = self.view.deref() * &ED25519_BASEPOINT_TABLE;
@ -254,7 +250,6 @@ impl Scanner {
///
/// If None is passed, a modified shared key derivation is used which is immune to the burning
/// bug (specifically the Guaranteed feature from Featured Addresses).
#[must_use]
pub fn from_view(pair: ViewPair, burning_bug: Option<HashSet<CompressedEdwardsY>>) -> Self {
let mut subaddresses = HashMap::new();
subaddresses.insert(pair.spend.compress(), None);

View file

@ -32,7 +32,6 @@ impl AbsoluteId {
w.write_all(&[self.o])
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = Vec::with_capacity(32 + 1);
self.write(&mut serialized).unwrap();
@ -61,7 +60,6 @@ impl OutputData {
w.write_all(&self.commitment.amount.to_le_bytes())
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = Vec::with_capacity(32 + 32 + 32 + 8);
self.write(&mut serialized).unwrap();
@ -110,7 +108,6 @@ impl Metadata {
Ok(())
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = Vec::with_capacity(1 + 8 + 1);
self.write(&mut serialized).unwrap();
@ -151,22 +148,18 @@ pub struct ReceivedOutput {
}
impl ReceivedOutput {
#[must_use]
pub const fn key(&self) -> EdwardsPoint {
pub fn key(&self) -> EdwardsPoint {
self.data.key
}
#[must_use]
pub const fn key_offset(&self) -> Scalar {
pub fn key_offset(&self) -> Scalar {
self.data.key_offset
}
#[must_use]
pub fn commitment(&self) -> Commitment {
self.data.commitment.clone()
}
#[must_use]
pub fn arbitrary_data(&self) -> &[Vec<u8>] {
&self.metadata.arbitrary_data
}
@ -177,7 +170,6 @@ impl ReceivedOutput {
self.metadata.write(w)
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut serialized = vec![];
self.write(&mut serialized).unwrap();
@ -223,22 +215,18 @@ impl SpendableOutput {
Ok(output)
}
#[must_use]
pub const fn key(&self) -> EdwardsPoint {
pub fn key(&self) -> EdwardsPoint {
self.output.key()
}
#[must_use]
pub const fn key_offset(&self) -> Scalar {
pub fn key_offset(&self) -> Scalar {
self.output.key_offset()
}
#[must_use]
pub fn commitment(&self) -> Commitment {
self.output.commitment()
}
#[must_use]
pub fn arbitrary_data(&self) -> &[Vec<u8>] {
self.output.arbitrary_data()
}
@ -270,8 +258,7 @@ impl<O: Clone + Zeroize> Drop for Timelocked<O> {
impl<O: Clone + Zeroize> ZeroizeOnDrop for Timelocked<O> {}
impl<O: Clone + Zeroize> Timelocked<O> {
#[must_use]
pub const fn timelock(&self) -> Timelock {
pub fn timelock(&self) -> Timelock {
self.0
}

View file

@ -7,25 +7,21 @@ use rand_core::{RngCore, CryptoRng};
pub(crate) mod classic;
use classic::{CLASSIC_SEED_LENGTH, CLASSIC_SEED_LENGTH_WITH_CHECKSUM, ClassicSeed};
#[allow(clippy::std_instead_of_core)]
mod seed_error {
/// Error when decoding a seed.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum SeedError {
#[cfg_attr(feature = "std", error("invalid number of words in seed"))]
InvalidSeedLength,
#[cfg_attr(feature = "std", error("unknown language"))]
UnknownLanguage,
#[cfg_attr(feature = "std", error("invalid checksum"))]
InvalidChecksum,
#[cfg_attr(feature = "std", error("english old seeds don't support checksums"))]
EnglishOldWithChecksum,
#[cfg_attr(feature = "std", error("invalid seed"))]
InvalidSeed,
}
/// Error when decoding a seed.
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum SeedError {
#[cfg_attr(feature = "std", error("invalid number of words in seed"))]
InvalidSeedLength,
#[cfg_attr(feature = "std", error("unknown language"))]
UnknownLanguage,
#[cfg_attr(feature = "std", error("invalid checksum"))]
InvalidChecksum,
#[cfg_attr(feature = "std", error("english old seeds don't support checksums"))]
EnglishOldWithChecksum,
#[cfg_attr(feature = "std", error("invalid seed"))]
InvalidSeed,
}
pub use seed_error::SeedError;
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)]
pub enum Language {
@ -61,7 +57,6 @@ impl fmt::Debug for Seed {
impl Seed {
/// Create a new seed.
#[must_use]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R, lang: Language) -> Self {
Self::Classic(ClassicSeed::new(rng, lang))
}
@ -77,7 +72,6 @@ impl Seed {
}
/// Create a Seed from entropy.
#[must_use]
pub fn from_entropy(lang: Language, entropy: Zeroizing<[u8; 32]>) -> Option<Self> {
ClassicSeed::from_entropy(lang, entropy).map(Self::Classic)
}
@ -90,7 +84,6 @@ impl Seed {
}
/// Return the entropy for this seed.
#[must_use]
pub fn entropy(&self) -> Zeroizing<[u8; 32]> {
match self {
Self::Classic(seed) => seed.entropy(),

View file

@ -25,7 +25,7 @@ struct SignableTransactionBuilderInternal {
impl SignableTransactionBuilderInternal {
// Takes in the change address so users don't miss that they have to manually set one
// If they don't, all leftover funds will become part of the fee
const fn new(protocol: Protocol, fee: Fee, change_address: Option<Change>) -> Self {
fn new(protocol: Protocol, fee: Fee, change_address: Option<Change>) -> Self {
Self {
protocol,
fee,
@ -91,7 +91,6 @@ impl SignableTransactionBuilder {
Self(self.0.clone())
}
#[must_use]
pub fn new(protocol: Protocol, fee: Fee, change_address: Option<Change>) -> Self {
Self(Arc::new(RwLock::new(SignableTransactionBuilderInternal::new(
protocol,

View file

@ -211,7 +211,6 @@ pub struct Fee {
}
impl Fee {
#[must_use]
pub fn calculate(&self, weight: usize) -> u64 {
((((self.per_weight * u64::try_from(weight).unwrap()) - 1) / self.mask) + 1) * self.mask
}
@ -262,7 +261,6 @@ impl fmt::Debug for Change {
impl Change {
/// Create a change output specification from a ViewPair, as needed to maintain privacy.
#[must_use]
pub fn new(view: &ViewPair, guaranteed: bool) -> Self {
Self {
address: view.address(
@ -280,7 +278,6 @@ impl Change {
/// Create a fingerprintable change output specification which will harm privacy.
///
/// Only use this if you know what you're doing.
#[must_use]
pub const fn fingerprintable(address: MoneroAddress) -> Self {
Self { address, view: None }
}
@ -394,8 +391,7 @@ impl SignableTransaction {
Ok(Self { protocol, r_seed, inputs, payments, data, fee })
}
#[must_use]
pub const fn fee(&self) -> u64 {
pub fn fee(&self) -> u64 {
self.fee
}
@ -568,7 +564,6 @@ impl SignableTransaction {
/// The eventuality is defined as the TX extra/outputs this transaction will create, if signed
/// with the specified seed. This eventuality can be compared to on-chain transactions to see
/// if the transaction has already been signed and published.
#[must_use]
pub fn eventuality(&self) -> Option<Eventuality> {
let inputs = self.inputs.iter().map(SpendableOutput::key).collect::<Vec<_>>();
let (tx_key, additional, outputs, id) = Self::prepare_payments(
@ -726,7 +721,6 @@ impl Eventuality {
///
/// This extra may be used with a transaction with a distinct set of inputs, yet no honest
/// transaction which doesn't satisfy this Eventuality will contain it.
#[must_use]
pub fn extra(&self) -> &[u8] {
&self.extra
}
@ -817,7 +811,6 @@ impl Eventuality {
write_vec(write_byte, &self.extra, w)
}
#[must_use]
pub fn serialize(&self) -> Vec<u8> {
let mut buf = Vec::with_capacity(128);
self.write(&mut buf).unwrap();

View file

@ -82,7 +82,6 @@ impl Default for MemDb {
impl MemDb {
/// Create a new in-memory database.
#[must_use]
pub fn new() -> Self {
Self::default()
}

View file

@ -24,17 +24,14 @@ mod shims {
}
impl Error {
#[must_use]
pub fn new<E: 'static + Send + Sync>(kind: ErrorKind, error: E) -> Self {
Self { kind, error: Box::new(error) }
}
#[must_use]
pub const fn kind(&self) -> ErrorKind {
self.kind
}
#[must_use]
pub fn into_inner(self) -> Option<Box<dyn Send + Sync>> {
Some(self.error)
}

View file

@ -1,6 +1,8 @@
use core::{ops::Deref, fmt};
use std::{io, collections::HashMap};
use thiserror::Error;
use zeroize::{Zeroize, Zeroizing};
use rand_core::{RngCore, CryptoRng};
@ -68,7 +70,7 @@ impl<C: Ciphersuite, M: Message> EncryptionKeyMessage<C, M> {
}
#[cfg(any(test, feature = "tests"))]
pub(crate) const fn enc_key(&self) -> C::G {
pub(crate) fn enc_key(&self) -> C::G {
self.enc_key
}
}
@ -328,19 +330,13 @@ fn encryption_key_transcript(context: &str) -> RecommendedTranscript {
transcript
}
#[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,
}
#[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)]
@ -386,7 +382,7 @@ impl<C: Ciphersuite> Encryption<C> {
}
}
pub(crate) const fn registration<M: Message>(&self, msg: M) -> EncryptionKeyMessage<C, M> {
pub(crate) fn registration<M: Message>(&self, msg: M) -> EncryptionKeyMessage<C, M> {
EncryptionKeyMessage { msg, enc_key: self.enc_pub_key }
}

View file

@ -94,7 +94,7 @@ impl<C: Ciphersuite> KeyGenMachine<C> {
/// Create a new machine to generate a key.
///
/// The context string should be unique among multisigs.
pub const fn new(params: ThresholdParams, context: String) -> Self {
pub fn new(params: ThresholdParams, context: String) -> Self {
Self { params, context, curve: PhantomData }
}

View file

@ -3,7 +3,8 @@
#![cfg_attr(not(feature = "std"), no_std)]
use core::fmt::{self, Debug};
extern crate alloc;
use thiserror::Error;
use zeroize::Zeroize;
@ -61,58 +62,49 @@ impl fmt::Display for Participant {
}
/// Various errors possible during key generation.
#[allow(clippy::std_instead_of_core)]
mod dkg_error {
use core::fmt::Debug;
use thiserror::Error;
use super::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),
#[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),
/// 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),
/// 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> },
}
/// 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 alloc::sync::Arc;
use std::{io, collections::HashMap};
use std::{sync::Arc, io, collections::HashMap};
use zeroize::Zeroizing;
@ -268,17 +260,17 @@ mod lib {
}
/// Parameters for these keys.
pub const fn params(&self) -> ThresholdParams {
pub fn params(&self) -> ThresholdParams {
self.params
}
/// Secret share for these keys.
pub const fn secret_share(&self) -> &Zeroizing<C::F> {
pub fn secret_share(&self) -> &Zeroizing<C::F> {
&self.secret_share
}
/// Group key for these keys.
pub const fn group_key(&self) -> C::G {
pub fn group_key(&self) -> C::G {
self.group_key
}
@ -432,7 +424,7 @@ mod lib {
}
/// Return the current offset in-use for these keys.
pub const fn current_offset(&self) -> Option<C::F> {
pub fn current_offset(&self) -> Option<C::F> {
self.offset
}
@ -506,12 +498,12 @@ mod lib {
impl<C: Ciphersuite> ThresholdView<C> {
/// Return the offset for this view.
pub const fn offset(&self) -> C::F {
pub fn offset(&self) -> C::F {
self.offset
}
/// Return the group key.
pub const fn group_key(&self) -> C::G {
pub fn group_key(&self) -> C::G {
self.group_key
}
@ -521,7 +513,7 @@ mod lib {
}
/// Return the interpolated, offset secret share.
pub const fn secret_share(&self) -> &Zeroizing<C::F> {
pub fn secret_share(&self) -> &Zeroizing<C::F> {
&self.secret_share
}

View file

@ -1,6 +1,6 @@
use core::{marker::PhantomData, ops::Deref};
use alloc::sync::Arc;
use std::{
sync::Arc,
io::{self, Read, Write},
collections::HashMap,
};

View file

@ -41,7 +41,7 @@ impl<G0: PrimeGroup, G1: PrimeGroup> Re<G0, G1> {
Self::R(G0::identity(), G1::identity())
}
pub(crate) const fn e_default() -> Self {
pub(crate) fn e_default() -> Self {
Self::e(G0::Scalar::ZERO)
}
}

View file

@ -26,7 +26,7 @@ pub(crate) enum BitSignature {
}
impl BitSignature {
pub(crate) const fn to_u8(&self) -> u8 {
pub(crate) fn to_u8(&self) -> u8 {
match self {
Self::ClassicLinear => 0,
Self::ConciseLinear => 1,
@ -35,7 +35,7 @@ impl BitSignature {
}
}
pub(crate) const fn from(algorithm: u8) -> Self {
pub(crate) fn from(algorithm: u8) -> Self {
match algorithm {
0 => Self::ClassicLinear,
1 => Self::ConciseLinear,
@ -45,14 +45,14 @@ impl BitSignature {
}
}
pub(crate) const fn bits(&self) -> usize {
pub(crate) fn bits(&self) -> usize {
match self {
Self::ClassicLinear | Self::EfficientLinear => 1,
Self::ConciseLinear | Self::CompromiseLinear => 2,
}
}
pub(crate) const fn ring_len(&self) -> usize {
pub(crate) fn ring_len(&self) -> usize {
#[allow(clippy::as_conversions, clippy::cast_possible_truncation)] // Needed for const
2_usize.pow(self.bits() as u32)
}

View file

@ -2,9 +2,10 @@ use core::ops::{Deref, DerefMut};
#[cfg(feature = "serialize")]
use std::io::{self, Read, Write};
use rand_core::{RngCore, CryptoRng};
use thiserror::Error;
use zeroize::{Zeroize, Zeroizing};
use rand_core::{RngCore, CryptoRng};
use digest::{Digest, HashMarker};
@ -92,27 +93,21 @@ impl<G: PrimeGroup> Generators<G> {
}
/// Error for cross-group DLEq proofs.
#[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,
}
#[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

View file

@ -147,7 +147,7 @@ pub type IetfSchnorr<C, H> = Schnorr<C, IetfTranscript, H>;
impl<C: Curve, T: Sync + Clone + Debug + Transcript, H: Hram<C>> Schnorr<C, T, H> {
/// Construct a Schnorr algorithm continuing the specified transcript.
pub const fn new(transcript: T) -> Self {
pub fn new(transcript: T) -> Self {
Self { transcript, c: None, _hram: PhantomData }
}
}
@ -156,7 +156,7 @@ impl<C: Curve, H: Hram<C>> IetfSchnorr<C, H> {
/// Construct a IETF-compatible Schnorr algorithm.
///
/// Please see the `IetfSchnorr` documentation for the full details of this.
pub const fn ietf() -> Self {
pub fn ietf() -> Self {
Self::new(IetfTranscript(vec![]))
}
}

View file

@ -1,8 +1,11 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
use core::fmt::Debug;
use std::collections::HashMap;
use thiserror::Error;
/// Distributed key generation protocol.
pub use dkg::{self, Participant, ThresholdParams, ThresholdCore, ThresholdKeys, ThresholdView};
@ -20,32 +23,25 @@ pub mod sign;
#[cfg(any(test, feature = "tests"))]
pub mod tests;
#[allow(clippy::std_instead_of_core)]
mod frost_error {
use core::fmt::Debug;
use thiserror::Error;
use dkg::Participant;
/// Various errors possible during signing.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
pub enum FrostError {
#[error("invalid participant (0 < participant <= {0}, yet participant is {1})")]
InvalidParticipant(u16, Participant),
#[error("invalid signing set ({0})")]
InvalidSigningSet(&'static str),
#[error("invalid participant quantity (expected {0}, got {1})")]
InvalidParticipantQuantity(usize, usize),
#[error("duplicated participant ({0})")]
DuplicatedParticipant(Participant),
#[error("missing participant {0}")]
MissingParticipant(Participant),
/// Various errors possible during signing.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
pub enum FrostError {
#[error("invalid participant (0 < participant <= {0}, yet participant is {1})")]
InvalidParticipant(u16, Participant),
#[error("invalid signing set ({0})")]
InvalidSigningSet(&'static str),
#[error("invalid participant quantity (expected {0}, got {1})")]
InvalidParticipantQuantity(usize, usize),
#[error("duplicated participant ({0})")]
DuplicatedParticipant(Participant),
#[error("missing participant {0}")]
MissingParticipant(Participant),
#[error("invalid preprocess (participant {0})")]
InvalidPreprocess(Participant),
#[error("invalid share (participant {0})")]
InvalidShare(Participant),
}
#[error("invalid preprocess (participant {0})")]
InvalidPreprocess(Participant),
#[error("invalid share (participant {0})")]
InvalidShare(Participant),
}
pub use frost_error::FrostError;
/// Validate a map of values to have the expected participants.
pub fn validate_map<T>(

View file

@ -53,7 +53,7 @@ struct Params<C: Curve, A: Algorithm<C>> {
}
impl<C: Curve, A: Algorithm<C>> Params<C, A> {
const fn new(algorithm: A, keys: ThresholdKeys<C>) -> Self {
fn new(algorithm: A, keys: ThresholdKeys<C>) -> Self {
Self { algorithm, keys }
}
@ -111,7 +111,7 @@ pub struct AlgorithmMachine<C: Curve, A: Algorithm<C>> {
impl<C: Curve, A: Algorithm<C>> AlgorithmMachine<C, A> {
/// Creates a new machine to generate a signature with the specified keys.
pub const fn new(algorithm: A, keys: ThresholdKeys<C>) -> Self {
pub fn new(algorithm: A, keys: ThresholdKeys<C>) -> Self {
Self { params: Params::new(algorithm, keys) }
}

View file

@ -124,7 +124,7 @@ Pippenger 6 is more efficient at 250 with 655µs per
Pippenger 7 is more efficient at 475 with 500µs per
Pippenger 8 is more efficient at 875 with 499µs per
*/
const fn algorithm(len: usize) -> Algorithm {
fn algorithm(len: usize) -> Algorithm {
#[cfg(not(debug_assertions))]
if len == 0 {
Algorithm::Null

View file

@ -61,7 +61,7 @@ enum DigestTranscriptMember {
}
impl DigestTranscriptMember {
const fn as_u8(&self) -> u8 {
fn as_u8(&self) -> u8 {
match self {
Self::Name => 0,
Self::Domain => 1,