Break Ethereum Deployer into crate

This commit is contained in:
Luke Parker
2024-09-15 17:13:10 -04:00
parent eb9bce6862
commit 4bcea31c2a
20 changed files with 411 additions and 74 deletions

View File

@@ -0,0 +1,24 @@
[package]
name = "serai-processor-ethereum-primitives"
version = "0.1.0"
description = "Primitives for Serai's Ethereum Processor"
license = "AGPL-3.0-only"
repository = "https://github.com/serai-dex/serai/tree/develop/processor/ethereum/primitives"
authors = ["Luke Parker <lukeparker5132@gmail.com>"]
edition = "2021"
publish = false
rust-version = "1.79"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints]
workspace = true
[dependencies]
group = { version = "0.13", default-features = false }
k256 = { version = "^0.13.1", default-features = false, features = ["std", "arithmetic"] }
alloy-core = { version = "0.8", default-features = false }
alloy-consensus = { version = "0.3", default-features = false, features = ["k256"] }

View File

@@ -0,0 +1,15 @@
AGPL-3.0-only license
Copyright (c) 2022-2024 Luke Parker
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License Version 3 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

View File

@@ -0,0 +1,3 @@
# Ethereum Processor Primitives
This library contains miscellaneous primitives and helper functions.

View File

@@ -0,0 +1,49 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![doc = include_str!("../README.md")]
#![deny(missing_docs)]
use group::ff::PrimeField;
use k256::{elliptic_curve::ops::Reduce, U256, Scalar};
use alloy_core::primitives::{Parity, Signature};
use alloy_consensus::{SignableTransaction, Signed, TxLegacy};
/// The Keccak256 hash function.
pub fn keccak256(data: impl AsRef<[u8]>) -> [u8; 32] {
alloy_core::primitives::keccak256(data.as_ref()).into()
}
/// Deterministically sign a transaction.
///
/// This function panics if passed a transaction with a non-None chain ID.
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)"
);
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());
loop {
// Create the signature
let r_bytes: [u8; 32] = r.to_repr().into();
let s_bytes: [u8; 32] = s.to_repr().into();
let v = Parity::NonEip155(false);
let signature = Signature::from_scalars_and_parity(r_bytes.into(), s_bytes.into(), v).unwrap();
// Check if this is a valid signature
let tx = tx.clone().into_signed(signature);
if tx.recover_signer().is_ok() {
return tx;
}
// Re-hash until valid
r = hash_to_scalar(r_bytes);
s = hash_to_scalar(s_bytes);
}
}