Bitcoin tweaks + cargo update

Removes bitcoin-serai's usage of sha2 for bitcoin-hashes. While sha2 is still
in play due to modular-frost (more specifically, due to ciphersuite), this
offers a bit more performance (assuming equivalency between sha2 and
bitcoin-hashes' impl) due to removing a static for a const.

Makes secp256k1 a dev dependency for bitcoin-serai. While secp256k1 is still
pulled in via bitcoin, it's hopefully slightly better to compile now and makes
usage of secp256k1 an implementation detail of bitcoin (letting it change it
freely).

Also offers slightly more efficient signing as we don't decode to a signature
just to re-encode for the transaction.

Removes a 20s sleep for a check every second, up to 20 times, for reduced test
times in the processor.
This commit is contained in:
Luke Parker
2023-11-06 07:19:55 -05:00
parent bd3272a9f2
commit cddb44ae3f
6 changed files with 182 additions and 169 deletions

View File

@@ -15,9 +15,6 @@ thiserror = { version = "1", default-features = false, optional = true }
zeroize = { version = "^1.5", default-features = false }
rand_core = { version = "0.6", default-features = false }
sha2 = { version = "0.10", default-features = false }
secp256k1 = { version = "0.28", default-features = false }
bitcoin = { version = "0.31", default-features = false, features = ["no-std"] }
k256 = { version = "^0.13.1", default-features = false, features = ["arithmetic", "bits"] }
@@ -31,6 +28,8 @@ serde_json = { version = "1", default-features = false, optional = true }
reqwest = { version = "0.11", default-features = false, features = ["default-tls", "json"], optional = true }
[dev-dependencies]
secp256k1 = { version = "0.28", default-features = false, features = ["std"] }
frost = { package = "modular-frost", path = "../../crypto/frost", features = ["tests"] }
tokio = { version = "1", features = ["macros"] }
@@ -44,9 +43,6 @@ std = [
"zeroize/std",
"rand_core/std",
"sha2/std",
"secp256k1/std",
"bitcoin/std",
"bitcoin/serde",

View File

@@ -33,15 +33,15 @@ pub fn make_even(mut key: ProjectivePoint) -> (ProjectivePoint, u64) {
#[cfg(feature = "std")]
mod frost_crypto {
use core::fmt::Debug;
use std_shims::{sync::OnceLock, vec::Vec, io};
use std_shims::{vec::Vec, io};
use zeroize::Zeroizing;
use rand_core::{RngCore, CryptoRng};
use sha2::{Digest, Sha256};
use bitcoin::hashes::{HashEngine, Hash, sha256::Hash as Sha256};
use transcript::Transcript;
use secp256k1::schnorr::Signature;
use k256::{elliptic_curve::ops::Reduce, U256, Scalar};
use frost::{
@@ -59,27 +59,22 @@ mod frost_crypto {
/// If the key is odd, this will panic.
#[derive(Clone, Copy, Debug)]
pub struct Hram;
static TAG_HASH_CELL: OnceLock<[u8; 32]> = OnceLock::new();
#[allow(non_snake_case)]
fn TAG_HASH() -> [u8; 32] {
*TAG_HASH_CELL.get_or_init(|| Sha256::digest(b"BIP0340/challenge").into())
}
#[allow(non_snake_case)]
impl HramTrait<Secp256k1> for Hram {
fn hram(R: &ProjectivePoint, A: &ProjectivePoint, m: &[u8]) -> Scalar {
// Convert the nonce to be even
let (R, _) = make_even(*R);
let mut data = Sha256::new();
data.update(TAG_HASH());
data.update(TAG_HASH());
data.update(x(&R));
data.update(x(A));
data.update(m);
const TAG_HASH: Sha256 = Sha256::const_hash(b"BIP0340/challenge");
Scalar::reduce(U256::from_be_slice(&data.finalize()))
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);
Scalar::reduce(U256::from_be_slice(Sha256::from_engine(data).as_ref()))
}
}
@@ -98,7 +93,7 @@ mod frost_crypto {
impl<T: Sync + Clone + Debug + Transcript> Algorithm<Secp256k1> for Schnorr<T> {
type Transcript = T;
type Addendum = ();
type Signature = Signature;
type Signature = [u8; 64];
fn transcript(&mut self) -> &mut Self::Transcript {
self.0.transcript()
@@ -152,9 +147,8 @@ mod frost_crypto {
(sig.R, offset) = make_even(sig.R);
// s = r + cx. Since we added to the r, add to s
sig.s += Scalar::from(offset);
// Convert to a secp256k1 signature
Signature::from_slice(&sig.serialize()[1 ..])
.expect("couldn't convert SchnorrSignature to Signature")
// Convert to a Bitcoin signature by dropping the byte for the point's sign bit
sig.serialize()[1 ..].try_into().unwrap()
})
}

View File

@@ -1,8 +1,6 @@
use rand_core::OsRng;
use sha2::{Digest, Sha256};
use secp256k1::{Secp256k1 as BContext, Message};
use secp256k1::{Secp256k1 as BContext, Message, schnorr::Signature};
use k256::Scalar;
use transcript::{Transcript, RecommendedTranscript};
@@ -34,12 +32,13 @@ fn test_algorithm() {
algo.clone(),
keys.clone(),
algorithm_machines(&mut OsRng, algo, &keys),
&Sha256::digest(MESSAGE),
Hash::hash(MESSAGE).as_ref(),
);
BContext::new()
.verify_schnorr(
&sig,
&Signature::from_slice(&sig)
.expect("couldn't convert produced signature to secp256k1::Signature"),
&Message::from(Hash::hash(MESSAGE)),
&x_only(&keys[&Participant::new(1).unwrap()].group_key()),
)

View File

@@ -429,7 +429,7 @@ impl SignatureMachine<Transaction> for TransactionSignatureMachine {
)?;
let mut witness = Witness::new();
witness.push(sig.as_ref());
witness.push(sig);
input.witness = witness;
}