diff --git a/chain-signatures/contract/src/lib.rs b/chain-signatures/contract/src/lib.rs index c6f3166cf..1437c47b1 100644 --- a/chain-signatures/contract/src/lib.rs +++ b/chain-signatures/contract/src/lib.rs @@ -13,6 +13,7 @@ use near_sdk::{ PromiseError, PublicKey, }; +use k256::elliptic_curve::sec1::ToEncodedPoint; use primitives::{ CandidateInfo, Candidates, ParticipantInfo, Participants, PkVotes, SignRequest, SignaturePromiseError, SignatureResult, Votes, @@ -373,6 +374,20 @@ impl VersionedMpcContract { } } + /// This is the derived public key of the caller given path and predecessor + /// if predecessor is not provided, it will be the caller of the contract + pub fn derived_public_key(&self, path: String, predecessor: Option) -> PublicKey { + let predecessor = predecessor.unwrap_or_else(env::predecessor_account_id); + let epsilon = derive_epsilon(&predecessor, &path); + let derived_public_key = + derive_key(near_public_key_to_affine_point(self.public_key()), epsilon); + let encoded_point = derived_public_key.to_encoded_point(false); + let slice: &[u8] = &encoded_point.as_bytes()[1..65]; + let mut data: Vec = vec![near_sdk::CurveType::SECP256K1 as u8]; + data.extend(slice.to_vec()); + PublicKey::try_from(data).unwrap() + } + /// Key versions refer new versions of the root key that we may choose to generate on cohort changes /// Older key versions will always work but newer key versions were never held by older signers /// Newer key versions may also add new security features, like only existing within a secure enclave