Simplify deterministic signing process in serai-processor-ethereum-primitives

This should be easier to specify/do an alternative implementation of.
This commit is contained in:
Luke Parker 2024-10-30 21:36:31 -04:00
parent 2a427382f1
commit 8e800885fb
No known key found for this signature in database

View file

@ -3,7 +3,7 @@
#![deny(missing_docs)]
use group::ff::PrimeField;
use k256::{elliptic_curve::ops::Reduce, U256, Scalar};
use k256::Scalar;
use alloy_core::primitives::{Parity, Signature};
use alloy_consensus::{SignableTransaction, Signed, TxLegacy};
@ -15,20 +15,21 @@ pub fn keccak256(data: impl AsRef<[u8]>) -> [u8; 32] {
/// Deterministically sign a transaction.
///
/// This function panics if passed a transaction with a non-None chain ID.
/// This signs a transaction via setting `r = 1, s = 1`, and incrementing `r` until a signer is
/// recoverable from the signature for this transaction. The purpose of this is to be able to send
/// a transaction from a known account which no one knows the private key for.
///
/// This function panics if passed a transaction with a non-None chain ID. This is because the
/// signer for this transaction is only singular across any/all EVM instances if it isn't binding
/// to an instance.
pub fn deterministically_sign(tx: &TxLegacy) -> Signed<TxLegacy> {
pub fn hash_to_scalar(data: impl AsRef<[u8]>) -> Scalar {
<Scalar as Reduce<U256>>::reduce_bytes(&keccak256(data).into())
}
assert!(
tx.chain_id.is_none(),
"chain ID was Some when deterministically signing a TX (causing a non-deterministic signer)"
"chain ID was Some when deterministically signing a TX (causing a non-singular signer)"
);
let sig_hash = tx.signature_hash().0;
let mut r = hash_to_scalar([sig_hash.as_slice(), b"r"].concat());
let mut s = hash_to_scalar([sig_hash.as_slice(), b"s"].concat());
let mut r = Scalar::ONE;
let s = Scalar::ONE;
loop {
// Create the signature
let r_bytes: [u8; 32] = r.to_repr().into();
@ -42,8 +43,6 @@ pub fn deterministically_sign(tx: &TxLegacy) -> Signed<TxLegacy> {
return tx;
}
// Re-hash until valid
r = hash_to_scalar(r_bytes);
s = hash_to_scalar(s_bytes);
r += Scalar::ONE;
}
}