熵密杯2024
·1934 words·10 mins
Table of Contents
为什么我证书patch不上 哭了
sm3长度扩展 #
我在此处囤个脚本,省得以后找了
my_sm3
#!/usr/bin/env python
# -*- coding:utf-8 -*-
"""
@Time:2019/10/13
@Author: hhzjj
@Description:SM3实现 将IV换成第一步得到第一步hash时各寄存器的值
"""
import binascii
from math import ceil
from myfunc import rotl, bytes_to_list
IV = [
1937774191, 1226093241, 388252375, 3666478592,
2842636476, 372324522, 3817729613, 2969243214,
]
T_j = [
2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
2043430169, 2043430169, 2043430169, 2043430169, 2043430169, 2043430169,
2043430169, 2043430169, 2043430169, 2043430169, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042, 2055708042, 2055708042,
2055708042, 2055708042, 2055708042, 2055708042
]
def sm3_ff_j(x, y, z, j):
if 0 <= j and j < 16:
ret = x ^ y ^ z
elif 16 <= j and j < 64:
ret = (x & y) | (x & z) | (y & z)
return ret
def sm3_gg_j(x, y, z, j):
if 0 <= j and j < 16:
ret = x ^ y ^ z
elif 16 <= j and j < 64:
#ret = (X | Y) & ((2 ** 32 - 1 - X) | Z)
ret = (x & y) | ((~ x) & z)
return ret
def sm3_p_0(x):
return x ^ (rotl(x, 9 % 32)) ^ (rotl(x, 17 % 32))
def sm3_p_1(x):
return x ^ (rotl(x, 15 % 32)) ^ (rotl(x, 23 % 32))
def sm3_cf(v_i, b_i):
w = []
for i in range(16):
weight = 0x1000000
data = 0
for k in range(i*4,(i+1)*4):
data = data + b_i[k]*weight
weight = int(weight/0x100)
w.append(data)
for j in range(16, 68):
w.append(0)
w[j] = sm3_p_1(w[j-16] ^ w[j-9] ^ (rotl(w[j-3], 15 % 32))) ^ (rotl(w[j-13], 7 % 32)) ^ w[j-6]
str1 = "%08x" % w[j]
w_1 = []
for j in range(0, 64):
w_1.append(0)
w_1[j] = w[j] ^ w[j+4]
str1 = "%08x" % w_1[j]
a, b, c, d, e, f, g, h = v_i
for j in range(0, 64):
ss_1 = rotl(
((rotl(a, 12 % 32)) +
e +
(rotl(T_j[j], j % 32))) & 0xffffffff, 7 % 32
)
ss_2 = ss_1 ^ (rotl(a, 12 % 32))
tt_1 = (sm3_ff_j(a, b, c, j) + d + ss_2 + w_1[j]) & 0xffffffff
tt_2 = (sm3_gg_j(e, f, g, j) + h + ss_1 + w[j]) & 0xffffffff
d = c
c = rotl(b, 9 % 32)
b = a
a = tt_1
h = g
g = rotl(f, 19 % 32)
f = e
e = sm3_p_0(tt_2)
a, b, c, d, e, f, g, h = map(
lambda x:x & 0xFFFFFFFF ,[a, b, c, d, e, f, g, h])
v_j = [a, b, c, d, e, f, g, h]
return [v_j[i] ^ v_i[i] for i in range(8)]
def sm3_hash(msg, new_v):
# print(msg)
len1 = len(msg)
reserve1 = len1 % 64
msg.append(0x80)
reserve1 = reserve1 + 1
# 56-64, add 64 byte
range_end = 56
if reserve1 > range_end:
range_end = range_end + 64
for i in range(reserve1, range_end):
msg.append(0x00)
bit_length = (len1) * 8
bit_length_str = [bit_length % 0x100]
for i in range(7):
bit_length = int(bit_length / 0x100)
bit_length_str.append(bit_length % 0x100)
for i in range(8):
msg.append(bit_length_str[7-i])
group_count = round(len(msg) / 64) - 1
B = []
for i in range(0, group_count):
B.append(msg[(i + 1)*64:(i+2)*64])
V = []
V.append(new_v)
for i in range(0, group_count):
V.append(sm3_cf(V[i], B[i]))
y = V[i+1]
result = ""
for i in y:
result = '%s%08x' % (result, i)
return result
def sm3_kdf(z, klen): # z为16进制表示的比特串(str),klen为密钥长度(单位byte)
klen = int(klen)
ct = 0x00000001
rcnt = ceil(klen/32)
zin = [i for i in bytes.fromhex(z.decode('utf8'))]
ha = ""
for i in range(rcnt):
msg = zin + [i for i in binascii.a2b_hex(('%08x' % ct).encode('utf8'))]
ha = ha + sm3_hash(msg)
ct += 1
return ha[0: klen * 2]
myfunc
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from random import choice
xor = lambda a, b:list(map(lambda x, y: x ^ y, a, b))
rotl = lambda x, n:((x << n) & 0xffffffff) | ((x >> (32 - n)) & 0xffffffff)
get_uint32_be = lambda key_data:((key_data[0] << 24) | (key_data[1] << 16) | (key_data[2] << 8) | (key_data[3]))
put_uint32_be = lambda n:[((n>>24)&0xff), ((n>>16)&0xff), ((n>>8)&0xff), ((n)&0xff)]
padding = lambda data, block=16: data + [(16 - len(data) % block)for _ in range(16 - len(data) % block)]
unpadding = lambda data: data[:-data[-1]]
list_to_bytes = lambda data: b''.join([bytes((i,)) for i in data])
bytes_to_list = lambda data: [i for i in data]
random_hex = lambda x: ''.join([choice('0123456789abcdef') for _ in range(x)])
exp
from gmssl import sm3, func
import random
import my_sm3
import struct
# secret = str(random.random())
# secret_hash = sm3.sm3_hash(func.bytes_to_list(bytes(secret, encoding='utf-8')))
# secret_len = len(secret)
append_m = "" # 附加消息
pad_str = ""
pad = []
def generate_guess_hash(old_hash, secret_len, append_m):
"""
SM3长度扩展攻击
:param old_hash: secret的hash值
:param secret_len: secret的长度
:param append_m: 附加的消息
:return: hash(secret + padding + append_m)
"""
vectors = []
message = ""
# 将old_hash分组,每组8个字节, 并转换为整数
for r in range(0, len(old_hash), 8):
vectors.append(int(old_hash[r:r + 8], 16))
# 伪造消息
if secret_len > 64:
for i in range(0, int(secret_len / 64) * 64):
message += 'a'
for i in range(0, secret_len % 64):
message += 'a'
message = func.bytes_to_list(bytes(message, encoding='utf-8'))
message = padding(message)
message.extend(func.bytes_to_list(append_m))
return my_sm3.sm3_hash(message, vectors)
def padding(msg):
mlen = len(msg)
msg.append(0x80)
mlen += 1
tail = mlen % 64
range_end = 56
if tail > range_end:
range_end = range_end + 64
for i in range(tail, range_end):
msg.append(0x00)
bit_len = (mlen - 1) * 8
msg.extend([int(x) for x in struct.pack('>q', bit_len)])
for j in range(int((mlen - 1) / 64) * 64 + (mlen - 1) % 64, len(msg)):
global pad
pad.append(msg[j])
global pad_str
pad_str += str(hex(msg[j]))
return msg
secret_hash = "890778c09f1f203f6728c573ca4a030e5cd0488d8c396f752acb6861fccb13ac"
append_m = b'\xff\xff\xff\xff'
secret_len = 36
guess_hash = generate_guess_hash(secret_hash, secret_len, append_m)
append_m = b'\xff\xff\xff\xff'
conter = "6c09794a"+"80000000000000000000000000000000000000000000000000000120ffffffff"
print(conter)
print("guess_hash " , guess_hash)
一个简陋lwe #
task
import sympy as sp
import random
# 设置参数
n = 16 # 向量长度
q = 251 # 模数
# 生成随机噪声向量e
e = sp.Matrix(sp.randMatrix(n, 1, min=0, max=1)) # 噪声向量
# 生成随机n维私钥向量s和n*n矩阵A
s = sp.Matrix(sp.randMatrix(n, 1, min=0, max=q - 1)) # 私钥向量
Temp = sp.Matrix(sp.randMatrix(n, n, min=0, max=q - 1)) # 中间变量矩阵Temp
A = Temp.inv_mod(q) # 计算矩阵Temp在模 q 下的逆矩阵作为A
# 计算n维公钥向量b
b = (A * s + e) % q # 公钥向量b = A * s + e
# 加密函数
def encrypt(message, A, b):
m_bin = bin(message)[2:].zfill(n) # 将消息转换为16比特的二进制字符串
m = sp.Matrix([int(bit) for bit in m_bin]) # 转换为SymPy矩阵
x = sp.Matrix(sp.randMatrix(n, n, min=0, max=q // (n * 4))) # 随机产生一个n*n的矩阵x
e1 = sp.Matrix(sp.randMatrix(n, 1, min=0, max=1)) # 随机产生一个n维噪声向量e
c1 = (x * A) % q # 密文部分c1 = x * A
c2 = (x * b + e1 + m * (q // 2)) % q # 密文部分c2 = x * b + e1 + m * q/2
return c1, c2
# 解密函数
def decrypt(c1, c2, s):
m_dec = (c2 - c1 * s) % q
m_rec = m_dec.applyfunc(lambda x: round(2 * x / q) % 2) # 还原消息
m_bin = ''.join([str(bit) for bit in m_rec]) # 将SymPy矩阵转换为二进制字符串
m_rec_int = int(m_bin, 2) # 将二进制字符串转换为整数
return m_rec_int
# 测试加解密
message = random.randint(0, 2 ** n - 1) # 要加密的消息,随机生成一个16比特整数
c1, c2 = encrypt(message, A, b) # 加密
print("原始消息: ", message)
print("公钥A=sp.", A)
print("公钥b=sp.", b)
print("密文c1=sp.", c1)
print("密文c2=sp.", c2)
decrypted_message = decrypt(c1, c2, s)
print("解密后的消息: ", decrypted_message) # 输出解密后的消息
在解密时将e置为全0,可以成功解密massage
import sympy as sp
import random
# 设置参数
n = 16 # 向量长度
q = 251 # 模数
# 生成随机噪声向量e e
# 加密函数
def encrypt(message, A, b):
m_bin = bin(message)[2:].zfill(n) # 将消息转换为16比特的二进制字符串
m = sp.Matrix([int(bit) for bit in m_bin]) # 转换为SymPy矩阵
x = sp.Matrix(sp.randMatrix(n, n, min=0, max=q // (n * 4))) # 随机产生一个n*n的矩阵x
e1 = sp.Matrix(sp.randMatrix(n, 1, min=0, max=1)) # 随机产生一个n维噪声向量e
c1 = (x * A) % q # 密文部分c1 = x * A
c2 = (x * b + e1 + m * (q // 2)) % q # 密文部分c2 = x * b + e1 + m * q/2
return c1, c2
# 解密函数
def decrypt(c1, c2, s):
m_dec = (c2 - c1 * s) % q
m_rec = m_dec.applyfunc(lambda x: round(2 * x / q) % 2) # 还原消息
m_bin = ''.join([str(bit) for bit in m_rec]) # 将SymPy矩阵转换为二进制字符串
m_rec_int = int(m_bin, 2) # 将二进制字符串转换为整数
return m_rec_int
# 测试加解密
# message = random.randint(0, 2 ** n - 1) # 要加密的消息,随机生成一个16比特整数
# c1, c2 = encrypt(message, A, b) # 加密
# print("原始消息: ", message)·
A=sp.Matrix([[243, 235, 167, 9, 150, 190, 119, 61, 46, 112, 27, 83, 249, 142, 102, 79], [236, 155, 70, 72, 247, 167, 129, 104, 129, 171, 249, 171, 143, 115, 244, 132], [60, 237, 108, 54, 38, 83, 162, 175, 209, 193, 3, 159, 88, 158, 213, 85], [128, 86, 66, 95, 201, 87, 205, 56, 53, 75, 166, 65, 243, 228, 144, 35], [45, 53, 59, 61, 13, 29, 78, 161, 232, 15, 83, 35, 192, 114, 185, 45], [188, 39, 139, 44, 208, 47, 78, 154, 223, 137, 56, 30, 141, 64, 130, 199], [75, 117, 156, 103, 176, 1, 226, 8, 53, 167, 15, 91, 42, 122, 139, 228], [243, 39, 59, 230, 250, 134, 70, 125, 57, 154, 244, 32, 118, 202, 223, 184], [38, 99, 163, 180, 184, 60, 52, 42, 7, 207, 87, 95, 188, 177, 244, 7], [67, 208, 131, 95, 67, 147, 188, 199, 115, 220, 221, 109, 37, 159, 212, 180], [112, 233, 124, 110, 57, 2, 186, 250, 186, 148, 245, 37, 204, 32, 31, 60], [170, 114, 211, 54, 133, 75, 60, 62, 75, 218, 79, 116, 63, 155, 123, 5], [186, 119, 87, 227, 73, 164, 59, 13, 142, 129, 44, 19, 4, 164, 12, 103], [40, 232, 237, 135, 42, 210, 99, 131, 217, 225, 42, 220, 148, 116, 69, 236], [153, 93, 138, 181, 191, 94, 157, 89, 218, 20, 136, 112, 180, 144, 214, 181], [17, 99, 91, 122, 169, 97, 74, 216, 82, 168, 166, 224, 23, 226, 202, 247]])
b=sp.Matrix([[134], [126], [157], [9], [166], [151], [149], [126], [95], [24], [62], [55], [7], [220], [239], [241]])
c1=sp.Matrix([[69, 232, 230, 63, 147, 120, 141, 146, 94, 101, 144, 212, 34, 79, 14, 158], [37, 194, 146, 82, 234, 99, 83, 10, 116, 153, 135, 202, 107, 106, 4, 139], [122, 216, 74, 193, 204, 187, 117, 120, 57, 182, 193, 226, 112, 225, 244, 111], [242, 199, 3, 106, 68, 102, 150, 75, 66, 186, 73, 76, 49, 112, 57, 233], [197, 139, 66, 9, 218, 134, 95, 242, 217, 4, 95, 200, 163, 234, 143, 27], [172, 130, 38, 76, 83, 71, 107, 69, 176, 68, 234, 162, 140, 131, 156, 68], [3, 157, 106, 106, 18, 67, 70, 186, 149, 222, 233, 83, 125, 172, 193, 16], [47, 200, 2, 133, 135, 191, 83, 78, 208, 225, 41, 226, 130, 38, 102, 31], [153, 92, 195, 56, 137, 161, 136, 91, 187, 198, 191, 6, 43, 141, 249, 8], [87, 232, 69, 230, 106, 119, 30, 201, 228, 60, 76, 230, 233, 57, 161, 48], [33, 220, 188, 140, 61, 174, 41, 23, 226, 61, 197, 159, 39, 62, 31, 232], [178, 194, 149, 161, 67, 19, 160, 89, 58, 37, 237, 82, 159, 11, 214, 155], [161, 6, 105, 144, 4, 215, 213, 86, 42, 144, 192, 107, 123, 198, 14, 100], [57, 129, 174, 207, 21, 122, 174, 225, 32, 19, 37, 230, 55, 105, 106, 28], [231, 246, 162, 210, 116, 100, 205, 241, 153, 126, 148, 155, 0, 25, 185, 134], [201, 120, 97, 103, 184, 164, 205, 155, 42, 189, 106, 218, 129, 198, 35, 248]])
c2=sp.Matrix([[233], [178], [154], [72], [224], [107], [97], [49], [179], [151], [245], [179], [242], [171], [199], [220]])
# 2699
Temp = A.inv_mod(q)
s1 = Temp*(b)
decrypted_message = decrypt(c1, c2, s1)
print("解密后的消息: ", decrypted_message) # 输出解密后的消息