本代码中的消息与密钥实例为论文[1]附录A的测试向量。
import math
class SipHash():
def __init__(self):
# initial constants
self.v_0 = 0x736f6d6570736575
self.v_1 = 0x646f72616e646f6d
self.v_2 = 0x6c7967656e657261
self.v_3 = 0x7465646279746573
self.k_0 = 0
self.k_1 = 0
def password(self,pwd):
# 初始化密钥:将pwd转换为k_0和k_1
# 需先确认计算机的编码方式(本人计算机是小端编码)
self.k_0 = int((pwd[:8])[::-1].hex(), 16)
self.k_1 = int((pwd[8:])[::-1].hex(), 16)
def siphash_fill(self,msg):
# 消息填充,使填充后长度为64bits的整数倍
# 输入参数msg为bytes类型
length = len(msg) # msg的长度(单位:bytes)
w = math.ceil((length + 1) / 8) # msg能够划分的消息块个数(每个消息块64bits)
remain_len = w * 8 - length # 需填充的长度
msg_new = bytearray((w * 8)) # 填充后的消息长度,单位:byte
# 将msg的数据存储至msg_new_bytes中
for i in range(w * 8 - remain_len):
msg_new[i] = msg[i]
# 填充0
for i in [w * 8 - remain_len, w * 8 - 1]:
msg_new[i] = 0
# 最后1字节填充msg的长度模256
msg_new[w * 8 - 1] = length % 256
return msg_new
def SipRound(self,a,b,c,d):
#轮函数计算,内部状态为64比特,运算应保留后64位
a = (a + b) & 0xffffffffffffffff
b = (((b << 13) | (b >> 51)) ^ a) & 0xffffffffffffffff
c = (c + d) & 0xffffffffffffffff
d = (((d << 16) | (d >> 48)) ^ c) & 0xffffffffffffffff
a = ((a << 32) | (a >> 32)) & 0xffffffffffffffff
c = (c + b) & 0xffffffffffffffff
b = (((b << 17) | (b >> 47)) ^ c) & 0xffffffffffffffff
a = (a + d) & 0xffffffffffffffff
d = (((d << 21) | (d >> 43)) ^ a) & 0xffffffffffffffff
c = ((c << 32) | (c >> 32)) & 0xffffffffffffffff
return a, b, c, d
def SipHash_2_4(self,msg,pwd):
# 填充消息
msg = self.siphash_fill(msg)
# 初始化密钥
self.password(pwd)
# 初始状态与密钥异或
self.v_0 ^= self.k_0
self.v_1 ^= self.k_1
self.v_2 ^= self.k_0
self.v_3 ^= self.k_1
# 压缩阶段
length = len(msg) // 8
for i in range(length):
m = int((msg[i * 8:(i + 1) * 8])[::-1].hex(), 16)
self.v_3 ^= m
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
self.v_0 ^= m
# 终结阶段
self.v_2 ^= 0xff
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
self.v_0, self.v_1, self.v_2, self.v_3 = self.SipRound(self.v_0, self.v_1, self.v_2, self.v_3)
return self.v_0 ^ self.v_1 ^ self.v_2 ^ self.v_3
if __name__ == '__main__':
msg = ''.join(chr(i) for i in range(15)).encode('utf-8') # msg = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e'
pwd = ''.join(chr(i) for i in range(16)).encode('utf-8') # pwd = b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
test1 = SipHash()
digest1 = test1.SipHash_2_4(msg,pwd)
print("message: ", msg.hex())
print("password:", pwd.hex())
print("digest1: ", hex(digest1))
运行结果:
参考文献:
[1]. Aumasson J P , Bernstein D J . SipHash: a fast short-input PRF[J]. Lecture Notes in Computer Science, 2012.
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)