Skip to content

Commit

Permalink
tweak DKG output to avoid rogue taproot tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
conduition committed Oct 5, 2024
1 parent d69a59d commit 802de7a
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 19 deletions.
14 changes: 5 additions & 9 deletions frost-core/src/keys/dkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,16 +562,12 @@ pub fn part3<C: Ciphersuite>(
&round2_secret_package.commitment,
)))
.collect();
let public_key_package = PublicKeyPackage::from_dkg_commitments(&commitments)?;

let key_package = KeyPackage {
header: Header::default(),
identifier: round2_secret_package.identifier,
C::dkg_output_finalize(
round2_secret_package.identifier,
commitments,
signing_share,
verifying_share,
verifying_key: public_key_package.verifying_key,
min_signers: round2_secret_package.min_signers,
};

Ok((key_package, public_key_package))
round2_secret_package.min_signers,
)
}
37 changes: 34 additions & 3 deletions frost-core/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ use core::{
ops::{Add, Mul, Sub},
};

use alloc::vec::Vec;
use alloc::{collections::BTreeMap, vec::Vec};
use rand_core::{CryptoRng, RngCore};

use crate::{
challenge,
keys::{KeyPackage, VerifyingShare},
keys::{
KeyPackage, PublicKeyPackage, SigningShare, VerifiableSecretSharingCommitment,
VerifyingShare,
},
round1, round2, BindingFactor, Challenge, Error, FieldError, GroupCommitment, GroupError,
Signature, SigningTarget, VerifyingKey,
Header, Identifier, Signature, SigningTarget, VerifyingKey,
};

/// A prime order finite field GF(q) over which all scalar values for our prime order group can be
Expand Down Expand Up @@ -447,4 +450,32 @@ pub trait Ciphersuite: Copy + Clone + PartialEq + Debug + 'static {
) -> <Self::Group as Group>::Element {
verifying_share.to_element()
}

/// Construct the key packages from the output of a successful DKG execution.
/// The signing share and verifying share have already been verified and the
/// identifier belongs to our signer.
///
/// In frost-sepc256k1-tr, this adds a hash-based tweak to the group key
/// to prevent peers from inserting rogue tapscript tweaks into the group's
/// joint public key.
fn dkg_output_finalize(
identifier: Identifier<Self>,
commitments: BTreeMap<Identifier<Self>, &VerifiableSecretSharingCommitment<Self>>,
signing_share: SigningShare<Self>,
verifying_share: VerifyingShare<Self>,
min_signers: u16,
) -> Result<(KeyPackage<Self>, PublicKeyPackage<Self>), Error<Self>> {
let public_key_package = PublicKeyPackage::from_dkg_commitments(&commitments)?;

let key_package = KeyPackage {
header: Header::default(),
identifier,
signing_share,
verifying_share,
verifying_key: public_key_package.verifying_key,
min_signers,
};

Ok((key_package, public_key_package))
}
}
41 changes: 41 additions & 0 deletions frost-secp256k1-tr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,47 @@ impl Ciphersuite for Secp256K1Sha256 {
vs
}
}

/// We add an unusable taproot tweak to the group key computed by a DKG run,
/// to prevent peers from inserting rogue tapscript tweaks into the group's
/// joint public key.
fn dkg_output_finalize(
identifier: Identifier,
commitments: BTreeMap<Identifier, &keys::VerifiableSecretSharingCommitment>,
signing_share: keys::SigningShare,
verifying_share: keys::VerifyingShare,
min_signers: u16,
) -> Result<(keys::KeyPackage, keys::PublicKeyPackage), Error> {
let untweaked_public_key_package =
keys::PublicKeyPackage::from_dkg_commitments(&commitments)?;

let untweaked_vk = untweaked_public_key_package.verifying_key().to_element();
let t = tweak(&untweaked_vk, Some(vec![])); // unspendable script path
let tG = ProjectivePoint::GENERATOR * t;

let tweaked_verifying_shares: BTreeMap<Identifier, keys::VerifyingShare> =
untweaked_public_key_package
.verifying_shares()
.clone()
.into_iter()
.map(|(id, share)| (id, keys::VerifyingShare::new(share.to_element() + tG)))
.collect();

let tweaked_verifying_key = VerifyingKey::new(untweaked_vk + tG);

let key_package = keys::KeyPackage::new(
identifier,
keys::SigningShare::new(signing_share.to_scalar() + t),
keys::VerifyingShare::new(verifying_share.to_element() + tG),
tweaked_verifying_key,
min_signers,
);

let public_key_package =
keys::PublicKeyPackage::new(tweaked_verifying_shares, tweaked_verifying_key);

Ok((key_package, public_key_package))
}
}

impl RandomizedCiphersuite for Secp256K1Sha256 {
Expand Down
14 changes: 7 additions & 7 deletions frost-secp256k1-tr/tests/helpers/vectors_dkg.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"hash": "SHA-256"
},
"inputs": {
"verifying_key": "034a48daffc43b47b42695611942c481aecffb9137686ad0b3e0ab8e1f1dab0293",
"verifying_key": "02409611d2fd36025b75caa15f1d70f6d5cfea9cc4254d29580075fdf832d934db",
"1": {
"identifier": 1,
"signing_key": "68e3f6904c6043973515a36bf7801a71597da35733f21305d75a5234f06e4529",
Expand All @@ -18,8 +18,8 @@
"2": "1dd3cb3e2370e6af22917415f0ad584514807b58b3cc40d2230a26e115f02771",
"3": "dd25ee86acd01f996618aa0d1153f5e8fbc929a8e8a18b8f0a15f91d087217e2"
},
"verifying_share": "03e2eada7cdb20ec24babb687eb633580c977148c70254700f1ad4a931316dc6d9",
"signing_share": "89b08895c083bb6a00de882d0e6ff2a20a1878b5e8c0c5aba5983100e3c45d0c"
"verifying_share": "03487e21b8658bffc7903fa2f6435bdae7a417990a27698c273a14f72bece665f3",
"signing_share": "051f56860fd1225af141494c573ce33da026e1c5f8c5099b73c9ad28675a8389"
},
"2": {
"identifier": 2,
Expand All @@ -31,8 +31,8 @@
"1": "b489a711942526abbb5330a8215d2e740f7dbddec3452006993a8cea3ac278cb",
"3": "20255dc07b1fb78bdf90bd85fd2389c988c8250faee11826656a09142fa9fc97"
},
"verifying_share": "0312705f7560a146760034ebdd103277e184ce81d2ba6a67a43f0b3f39410cc396",
"signing_share": "ea3cdccc32746d918c2910295b0a03dfa1c94f01d20f860c6fe8c22fb6c0d831"
"verifying_share": "02aab83a9c57284041ae6add2d5e2ea43d715c6607e03c4c22ca5aae10086076f4",
"signing_share": "65abaabc81c1d4827c8bd148a3d6f47b37d7b811e213c9fc3e1a3e573a56feae"
},
"3": {
"identifier": 3,
Expand All @@ -44,8 +44,8 @@
"1": "da5c7f5238079835fe71f746364bb8756a7dcb228aeea686fa2aaa44dfec929c",
"2": "0d47e4b622ee3804bff8cfe088653efefe865cce0c065aecbf7e318182b89e2d"
},
"verifying_share": "036607b45621ce6840d999980c9c74d69a15fa5a246e852ee2ca6924ce65fa299b",
"signing_share": "4ac93102a4651fb917739825a7a4151e7ecb48670c15a6317a66f4d1b9871215"
"verifying_share": "031f1571625e54d9bb0e58e228abe5430460ab9d414bced42250fd09526476290b",
"signing_share": "c637fef2f3b286aa07d65944f07105b8cf888e5dcb628a5d086acf860d5379d3"
}
}
}

0 comments on commit 802de7a

Please sign in to comment.