pub struct Schnorr<CH, NG = ()> { /* private fields */ }
Expand description

An instance of a BIP-340 style Schnorr signature scheme.

Each instance is defined by its:

  • challenge_hash: The hash function instance that is used to produce the Fiat-Shamir challenge.
  • nonce_gen: The NonceGen used to hash the signing inputs (and perhaps additional randomness) to produce the secret nonce.

Implementations

Create a new instance that can only verify signatures.

Example
use schnorr_fun::Schnorr;
use sha2::Sha256;

let schnorr = Schnorr::<Sha256>::verify_only();

Creates a instance capable of signing and verifying.

Examples
use rand::rngs::ThreadRng;
use schnorr_fun::{
    nonce::{Deterministic, GlobalRng, Synthetic},
    Schnorr,
};
use sha2::Sha256;
// Use synthetic nonces (preferred)
let nonce_gen = Synthetic::<Sha256, GlobalRng<ThreadRng>>::default();
// Use deterministic nonces.
let nonce_gen = Deterministic::<Sha256>::default();
let schnorr = Schnorr::<Sha256, _>::new(nonce_gen.clone());
// then go and sign/verify messages!

Sign a message using a secret key and a particular nonce derivation scheme.

Examples
let keypair = schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
let message = Message::<Public>::plain(
    "times-of-london",
    b"Chancellor on brink of second bailout for banks",
);
let signature = schnorr.sign(&keypair, message);
assert!(schnorr.verify(&keypair.verification_key(), message, &signature));

Returns the NonceGen instance being used to genreate nonces.

Returns the challenge hash being used to sign/verify signatures

Converts a non-zero scalar to a key-pair by interpreting it as a secret key.

The secret key in the resulting key is not guaranteed to be the same as the input. For half the input values the result will be the negation of it. This happens because the corresponding Point may not have an y-coordinate that is even (see EvenY)

Produces the Fiat-Shamir challenge for a Schnorr signature in the form specified by BIP-340.

Concretely computes the hash H(R || X || m). The Secrecy of the message is inherited by the returned scalar.

Example

Here’s how you could use this to roll your own signatures.

use schnorr_fun::{
    fun::{marker::*, s, Scalar, XOnly, G},
    Message, Schnorr, Signature,
};
let message = Message::<Public>::plain("my-app", b"we rolled our own schnorr!");
let keypair = schnorr.new_keypair(Scalar::random(&mut rand::thread_rng()));
let mut r = Scalar::random(&mut rand::thread_rng());
let R = XOnly::from_scalar_mul(G, &mut r);
let challenge = schnorr.challenge(R, keypair.public_key(), message);
let s = s!(r + challenge * { keypair.secret_key() });
let signature = Signature { R, s };
assert!(schnorr.verify(&keypair.verification_key(), message, &signature));

Verifies a signature on a message under a given public key.

Note that a full Point<EvenY,..> is passed in rather than a XOnly because it’s more efficient for repeated verification (where as XOnly is more efficient for repeated signing).

Example
use schnorr_fun::{
    fun::{marker::*, nonce, Scalar, hex, Point},
    Message, Schnorr, Signature
};
use sha2::Sha256;
use core::str::FromStr;

let schnorr = Schnorr::<Sha256>::verify_only();
let public_key = Point::<EvenY, Public>::from_str("d69c3509bb99e412e68b0fe8544e72837dfa30746d8be2aa65975f29d22dc7b9").unwrap();
let signature = Signature::<Public>::from_str("00000000000000000000003b78ce563f89a0ed9414f5aa28ad0d96d6795f9c6376afb1548af603b3eb45c9f8207dee1060cb71c04e80f593060b07d28308d7f4").unwrap();
let message = hex::decode("4df3c3f68fcc83b27e9d42c90431a72499f17875c81a599b566c9889b9696703").unwrap();
assert!(schnorr.verify(&public_key, Message::<Secret>::raw(&message), &signature));

// We could also say the message is secret if we don't want to leak which message we are
// verifying through execution time.
assert!(schnorr.verify(&public_key, Message::<Secret>::raw(&message), &signature));

Anticipates a Schnorr signature given the nonce R that will be used ahead of time. Deterministically returns the group element that corresponds to the scalar value of the signature. i.e R + c * X

Trait Implementations

Derives the public encryption key corresponding to a secret decryption key. Read more

Verifies an encrypted signature is valid i.e. if it is decrypted it will yield a signature on message under verification_key. Read more

Decrypts an encrypted signature yielding the signature. Read more

Recovers the decryption key given an encrypted signature and the signature that was decrypted from it. Read more

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Returns a Schnorr instance tagged in the default way according to BIP340.

Examples
use schnorr_fun::{nonce::Deterministic, Schnorr};
use sha2::Sha256;

let schnorr = Schnorr::<Sha256, Deterministic<Sha256>>::default();

Create a signature on a message encrypted under encryption_key. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Returns a new instance of the invocant that will be marked with M. Read more

Should always be Self

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.