From 1ef7be0af6ee410d7456a036fd9df396cf681b48 Mon Sep 17 00:00:00 2001 From: Sergio Chouhy Date: Tue, 15 Jul 2025 15:48:59 -0300 Subject: [PATCH] add pem feature to k256 and remove manual impls of Serialize and Deserialize --- Cargo.lock | 11 +++++++ Cargo.toml | 2 +- accounts/src/key_management/mod.rs | 18 ++++++++++- common/src/transaction.rs | 48 +++++++++++++++++++++--------- node_core/src/chain_storage/mod.rs | 2 +- node_core/src/lib.rs | 35 +++++----------------- sequencer_core/src/lib.rs | 2 +- 7 files changed, 72 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c19ab6f..554d101 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1247,6 +1247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ "const-oid", + "pem-rfc7468", "zeroize", ] @@ -1486,6 +1487,7 @@ dependencies = [ "ff", "generic-array", "group", + "pem-rfc7468", "pkcs8", "rand_core 0.6.4", "sec1", @@ -3196,6 +3198,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" diff --git a/Cargo.toml b/Cargo.toml index 7af2e24..0419f1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -55,7 +55,7 @@ features = ["std", "std_rng", "getrandom"] version = "0.8.5" [workspace.dependencies.k256] -features = ["ecdsa-core", "arithmetic", "expose-field", "serde"] +features = ["ecdsa-core", "arithmetic", "expose-field", "serde", "pem"] version = "0.13.4" [workspace.dependencies.elliptic-curve] diff --git a/accounts/src/key_management/mod.rs b/accounts/src/key_management/mod.rs index 69b8ce0..2598294 100644 --- a/accounts/src/key_management/mod.rs +++ b/accounts/src/key_management/mod.rs @@ -3,12 +3,14 @@ use common::merkle_tree_public::TreeHashType; use constants_types::{CipherText, Nonce}; use elliptic_curve::point::AffineCoordinates; use ephemeral_key_holder::EphemeralKeyHolder; -use k256::AffinePoint; +use k256::{ecdsa::SigningKey, AffinePoint, FieldBytes}; use log::info; +use rand::{rngs::OsRng, RngCore}; use secret_holders::{SeedHolder, TopSecretKeyHolder, UTXOSecretKeyHolder}; use serde::{Deserialize, Serialize}; use crate::account_core::PublicKey; +pub type PublicAccountSecretKey = [u8; 32]; pub mod constants_types; pub mod ephemeral_key_holder; @@ -21,6 +23,7 @@ pub struct AddressKeyHolder { #[allow(dead_code)] top_secret_key_holder: TopSecretKeyHolder, pub utxo_secret_key_holder: UTXOSecretKeyHolder, + pub pub_account_secret_key: PublicAccountSecretKey, pub address: TreeHashType, pub nullifer_public_key: PublicKey, pub viewing_public_key: PublicKey, @@ -39,15 +42,28 @@ impl AddressKeyHolder { let nullifer_public_key = utxo_secret_key_holder.generate_nullifier_public_key(); let viewing_public_key = utxo_secret_key_holder.generate_viewing_public_key(); + let pub_account_secret_key = { + let mut bytes = [0; 32]; + OsRng.fill_bytes(&mut bytes); + bytes + }; + Self { top_secret_key_holder, utxo_secret_key_holder, address, nullifer_public_key, viewing_public_key, + pub_account_secret_key, } } + pub fn pub_account_secret_key(&self) -> SigningKey { + let field_bytes = FieldBytes::from_slice(&self.pub_account_secret_key); + // TODO: remove unwrap + SigningKey::from_bytes(&field_bytes).unwrap() + } + pub fn calculate_shared_secret_receiver( &self, ephemeral_public_key_sender: AffinePoint, diff --git a/common/src/transaction.rs b/common/src/transaction.rs index 1544d67..ee832c7 100644 --- a/common/src/transaction.rs +++ b/common/src/transaction.rs @@ -1,8 +1,17 @@ -use k256::Scalar; +use k256::{ + ecdsa::{ + signature::{Signer, Verifier}, + Signature, SigningKey, VerifyingKey, + }, + EncodedPoint, Scalar, +}; use log::info; use secp256k1_zkp::{PedersenCommitment, Tweak}; -use serde::{Deserialize, Serialize}; +use serde::de::{Error as DeError, Visitor}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use sha2::{digest::FixedOutput, Digest}; +use std::fmt; use crate::merkle_tree_public::TreeHashType; @@ -217,10 +226,9 @@ impl TransactionBody { } } -pub type SignaturePrivateKey = Scalar; - -#[derive(Debug, Serialize, Deserialize, Clone)] -struct TransactionSignature; +pub type SignaturePrivateKey = SigningKey; +pub type SignaturePublicKey = VerifyingKey; +pub type TransactionSignature = Signature; type TransactionHash = TreeHashType; @@ -229,24 +237,36 @@ type TransactionHash = TreeHashType; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct SignedTransaction { pub body: TransactionBody, - signature: TransactionSignature, + signature: (TransactionSignature, SignaturePublicKey), } impl SignedTransaction { pub fn from_transaction_body( body: TransactionBody, - _private_key: SignaturePrivateKey, + private_key: SignaturePrivateKey, ) -> SignedTransaction { - let _hash = body.hash(); + let hash = body.hash(); + let signature: Signature = private_key.sign(&hash); // TODO: Implement actual signature over `hash` - let signature = TransactionSignature {}; - Self { body, signature } + let public_key = VerifyingKey::from(&private_key); + Self { + body, + signature: (signature, public_key), + } } pub fn into_authenticated(self) -> Result { let hash = self.body.hash(); - // TODO: Check signature over hash - Err(TransactionSignatureError::InvalidSignature) + let (signature, public_key) = &self.signature; + + public_key + .verify(&hash, signature) + .map_err(|_| TransactionSignatureError::InvalidSignature)?; + + Ok(AuthenticatedTransaction { + hash, + signed_tx: self, + }) } } @@ -269,7 +289,7 @@ impl AuthenticatedTransaction { } pub fn signature(&self) -> &TransactionSignature { - &self.signed_tx.signature + &self.signed_tx.signature.0 } pub fn hash(&self) -> &TransactionHash { diff --git a/node_core/src/chain_storage/mod.rs b/node_core/src/chain_storage/mod.rs index 04ba03a..bb8641a 100644 --- a/node_core/src/chain_storage/mod.rs +++ b/node_core/src/chain_storage/mod.rs @@ -320,7 +320,7 @@ mod tests { sc_addr: "sc_addr".to_string(), state_changes: (serde_json::Value::Null, 0), }; - SignedTransaction::from_transaction_body(body, SignaturePrivateKey::ONE) + SignedTransaction::from_transaction_body(body, SignaturePrivateKey::random(&mut rng)) } fn create_sample_block(block_id: u64, prev_block_id: u64) -> Block { diff --git a/node_core/src/lib.rs b/node_core/src/lib.rs index 04aa467..7812614 100644 --- a/node_core/src/lib.rs +++ b/node_core/src/lib.rs @@ -265,10 +265,7 @@ impl NodeCore { state_changes, }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), @@ -366,10 +363,7 @@ impl NodeCore { state_changes, }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), @@ -487,10 +481,7 @@ impl NodeCore { }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), @@ -637,10 +628,7 @@ impl NodeCore { }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), @@ -771,10 +759,7 @@ impl NodeCore { }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), @@ -866,10 +851,7 @@ impl NodeCore { }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(SignedTransaction::from_transaction_body( transaction_body, @@ -1512,10 +1494,7 @@ impl NodeCore { state_changes, }; // TODO: Change to the correct key once established. - let key_to_sign_transaction = account - .key_holder - .utxo_secret_key_holder - .nullifier_secret_key; + let key_to_sign_transaction = account.key_holder.pub_account_secret_key(); Ok(( SignedTransaction::from_transaction_body(transaction_body, key_to_sign_transaction), diff --git a/sequencer_core/src/lib.rs b/sequencer_core/src/lib.rs index d480670..f812ea0 100644 --- a/sequencer_core/src/lib.rs +++ b/sequencer_core/src/lib.rs @@ -311,7 +311,7 @@ mod tests { sc_addr: "sc_addr".to_string(), state_changes: (serde_json::Value::Null, 0), }; - SignedTransaction::from_transaction_body(body, SignaturePrivateKey::ONE) + SignedTransaction::from_transaction_body(body, SignaturePrivateKey::random(&mut rng)) } fn common_setup(sequencer: &mut SequencerCore) {