mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
feat: Alloy migration (#4737)
Co-authored-by: Alessandro Mazza <121622391+alessandromazza98@users.noreply.github.com> Co-authored-by: Supernovahs.eth <91280922+supernovahs@users.noreply.github.com> Co-authored-by: Oliver Nordbjerg <hi@notbjerg.me>
This commit is contained in:
@ -8,10 +8,10 @@ homepage.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
reth-rlp = { workspace = true, features = ["derive", "ethereum-types", "std"] }
|
||||
reth-primitives.workspace = true
|
||||
reth-net-common = { path = "../common" }
|
||||
|
||||
alloy-rlp = { workspace = true, features = ["derive"] }
|
||||
futures.workspace = true
|
||||
thiserror.workspace = true
|
||||
tokio = { workspace = true, features = ["full"] }
|
||||
@ -38,6 +38,3 @@ aes = "0.8.1"
|
||||
hmac = "0.12.1"
|
||||
block-padding = "0.3.2"
|
||||
cipher = { version = "0.4.3", features = ["block-padding"] }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal.workspace = true
|
||||
|
||||
@ -6,6 +6,7 @@ use crate::{
|
||||
ECIESError,
|
||||
};
|
||||
use aes::{cipher::StreamCipher, Aes128, Aes256};
|
||||
use alloy_rlp::{Encodable, Rlp, RlpEncodable, RlpMaxEncodedLen};
|
||||
use byteorder::{BigEndian, ByteOrder, ReadBytesExt};
|
||||
use ctr::Ctr64BE;
|
||||
use digest::{crypto_common::KeyIvInit, Digest};
|
||||
@ -13,9 +14,8 @@ use educe::Educe;
|
||||
use rand::{thread_rng, Rng};
|
||||
use reth_primitives::{
|
||||
bytes::{BufMut, Bytes, BytesMut},
|
||||
H128, H256, H512 as PeerId,
|
||||
B128, B256, B512 as PeerId,
|
||||
};
|
||||
use reth_rlp::{Encodable, Rlp, RlpEncodable, RlpMaxEncodedLen};
|
||||
use secp256k1::{
|
||||
ecdsa::{RecoverableSignature, RecoveryId},
|
||||
PublicKey, SecretKey, SECP256K1,
|
||||
@ -31,12 +31,12 @@ const PROTOCOL_VERSION: usize = 4;
|
||||
///
|
||||
/// This uses the given remote public key and local (ephemeral) secret key to [compute a shared
|
||||
/// secp256k1 point](secp256k1::ecdh::shared_secret_point) and slices off the y coordinate from the
|
||||
/// returned pair, returning only the bytes of the x coordinate as a [`H256`].
|
||||
fn ecdh_x(public_key: &PublicKey, secret_key: &SecretKey) -> H256 {
|
||||
H256::from_slice(&secp256k1::ecdh::shared_secret_point(public_key, secret_key)[..32])
|
||||
/// returned pair, returning only the bytes of the x coordinate as a [`B256`].
|
||||
fn ecdh_x(public_key: &PublicKey, secret_key: &SecretKey) -> B256 {
|
||||
B256::from_slice(&secp256k1::ecdh::shared_secret_point(public_key, secret_key)[..32])
|
||||
}
|
||||
|
||||
fn kdf(secret: H256, s1: &[u8], dest: &mut [u8]) {
|
||||
fn kdf(secret: B256, s1: &[u8], dest: &mut [u8]) {
|
||||
// SEC/ISO/Shoup specify counter size SHOULD be equivalent
|
||||
// to size of hash output, however, it also notes that
|
||||
// the 4 bytes is okay. NIST specifies 4 bytes.
|
||||
@ -46,7 +46,7 @@ fn kdf(secret: H256, s1: &[u8], dest: &mut [u8]) {
|
||||
let mut hasher = Sha256::default();
|
||||
let ctrs = [(ctr >> 24) as u8, (ctr >> 16) as u8, (ctr >> 8) as u8, ctr as u8];
|
||||
hasher.update(ctrs);
|
||||
hasher.update(secret.as_bytes());
|
||||
hasher.update(secret.as_slice());
|
||||
hasher.update(s1);
|
||||
let d = hasher.finalize();
|
||||
dest[written..(written + 32)].copy_from_slice(&d);
|
||||
@ -68,11 +68,11 @@ pub struct ECIES {
|
||||
#[educe(Debug(ignore))]
|
||||
ephemeral_secret_key: SecretKey,
|
||||
ephemeral_public_key: PublicKey,
|
||||
ephemeral_shared_secret: Option<H256>,
|
||||
ephemeral_shared_secret: Option<B256>,
|
||||
remote_ephemeral_public_key: Option<PublicKey>,
|
||||
|
||||
nonce: H256,
|
||||
remote_nonce: Option<H256>,
|
||||
nonce: B256,
|
||||
remote_nonce: Option<B256>,
|
||||
|
||||
#[educe(Debug(ignore))]
|
||||
ingress_aes: Option<Ctr64BE<Aes256>>,
|
||||
@ -100,7 +100,7 @@ impl ECIES {
|
||||
fn new_static_client(
|
||||
secret_key: SecretKey,
|
||||
remote_id: PeerId,
|
||||
nonce: H256,
|
||||
nonce: B256,
|
||||
ephemeral_secret_key: SecretKey,
|
||||
) -> Result<Self, ECIESError> {
|
||||
let public_key = PublicKey::from_secret_key(SECP256K1, &secret_key);
|
||||
@ -133,9 +133,9 @@ impl ECIES {
|
||||
|
||||
/// Create a new ECIES client with the given static secret key and remote peer ID.
|
||||
pub fn new_client(secret_key: SecretKey, remote_id: PeerId) -> Result<Self, ECIESError> {
|
||||
let nonce = H256::random();
|
||||
let ephemeral_secret_key = SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let nonce = rng.gen();
|
||||
let ephemeral_secret_key = SecretKey::new(&mut rng);
|
||||
Self::new_static_client(secret_key, remote_id, nonce, ephemeral_secret_key)
|
||||
}
|
||||
|
||||
@ -143,7 +143,7 @@ impl ECIES {
|
||||
/// key.
|
||||
pub fn new_static_server(
|
||||
secret_key: SecretKey,
|
||||
nonce: H256,
|
||||
nonce: B256,
|
||||
ephemeral_secret_key: SecretKey,
|
||||
) -> Result<Self, ECIESError> {
|
||||
let public_key = PublicKey::from_secret_key(SECP256K1, &secret_key);
|
||||
@ -175,9 +175,9 @@ impl ECIES {
|
||||
|
||||
/// Create a new ECIES server with the given static secret key.
|
||||
pub fn new_server(secret_key: SecretKey) -> Result<Self, ECIESError> {
|
||||
let nonce = H256::random();
|
||||
let ephemeral_secret_key = SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
|
||||
let mut rng = thread_rng();
|
||||
let nonce = rng.gen();
|
||||
let ephemeral_secret_key = SecretKey::new(&mut rng);
|
||||
Self::new_static_server(secret_key, nonce, ephemeral_secret_key)
|
||||
}
|
||||
|
||||
@ -187,9 +187,11 @@ impl ECIES {
|
||||
}
|
||||
|
||||
fn encrypt_message(&self, data: &[u8], out: &mut BytesMut) {
|
||||
let mut rng = thread_rng();
|
||||
|
||||
out.reserve(secp256k1::constants::UNCOMPRESSED_PUBLIC_KEY_SIZE + 16 + data.len() + 32);
|
||||
|
||||
let secret_key = SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
let secret_key = SecretKey::new(&mut rng);
|
||||
out.extend_from_slice(
|
||||
&PublicKey::from_secret_key(SECP256K1, &secret_key).serialize_uncompressed(),
|
||||
);
|
||||
@ -198,11 +200,11 @@ impl ECIES {
|
||||
let mut key = [0u8; 32];
|
||||
kdf(x, &[], &mut key);
|
||||
|
||||
let enc_key = H128::from_slice(&key[..16]);
|
||||
let enc_key = B128::from_slice(&key[..16]);
|
||||
let mac_key = sha256(&key[16..32]);
|
||||
|
||||
let iv = H128::random();
|
||||
let mut encryptor = Ctr64BE::<Aes128>::new(enc_key.as_ref().into(), iv.as_ref().into());
|
||||
let iv: B128 = rng.gen();
|
||||
let mut encryptor = Ctr64BE::<Aes128>::new((&enc_key.0).into(), (&iv.0).into());
|
||||
|
||||
let mut encrypted = data.to_vec();
|
||||
encryptor.apply_keystream(&mut encrypted);
|
||||
@ -210,9 +212,9 @@ impl ECIES {
|
||||
let total_size: u16 = u16::try_from(65 + 16 + data.len() + 32).unwrap();
|
||||
|
||||
let tag =
|
||||
hmac_sha256(mac_key.as_ref(), &[iv.as_bytes(), &encrypted], &total_size.to_be_bytes());
|
||||
hmac_sha256(mac_key.as_ref(), &[iv.as_slice(), &encrypted], &total_size.to_be_bytes());
|
||||
|
||||
out.extend_from_slice(iv.as_bytes());
|
||||
out.extend_from_slice(iv.as_slice());
|
||||
out.extend_from_slice(&encrypted);
|
||||
out.extend_from_slice(tag.as_ref());
|
||||
}
|
||||
@ -223,12 +225,12 @@ impl ECIES {
|
||||
let public_key = PublicKey::from_slice(pubkey_bytes)?;
|
||||
let (data_iv, tag_bytes) = split_at_mut(encrypted, encrypted.len() - 32)?;
|
||||
let (iv, encrypted_data) = split_at_mut(data_iv, 16)?;
|
||||
let tag = H256::from_slice(tag_bytes);
|
||||
let tag = B256::from_slice(tag_bytes);
|
||||
|
||||
let x = ecdh_x(&public_key, &self.secret_key);
|
||||
let mut key = [0u8; 32];
|
||||
kdf(x, &[], &mut key);
|
||||
let enc_key = H128::from_slice(&key[..16]);
|
||||
let enc_key = B128::from_slice(&key[..16]);
|
||||
let mac_key = sha256(&key[16..32]);
|
||||
|
||||
let check_tag = hmac_sha256(mac_key.as_ref(), &[iv, encrypted_data], auth_data);
|
||||
@ -238,7 +240,7 @@ impl ECIES {
|
||||
|
||||
let decrypted_data = encrypted_data;
|
||||
|
||||
let mut decryptor = Ctr64BE::<Aes128>::new(enc_key.as_ref().into(), (*iv).into());
|
||||
let mut decryptor = Ctr64BE::<Aes128>::new((&enc_key.0).into(), (*iv).into());
|
||||
decryptor.apply_keystream(decrypted_data);
|
||||
|
||||
Ok(decrypted_data)
|
||||
@ -249,7 +251,7 @@ impl ECIES {
|
||||
let msg = x ^ self.nonce;
|
||||
let (rec_id, sig) = SECP256K1
|
||||
.sign_ecdsa_recoverable(
|
||||
&secp256k1::Message::from_slice(msg.as_bytes()).unwrap(),
|
||||
&secp256k1::Message::from_slice(msg.as_slice()).unwrap(),
|
||||
&self.ephemeral_secret_key,
|
||||
)
|
||||
.serialize_compact();
|
||||
@ -264,7 +266,7 @@ impl ECIES {
|
||||
struct S<'a> {
|
||||
sig_bytes: &'a [u8; 65],
|
||||
id: &'a PeerId,
|
||||
nonce: &'a H256,
|
||||
nonce: &'a B256,
|
||||
protocol_version: u8,
|
||||
}
|
||||
|
||||
@ -346,11 +348,11 @@ impl ECIES {
|
||||
#[derive(RlpEncodable, RlpMaxEncodedLen)]
|
||||
struct S {
|
||||
id: PeerId,
|
||||
nonce: H256,
|
||||
nonce: B256,
|
||||
protocol_version: u8,
|
||||
}
|
||||
|
||||
reth_rlp::encode_fixed_size(&S {
|
||||
alloy_rlp::encode_fixed_size(&S {
|
||||
id: pk2id(&self.ephemeral_public_key),
|
||||
nonce: self.nonce,
|
||||
protocol_version: PROTOCOL_VERSION as u8,
|
||||
@ -425,32 +427,30 @@ impl ECIES {
|
||||
} {
|
||||
hasher.update(el);
|
||||
}
|
||||
let h_nonce = H256::from(hasher.finalize().as_ref());
|
||||
let h_nonce = B256::from(hasher.finalize().as_ref());
|
||||
|
||||
let iv = H128::default();
|
||||
let shared_secret: H256 = {
|
||||
let iv = B128::default();
|
||||
let shared_secret: B256 = {
|
||||
let mut hasher = Keccak256::new();
|
||||
hasher.update(self.ephemeral_shared_secret.unwrap().0.as_ref());
|
||||
hasher.update(h_nonce.0.as_ref());
|
||||
H256::from(hasher.finalize().as_ref())
|
||||
B256::from(hasher.finalize().as_ref())
|
||||
};
|
||||
|
||||
let aes_secret: H256 = {
|
||||
let aes_secret: B256 = {
|
||||
let mut hasher = Keccak256::new();
|
||||
hasher.update(self.ephemeral_shared_secret.unwrap().0.as_ref());
|
||||
hasher.update(shared_secret.0.as_ref());
|
||||
H256::from(hasher.finalize().as_ref())
|
||||
B256::from(hasher.finalize().as_ref())
|
||||
};
|
||||
self.ingress_aes =
|
||||
Some(Ctr64BE::<Aes256>::new(aes_secret.0.as_ref().into(), iv.as_ref().into()));
|
||||
self.egress_aes =
|
||||
Some(Ctr64BE::<Aes256>::new(aes_secret.0.as_ref().into(), iv.as_ref().into()));
|
||||
self.ingress_aes = Some(Ctr64BE::<Aes256>::new((&aes_secret.0).into(), (&iv.0).into()));
|
||||
self.egress_aes = Some(Ctr64BE::<Aes256>::new((&aes_secret.0).into(), (&iv.0).into()));
|
||||
|
||||
let mac_secret: H256 = {
|
||||
let mac_secret: B256 = {
|
||||
let mut hasher = Keccak256::new();
|
||||
hasher.update(self.ephemeral_shared_secret.unwrap().0.as_ref());
|
||||
hasher.update(aes_secret.0.as_ref());
|
||||
H256::from(hasher.finalize().as_ref())
|
||||
B256::from(hasher.finalize().as_ref())
|
||||
};
|
||||
self.ingress_mac = Some(MAC::new(mac_secret));
|
||||
self.ingress_mac.as_mut().unwrap().update((mac_secret ^ self.nonce).as_ref());
|
||||
@ -484,13 +484,13 @@ impl ECIES {
|
||||
|
||||
out.reserve(ECIES::header_len());
|
||||
out.extend_from_slice(&header);
|
||||
out.extend_from_slice(tag.as_bytes());
|
||||
out.extend_from_slice(tag.as_slice());
|
||||
}
|
||||
|
||||
pub fn read_header(&mut self, data: &mut [u8]) -> Result<usize, ECIESError> {
|
||||
let (header_bytes, mac_bytes) = split_at_mut(data, 16)?;
|
||||
let header = HeaderBytes::from_mut_slice(header_bytes);
|
||||
let mac = H128::from_slice(&mac_bytes[..16]);
|
||||
let mac = B128::from_slice(&mac_bytes[..16]);
|
||||
|
||||
self.ingress_mac.as_mut().unwrap().update_header(header);
|
||||
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
|
||||
@ -538,12 +538,12 @@ impl ECIES {
|
||||
self.egress_mac.as_mut().unwrap().update_body(encrypted);
|
||||
let tag = self.egress_mac.as_mut().unwrap().digest();
|
||||
|
||||
out.extend_from_slice(tag.as_bytes());
|
||||
out.extend_from_slice(tag.as_slice());
|
||||
}
|
||||
|
||||
pub fn read_body<'a>(&mut self, data: &'a mut [u8]) -> Result<&'a mut [u8], ECIESError> {
|
||||
let (body, mac_bytes) = split_at_mut(data, data.len() - 16)?;
|
||||
let mac = H128::from_slice(mac_bytes);
|
||||
let mac = B128::from_slice(mac_bytes);
|
||||
self.ingress_mac.as_mut().unwrap().update_body(body);
|
||||
let check_mac = self.ingress_mac.as_mut().unwrap().digest();
|
||||
if check_mac != mac {
|
||||
@ -561,7 +561,7 @@ impl ECIES {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use hex_literal::hex;
|
||||
use reth_primitives::{b256, hex};
|
||||
|
||||
#[test]
|
||||
fn ecdh() {
|
||||
@ -573,15 +573,16 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
ecdh_x(&remote_public_key, &our_secret_key),
|
||||
hex!("821ce7e01ea11b111a52b2dafae8a3031a372d83bdf1a78109fa0783c2b9d5d3").into()
|
||||
hex!("821ce7e01ea11b111a52b2dafae8a3031a372d83bdf1a78109fa0783c2b9d5d3")
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn communicate() {
|
||||
let server_secret_key = SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
let mut rng = thread_rng();
|
||||
let server_secret_key = SecretKey::new(&mut rng);
|
||||
let server_public_key = PublicKey::from_secret_key(SECP256K1, &server_secret_key);
|
||||
let client_secret_key = SecretKey::new(&mut secp256k1::rand::thread_rng());
|
||||
let client_secret_key = SecretKey::new(&mut rng);
|
||||
|
||||
let mut server_ecies = ECIES::new_server(server_secret_key).unwrap();
|
||||
let mut client_ecies =
|
||||
@ -667,7 +668,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let client_nonce =
|
||||
H256(hex!("7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6"));
|
||||
b256!("7e968bba13b6c50e2c4cd7f241cc0d64d1ac25c7f5952df231ac6a2bda8ee5d6");
|
||||
|
||||
let server_id = pk2id(&PublicKey::from_secret_key(SECP256K1, &eip8_test_server_key()));
|
||||
|
||||
@ -682,7 +683,7 @@ mod tests {
|
||||
.unwrap();
|
||||
|
||||
let server_nonce =
|
||||
H256(hex!("559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd"));
|
||||
b256!("559aead08264d5795d3909718cdd05abd49572e84fe55590eef31a88a08fdffd");
|
||||
|
||||
ECIES::new_static_server(eip8_test_server_key(), server_nonce, server_ephemeral_key)
|
||||
.unwrap()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::{algorithm::ECIES, ECIESError, EgressECIESValue, IngressECIESValue};
|
||||
use reth_primitives::{bytes::BytesMut, H512 as PeerId};
|
||||
use reth_primitives::{bytes::BytesMut, B512 as PeerId};
|
||||
use secp256k1::SecretKey;
|
||||
use std::{fmt::Debug, io};
|
||||
use tokio_util::codec::{Decoder, Encoder};
|
||||
|
||||
@ -63,7 +63,7 @@ pub enum ECIESErrorImpl {
|
||||
Secp256k1(secp256k1::Error),
|
||||
/// Error when decoding RLP data
|
||||
#[error(transparent)]
|
||||
RLPDecoding(reth_rlp::DecodeError),
|
||||
RLPDecoding(alloy_rlp::Error),
|
||||
/// Error when converting to integer
|
||||
#[error(transparent)]
|
||||
FromInt(std::num::TryFromIntError),
|
||||
@ -111,8 +111,8 @@ impl From<secp256k1::Error> for ECIESError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<reth_rlp::DecodeError> for ECIESError {
|
||||
fn from(source: reth_rlp::DecodeError) -> Self {
|
||||
impl From<alloy_rlp::Error> for ECIESError {
|
||||
fn from(source: alloy_rlp::Error) -> Self {
|
||||
ECIESErrorImpl::RLPDecoding(source).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ mod codec;
|
||||
|
||||
use reth_primitives::{
|
||||
bytes::{Bytes, BytesMut},
|
||||
H512 as PeerId,
|
||||
B512 as PeerId,
|
||||
};
|
||||
|
||||
/// Raw egress values for an ECIES protocol
|
||||
|
||||
@ -4,7 +4,7 @@ use block_padding::NoPadding;
|
||||
use cipher::BlockEncrypt;
|
||||
use digest::KeyInit;
|
||||
use generic_array::GenericArray;
|
||||
use reth_primitives::{H128, H256};
|
||||
use reth_primitives::{B128, B256};
|
||||
use sha3::{Digest, Keccak256};
|
||||
use typenum::U16;
|
||||
|
||||
@ -19,13 +19,13 @@ pub type HeaderBytes = GenericArray<u8, U16>;
|
||||
/// and is not defined as a general MAC.
|
||||
#[derive(Debug)]
|
||||
pub struct MAC {
|
||||
secret: H256,
|
||||
secret: B256,
|
||||
hasher: Keccak256,
|
||||
}
|
||||
|
||||
impl MAC {
|
||||
/// Initialize the MAC with the given secret
|
||||
pub fn new(secret: H256) -> Self {
|
||||
pub fn new(secret: B256) -> Self {
|
||||
Self { secret, hasher: Keccak256::new() }
|
||||
}
|
||||
|
||||
@ -37,9 +37,9 @@ impl MAC {
|
||||
/// Accumulate the given [`HeaderBytes`] into the MAC's internal state.
|
||||
pub fn update_header(&mut self, data: &HeaderBytes) {
|
||||
let aes = Aes256Enc::new_from_slice(self.secret.as_ref()).unwrap();
|
||||
let mut encrypted = self.digest().to_fixed_bytes();
|
||||
let mut encrypted = self.digest().0;
|
||||
|
||||
aes.encrypt_padded::<NoPadding>(&mut encrypted, H128::len_bytes()).unwrap();
|
||||
aes.encrypt_padded::<NoPadding>(&mut encrypted, B128::len_bytes()).unwrap();
|
||||
for i in 0..data.len() {
|
||||
encrypted[i] ^= data[i];
|
||||
}
|
||||
@ -51,9 +51,9 @@ impl MAC {
|
||||
self.hasher.update(data);
|
||||
let prev = self.digest();
|
||||
let aes = Aes256Enc::new_from_slice(self.secret.as_ref()).unwrap();
|
||||
let mut encrypted = self.digest().to_fixed_bytes();
|
||||
let mut encrypted = self.digest().0;
|
||||
|
||||
aes.encrypt_padded::<NoPadding>(&mut encrypted, H128::len_bytes()).unwrap();
|
||||
aes.encrypt_padded::<NoPadding>(&mut encrypted, B128::len_bytes()).unwrap();
|
||||
for i in 0..16 {
|
||||
encrypted[i] ^= prev[i];
|
||||
}
|
||||
@ -62,7 +62,7 @@ impl MAC {
|
||||
|
||||
/// Produce a digest by finalizing the internal keccak256 hasher and returning the first 128
|
||||
/// bits.
|
||||
pub fn digest(&self) -> H128 {
|
||||
H128::from_slice(&self.hasher.clone().finalize()[..16])
|
||||
pub fn digest(&self) -> B128 {
|
||||
B128::from_slice(&self.hasher.clone().finalize()[..16])
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ use futures::{ready, Sink, SinkExt};
|
||||
use reth_net_common::stream::HasRemoteAddr;
|
||||
use reth_primitives::{
|
||||
bytes::{Bytes, BytesMut},
|
||||
H512 as PeerId,
|
||||
B512 as PeerId,
|
||||
};
|
||||
use secp256k1::SecretKey;
|
||||
use std::{
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
//! Utility functions for hashing and encoding.
|
||||
|
||||
use hmac::{Hmac, Mac};
|
||||
use reth_primitives::{H256, H512 as PeerId};
|
||||
use reth_primitives::{B256, B512 as PeerId};
|
||||
use secp256k1::PublicKey;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
/// Hashes the input data with SHA256.
|
||||
pub(crate) fn sha256(data: &[u8]) -> H256 {
|
||||
H256::from(Sha256::digest(data).as_ref())
|
||||
pub(crate) fn sha256(data: &[u8]) -> B256 {
|
||||
B256::from(Sha256::digest(data).as_ref())
|
||||
}
|
||||
|
||||
/// Produces a HMAC_SHA256 digest of the `input_data` and `auth_data` with the given `key`.
|
||||
/// This is done by accumulating each slice in `input_data` into the HMAC state, then accumulating
|
||||
/// the `auth_data` and returning the resulting digest.
|
||||
pub(crate) fn hmac_sha256(key: &[u8], input: &[&[u8]], auth_data: &[u8]) -> H256 {
|
||||
pub(crate) fn hmac_sha256(key: &[u8], input: &[&[u8]], auth_data: &[u8]) -> B256 {
|
||||
let mut hmac = Hmac::<Sha256>::new_from_slice(key).unwrap();
|
||||
for input in input {
|
||||
hmac.update(input);
|
||||
}
|
||||
hmac.update(auth_data);
|
||||
H256::from_slice(&hmac.finalize().into_bytes())
|
||||
B256::from_slice(&hmac.finalize().into_bytes())
|
||||
}
|
||||
|
||||
/// Converts a [secp256k1::PublicKey] to a [PeerId] by stripping the
|
||||
@ -31,13 +31,13 @@ pub fn pk2id(pk: &PublicKey) -> PeerId {
|
||||
/// Converts a [PeerId] to a [secp256k1::PublicKey] by prepending the [PeerId] bytes with the
|
||||
/// SECP256K1_TAG_PUBKEY_UNCOMPRESSED tag.
|
||||
pub(crate) fn id2pk(id: PeerId) -> Result<PublicKey, secp256k1::Error> {
|
||||
// NOTE: H512 is used as a PeerId not because it represents a hash, but because 512 bits is
|
||||
// NOTE: B512 is used as a PeerId not because it represents a hash, but because 512 bits is
|
||||
// enough to represent an uncompressed public key.
|
||||
let mut s = [0u8; 65];
|
||||
// SECP256K1_TAG_PUBKEY_UNCOMPRESSED = 0x04
|
||||
// see: https://github.com/bitcoin-core/secp256k1/blob/master/include/secp256k1.h#L211
|
||||
s[0] = 4;
|
||||
s[1..].copy_from_slice(id.as_bytes());
|
||||
s[1..].copy_from_slice(id.as_slice());
|
||||
PublicKey::from_slice(&s)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user