11pub trait Hasher < const DIGEST_BYTES : usize > {
2- /// return a new instance with default parameters
2+ /// Return a new instance with default parameters.
33 fn new_default ( ) -> Self ;
44
5- /// Add new data
5+ /// Add new data.
66 fn update ( & mut self , data : & [ u8 ] ) ;
77
8- /// Returns the hash of current data. If it is necessary does finalization
9- /// work on the instance, thus it may no longer make sense to do `update`
8+ /// Returns the hash of current data. If necessary does finalization work
9+ /// on the instance, thus it may no longer make sense to call `update`
1010 /// after calling this.
1111 fn get_hash ( & mut self ) -> [ u8 ; DIGEST_BYTES ] ;
1212}
1313
14- /// HMAC based on RFC2104 , applicable to many cryptographic hash functions
14+ /// HMAC based on RFC 2104 , applicable to many cryptographic hash functions.
1515pub struct HMAC < const KEY_BYTES : usize , const DIGEST_BYTES : usize , H : Hasher < DIGEST_BYTES > > {
1616 pub inner_internal_state : H ,
1717 pub outer_internal_state : H ,
@@ -27,25 +27,24 @@ impl<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>>
2727 }
2828 }
2929
30- /// Note that `key` must be no longer than `KEY_BYTES`. According to RFC,
31- /// if it is so, you should replace it with its hash. We do not do this
32- /// automatically due to fear of `DIGEST_BYTES` not being the same as
33- /// `KEY_BYTES` or even being longer than it
30+ /// Note that `key` must be no longer than `KEY_BYTES`. According to the
31+ /// RFC, if it is so, you should replace it with its hash. We do not do
32+ /// this automatically due to fear of `DIGEST_BYTES` not being the same as
33+ /// `KEY_BYTES` or even being longer than it.
3434 pub fn add_key ( & mut self , key : & [ u8 ] ) -> Result < ( ) , & ' static str > {
3535 match key. len ( ) . cmp ( & KEY_BYTES ) {
3636 std:: cmp:: Ordering :: Less | std:: cmp:: Ordering :: Equal => {
3737 let mut tmp_key = [ 0u8 ; KEY_BYTES ] ;
3838 for ( d, s) in tmp_key. iter_mut ( ) . zip ( key. iter ( ) ) {
3939 * d = * s;
4040 }
41- // key ^ 0x363636.. should be used as inner key
41+ // key XOR 0x363636… is the inner key
4242 for b in tmp_key. iter_mut ( ) {
4343 * b ^= 0x36 ;
4444 }
4545 self . inner_internal_state . update ( & tmp_key) ;
46- // key ^ 0x5c5c5c.. should be used as outer key, but the key is
47- // already XORed with 0x363636.. , so it must now be XORed with
48- // 0x6a6a6a..
46+ // key XOR 0x5c5c5c… is the outer key; the key is already
47+ // XORed with 0x36, so XOR with 0x6a to get the net 0x5c.
4948 for b in tmp_key. iter_mut ( ) {
5049 * b ^= 0x6a ;
5150 }
@@ -66,24 +65,3 @@ impl<const KEY_BYTES: usize, const DIGEST_BYTES: usize, H: Hasher<DIGEST_BYTES>>
6665 self . outer_internal_state . get_hash ( )
6766 }
6867}
69-
70- #[ cfg( test) ]
71- mod tests {
72- use super :: super :: sha256:: tests:: get_hash_string;
73- use super :: super :: SHA256 ;
74- use super :: HMAC ;
75-
76- #[ test]
77- fn sha256_basic ( ) {
78- // To test this, use the following command on linux:
79- // echo -n "Hello World" | openssl sha256 -hex -mac HMAC -macopt hexkey:"deadbeef"
80- let mut hmac: HMAC < 64 , 32 , SHA256 > = HMAC :: new_default ( ) ;
81- hmac. add_key ( & [ 0xde , 0xad , 0xbe , 0xef ] ) . unwrap ( ) ;
82- hmac. update ( b"Hello World" ) ;
83- let hash = hmac. finalize ( ) ;
84- assert_eq ! (
85- get_hash_string( & hash) ,
86- "f585fc4536e8e7f378437465b65b6c2eb79036409b18a7d28b6d4c46d3a156f8"
87- ) ;
88- }
89- }
0 commit comments