diff --git a/Cargo.toml b/Cargo.toml index f88d422..3bf0f49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,8 +11,7 @@ repository = "https://github.com/penumbra-zone/decaf377-rdsa" [dependencies] # No Alloc, No Std blake2b_simd = { version = "0.5", default-features = false } -cfg-if = "1.0" -decaf377 = { git = "https://github.com/penumbra-zone/decaf377", rev = "f8c185eb40d2ece19783ce02b99861e85d304e92", default-features = false } +decaf377 = { git = "https://github.com/penumbra-zone/decaf377", rev = "e26c88c896d9e3da4677bfe9ba127ce45979e0b2", default-features = false } digest = { version = "0.9", default-features = false } rand_core = { version = "0.6", default-features = false } hex = { version = "0.4", default-features = false } @@ -39,8 +38,7 @@ name = "bench" harness = false [features] -#default = ["serde", "std"] -default = [] +default = ["serde", "std"] alloc = ["ark-ff", "ark-serialize"] std = ["alloc", "ark-ff/std", "blake2b_simd/std", "decaf377/arkworks", "digest/std", "hex/std", "rand_core/std", "thiserror"] parallel = ["ark-ff/parallel", "decaf377/parallel"] diff --git a/src/lib.rs b/src/lib.rs index bdee263..8fecba0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std)] #![doc = include_str!("../README.md")] -use cfg_if::cfg_if; mod domain; mod error; @@ -8,20 +7,16 @@ mod hash; use hash::HStar; mod signature; +mod signing_key; +mod verification_key; + pub use domain::{Binding, Domain, SpendAuth}; pub use error::Error; +pub use signature::Signature; +pub use signing_key::SigningKey; +pub use verification_key::{VerificationKey, VerificationKeyBytes}; -cfg_if! { - if #[cfg(feature = "std")] { - pub mod batch; - - mod signing_key; - mod verification_key; - - pub use signature::Signature; - pub use signing_key::SigningKey; - pub use verification_key::{VerificationKey, VerificationKeyBytes}; +pub use decaf377::Fr; - pub use decaf377::Fr; - } -} +#[cfg(feature = "std")] +pub mod batch; diff --git a/src/signing_key.rs b/src/signing_key.rs index 04f30ca..8e632ea 100644 --- a/src/signing_key.rs +++ b/src/signing_key.rs @@ -1,9 +1,7 @@ -use std::convert::{TryFrom, TryInto}; - use decaf377::Fr; use rand_core::{CryptoRng, RngCore}; -use crate::{Binding, Domain, Error, Signature, SpendAuth, VerificationKey}; +use crate::{Domain, Error, Signature, SpendAuth, VerificationKey}; /// A `decaf377-rdsa` signing key. #[derive(Copy, Clone)] @@ -16,22 +14,6 @@ pub struct SigningKey { pk: VerificationKey, } -impl std::fmt::Debug for SigningKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("SigningKey") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() - } -} - -impl std::fmt::Debug for SigningKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("SigningKey") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() - } -} - impl<'a, D: Domain> From<&'a SigningKey> for VerificationKey { fn from(sk: &'a SigningKey) -> VerificationKey { sk.pk.clone() @@ -63,8 +45,7 @@ impl TryFrom<[u8; 32]> for SigningKey { type Error = Error; fn try_from(bytes: [u8; 32]) -> Result { - use ark_serialize::CanonicalDeserialize; - let sk = Fr::deserialize_compressed(&bytes[..]).map_err(|_| Error::MalformedSigningKey)?; + let sk = Fr::from_bytes_checked(&bytes).map_err(|_| Error::MalformedSigningKey)?; Ok(Self::new_from_field(sk)) } } @@ -186,3 +167,30 @@ impl SigningKey { Signature::from_parts(r_bytes, s_bytes) } } + +#[cfg(feature = "std")] +mod std_only { + use super::*; + use std::fmt; + + use crate::Binding; + + impl fmt::Debug for SigningKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("SigningKey") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } + } + + impl fmt::Debug for SigningKey { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("SigningKey") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } + } +} + +#[cfg(feature = "std")] +pub use std_only::*; diff --git a/src/verification_key.rs b/src/verification_key.rs index 2e9250a..c2f2c40 100644 --- a/src/verification_key.rs +++ b/src/verification_key.rs @@ -1,13 +1,12 @@ -use std::{ - cmp::Ord, - convert::TryFrom, +use core::{ + cmp::{self, Ord}, hash::{Hash, Hasher}, marker::PhantomData, }; use decaf377::Fr; -use crate::{domain::Sealed, Binding, Domain, Error, Signature, SpendAuth}; +use crate::{domain::Sealed, Domain, Error, Signature, SpendAuth}; /// A refinement type for `[u8; 32]` indicating that the bytes represent /// an encoding of a `decaf377-rdsa` verification key. @@ -51,13 +50,13 @@ impl Hash for VerificationKeyBytes { } impl PartialOrd for VerificationKeyBytes { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { self.bytes.partial_cmp(&other.bytes) } } impl Ord for VerificationKeyBytes { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> cmp::Ordering { self.bytes.cmp(&other.bytes) } } @@ -84,13 +83,13 @@ impl Hash for VerificationKey { } impl PartialOrd for VerificationKey { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { self.bytes.partial_cmp(&other.bytes) } } impl Ord for VerificationKey { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> cmp::Ordering { self.bytes.cmp(&other.bytes) } } @@ -212,7 +211,7 @@ impl VerificationKey { /// Convenience method for identity checks. pub fn is_identity(&self) -> bool { - self.point.is_identity() + self.point == decaf377::Element::IDENTITY } /// Verify a purported `signature` with a prehashed challenge. @@ -232,7 +231,7 @@ impl VerificationKey { let cA = self.point * c; let check = sB - cA - R; - if check.is_identity() { + if check == decaf377::Element::IDENTITY { Ok(()) } else { Err(Error::InvalidSignature) @@ -240,49 +239,59 @@ impl VerificationKey { } } -impl std::cmp::PartialEq for VerificationKey { +impl PartialEq for VerificationKey { fn eq(&self, other: &Self) -> bool { self.bytes.eq(&other.bytes) } } -impl std::cmp::PartialEq for VerificationKeyBytes { +impl PartialEq for VerificationKeyBytes { fn eq(&self, other: &Self) -> bool { self.bytes.eq(&other.bytes) } } -impl std::cmp::Eq for VerificationKey {} -impl std::cmp::Eq for VerificationKeyBytes {} +impl Eq for VerificationKey {} +impl Eq for VerificationKeyBytes {} -impl std::fmt::Debug for VerificationKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("VerificationKey") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() +#[cfg(feature = "std")] +mod std_only { + use super::*; + + use crate::Binding; + + impl std::fmt::Debug for VerificationKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("VerificationKey") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } } -} -impl std::fmt::Debug for VerificationKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("VerificationKey") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() + impl std::fmt::Debug for VerificationKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("VerificationKey") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } } -} -impl std::fmt::Debug for VerificationKeyBytes { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("VerificationKeyBytes") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() + impl std::fmt::Debug for VerificationKeyBytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("VerificationKeyBytes") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } } -} -impl std::fmt::Debug for VerificationKeyBytes { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_tuple("VerificationKeyBytes") - .field(&hex::encode(&<[u8; 32]>::from(*self))) - .finish() + impl std::fmt::Debug for VerificationKeyBytes { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("VerificationKeyBytes") + .field(&hex::encode(&<[u8; 32]>::from(*self))) + .finish() + } } } + +#[cfg(feature = "std")] +pub use std_only::*;