Skip to content

Commit

Permalink
Convert ECDSA Public Keys to EVM Addresses when building the merkle tree
Browse files Browse the repository at this point in the history
  • Loading branch information
shekohex committed Oct 10, 2023
1 parent d7dd8f3 commit 243fc35
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pallets/dkg-metadata/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ sp-core = { workspace = true }
sp-io = { workspace = true }
sp-staking = { workspace = true }
sp-keystore = { workspace = true }
k256 = { version = "0.11.5", default-features = false, features = ["arithmetic", "ecdsa"] }

[features]
default = ["std"]
Expand Down
9 changes: 8 additions & 1 deletion pallets/dkg-metadata/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,13 @@ pub mod pallet {
+ Into<ecdsa::Public>
+ From<ecdsa::Public>
+ MaxEncodedLen;
/// Convert DKG AuthorityId to a form that would end up in the Merkle Tree.
///
/// For instance for ECDSA (secp256k1) we want to store uncompressed public keys (65 bytes)
/// and later to Ethereum Addresses (160 bits) to simplify using them on Ethereum chain,
/// but the rest of the Substrate codebase is storing them compressed (33 bytes) for
/// efficiency reasons.
type DKGAuthorityToMerkleLeaf: Convert<Self::DKGId, Vec<u8>>;
/// Jail lengths for misbehaviours
type KeygenJailSentence: Get<BlockNumberFor<Self>>;
type SigningJailSentence: Get<BlockNumberFor<Self>>;
Expand Down Expand Up @@ -1637,7 +1644,7 @@ impl<T: Config> Pallet<T> {
// Hash the external accounts into 32 byte chunks to form the base layer of the merkle tree
let mut base_layer: Vec<[u8; 32]> = voters
.iter()
.map(|account| account.to_raw_vec())
.map(|account| T::DKGAuthorityToMerkleLeaf::convert(account.clone()))
.map(|account| keccak_256(&account))
.collect();
// Pad base_layer to have length 2^height
Expand Down
25 changes: 23 additions & 2 deletions pallets/dkg-metadata/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ use sp_runtime::{
impl_opaque_keys,
testing::TestXt,
traits::{
BlakeTwo256, ConvertInto, Extrinsic as ExtrinsicT, IdentifyAccount, IdentityLookup,
OpaqueKeys, Verify,
BlakeTwo256, Convert, ConvertInto, Extrinsic as ExtrinsicT, IdentifyAccount,
IdentityLookup, OpaqueKeys, Verify,
},
BuildStorage, Percent, Permill,
};
Expand Down Expand Up @@ -141,6 +141,7 @@ parameter_types! {

impl pallet_dkg_metadata::Config for Test {
type DKGId = DKGId;
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
type RuntimeEvent = RuntimeEvent;
type OnAuthoritySetChangeHandler = ();
type OnDKGPublicKeyChangeHandler = ();
Expand Down Expand Up @@ -254,3 +255,23 @@ pub fn new_test_ext_raw_authorities(authorities: Vec<(AccountId, DKGId)>) -> Tes
ext.register_extension(KeystoreExt(Arc::new(MemoryKeystore::new()) as KeystorePtr));
ext
}

/// Convert DKG secp256k1 public keys into Ethereum addresses
pub struct DKGEcdsaToEthereumAddress;
impl Convert<dkg_runtime_primitives::crypto::AuthorityId, Vec<u8>> for DKGEcdsaToEthereumAddress {
fn convert(a: dkg_runtime_primitives::crypto::AuthorityId) -> Vec<u8> {
use k256::{ecdsa::VerifyingKey, elliptic_curve::sec1::ToEncodedPoint};
let _x = VerifyingKey::from_sec1_bytes(sp_core::crypto::ByteArray::as_slice(&a));
VerifyingKey::from_sec1_bytes(sp_core::crypto::ByteArray::as_slice(&a))
.map(|pub_key| {
// uncompress the key
let uncompressed = pub_key.to_encoded_point(false);
// convert to ETH address
sp_io::hashing::keccak_256(&uncompressed.as_bytes()[1..])[12..].to_vec()
})
.map_err(|_| {
log::error!(target: "runtime::dkg_proposals", "Invalid DKG PublicKey format!");
})
.unwrap_or_default()
}
}
1 change: 1 addition & 0 deletions pallets/dkg-proposal-handler/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ parameter_types! {
impl pallet_dkg_metadata::Config for Test {
type DKGId = DKGId;
type RuntimeEvent = RuntimeEvent;
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
type OnAuthoritySetChangeHandler = ();
type OnDKGPublicKeyChangeHandler = ();
type OffChainAuthId = dkg_runtime_primitives::offchain::crypto::OffchainAuthId;
Expand Down
1 change: 1 addition & 0 deletions pallets/dkg-proposals/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ parameter_types! {

impl pallet_dkg_metadata::Config for Test {
type DKGId = DKGId;
type DKGAuthorityToMerkleLeaf = DKGEcdsaToEthereumAddress;
type RuntimeEvent = RuntimeEvent;
type OnAuthoritySetChangeHandler = DKGProposals;
type OnDKGPublicKeyChangeHandler = ();
Expand Down
1 change: 1 addition & 0 deletions standalone/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ parameter_types! {

impl pallet_dkg_metadata::Config for Runtime {
type DKGId = DKGId;
type DKGAuthorityToMerkleLeaf = pallet_dkg_proposals::DKGEcdsaToEthereumAddress;
type RuntimeEvent = RuntimeEvent;
type OnAuthoritySetChangeHandler = DKGProposals;
type OnDKGPublicKeyChangeHandler = ();
Expand Down

0 comments on commit 243fc35

Please sign in to comment.