Module k256::schnorr

source ·
Available on crate feature schnorr only.
Expand description

Taproot Schnorr signatures as defined in BIP340.


Schnorr signatures are a simple group-based digital signature scheme with a number of desirable properties relating to security and composability:

  • Provably secure: strongly unforgable under chosen message attack (SUF-CMA).
  • Non-malleable: signatures cannot be altered by an attacker and still verify.
  • Linear: multiple parties can collaborate to produce a valid signature a.k.a. multisignatures.

Originally described in the late 1980s by their eponymous creator Claus Schnorr, they were patent-encumbered and thus lingered in obscurity until the relevant patents expired in 2010.

Since then, Schnorr signatures have seen something of a resurgence, with EdDSA and its concrete instantiation Ed25519 over the Curve25519 elliptic curve becoming the first Schnorr variant to see mainstream standardization.

The Taproot upgrade to Bitcoin includes a variant of Schnorr which operates over the secp256k1 elliptic curve, and is specified in BIP340. That is the variant which is implemented by this crate.

Because Taproot Schnorr is intended for use in consensus-critical applications (e.g. Bitcoin), it is fully specified such that no two implementations should disagree on the validity of a signature.


use k256::schnorr::{
    signature::{Signer, Verifier},
    SigningKey, VerifyingKey
use rand_core::OsRng; // requires 'getrandom' feature

// Signing
let signing_key = SigningKey::random(&mut OsRng); // serialize with `.to_bytes()`
let verifying_key_bytes = signing_key.verifying_key().to_bytes(); // 32-bytes

let message = b"Schnorr signatures prove knowledge of a secret in the random oracle model";
let signature = signing_key.sign(message); // returns `k256::schnorr::Signature`

// Verification
let verifying_key = VerifyingKey::from_bytes(&verifying_key_bytes)?;
verifying_key.verify(message, &signature)?;




Type Definitions