Crate ed25519_dalek [] [src]

ed25519 signatures and verification


Creating an ed25519 signature on a message is simple.

First, we need to generate a Keypair, which includes both public and secret halves of an asymmetric key. To do so, we need a cryptographically secure pseudorandom number generator (CSPRING), and a hash function which has 512 bits of output. For this example, we'll use the operating system's builtin PRNG and SHA-512 to generate a keypair:

extern crate rand;
extern crate sha2;
extern crate ed25519_dalek;

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);

We can now use this keypair to sign a message:

let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
let signature: Signature = keypair.sign::<Sha512>(message);

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

let verified: bool = keypair.verify::<Sha512>(message, &signature);


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

use ed25519_dalek::PublicKey;

let public_key: PublicKey = keypair.public;
let verified: bool = public_key.verify::<Sha512>(message, &signature);



PublicKeys, SecretKeys, Keypairs, and Signatures can be serialised into byte-arrays by calling .to_bytes(). It's perfectly acceptible 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!)


let public_key_bytes: [u8; PUBLIC_KEY_LENGTH] = public_key.to_bytes();
let secret_key_bytes: [u8; SECRET_KEY_LENGTH] = keypair.secret.to_bytes();
let keypair_bytes:    [u8; KEYPAIR_LENGTH]    = keypair.to_bytes();
let signature_bytes:  [u8; SIGNATURE_LENGTH]  = signature.to_bytes();

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

let public_key: PublicKey = PublicKey::from_bytes(&public_key_bytes)?;
let secret_key: SecretKey = SecretKey::from_bytes(&secret_key_bytes)?;
let keypair:    Keypair   = Keypair::from_bytes(&keypair_bytes)?;
let signature:  Signature = Signature::from_bytes(&signature_bytes)?;

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:

Be careful when using this code, it's not being tested!
$ cargo build --features="serde"

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

extern crate serde;
extern crate bincode;

use bincode::{serialize, Infinite};

let encoded_public_key: Vec<u8> = serialize(&public_key, Infinite).unwrap();
let encoded_signature: Vec<u8> = serialize(&signature, Infinite).unwrap();

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

use bincode::{deserialize};

let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
let decoded_public_key: PublicKey = deserialize(&encoded_public_key).unwrap();
let decoded_signature: Signature = deserialize(&encoded_signature).unwrap();

let verified: bool = decoded_public_key.verify::<Sha512>(&message, &decoded_signature);




An "expanded" secret key.


An ed25519 keypair.


An ed25519 public key.


An EdDSA secret key.


An EdDSA signature.



The length of an ed25519 EdDSA Keypair, in bytes.


The length of an ed25519 EdDSA PublicKey, in bytes.


The length of an ed25519 EdDSA SecretKey, in bytes.


The length of an ed25519 EdDSA Signature, in bytes.