From 71cc5ed739636f9bcf33cd218b4e37de7e71afdb Mon Sep 17 00:00:00 2001 From: Nate Maninger Date: Tue, 2 Apr 2024 22:54:17 -0700 Subject: [PATCH] transaction fixes --- src/address.rs | 13 ++++++------- src/lib.rs | 2 +- src/signing.rs | 47 ++++++++++++++++++++++++++++++++++++++++++++- src/transactions.rs | 15 ++++++++------- 4 files changed, 61 insertions(+), 16 deletions(-) diff --git a/src/address.rs b/src/address.rs index 4d62c46..30fff2d 100644 --- a/src/address.rs +++ b/src/address.rs @@ -3,8 +3,8 @@ use core::fmt; use crate::blake2b::Accumulator; use blake2b_simd::Params; use crate::blake2b::LEAF_HASH_PREFIX; -use crate::{SiaEncodable, HexParseError}; -use ed25519_dalek::{SigningKey, Signer, VerifyingKey, Verifier, Signature}; +use crate::{SiaEncodable, HexParseError, Signature}; +use ed25519_dalek::{SigningKey, Signer, VerifyingKey, Verifier}; /// An ed25519 public key that can be used to verify a signature #[derive(Debug, PartialEq, Clone, Copy)] @@ -15,10 +15,9 @@ impl PublicKey { self.0 } - pub fn verify_hash(&self, hash: &[u8;32], signature: &[u8;64]) -> bool { + pub fn verify_hash(&self, hash: &[u8;32], signature: Signature) -> bool { let pk = VerifyingKey::from_bytes(&self.0).unwrap(); - let sig = Signature::from_bytes(signature); - pk.verify(hash, &sig).is_ok() + pk.verify(hash, &signature.into()).is_ok() } } @@ -40,9 +39,9 @@ impl PrivateKey { PublicKey(self.0[32..].try_into().unwrap()) } - pub fn sign_hash(&self, hash: &[u8;32]) -> [u8;64] { + pub fn sign_hash(&self, hash: &[u8;32]) -> Signature { let sk = SigningKey::from_bytes(&self.0[..32].try_into().unwrap()); - sk.sign(hash).to_bytes() + Signature::new(sk.sign(hash).to_vec()) } } diff --git a/src/lib.rs b/src/lib.rs index 7a683bb..8697ea9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,7 +31,7 @@ pub enum HexParseError { HexError(hex::FromHexError), } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct Hash256([u8;32]); impl Hash256 { diff --git a/src/signing.rs b/src/signing.rs index bb5bc72..3f14a3c 100644 --- a/src/signing.rs +++ b/src/signing.rs @@ -1,7 +1,9 @@ +use core::fmt; + use crate::consensus::ChainIndex; use crate::transactions::{Transaction, CoveredFields}; use blake2b_simd::Params; -use crate::SiaEncodable; +use crate::{HexParseError, SiaEncodable}; pub struct NetworkHardforks { pub asic_height: u64, @@ -17,6 +19,49 @@ pub struct SigningState { hardforks: NetworkHardforks, } +#[derive(Debug, Clone)] +pub struct Signature(Vec); + +impl Signature { + pub fn new(data: Vec) -> Self { + Signature(data) + } + + pub fn data(&self) -> &[u8] { + &self.0 + } + + pub fn parse_string(s: &str) -> Result { + let s = match s.split_once(":"){ + Some((_prefix, suffix)) => suffix, + None => s + }; + + let data = hex::decode(s).map_err(|e| HexParseError::HexError(e))?; + Ok(Signature(data)) + } +} + +impl Into for Signature { + fn into(self) -> ed25519_dalek::Signature { + ed25519_dalek::Signature::from_bytes(self.0.as_slice().try_into().unwrap()) + } + +} + +impl SiaEncodable for Signature { + fn encode(&self, buf: &mut Vec) { + buf.extend_from_slice(&(self.0.len() as u64).to_le_bytes()); + buf.extend_from_slice(&self.0); + } +} + +impl fmt::Display for Signature { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "sig:{}", hex::encode(&self.0)) + } +} + impl SigningState { pub fn new(index: ChainIndex, hardforks: NetworkHardforks) -> Self { SigningState { diff --git a/src/transactions.rs b/src/transactions.rs index bd18fd3..df7951b 100644 --- a/src/transactions.rs +++ b/src/transactions.rs @@ -1,7 +1,8 @@ use core::fmt; -use crate::currency::Currency; -use crate::address::{Address, UnlockConditions}; +use crate::Signature; +use crate::Currency; +use crate::{Address, UnlockConditions}; use crate::{HexParseError, Hash256, SiaEncodable}; use blake2b_simd::{Params, State}; @@ -318,21 +319,21 @@ impl SiaEncodable for CoveredFields { } #[derive(Debug, Clone)] -pub struct Signature { +pub struct TransactionSignature { pub parent_id: Hash256, pub public_key_index: u64, pub timelock: u64, pub covered_fields: CoveredFields, - pub signature: [u8;64], + pub signature: Signature, } -impl SiaEncodable for Signature { +impl SiaEncodable for TransactionSignature { fn encode(&self, buf: &mut Vec) { buf.extend_from_slice(&self.parent_id.as_bytes()); buf.extend_from_slice(&self.public_key_index.to_le_bytes()); buf.extend_from_slice(&self.timelock.to_le_bytes()); self.covered_fields.encode(buf); - buf.extend_from_slice(&self.signature); + self.signature.encode(buf); } } @@ -372,7 +373,7 @@ pub struct Transaction { pub file_contracts: Vec, pub file_contract_revisions: Vec, pub storage_proofs: Vec, - pub signatures: Vec, + pub signatures: Vec, pub arbitrary_data: Vec>, }