Crate ed25519_dalek

source ·
Expand description

A Rust implementation of ed25519 key generation, signing, and verification.

§Example

Creating an ed25519 signature on a message is simple.

First, we need to generate a SigningKey, which includes both public and secret halves of an asymmetric key. To do so, we need a cryptographically secure pseudorandom number generator (CSPRNG). For this example, we’ll use the operating system’s builtin PRNG:

use rand::rngs::OsRng;
use ed25519_dalek::SigningKey;
use ed25519_dalek::Signature;

let mut csprng = OsRng;
let signing_key: SigningKey = SigningKey::generate(&mut csprng);

We can now use this signing_key to sign a message:

use ed25519_dalek::{Signature, Signer};
let message: &[u8] = b"This is a test of the tsunami alert system.";
let signature: Signature = signing_key.sign(message);

As well as to verify that this is, indeed, a valid signature on that message:

use ed25519_dalek::Verifier;
assert!(signing_key.verify(message, &signature).is_ok());

Anyone else, given the public half of the signing_key can also easily verify this signature:

use ed25519_dalek::{VerifyingKey, Verifier};

let verifying_key: VerifyingKey = signing_key.verifying_key();
assert!(verifying_key.verify(message, &signature).is_ok());

§Serialisation

VerifyingKeys, SecretKeys, SigningKeys, and Signatures can be serialised into byte-arrays by calling .to_bytes(). It’s perfectly acceptable and safe to transfer and/or store those bytes. (Of course, never transfer your secret key to anyone else, since they will only need the public key to verify your signatures!)

use ed25519_dalek::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};

let verifying_key_bytes: [u8; PUBLIC_KEY_LENGTH] = signing_key.verifying_key().to_bytes();
let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = signing_key.to_bytes();
let signing_key_bytes:    [u8; KEYPAIR_LENGTH]    = signing_key.to_keypair_bytes();
let signature_bytes:  [u8; SIGNATURE_LENGTH]  = signature.to_bytes();

And similarly, decoded from bytes with ::from_bytes():

let verifying_key: VerifyingKey = VerifyingKey::from_bytes(&verifying_key_bytes)?;
let signing_key: SigningKey = SigningKey::from_bytes(&signing_key_bytes);
let signature: Signature = Signature::try_from(&signature_bytes[..])?;

§PKCS#8 Key Encoding

PKCS#8 is a private key format with support for multiple algorithms. It can be encoded as binary (DER) or text (PEM).

You can recognize PEM-encoded PKCS#8 keys by the following:

-----BEGIN PRIVATE KEY-----

To use PKCS#8, you need to enable the pkcs8 crate feature.

The following traits can be used to decode/encode SigningKey and VerifyingKey as PKCS#8. Note that [pkcs8] is re-exported from the toplevel of the crate:

  • [pkcs8::DecodePrivateKey]: decode private keys from PKCS#8
  • [pkcs8::EncodePrivateKey]: encode private keys to PKCS#8
  • [pkcs8::DecodePublicKey]: decode public keys from PKCS#8
  • [pkcs8::EncodePublicKey]: encode public keys to PKCS#8
§Example

NOTE: this requires the pem crate feature.

use ed25519_dalek::{VerifyingKey, pkcs8::DecodePublicKey};

let pem = "-----BEGIN PUBLIC KEY-----
MCowBQYDK2VwAyEAGb9ECWmEzf6FQbrBZ9w7lshQhqowtrbLDFw4rXAxZuE=
-----END PUBLIC KEY-----";

let verifying_key = VerifyingKey::from_public_key_pem(pem)
    .expect("invalid public key PEM");

§Using Serde

If you prefer the bytes to be wrapped in another serialisation format, all types additionally come with built-in serde support by building ed25519-dalek via:

$ cargo build --features="serde"

They can be then serialised into any of the wire formats which serde supports. For example, using bincode:

use bincode::serialize;

let encoded_verifying_key: Vec<u8> = serialize(&verifying_key).unwrap();
let encoded_signature: Vec<u8> = serialize(&signature).unwrap();

After sending the encoded_verifying_key and encoded_signature, the recipient may deserialise them and verify:

use bincode::deserialize;

let message: &[u8] = b"This is a test of the tsunami alert system.";
let decoded_verifying_key: VerifyingKey = deserialize(&encoded_verifying_key).unwrap();
let decoded_signature: Signature = deserialize(&encoded_signature).unwrap();

let verified: bool = decoded_verifying_key.verify(&message, &decoded_signature).is_ok();

assert!(verified);

Re-exports§

Structs§

Constants§

Traits§

  • Sign the provided message bytestring using Self (e.g. a cryptographic key or connection to an HSM), returning a digital signature.
  • Verify the provided message bytestring using Self (e.g. a public key)

Type Aliases§