1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219
|
from collections import Counter from Crypto.Util.number import long_to_bytes,bytes_to_long import exp
SM4_BOXES_TABLE = [ 0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16, 0xb6, 0x14, 0xc2, 0x28, 0xfb, 0x2c, 0x05, 0x2b, 0x67, 0x9a, 0x76, 0x2a, 0xbe, 0x04, 0xc3, 0xaa, 0x44, 0x13, 0x26, 0x49, 0x86, 0x06, 0x99, 0x9c, 0x42, 0x50, 0xf4, 0x91, 0xef, 0x98, 0x7a, 0x33, 0x54, 0x0b, 0x43, 0xed, 0xcf, 0xac, 0x62, 0xe4, 0xb3, 0x1c, 0xa9, 0xc9, 0x08, 0xe8, 0x95, 0x80, 0xdf, 0x94, 0xfa, 0x75, 0x8f, 0x3f, 0xa6, 0x47, 0x07, 0xa7, 0xfc, 0xf3, 0x73, 0x17, 0xba, 0x83, 0x59, 0x3c, 0x19, 0xe6, 0x85, 0x4f, 0xa8, 0x68, 0x6b, 0x81, 0xb2, 0x71, 0x64, 0xda, 0x8b, 0xf8, 0xeb, 0x0f, 0x4b, 0x70, 0x56, 0x9d, 0x35, 0x1e, 0x24, 0x0e, 0x5e, 0x63, 0x58, 0xd1, 0xa2, 0x25, 0x22, 0x7c, 0x3b, 0x01, 0x21, 0x78, 0x87, 0xd4, 0x00, 0x46, 0x57, 0x9f, 0xd3, 0x27, 0x52, 0x4c, 0x36, 0x02, 0xe7, 0xa0, 0xc4, 0xc8, 0x9e, 0xea, 0xbf, 0x8a, 0xd2, 0x40, 0xc7, 0x38, 0xb5, 0xa3, 0xf7, 0xf2, 0xce, 0xf9, 0x61, 0x15, 0xa1, 0xe0, 0xae, 0x5d, 0xa4, 0x9b, 0x34, 0x1a, 0x55, 0xad, 0x93, 0x32, 0x30, 0xf5, 0x8c, 0xb1, 0xe3, 0x1d, 0xf6, 0xe2, 0x2e, 0x82, 0x66, 0xca, 0x60, 0xc0, 0x29, 0x23, 0xab, 0x0d, 0x53, 0x4e, 0x6f, 0xd5, 0xdb, 0x37, 0x45, 0xde, 0xfd, 0x8e, 0x2f, 0x03, 0xff, 0x6a, 0x72, 0x6d, 0x6c, 0x5b, 0x51, 0x8d, 0x1b, 0xaf, 0x92, 0xbb, 0xdd, 0xbc, 0x7f, 0x11, 0xd9, 0x5c, 0x41, 0x1f, 0x10, 0x5a, 0xd8, 0x0a, 0xc1, 0x31, 0x88, 0xa5, 0xcd, 0x7b, 0xbd, 0x2d, 0x74, 0xd0, 0x12, 0xb8, 0xe5, 0xb4, 0xb0, 0x89, 0x69, 0x97, 0x4a, 0x0c, 0x96, 0x77, 0x7e, 0x65, 0xb9, 0xf1, 0x09, 0xc5, 0x6e, 0xc6, 0x84, 0x18, 0xf0, 0x7d, 0xec, 0x3a, 0xdc, 0x4d, 0x20, 0x79, 0xee, 0x5f, 0x3e, 0xd7, 0xcb, 0x39, 0x48, ] Dance_Box = [[46, 38, 43, 106, 114, 176, 12, 69, 1, 21, 82, 27, 184, 109, 170, 0, 179, 25, 4, 145, 33, 61, 66, 223, 85, 238, 22, 23, 59, 64, 19, 174, 180, 240, 111, 128, 187, 65, 72, 35, 77, 221, 157, 172, 13, 197, 44, 229, 226, 130, 220, 49, 198, 24, 103, 76, 39, 211, 191, 115, 165, 206, 30, 7, 98, 156, 205, 181, 89, 252, 58, 138, 253, 104, 212, 236, 54, 224, 166, 155, 118, 8, 93, 140, 28, 95, 225, 248, 80, 182, 112, 63, 192, 116, 47, 217, 91, 84, 144, 53, 124, 117, 16, 73, 218, 254, 188, 18, 11, 107, 222, 5, 52, 129, 194, 173, 81, 9, 137, 246, 242, 143, 175, 147, 74, 195, 41, 133, 207, 120, 92, 17, 164, 169, 171, 48, 241, 57, 31, 83, 55, 96, 29, 185, 68, 232, 70, 148, 243, 209, 100, 214, 37, 244, 219, 131, 203, 139, 126, 183, 167, 199, 101, 159, 50, 230, 168, 45, 149, 123, 119, 87, 134, 75, 127, 67, 250, 228, 247, 135, 113, 60, 62, 177, 150, 121, 162, 227, 142, 34, 178, 42, 15, 160, 161, 216, 235, 234, 163, 186, 154, 141, 233, 208, 78, 151, 204, 190, 86, 152, 245, 239, 108, 196, 158, 210, 99, 237, 251, 3, 40, 90, 125, 132, 36, 215, 193, 71, 255, 200, 102, 56, 32, 136, 146, 79, 97, 110, 249, 20, 202, 231, 122, 88, 94, 6, 153, 105, 14, 10, 2, 201, 189, 213, 51, 26], [246, 56, 103, 21, 181, 105, 216, 118, 145, 183, 169, 211, 27, 242, 190, 162, 237, 179, 244, 199, 206, 35, 120, 38, 95, 133, 25, 231, 3, 70, 40, 238, 223, 45, 127, 245, 4, 15, 250, 11, 52, 215, 142, 129, 167, 191, 61, 241, 188, 226, 249, 146, 221, 184, 104, 109, 157, 39, 176, 114, 236, 240, 254, 253, 251, 158, 198, 37, 42, 19, 87, 230, 153, 43, 77, 76, 208, 26, 32, 18, 150, 195, 122, 90, 80, 148, 197, 44, 83, 51, 166, 75, 88, 73, 64, 252, 20, 119, 46, 201, 196, 121, 222, 115, 22, 128, 164, 102, 97, 5, 217, 172, 177, 81, 58, 234, 168, 60, 29, 124, 147, 101, 224, 151, 130, 65, 98, 225, 155, 91, 108, 152, 140, 219, 9, 24, 189, 203, 138, 160, 59, 48, 193, 14, 69, 159, 233, 53, 135, 143, 33, 165, 41, 132, 57, 187, 227, 93, 200, 1, 0, 149, 137, 194, 23, 117, 170, 247, 17, 255, 92, 205, 47, 213, 136, 66, 2, 209, 6, 110, 78, 63, 28, 74, 235, 229, 30, 139, 154, 94, 131, 49, 86, 185, 163, 79, 68, 8, 72, 174, 99, 111, 141, 107, 210, 34, 207, 239, 106, 144, 228, 186, 89, 204, 55, 54, 171, 161, 100, 16, 13, 7, 50, 182, 112, 173, 212, 31, 214, 85, 156, 180, 175, 116, 248, 243, 36, 82, 134, 123, 220, 10, 125, 96, 67, 62, 12, 202, 126, 71, 84, 113, 232, 178, 192, 218], [46, 38, 43, 106, 114, 176, 12, 69, 1, 21, 82, 27, 184, 109, 170, 0, 179, 25, 4, 145, 33, 61, 66, 223, 85, 238, 22, 23, 59, 64, 19, 174, 180, 240, 111, 128, 187, 65, 72, 35, 77, 221, 157, 172, 13, 197, 44, 229, 226, 130, 220, 49, 198, 24, 103, 76, 39, 211, 191, 115, 165, 206, 30, 7, 98, 156, 205, 181, 89, 252, 58, 138, 253, 104, 212, 236, 54, 224, 166, 155, 118, 8, 93, 140, 28, 95, 225, 248, 80, 182, 112, 63, 192, 116, 47, 217, 91, 84, 144, 53, 124, 117, 16, 73, 218, 254, 188, 18, 11, 107, 222, 5, 52, 129, 194, 173, 81, 9, 137, 246, 242, 143, 175, 147, 74, 195, 41, 133, 207, 120, 92, 17, 164, 169, 171, 48, 241, 57, 31, 83, 55, 96, 29, 185, 68, 232, 70, 148, 243, 209, 100, 214, 37, 244, 219, 131, 203, 139, 126, 183, 167, 199, 101, 159, 50, 230, 168, 45, 149, 123, 119, 87, 134, 75, 127, 67, 250, 228, 247, 135, 113, 60, 62, 177, 150, 121, 162, 227, 142, 34, 178, 42, 15, 160, 161, 216, 235, 234, 163, 186, 154, 141, 233, 208, 78, 151, 204, 190, 86, 152, 245, 239, 108, 196, 158, 210, 99, 237, 251, 3, 40, 90, 125, 132, 36, 215, 193, 71, 255, 200, 102, 56, 32, 136, 146, 79, 97, 110, 249, 20, 202, 231, 122, 88, 94, 6, 153, 105, 14, 10, 2, 201, 189, 213, 51, 26], [206, 165, 193, 37, 187, 108, 248, 246, 44, 139, 152, 201, 173, 214, 77, 72, 97, 35, 70, 24, 3, 79, 178, 175, 30, 66, 18, 198, 114, 125, 32, 210, 180, 224, 235, 28, 62, 136, 149, 227, 82, 147, 90, 119, 85, 199, 126, 121, 51, 20, 88, 4, 75, 101, 38, 151, 109, 115, 110, 223, 43, 17, 146, 249, 226, 26, 222, 232, 87, 195, 200, 131, 245, 81, 113, 157, 220, 12, 16, 184, 204, 192, 84, 31, 197, 215, 129, 94, 93, 181, 218, 194, 65, 148, 158, 112, 221, 34, 25, 33, 243, 78, 10, 67, 209, 6, 252, 196, 237, 42, 172, 164, 161, 244, 111, 191, 46, 170, 128, 69, 183, 212, 60, 99, 8, 122, 49, 86, 247, 96, 179, 57, 135, 106, 0, 58, 100, 202, 55, 98, 1, 254, 53, 155, 156, 83, 132, 9, 19, 171, 48, 95, 166, 68, 22, 104, 7, 14, 142, 211, 213, 50, 150, 234, 182, 203, 217, 64, 185, 163, 73, 45, 41, 118, 103, 134, 186, 230, 241, 250, 52, 207, 162, 124, 140, 116, 167, 228, 92, 63, 47, 176, 239, 238, 5, 216, 225, 188, 137, 160, 80, 231, 102, 11, 89, 91, 59, 23, 240, 105, 153, 177, 138, 219, 174, 123, 36, 159, 76, 21, 56, 242, 61, 107, 133, 143, 154, 130, 233, 15, 145, 255, 13, 189, 120, 251, 236, 117, 208, 190, 169, 168, 74, 229, 54, 2, 39, 127, 29, 253, 141, 71, 205, 40, 144, 27]]
SM4_FK = [0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc]
SM4_CK = [ 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 ] i2l = lambda x: [(x >> 24) & 0xff, (x >> 16) & 0xff, (x >> 8) & 0xff, x & 0xff] l2i = lambda x: (x[0] << 24)|(x[1] << 16)|(x[2] << 8)|x[3] rotl32 = lambda x, n: ((x << n) & 0xffffffff) | ((x >> (32-n)) & 0xffffffff) rotl8 = lambda x, n: ((x << n) & 0xff) | ((x >> (8-n)) & 0xff) xor = lambda x, y: list(map(lambda a, b: a ^ b, x, y)) pad = lambda data, block=16: data + [16 - len(data) % block]*(16 - len(data) % block) rotr8 = lambda x, n: ((x >> n) & 0xff) | ((x << (8-n)) & 0xff)
def invL(A):return A ^ rotl32(A,2) ^ rotl32(A,4) ^ rotl32(A,8) ^ rotl32(A,12) ^ rotl32(A,14) ^ rotl32(A,16) ^ rotl32(A,18) ^ rotl32(A,22) ^ rotl32(A,24) ^ rotl32(A,30) def L(b):return b ^ rotl32(b, 2) ^ rotl32(b, 10) ^ rotl32(b, 18) ^ rotl32(b, 24)
def dance(): global Dance_Box Dance_Box = Dance_Box[2:]+Dance_Box[:2]
def tfunc(bk): ar = [SM4_BOXES_TABLE[i] for i in i2l(bk)] b = l2i(ar) return b ^ rotl32(b, 2) ^ rotl32(b, 10) ^ rotl32(b, 18) ^ rotl32(b, 24)
def pfunc_inv(bk): res = [] for i in range(4): sbox = Dance_Box[i] tmp = i2l(bk[i]) b = [rotr8(tmp[i],i+3) for i in range(4)] ar = [sbox.index(_) for _ in b] res.append(l2i(ar)) return res
def pfunc(bk): res = [] for i in range(4): sbox = Dance_Box[i] ar = [sbox[_] for _ in i2l(bk[i])] b = [rotl8(ar[i], i+3) for i in range(4)] res.append(l2i(b)) return res
def decry_one(bk,dt=0): dance() result = pfunc_inv(bk) dance() return result
def one_round(bk, rk): '''把当前轮的轮密钥传进来,和是否故障传进来就能获得上轮的密文''' buf = bk result = buf[3] ^ tfunc(buf[0]^buf[1]^buf[2]^rk) buf = buf[3:]+buf[:3] buf[0] = result
return buf
def find_out(outX1,outX2): in1 = i2l(outX1[0]^outX1[1]^outX1[2]) in2 = i2l(outX2[0]^outX2[1]^outX2[2]) diff = long_to_bytes(invL(outX1[3]^outX2[3])) rk = [] for _ in range(4): for k in range(256): if(SM4_BOXES_TABLE[(in1[_]^k)] ^ SM4_BOXES_TABLE[(in2[_]^k)]) == diff[_]: rk += [(k,_)] return rk
def round_key(k): ar = [SM4_BOXES_TABLE[i] for i in i2l(k)] b = l2i(ar) return b ^ rotl32(b, 13) ^ rotl32(b, 23)
def expand_key_inv(MK): k = [0]*32 k = MK + k for i in range(32): k[i + 4] = k[i] ^ (round_key(k[i + 1] ^ k[i + 2] ^ k[i + 3] ^ SM4_CK[31-i])) return xor(k[::-1][:4],SM4_FK)
def getC(c): tmp = bytes.fromhex(c) result = [bytes_to_long(tmp[:4]),bytes_to_long(tmp[4:8]),bytes_to_long(tmp[8:12]),bytes_to_long(tmp[12:16])] return result[::-1]
def getC_(c): tmp = bytes.fromhex(c) result = [bytes_to_long(tmp[16:16+4]),bytes_to_long(tmp[16+4:16+8]),bytes_to_long(tmp[16+8:16+12]),bytes_to_long(tmp[16+12:16+16])] return result[::-1]
ct = [ 'e5a304ea2ffc53a1ff94337c2b2ae5368b46c6da3cc37f8438eb967b29249d4e', '6733baa353d4cfc4ff94337c58dc7fdbd6df83f4fbf6e5e838eb967b98d7e8d3', 'e77dbfe7868701fbd7072e6358dc7fdba067d296707bad1b0f4541dc98d7e8d3', '54b772d532556d5573a6ab667c9ff76857b5efc3b62130668e46a79b163138e4', '47339f6738dd9f4c9581fbd496dde76ea320d95b457e0373cddb910acc41fe35' ]
rk = []
c1 = decry_one(getC(ct[0])) c2 = decry_one(getC(ct[1])) c1_=decry_one(getC_(ct[0])) c2_=decry_one(getC_(ct[1])) print(find_out(c1,c2)) print(find_out(c1_,c2_))
rk1 = [167,248,68,191] rk1 = bytes_to_long(bytes(rk1))
c2_= decry_one(one_round(c2_,rk1)) c2 = decry_one(one_round(c2,rk1)) c3 = decry_one(getC(ct[2])) c3 = decry_one(one_round(c3,rk1)) c3_= decry_one(getC_(ct[2])) c3_= decry_one(one_round(c3_,rk1))
print(find_out(c2,c3)) print(find_out(c2_,c3_))
rk2 = [89,46,96,172] rk2 = bytes_to_long(bytes(rk2))
c3_= decry_one(one_round(c3_,rk2)) c3 = decry_one(one_round(c3,rk2))
c4_=decry_one(getC_(ct[3])) c4_ = decry_one(one_round(c4_,rk1)) c4_ = decry_one(one_round(c4_,rk2))
c4 = decry_one(getC(ct[3])) c4 = decry_one(one_round(c4,rk1)) c4 = decry_one(one_round(c4,rk2)) print(find_out(c3,c4)) print(find_out(c3_,c4_))
rk3 = [153,189,51,187] rk3 = bytes_to_long(bytes(rk3))
c4_= decry_one(one_round(c4_,rk3)) c4 = decry_one(one_round(c4,rk3))
c5_ = decry_one(getC_(ct[4])) c5_ = decry_one(one_round(c5_,rk1)) c5_ = decry_one(one_round(c5_,rk2)) c5_ = decry_one(one_round(c5_,rk3))
c5 = decry_one(getC(ct[4])) c5 = decry_one(one_round(c5,rk1)) c5 = decry_one(one_round(c5,rk2)) c5 = decry_one(one_round(c5,rk3)) print(find_out(c4,c5)) print(find_out(c4_,c5_))
rk4 = [159,42,97,109] rk4 = bytes_to_long(bytes(rk4))
tmp = [rk1,rk2,rk3,rk4] recover = expand_key_inv(tmp)
print(recover)
c31 = long_to_bytes(0xe5a304ea2ffc53a1ff94337c2b2ae5368b46c6da3cc37f8438eb967b29249d4e) print(exp.decrypt_ecb(c31,31))
|