Skip to content

Commit

Permalink
Stab at implementing signature traits
Browse files Browse the repository at this point in the history
  • Loading branch information
nickray committed Jun 2, 2022
1 parent 0eae1cf commit a203fcd
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ rustdoc-args = ["--cfg", "docsrs"]
der = { version = "0.6", features = ["derive"], optional = true }
ecdsa = { version = "0.14", package = "ecdsa", default-features = false, optional = true }
elliptic-curve = { version = "0.12", default-features = false, optional = true }
p256-cortex-m4-sys = "0.1.0-alpha.2"
p256-cortex-m4-sys = "0.1.0"
rand_core = { version = "0.6", default-features = false }
sha2 = { version = "0.10", default-features = false, optional = true }
signature = { version = "1.5", default-features = false, optional = true }
zeroize = { version = "1.5", default-features = false, features = ["zeroize_derive"] }

[dependencies.p256]
Expand Down
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,6 @@ pub use cortex_m4::*;
mod fallback;
#[cfg(all(feature = "non-cortex-m4-fallback", not(cortex_m4)))]
pub use fallback::*;

#[cfg(feature = "signature")]
pub mod signature;
75 changes: 75 additions & 0 deletions src/signature.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
//! Implementations of the `signature` traits.
pub use elliptic_curve::consts::U32;
pub use rand_core::{CryptoRng, RngCore};
pub use signature::{digest::{Digest, FixedOutput}, Result};

use crate::{PublicKey, SecretKey};

#[derive(Clone, Copy, Debug)]
/// "Bag of bytes" form of signature, as required by [`signature::Signature`] trait.
// NB: All ways of constructing this should ensure it's formally valid
// TODO: should we store (r, s), which we have to verify anyway?
// This is a trade-off between space efficiency and runtime efficiency.
pub struct Signature([u8; 64]);

impl From<crate::Signature> for Signature {
/// Converts an internal signature to a bag-of-bytes signature
fn from(signature: crate::Signature) -> Signature {
Signature(signature.to_untagged_bytes())
}
}

impl From<Signature> for crate::Signature {
/// Converts a bag-of-bytes signature to an internal signature
fn from(signature: Signature) -> crate::Signature {
crate::Signature::from_untagged_bytes(&signature.0)
.expect("valid signature")
}
}


impl AsRef<[u8]> for Signature {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl TryFrom<&[u8]> for Signature {
type Error = signature::Error;

fn try_from(bytes: &[u8]) -> Result<Self> {
crate::Signature::from_untagged_bytes(bytes)
.map_err(|_| signature::Error::new())
.map(|sig| sig.into())
}
}

impl signature::Signature for Signature {
fn from_bytes(bytes: &[u8]) -> Result<Self> {
bytes.try_into()
}
}

impl signature::Verifier<Signature> for PublicKey {
fn verify(&self, msg: &[u8], signature: &Signature) -> Result<()> {
self.verify(msg, &(*signature).into())
.then(|| ())
.ok_or_else(signature::Error::new)
}
}

impl signature::RandomizedSigner<Signature> for SecretKey {
fn try_sign_with_rng(&self, rng: impl CryptoRng + RngCore, msg: &[u8]) -> Result<Signature> {
Ok(self.sign(msg, rng).into())
}
}

impl<D> signature::RandomizedDigestSigner<D, Signature> for SecretKey
where
D: Digest + FixedOutput<OutputSize = U32>,
{
fn try_sign_digest_with_rng(&self, rng: impl CryptoRng + RngCore, digest: D) -> Result<Signature> {
Ok(self.sign_prehashed(digest.finalize_fixed().into(), rng).into())
}
}

0 comments on commit a203fcd

Please sign in to comment.