1
1
use std:: hash:: Hasher ;
2
2
3
- use siphasher:: sip128:: SipHasher24 ;
3
+ use siphasher:: sip128:: { Hash128 , Hasher128 , SipHasher24 } ;
4
4
5
- use crate :: { Error , Result } ;
5
+ use crate :: { Result , VickyError } ;
6
6
7
7
#[ derive( Debug , Clone , Copy ) ]
8
8
pub struct SecretKey ( [ u8 ; 16 ] ) ;
@@ -17,7 +17,7 @@ impl SecretKey {
17
17
pub fn new < B : AsRef < [ u8 ] > + ?Sized > ( key : & B ) -> Result < Self > {
18
18
let key = key. as_ref ( ) ;
19
19
if key. len ( ) != Self :: LEN {
20
- return Err ( Error :: WrongSecretKeyLength ) ;
20
+ return Err ( Box :: new ( VickyError :: WrongSecretKeyLength ) ) ;
21
21
}
22
22
let mut bytes = [ 0u8 ; Self :: LEN ] ;
23
23
bytes. copy_from_slice ( & key) ;
@@ -34,14 +34,10 @@ pub(crate) struct PartedHash {
34
34
35
35
pub ( crate ) const INVALID_SIG : u32 = 0 ;
36
36
pub ( crate ) const USER_NAMESPACE : u8 = 1 ;
37
+ //pub(crate) const TYPED_NAMESPACE: u8 = 2;
37
38
38
39
impl PartedHash {
39
- pub fn from_buffer ( namespace : u8 , key : & SecretKey , buf : & [ u8 ] ) -> Self {
40
- // maybe use blake3?
41
- let mut hasher = SipHasher24 :: new_with_key ( & key. 0 ) ;
42
- hasher. write_u8 ( namespace) ;
43
- hasher. write ( buf) ;
44
- let h = hasher. hash ( buf) ;
40
+ fn from_hash ( h : Hash128 ) -> Self {
45
41
let mut signature = h. h1 as u32 ;
46
42
if signature == INVALID_SIG {
47
43
signature = h. h2 as u32 ;
@@ -58,27 +54,72 @@ impl PartedHash {
58
54
signature,
59
55
}
60
56
}
57
+ pub fn from_buffer ( namespace : u8 , key : & SecretKey , buf : & [ u8 ] ) -> Self {
58
+ // maybe use blake3?
59
+ let mut hasher = SipHasher24 :: new_with_key ( & key. 0 ) ;
60
+ hasher. write_u8 ( namespace) ;
61
+ hasher. write ( buf) ;
62
+ Self :: from_hash ( hasher. finish128 ( ) )
63
+ }
64
+
65
+ #[ allow( dead_code) ]
66
+ pub fn builder ( key : & SecretKey ) -> PartedHashBuilder {
67
+ PartedHashBuilder ( SipHasher24 :: new_with_key ( & key. 0 ) )
68
+ }
69
+
70
+ #[ allow( dead_code) ]
71
+ pub fn to_u64 ( & self ) -> u64 {
72
+ ( ( self . shard_selector as u64 ) << 48 )
73
+ | ( ( self . row_selector as u64 ) << 32 )
74
+ | ( self . signature as u64 )
75
+ }
76
+ }
77
+
78
+ #[ allow( dead_code) ]
79
+ pub ( crate ) struct PartedHashBuilder ( SipHasher24 ) ;
80
+
81
+ impl PartedHashBuilder {
82
+ #[ allow( dead_code) ]
83
+ pub fn write ( mut self , bytes : & [ u8 ] ) -> Self {
84
+ self . 0 . write ( bytes) ;
85
+ self
86
+ }
87
+ #[ allow( dead_code) ]
88
+ pub fn write_u32 ( mut self , v : u32 ) -> Self {
89
+ self . 0 . write_u32 ( v) ;
90
+ self
91
+ }
92
+ #[ allow( dead_code) ]
93
+ pub fn write_u8 ( mut self , v : u8 ) -> Self {
94
+ self . 0 . write_u8 ( v) ;
95
+ self
96
+ }
97
+ #[ allow( dead_code) ]
98
+ pub fn finish ( self ) -> PartedHash {
99
+ PartedHash :: from_hash ( self . 0 . finish128 ( ) )
100
+ }
61
101
}
62
102
63
103
#[ test]
64
104
fn test_parted_hash ( ) -> Result < ( ) > {
65
- assert ! ( matches!(
66
- SecretKey :: new( "1234" ) ,
67
- Err ( Error :: WrongSecretKeyLength )
68
- ) ) ;
69
- assert ! ( matches!(
70
- SecretKey :: new( "12341234123412341" ) ,
71
- Err ( Error :: WrongSecretKeyLength )
72
- ) ) ;
105
+ SecretKey :: new ( "1234" ) . expect_err ( "shouldn't work" ) ;
106
+ SecretKey :: new ( "12341234123412341" ) . expect_err ( "shouldn't work" ) ;
107
+
73
108
let key = SecretKey :: new ( "aaaabbbbccccdddd" ) ?;
74
109
75
110
assert_eq ! (
76
- PartedHash :: from_buffer( USER_NAMESPACE , & key, b"hello world" ) ,
77
- PartedHash {
78
- shard_selector: 62379 ,
79
- row_selector: 17802 ,
80
- signature: 3217405680
81
- }
111
+ PartedHash :: from_buffer( USER_NAMESPACE , & key, b"hello world" ) . to_u64( ) ,
112
+ 12143172433256666175 ,
82
113
) ;
114
+
115
+ assert_eq ! (
116
+ PartedHash :: builder( & key)
117
+ . write_u8( USER_NAMESPACE )
118
+ . write( b"hello world" )
119
+ . finish( )
120
+ . to_u64( ) ,
121
+ 12143172433256666175 ,
122
+ ) ;
123
+
83
124
Ok ( ( ) )
84
125
}
0 commit comments