diff --git a/Cargo.lock b/Cargo.lock index a09e75d7..e2a4d6d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3546,11 +3546,11 @@ version = "0.2.0" dependencies = [ "ciphersuite 0.4.2", "flexible-transcript", - "group", "modular-frost", "rand_core 0.6.4", "schnorr-signatures", "schnorrkel", + "std-shims", "zeroize", ] @@ -6098,6 +6098,7 @@ dependencies = [ "schnorr-signatures", "serde_json", "sha2 0.10.9", + "std-shims", "subtle", "thiserror 2.0.16", "zeroize", @@ -10235,10 +10236,15 @@ dependencies = [ "ciphersuite 0.4.2", "dalek-ff-group 0.5.0", "dkg", + "dkg-dealer", "dkg-evrf", + "dkg-musig", + "dkg-recovery", "embedwards25519", "flexible-transcript", + "frost-schnorrkel", "minimal-ed448", + "modular-frost", "multiexp", "prime-field", "schnorr-signatures", diff --git a/crypto/frost/Cargo.toml b/crypto/frost/Cargo.toml index 790e4e3c..a7d56dd8 100644 --- a/crypto/frost/Cargo.toml +++ b/crypto/frost/Cargo.toml @@ -17,33 +17,35 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] -thiserror = { version = "2", default-features = false, features = ["std"] } +std-shims = { version = "0.1", path = "../../common/std-shims", default-features = false, features = ["alloc"] } -rand_core = { version = "0.6", default-features = false, features = ["std"] } -rand_chacha = { version = "0.3", default-features = false, features = ["std"] } +thiserror = { version = "2", default-features = false } -zeroize = { version = "^1.5", default-features = false, features = ["std", "zeroize_derive"] } -subtle = { version = "^2.4", default-features = false, features = ["std"] } +rand_core = { version = "0.6", default-features = false, features = ["alloc"] } +rand_chacha = { version = "0.3", default-features = false } -hex = { version = "0.4", default-features = false, features = ["std"], optional = true } +zeroize = { version = "^1.5", default-features = false, features = ["alloc", "zeroize_derive"] } +subtle = { version = "^2.4", default-features = false } -transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", default-features = false, features = ["std", "recommended"] } +hex = { version = "0.4", default-features = false, features = ["alloc"], optional = true } -dalek-ff-group = { path = "../dalek-ff-group", version = "0.5", default-features = false, features = ["std"], optional = true } -minimal-ed448 = { path = "../ed448", version = "0.4", default-features = false, features = ["std"], optional = true } +transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", default-features = false, features = ["recommended"] } -ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["std"] } +dalek-ff-group = { path = "../dalek-ff-group", version = "0.5", default-features = false, features = ["alloc"], optional = true } +minimal-ed448 = { path = "../ed448", version = "0.4", default-features = false, features = ["alloc"], optional = true } + +ciphersuite = { path = "../ciphersuite", version = "^0.4.1", default-features = false, features = ["alloc"] } sha2 = { version = "0.10.0", default-features = false, optional = true } elliptic-curve = { version = "0.13", default-features = false, features = ["hash2curve"], optional = true } -ciphersuite-kp256 = { path = "../ciphersuite/kp256", version = "0.4", default-features = false, features = ["std"], optional = true } +ciphersuite-kp256 = { path = "../ciphersuite/kp256", version = "0.4", default-features = false, features = ["alloc"], optional = true } -multiexp = { path = "../multiexp", version = "0.4", default-features = false, features = ["std", "batch"] } +multiexp = { path = "../multiexp", version = "0.4", default-features = false, features = ["alloc", "batch"] } -schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["std"] } +schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1", default-features = false, features = ["alloc"] } -dkg = { path = "../dkg", version = "0.6.1", default-features = false, features = ["std"] } -dkg-recovery = { path = "../dkg/recovery", version = "0.6", default-features = false, features = ["std"], optional = true } -dkg-dealer = { path = "../dkg/dealer", version = "0.6", default-features = false, features = ["std"], optional = true } +dkg = { path = "../dkg", version = "0.6.1", default-features = false } +dkg-recovery = { path = "../dkg/recovery", version = "0.6", default-features = false, optional = true } +dkg-dealer = { path = "../dkg/dealer", version = "0.6", default-features = false, optional = true } [dev-dependencies] hex = "0.4" @@ -54,6 +56,38 @@ dkg-recovery = { path = "../dkg/recovery", default-features = false, features = dkg-dealer = { path = "../dkg/dealer", default-features = false, features = ["std"] } [features] +std = [ + "std-shims/std", + + "thiserror/std", + + "rand_core/std", + "rand_chacha/std", + + "zeroize/std", + "subtle/std", + + "hex?/std", + + "transcript/std", + + "dalek-ff-group?/std", + "minimal-ed448?/std", + + "ciphersuite/std", + "sha2?/std", + "elliptic-curve?/std", + "ciphersuite-kp256?/std", + + "multiexp/std", + + "schnorr/std", + + "dkg/std", + "dkg-recovery?/std", + "dkg-dealer?/std", +] + ed25519 = ["dalek-ff-group"] ristretto = ["dalek-ff-group"] @@ -63,3 +97,5 @@ p256 = ["sha2", "elliptic-curve", "ciphersuite-kp256"] ed448 = ["minimal-ed448"] tests = ["hex", "rand_core/getrandom", "dkg-dealer", "dkg-recovery"] + +default = ["std"] diff --git a/crypto/frost/src/algorithm.rs b/crypto/frost/src/algorithm.rs index 7c0dc37e..26847c43 100644 --- a/crypto/frost/src/algorithm.rs +++ b/crypto/frost/src/algorithm.rs @@ -1,5 +1,7 @@ use core::{marker::PhantomData, fmt::Debug}; -use std::io::{self, Read, Write}; +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::io::{self, Read, Write}; use zeroize::Zeroizing; use rand_core::{RngCore, CryptoRng}; diff --git a/crypto/frost/src/curve/mod.rs b/crypto/frost/src/curve/mod.rs index 0796c5ef..3b5db584 100644 --- a/crypto/frost/src/curve/mod.rs +++ b/crypto/frost/src/curve/mod.rs @@ -1,5 +1,7 @@ use core::{ops::Deref, convert::AsRef}; -use std::io::{self, Read}; +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::io::{self, Read}; use rand_core::{RngCore, CryptoRng}; diff --git a/crypto/frost/src/lib.rs b/crypto/frost/src/lib.rs index 6baf8872..24cdfd7f 100644 --- a/crypto/frost/src/lib.rs +++ b/crypto/frost/src/lib.rs @@ -1,8 +1,11 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc = include_str!("../README.md")] +#![cfg_attr(not(feature = "std"), no_std)] use core::fmt::Debug; -use std::collections::HashMap; +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::collections::HashMap; use thiserror::Error; diff --git a/crypto/frost/src/nonce.rs b/crypto/frost/src/nonce.rs index f76f9bc4..6351a36e 100644 --- a/crypto/frost/src/nonce.rs +++ b/crypto/frost/src/nonce.rs @@ -6,7 +6,9 @@ // Each nonce remains of the form (d, e) and made into a proper nonce with d + (e * b) use core::ops::Deref; -use std::{ +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::{ io::{self, Read, Write}, collections::HashMap, }; diff --git a/crypto/frost/src/sign.rs b/crypto/frost/src/sign.rs index 833c251c..25151d5a 100644 --- a/crypto/frost/src/sign.rs +++ b/crypto/frost/src/sign.rs @@ -1,5 +1,7 @@ use core::{ops::Deref, fmt::Debug}; -use std::{ +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::{ io::{self, Read, Write}, collections::HashMap, }; diff --git a/crypto/frost/src/tests/mod.rs b/crypto/frost/src/tests/mod.rs index f4f6330b..423aa483 100644 --- a/crypto/frost/src/tests/mod.rs +++ b/crypto/frost/src/tests/mod.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std_shims::collections::HashMap; use rand_core::{RngCore, CryptoRng}; diff --git a/crypto/frost/src/tests/nonces.rs b/crypto/frost/src/tests/nonces.rs index a28c7dea..2e6d275b 100644 --- a/crypto/frost/src/tests/nonces.rs +++ b/crypto/frost/src/tests/nonces.rs @@ -1,4 +1,4 @@ -use std::io::{self, Read}; +use std_shims::io::{self, Read}; use zeroize::Zeroizing; diff --git a/crypto/frost/src/tests/vectors.rs b/crypto/frost/src/tests/vectors.rs index d5cda345..c127d58a 100644 --- a/crypto/frost/src/tests/vectors.rs +++ b/crypto/frost/src/tests/vectors.rs @@ -1,8 +1,8 @@ use core::ops::Deref; -use std::collections::HashMap; +use std_shims::collections::HashMap; #[cfg(test)] -use std::str::FromStr; +use core::str::FromStr; use zeroize::Zeroizing; diff --git a/crypto/schnorrkel/Cargo.toml b/crypto/schnorrkel/Cargo.toml index 030c4c28..1fe90be3 100644 --- a/crypto/schnorrkel/Cargo.toml +++ b/crypto/schnorrkel/Cargo.toml @@ -17,18 +17,35 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] -rand_core = "0.6" -zeroize = "^1.5" +std-shims = { version = "0.1", default-features = false, features = ["alloc"] } -transcript = { package = "flexible-transcript", path = "../transcript", version = "^0.3.2", features = ["merlin"] } +rand_core = { version = "0.6", default-features = false } +zeroize = { version = "1.5", default-features = false, features = ["zeroize_derive", "alloc"] } -group = "0.13" +transcript = { package = "flexible-transcript", path = "../transcript", version = "0.3.2", default-features = false, features = ["merlin"] } -ciphersuite = { path = "../ciphersuite", version = "^0.4.1", features = ["std"] } -schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "^0.5.1" } -frost = { path = "../frost", package = "modular-frost", version = "0.11.0", features = ["ristretto"] } +ciphersuite = { path = "../ciphersuite", version = "0.4.1", default-features = false, features = ["alloc"] } +schnorr = { package = "schnorr-signatures", path = "../schnorr", version = "0.5.1", default-features = false, features = ["alloc"] } +frost = { path = "../frost", package = "modular-frost", version = "0.11.0", default-features = false, features = ["ristretto"] } -schnorrkel = { version = "0.11" } +schnorrkel = { version = "0.11", default-features = false, features = ["alloc"] } [dev-dependencies] frost = { path = "../frost", package = "modular-frost", features = ["tests"] } + +[features] +std = [ + "std-shims/std", + + "rand_core/std", + "zeroize/std", + + "transcript/std", + + "ciphersuite/std", + "schnorr/std", + "frost/std", + + "schnorrkel/std", +] +default = ["std"] diff --git a/crypto/schnorrkel/src/lib.rs b/crypto/schnorrkel/src/lib.rs index 4eb3c853..41f42db2 100644 --- a/crypto/schnorrkel/src/lib.rs +++ b/crypto/schnorrkel/src/lib.rs @@ -1,7 +1,10 @@ #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc = include_str!("../README.md")] +#![cfg_attr(not(feature = "std"), no_std)] -use std::io::{self, Read}; +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::io::{self, Read}; use rand_core::{RngCore, CryptoRng}; diff --git a/crypto/schnorrkel/src/tests.rs b/crypto/schnorrkel/src/tests.rs index 2f3c758b..b0ae9138 100644 --- a/crypto/schnorrkel/src/tests.rs +++ b/crypto/schnorrkel/src/tests.rs @@ -1,6 +1,6 @@ use rand_core::OsRng; -use group::GroupEncoding; +use ciphersuite::group::GroupEncoding; use frost::{ Participant, tests::{key_gen, algorithm_machines, sign}, diff --git a/networks/bitcoin/Cargo.toml b/networks/bitcoin/Cargo.toml index 4d220f1d..40823f9d 100644 --- a/networks/bitcoin/Cargo.toml +++ b/networks/bitcoin/Cargo.toml @@ -27,7 +27,7 @@ rand_core = { version = "0.6", default-features = false } bitcoin = { version = "0.32", default-features = false } k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic", "bits"] } -frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"], optional = true } +frost = { package = "modular-frost", path = "../../crypto/frost", version = "0.11", default-features = false, features = ["secp256k1"] } hex = { version = "0.4", default-features = false, optional = true } serde = { version = "1", default-features = false, features = ["derive"], optional = true } @@ -55,7 +55,7 @@ std = [ "bitcoin/serde", "k256/std", - "frost", + "frost/std", "hex/std", "serde/std", diff --git a/networks/bitcoin/src/crypto.rs b/networks/bitcoin/src/crypto.rs index 51e0f852..c083625e 100644 --- a/networks/bitcoin/src/crypto.rs +++ b/networks/bitcoin/src/crypto.rs @@ -1,9 +1,27 @@ -#[cfg(feature = "std")] +use core::fmt::Debug; +#[allow(unused_imports)] +use std_shims::prelude::*; +use std_shims::io; + use subtle::{Choice, ConstantTimeEq, ConditionallySelectable}; +use zeroize::Zeroizing; +use rand_core::{RngCore, CryptoRng}; -use k256::{elliptic_curve::sec1::ToEncodedPoint, ProjectivePoint}; +use k256::{ + elliptic_curve::{ops::Reduce, sec1::ToEncodedPoint}, + U256, Scalar, ProjectivePoint, +}; -use bitcoin::key::XOnlyPublicKey; +use bitcoin::{ + hashes::{HashEngine, Hash, sha256::Hash as Sha256}, + key::XOnlyPublicKey, +}; + +use frost::{ + curve::{WrappedGroup, Secp256k1}, + Participant, ThresholdKeys, ThresholdView, FrostError, + algorithm::{Hram as HramTrait, Algorithm, IetfSchnorr as FrostSchnorr}, +}; /// Get the x coordinate of a non-infinity point. /// @@ -21,142 +39,118 @@ pub(crate) fn x_only(key: &ProjectivePoint) -> XOnlyPublicKey { } /// Return if a point must be negated to have an even Y coordinate and be eligible for use. -#[cfg(feature = "std")] pub(crate) fn needs_negation(key: &ProjectivePoint) -> Choice { use k256::elliptic_curve::sec1::Tag; u8::from(key.to_encoded_point(true).tag()).ct_eq(&u8::from(Tag::CompressedOddY)) } -#[cfg(feature = "std")] -mod frost_crypto { - use core::fmt::Debug; - use std_shims::{vec::Vec, io}; +/// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm. +/// +/// If passed an odd nonce, the challenge will be negated. +/// +/// If either `R` or `A` is the point at infinity, this will panic. +#[derive(Clone, Copy, Debug)] +pub struct Hram; +#[allow(non_snake_case)] +impl HramTrait for Hram { + fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar { + const TAG_HASH: Sha256 = Sha256::const_hash(b"BIP0340/challenge"); - use zeroize::Zeroizing; - use rand_core::{RngCore, CryptoRng}; + let mut data = Sha256::engine(); + data.input(TAG_HASH.as_ref()); + data.input(TAG_HASH.as_ref()); + data.input(&x(R)); + data.input(&x(A)); + data.input(m); - use bitcoin::hashes::{HashEngine, Hash, sha256::Hash as Sha256}; - - use k256::{elliptic_curve::ops::Reduce, U256, Scalar}; - - use frost::{ - curve::{WrappedGroup, Secp256k1}, - Participant, ThresholdKeys, ThresholdView, FrostError, - algorithm::{Hram as HramTrait, Algorithm, IetfSchnorr as FrostSchnorr}, - }; - - use super::*; - - /// A BIP-340 compatible HRAm for use with the modular-frost Schnorr Algorithm. - /// - /// If passed an odd nonce, the challenge will be negated. - /// - /// If either `R` or `A` is the point at infinity, this will panic. - #[derive(Clone, Copy, Debug)] - pub struct Hram; - #[allow(non_snake_case)] - impl HramTrait for Hram { - fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar { - const TAG_HASH: Sha256 = Sha256::const_hash(b"BIP0340/challenge"); - - let mut data = Sha256::engine(); - data.input(TAG_HASH.as_ref()); - data.input(TAG_HASH.as_ref()); - data.input(&x(R)); - data.input(&x(A)); - data.input(m); - - let c = Scalar::reduce(U256::from_be_slice(Sha256::from_engine(data).as_ref())); - // If the nonce was odd, sign `r - cx` instead of `r + cx`, allowing us to negate `s` at the - // end to sign as `-r + cx` - <_>::conditional_select(&c, &-c, needs_negation(R)) - } - } - - /// BIP-340 Schnorr signature algorithm. - /// - /// This may panic if called with nonces/a group key which are the point at infinity (which have - /// a negligible probability for a well-reasoned caller, even with malicious participants - /// present). - /// - /// `verify`, `verify_share` MUST be called after `sign_share` is called. Otherwise, this library - /// MAY panic. - #[derive(Clone)] - pub struct Schnorr(FrostSchnorr); - impl Schnorr { - /// Construct a Schnorr algorithm continuing the specified transcript. - #[allow(clippy::new_without_default)] - pub fn new() -> Schnorr { - Schnorr(FrostSchnorr::ietf()) - } - } - - impl Algorithm for Schnorr { - type Transcript = as Algorithm>::Transcript; - type Addendum = (); - type Signature = [u8; 64]; - - fn transcript(&mut self) -> &mut Self::Transcript { - self.0.transcript() - } - - fn nonces(&self) -> Vec> { - self.0.nonces() - } - - fn preprocess_addendum( - &mut self, - rng: &mut R, - keys: &ThresholdKeys, - ) { - self.0.preprocess_addendum(rng, keys) - } - - fn read_addendum(&self, reader: &mut R) -> io::Result { - self.0.read_addendum(reader) - } - - fn process_addendum( - &mut self, - view: &ThresholdView, - i: Participant, - addendum: (), - ) -> Result<(), FrostError> { - self.0.process_addendum(view, i, addendum) - } - - fn sign_share( - &mut self, - params: &ThresholdView, - nonce_sums: &[Vec<::G>], - nonces: Vec::F>>, - msg: &[u8], - ) -> ::F { - self.0.sign_share(params, nonce_sums, nonces, msg) - } - - fn verify( - &self, - group_key: ProjectivePoint, - nonces: &[Vec], - sum: Scalar, - ) -> Option { - self.0.verify(group_key, nonces, sum).map(|mut sig| { - sig.s = <_>::conditional_select(&sum, &-sum, needs_negation(&sig.R)); - // Convert to a Bitcoin signature by dropping the byte for the point's sign bit - sig.serialize()[1 ..].try_into().unwrap() - }) - } - - fn verify_share( - &self, - verification_share: ProjectivePoint, - nonces: &[Vec], - share: Scalar, - ) -> Result, ()> { - self.0.verify_share(verification_share, nonces, share) - } + let c = Scalar::reduce(U256::from_be_slice(Sha256::from_engine(data).as_ref())); + // If the nonce was odd, sign `r - cx` instead of `r + cx`, allowing us to negate `s` at the + // end to sign as `-r + cx` + <_>::conditional_select(&c, &-c, needs_negation(R)) + } +} + +/// BIP-340 Schnorr signature algorithm. +/// +/// This may panic if called with nonces/a group key which are the point at infinity (which have +/// a negligible probability for a well-reasoned caller, even with malicious participants +/// present). +/// +/// `verify`, `verify_share` MUST be called after `sign_share` is called. Otherwise, this library +/// MAY panic. +#[derive(Clone)] +pub struct Schnorr(FrostSchnorr); +impl Schnorr { + /// Construct a Schnorr algorithm continuing the specified transcript. + #[allow(clippy::new_without_default)] + pub fn new() -> Schnorr { + Schnorr(FrostSchnorr::ietf()) + } +} + +impl Algorithm for Schnorr { + type Transcript = as Algorithm>::Transcript; + type Addendum = (); + type Signature = [u8; 64]; + + fn transcript(&mut self) -> &mut Self::Transcript { + self.0.transcript() + } + + fn nonces(&self) -> Vec> { + self.0.nonces() + } + + fn preprocess_addendum( + &mut self, + rng: &mut R, + keys: &ThresholdKeys, + ) { + self.0.preprocess_addendum(rng, keys) + } + + fn read_addendum(&self, reader: &mut R) -> io::Result { + self.0.read_addendum(reader) + } + + fn process_addendum( + &mut self, + view: &ThresholdView, + i: Participant, + addendum: (), + ) -> Result<(), FrostError> { + self.0.process_addendum(view, i, addendum) + } + + fn sign_share( + &mut self, + params: &ThresholdView, + nonce_sums: &[Vec<::G>], + nonces: Vec::F>>, + msg: &[u8], + ) -> ::F { + self.0.sign_share(params, nonce_sums, nonces, msg) + } + + fn verify( + &self, + group_key: ProjectivePoint, + nonces: &[Vec], + sum: Scalar, + ) -> Option { + self.0.verify(group_key, nonces, sum).map(|mut sig| { + sig.s = <_>::conditional_select(&sum, &-sum, needs_negation(&sig.R)); + // Convert to a Bitcoin signature by dropping the byte for the point's sign bit + sig.serialize()[1 ..].try_into().unwrap() + }) + } + + fn verify_share( + &self, + verification_share: ProjectivePoint, + nonces: &[Vec], + share: Scalar, + ) -> Result, ()> { + self.0.verify_share(verification_share, nonces, share) } } -#[cfg(feature = "std")] -pub use frost_crypto::*; diff --git a/networks/bitcoin/src/lib.rs b/networks/bitcoin/src/lib.rs index 0aa17709..05d60139 100644 --- a/networks/bitcoin/src/lib.rs +++ b/networks/bitcoin/src/lib.rs @@ -2,9 +2,6 @@ #![doc = include_str!("../README.md")] #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(not(feature = "std"))] -extern crate alloc; - /// The bitcoin Rust library. pub use bitcoin; diff --git a/networks/bitcoin/src/wallet/mod.rs b/networks/bitcoin/src/wallet/mod.rs index 97319f5f..a14d33f1 100644 --- a/networks/bitcoin/src/wallet/mod.rs +++ b/networks/bitcoin/src/wallet/mod.rs @@ -1,36 +1,31 @@ +#[allow(unused_imports)] +use std_shims::prelude::*; use std_shims::{ - vec::Vec, collections::HashMap, - io::{self, Write}, + io::{self, Read, Write}, }; -#[cfg(feature = "std")] -use std::io::{Read, BufReader}; use k256::{ elliptic_curve::sec1::{Tag, ToEncodedPoint}, Scalar, ProjectivePoint, }; -#[cfg(feature = "std")] use frost::{ curve::{WrappedGroup, GroupIo, Secp256k1}, ThresholdKeys, }; use bitcoin::{ - consensus::encode::serialize, key::TweakedPublicKey, OutPoint, ScriptBuf, TxOut, Transaction, - Block, + hashes::Hash, + key::TweakedPublicKey, + TapTweakHash, + consensus::encode::{Decodable, serialize}, + OutPoint, ScriptBuf, TxOut, Transaction, Block, }; -#[cfg(feature = "std")] -use bitcoin::{hashes::Hash, consensus::encode::Decodable, TapTweakHash}; -use crate::crypto::x_only; -#[cfg(feature = "std")] -use crate::crypto::needs_negation; +use crate::crypto::{x_only, needs_negation}; -#[cfg(feature = "std")] mod send; -#[cfg(feature = "std")] pub use send::*; /// Tweak keys to ensure they're usable with Bitcoin's Taproot upgrade. @@ -42,7 +37,6 @@ pub use send::*; /// After adding an unspendable script path, the key is negated if odd. /// /// This has a neligible probability of returning keys whose group key is the point at infinity. -#[cfg(feature = "std")] pub fn tweak_keys(keys: ThresholdKeys) -> ThresholdKeys { // Adds the unspendable script path per // https://github.com/bitcoin/bips/blob/master/bip-0341.mediawiki#cite_note-23 @@ -118,18 +112,23 @@ impl ReceivedOutput { } /// Read a ReceivedOutput from a generic satisfying Read. - #[cfg(feature = "std")] pub fn read(r: &mut R) -> io::Result { let offset = Secp256k1::read_F(r)?; - let output; - let outpoint; - { - let mut buf_r = BufReader::with_capacity(0, r); - output = - TxOut::consensus_decode(&mut buf_r).map_err(|_| io::Error::other("invalid TxOut"))?; - outpoint = - OutPoint::consensus_decode(&mut buf_r).map_err(|_| io::Error::other("invalid OutPoint"))?; + + struct BitcoinRead(R); + impl bitcoin::io::Read for BitcoinRead { + fn read(&mut self, buf: &mut [u8]) -> bitcoin::io::Result { + self + .0 + .read(buf) + .map_err(|e| bitcoin::io::Error::new(bitcoin::io::ErrorKind::Other, e.to_string())) + } } + let mut r = BitcoinRead(r); + + let output = TxOut::consensus_decode(&mut r).map_err(|_| io::Error::other("invalid TxOut"))?; + let outpoint = + OutPoint::consensus_decode(&mut r).map_err(|_| io::Error::other("invalid OutPoint"))?; Ok(ReceivedOutput { offset, output, outpoint }) } diff --git a/networks/bitcoin/src/wallet/send.rs b/networks/bitcoin/src/wallet/send.rs index 52824280..ec959934 100644 --- a/networks/bitcoin/src/wallet/send.rs +++ b/networks/bitcoin/src/wallet/send.rs @@ -1,3 +1,5 @@ +#[allow(unused_imports)] +use std_shims::prelude::*; use std_shims::{ io::{self, Read}, collections::HashMap, diff --git a/tests/no-std/Cargo.toml b/tests/no-std/Cargo.toml index 0b75f8ab..2552d7aa 100644 --- a/tests/no-std/Cargo.toml +++ b/tests/no-std/Cargo.toml @@ -36,9 +36,13 @@ secq256k1 = { path = "../../crypto/secq256k1", default-features = false } embedwards25519 = { path = "../../crypto/embedwards25519", default-features = false } dkg = { path = "../../crypto/dkg", default-features = false, optional = true } +dkg-dealer = { path = "../../crypto/dkg/dealer", default-features = false, optional = true } +dkg-recovery = { path = "../../crypto/dkg/recovery", default-features = false, optional = true } +dkg-musig = { path = "../../crypto/dkg/musig", default-features = false, optional = true } dkg-evrf = { path = "../../crypto/dkg/evrf", default-features = false, features = ["secp256k1", "ed25519"], optional = true } -# modular-frost = { path = "../../crypto/frost", default-features = false } -# frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false } + +modular-frost = { path = "../../crypto/frost", default-features = false, optional = true } +frost-schnorrkel = { path = "../../crypto/schnorrkel", default-features = false, optional = true } bitcoin-serai = { path = "../../networks/bitcoin", default-features = false, features = ["hazmat"], optional = true } @@ -62,7 +66,13 @@ alloc = [ "embedwards25519/alloc", "dkg", + "dkg-dealer", + "dkg-recovery", + "dkg-musig", "dkg-evrf", + "modular-frost", + "frost-schnorrkel", + "bitcoin-serai", ] diff --git a/tests/no-std/src/lib.rs b/tests/no-std/src/lib.rs index 57f41a0e..320a3c87 100644 --- a/tests/no-std/src/lib.rs +++ b/tests/no-std/src/lib.rs @@ -21,12 +21,13 @@ pub mod alloc { pub use multiexp; pub use dkg; + pub use dkg_dealer; + pub use dkg_recovery; + pub use dkg_musig; pub use dkg_evrf; - pub use bitcoin_serai; - - /* pub use modular_frost; pub use frost_schnorrkel; - */ + + pub use bitcoin_serai; }