【Python实现】SM3密码杂凑算法
2021/10/5 12:10:52
本文主要是介绍【Python实现】SM3密码杂凑算法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
这是我大三上学期的一个作品。然后为了能够显示中间过程,用面向过程的思想编写。
- 注:强烈建议用 jupyter 运行代码
- n 代表运行顺序
In [n]:
代表第 n 步运行Out [n]:
代表第 n 步运行对应的输入In [ ]:
代表不运行
SM3密码杂凑算法.pdf下载
国家密码管理局关于发布《SM3密码杂凑算法》公告
发布日期:2010-12-17
来源:国家密码管理局
准备
统一数据结构(以65535为例)
In [1]:
import numpy as np
32位二进制(列表形式)
In [2]:
# 示例:array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=np.uint8) # 十进制 转 32位二进制 def Dec_to_Bin(Dec): Dec %= 2**32 return np.array([Dec >> tmp & 1 for tmp in range(32)][::-1], dtype = np.uint8) # 十六进制 转 32位二进制 def Hex_to_Bin(Hex): return Dec_to_Bin(eval('0x' + Hex))
十进制
In [3]:
# 示例:65535 # 二进制 转 十进制 def Bin_to_Dec(Bin): Dec = 0 for i in range(len(Bin)): Dec += Bin[-i-1] * 2 ** i return Dec # 十六进制 转 十进制 def Hex_to_Dec(Hex): return eval('0x' + Hex)
8位十六进制(字符串形式)
In [4]:
# 示例:'0000ffff' # 32位二进制 转 8位十六进制 def Bin_to_Hex(Bin): Hex = '' for i in range(len(Bin)//4): tmp = hex(Bin_to_Dec(Bin[4 * i : 4 * (i + 1)]))[-1] Hex += str(tmp) return Hex # 十进制 转 8位十六进制 def Dec_to_Hex(Dec): Dec %= 2**32 Hex = '' for tmp1 in [hex(Dec >> (tmp2 * 4) & 0xf)[-1] for tmp2 in range(8)][::-1]: Hex += str(tmp1) return Hex
64位十六进制(字符串形式)
In [5]:
# 十进制 转 64位十六进制 def Dec_to_Hex_64(Dec): Hex = '' for tmp1 in [hex((Dec) >> (tmp2 * 4) & 0xf)[-1] for tmp2 in range(64)][::-1]: Hex += str(tmp1) return Hex
定义 循环左移 和 按位取反 函数
In [6]:
# 循环左移 def cycle_left(X, n, dtype): if dtype == 'Bin': n = n % 32 return Bin_to_Dec(np.append(X[n:], X[:n])) elif dtype == 'Dec': return cycle_left(Dec_to_Bin(X), n, 'Bin') elif dtype == 'Hex': return cycle_left(Hex_to_Bin(X), n, 'Bin') else: raise TypeError("二进制请输入np_bin和Bin,十进制请输入num和Dec,十六进制请输入str和Hex")
In [7]:
# 按位取反 def invert(X, dtype): if dtype == 'Bin': for i in range(len(X)): if X[i] == 0: X[i] = 1 else: X[i] = 0 return Bin_to_Dec(X) elif dtype == 'Dec': return invert(Dec_to_Bin(X), 'Bin') elif dtype == 'Hex': return invert(Hex_to_Bin(X), 'Bin') else: raise TypeError("二进制请输入np_bin和Bin,十进制请输入num和Dec,十六进制请输入str和Hex")
常数与函数
In [8]:
# 初始值 IV = '7380166f4914b2b9172442d7da8a0600a96f30bc163138aae38dee4db0fb0e4e'
In [9]:
# 常量 def T(j): if 0 <= j <= 15: return 0x79cc4519 elif 16 <= j <= 63: return 0x7a879d8a
In [10]:
# 布尔函数 def FF(X, Y, Z, j): X %= 2**32 Y %= 2**32 Z %= 2**32 if 0 <= j <= 15: return X ^ Y ^ Z elif 16 <= j <= 63: return (X & Y) | (X & Z) | (Y & Z) def GG(X, Y, Z, j): X %= 2**32 Y %= 2**32 Z %= 2**32 if 0 <= j <= 15: return X ^ Y ^ Z elif 16 <= j <= 63: return (X & Y) | (invert(X, 'Dec') & Z)
In [11]:
# 置换函数 def P0(X): X %= 2**32 return X ^ cycle_left(X, 9, 'Dec') ^ cycle_left(X, 17, 'Dec') def P1(X): X %= 2**32 return X ^ cycle_left(X, 15, 'Dec') ^ cycle_left(X, 23, 'Dec')
算法实现
填充
In [12]:
# 消息m m = b'abc' # m = b'abcd' * 16
In [13]:
# 消息 -> ASCII码 -> 二进制 ASCII = np.frombuffer(m, dtype = np.uint8) Bit = np.unpackbits(ASCII)
In [14]:
# 假设消息 m 的长度为 l 比特 l = len(Bit) print("原始消息长度为 %d 比特" % l)
Out [14]:
原始消息长度为 24 比特
In [15]:
# 在消息的末尾添加一个1比特的数值"1",N_512_Bit 代表 512整数倍比特 ONE = np.ones(1, dtype = np.uint8) N_512_Bit = np.append(Bit, ONE)
In [16]:
# N 为512比特长度的倍数 # k 为需要添加的0的个数,满足 l + 1 + k = 448mod512 N = 1 while True: if l + 1 + 64 <= 512 * N: k = 512 * N - l - 1 - 64 break N += 1
In [17]:
# 添加消息长度(不包括最后一个分组) print("需要添加 %d 个'0'" % k) ZEROS = np.zeros(k, dtype = np.uint8) N_512_Bit = np.append(N_512_Bit, ZEROS)
Out [17]:
需要添加 423 个'0'
In [18]:
# 保存原始消息的长度到最后一个分组的最后64比特 last_64_bit = [l >> d & 1 for d in range(64)][::-1] last_64_bit = np.array(last_64_bit, dtype = np.uint8) N_512_Bit = np.append(N_512_Bit, last_64_bit)
In [19]:
# 填充后的结果展示(二进制表示) for i in range(len(N_512_Bit)): print(N_512_Bit[i], end = '') if (i + 1) % 64 == 0: print() elif (i + 1) % 8 == 0: print(end = ' ') else: pass
Out [19]:
01100001 01100010 01100011 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00011000
In [20]:
# 填充后的结果展示(十六进制表示) N_128_hex = Bin_to_Hex(N_512_Bit) for i in range(len(N_128_hex)): print(N_128_hex[i], end = '') if (i + 1) % 64 == 0: print() elif (i + 1) % 8 == 0: print(end = ' ') else: pass
Out [20]:
61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018
迭代压缩
迭代过程
In [22]:
# 按512比特进行分组 def split_group(N_512_Bit, N): print("有 %d 个组" % N) Group = {} for i in range(N): Group["Group" + str(i)] = message_extension(N_512_Bit[512 * i : 512 * (i + 1)]) return Group
In [23]:
# 将填充后的消息 m' 按512比特进行分组(程序中用 m_ 代替 m') Group = split_group(N_512_Bit, N)
Out [23]:
有 1 个组
In [26]:
V_i_1 = V_i = IV for n in range(N): B_i = Group['Group' + str(n)] V_i = V_i_1 # V(i + 1) = CF(V(i), B(i)) V_i_1 = CF(V_i, B_i)
Out [26]:
j A B C D E F G H 7380166f 4914b2b9 172442d7 da8a0600 a96f30bc 163138aa e38dee4d b0fb0e4e 0 b9edc12b 7380166f 29657292 172442d7 b2ad29f4 a96f30bc c550b189 e38dee4d 1 ea52428c b9edc12b 002cdee7 29657292 ac353a23 b2ad29f4 85e54b79 c550b189 2 609f2850 ea52428c db825773 002cdee7 d33ad5fb ac353a23 4fa59569 85e54b79 3 35037e59 609f2850 a48519d4 db825773 b8204b5f d33ad5fb d11d61a9 4fa59569 4 1f995766 35037e59 3e50a0c1 a48519d4 8ad212ea b8204b5f afde99d6 d11d61a9 5 374a0ca7 1f995766 06fcb26a 3e50a0c1 acf0f639 8ad212ea 5afdc102 afde99d6 6 33130100 374a0ca7 32aecc3f 06fcb26a 3391ec8a acf0f639 97545690 5afdc102 7 1022ac97 33130100 94194e6e 32aecc3f 367250a1 3391ec8a b1cd6787 97545690 8 d47caf4c 1022ac97 26020066 94194e6e 6ad473a4 367250a1 64519c8f b1cd6787 9 59c2744b d47caf4c 45592e20 26020066 c6a3ceae 6ad473a4 8509b392 64519c8f 10 481ba2a0 59c2744b f95e99a8 45592e20 02afb727 c6a3ceae 9d2356a3 8509b392 11 694a3d09 481ba2a0 84e896b3 f95e99a8 9dd1b58c 02afb727 7576351e 9d2356a3 12 89cbcd58 694a3d09 37454090 84e896b3 6370db62 9dd1b58c b938157d 7576351e 13 24c95abc 89cbcd58 947a12d2 37454090 1a4a2554 6370db62 ac64ee8d b938157d 14 7c529778 24c95abc 979ab113 947a12d2 3ee95933 1a4a2554 db131b86 ac64ee8d 15 34d1691e 7c529778 92b57849 979ab113 61f99646 3ee95933 2aa0d251 db131b86 16 796afab1 34d1691e a52ef0f8 92b57849 067550f5 61f99646 c999f74a 2aa0d251 17 7d27cc0e 796afab1 a2d23c69 a52ef0f8 b3c8669b 067550f5 b2330fcc c999f74a 18 d7820ad1 7d27cc0e d5f562f2 a2d23c69 575c37d8 b3c8669b 87a833aa b2330fcc 19 f84fd372 d7820ad1 4f981cfa d5f562f2 a5dceaf1 575c37d8 34dd9e43 87a833aa 20 02c57896 f84fd372 0415a3af 4f981cfa 74576681 a5dceaf1 bec2bae1 34dd9e43 21 4d0c2fcd 02c57896 9fa6e5f0 0415a3af 576f1d09 74576681 578d2ee7 bec2bae1 22 eeeec41a 4d0c2fcd 8af12c05 9fa6e5f0 b5523911 576f1d09 340ba2bb 578d2ee7 23 f368da78 eeeec41a 185f9a9a 8af12c05 6a879032 b5523911 e84abb78 340ba2bb 24 15ce1286 f368da78 dd8835dd 185f9a9a 62063354 6a879032 c88daa91 e84abb78 25 c3fd31c2 15ce1286 d1b4f1e6 dd8835dd 4db58f43 62063354 8193543c c88daa91 26 6243be5e c3fd31c2 9c250c2b d1b4f1e6 131152fe 4db58f43 9aa31031 8193543c 27 a549beaa 6243be5e fa638587 9c250c2b cf65e309 131152fe 7a1a6dac 9aa31031 28 e11eb847 a549beaa 877cbcc4 fa638587 e5b64e96 cf65e309 97f0988a 7a1a6dac 29 ff9bac9d e11eb847 937d554a 877cbcc4 9811b46d e5b64e96 184e7b2f 97f0988a 30 a5a4a2b3 ff9bac9d 3d708fc2 937d554a e92df4ea 9811b46d 74b72db2 184e7b2f 31 89a13e59 a5a4a2b3 37593bff 3d708fc2 0a1ff572 e92df4ea a36cc08d 74b72db2 32 3720bd4e 89a13e59 4945674b 37593bff cf7d1683 0a1ff572 a757496f a36cc08d 33 9ccd089c 3720bd4e 427cb313 4945674b da8c835f cf7d1683 ab9050ff a757496f 34 c7a0744d 9ccd089c 417a9c6e 427cb313 0958ff1b da8c835f b41e7be8 ab9050ff 35 d955c3ed c7a0744d 9a113939 417a9c6e c533f0ff 0958ff1b 1afed464 b41e7be8 36 e142d72b d955c3ed 40e89b8f 9a113939 d4509586 c533f0ff f8d84ac7 1afed464 37 e7250598 e142d72b ab87dbb2 40e89b8f c7f93fd3 d4509586 87fe299f f8d84ac7 38 2f13c4ad e7250598 85ae57c2 ab87dbb2 1a6cabc9 c7f93fd3 ac36a284 87fe299f 39 19f363f9 2f13c4ad 4a0b31ce 85ae57c2 c302badb 1a6cabc9 fe9e3fc9 ac36a284 40 55e1dde2 19f363f9 27895a5e 4a0b31ce 459daccf c302badb 5e48d365 fe9e3fc9 41 d4f4efe3 55e1dde2 e6c7f233 27895a5e 5cfba85a 459daccf d6de1815 5e48d365 42 48dcbc62 d4f4efe3 c3bbc4ab e6c7f233 6f49c7bb 5cfba85a 667a2ced d6de1815 43 8237b8a0 48dcbc62 e9dfc7a9 c3bbc4ab d89d2711 6f49c7bb 42d2e7dd 667a2ced 44 d8685939 8237b8a0 b978c491 e9dfc7a9 8ee87df5 d89d2711 3ddb7a4e 42d2e7dd 45 d2090a86 d8685939 6f714104 b978c491 2e533625 8ee87df5 388ec4e9 3ddb7a4e 46 e51076b3 d2090a86 d0b273b0 6f714104 d9f89e61 2e533625 efac7743 388ec4e9 47 47c5be50 e51076b3 12150da4 d0b273b0 3567734e d9f89e61 b1297299 efac7743 48 abddbdc8 47c5be50 20ed67ca 12150da4 3dfcdd11 3567734e f30ecfc4 b1297299 49 bd708003 abddbdc8 8b7ca08f 20ed67ca 93494bc0 3dfcdd11 9a71ab3b f30ecfc4 50 15e2f5d3 bd708003 bb7b9157 8b7ca08f c3956c3f 93494bc0 e889efe6 9a71ab3b 51 13826486 15e2f5d3 e100077a bb7b9157 cd09a51c c3956c3f 5e049a4a e889efe6 52 4a00ed2f 13826486 c5eba62b e100077a 0741f675 cd09a51c 61fe1cab 5e049a4a 53 f4412e82 4a00ed2f 04c90c27 c5eba62b 7429807c 0741f675 28e6684d 61fe1cab 54 549db4b7 f4412e82 01da5e94 04c90c27 f6bc15ed 7429807c b3a83a0f 28e6684d 55 22a79585 549db4b7 825d05e8 01da5e94 9d4db19a f6bc15ed 03e3a14c b3a83a0f 56 30245b78 22a79585 3b696ea9 825d05e8 f6804c82 9d4db19a af6fb5e0 03e3a14c 57 6598314f 30245b78 4f2b0a45 3b696ea9 f522adb2 f6804c82 8cd4ea6d af6fb5e0 58 c3d629a9 6598314f 48b6f060 4f2b0a45 14fb0764 f522adb2 6417b402 8cd4ea6d 59 ddb0a26a c3d629a9 30629ecb 48b6f060 589f7d5c 14fb0764 6d97a915 6417b402 60 71034d71 ddb0a26a ac535387 30629ecb 14d5c7f6 589f7d5c 3b20a7d8 6d97a915 61 5e636b4b 71034d71 6144d5bb ac535387 09ccd95e 14d5c7f6 eae2c4fb 3b20a7d8 62 2bfa5f60 5e636b4b 069ae2e2 6144d5bb 4ac3cf08 09ccd95e 3fb0a6ae eae2c4fb 63 1547e69b 2bfa5f60 c6d696bc 069ae2e2 e808f43b 4ac3cf08 caf04e66 3fb0a6ae
消息扩展
In [21]:
def message_extension(_512_bit): W = {} # W0 ~ W67 for j in range(68): # W0 ~ W15 if j <= 15: W["W" + str(j)] = Bin_to_Dec(_512_bit[32 * j : 32 * (j + 1)]) # W16 ~ W67 elif 16 <= j <= 67: W_j_16 = W["W" + str(j - 16)] W_j_13 = W["W" + str(j - 13)] W_j_9 = W["W" + str(j - 9)] W_j_6 = W["W" + str(j - 6)] W_j_3 = W["W" + str(j - 3)] W["W" + str(j)] = P1(W_j_16 ^ W_j_9 ^ cycle_left(W_j_3, 15, 'Dec')) ^ cycle_left(W_j_13, 7, 'Dec') ^ W_j_6 # W'0 ~ W'63(程序中用 W_ 代替 W') for j in range(64): W["W_" + str(j)] = W['W' + str(j)] ^ W['W' + str(j + 4)] return W
In [24]:
for j in range(N): print("W0 ~ W67") W = Group['Group' + str(j)] for i in range(68): print(Dec_to_Hex(W['W' + str(i)]), end=' ') if (i + 1) % 8 == 0: print() print("\n\n" + "W'0 ~ W'63") W = Group['Group' + str(j)] for i in range(64): print(Dec_to_Hex(W['W_' + str(i)]), end=' ') if (i + 1) % 8 == 0: print() print()
Out [24]:
W0 ~ W67 61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018 9092e200 00000000 000c0606 719c70ed 00000000 8001801f 939f7da9 00000000 2c6fa1f9 adaaef14 00000000 0001801e 9a965f89 49710048 23ce86a1 b2d12f1b e1dae338 f8061807 055d68be 86cfd481 1f447d83 d9023dbf 185898e0 e0061807 050df55c cde0104c a5b9c955 a7df0184 6e46cd08 e3babdf8 70caa422 0353af50 a92dbca1 5f33cfd2 e16f6e89 f70fe941 ca5462dc 85a90152 76af6296 c922bdb2 68378cf5 97585344 09008723 86faee74 2ab908b0 4a64bc50 864e6e08 f07e6590 325c8f78 accb8011 e11db9dd b99c0545 W'0 ~ W'63 61626380 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000018 9092e200 00000000 000c0606 719c70f5 9092e200 8001801f 93937baf 719c70ed 2c6fa1f9 2dab6f0b 939f7da9 0001801e b6f9fe70 e4dbef5c 23ce86a1 b2d0af05 7b4cbcb1 b177184f 2693ee1f 341efb9a fe9e9ebb 210425b8 1d05f05e 66c9cc86 1a4988df 14e22df3 bde151b5 47d91983 6b4b3854 2e5aadb4 d5736d77 a48caed4 c76b71a9 bc89722a 91a5caab f45c4611 6379de7d da9ace80 97c00c1f 3e2d54f3 a263ee29 12f15216 7fafe5b5 4fd853c6 428e8445 dd3cef14 8f4ee92b 76848be4 18e587c8 e6af3c41 6753d7d5 49e260d5
压缩函数
In [25]:
def CF(V_i, B_i): A = eval('0x' + V_i[ 0 : 8]) B = eval('0x' + V_i[ 8 : 16]) C = eval('0x' + V_i[16 : 24]) D = eval('0x' + V_i[24 : 32]) E = eval('0x' + V_i[32 : 40]) F = eval('0x' + V_i[40 : 48]) G = eval('0x' + V_i[48 : 56]) H = eval('0x' + V_i[56 : 64]) print(' j', '{:^9}{:^9}{:^9}{:^9}{:^9}{:^9}{:^9}{:^9}'.format('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'), sep='') print( ' ', Dec_to_Hex(A), Dec_to_Hex(B), Dec_to_Hex(C), Dec_to_Hex(D), Dec_to_Hex(E), Dec_to_Hex(F), Dec_to_Hex(G), Dec_to_Hex(H) ) for j in range(64): SS1 = cycle_left(cycle_left(A, 12, 'Dec') + E + cycle_left(T(j), j, 'Dec'), 7, 'Dec') SS2 = SS1 ^ cycle_left(A, 12, 'Dec') TT1 = FF(A, B, C, j) + D + SS2 + B_i["W_" + str(j)] TT2 = GG(E, F, G, j) + H + SS1 + B_i["W" + str(j)] D = C C = cycle_left(B, 9, 'Dec') B = A A = TT1 H = G G = cycle_left(F, 19, 'Dec') F = E E = P0(TT2) print( '{:>2}'.format(j), Dec_to_Hex(A), Dec_to_Hex(B), Dec_to_Hex(C), Dec_to_Hex(D), Dec_to_Hex(E), Dec_to_Hex(F), Dec_to_Hex(G), Dec_to_Hex(H) ) print() new_ABCDEFGH = '' for each in [A, B, C, D, E, F, G, H]: new_ABCDEFGH += Dec_to_Hex(each) V_i_1 = Hex_to_Dec(new_ABCDEFGH) ^ Hex_to_Dec(V_i) return Dec_to_Hex_64(V_i_1)
杂凑值
In [27]:
# 'abc' V_i_1 == '66c7f0f462eeedd9d1f2d46bdc10e4e24167c4875cf2f7a2297da02b8f4ba8e0'
Out [27]:
True
In [ ]:
# 'abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd' # V_i_1 == 'debe9ff92275b8a138604889c18e5a4d6fdb70e5387e5765293dcba39c0c5732'
这篇关于【Python实现】SM3密码杂凑算法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-21Python编程基础教程
- 2024-11-20Python编程基础与实践
- 2024-11-20Python编程基础与高级应用
- 2024-11-19Python 基础编程教程
- 2024-11-19Python基础入门教程
- 2024-11-17在FastAPI项目中添加一个生产级别的数据库——本地环境搭建指南
- 2024-11-16`PyMuPDF4LLM`:提取PDF数据的神器
- 2024-11-16四种数据科学Web界面框架快速对比:Rio、Reflex、Streamlit和Plotly Dash
- 2024-11-14获取参数学习:Python编程入门教程
- 2024-11-14Python编程基础入门