Skip to content
This repository has been archived by the owner on Sep 4, 2022. It is now read-only.

Commit

Permalink
Use ed25519::Signature type; impl Signer/Verifier traits
Browse files Browse the repository at this point in the history
The `ed25519` crate provides a common `Signature` type which can be
shared among libraries which implement Ed25519 signing/verification.

Without common types/traits for Ed25519 signatures, downstream consumer
crates which use Ed25519 as part of a high-level protocol implementation
which allows consumers of their crates to be able to use their choice of
Rust Ed25519 libraries wind up writing their own abstractions to do so
on a crate-by-crate basis.

The `ed25519` crate, and the `signature` crate it's built on, provide
a common abstraction layer:

- `ed25519` crate: https://github.com/RustCrypto/signatures/tree/master/ed25519
- `signature` crate: https://github.com/RustCrypto/traits/tree/master/signature

The `ed25519` crate has been natively adopted by `ed25519-dalek`:

- Issue: dalek-cryptography/ed25519-dalek#80
- Usage example: https://docs.rs/ed25519/1.0.2/ed25519/#using-above-example-with-ed25519-dalek

If `sodiumoxide` were to adopt these types/traits as well, I'd be happy
to add similar documentation to the `ed25519` crate for how to use them
with `sodiumoxide`.
  • Loading branch information
tarcieri committed Dec 7, 2020
1 parent bd35f18 commit 79e6f84
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 32 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ exclude = [
members = ["libsodium-sys", "testcrate"]

[dependencies]
ed25519 = { version = "1", default-features = false }
libc = { version = "^0.2.41" , default-features = false }
libsodium-sys = { version = "0.2.5", path = "libsodium-sys" }
serde = { version = "^1.0.59", default-features = false, optional = true }
Expand Down
61 changes: 29 additions & 32 deletions src/crypto/sign/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
//! standard notion of unforgeability for a public-key signature scheme under
//! chosen-message attacks.
pub use ed25519::{
signature::{Signer, Verifier},
Error, Signature,
};

use ffi;
use libc::c_ulonglong;
#[cfg(not(feature = "std"))]
Expand Down Expand Up @@ -52,14 +57,25 @@ impl SecretKey {
}
}

impl Signer<Signature> for SecretKey {
fn try_sign(&self, msg: &[u8]) -> Result<Signature, Error> {
Ok(sign_detached(msg, self))
}
}

new_type! {
/// `PublicKey` for signatures
public PublicKey(PUBLICKEYBYTES);
}

new_type! {
/// Detached signature
public Signature(SIGNATUREBYTES);
impl Verifier<Signature> for PublicKey {
fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), Error> {
if verify_detached(sig, msg, self) {
Ok(())
} else {
Err(Error::new())
}
}
}

/// `gen_keypair()` randomly generates a secret key and a corresponding public
Expand Down Expand Up @@ -136,19 +152,19 @@ pub fn verify(sm: &[u8], pk: &PublicKey) -> Result<Vec<u8>, ()> {
/// `sign_detached()` signs a message `m` using the signer's secret key `sk`.
/// `sign_detached()` returns the resulting signature `sig`.
pub fn sign_detached(m: &[u8], sk: &SecretKey) -> Signature {
let mut sig = Signature([0u8; SIGNATUREBYTES]);
let mut sig = [0u8; SIGNATUREBYTES];
let mut siglen: c_ulonglong = 0;
unsafe {
ffi::crypto_sign_ed25519_detached(
sig.0.as_mut_ptr(),
sig.as_mut_ptr(),
&mut siglen,
m.as_ptr(),
m.len() as c_ulonglong,
sk.0.as_ptr(),
);
}
assert_eq!(siglen, SIGNATUREBYTES as c_ulonglong);
sig
Signature::new(sig)
}

/// `verify_detached()` verifies the signature in `sig` against the message `m`
Expand All @@ -157,7 +173,7 @@ pub fn sign_detached(m: &[u8], sk: &SecretKey) -> Signature {
pub fn verify_detached(sig: &Signature, m: &[u8], pk: &PublicKey) -> bool {
let ret = unsafe {
ffi::crypto_sign_ed25519_verify_detached(
sig.0.as_ptr(),
sig.as_ref().as_ptr(),
m.as_ptr(),
m.len() as c_ulonglong,
pk.0.as_ptr(),
Expand Down Expand Up @@ -204,16 +220,12 @@ impl State {
);
}
assert_eq!(siglen, SIGNATUREBYTES as c_ulonglong);
Signature(sig)
Signature::new(sig)
}

/// `veriry` verifies the signature in `sm` using the signer's public key `pk`.
pub fn verify(
&mut self,
&Signature(ref sig): &Signature,
&PublicKey(ref pk): &PublicKey,
) -> bool {
let mut sig = *sig;
/// `verify` verifies the signature in `sm` using the signer's public key `pk`.
pub fn verify(&mut self, sig: &Signature, &PublicKey(ref pk): &PublicKey) -> bool {
let mut sig = sig.to_bytes();
let ret = unsafe {
ffi::crypto_sign_ed25519ph_final_verify(&mut self.0, sig.as_mut_ptr(), pk.as_ptr())
};
Expand Down Expand Up @@ -289,10 +301,10 @@ mod test {
for i in 0..32usize {
let (pk, sk) = gen_keypair();
let m = randombytes(i);
let Signature(mut sig) = sign_detached(&m, &sk);
let mut sig = sign_detached(&m, &sk).to_bytes();
for j in 0..SIGNATUREBYTES {
sig[j] ^= 0x20;
assert!(!verify_detached(&Signature(sig), &m, &pk));
assert!(!verify_detached(&Signature::new(sig), &m, &pk));
sig[j] ^= 0x20;
}
}
Expand Down Expand Up @@ -389,21 +401,6 @@ mod test {
}
}

#[cfg(feature = "serde")]
#[test]
fn test_serialisation() {
use randombytes::randombytes;
use test_utils::round_trip;
for i in 0..256usize {
let (pk, sk) = gen_keypair();
let m = randombytes(i);
let sig = sign_detached(&m, &sk);
round_trip(pk);
round_trip(sk);
round_trip(sig);
}
}

#[test]
fn test_streaming_sign() {
use randombytes::randombytes;
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@

extern crate libsodium_sys as ffi;

extern crate ed25519;
extern crate libc;
#[cfg(any(test, feature = "serde"))]
extern crate serde;
Expand Down

0 comments on commit 79e6f84

Please sign in to comment.