Crate schnorrkel
source ·Expand description
Schnorr signature variants using Ristretto point compression.
Example
Creating a 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 (CSPRNG).
use rand::{Rng, rngs::OsRng};
use schnorrkel::{Keypair,Signature};
let keypair: Keypair = Keypair::generate_with(OsRng);
We can now use this keypair
to sign a message:
let context = signing_context(b"this signature does this thing");
let message: &[u8] = "This is a test of the tsunami alert system.".as_bytes();
let signature: Signature = keypair.sign(context.bytes(message));
As well as to verify that this is, indeed, a valid signature on
that message
:
assert!(keypair.verify(context.bytes(message), &signature).is_ok());
Anyone else, given the public
half of the keypair
can also easily
verify this signature:
use schnorrkel::PublicKey;
let public_key: PublicKey = keypair.public;
assert!(public_key.verify(context.bytes(message), &signature).is_ok());
Serialisation
PublicKey
s, MiniSecretKey
s, Keypair
s, and Signature
s 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!)
use schnorrkel::{PUBLIC_KEY_LENGTH, SECRET_KEY_LENGTH, KEYPAIR_LENGTH, SIGNATURE_LENGTH};
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 schnorrkell
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_public_key: Vec<u8> = serialize(&public_key).unwrap();
let encoded_signature: Vec<u8> = serialize(&signature).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();
assert!( public_key.verify(context.bytes(message), &signature).is_ok() );
Re-exports
pub use crate::context::signing_context;
pub use crate::sign::Signature;
pub use crate::sign::SIGNATURE_LENGTH;
pub use crate::errors::SignatureError;
pub use crate::errors::SignatureResult;
pub use crate::keys::*;
Modules
- Elliptic curve Qu-Vanstone implicit certificate scheme (ECQV) for Ristretto
- Schnorr signature contexts and configuration, adaptable to most Schnorr signature schemes.
- Implementation of “hierarchical deterministic key derivation” (HDKD) for Schnorr signatures on Ristretto
- Errors which may occur when parsing keys and/or signatures to or from wire formats.
- Schnorr signatures on the 2-torsion free subgroup of ed25519, as provided by the Ristretto point compression.
- Implementation for Ristretto Schnorr signatures of “Simple Schnorr Multi-Signatures with Applications to Bitcoin” by Gregory Maxwell, Andrew Poelstra, Yannick Seurin, and Pieter Wuille https://eprint.iacr.org/2018/068
- Ristretto point tooling
- Schnorr signature creation and verification, including batch verification.
- Implementation of a Verifiable Random Function (VRF) using Ristretto points and Schnorr DLEQ proofs.
Functions
- Verify a batch of
signatures
onmessages
with their respectivepublic_keys
. - Verify a batch of
signatures
onmessages
with their respectivepublic_keys
. - Verify a batch of
signatures
onmessages
with their respectivepublic_keys
.