Gate libsecp256k1 update (backport #18656) (#18700)

* hijack secp256k1 enablement feature plumbing for libsecp256k1 upgrade

* Bump libsecp256k1 to v0.5.0

* gate libsecp256k1 upgrade to v0.5.0

Co-authored-by: Trent Nelson <trent@solana.com>
This commit is contained in:
mergify[bot]
2021-07-16 03:34:13 +00:00
committed by GitHub
parent e15721f22d
commit 63d7fdb4bd
19 changed files with 208 additions and 194 deletions

View File

@@ -29,18 +29,18 @@ pub struct SecpSignatureOffsets {
}
pub fn new_secp256k1_instruction(
priv_key: &secp256k1::SecretKey,
priv_key: &libsecp256k1::SecretKey,
message_arr: &[u8],
) -> Instruction {
let secp_pubkey = secp256k1::PublicKey::from_secret_key(priv_key);
let secp_pubkey = libsecp256k1::PublicKey::from_secret_key(priv_key);
let eth_pubkey = construct_eth_pubkey(&secp_pubkey);
let mut hasher = sha3::Keccak256::new();
hasher.update(&message_arr);
let message_hash = hasher.finalize();
let mut message_hash_arr = [0u8; 32];
message_hash_arr.copy_from_slice(&message_hash.as_slice());
let message = secp256k1::Message::parse(&message_hash_arr);
let (signature, recovery_id) = secp256k1::sign(&message, priv_key);
let message = libsecp256k1::Message::parse(&message_hash_arr);
let (signature, recovery_id) = libsecp256k1::sign(&message, priv_key);
let signature_arr = signature.serialize();
assert_eq!(signature_arr.len(), SIGNATURE_SERIALIZED_SIZE);
@@ -84,7 +84,9 @@ pub fn new_secp256k1_instruction(
}
}
pub fn construct_eth_pubkey(pubkey: &secp256k1::PublicKey) -> [u8; HASHED_PUBKEY_SERIALIZED_SIZE] {
pub fn construct_eth_pubkey(
pubkey: &libsecp256k1::PublicKey,
) -> [u8; HASHED_PUBKEY_SERIALIZED_SIZE] {
let mut addr = [0u8; HASHED_PUBKEY_SERIALIZED_SIZE];
addr.copy_from_slice(&sha3::Keccak256::digest(&pubkey.serialize()[1..])[12..]);
assert_eq!(addr.len(), HASHED_PUBKEY_SERIALIZED_SIZE);
@@ -94,6 +96,7 @@ pub fn construct_eth_pubkey(pubkey: &secp256k1::PublicKey) -> [u8; HASHED_PUBKEY
pub fn verify_eth_addresses(
data: &[u8],
instruction_datas: &[&[u8]],
libsecp256k1_0_5_upgrade_enabled: bool,
) -> Result<(), Secp256k1Error> {
if data.is_empty() {
return Err(Secp256k1Error::InvalidInstructionDataSize);
@@ -121,11 +124,20 @@ pub fn verify_eth_addresses(
if sig_end >= signature_instruction.len() {
return Err(Secp256k1Error::InvalidSignature);
}
let signature =
secp256k1::Signature::parse_slice(&signature_instruction[sig_start..sig_end])
.map_err(|_| Secp256k1Error::InvalidSignature)?;
let recovery_id = secp256k1::RecoveryId::parse(signature_instruction[sig_end])
let sig_parse_result = if libsecp256k1_0_5_upgrade_enabled {
libsecp256k1::Signature::parse_standard_slice(
&signature_instruction[sig_start..sig_end],
)
} else {
libsecp256k1::Signature::parse_overflowing_slice(
&signature_instruction[sig_start..sig_end],
)
};
let signature = sig_parse_result.map_err(|_| Secp256k1Error::InvalidSignature)?;
let recovery_id = libsecp256k1::RecoveryId::parse(signature_instruction[sig_end])
.map_err(|_| Secp256k1Error::InvalidRecoveryId)?;
// Parse out pubkey
@@ -148,8 +160,8 @@ pub fn verify_eth_addresses(
hasher.update(message_slice);
let message_hash = hasher.finalize();
let pubkey = secp256k1::recover(
&secp256k1::Message::parse_slice(&message_hash).unwrap(),
let pubkey = libsecp256k1::recover(
&libsecp256k1::Message::parse_slice(&message_hash).unwrap(),
&signature,
&recovery_id,
)
@@ -193,7 +205,7 @@ pub mod test {
let writer = std::io::Cursor::new(&mut instruction_data[1..]);
bincode::serialize_into(writer, &offsets).unwrap();
verify_eth_addresses(&instruction_data, &[&[0u8; 100]])
verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false)
}
#[test]
@@ -208,7 +220,7 @@ pub mod test {
instruction_data.truncate(instruction_data.len() - 1);
assert_eq!(
verify_eth_addresses(&instruction_data, &[&[0u8; 100]]),
verify_eth_addresses(&instruction_data, &[&[0u8; 100]], false),
Err(Secp256k1Error::InvalidInstructionDataSize)
);