Resolve merging crypto-{audit, tweaks} and use the proper transcript in Bitcoin

This commit is contained in:
Luke Parker
2023-03-16 16:59:20 -04:00
parent 64924835ad
commit d2c1592c61
8 changed files with 75 additions and 36 deletions

View File

@@ -18,7 +18,7 @@ sha2 = "0.10"
secp256k1 = { version = "0.24", features = ["global-context"] }
bitcoin = { version = "0.29", features = ["serde"] }
k256 = { version = "0.11", features = ["arithmetic"] }
k256 = { version = "0.12", features = ["arithmetic"] }
transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.2", features = ["recommended"] }
frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1"] }

View File

@@ -8,7 +8,8 @@ use bitcoin::hashes::{Hash as HashTrait, sha256::Hash};
use k256::Scalar;
use frost::{
curve::Secp256k1,
algorithm::Schnorr,
Participant,
algorithm::IetfSchnorr,
tests::{algorithm_machines, key_gen, sign},
};
@@ -24,12 +25,12 @@ fn test_signing() {
*keys = keys.offset(Scalar::from(offset));
}
let algo = Schnorr::<Secp256k1, BitcoinHram>::new();
let algo = IetfSchnorr::<Secp256k1, BitcoinHram>::ietf();
let mut sig = sign(
&mut OsRng,
algo,
keys.clone(),
algorithm_machines(&mut OsRng, Schnorr::<Secp256k1, BitcoinHram>::new(), &keys),
algorithm_machines(&mut OsRng, IetfSchnorr::ietf(), &keys),
&Sha256::digest(MESSAGE),
);
@@ -41,7 +42,7 @@ fn test_signing() {
.verify_schnorr(
&Signature::from_slice(&sig.serialize()[1 .. 65]).unwrap(),
&Message::from(Hash::hash(MESSAGE)),
&x_only(&keys[&1].group_key()),
&x_only(&keys[&Participant::new(1).unwrap()].group_key()),
)
.unwrap()
}

View File

@@ -10,7 +10,7 @@ use transcript::{Transcript, RecommendedTranscript};
use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar};
use frost::{
curve::{Ciphersuite, Secp256k1},
ThresholdKeys, FrostError,
Participant, ThresholdKeys, FrostError,
algorithm::Schnorr,
sign::*,
};
@@ -168,25 +168,21 @@ impl SignableTransaction {
let mut sigs = vec![];
for i in 0 .. tx.input.len() {
// TODO: Use the above transcript here
let mut transcript = transcript.clone();
transcript.append_message(b"signing_input", u32::try_from(i).unwrap().to_le_bytes());
sigs.push(
AlgorithmMachine::new(
Schnorr::<Secp256k1, BitcoinHram>::new(),
keys.clone().offset(self.1[i]),
)
.unwrap(),
AlgorithmMachine::new(Schnorr::new(transcript), keys.clone().offset(self.1[i])).unwrap(),
);
}
Ok(TransactionMachine { tx: self, transcript, sigs })
Ok(TransactionMachine { tx: self, sigs })
}
}
/// A FROST signing machine to produce a Bitcoin transaction.
pub struct TransactionMachine {
tx: SignableTransaction,
transcript: RecommendedTranscript,
sigs: Vec<AlgorithmMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
sigs: Vec<AlgorithmMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>>,
}
impl PreprocessMachine for TransactionMachine {
@@ -209,14 +205,14 @@ impl PreprocessMachine for TransactionMachine {
})
.collect();
(TransactionSignMachine { tx: self.tx, transcript: self.transcript, sigs }, preprocesses)
(TransactionSignMachine { tx: self.tx, sigs }, preprocesses)
}
}
pub struct TransactionSignMachine {
tx: SignableTransaction,
transcript: RecommendedTranscript,
sigs: Vec<AlgorithmSignMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
sigs:
Vec<AlgorithmSignMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>>,
}
impl SignMachine<Transaction> for TransactionSignMachine {
@@ -250,7 +246,7 @@ impl SignMachine<Transaction> for TransactionSignMachine {
fn sign(
mut self,
commitments: HashMap<u16, Self::Preprocess>,
commitments: HashMap<Participant, Self::Preprocess>,
msg: &[u8],
) -> Result<(TransactionSignatureMachine, Self::SignatureShare), FrostError> {
if !msg.is_empty() {
@@ -293,7 +289,9 @@ impl SignMachine<Transaction> for TransactionSignMachine {
pub struct TransactionSignatureMachine {
tx: Transaction,
sigs: Vec<AlgorithmSignatureMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
sigs: Vec<
AlgorithmSignatureMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>,
>,
}
impl SignatureMachine<Transaction> for TransactionSignatureMachine {
@@ -305,7 +303,7 @@ impl SignatureMachine<Transaction> for TransactionSignatureMachine {
fn complete(
mut self,
mut shares: HashMap<u16, Self::SignatureShare>,
mut shares: HashMap<Participant, Self::SignatureShare>,
) -> Result<Transaction, FrostError> {
for (input, schnorr) in self.tx.input.iter_mut().zip(self.sigs.drain(..)) {
let mut sig = schnorr.complete(

View File

@@ -12,9 +12,10 @@ all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[dependencies]
futures = "0.3"
lazy_static = "1"
thiserror = "1"
crc = "3"
rand_core = "0.6"
rand_chacha = { version = "0.3", optional = true }
@@ -24,6 +25,7 @@ rand_distr = "0.4"
zeroize = { version = "^1.5", features = ["zeroize_derive"] }
subtle = "^2.4"
crc = "3"
sha3 = "0.10"
curve25519-dalek = { version = "^3.2", features = ["std"] }

View File

@@ -184,7 +184,7 @@ fn core(
let L = (&s[i] * &ED25519_BASEPOINT_TABLE) + (c_p * P[i]) + (c_c * C[i]);
let PH = hash_to_point(P[i]);
// Shouldn't be an issue as all of the variables in this vartime statement are public
let R = (s[i] * PH) + images_precomp.vartime_multiscalar_mul(&[c_p, c_c]);
let R = (s[i] * PH) + images_precomp.vartime_multiscalar_mul([c_p, c_c]);
to_hash.truncate(((2 * n) + 3) * 32);
to_hash.extend(L.compress().to_bytes());