Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HD derivation: add ed25519 support #9

Merged
merged 12 commits into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
env:
CARGO_TERM_COLOR: always
CARGO_NET_GIT_FETCH_WITH_CLI: true
RUSTFLAGS: -D warnings

jobs:
build-bare:
Expand Down
43 changes: 28 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions givre/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
cggmp21-keygen = { version = "0.3", default-features = false, optional = true }
key-share = { version = "0.4.1", default-features = false }
cggmp21-keygen = { version = "0.4", default-features = false, optional = true }
key-share = { version = "0.5", default-features = false }

generic-ec = { version = "0.4", default-features = false, features = ["alloc"] }

Expand All @@ -22,7 +22,7 @@ sha2 = { version = "0.10", default-features = false, optional = true }

serde = { version = "1", default-features = false, features = ["derive"], optional = true }

slip-10 = { version = "0.4", default-features = false, optional = true }
hd-wallet = { version = "0.5", default-features = false, optional = true }

[dev-dependencies]
rand_core = { version = "0.6", default-features = false, features = ["getrandom"] }
Expand All @@ -36,7 +36,7 @@ std = [
"cggmp21-keygen?/std",
"round-based?/std",
"serde?/std",
"slip-10?/std"
"hd-wallet?/std"
]

cggmp21-keygen = ["dep:cggmp21-keygen"]
Expand All @@ -46,11 +46,11 @@ serde = ["dep:serde", "key-share/serde"]

spof = ["key-share/spof"]

hd-wallets = ["slip-10", "key-share/hd-wallets", "cggmp21-keygen?/hd-wallets"]
hd-wallet = ["dep:hd-wallet", "key-share/hd-wallet", "cggmp21-keygen?/hd-wallet"]
taproot = ["sha2"]

all-ciphersuites = ["ciphersuite-secp256k1", "ciphersuite-ed25519", "ciphersuite-bitcoin"]
ciphersuite-secp256k1 = ["generic-ec/curve-secp256k1", "k256", "sha2", "static_assertions"]
ciphersuite-ed25519 = ["generic-ec/curve-ed25519", "sha2"]
ciphersuite-bitcoin = ["ciphersuite-secp256k1", "taproot"]
ciphersuite-secp256k1 = ["generic-ec/curve-secp256k1", "hd-wallet?/curve-secp256k1", "k256", "sha2", "static_assertions"]
ciphersuite-ed25519 = ["generic-ec/curve-ed25519", "hd-wallet?/curve-ed25519", "sha2"]
ciphersuite-bitcoin = ["ciphersuite-secp256k1", "hd-wallet?/curve-secp256k1", "taproot"]

4 changes: 4 additions & 0 deletions givre/src/ciphersuite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ pub trait Ciphersuite: Sized + Clone + Copy + core::fmt::Debug {
/// Indicates that the ciphersuite outputs taproot-compatible signatures
const IS_TAPROOT: bool = false;

/// HD derivation algorithm recommended to be used with this ciphersuite
#[cfg(feature = "hd-wallet")]
type HdAlgo: hd_wallet::HdWallet<Self::Curve>;

/// `H1` hash function as defined in the draft
///
/// Accepts a list of bytestring, that'll be concatenated before hashing.
Expand Down
3 changes: 3 additions & 0 deletions givre/src/ciphersuite/bitcoin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ impl Ciphersuite for Bitcoin {

const IS_TAPROOT: bool = true;

#[cfg(feature = "hd-wallet")]
type HdAlgo = hd_wallet::Slip10;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
Secp256k1::h1(msg)
}
Expand Down
3 changes: 3 additions & 0 deletions givre/src/ciphersuite/ed25519.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ impl Ciphersuite for Ed25519 {
type Digest = sha2::Sha512;
type MultiscalarMul = generic_ec::multiscalar::Dalek;

#[cfg(feature = "hd-wallet")]
type HdAlgo = hd_wallet::Edwards;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
let mut hash = sha2::Sha512::new()
.chain_update(Self::NAME)
Expand Down
3 changes: 3 additions & 0 deletions givre/src/ciphersuite/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ impl Ciphersuite for Secp256k1 {
type Digest = sha2::Sha256;
type MultiscalarMul = generic_ec::multiscalar::Default;

#[cfg(feature = "hd-wallet")]
type HdAlgo = hd_wallet::Slip10;

fn h1(msg: &[&[u8]]) -> generic_ec::Scalar<Self::Curve> {
hash_to_scalar(msg, &[Self::NAME.as_bytes(), b"rho"])
}
Expand Down
5 changes: 5 additions & 0 deletions givre/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,8 @@ extern crate std;
extern crate alloc;

pub use generic_ec;
#[cfg(feature = "hd-wallet")]
pub use hd_wallet;
#[cfg(feature = "full-signing")]
pub use round_based;

Expand Down Expand Up @@ -202,6 +204,9 @@ pub mod key_share {
}

mod error {
// It's currently only needed in full signing, but better keep it always in the code
#![cfg_attr(not(feature = "full-signing"), allow(dead_code, unused_imports))]

#[cfg(feature = "std")]
pub use std::error::Error as StdError;

Expand Down
40 changes: 34 additions & 6 deletions givre/src/signing/aggregate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use super::{round1::PublicCommitments, round2::SigShare, utils};
serde(bound = "")
)]
/// Schnorr Signature
pub struct Signature<C: Ciphersuite + ?Sized> {
pub struct Signature<C: Ciphersuite> {
/// $R$ component of the signature
pub r: crate::ciphersuite::NormalizedPoint<C, Point<C::Curve>>,
/// $z$ component of the signature
Expand Down Expand Up @@ -129,25 +129,52 @@ impl<'a, C: Ciphersuite> AggregateOptions<'a, C> {

/// Specifies HD derivation path
///
/// Uses default HD derivation algorithm defined for the ciphersuite in [`Ciphersuite::HdAlgo`].
/// If you need to use another algorithm, use [`AggregateOptions::set_derivation_path_with_algo`].
///
/// If called twice, the second call overwrites the first.
///
/// Returns error if the key doesn't support HD derivation, or if the path is invalid
#[cfg(feature = "hd-wallets")]
#[cfg(feature = "hd-wallet")]
pub fn set_derivation_path<Index>(
self,
path: impl IntoIterator<Item = Index>,
) -> Result<Self, crate::key_share::HdError<<slip_10::NonHardenedIndex as TryFrom<Index>>::Error>>
) -> Result<
Self,
crate::key_share::HdError<<hd_wallet::NonHardenedIndex as TryFrom<Index>>::Error>,
>
where
hd_wallet::NonHardenedIndex: TryFrom<Index>,
{
self.set_derivation_path_with_algo::<C::HdAlgo, _>(path)
}

/// Specifies HD derivation path
///
/// Uses HD derivation algorithm defined by [`hd_wallet::HdWallet`] trait.
///
/// If called twice, the second call overwrites the first.
///
/// Returns error if the key doesn't support HD derivation, or if the path is invalid
#[cfg(feature = "hd-wallet")]
pub fn set_derivation_path_with_algo<HdAlgo: hd_wallet::HdWallet<C::Curve>, Index>(
self,
path: impl IntoIterator<Item = Index>,
) -> Result<
Self,
crate::key_share::HdError<<hd_wallet::NonHardenedIndex as TryFrom<Index>>::Error>,
>
where
slip_10::NonHardenedIndex: TryFrom<Index>,
hd_wallet::NonHardenedIndex: TryFrom<Index>,
{
use crate::key_share::HdError;

let public_key = self
.key_info
.extended_public_key()
.ok_or(HdError::DisabledHd)?;
let additive_shift =
utils::derive_additive_shift(public_key, path).map_err(HdError::InvalidPath)?;
let additive_shift = utils::derive_additive_shift::<C::Curve, HdAlgo, _>(public_key, path)
.map_err(HdError::InvalidPath)?;

Ok(self.dangerous_set_hd_additive_shift(additive_shift))
}
Expand All @@ -156,6 +183,7 @@ impl<'a, C: Ciphersuite> AggregateOptions<'a, C> {
///
/// CAUTION: additive shift MUST BE derived from the extended public key obtained from
/// the key share which is used for signing by calling [`utils::derive_additive_shift`].
#[cfg(feature = "hd-wallet")]
pub(crate) fn dangerous_set_hd_additive_shift(
mut self,
hd_additive_shift: Scalar<C::Curve>,
Expand Down
Loading
Loading