1414/// was generated by the fastest processor at the time the entry was logged.
1515
1616use generic_array:: GenericArray ;
17- use generic_array:: typenum:: U32 ;
17+ use generic_array:: typenum:: { U32 , U64 } ;
18+ use ring:: signature:: Ed25519KeyPair ;
1819pub type Sha256Hash = GenericArray < u8 , U32 > ;
20+ pub type PublicKey = GenericArray < u8 , U32 > ;
21+ pub type Signature = GenericArray < u8 , U64 > ;
1922
2023#[ derive( Serialize , Deserialize , Debug , PartialEq , Eq , Clone ) ]
2124pub struct Entry {
@@ -32,7 +35,12 @@ pub struct Entry {
3235#[ derive( Serialize , Deserialize , Debug , PartialEq , Eq , Clone ) ]
3336pub enum Event {
3437 Tick ,
35- UserDataKey ( Sha256Hash ) ,
38+ Discovery ( Sha256Hash ) ,
39+ Claim {
40+ key : PublicKey ,
41+ data : Sha256Hash ,
42+ sig : Signature ,
43+ } ,
3644}
3745
3846impl Entry {
@@ -47,12 +55,30 @@ impl Entry {
4755 }
4856
4957 /// Verifies self.end_hash is the result of hashing a 'start_hash' 'self.num_hashes' times.
50- /// If the event is a UserDataKey , then hash that as well.
58+ /// If the event is not a Tick , then hash that as well.
5159 pub fn verify ( self : & Self , start_hash : & Sha256Hash ) -> bool {
60+ if let Event :: Claim { key, data, sig } = self . event {
61+ if !verify_signature ( & key, & data, & sig) {
62+ return false ;
63+ }
64+ }
5265 self . end_hash == next_hash ( start_hash, self . num_hashes , & self . event )
5366 }
5467}
5568
69+ /// Return a Claim Event for the given hash and key-pair.
70+ pub fn sign_hash ( data : & Sha256Hash , key_pair : & Ed25519KeyPair ) -> Event {
71+ let sig = key_pair. sign ( data) ;
72+ let peer_public_key_bytes = key_pair. public_key_bytes ( ) ;
73+ let sig_bytes = sig. as_ref ( ) ;
74+ Event :: Claim {
75+ key : GenericArray :: clone_from_slice ( peer_public_key_bytes) ,
76+ data : GenericArray :: clone_from_slice ( data) ,
77+ sig : GenericArray :: clone_from_slice ( sig_bytes) ,
78+ }
79+ }
80+
81+ /// Return a Sha256 hash for the given data.
5682pub fn hash ( val : & [ u8 ] ) -> Sha256Hash {
5783 use sha2:: { Digest , Sha256 } ;
5884 let mut hasher = Sha256 :: default ( ) ;
@@ -61,21 +87,32 @@ pub fn hash(val: &[u8]) -> Sha256Hash {
6187}
6288
6389/// Return the hash of the given hash extended with the given value.
64- pub fn extend_and_hash ( end_hash : & Sha256Hash , val : & [ u8 ] ) -> Sha256Hash {
90+ pub fn extend_and_hash ( end_hash : & Sha256Hash , ty : u8 , val : & [ u8 ] ) -> Sha256Hash {
6591 let mut hash_data = end_hash. to_vec ( ) ;
92+ hash_data. push ( ty) ;
6693 hash_data. extend_from_slice ( val) ;
6794 hash ( & hash_data)
6895}
6996
97+ pub fn hash_event ( end_hash : & Sha256Hash , event : & Event ) -> Sha256Hash {
98+ match * event {
99+ Event :: Tick => * end_hash,
100+ Event :: Discovery ( data) => extend_and_hash ( end_hash, 1 , & data) ,
101+ Event :: Claim { key, data, sig } => {
102+ let mut event_data = data. to_vec ( ) ;
103+ event_data. extend_from_slice ( & sig) ;
104+ event_data. extend_from_slice ( & key) ;
105+ extend_and_hash ( end_hash, 2 , & event_data)
106+ }
107+ }
108+ }
109+
70110pub fn next_hash ( start_hash : & Sha256Hash , num_hashes : u64 , event : & Event ) -> Sha256Hash {
71111 let mut end_hash = * start_hash;
72112 for _ in 0 ..num_hashes {
73113 end_hash = hash ( & end_hash) ;
74114 }
75- if let Event :: UserDataKey ( key) = * event {
76- return extend_and_hash ( & end_hash, & key) ;
77- }
78- end_hash
115+ hash_event ( & end_hash, event)
79116}
80117
81118/// Creates the next Tick Entry 'num_hashes' after 'start_hash'.
@@ -107,6 +144,16 @@ pub fn verify_slice_seq(events: &[Entry], start_hash: &Sha256Hash) -> bool {
107144 event_pairs. all ( |( x0, x1) | x1. verify ( & x0. end_hash ) )
108145}
109146
147+ /// Verify a signed message with the given public key.
148+ pub fn verify_signature ( peer_public_key_bytes : & [ u8 ] , msg_bytes : & [ u8 ] , sig_bytes : & [ u8 ] ) -> bool {
149+ use untrusted;
150+ use ring:: signature;
151+ let peer_public_key = untrusted:: Input :: from ( peer_public_key_bytes) ;
152+ let msg = untrusted:: Input :: from ( msg_bytes) ;
153+ let sig = untrusted:: Input :: from ( sig_bytes) ;
154+ signature:: verify ( & signature:: ED25519 , peer_public_key, msg, sig) . is_ok ( )
155+ }
156+
110157/// Create a vector of Ticks of length 'len' from 'start_hash' hash and 'num_hashes'.
111158pub fn create_ticks ( start_hash : & Sha256Hash , num_hashes : u64 , len : usize ) -> Vec < Entry > {
112159 use std:: iter;
@@ -169,9 +216,9 @@ mod tests {
169216 let zero = Sha256Hash :: default ( ) ;
170217 let one = hash ( & zero) ;
171218
172- // First, verify UserData events
219+ // First, verify Discovery events
173220 let mut end_hash = zero;
174- let events = [ Event :: UserDataKey ( zero) , Event :: UserDataKey ( one) ] ;
221+ let events = [ Event :: Discovery ( zero) , Event :: Discovery ( one) ] ;
175222 let mut entries: Vec < Entry > = events
176223 . iter ( )
177224 . map ( |event| {
@@ -180,16 +227,66 @@ mod tests {
180227 entry
181228 } )
182229 . collect ( ) ;
183- assert ! ( verify_slice( & entries, & zero) ) ; // inductive step
230+ assert ! ( verify_slice( & entries, & zero) ) ;
184231
185- // Next, swap only two UserData events and ensure verification fails.
232+ // Next, swap two Discovery events and ensure verification fails.
186233 let event0 = entries[ 0 ] . event . clone ( ) ;
187234 let event1 = entries[ 1 ] . event . clone ( ) ;
188235 entries[ 0 ] . event = event1;
189236 entries[ 1 ] . event = event0;
190- assert ! ( !verify_slice( & entries, & zero) ) ; // inductive step
237+ assert ! ( !verify_slice( & entries, & zero) ) ;
191238 }
192239
240+ #[ test]
241+ fn test_signature ( ) {
242+ use untrusted;
243+ use ring:: { rand, signature} ;
244+ let rng = rand:: SystemRandom :: new ( ) ;
245+ let pkcs8_bytes = signature:: Ed25519KeyPair :: generate_pkcs8 ( & rng) . unwrap ( ) ;
246+ let key_pair =
247+ signature:: Ed25519KeyPair :: from_pkcs8 ( untrusted:: Input :: from ( & pkcs8_bytes) ) . unwrap ( ) ;
248+ const MESSAGE : & ' static [ u8 ] = b"hello, world" ;
249+ let event0 = sign_hash ( & hash ( MESSAGE ) , & key_pair) ;
250+ let zero = Sha256Hash :: default ( ) ;
251+ let mut end_hash = zero;
252+ let entries: Vec < Entry > = [ event0]
253+ . iter ( )
254+ . map ( |event| {
255+ let entry = next_entry ( & end_hash, 0 , event. clone ( ) ) ;
256+ end_hash = entry. end_hash ;
257+ entry
258+ } )
259+ . collect ( ) ;
260+ assert ! ( verify_slice( & entries, & zero) ) ;
261+ }
262+
263+ #[ test]
264+ fn test_bad_signature ( ) {
265+ use untrusted;
266+ use ring:: { rand, signature} ;
267+ let rng = rand:: SystemRandom :: new ( ) ;
268+ let pkcs8_bytes = signature:: Ed25519KeyPair :: generate_pkcs8 ( & rng) . unwrap ( ) ;
269+ let key_pair =
270+ signature:: Ed25519KeyPair :: from_pkcs8 ( untrusted:: Input :: from ( & pkcs8_bytes) ) . unwrap ( ) ;
271+ const MESSAGE : & ' static [ u8 ] = b"hello, world" ;
272+ let mut event0 = sign_hash ( & hash ( MESSAGE ) , & key_pair) ;
273+ if let Event :: Claim { key, sig, .. } = event0 {
274+ const GOODBYE : & ' static [ u8 ] = b"goodbye cruel world" ;
275+ let data = hash ( GOODBYE ) ;
276+ event0 = Event :: Claim { key, data, sig } ;
277+ }
278+ let zero = Sha256Hash :: default ( ) ;
279+ let mut end_hash = zero;
280+ let entries: Vec < Entry > = [ event0]
281+ . iter ( )
282+ . map ( |event| {
283+ let entry = next_entry ( & end_hash, 0 , event. clone ( ) ) ;
284+ end_hash = entry. end_hash ;
285+ entry
286+ } )
287+ . collect ( ) ;
288+ assert ! ( !verify_slice( & entries, & zero) ) ;
289+ }
193290}
194291
195292#[ cfg( all( feature = "unstable" , test) ) ]
0 commit comments