R14:rawptr[X] -> X*(41 文件 / 2037 行改动),X 含模块限定名与嵌套下标(rawptr[GSList[NameEntry]] -> GSList[NameEntry]*)。保留 6 处 rawptr[t.CPtr](规范例外:存纯裸指针);# 注释与字符串里的 rawptr[...] 属元语法描述,未动。 R16(保守子集):t.CConst | str/bytes -> const str/bytes,t.CConst | char | t.CPtr -> const str;typedef 右值位置豁免(const str 在该处无法注册,与 R1 同源)。 验证:TPC 自举三重重编 SUCCESS;TransPyV.exe 全量 77/77 顺序回归通过。
118 lines
4.3 KiB
Plaintext
118 lines
4.3 KiB
Plaintext
import string
|
|
import t, c
|
|
|
|
|
|
|
|
# ==============================================
|
|
# SHA1 Hash Algorithm
|
|
# ==============================================
|
|
define SHA1_BLOCK_LEN = 64
|
|
define SHA1_DIGEST_LEN = 20
|
|
|
|
define sha1_rotl(x: uint32, n: int) -> uint32: return (x << n) | (x >> (32 - n))
|
|
# 3-round logical functions
|
|
define sha1_f1(b: uint32, c: uint32, d: uint32) -> uint32: return (b & c) | (~b & d)
|
|
define sha1_f2(b: uint32, c: uint32, d: uint32) -> uint32: return b ^ c ^ d
|
|
define sha1_f3(b: uint32, c: uint32, d: uint32) -> uint32: return (b & c) | (b & d) | (c & d)
|
|
|
|
# SHA1 Context
|
|
class sha1:
|
|
state: [5]uint32 = [
|
|
0x67452301, 0xefcdab89,
|
|
0x98badcfe, 0x10325476,
|
|
0xc3d2e1f0
|
|
] # 5 32-bit state registers
|
|
count: uint64 = 0 # processed bits
|
|
buf: [SHA1_BLOCK_LEN]uint8
|
|
def __init__(self):
|
|
string.memset(self.buf, 0, SHA1_BLOCK_LEN)
|
|
# Single-group compression transform
|
|
def transform(self, block: uint8*):
|
|
w: [80]uint32
|
|
data: uint8* = block
|
|
# First 16 words
|
|
for i in range(16):
|
|
w[i] = (((uint32(data[i * 4 + 0])) << 24) |
|
|
((uint32(data[i * 4 + 1])) << 16) |
|
|
((uint32(data[i * 4 + 2])) << 8) |
|
|
((uint32(data[i * 4 + 3])) << 0))
|
|
# Extend to 80 words
|
|
for i in range(16, 80):
|
|
w[i] = sha1_rotl(w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16],1)
|
|
a: uint32 = self.state[0]
|
|
b: uint32 = self.state[1]
|
|
c: uint32 = self.state[2]
|
|
d: uint32 = self.state[3]
|
|
e: uint32 = self.state[4]
|
|
k: uint32
|
|
tmp: uint32
|
|
# 4-round iterations
|
|
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: uint8* = uint8*(s)
|
|
length: sizet = len(s)
|
|
idx: sizet = self.count % SHA1_BLOCK_LEN
|
|
self.count += length
|
|
if idx > 0:
|
|
left: sizet = SHA1_BLOCK_LEN - idx
|
|
if length >= left:
|
|
string.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:
|
|
string.memcpy(self.buf + idx, data, length)
|
|
def final(self, out: [SHA1_DIGEST_LEN]uint8):
|
|
idx: sizet = self.count % SHA1_BLOCK_LEN
|
|
self.buf[idx] = 0x80
|
|
idx += 1
|
|
if idx > SHA1_BLOCK_LEN - 8:
|
|
string.memset(self.buf + idx, 0, SHA1_BLOCK_LEN - idx)
|
|
self.transform(self.buf)
|
|
idx = 0
|
|
string.memset(self.buf + idx,0,SHA1_BLOCK_LEN-8-idx)
|
|
bits: uint64 = self.count << 3
|
|
# SHA1 big-endian write length
|
|
for i in range(8):
|
|
self.buf[SHA1_BLOCK_LEN - 8 + i] = (bits >> (56 - i * 8)) & 0xFF
|
|
self.transform(self.buf)
|
|
# State registers to big-endian byte output output output
|
|
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
|