Struct schnorr_fun::Schnorr
source · pub struct Schnorr<CH, NG = NoNonces> { /* 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
: TheNonceGen
used to hash the signing inputs (and perhaps additional randomness) to produce the secret nonce.
Implementations§
source§impl<H: Digest<OutputSize = U32> + Tag + Default> Schnorr<H, NoNonces>
impl<H: Digest<OutputSize = U32> + Tag + Default> Schnorr<H, NoNonces>
sourcepub fn verify_only() -> Self
pub fn verify_only() -> Self
Create a new instance that can only verify signatures.
§Example
use schnorr_fun::Schnorr;
use sha2::Sha256;
let schnorr = Schnorr::<Sha256>::verify_only();
source§impl<CH, NG> Schnorr<CH, NG>
impl<CH, NG> Schnorr<CH, NG>
sourcepub fn new(nonce_gen: NG) -> Self
pub fn new(nonce_gen: NG) -> Self
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!
source§impl<CH, NG> Schnorr<CH, NG>
impl<CH, NG> Schnorr<CH, NG>
sourcepub fn sign(
&self,
keypair: &KeyPair<EvenY>,
message: Message<'_, impl Secrecy>
) -> Signature
pub fn sign( &self, keypair: &KeyPair<EvenY>, message: Message<'_, impl Secrecy> ) -> Signature
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.public_key(), message, &signature));
source§impl<NG, CH: Digest<OutputSize = U32> + Clone> Schnorr<CH, NG>
impl<NG, CH: Digest<OutputSize = U32> + Clone> Schnorr<CH, NG>
sourcepub fn challenge_hash(&self) -> CH
pub fn challenge_hash(&self) -> CH
Returns the challenge hash being used to sign/verify signatures
sourcepub fn new_keypair(&self, sk: Scalar) -> KeyPair<EvenY>
pub fn new_keypair(&self, sk: Scalar) -> KeyPair<EvenY>
Convieninece method for creating a new signing KeyPair<EvenY>
sourcepub fn challenge<S: Secrecy>(
&self,
R: &Point<EvenY, impl Secrecy>,
X: &Point<EvenY, impl Secrecy>,
m: Message<'_, S>
) -> Scalar<S, Zero>
pub fn challenge<S: Secrecy>( &self, R: &Point<EvenY, impl Secrecy>, X: &Point<EvenY, impl Secrecy>, m: Message<'_, S> ) -> Scalar<S, Zero>
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, Point, Scalar, 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 = Point::even_y_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.public_key(), message, &signature));
sourcepub fn verify(
&self,
public_key: &Point<EvenY, impl Secrecy>,
message: Message<'_, impl Secrecy>,
signature: &Signature<impl Secrecy>
) -> bool
pub fn verify( &self, public_key: &Point<EvenY, impl Secrecy>, message: Message<'_, impl Secrecy>, signature: &Signature<impl Secrecy> ) -> bool
Verifies a signature on a message under a given public key.
§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 want to use a constant time algorithm to verify the signature.
assert!(schnorr.verify(&public_key, Message::<Secret>::raw(&message), &signature));
sourcepub fn anticipate_signature(
&self,
X: &Point<EvenY, impl Secrecy>,
R: &Point<EvenY, impl Secrecy>,
m: Message<'_, impl Secrecy>
) -> Point<NonNormal, Public, Zero>
pub fn anticipate_signature( &self, X: &Point<EvenY, impl Secrecy>, R: &Point<EvenY, impl Secrecy>, m: Message<'_, impl Secrecy> ) -> Point<NonNormal, Public, Zero>
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§
source§impl<CH, NG> Adaptor for Schnorr<CH, NG>
impl<CH, NG> Adaptor for Schnorr<CH, NG>
source§fn encryption_key_for(&self, decryption_key: &Scalar) -> Point
fn encryption_key_for(&self, decryption_key: &Scalar) -> Point
source§fn verify_encrypted_signature(
&self,
verification_key: &Point<EvenY, impl Secrecy>,
encryption_key: &Point<impl PointType, impl Secrecy>,
message: Message<'_, impl Secrecy>,
encrypted_signature: &EncryptedSignature<impl Secrecy>
) -> bool
fn verify_encrypted_signature( &self, verification_key: &Point<EvenY, impl Secrecy>, encryption_key: &Point<impl PointType, impl Secrecy>, message: Message<'_, impl Secrecy>, encrypted_signature: &EncryptedSignature<impl Secrecy> ) -> bool
message
under verification_key
. Read more