mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Resolve merging crypto-{audit, tweaks} and use the proper transcript in Bitcoin
This commit is contained in:
43
Cargo.lock
generated
43
Cargo.lock
generated
@@ -602,7 +602,7 @@ dependencies = [
|
|||||||
"bitcoin",
|
"bitcoin",
|
||||||
"flexible-transcript",
|
"flexible-transcript",
|
||||||
"hex",
|
"hex",
|
||||||
"k256",
|
"k256 0.12.0",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
@@ -1037,7 +1037,7 @@ dependencies = [
|
|||||||
"hex",
|
"hex",
|
||||||
"k256 0.12.0",
|
"k256 0.12.0",
|
||||||
"minimal-ed448",
|
"minimal-ed448",
|
||||||
"p256",
|
"p256 0.12.0",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
"sha3",
|
"sha3",
|
||||||
@@ -2599,7 +2599,7 @@ version = "0.12.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"group",
|
"group",
|
||||||
"k256 0.12.0",
|
"k256 0.12.0",
|
||||||
"p256",
|
"p256 0.12.0",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -3350,6 +3350,15 @@ version = "0.3.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0"
|
checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hkdf"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437"
|
||||||
|
dependencies = [
|
||||||
|
"hmac 0.12.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
@@ -5575,6 +5584,17 @@ version = "6.4.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "p256"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594"
|
||||||
|
dependencies = [
|
||||||
|
"ecdsa 0.14.8",
|
||||||
|
"elliptic-curve",
|
||||||
|
"sha2 0.10.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "p256"
|
name = "p256"
|
||||||
version = "0.12.0"
|
version = "0.12.0"
|
||||||
@@ -5587,6 +5607,17 @@ dependencies = [
|
|||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "p384"
|
||||||
|
version = "0.11.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dfc8c5bf642dde52bb9e87c0ecd8ca5a76faac2eeed98dedb7c717997e1080aa"
|
||||||
|
dependencies = [
|
||||||
|
"ecdsa 0.14.8",
|
||||||
|
"elliptic-curve",
|
||||||
|
"sha2 0.10.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packed_simd_2"
|
name = "packed_simd_2"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
@@ -8224,7 +8255,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"group",
|
"group",
|
||||||
"hex",
|
"hex",
|
||||||
"k256",
|
"k256 0.12.0",
|
||||||
"modular-frost",
|
"modular-frost",
|
||||||
"monero-serai",
|
"monero-serai",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
@@ -10788,7 +10819,7 @@ dependencies = [
|
|||||||
"hmac 0.12.1",
|
"hmac 0.12.1",
|
||||||
"log",
|
"log",
|
||||||
"oid-registry 0.6.1",
|
"oid-registry 0.6.1",
|
||||||
"p256",
|
"p256 0.11.1",
|
||||||
"p384",
|
"p384",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
@@ -10799,7 +10830,7 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"sha1",
|
"sha1",
|
||||||
"sha2 0.10.6",
|
"sha2 0.10.6",
|
||||||
"signature",
|
"signature 1.6.4",
|
||||||
"subtle",
|
"subtle",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ sha2 = "0.10"
|
|||||||
secp256k1 = { version = "0.24", features = ["global-context"] }
|
secp256k1 = { version = "0.24", features = ["global-context"] }
|
||||||
bitcoin = { version = "0.29", features = ["serde"] }
|
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"] }
|
transcript = { package = "flexible-transcript", path = "../../crypto/transcript", version = "0.2", features = ["recommended"] }
|
||||||
frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1"] }
|
frost = { version = "0.5", package = "modular-frost", path = "../../crypto/frost", features = ["secp256k1"] }
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ use bitcoin::hashes::{Hash as HashTrait, sha256::Hash};
|
|||||||
use k256::Scalar;
|
use k256::Scalar;
|
||||||
use frost::{
|
use frost::{
|
||||||
curve::Secp256k1,
|
curve::Secp256k1,
|
||||||
algorithm::Schnorr,
|
Participant,
|
||||||
|
algorithm::IetfSchnorr,
|
||||||
tests::{algorithm_machines, key_gen, sign},
|
tests::{algorithm_machines, key_gen, sign},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -24,12 +25,12 @@ fn test_signing() {
|
|||||||
*keys = keys.offset(Scalar::from(offset));
|
*keys = keys.offset(Scalar::from(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
let algo = Schnorr::<Secp256k1, BitcoinHram>::new();
|
let algo = IetfSchnorr::<Secp256k1, BitcoinHram>::ietf();
|
||||||
let mut sig = sign(
|
let mut sig = sign(
|
||||||
&mut OsRng,
|
&mut OsRng,
|
||||||
algo,
|
algo,
|
||||||
keys.clone(),
|
keys.clone(),
|
||||||
algorithm_machines(&mut OsRng, Schnorr::<Secp256k1, BitcoinHram>::new(), &keys),
|
algorithm_machines(&mut OsRng, IetfSchnorr::ietf(), &keys),
|
||||||
&Sha256::digest(MESSAGE),
|
&Sha256::digest(MESSAGE),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -41,7 +42,7 @@ fn test_signing() {
|
|||||||
.verify_schnorr(
|
.verify_schnorr(
|
||||||
&Signature::from_slice(&sig.serialize()[1 .. 65]).unwrap(),
|
&Signature::from_slice(&sig.serialize()[1 .. 65]).unwrap(),
|
||||||
&Message::from(Hash::hash(MESSAGE)),
|
&Message::from(Hash::hash(MESSAGE)),
|
||||||
&x_only(&keys[&1].group_key()),
|
&x_only(&keys[&Participant::new(1).unwrap()].group_key()),
|
||||||
)
|
)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ use transcript::{Transcript, RecommendedTranscript};
|
|||||||
use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar};
|
use k256::{elliptic_curve::sec1::ToEncodedPoint, Scalar};
|
||||||
use frost::{
|
use frost::{
|
||||||
curve::{Ciphersuite, Secp256k1},
|
curve::{Ciphersuite, Secp256k1},
|
||||||
ThresholdKeys, FrostError,
|
Participant, ThresholdKeys, FrostError,
|
||||||
algorithm::Schnorr,
|
algorithm::Schnorr,
|
||||||
sign::*,
|
sign::*,
|
||||||
};
|
};
|
||||||
@@ -168,25 +168,21 @@ impl SignableTransaction {
|
|||||||
|
|
||||||
let mut sigs = vec![];
|
let mut sigs = vec![];
|
||||||
for i in 0 .. tx.input.len() {
|
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(
|
sigs.push(
|
||||||
AlgorithmMachine::new(
|
AlgorithmMachine::new(Schnorr::new(transcript), keys.clone().offset(self.1[i])).unwrap(),
|
||||||
Schnorr::<Secp256k1, BitcoinHram>::new(),
|
|
||||||
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.
|
/// A FROST signing machine to produce a Bitcoin transaction.
|
||||||
pub struct TransactionMachine {
|
pub struct TransactionMachine {
|
||||||
tx: SignableTransaction,
|
tx: SignableTransaction,
|
||||||
transcript: RecommendedTranscript,
|
sigs: Vec<AlgorithmMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>>,
|
||||||
sigs: Vec<AlgorithmMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PreprocessMachine for TransactionMachine {
|
impl PreprocessMachine for TransactionMachine {
|
||||||
@@ -209,14 +205,14 @@ impl PreprocessMachine for TransactionMachine {
|
|||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
(TransactionSignMachine { tx: self.tx, transcript: self.transcript, sigs }, preprocesses)
|
(TransactionSignMachine { tx: self.tx, sigs }, preprocesses)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TransactionSignMachine {
|
pub struct TransactionSignMachine {
|
||||||
tx: SignableTransaction,
|
tx: SignableTransaction,
|
||||||
transcript: RecommendedTranscript,
|
sigs:
|
||||||
sigs: Vec<AlgorithmSignMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
|
Vec<AlgorithmSignMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SignMachine<Transaction> for TransactionSignMachine {
|
impl SignMachine<Transaction> for TransactionSignMachine {
|
||||||
@@ -250,7 +246,7 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||||||
|
|
||||||
fn sign(
|
fn sign(
|
||||||
mut self,
|
mut self,
|
||||||
commitments: HashMap<u16, Self::Preprocess>,
|
commitments: HashMap<Participant, Self::Preprocess>,
|
||||||
msg: &[u8],
|
msg: &[u8],
|
||||||
) -> Result<(TransactionSignatureMachine, Self::SignatureShare), FrostError> {
|
) -> Result<(TransactionSignatureMachine, Self::SignatureShare), FrostError> {
|
||||||
if !msg.is_empty() {
|
if !msg.is_empty() {
|
||||||
@@ -293,7 +289,9 @@ impl SignMachine<Transaction> for TransactionSignMachine {
|
|||||||
|
|
||||||
pub struct TransactionSignatureMachine {
|
pub struct TransactionSignatureMachine {
|
||||||
tx: Transaction,
|
tx: Transaction,
|
||||||
sigs: Vec<AlgorithmSignatureMachine<Secp256k1, Schnorr<Secp256k1, BitcoinHram>>>,
|
sigs: Vec<
|
||||||
|
AlgorithmSignatureMachine<Secp256k1, Schnorr<Secp256k1, RecommendedTranscript, BitcoinHram>>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SignatureMachine<Transaction> for TransactionSignatureMachine {
|
impl SignatureMachine<Transaction> for TransactionSignatureMachine {
|
||||||
@@ -305,7 +303,7 @@ impl SignatureMachine<Transaction> for TransactionSignatureMachine {
|
|||||||
|
|
||||||
fn complete(
|
fn complete(
|
||||||
mut self,
|
mut self,
|
||||||
mut shares: HashMap<u16, Self::SignatureShare>,
|
mut shares: HashMap<Participant, Self::SignatureShare>,
|
||||||
) -> Result<Transaction, FrostError> {
|
) -> Result<Transaction, FrostError> {
|
||||||
for (input, schnorr) in self.tx.input.iter_mut().zip(self.sigs.drain(..)) {
|
for (input, schnorr) in self.tx.input.iter_mut().zip(self.sigs.drain(..)) {
|
||||||
let mut sig = schnorr.complete(
|
let mut sig = schnorr.complete(
|
||||||
|
|||||||
@@ -12,9 +12,10 @@ all-features = true
|
|||||||
rustdoc-args = ["--cfg", "docsrs"]
|
rustdoc-args = ["--cfg", "docsrs"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
futures = "0.3"
|
||||||
|
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
thiserror = "1"
|
thiserror = "1"
|
||||||
crc = "3"
|
|
||||||
|
|
||||||
rand_core = "0.6"
|
rand_core = "0.6"
|
||||||
rand_chacha = { version = "0.3", optional = true }
|
rand_chacha = { version = "0.3", optional = true }
|
||||||
@@ -24,6 +25,7 @@ rand_distr = "0.4"
|
|||||||
zeroize = { version = "^1.5", features = ["zeroize_derive"] }
|
zeroize = { version = "^1.5", features = ["zeroize_derive"] }
|
||||||
subtle = "^2.4"
|
subtle = "^2.4"
|
||||||
|
|
||||||
|
crc = "3"
|
||||||
sha3 = "0.10"
|
sha3 = "0.10"
|
||||||
|
|
||||||
curve25519-dalek = { version = "^3.2", features = ["std"] }
|
curve25519-dalek = { version = "^3.2", features = ["std"] }
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ fn core(
|
|||||||
let L = (&s[i] * &ED25519_BASEPOINT_TABLE) + (c_p * P[i]) + (c_c * C[i]);
|
let L = (&s[i] * &ED25519_BASEPOINT_TABLE) + (c_p * P[i]) + (c_c * C[i]);
|
||||||
let PH = hash_to_point(P[i]);
|
let PH = hash_to_point(P[i]);
|
||||||
// Shouldn't be an issue as all of the variables in this vartime statement are public
|
// 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.truncate(((2 * n) + 3) * 32);
|
||||||
to_hash.extend(L.compress().to_bytes());
|
to_hash.extend(L.compress().to_bytes());
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ use async_trait::async_trait;
|
|||||||
|
|
||||||
use rand_core::OsRng;
|
use rand_core::OsRng;
|
||||||
|
|
||||||
|
use frost::Participant;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
NetworkError, Network,
|
NetworkError, Network,
|
||||||
coin::Coin,
|
coin::Coin,
|
||||||
@@ -15,11 +17,11 @@ use crate::{
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct LocalNetwork {
|
struct LocalNetwork {
|
||||||
i: u16,
|
i: Participant,
|
||||||
size: u16,
|
size: u16,
|
||||||
round: usize,
|
round: usize,
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
rounds: Arc<RwLock<Vec<HashMap<u16, Vec<u8>>>>>,
|
rounds: Arc<RwLock<Vec<HashMap<Participant, Vec<u8>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalNetwork {
|
impl LocalNetwork {
|
||||||
@@ -27,7 +29,12 @@ impl LocalNetwork {
|
|||||||
let rounds = Arc::new(RwLock::new(vec![]));
|
let rounds = Arc::new(RwLock::new(vec![]));
|
||||||
let mut res = vec![];
|
let mut res = vec![];
|
||||||
for i in 1 ..= size {
|
for i in 1 ..= size {
|
||||||
res.push(LocalNetwork { i, size, round: 0, rounds: rounds.clone() });
|
res.push(LocalNetwork {
|
||||||
|
i: Participant::new(i).unwrap(),
|
||||||
|
size,
|
||||||
|
round: 0,
|
||||||
|
rounds: rounds.clone(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
@@ -35,7 +42,7 @@ impl LocalNetwork {
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl Network for LocalNetwork {
|
impl Network for LocalNetwork {
|
||||||
async fn round(&mut self, data: Vec<u8>) -> Result<HashMap<u16, Vec<u8>>, NetworkError> {
|
async fn round(&mut self, data: Vec<u8>) -> Result<HashMap<Participant, Vec<u8>>, NetworkError> {
|
||||||
{
|
{
|
||||||
let mut rounds = self.rounds.write().unwrap();
|
let mut rounds = self.rounds.write().unwrap();
|
||||||
if rounds.len() == self.round {
|
if rounds.len() == self.round {
|
||||||
@@ -64,14 +71,14 @@ pub async fn test_send<C: Coin + Clone>(coin: C, fee: C::Fee) {
|
|||||||
let latest = coin.get_latest_block_number().await.unwrap();
|
let latest = coin.get_latest_block_number().await.unwrap();
|
||||||
|
|
||||||
let mut keys = frost::tests::key_gen::<_, C::Curve>(&mut OsRng);
|
let mut keys = frost::tests::key_gen::<_, C::Curve>(&mut OsRng);
|
||||||
let threshold = keys[&1].params().t();
|
let threshold = keys[&Participant::new(1).unwrap()].params().t();
|
||||||
let mut networks = LocalNetwork::new(threshold);
|
let mut networks = LocalNetwork::new(threshold);
|
||||||
|
|
||||||
let mut wallets = vec![];
|
let mut wallets = vec![];
|
||||||
for i in 1 ..= threshold {
|
for i in 1 ..= threshold {
|
||||||
let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone());
|
let mut wallet = Wallet::new(MemCoinDb::new(), coin.clone());
|
||||||
wallet.acknowledge_block(0, latest);
|
wallet.acknowledge_block(0, latest);
|
||||||
wallet.add_keys(&WalletKeys::new(keys.remove(&i).unwrap(), 0));
|
wallet.add_keys(&WalletKeys::new(keys.remove(&Participant::new(i).unwrap()).unwrap(), 0));
|
||||||
wallets.push(wallet);
|
wallets.push(wallet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user