mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-21 14:34:49 +01:00
test: add SipHash implementation for generic data in Python
We will need this in the next commit to calculate ranged hashes of scriptPubKeys as defined in BIP158.
This commit is contained in:
parent
a97791d9fb
commit
25ee74dd11
1 changed files with 29 additions and 27 deletions
|
@ -1,15 +1,17 @@
|
|||
#!/usr/bin/env python3
|
||||
# Copyright (c) 2016-2018 The Bitcoin Core developers
|
||||
# Copyright (c) 2016-2022 The Bitcoin Core developers
|
||||
# Distributed under the MIT software license, see the accompanying
|
||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
"""Specialized SipHash-2-4 implementations.
|
||||
"""SipHash-2-4 implementation.
|
||||
|
||||
This implements SipHash-2-4 for 256-bit integers.
|
||||
This implements SipHash-2-4. For convenience, an interface taking 256-bit
|
||||
integers is provided in addition to the one accepting generic data.
|
||||
"""
|
||||
|
||||
def rotl64(n, b):
|
||||
return n >> (64 - b) | (n & ((1 << (64 - b)) - 1)) << b
|
||||
|
||||
|
||||
def siphash_round(v0, v1, v2, v3):
|
||||
v0 = (v0 + v1) & ((1 << 64) - 1)
|
||||
v1 = rotl64(v1, 13)
|
||||
|
@ -27,37 +29,37 @@ def siphash_round(v0, v1, v2, v3):
|
|||
v2 = rotl64(v2, 32)
|
||||
return (v0, v1, v2, v3)
|
||||
|
||||
def siphash256(k0, k1, h):
|
||||
n0 = h & ((1 << 64) - 1)
|
||||
n1 = (h >> 64) & ((1 << 64) - 1)
|
||||
n2 = (h >> 128) & ((1 << 64) - 1)
|
||||
n3 = (h >> 192) & ((1 << 64) - 1)
|
||||
|
||||
def siphash(k0, k1, data):
|
||||
assert(type(data) == bytes)
|
||||
v0 = 0x736f6d6570736575 ^ k0
|
||||
v1 = 0x646f72616e646f6d ^ k1
|
||||
v2 = 0x6c7967656e657261 ^ k0
|
||||
v3 = 0x7465646279746573 ^ k1 ^ n0
|
||||
v3 = 0x7465646279746573 ^ k1
|
||||
c = 0
|
||||
t = 0
|
||||
for d in data:
|
||||
t |= d << (8 * (c % 8))
|
||||
c = (c + 1) & 0xff
|
||||
if (c & 7) == 0:
|
||||
v3 ^= t
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= t
|
||||
t = 0
|
||||
t = t | (c << 56)
|
||||
v3 ^= t
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= n0
|
||||
v3 ^= n1
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= n1
|
||||
v3 ^= n2
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= n2
|
||||
v3 ^= n3
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= n3
|
||||
v3 ^= 0x2000000000000000
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0 ^= 0x2000000000000000
|
||||
v2 ^= 0xFF
|
||||
v0 ^= t
|
||||
v2 ^= 0xff
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
v0, v1, v2, v3 = siphash_round(v0, v1, v2, v3)
|
||||
return v0 ^ v1 ^ v2 ^ v3
|
||||
|
||||
|
||||
def siphash256(k0, k1, num):
|
||||
assert(type(num) == int)
|
||||
return siphash(k0, k1, num.to_bytes(32, 'little'))
|
||||
|
|
Loading…
Add table
Reference in a new issue