Add Signature wrapper and supporting traits
This commit is contained in:
parent
7ccd771ccc
commit
4d77fa900b
|
@ -3,7 +3,6 @@ extern crate bincode;
|
||||||
extern crate bs58;
|
extern crate bs58;
|
||||||
extern crate clap;
|
extern crate clap;
|
||||||
extern crate dirs;
|
extern crate dirs;
|
||||||
extern crate generic_array;
|
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
extern crate solana;
|
extern crate solana;
|
||||||
|
|
||||||
|
@ -196,7 +195,7 @@ fn parse_args() -> Result<WalletConfig, Box<error::Error>> {
|
||||||
.expect("base58-encoded signature");
|
.expect("base58-encoded signature");
|
||||||
|
|
||||||
if sig_vec.len() == std::mem::size_of::<Signature>() {
|
if sig_vec.len() == std::mem::size_of::<Signature>() {
|
||||||
let sig = Signature::clone_from_slice(&sig_vec);
|
let sig = Signature::new(&sig_vec);
|
||||||
Ok(WalletCommand::Confirm(sig))
|
Ok(WalletCommand::Confirm(sig))
|
||||||
} else {
|
} else {
|
||||||
display_actions();
|
display_actions();
|
||||||
|
@ -277,7 +276,7 @@ fn process_command(
|
||||||
WalletCommand::Pay(tokens, to) => {
|
WalletCommand::Pay(tokens, to) => {
|
||||||
let last_id = client.get_last_id();
|
let last_id = client.get_last_id();
|
||||||
let sig = client.transfer(tokens, &config.id, to, &last_id)?;
|
let sig = client.transfer(tokens, &config.id, to, &last_id)?;
|
||||||
println!("{}", bs58::encode(sig).into_string());
|
println!("{}", sig);
|
||||||
}
|
}
|
||||||
// Confirm the last client transaction by signature
|
// Confirm the last client transaction by signature
|
||||||
WalletCommand::Confirm(sig) => {
|
WalletCommand::Confirm(sig) => {
|
||||||
|
|
|
@ -139,7 +139,7 @@ impl Entry {
|
||||||
|
|
||||||
fn add_transaction_data(hash_data: &mut Vec<u8>, tx: &Transaction) {
|
fn add_transaction_data(hash_data: &mut Vec<u8>, tx: &Transaction) {
|
||||||
hash_data.push(0u8);
|
hash_data.push(0u8);
|
||||||
hash_data.extend_from_slice(&tx.sig);
|
hash_data.extend_from_slice(&tx.sig.as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates the hash `num_hashes` after `start_hash`. If the transaction contains
|
/// Creates the hash `num_hashes` after `start_hash`. If the transaction contains
|
||||||
|
|
|
@ -41,7 +41,38 @@ impl fmt::Display for PublicKey {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Signature = GenericArray<u8, U64>;
|
#[derive(Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||||
|
pub struct Signature(GenericArray<u8, U64>);
|
||||||
|
|
||||||
|
impl Signature {
|
||||||
|
pub fn new(signature_slice: &[u8]) -> Self {
|
||||||
|
Signature(GenericArray::clone_from_slice(&signature_slice))
|
||||||
|
}
|
||||||
|
pub fn verify(&self, peer_public_key_bytes: &[u8], msg_bytes: &[u8]) -> bool {
|
||||||
|
let peer_public_key = Input::from(peer_public_key_bytes);
|
||||||
|
let msg = Input::from(msg_bytes);
|
||||||
|
let sig = Input::from(self.0.as_slice());
|
||||||
|
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRef<[u8]> for Signature {
|
||||||
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
&self.0[..]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Signature {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", bs58::encode(self.0).into_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Signature {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "{}", bs58::encode(self.0).into_string())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub trait KeyPairUtil {
|
pub trait KeyPairUtil {
|
||||||
fn new() -> Self;
|
fn new() -> Self;
|
||||||
|
@ -62,19 +93,6 @@ impl KeyPairUtil for Ed25519KeyPair {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait SignatureUtil {
|
|
||||||
fn verify(&self, peer_public_key_bytes: &[u8], msg_bytes: &[u8]) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SignatureUtil for GenericArray<u8, U64> {
|
|
||||||
fn verify(&self, peer_public_key_bytes: &[u8], msg_bytes: &[u8]) -> bool {
|
|
||||||
let peer_public_key = Input::from(peer_public_key_bytes);
|
|
||||||
let msg = Input::from(msg_bytes);
|
|
||||||
let sig = Input::from(self);
|
|
||||||
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct GenKeys {
|
pub struct GenKeys {
|
||||||
generator: ChaChaRng,
|
generator: ChaChaRng,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use budget::{Budget, Condition};
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use hash::Hash;
|
use hash::Hash;
|
||||||
use payment_plan::{Payment, PaymentPlan, Witness};
|
use payment_plan::{Payment, PaymentPlan, Witness};
|
||||||
use signature::{KeyPair, KeyPairUtil, PublicKey, Signature, SignatureUtil};
|
use signature::{KeyPair, KeyPairUtil, PublicKey, Signature};
|
||||||
|
|
||||||
pub const SIGNED_DATA_OFFSET: usize = 112;
|
pub const SIGNED_DATA_OFFSET: usize = 112;
|
||||||
pub const SIG_OFFSET: usize = 8;
|
pub const SIG_OFFSET: usize = 8;
|
||||||
|
@ -186,7 +186,7 @@ impl Transaction {
|
||||||
/// Sign this transaction.
|
/// Sign this transaction.
|
||||||
pub fn sign(&mut self, keypair: &KeyPair) {
|
pub fn sign(&mut self, keypair: &KeyPair) {
|
||||||
let sign_data = self.get_sign_data();
|
let sign_data = self.get_sign_data();
|
||||||
self.sig = Signature::clone_from_slice(keypair.sign(&sign_data).as_ref());
|
self.sig = Signature::new(keypair.sign(&sign_data).as_ref());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify only the transaction signature.
|
/// Verify only the transaction signature.
|
||||||
|
@ -317,7 +317,7 @@ mod tests {
|
||||||
let sign_data = tx.get_sign_data();
|
let sign_data = tx.get_sign_data();
|
||||||
let tx_bytes = serialize(&tx).unwrap();
|
let tx_bytes = serialize(&tx).unwrap();
|
||||||
assert_matches!(memfind(&tx_bytes, &sign_data), Some(SIGNED_DATA_OFFSET));
|
assert_matches!(memfind(&tx_bytes, &sign_data), Some(SIGNED_DATA_OFFSET));
|
||||||
assert_matches!(memfind(&tx_bytes, &tx.sig), Some(SIG_OFFSET));
|
assert_matches!(memfind(&tx_bytes, &tx.sig.as_ref()), Some(SIG_OFFSET));
|
||||||
assert_matches!(memfind(&tx_bytes, &tx.from.as_ref()), Some(PUB_KEY_OFFSET));
|
assert_matches!(memfind(&tx_bytes, &tx.from.as_ref()), Some(PUB_KEY_OFFSET));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue