Skip to content

Commit

Permalink
Simplify hash/nonce_gen tagging
Browse files Browse the repository at this point in the history
We don't need two traits that have almost the same API.
  • Loading branch information
LLFourn committed Dec 12, 2022
1 parent 1ec357b commit 53aad8a
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 149 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- Remove `XOnly` in favor of `Point<EvenY>`
- Replace `.mark` system with methods for changing each marker type.
- Make `From<u32>` for `Scalar` regardless of secrecy
- Merge `AddTag` and `Tagged` into one trait `Tag`

## 0.7.1

Expand Down
14 changes: 7 additions & 7 deletions ecdsa_fun/src/adaptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ use secp256kfun::{
digest::generic_array::typenum::U32,
g,
marker::*,
nonce::{AddTag, NonceGen},
s, Point, Scalar, G,
nonce::{NoNonces, NonceGen},
s, Point, Scalar, Tag, G,
};
pub use sigma_fun::HashTranscript;
use sigma_fun::{secp256k1, Eq, FiatShamir, ProverTranscript, Transcript};
Expand All @@ -88,15 +88,15 @@ pub struct Adaptor<T, NonceGen> {

impl<T, NG> Default for Adaptor<T, NG>
where
NG: Default + AddTag,
NG: Default + Tag,
T: Transcript<DLEQ> + Default,
{
fn default() -> Self {
Self::new(NG::default())
}
}

impl<T: Transcript<DLEQ> + Default, NG: AddTag> Adaptor<T, NG> {
impl<T: Transcript<DLEQ> + Default, NG: Tag> Adaptor<T, NG> {
pub fn new(nonce_gen: NG) -> Self {
let sigma = DLEQ::default();
Self {
Expand All @@ -106,15 +106,15 @@ impl<T: Transcript<DLEQ> + Default, NG: AddTag> Adaptor<T, NG> {
}
}

impl<T: Transcript<DLEQ> + Default> Adaptor<T, ()> {
impl<T: Transcript<DLEQ> + Default> Adaptor<T, NoNonces> {
/// Create an `Adaptor` instance that can do verification only
/// # Example
/// ```
/// use ecdsa_fun::adaptor::{Adaptor, HashTranscript};
/// let adaptor = Adaptor::<HashTranscript<sha2::Sha256>, _>::verify_only();
/// ```
pub fn verify_only() -> Self {
Self::new(())
Self::new(NoNonces)
}
}

Expand Down Expand Up @@ -189,7 +189,7 @@ impl<T: Transcript<DLEQ>, NG> Adaptor<T, NG> {
/// # Example
/// ```
/// # use ecdsa_fun::{ adaptor::{Adaptor, HashTranscript}, fun::Scalar };
/// # let adaptor = Adaptor::<HashTranscript::<sha2::Sha256>,()>::default();
/// # let adaptor = Adaptor::<HashTranscript::<sha2::Sha256>, _>::verify_only();
/// let secret_decryption_key = Scalar::random(&mut rand::thread_rng());
/// let public_encryption_key = adaptor.encryption_key_for(&secret_decryption_key);
pub fn encryption_key_for(&self, decryption_key: &Scalar) -> Point {
Expand Down
12 changes: 4 additions & 8 deletions ecdsa_fun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,9 @@ mod libsecp_compat;
#[cfg(feature = "serde")]
/// Rexport `serde`
pub use fun::serde;
use fun::Tag;

use fun::{
derive_nonce, g,
marker::*,
nonce::{AddTag, NonceGen},
s, Point, Scalar, G,
};
use fun::{derive_nonce, g, marker::*, nonce::NonceGen, s, Point, Scalar, G};
pub use secp256kfun as fun;
pub use secp256kfun::nonce;
mod signature;
Expand Down Expand Up @@ -71,10 +67,10 @@ impl<NG> ECDSA<NG> {
/// [`NonceGen`]: crate::nonce::NonceGen
pub fn new(nonce_gen: NG) -> Self
where
NG: AddTag,
NG: Tag,
{
ECDSA {
nonce_gen: nonce_gen.add_tag("secp256kfun/ecdsa_fun"),
nonce_gen: nonce_gen.tag(b"secp256kfun/ecdsa_fun"),
enforce_low_s: false,
}
}
Expand Down
6 changes: 5 additions & 1 deletion ecdsa_fun/tests/adaptor_test_vectors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ static DLC_SPEC_JSON: &'static str = include_str!("./test_vectors.json");
use ecdsa_fun::{
adaptor::{Adaptor, EncryptedSignature, HashTranscript},
fun::{Point, Scalar},
nonce::NoNonces,
serde, Signature,
};
use sha2::Sha256;
Expand Down Expand Up @@ -79,7 +80,10 @@ fn run_test_vectors() {
}
}

fn run_test_vector(ecdsa_adaptor: &Adaptor<HashTranscript<Sha256>, ()>, t: &Verification) -> bool {
fn run_test_vector(
ecdsa_adaptor: &Adaptor<HashTranscript<Sha256>, NoNonces>,
t: &Verification,
) -> bool {
if !ecdsa_adaptor.verify_encrypted_signature(
&t.public_signing_key,
&t.encryption_key,
Expand Down
8 changes: 5 additions & 3 deletions schnorr_fun/benches/bench_schnorr.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
//! This broken and just as a reference until we get proper bip340 benchmarks from proper rust lib
#![allow(non_upper_case_globals)]
use criterion::{criterion_group, criterion_main, Criterion};
use schnorr_fun::{Message, Schnorr};
use secp256kfun::{marker::*, nonce::Deterministic, Scalar};
use schnorr_fun::{
fun::{marker::*, nonce, Scalar},
Message, Schnorr,
};
use sha2::Sha256;

const MESSAGE: &'static [u8; 32] = b"hello world you are beautiful!!!";

lazy_static::lazy_static! {
static ref SK: Scalar<Secret, NonZero> = Scalar::from_bytes_mod_order(*b"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").non_zero().unwrap();
static ref schnorr: Schnorr<Sha256, Deterministic<Sha256>> = Schnorr::new(Deterministic::default());
static ref schnorr: Schnorr<Sha256, nonce::Deterministic<Sha256>> = Schnorr::default();
}

// note schnorr runs against grin's secp256k1 library
Expand Down
11 changes: 5 additions & 6 deletions schnorr_fun/src/adaptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ use crate::{
digest::{generic_array::typenum::U32, Digest},
g,
marker::*,
nonce::NonceGen,
s, Point, Scalar, XOnlyKeyPair, G,
nonce, s, Point, Scalar, XOnlyKeyPair, G,
},
Message, Schnorr, Signature,
};
Expand All @@ -81,7 +80,7 @@ pub trait EncryptedSign {
impl<NG, CH> EncryptedSign for Schnorr<CH, NG>
where
CH: Digest<OutputSize = U32> + Clone,
NG: NonceGen,
NG: nonce::NonceGen,
{
fn encrypted_sign(
&self,
Expand Down Expand Up @@ -275,7 +274,7 @@ where
mod test {

use super::*;
use crate::nonce::{Deterministic, GlobalRng, Synthetic};
use crate::nonce::{GlobalRng, Synthetic};
use rand::rngs::ThreadRng;
use secp256kfun::proptest::prelude::*;
use sha2::Sha256;
Expand All @@ -285,7 +284,7 @@ mod test {
proptest! {
#[test]
fn signing_tests_deterministic(secret_key in any::<Scalar>(), decryption_key in any::<Scalar>()) {
let schnorr = Schnorr::<Sha256, Deterministic<Sha256>>::default();
let schnorr = Schnorr::<Sha256, nonce::Deterministic<Sha256>>::default();
test_it(schnorr, secret_key, decryption_key);
}

Expand All @@ -297,7 +296,7 @@ mod test {

}

fn test_it<NG: NonceGen>(
fn test_it<NG: nonce::NonceGen>(
schnorr: Schnorr<Sha256, NG>,
secret_key: Scalar,
decryption_key: Scalar,
Expand Down
36 changes: 21 additions & 15 deletions schnorr_fun/src/frost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,15 @@
//! that should make sense in most applications:
//!
//! ```
//! use schnorr_fun::{frost, fun::{ Scalar, nonce::{self, AddTag}, derive_nonce_rng }};
//! use schnorr_fun::{frost, fun::{ Scalar, nonce, Tag, derive_nonce_rng }};
//! use sha2::Sha256;
//! use rand_chacha::ChaCha20Rng;
//!
//! let static_secret_key = /* from local storage */
//! # Scalar::random(&mut rand::thread_rng());
//! let mut poly_rng = derive_nonce_rng! {
//! // use Deterministic nonce gen so we reproduce it later
//! nonce_gen => nonce::Deterministic::<Sha256>::default().add_tag("my-app-name"),
//! nonce_gen => nonce::Deterministic::<Sha256>::default().tag(b"my-app-name/frost/keygen"),
//! secret => static_secret_key,
//! // session id must be unique for each key generation session
//! public => ["forst_key_session_1053"],
Expand All @@ -144,17 +144,16 @@
//! ```
//!
//! Note that if a key generation sesssion fails you must always start a fresh session with a different session id.
#![cfg(feature = "serde")]
pub use crate::binonce::{Nonce, NonceKeyPair};
use crate::{Message, Schnorr, Signature};
use alloc::{collections::BTreeMap, vec::Vec};
use secp256kfun::{
derive_nonce_rng,
digest::{generic_array::typenum::U32, Digest},
g,
hash::{HashAdd, Tagged},
hash::{HashAdd, Tag},
marker::*,
nonce::{self, AddTag, NonceGen},
nonce::{self, NonceGen},
rand_core::{RngCore, SeedableRng},
s, Point, Scalar, G,
};
Expand All @@ -175,15 +174,20 @@ pub struct Frost<H, NG> {
keygen_id_hash: H,
}

impl<H: Default + Tagged + Digest<OutputSize = U32>, NG: Default + AddTag> Default
for Frost<H, NG>
impl<H, NG> Default for Frost<H, NG>
where
H: Default + Tag + Digest<OutputSize = U32>,
NG: Default + Tag,
{
fn default() -> Self {
Frost::new(Schnorr::default())
}
}

impl<H: Tagged, NG> Frost<H, NG> {
impl<H, NG> Frost<H, NG>
where
H: Tag + Default,
{
/// Generate a new Frost context from a Schnorr context.
///
/// # Examples
Expand All @@ -197,8 +201,8 @@ impl<H: Tagged, NG> Frost<H, NG> {
pub fn new(schnorr: Schnorr<H, NG>) -> Self {
Self {
schnorr,
binding_hash: H::default().tagged(b"frost/binding"),
keygen_id_hash: H::default().tagged(b"frost/keygenid"),
binding_hash: H::default().tag(b"frost/binding"),
keygen_id_hash: H::default().tag(b"frost/keygenid"),
}
}
}
Expand Down Expand Up @@ -891,8 +895,10 @@ fn lagrange_lambda(x_j: u32, x_ms: &[u32]) -> Scalar {
/// use schnorr_fun::frost;
/// let frost = frost::new_with_deterministic_nonces::<sha2::Sha256>();
/// ```
pub fn new_with_deterministic_nonces<H: Tagged + Digest<OutputSize = U32>>(
) -> Frost<H, nonce::Deterministic<H>> {
pub fn new_with_deterministic_nonces<H>() -> Frost<H, nonce::Deterministic<H>>
where
H: Tag + Digest<OutputSize = U32> + Default,
{
Frost::default()
}

Expand All @@ -909,7 +915,7 @@ pub fn new_with_deterministic_nonces<H: Tagged + Digest<OutputSize = U32>>(
/// ```
pub fn new_with_synthetic_nonces<H, R>() -> Frost<H, nonce::Synthetic<H, nonce::GlobalRng<R>>>
where
H: Tagged + Digest<OutputSize = U32>,
H: Tag + Digest<OutputSize = U32> + Default,
R: RngCore + Default,
{
Frost::default()
Expand All @@ -918,9 +924,9 @@ where
/// Create a Frost instance which does not handle nonce generation.
///
/// You can still sign with this instance but you you will have to generate nonces in your own way.
pub fn new_without_nonce_generation<H>() -> Frost<H, ()>
pub fn new_without_nonce_generation<H>() -> Frost<H, nonce::NoNonces>
where
H: Tagged + Digest<OutputSize = U32>,
H: Tag + Digest<OutputSize = U32> + Default,
{
Frost::default()
}
Expand Down
4 changes: 1 addition & 3 deletions schnorr_fun/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ mod libsecp_compat;
#[doc(hidden)]
macro_rules! test_instance {
() => {
$crate::Schnorr::<sha2::Sha256, _>::new(
$crate::nonce::Deterministic::<sha2::Sha256>::default(),
)
$crate::Schnorr::<sha2::Sha256, secp256kfun::nonce::Deterministic<sha2::Sha256>>::default()
};
}

0 comments on commit 53aad8a

Please sign in to comment.