curve25519-dalek-source/src/ed25519.rs

1192 lines
40 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// -*- mode: rust; -*-
//
// This file is part of ed25519-dalek.
// Copyright (c) 2017 Isis Lovecruft
// See LICENSE for licensing information.
//
// Authors:
// - Isis Agora Lovecruft <isis@patternsinthevoid.net>
//! A Rust implementation of ed25519 EdDSA key generation, signing, and
//! verification.
use core::fmt::{Debug};
#[cfg(feature = "std")]
use rand::Rng;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
#[cfg(feature = "serde")]
use serde::{Serializer, Deserializer};
#[cfg(feature = "serde")]
use serde::de::Error as SerdeError;
#[cfg(feature = "serde")]
use serde::de::Visitor;
#[cfg(feature = "sha2")]
use sha2::Sha512;
use digest::Digest;
use generic_array::typenum::U64;
use curve25519_dalek::constants;
use curve25519_dalek::edwards::CompressedEdwardsY;
use curve25519_dalek::edwards::ExtendedPoint;
use curve25519_dalek::scalar::Scalar;
use subtle::slices_equal;
use errors::DecodingError;
use errors::InternalError;
/// The length of a curve25519 EdDSA `Signature`, in bytes.
pub const SIGNATURE_LENGTH: usize = 64;
/// The length of a curve25519 EdDSA `SecretKey`, in bytes.
pub const SECRET_KEY_LENGTH: usize = 32;
/// The length of an ed25519 EdDSA `PublicKey`, in bytes.
pub const PUBLIC_KEY_LENGTH: usize = 32;
/// The length of an ed25519 EdDSA `Keypair`, in bytes.
pub const KEYPAIR_LENGTH: usize = SECRET_KEY_LENGTH + PUBLIC_KEY_LENGTH;
/// The length of the "key" portion of an "expanded" curve25519 EdDSA secret key, in bytes.
const EXPANDED_SECRET_KEY_KEY_LENGTH: usize = 32;
/// The length of the "nonce" portion of an "expanded" curve25519 EdDSA secret key, in bytes.
const EXPANDED_SECRET_KEY_NONCE_LENGTH: usize = 32;
/// The length of an "expanded" curve25519 EdDSA key, `ExpandedSecretKey`, in bytes.
pub const EXPANDED_SECRET_KEY_LENGTH: usize = EXPANDED_SECRET_KEY_KEY_LENGTH + EXPANDED_SECRET_KEY_NONCE_LENGTH;
/// An EdDSA signature.
///
/// # Note
///
/// These signatures, unlike the ed25519 signature reference implementation, are
/// "detached"—that is, they do **not** include a copy of the message which has
/// been signed.
#[derive(Copy)]
#[repr(C)]
pub struct Signature {
/// `r` is an `ExtendedPoint`, formed by using an hash function with
/// 512-bits output to produce the digest of:
///
/// - the nonce half of the `ExpandedSecretKey`, and
/// - the message to be signed.
///
/// This digest is then interpreted as a `Scalar` and reduced into an
/// element in /l. The scalar is then multiplied by the distinguished
/// basepoint to produce `r`, and `ExtendedPoint`.
pub (crate) r: CompressedEdwardsY,
/// `s` is a `Scalar`, formed by using an hash function with 512-bits output
/// to produce the digest of:
///
/// - the `r` portion of this `Signature`,
/// - the `PublicKey` which should be used to verify this `Signature`, and
/// - the message to be signed.
///
/// This digest is then interpreted as a `Scalar` and reduced into an
/// element in /l.
pub (crate) s: Scalar,
}
impl Clone for Signature {
fn clone(&self) -> Self { *self }
}
impl Debug for Signature {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "Signature( r: {:?}, s: {:?} )", &self.r, &self.s)
}
}
impl Eq for Signature {}
impl PartialEq for Signature {
fn eq(&self, other: &Signature) -> bool {
let mut equal: u8 = 0;
for i in 0..32 {
equal |= self.r.0[i] ^ other.r.0[i];
equal |= self.s[i] ^ other.s[i];
}
equal == 0
}
}
impl Signature {
/// Convert this `Signature` to a byte array.
#[inline]
pub fn to_bytes(&self) -> [u8; SIGNATURE_LENGTH] {
let mut signature_bytes: [u8; SIGNATURE_LENGTH] = [0u8; SIGNATURE_LENGTH];
signature_bytes[..32].copy_from_slice(&self.r.as_bytes()[..]);
signature_bytes[32..].copy_from_slice(&self.s.as_bytes()[..]);
signature_bytes
}
/// Construct a `Signature` from a slice of bytes.
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<Signature, DecodingError> {
if bytes.len() != SIGNATURE_LENGTH {
return Err(DecodingError(InternalError::BytesLengthError{
name: "Signature", length: SIGNATURE_LENGTH }));
}
let mut lower: [u8; 32] = [0u8; 32];
let mut upper: [u8; 32] = [0u8; 32];
lower.copy_from_slice(&bytes[..32]);
upper.copy_from_slice(&bytes[32..]);
if upper[31] & 224 != 0 {
return Err(DecodingError(InternalError::ScalarFormatError));
}
Ok(Signature{ r: CompressedEdwardsY(lower), s: Scalar::from_bits(upper) })
}
}
#[cfg(feature = "serde")]
impl Serialize for Signature {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_bytes(&self.to_bytes()[..])
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for Signature {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'d> {
struct SignatureVisitor;
impl<'d> Visitor<'d> for SignatureVisitor {
type Value = Signature;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("An ed25519 signature as 64 bytes, as specified in RFC8032.")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Signature, E> where E: SerdeError{
Signature::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
}
}
deserializer.deserialize_bytes(SignatureVisitor)
}
}
/// An EdDSA secret key.
#[repr(C)]
pub struct SecretKey(pub (crate) [u8; SECRET_KEY_LENGTH]);
impl Debug for SecretKey {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "SecretKey: {:?}", &self.0[..])
}
}
impl SecretKey {
/// Expand this `SecretKey` into an `ExpandedSecretKey`.
pub fn expand<D>(&self) -> ExpandedSecretKey where D: Digest<OutputSize = U64> + Default {
ExpandedSecretKey::from_secret_key::<D>(&self)
}
/// Convert this secret key to a byte array.
#[inline]
pub fn to_bytes(&self) -> [u8; SECRET_KEY_LENGTH] {
self.0
}
/// View this secret key as a byte array.
#[inline]
pub fn as_bytes<'a>(&'a self) -> &'a [u8; SECRET_KEY_LENGTH] {
&self.0
}
/// Construct a `SecretKey` from a slice of bytes.
///
/// # Example
///
/// ```
/// # extern crate ed25519_dalek;
/// #
/// use ed25519_dalek::SecretKey;
/// use ed25519_dalek::SECRET_KEY_LENGTH;
/// use ed25519_dalek::DecodingError;
///
/// # fn doctest() -> Result<SecretKey, DecodingError> {
/// let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = [
/// 157, 097, 177, 157, 239, 253, 090, 096,
/// 186, 132, 074, 244, 146, 236, 044, 196,
/// 068, 073, 197, 105, 123, 050, 105, 025,
/// 112, 059, 172, 003, 028, 174, 127, 096, ];
///
/// let secret_key: SecretKey = SecretKey::from_bytes(&secret_key_bytes)?;
/// #
/// # Ok(secret_key)
/// # }
/// #
/// # fn main() {
/// # let result = doctest();
/// # assert!(result.is_ok());
/// # }
/// ```
///
/// # Returns
///
/// A `Result` whose okay value is an EdDSA `SecretKey` or whose error value
/// is an `DecodingError` wrapping the internal error that occurred.
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<SecretKey, DecodingError> {
if bytes.len() != SECRET_KEY_LENGTH {
return Err(DecodingError(InternalError::BytesLengthError{
name: "SecretKey", length: SECRET_KEY_LENGTH }));
}
let mut bits: [u8; 32] = [0u8; 32];
bits.copy_from_slice(&bytes[..32]);
Ok(SecretKey(bits))
}
/// Generate a `SecretKey` from a `csprng`.
///
/// # Example
///
/// ```
/// extern crate rand;
/// extern crate sha2;
/// extern crate ed25519_dalek;
///
/// # fn main() {
///
/// use rand::Rng;
/// use rand::OsRng;
/// use sha2::Sha512;
/// use ed25519_dalek::PublicKey;
/// use ed25519_dalek::SecretKey;
/// use ed25519_dalek::Signature;
///
/// let mut csprng: OsRng = OsRng::new().unwrap();
/// let secret_key: SecretKey = SecretKey::generate(&mut csprng);
///
/// # }
/// ```
///
/// Afterwards, you can generate the corresponding public—provided you also
/// supply a hash function which implements the `Digest` and `Default`
/// traits, and which returns 512 bits of output—via:
///
/// ```
/// # extern crate rand;
/// # extern crate sha2;
/// # extern crate ed25519_dalek;
/// #
/// # fn main() {
/// #
/// # use rand::Rng;
/// # use rand::OsRng;
/// # use sha2::Sha512;
/// # use ed25519_dalek::PublicKey;
/// # use ed25519_dalek::SecretKey;
/// # use ed25519_dalek::Signature;
/// #
/// # let mut csprng: OsRng = OsRng::new().unwrap();
/// # let secret_key: SecretKey = SecretKey::generate(&mut csprng);
///
/// let public_key: PublicKey = PublicKey::from_secret::<Sha512>(&secret_key);
/// # }
/// ```
///
/// The standard hash function used for most ed25519 libraries is SHA-512,
/// which is available with `use sha2::Sha512` as in the example above.
/// Other suitable hash functions include Keccak-512 and Blake2b-512.
///
/// # Input
///
/// A CSPRNG with a `fill_bytes()` method, e.g. the one returned
/// from `rand::OsRng::new()` (in the `rand` crate).
///
#[cfg(feature = "std")]
pub fn generate(csprng: &mut Rng) -> SecretKey {
let mut sk: SecretKey = SecretKey([0u8; 32]);
csprng.fill_bytes(&mut sk.0);
sk
}
}
#[cfg(feature = "serde")]
impl Serialize for SecretKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_bytes(self.as_bytes())
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for SecretKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'d> {
struct SecretKeyVisitor;
impl<'d> Visitor<'d> for SecretKeyVisitor {
type Value = SecretKey;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("An ed25519 secret key as 32 bytes, as specified in RFC8032.")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<SecretKey, E> where E: SerdeError {
SecretKey::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
}
}
deserializer.deserialize_bytes(SecretKeyVisitor)
}
}
/// An "expanded" secret key.
///
/// This is produced by using an hash function with 512-bits output to digest a
/// `SecretKey`. The output digest is then split in half, the lower half being
/// the actual `key` used to sign messages, after twiddling with some bits.¹ The
/// upper half is used a sort of half-baked, ill-designed² pseudo-domain-separation
/// "nonce"-like thing, which is used during signature production by
/// concatenating it with the message to be signed before the message is hashed.
//
// ¹ This results in a slight bias towards non-uniformity at one spectrum of
// the range of valid keys. Oh well: not my idea; not my problem.
//
// ² It is the author's view (specifically, isis agora lovecruft, in the event
// you'd like to complain about me, again) that this is "ill-designed" because
// this doesn't actually provide true hash domain separation, in that in many
// real-world applications a user wishes to have one key which is used in
// several contexts (such as within tor, which does does domain separation
// manually by pre-concatenating static strings to messages to achieve more
// robust domain separation). In other real-world applications, such as
// bitcoind, a user might wish to have one master keypair from which others are
// derived (à la BIP32) and different domain separators between keys derived at
// different levels (and similarly for tree-based key derivation constructions,
// such as hash-based signatures). Leaving the domain separation to
// application designers, who thus far have produced incompatible,
// slightly-differing, ad hoc domain separation (at least those application
// designers who knew enough cryptographic theory to do so!), is therefore a
// bad design choice on the part of the cryptographer designing primitives
// which should be simple and as foolproof as possible to use for
// non-cryptographers. Further, later in the ed25519 signature scheme, as
// specified in RFC8032, the public key is added into *another* hash digest
// (along with the message, again); it is unclear to this author why there's
// not only one but two poorly-thought-out attempts at domain separation in the
// same signature scheme, and which both fail in exactly the same way. For a
// better-designed, Schnorr-based signature scheme, see Trevor Perrin's work on
// "generalised EdDSA" and "VXEdDSA".
#[repr(C)]
pub struct ExpandedSecretKey {
pub (crate) key: Scalar,
pub (crate) nonce: [u8; 32],
}
#[cfg(feature = "sha2")]
impl<'a> From<&'a SecretKey> for ExpandedSecretKey {
/// Construct an `ExpandedSecretKey` from a `SecretKey`.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate sha2;
/// # extern crate ed25519_dalek;
/// #
/// # fn main() {
/// #
/// use rand::{Rng, OsRng};
/// use sha2::Sha512;
/// use ed25519_dalek::{SecretKey, ExpandedSecretKey};
///
/// let mut csprng: OsRng = OsRng::new().unwrap();
/// let secret_key: SecretKey = SecretKey::generate(&mut csprng);
/// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from(&secret_key);
/// # }
/// ```
fn from(secret_key: &'a SecretKey) -> ExpandedSecretKey {
ExpandedSecretKey::from_secret_key::<Sha512>(&secret_key)
}
}
impl ExpandedSecretKey {
/// Convert this `ExpandedSecretKey` into an array of 64 bytes.
///
/// # Returns
///
/// An array of 64 bytes. The first 32 bytes represent the "expanded"
/// secret key, and the last 32 bytes represent the "domain-separation"
/// "nonce".
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate sha2;
/// # extern crate ed25519_dalek;
/// #
/// # #[cfg(feature = "sha2")]
/// # fn main() {
/// #
/// use rand::{Rng, OsRng};
/// use sha2::Sha512;
/// use ed25519_dalek::{SecretKey, ExpandedSecretKey};
///
/// let mut csprng: OsRng = OsRng::new().unwrap();
/// let secret_key: SecretKey = SecretKey::generate(&mut csprng);
/// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from(&secret_key);
/// let expanded_secret_key_bytes: [u8; 64] = expanded_secret_key.to_bytes();
///
/// assert!(&expanded_secret_key_bytes[..] != &[0u8; 64][..]);
/// # }
/// #
/// # #[cfg(not(feature = "sha2"))]
/// # fn main() { }
/// ```
#[inline]
pub fn to_bytes(&self) -> [u8; EXPANDED_SECRET_KEY_LENGTH] {
let mut bytes: [u8; 64] = [0u8; 64];
bytes[..32].copy_from_slice(self.key.as_bytes());
bytes[32..].copy_from_slice(&self.nonce[..]);
bytes
}
/// Construct an `ExpandedSecretKey` from a slice of bytes.
///
/// # Returns
///
/// A `Result` whose okay value is an EdDSA `ExpandedSecretKey` or whose
/// error value is an `DecodingError` describing the error that occurred.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate sha2;
/// # extern crate ed25519_dalek;
/// #
/// use rand::{Rng, OsRng};
/// use ed25519_dalek::{SecretKey, ExpandedSecretKey};
/// use ed25519_dalek::DecodingError;
///
/// # #[cfg(feature = "sha2")]
/// # fn do_test() -> Result<ExpandedSecretKey, DecodingError> {
/// #
/// let mut csprng: OsRng = OsRng::new().unwrap();
/// let secret_key: SecretKey = SecretKey::generate(&mut csprng);
/// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from(&secret_key);
/// let bytes: [u8; 64] = expanded_secret_key.to_bytes();
/// let expanded_secret_key_again = ExpandedSecretKey::from_bytes(&bytes)?;
/// #
/// # Ok(expanded_secret_key_again)
/// # }
/// #
/// # #[cfg(feature = "sha2")]
/// # fn main() {
/// # let result = do_test();
/// # assert!(result.is_ok());
/// # }
/// #
/// # #[cfg(not(feature = "sha2"))]
/// # fn main() {}
/// ```
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<ExpandedSecretKey, DecodingError> {
if bytes.len() != EXPANDED_SECRET_KEY_LENGTH {
return Err(DecodingError(InternalError::BytesLengthError{
name: "ExpandedSecretKey", length: EXPANDED_SECRET_KEY_LENGTH }));
}
let mut lower: [u8; 32] = [0u8; 32];
let mut upper: [u8; 32] = [0u8; 32];
lower.copy_from_slice(&bytes[00..32]);
upper.copy_from_slice(&bytes[32..64]);
Ok(ExpandedSecretKey{ key: Scalar::from_bits(lower),
nonce: upper })
}
/// Construct an `ExpandedSecretKey` from a `SecretKey`, using hash function `D`.
///
/// # Examples
///
/// ```
/// # extern crate rand;
/// # extern crate sha2;
/// # extern crate ed25519_dalek;
/// #
/// # fn do_test() {
/// #
/// use rand::{Rng, OsRng};
/// use sha2::Sha512;
/// use ed25519_dalek::{SecretKey, ExpandedSecretKey};
///
/// let mut csprng: OsRng = OsRng::new().unwrap();
/// let secret_key: SecretKey = SecretKey::generate(&mut csprng);
/// let expanded_secret_key: ExpandedSecretKey = ExpandedSecretKey::from_secret_key::<Sha512>(&secret_key);
/// # }
/// #
/// # fn main() { do_test(); }
/// ```
pub fn from_secret_key<D>(secret_key: &SecretKey) -> ExpandedSecretKey
where D: Digest<OutputSize = U64> + Default {
let mut h: D = D::default();
let mut hash: [u8; 64] = [0u8; 64];
let mut lower: [u8; 32] = [0u8; 32];
let mut upper: [u8; 32] = [0u8; 32];
h.input(secret_key.as_bytes());
hash.copy_from_slice(h.fixed_result().as_slice());
lower.copy_from_slice(&hash[00..32]);
upper.copy_from_slice(&hash[32..64]);
lower[0] &= 248;
lower[31] &= 63;
lower[31] |= 64;
ExpandedSecretKey{ key: Scalar::from_bits(lower), nonce: upper, }
}
/// Sign a message with this `ExpandedSecretKey`.
pub fn sign<D>(&self, message: &[u8], public_key: &PublicKey) -> Signature
where D: Digest<OutputSize = U64> + Default {
let mut h: D = D::default();
let mut hash: [u8; 64] = [0u8; 64];
let mesg_digest: Scalar;
let hram_digest: Scalar;
let r: ExtendedPoint;
let s: Scalar;
h.input(&self.nonce);
h.input(&message);
hash.copy_from_slice(h.fixed_result().as_slice());
mesg_digest = Scalar::from_bytes_mod_order_wide(&hash);
r = &mesg_digest * &constants::ED25519_BASEPOINT_TABLE;
h = D::default();
h.input(r.compress().as_bytes());
h.input(public_key.as_bytes());
h.input(&message);
hash.copy_from_slice(h.fixed_result().as_slice());
hram_digest = Scalar::from_bytes_mod_order_wide(&hash);
s = &(&hram_digest * &self.key) + &mesg_digest;
Signature{ r: r.compress(), s: s }
}
}
#[cfg(feature = "serde")]
impl Serialize for ExpandedSecretKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_bytes(&self.to_bytes()[..])
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for ExpandedSecretKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'d> {
struct ExpandedSecretKeyVisitor;
impl<'d> Visitor<'d> for ExpandedSecretKeyVisitor {
type Value = ExpandedSecretKey;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("An ed25519 expanded secret key as 64 bytes, as specified in RFC8032.")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<ExpandedSecretKey, E> where E: SerdeError {
ExpandedSecretKey::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
}
}
deserializer.deserialize_bytes(ExpandedSecretKeyVisitor)
}
}
/// An ed25519 public key.
#[derive(Copy, Clone, Eq, PartialEq)]
#[repr(C)]
pub struct PublicKey(pub (crate) CompressedEdwardsY);
impl Debug for PublicKey {
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
write!(f, "PublicKey( CompressedEdwardsY( {:?} ))", self.0)
}
}
impl PublicKey {
/// Convert this public key to a byte array.
#[inline]
pub fn to_bytes(&self) -> [u8; PUBLIC_KEY_LENGTH] {
self.0.to_bytes()
}
/// View this public key as a byte array.
#[inline]
pub fn as_bytes<'a>(&'a self) -> &'a [u8; PUBLIC_KEY_LENGTH] {
&(self.0).0
}
/// Construct a `PublicKey` from a slice of bytes.
///
/// # Warning
///
/// The caller is responsible for ensuring that the bytes passed into this
/// method actually represent a `curve25519_dalek::curve::CompressedEdwardsY`
/// and that said compressed point is actually a point on the curve.
///
/// # Example
///
/// ```
/// # extern crate ed25519_dalek;
/// #
/// use ed25519_dalek::PublicKey;
/// use ed25519_dalek::PUBLIC_KEY_LENGTH;
/// use ed25519_dalek::DecodingError;
///
/// # fn doctest() -> Result<PublicKey, DecodingError> {
/// let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = [
/// 215, 90, 152, 1, 130, 177, 10, 183, 213, 75, 254, 211, 201, 100, 7, 58,
/// 14, 225, 114, 243, 218, 166, 35, 37, 175, 2, 26, 104, 247, 7, 81, 26];
///
/// let public_key = PublicKey::from_bytes(&public_key_bytes)?;
/// #
/// # Ok(public_key)
/// # }
/// #
/// # fn main() {
/// # doctest();
/// # }
/// ```
///
/// # Returns
///
/// A `Result` whose okay value is an EdDSA `PublicKey` or whose error value
/// is an `DecodingError` describing the error that occurred.
#[inline]
pub fn from_bytes(bytes: &[u8]) -> Result<PublicKey, DecodingError> {
if bytes.len() != PUBLIC_KEY_LENGTH {
return Err(DecodingError(InternalError::BytesLengthError{
name: "PublicKey", length: PUBLIC_KEY_LENGTH }));
}
let mut bits: [u8; 32] = [0u8; 32];
bits.copy_from_slice(&bytes[..32]);
Ok(PublicKey(CompressedEdwardsY(bits)))
}
/// Convert this public key to its underlying extended twisted Edwards coordinate.
#[inline]
fn decompress(&self) -> Option<ExtendedPoint> {
self.0.decompress()
}
/// Derive this public key from its corresponding `SecretKey`.
#[allow(unused_assignments)]
pub fn from_secret<D>(secret_key: &SecretKey) -> PublicKey
where D: Digest<OutputSize = U64> + Default {
let mut h: D = D::default();
let mut hash: [u8; 64] = [0u8; 64];
let mut digest: [u8; 32] = [0u8; 32];
let pk: [u8; 32];
h.input(secret_key.as_bytes());
hash.copy_from_slice(h.fixed_result().as_slice());
digest.copy_from_slice(&hash[..32]);
digest[0] &= 248;
digest[31] &= 127;
digest[31] |= 64;
pk = (&Scalar::from_bits(digest) * &constants::ED25519_BASEPOINT_TABLE).compress().to_bytes();
PublicKey(CompressedEdwardsY(pk))
}
/// Verify a signature on a message with this keypair's public key.
///
/// # Return
///
/// Returns true if the signature was successfully verified, and
/// false otherwise.
pub fn verify<D>(&self, message: &[u8], signature: &Signature) -> bool
where D: Digest<OutputSize = U64> + Default
{
use curve25519_dalek::edwards::vartime;
let mut h: D = D::default();
let mut a: ExtendedPoint;
let ao: Option<ExtendedPoint>;
let mut digest: [u8; 64] = [0u8; 64];
ao = self.decompress();
if ao.is_some() {
a = ao.unwrap();
} else {
return false;
}
a = -(&a);
h.input(signature.r.as_bytes());
h.input(self.as_bytes());
h.input(&message);
digest.copy_from_slice(h.fixed_result().as_slice());
let digest_reduced: Scalar = Scalar::from_bytes_mod_order_wide(&digest);
let r: ExtendedPoint = vartime::double_scalar_mult_basepoint(&digest_reduced, &a, &signature.s);
slices_equal(signature.r.as_bytes(), r.compress().as_bytes()) == 1
}
}
#[cfg(feature = "serde")]
impl Serialize for PublicKey {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_bytes(self.as_bytes())
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for PublicKey {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'d> {
struct PublicKeyVisitor;
impl<'d> Visitor<'d> for PublicKeyVisitor {
type Value = PublicKey;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("An ed25519 public key as a 32-byte compressed point, as specified in RFC8032")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<PublicKey, E> where E: SerdeError {
PublicKey::from_bytes(bytes).or(Err(SerdeError::invalid_length(bytes.len(), &self)))
}
}
deserializer.deserialize_bytes(PublicKeyVisitor)
}
}
/// An ed25519 keypair.
#[derive(Debug)]
#[repr(C)]
pub struct Keypair {
/// The secret half of this keypair.
pub secret: SecretKey,
/// The public half of this keypair.
pub public: PublicKey,
}
impl Keypair {
/// Convert this keypair to bytes.
///
/// # Returns
///
/// An array of bytes, `[u8; KEYPAIR_LENGTH]`. The first
/// `SECRET_KEY_LENGTH` of bytes is the `SecretKey`, and the next
/// `PUBLIC_KEY_LENGTH` bytes is the `PublicKey` (the same as other
/// libraries, such as [Adam Langley's ed25519 Golang
/// implementation](https://github.com/agl/ed25519/)).
pub fn to_bytes(&self) -> [u8; KEYPAIR_LENGTH] {
let mut bytes: [u8; KEYPAIR_LENGTH] = [0u8; KEYPAIR_LENGTH];
bytes[..SECRET_KEY_LENGTH].copy_from_slice(self.secret.as_bytes());
bytes[SECRET_KEY_LENGTH..].copy_from_slice(self.public.as_bytes());
bytes
}
/// Construct a `Keypair` from the bytes of a `PublicKey` and `SecretKey`.
///
/// # Inputs
///
/// * `bytes`: an `&[u8]` representing the scalar for the secret key, and a
/// compressed Edwards-Y coordinate of a point on curve25519, both as bytes.
/// (As obtained from `Keypair::to_bytes()`.)
///
/// # Warning
///
/// Absolutely no validation is done on the key. If you give this function
/// bytes which do not represent a valid point, or which do not represent
/// corresponding parts of the key, then your `Keypair` will be broken and
/// it will be your fault.
///
/// # Returns
///
/// A `Result` whose okay value is an EdDSA `Keypair` or whose error value
/// is an `DecodingError` describing the error that occurred.
pub fn from_bytes<'a>(bytes: &'a [u8]) -> Result<Keypair, DecodingError> {
if bytes.len() != KEYPAIR_LENGTH {
return Err(DecodingError(InternalError::BytesLengthError{
name: "Keypair", length: KEYPAIR_LENGTH}));
}
let secret = SecretKey::from_bytes(&bytes[..SECRET_KEY_LENGTH])?;
let public = PublicKey::from_bytes(&bytes[SECRET_KEY_LENGTH..])?;
Ok(Keypair{ secret: secret, public: public })
}
/// Generate an ed25519 keypair.
///
/// # Example
///
/// ```
/// extern crate rand;
/// extern crate sha2;
/// extern crate ed25519_dalek;
///
/// # fn main() {
///
/// use rand::Rng;
/// use rand::OsRng;
/// use sha2::Sha512;
/// use ed25519_dalek::Keypair;
/// use ed25519_dalek::Signature;
///
/// let mut cspring: OsRng = OsRng::new().unwrap();
/// let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring);
///
/// # }
/// ```
///
/// # Input
///
/// A CSPRNG with a `fill_bytes()` method, e.g. the one returned
/// from `rand::OsRng::new()` (in the `rand` crate).
///
/// The caller must also supply a hash function which implements the
/// `Digest` and `Default` traits, and which returns 512 bits of output.
/// The standard hash function used for most ed25519 libraries is SHA-512,
/// which is available with `use sha2::Sha512` as in the example above.
/// Other suitable hash functions include Keccak-512 and Blake2b-512.
#[cfg(feature = "std")]
pub fn generate<D>(csprng: &mut Rng) -> Keypair
where D: Digest<OutputSize = U64> + Default {
let sk: SecretKey = SecretKey::generate(csprng);
let pk: PublicKey = PublicKey::from_secret::<D>(&sk);
Keypair{ public: pk, secret: sk }
}
/// Sign a message with this keypair's secret key.
pub fn sign<D>(&self, message: &[u8]) -> Signature
where D: Digest<OutputSize = U64> + Default {
self.secret.expand::<D>().sign::<D>(&message, &self.public)
}
/// Verify a signature on a message with this keypair's public key.
pub fn verify<D>(&self, message: &[u8], signature: &Signature) -> bool
where D: Digest<OutputSize = U64> + Default {
self.public.verify::<D>(message, signature)
}
}
#[cfg(feature = "serde")]
impl Serialize for Keypair {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
serializer.serialize_bytes(&self.to_bytes()[..])
}
}
#[cfg(feature = "serde")]
impl<'d> Deserialize<'d> for Keypair {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'d> {
struct KeypairVisitor;
impl<'d> Visitor<'d> for KeypairVisitor {
type Value = Keypair;
fn expecting(&self, formatter: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
formatter.write_str("An ed25519 signature as specified in RFC8032")
}
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Keypair, E> where E: SerdeError {
let secret_key = SecretKey::from_bytes(&bytes[..SECRET_KEY_LENGTH]);
let public_key = PublicKey::from_bytes(&bytes[SECRET_KEY_LENGTH..]);
if secret_key.is_ok() && public_key.is_ok() {
Ok(Keypair{ secret: secret_key.unwrap(), public: public_key.unwrap() })
} else {
Err(SerdeError::invalid_length(bytes.len(), &self))
}
}
}
deserializer.deserialize_bytes(KeypairVisitor)
}
}
#[cfg(test)]
mod test {
use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use std::string::String;
use std::vec::Vec;
use curve25519_dalek::edwards::ExtendedPoint;
use rand::OsRng;
use hex::FromHex;
use sha2::Sha512;
use super::*;
#[cfg(all(test, feature = "serde"))]
static PUBLIC_KEY: PublicKey = PublicKey(CompressedEdwardsY([
130, 039, 155, 015, 062, 076, 188, 063,
124, 122, 026, 251, 233, 253, 225, 220,
014, 041, 166, 120, 108, 035, 254, 077,
160, 083, 172, 058, 219, 042, 086, 120, ]));
#[cfg(all(test, feature = "serde"))]
static SECRET_KEY: SecretKey = SecretKey([
062, 070, 027, 163, 092, 182, 011, 003,
077, 234, 098, 004, 011, 127, 079, 228,
243, 187, 150, 073, 201, 137, 076, 022,
085, 251, 152, 002, 241, 042, 072, 054, ]);
/// Signature with the above keypair of a blank message.
#[cfg(all(test, feature = "serde"))]
static SIGNATURE_BYTES: [u8; SIGNATURE_LENGTH] = [
010, 126, 151, 143, 157, 064, 047, 001,
196, 140, 179, 058, 226, 152, 018, 102,
160, 123, 080, 016, 210, 086, 196, 028,
053, 231, 012, 157, 169, 019, 158, 063,
045, 154, 238, 007, 053, 185, 227, 229,
079, 108, 213, 080, 124, 252, 084, 167,
216, 085, 134, 144, 129, 149, 041, 081,
063, 120, 126, 100, 092, 059, 050, 011, ];
#[test]
fn unmarshal_marshal() { // TestUnmarshalMarshal
let mut cspring: OsRng;
let mut keypair: Keypair;
let mut x: Option<ExtendedPoint>;
let a: ExtendedPoint;
let public: PublicKey;
cspring = OsRng::new().unwrap();
// from_bytes() fails if vx²-u=0 and vx²+u=0
loop {
keypair = Keypair::generate::<Sha512>(&mut cspring);
x = keypair.public.decompress();
if x.is_some() {
a = x.unwrap();
break;
}
}
public = PublicKey(a.compress());
assert!(keypair.public.0 == public.0);
}
#[test]
fn sign_verify() { // TestSignVerify
let mut cspring: OsRng;
let keypair: Keypair;
let good_sig: Signature;
let bad_sig: Signature;
let good: &[u8] = "test message".as_bytes();
let bad: &[u8] = "wrong message".as_bytes();
cspring = OsRng::new().unwrap();
keypair = Keypair::generate::<Sha512>(&mut cspring);
good_sig = keypair.sign::<Sha512>(&good);
bad_sig = keypair.sign::<Sha512>(&bad);
assert!(keypair.verify::<Sha512>(&good, &good_sig) == true,
"Verification of a valid signature failed!");
assert!(keypair.verify::<Sha512>(&good, &bad_sig) == false,
"Verification of a signature on a different message passed!");
assert!(keypair.verify::<Sha512>(&bad, &good_sig) == false,
"Verification of a signature on a different message passed!");
}
// TESTVECTORS is taken from sign.input.gz in agl's ed25519 Golang
// package. It is a selection of test cases from
// http://ed25519.cr.yp.to/python/sign.input
#[cfg(test)]
#[cfg(not(release))]
#[test]
fn golden() { // TestGolden
let mut line: String;
let mut lineno: usize = 0;
let f = File::open("TESTVECTORS");
if f.is_err() {
println!("This test is only available when the code has been cloned \
from the git repository, since the TESTVECTORS file is large \
and is therefore not included within the distributed crate.");
panic!();
}
let file = BufReader::new(f.unwrap());
for l in file.lines() {
lineno += 1;
line = l.unwrap();
let parts: Vec<&str> = line.split(':').collect();
assert_eq!(parts.len(), 5, "wrong number of fields in line {}", lineno);
let sec_bytes: Vec<u8> = FromHex::from_hex(&parts[0]).unwrap();
let pub_bytes: Vec<u8> = FromHex::from_hex(&parts[1]).unwrap();
let msg_bytes: Vec<u8> = FromHex::from_hex(&parts[2]).unwrap();
let sig_bytes: Vec<u8> = FromHex::from_hex(&parts[3]).unwrap();
let secret: SecretKey = SecretKey::from_bytes(&sec_bytes[..SECRET_KEY_LENGTH]).unwrap();
let public: PublicKey = PublicKey::from_bytes(&pub_bytes[..PUBLIC_KEY_LENGTH]).unwrap();
let keypair: Keypair = Keypair{ secret: secret, public: public };
// The signatures in the test vectors also include the message
// at the end, but we just want R and S.
let sig1: Signature = Signature::from_bytes(&sig_bytes[..64]).unwrap();
let sig2: Signature = keypair.sign::<Sha512>(&msg_bytes);
assert!(sig1 == sig2, "Signature bytes not equal on line {}", lineno);
assert!(keypair.verify::<Sha512>(&msg_bytes, &sig2),
"Signature verification failed on line {}", lineno);
}
}
#[test]
fn public_key_from_bytes() {
// Make another function so that we can test the ? operator.
fn do_the_test() -> Result<PublicKey, DecodingError> {
let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = [
215, 090, 152, 001, 130, 177, 010, 183,
213, 075, 254, 211, 201, 100, 007, 058,
014, 225, 114, 243, 218, 166, 035, 037,
175, 002, 026, 104, 247, 007, 081, 026, ];
let public_key = PublicKey::from_bytes(&public_key_bytes)?;
Ok(public_key)
}
assert_eq!(do_the_test(), Ok(PublicKey(CompressedEdwardsY([
215, 090, 152, 001, 130, 177, 010, 183,
213, 075, 254, 211, 201, 100, 007, 058,
014, 225, 114, 243, 218, 166, 035, 037,
175, 002, 026, 104, 247, 007, 081, 026, ]))))
}
#[cfg(all(test, feature = "serde"))]
use bincode::{serialize, deserialize, Infinite};
#[cfg(all(test, feature = "serde"))]
#[test]
fn serialize_deserialize_signature() {
let signature: Signature = Signature::from_bytes(&SIGNATURE_BYTES).unwrap();
let encoded_signature: Vec<u8> = serialize(&signature, Infinite).unwrap();
let decoded_signature: Signature = deserialize(&encoded_signature).unwrap();
assert_eq!(signature, decoded_signature);
}
#[cfg(all(test, feature = "serde"))]
#[test]
fn serialize_deserialize_public_key() {
let encoded_public_key: Vec<u8> = serialize(&PUBLIC_KEY, Infinite).unwrap();
let decoded_public_key: PublicKey = deserialize(&encoded_public_key).unwrap();
assert_eq!(PUBLIC_KEY, decoded_public_key);
}
#[cfg(all(test, feature = "serde"))]
#[test]
fn serialize_deserialize_secret_key() {
let encoded_secret_key: Vec<u8> = serialize(&SECRET_KEY, Infinite).unwrap();
let decoded_secret_key: SecretKey = deserialize(&encoded_secret_key).unwrap();
for i in 0..32 {
assert_eq!(SECRET_KEY.0[i], decoded_secret_key.0[i]);
}
}
}
#[cfg(all(test, feature = "bench"))]
mod bench {
use test::Bencher;
use rand::OsRng;
use sha2::Sha512;
use super::*;
/// A fake RNG which simply returns zeroes.
struct ZeroRng;
impl ZeroRng {
pub fn new() -> ZeroRng {
ZeroRng
}
}
impl Rng for ZeroRng {
fn next_u32(&mut self) -> u32 { 0u32 }
fn fill_bytes(&mut self, bytes: &mut [u8]) {
for i in 0 .. bytes.len() {
bytes[i] = 0;
}
}
}
#[bench]
fn sign(b: &mut Bencher) {
let mut cspring: OsRng = OsRng::new().unwrap();
let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring);
let msg: &[u8] = b"";
b.iter(| | keypair.sign::<Sha512>(msg));
}
#[bench]
fn sign_expanded_key(b: &mut Bencher) {
let mut cspring: OsRng = OsRng::new().unwrap();
let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring);
let expanded: ExpandedSecretKey = keypair.secret.expand::<Sha512>();
let msg: &[u8] = b"";
b.iter(| | expanded.sign::<Sha512>(msg, &keypair.public));
}
#[bench]
fn verify(b: &mut Bencher) {
let mut cspring: OsRng = OsRng::new().unwrap();
let keypair: Keypair = Keypair::generate::<Sha512>(&mut cspring);
let msg: &[u8] = b"";
let sig: Signature = keypair.sign::<Sha512>(msg);
b.iter(| | keypair.verify::<Sha512>(msg, &sig));
}
#[bench]
fn key_generation(b: &mut Bencher) {
let mut rng: ZeroRng = ZeroRng::new();
b.iter(| | Keypair::generate::<Sha512>(&mut rng));
}
#[bench]
fn underlying_scalar_mult_basepoint(b: &mut Bencher) {
use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE;
let scalar: Scalar = Scalar::from_bits([
20, 130, 129, 196, 247, 182, 211, 102,
11, 168, 169, 131, 159, 69, 126, 35,
109, 193, 175, 54, 118, 234, 138, 81,
60, 183, 80, 186, 92, 248, 132, 13, ]);
b.iter(| | &scalar * &ED25519_BASEPOINT_TABLE);
}
}