1
1
#!/usr/bin/env python3
2
- # Copyright (c) 2016-2018 The Bitcoin Core developers
2
+ # Copyright (c) 2016-2022 The Bitcoin Core developers
3
3
# Distributed under the MIT software license, see the accompanying
4
4
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
- """Specialized SipHash-2-4 implementations .
5
+ """SipHash-2-4 implementation .
6
6
7
- This implements SipHash-2-4 for 256-bit integers.
7
+ This implements SipHash-2-4. For convenience, an interface taking 256-bit
8
+ integers is provided in addition to the one accepting generic data.
8
9
"""
9
10
10
11
def rotl64 (n , b ):
11
12
return n >> (64 - b ) | (n & ((1 << (64 - b )) - 1 )) << b
12
13
14
+
13
15
def siphash_round (v0 , v1 , v2 , v3 ):
14
16
v0 = (v0 + v1 ) & ((1 << 64 ) - 1 )
15
17
v1 = rotl64 (v1 , 13 )
@@ -27,37 +29,37 @@ def siphash_round(v0, v1, v2, v3):
27
29
v2 = rotl64 (v2 , 32 )
28
30
return (v0 , v1 , v2 , v3 )
29
31
30
- def siphash256 (k0 , k1 , h ):
31
- n0 = h & ((1 << 64 ) - 1 )
32
- n1 = (h >> 64 ) & ((1 << 64 ) - 1 )
33
- n2 = (h >> 128 ) & ((1 << 64 ) - 1 )
34
- n3 = (h >> 192 ) & ((1 << 64 ) - 1 )
32
+
33
+ def siphash (k0 , k1 , data ):
34
+ assert (type (data ) == bytes )
35
35
v0 = 0x736f6d6570736575 ^ k0
36
36
v1 = 0x646f72616e646f6d ^ k1
37
37
v2 = 0x6c7967656e657261 ^ k0
38
- v3 = 0x7465646279746573 ^ k1 ^ n0
39
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
40
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
41
- v0 ^= n0
42
- v3 ^= n1
43
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
44
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
45
- v0 ^= n1
46
- v3 ^= n2
38
+ v3 = 0x7465646279746573 ^ k1
39
+ c = 0
40
+ t = 0
41
+ for d in data :
42
+ t |= d << (8 * (c % 8 ))
43
+ c = (c + 1 ) & 0xff
44
+ if (c & 7 ) == 0 :
45
+ v3 ^= t
46
+ v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
47
+ v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
48
+ v0 ^= t
49
+ t = 0
50
+ t = t | (c << 56 )
51
+ v3 ^= t
47
52
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
48
53
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
49
- v0 ^= n2
50
- v3 ^= n3
51
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
52
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
53
- v0 ^= n3
54
- v3 ^= 0x2000000000000000
55
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
56
- v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
57
- v0 ^= 0x2000000000000000
58
- v2 ^= 0xFF
54
+ v0 ^= t
55
+ v2 ^= 0xff
59
56
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
60
57
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
61
58
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
62
59
v0 , v1 , v2 , v3 = siphash_round (v0 , v1 , v2 , v3 )
63
60
return v0 ^ v1 ^ v2 ^ v3
61
+
62
+
63
+ def siphash256 (k0 , k1 , num ):
64
+ assert (type (num ) == int )
65
+ return siphash (k0 , k1 , num .to_bytes (32 , 'little' ))
0 commit comments