Struct schnorr_fun::Schnorr
source · [−]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
: TheNonceGen
used to hash the signing inputs (and perhaps additional randomness) to produce the secret nonce.
Implementations
sourceimpl<H: Digest<OutputSize = U32> + Tagged> Schnorr<H, ()>
impl<H: Digest<OutputSize = U32> + Tagged> Schnorr<H, ()>
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();
sourceimpl<CH, NG> Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Tagged,
NG: AddTag,
impl<CH, NG> Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Tagged,
NG: AddTag,
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!
sourceimpl<NG, CH> Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
NG: NonceGen,
impl<NG, CH> Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
NG: NonceGen,
sourcepub fn sign(
&self,
keypair: &KeyPair,
message: Message<'_, impl Secrecy>
) -> Signature
pub fn sign(
&self,
keypair: &KeyPair,
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.verification_key(), message, &signature));
sourceimpl<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
pub fn new_keypair(&self, sk: Scalar) -> KeyPair
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
)
sourcepub fn challenge<S: Secrecy>(
&self,
R: XOnly,
X: XOnly,
m: Message<'_, S>
) -> Scalar<S, Zero>
pub fn challenge<S: Secrecy>(
&self,
R: XOnly,
X: XOnly,
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, 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));
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.
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));
sourcepub fn anticipate_signature(
&self,
X: &Point<EvenY, impl Secrecy>,
R: &Point<EvenY, impl Secrecy>,
m: Message<'_, impl Secrecy>
) -> Point<Jacobian, Public, Zero>
pub fn anticipate_signature(
&self,
X: &Point<EvenY, impl Secrecy>,
R: &Point<EvenY, impl Secrecy>,
m: Message<'_, impl Secrecy>
) -> Point<Jacobian, 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
sourceimpl<CH, NG> Adaptor for Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
impl<CH, NG> Adaptor for Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
sourcefn encryption_key_for(&self, decryption_key: &Scalar) -> Point
fn encryption_key_for(&self, decryption_key: &Scalar) -> Point
Derives the public encryption key corresponding to a secret decryption key. Read more
sourcefn verify_encrypted_signature(
&self,
verification_key: &Point<EvenY, impl Secrecy>,
encryption_key: &Point<impl Normalized, 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 Normalized, impl Secrecy>,
message: Message<'_, impl Secrecy>,
encrypted_signature: &EncryptedSignature<impl Secrecy>
) -> bool
Verifies an encrypted signature is valid i.e. if it is decrypted it will yield a signature
on message
under verification_key
. Read more
sourcefn decrypt_signature(
&self,
decryption_key: Scalar<impl Secrecy>,
encrypted_signature: EncryptedSignature<impl Secrecy>
) -> Signature
fn decrypt_signature(
&self,
decryption_key: Scalar<impl Secrecy>,
encrypted_signature: EncryptedSignature<impl Secrecy>
) -> Signature
Decrypts an encrypted signature yielding the signature. Read more
sourcefn recover_decryption_key(
&self,
encryption_key: &Point<impl Normalized, impl Secrecy>,
encrypted_signature: &EncryptedSignature<impl Secrecy>,
signature: &Signature<impl Secrecy>
) -> Option<Scalar>
fn recover_decryption_key(
&self,
encryption_key: &Point<impl Normalized, impl Secrecy>,
encrypted_signature: &EncryptedSignature<impl Secrecy>,
signature: &Signature<impl Secrecy>
) -> Option<Scalar>
Recovers the decryption key given an encrypted signature and the signature that was decrypted from it. Read more
sourceimpl<CH: Default + Tagged + Digest<OutputSize = U32>, NG: Default + AddTag> Default for Schnorr<CH, NG>
impl<CH: Default + Tagged + Digest<OutputSize = U32>, NG: Default + AddTag> Default for Schnorr<CH, NG>
sourceimpl<NG, CH> EncryptedSign for Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
NG: NonceGen,
impl<NG, CH> EncryptedSign for Schnorr<CH, NG> where
CH: Digest<OutputSize = U32> + Clone,
NG: NonceGen,
sourcefn encrypted_sign(
&self,
signing_key: &KeyPair,
encryption_key: &Point<impl Normalized, impl Secrecy>,
message: Message<'_, impl Secrecy>
) -> EncryptedSignature
fn encrypted_sign(
&self,
signing_key: &KeyPair,
encryption_key: &Point<impl Normalized, impl Secrecy>,
message: Message<'_, impl Secrecy>
) -> EncryptedSignature
Create a signature on a message encrypted under encryption_key
. Read more
Auto Trait Implementations
impl<CH, NG> RefUnwindSafe for Schnorr<CH, NG> where
CH: RefUnwindSafe,
NG: RefUnwindSafe,
impl<CH, NG> Send for Schnorr<CH, NG> where
CH: Send,
NG: Send,
impl<CH, NG> Sync for Schnorr<CH, NG> where
CH: Sync,
NG: Sync,
impl<CH, NG> Unpin for Schnorr<CH, NG> where
CH: Unpin,
NG: Unpin,
impl<CH, NG> UnwindSafe for Schnorr<CH, NG> where
CH: UnwindSafe,
NG: UnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Mark for T
impl<T> Mark for T
sourcefn mark<M>(self) -> <M as ChangeMark<T>>::Out where
M: ChangeMark<T>,
fn mark<M>(self) -> <M as ChangeMark<T>>::Out where
M: ChangeMark<T>,
Returns a new instance of the invocant that will be marked with M
. Read more
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more