snapshot before regression test
This commit is contained in:
120
includes/hashlib/__sha1.py
Normal file
120
includes/hashlib/__sha1.py
Normal file
@@ -0,0 +1,120 @@
|
||||
import string
|
||||
import t, c
|
||||
|
||||
|
||||
|
||||
# ==============================================
|
||||
# SHA1 哈希算法
|
||||
# ==============================================
|
||||
SHA1_BLOCK_LEN: t.CDefine = 64
|
||||
SHA1_DIGEST_LEN: t.CDefine = 20
|
||||
|
||||
def sha1_rotl(x: t.CUInt32T, n: t.CInt) -> t.CUInt32T: return (x << n) | (x >> (32 - n))
|
||||
# 三轮逻辑函数
|
||||
def sha1_f1(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return (b & c) | (~b & d)
|
||||
def sha1_f2(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return b ^ c ^ d
|
||||
def sha1_f3(b: t.CUInt32T, c: t.CUInt32T, d: t.CUInt32T) -> t.CUInt32T: return (b & c) | (b & d) | (c & d)
|
||||
|
||||
# SHA1 上下文
|
||||
@t.Object
|
||||
class sha1:
|
||||
state: t.CArray[t.CUInt32T, 5]
|
||||
count: t.CUInt64T
|
||||
buf: t.CArray[t.CUInt8T, SHA1_BLOCK_LEN]
|
||||
def __init__(self):
|
||||
memset(self.buf, 0, SHA1_BLOCK_LEN)
|
||||
self.state[0] = 0x67452301
|
||||
self.state[1] = 0xefcdab89
|
||||
self.state[2] = 0x98badcfe
|
||||
self.state[3] = 0x10325476
|
||||
self.state[4] = 0xc3d2e1f0
|
||||
self.count = 0
|
||||
# 单分组压缩
|
||||
def transform(self, block: t.CUInt8T | t.CPtr):
|
||||
w: t.CArray[t.CUInt32T, 80]
|
||||
data: t.CUInt8T | t.CPtr = block
|
||||
# 前16个字
|
||||
for i in range(16):
|
||||
w[i] = (((t.CUInt32T(data[i * 4 + 0])) << 24) |
|
||||
((t.CUInt32T(data[i * 4 + 1])) << 16) |
|
||||
((t.CUInt32T(data[i * 4 + 2])) << 8) |
|
||||
((t.CUInt32T(data[i * 4 + 3])) << 0))
|
||||
# 扩展到80个字
|
||||
for i in range(16, 80):
|
||||
w[i] = sha1_rotl(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16],1)
|
||||
a: t.CUInt32T = self.state[0]
|
||||
b: t.CUInt32T = self.state[1]
|
||||
c: t.CUInt32T = self.state[2]
|
||||
d: t.CUInt32T = self.state[3]
|
||||
e: t.CUInt32T = self.state[4]
|
||||
k: t.CUInt32T
|
||||
tmp: t.CUInt32T
|
||||
# 4轮迭代
|
||||
for i in range(0, 20):
|
||||
k = 0x5a827999
|
||||
tmp = sha1_rotl(a,5) + sha1_f1(b, c, d) + e + k + w[i]
|
||||
e = d; d = c
|
||||
c = sha1_rotl(b, 30)
|
||||
b = a; a = tmp
|
||||
for i in range(20, 40):
|
||||
k = 0x6ed9eba1
|
||||
tmp = sha1_rotl(a,5) + sha1_f2(b, c, d) + e + k + w[i]
|
||||
e = d; d = c
|
||||
c = sha1_rotl(b, 30)
|
||||
b = a; a = tmp
|
||||
for i in range(40, 60):
|
||||
k = 0x8f1bbcdc
|
||||
tmp = sha1_rotl(a,5) + sha1_f3(b, c, d) + e + k + w[i]
|
||||
e = d; d = c
|
||||
c = sha1_rotl(b, 30)
|
||||
b = a; a = tmp
|
||||
for i in range(60, 80):
|
||||
k = 0xca62c1d6
|
||||
tmp = sha1_rotl(a,5) + sha1_f2(b, c, d) + e + k + w[i]
|
||||
e = d; d = c
|
||||
c = sha1_rotl(b, 30)
|
||||
b = a; a = tmp
|
||||
self.state[0] += a
|
||||
self.state[1] += b
|
||||
self.state[2] += c
|
||||
self.state[3] += d
|
||||
self.state[4] += e
|
||||
def update(self, s: str):
|
||||
data: t.CUInt8T | t.CPtr = t.CUInt8T(s, t.CPtr)
|
||||
length: t.CSizeT = len(s)
|
||||
idx: t.CSizeT = self.count % SHA1_BLOCK_LEN
|
||||
self.count += length
|
||||
if idx > 0:
|
||||
left: t.CSizeT = SHA1_BLOCK_LEN - idx
|
||||
if length >= left:
|
||||
memcpy(self.buf + idx, data, left)
|
||||
self.transform(self.buf)
|
||||
data += left
|
||||
length -= left
|
||||
idx = 0
|
||||
while length >= SHA1_BLOCK_LEN:
|
||||
self.transform(data)
|
||||
data += SHA1_BLOCK_LEN
|
||||
length -= SHA1_BLOCK_LEN
|
||||
if length > 0:
|
||||
memcpy(self.buf + idx, data, length)
|
||||
def final(self, out: t.CArray[t.CUInt8T, SHA1_DIGEST_LEN]):
|
||||
idx: t.CSizeT = self.count % SHA1_BLOCK_LEN
|
||||
self.buf[idx] = 0x80
|
||||
idx += 1
|
||||
if idx > SHA1_BLOCK_LEN - 8:
|
||||
memset(self.buf + idx, 0, SHA1_BLOCK_LEN - idx)
|
||||
self.transform(self.buf)
|
||||
idx = 0
|
||||
memset(self.buf + idx,0,SHA1_BLOCK_LEN-8-idx)
|
||||
bits: t.CUInt64T = self.count << 3
|
||||
# SHA1 大端写入长度
|
||||
for i in range(8):
|
||||
self.buf[SHA1_BLOCK_LEN - 8 + i] = (bits >> (56 - i * 8)) & 0xFF
|
||||
self.transform(self.buf)
|
||||
# 大端输出摘要
|
||||
for i in range(5):
|
||||
out[i * 4 + 0] = (self.state[i] >> 24) & 0xFF
|
||||
out[i * 4 + 1] = (self.state[i] >> 16) & 0xFF
|
||||
out[i * 4 + 2] = (self.state[i] >> 8) & 0xFF
|
||||
out[i * 4 + 3] = (self.state[i] >> 0) & 0xFF
|
||||
Reference in New Issue
Block a user