Move Event into its own crate
The log crate was starting to be the catch-all for all things related to entries, events, signatures, and hashes. This split shows us that: * Event depends only on signatures, not on hashes [directly] * All event testing was done via log testing (shame on me) * Accounting depends only on events
This commit is contained in:
98
src/log.rs
98
src/log.rs
@@ -14,13 +14,11 @@
|
||||
/// was generated by the fastest processor at the time the entry was logged.
|
||||
|
||||
use generic_array::GenericArray;
|
||||
use generic_array::typenum::{U32, U64};
|
||||
use ring::signature::Ed25519KeyPair;
|
||||
use generic_array::typenum::U32;
|
||||
use serde::Serialize;
|
||||
use event::*;
|
||||
|
||||
pub type Sha256Hash = GenericArray<u8, U32>;
|
||||
pub type PublicKey = GenericArray<u8, U32>;
|
||||
pub type Signature = GenericArray<u8, U64>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Entry<T> {
|
||||
@@ -29,27 +27,6 @@ pub struct Entry<T> {
|
||||
pub event: Event<T>,
|
||||
}
|
||||
|
||||
/// When 'event' is Tick, the event represents a simple clock tick, and exists for the
|
||||
/// sole purpose of improving the performance of event log verification. A tick can
|
||||
/// be generated in 'num_hashes' hashes and verified in 'num_hashes' hashes. By logging
|
||||
/// a hash alongside the tick, each tick and be verified in parallel using the 'end_hash'
|
||||
/// of the preceding tick to seed its hashing.
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Event<T> {
|
||||
Tick,
|
||||
Claim {
|
||||
key: PublicKey,
|
||||
data: T,
|
||||
sig: Signature,
|
||||
},
|
||||
Transaction {
|
||||
from: PublicKey,
|
||||
to: PublicKey,
|
||||
data: T,
|
||||
sig: Signature,
|
||||
},
|
||||
}
|
||||
|
||||
impl<T> Entry<T> {
|
||||
/// Creates a Entry from the number of hashes 'num_hashes' since the previous event
|
||||
/// and that resulting 'end_hash'.
|
||||
@@ -62,36 +39,6 @@ impl<T> Entry<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a new ED25519 keypair
|
||||
pub fn generate_keypair() -> Ed25519KeyPair {
|
||||
use ring::{rand, signature};
|
||||
use untrusted;
|
||||
let rng = rand::SystemRandom::new();
|
||||
let pkcs8_bytes = signature::Ed25519KeyPair::generate_pkcs8(&rng).unwrap();
|
||||
signature::Ed25519KeyPair::from_pkcs8(untrusted::Input::from(&pkcs8_bytes)).unwrap()
|
||||
}
|
||||
|
||||
/// Return the public key for the given keypair
|
||||
pub fn get_pubkey(keypair: &Ed25519KeyPair) -> PublicKey {
|
||||
GenericArray::clone_from_slice(keypair.public_key_bytes())
|
||||
}
|
||||
|
||||
/// Return a signature for the given data using the private key from the given keypair.
|
||||
pub fn sign_serialized<T: Serialize>(data: &T, keypair: &Ed25519KeyPair) -> Signature {
|
||||
use bincode::serialize;
|
||||
let serialized = serialize(data).unwrap();
|
||||
GenericArray::clone_from_slice(keypair.sign(&serialized).as_ref())
|
||||
}
|
||||
|
||||
/// Return a signature for the given transaction data using the private key from the given keypair.
|
||||
pub fn sign_transaction_data<T: Serialize>(
|
||||
data: &T,
|
||||
keypair: &Ed25519KeyPair,
|
||||
to: &PublicKey,
|
||||
) -> Signature {
|
||||
sign_serialized(&(data, to), keypair)
|
||||
}
|
||||
|
||||
/// Return a Sha256 hash for the given data.
|
||||
pub fn hash(val: &[u8]) -> Sha256Hash {
|
||||
use sha2::{Digest, Sha256};
|
||||
@@ -107,14 +54,6 @@ pub fn extend_and_hash(end_hash: &Sha256Hash, val: &[u8]) -> Sha256Hash {
|
||||
hash(&hash_data)
|
||||
}
|
||||
|
||||
pub fn get_signature<T>(event: &Event<T>) -> Option<Signature> {
|
||||
match *event {
|
||||
Event::Tick => None,
|
||||
Event::Claim { sig, .. } => Some(sig),
|
||||
Event::Transaction { sig, .. } => Some(sig),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn hash_event<T>(end_hash: &Sha256Hash, event: &Event<T>) -> Sha256Hash {
|
||||
match get_signature(event) {
|
||||
None => *end_hash,
|
||||
@@ -164,29 +103,6 @@ pub fn next_tick<T: Serialize>(start_hash: &Sha256Hash, num_hashes: u64) -> Entr
|
||||
next_entry(start_hash, num_hashes, Event::Tick)
|
||||
}
|
||||
|
||||
pub fn verify_event<T: Serialize>(event: &Event<T>) -> bool {
|
||||
use bincode::serialize;
|
||||
if let Event::Claim { key, ref data, sig } = *event {
|
||||
let mut claim_data = serialize(&data).unwrap();
|
||||
if !verify_signature(&key, &claim_data, &sig) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if let Event::Transaction {
|
||||
from,
|
||||
to,
|
||||
ref data,
|
||||
sig,
|
||||
} = *event
|
||||
{
|
||||
let sign_data = serialize(&(&data, &to)).unwrap();
|
||||
if !verify_signature(&from, &sign_data, &sig) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
/// Verifies self.end_hash is the result of hashing a 'start_hash' 'self.num_hashes' times.
|
||||
/// If the event is not a Tick, then hash that as well.
|
||||
pub fn verify_entry<T: Serialize>(entry: &Entry<T>, start_hash: &Sha256Hash) -> bool {
|
||||
@@ -219,16 +135,6 @@ pub fn verify_slice_seq<T: Serialize>(events: &[Entry<T>], start_hash: &Sha256Ha
|
||||
event_pairs.all(|(x0, x1)| verify_entry(&x1, &x0.end_hash))
|
||||
}
|
||||
|
||||
/// Verify a signed message with the given public key.
|
||||
pub fn verify_signature(peer_public_key_bytes: &[u8], msg_bytes: &[u8], sig_bytes: &[u8]) -> bool {
|
||||
use untrusted;
|
||||
use ring::signature;
|
||||
let peer_public_key = untrusted::Input::from(peer_public_key_bytes);
|
||||
let msg = untrusted::Input::from(msg_bytes);
|
||||
let sig = untrusted::Input::from(sig_bytes);
|
||||
signature::verify(&signature::ED25519, peer_public_key, msg, sig).is_ok()
|
||||
}
|
||||
|
||||
pub fn create_entries<T: Serialize>(
|
||||
start_hash: &Sha256Hash,
|
||||
num_hashes: u64,
|
||||
|
Reference in New Issue
Block a user