- 主算法
import multi_Num sbox = {0: 99, 1: 124, 2: 119, 3: 123, 4: 242, 5: 107, 6: 111, 7: 197, 8: 48, 9: 1, 10: 103, 11: 43, 12: 254, 13: 215, 14: 171, 15: 118, 16: 202, 17: 130, 18: 201, 19: 125, 20: 250, 21: 89, 22: 71, 23: 240, 24: 173, 25: 212, 26: 162, 27: 175, 28: 156, 29: 164, 30: 114, 31: 192, 32: 183, 33: 253, 34: 147, 35: 38, 36: 54, 37: 63, 38: 247, 39: 204, 40: 52, 41: 165, 42: 229, 43: 241, 44: 113, 45: 216, 46: 49, 47: 21, 48: 4, 49: 199, 50: 35, 51: 195, 52: 24, 53: 150, 54: 5, 55: 154, 56: 7, 57: 18, 58: 128, 59: 226, 60: 235, 61: 39, 62: 178, 63: 117, 64: 9, 65: 131, 66: 44, 67: 26, 68: 27, 69: 110, 70: 90, 71: 160, 72: 82, 73: 59, 74: 214, 75: 179, 76: 41, 77: 227, 78: 47, 79: 132, 80: 83, 81: 209, 82: 0, 83: 237, 84: 32, 85: 252, 86: 177, 87: 91, 88: 106, 89: 203, 90: 190, 91: 57, 92: 74, 93: 76, 94: 88, 95: 207, 96: 208, 97: 239, 98: 170, 99: 251, 100: 67, 101: 77, 102: 51, 103: 133, 104: 69, 105: 249, 106: 2, 107: 127, 108: 80, 109: 60, 110: 159, 111: 168, 112: 81, 113: 163, 114: 64, 115: 143, 116: 146, 117: 157, 118: 56, 119: 245, 120: 188, 121: 182, 122: 218, 123: 33, 124: 16, 125: 255, 126: 243, 127: 210, 128: 205, 129: 12, 130: 19, 131: 236, 132: 95, 133: 151, 134: 68, 135: 23, 136: 196, 137: 167, 138: 126, 139: 61, 140: 100, 141: 93, 142: 25, 143: 115, 144: 96, 145: 129, 146: 79, 147: 220, 148: 34, 149: 42, 150: 144, 151: 136, 152: 70, 153: 238, 154: 184, 155: 20, 156: 222, 157: 94, 158: 11, 159: 219, 160: 224, 161: 50, 162: 58, 163: 10, 164: 73, 165: 6, 166: 36, 167: 92, 168: 194, 169: 211, 170: 172, 171: 98, 172: 145, 173: 149, 174: 228, 175: 121, 176: 231, 177: 200, 178: 55, 179: 109, 180: 141, 181: 213, 182: 78, 183: 169, 184: 108, 185: 86, 186: 244, 187: 234, 188: 101, 189: 122, 190: 174, 191: 8, 192: 186, 193: 120, 194: 37, 195: 46, 196: 28, 197: 166, 198: 180, 199: 198, 200: 232, 201: 221, 202: 116, 203: 31, 204: 75, 205: 189, 206: 139, 207: 138, 208: 112, 209: 62, 210: 181, 211: 102, 212: 72, 213: 3, 214: 246, 215: 14, 216: 97, 217: 53, 218: 87, 219: 185, 220: 134, 221: 193, 222: 29, 223: 158, 224: 225, 225: 248, 226: 152, 227: 17, 228: 105, 229: 217, 230: 142, 231: 148, 232: 155, 233: 30, 234: 135, 235: 233, 236: 206, 237: 85, 238: 40, 239: 223, 240: 140, 241: 161, 242: 137, 243: 13, 244: 191, 245: 230, 246: 66, 247: 104, 248: 65, 249: 153, 250: 45, 251: 15, 252: 176, 253: 84, 254: 187, 255: 22} # 以字典的形式保存s盒,查表时更加方便,无需再转换高低四位 X2 = [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, 272, 274, 276, 278, 280, 282, 7, 5, 59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101, 155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165, 219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229] X3 = [0, 12, 24, 36, 48, 60, 72, 84, 96, 108, 120, 132, 144, 156, 168, 180, 192, 204, 216, 228, 240, 252, 264, 276, 59, 55, 35, 95, 75, 71, 115, 111, 155, 151, 131, 191, 171, 167, 211, 207, 251, 247, 227, 50, 38, 42, 30, 2, 118, 122, 110, 82, 70, 74, 190, 162, 150, 154, 142, 242, 230, 234, 222, 194, 45, 33, 53, 274, 262, 266, 101, 121, 77, 65, 85, 169, 189, 177, 133, 153, 237, 225, 245, 201, 221, 209, 100, 120, 76, 64, 84, 40, 60, 48, 4, 24, 236, 224, 244, 200, 220, 208, 164, 184, 140, 128, 148, 115, 103, 107, 95, 67, 55, 59, 47, 264, 7, 272, 255, 227, 215, 219, 207, 179, 167, 171, 159, 131, 90, 86, 66, 126, 106, 102, 18, 14, 58, 54, 34, 222, 202, 198, 242, 238, 154, 150, 130, 190, 170, 166, 73, 85, 97, 109, 121, 5, 266, 262, 41, 53, 193, 205, 217, 229, 241, 253, 137, 149, 161, 173, 185, 220, 200, 196, 240, 236, 152, 148, 128, 188, 168, 164, 80, 76, 120, 116, 96, 28, 8, 4, 48, 44, 195, 207, 219, 231, 243, 255, 139, 151, 163, 175, 187, 71, 83, 95, 107, 119, 280, 276, 256, 39, 51, 63, 230, 250, 206, 194, 214, 170, 190, 178, 134, 154, 110, 98, 118, 74, 94, 82, 38, 58, 14, 2, 22, 241, 229, 233, 221, 193, 181, 185, 173, 145, 133, 137, 125, 97, 85, 89, 77, 49, 37, 41, 262, 282] RC = [1, 2, 4, 8, 16, 32, 64, 128, 27, 54] # 将RC以十进制表示,RC的产生是GF(2^8)域上的乘法 def sboxChange(plain): s = 0 for i in range(0, 128, 8): s ^= (sbox[(plain >> i) & 255]) << i return s def mov(num, i): # i是需要移位的次数 for i in range(0, i): num = ((num & 255) << 24) ^ (num >> 8) # b循环右移一个字节,同时也可以看作左移3个字节 return num def rowMove(a, time): # 加密运算时time=1,解密运算时time=3因为循环左移3个字节等价于循环右移一个字节 for i in range(0, time): b = 0 for i in range(0, 4): b ^= (((a >> (96 - i * 32)) & (255 << 24)) ^ ((a >> 32 * ((3 * i + 2) % 4)) & (255 << 16)) ^ ( (a >> 32 * ((3 * i + 1) % 4)) & (255 << 8)) ^ ((a >> 32 * ((3 * i) % 4)) & 255)) << (32 * (3 - i)) a = b # print(hex(b))过程检验 return a def columMix(num): # 加密的列混淆变换 colummix = 0 for i in range(0, 128, 32): s = 0 # s清零以记录本轮结果 colum = num >> i & (pow(2, 32) - 1) # 移位以处理下一个列向量 colum1 = mov(colum, 3) # 循环左移一个字节 temp = (colum & 255) ^ ((colum >> 8) & 255) ^ ((colum >> 16) & 255) ^ ((colum >> 24) & 255) for j in range(0, 32, 8): s ^= multi_Num.multi_multiplication(1, ( (colum >> j) & 255 ^ temp ^ X2[(colum >> j) & 255 ^ (colum1 >> j) & 255]))[1] << j # 查表的过程 # 列混淆会用到GF(2^8)域上的乘法 # print(hex(s)) 过程检测 colummix ^= s << i return colummix def key_extends(key): # 密钥扩展,key是整数 for i in range(4, 44): if i % 4 == 0: # 用到g函数的过程 start = (key >> 96) & (pow(2, 32) - 1) # 取开始8个字节 final = key & (pow(2, 32) - 1) # 取a的最后8个字节 leftmov = (final >> 24) ^ ((final & (pow(2, 24) - 1)) << 8) # final循环左移一个字节 w = sbox[leftmov & 255] ^ (sbox[(leftmov >> 8) & 255] << 8) ^ \ (sbox[(leftmov >> 16) & 255] << 16) ^ (sbox[(leftmov >> 24) & 255] << 24) # 查字典再移位异或起来生产w w ^= RC[(i - 4) // 4] * pow(2, 24) ^ start # print(hex(w)) 检验生产的密钥 key = (key << 32) ^ w # key变长 else: # 不用g函数的过程 start = (key >> 96) & (pow(2, 32) - 1) # 取开始8个字节 final = key & (pow(2, 32) - 1) # 取a的最后8个字节 w = start ^ final # print(hex(w)) 检验生产的密钥 key = (key << 32) ^ w # key变长 return key def plusPlainKey(key, plain, mode): # 轮密钥加 plain1 = 0 for i in range(0, 128, 8): if mode == 0: plain1 ^= ((key >> i) & 255 ^ (plain >> i) & 255) << i else: plain1 ^= ((key >> (128-i)) & 255 ^ (plain >> (128-i)) & 255) << i # print(hex(plain1)) return plain1 def AesSingle(key, plain, i): # 单轮aes加密,i用于if条件判断第九轮和第十轮的运算 plus = plusPlainKey(key, plain,0) print(i, "轮开始", hex(plus)) if i < 10: s = sboxChange(plus) print("字节代替后", hex(s)) r = rowMove(s,1) print("行移位后", hex(r)) plain = r if i < 9: c = columMix(r) print("列混淆后", hex(c)) plain = c return plain if __name__ == '__main__': print("输入明文,示例:", "0123456789abcdeffedcba9876543210") plain = int(input(), 16) print("输入密钥,示例:", "0f1571c947d9e8590cb7add6af7f6798") key = int(input(), 16) key = key_extends(key) for i in range(0, 11): key1 = key >> (128 * (10 - i)) & pow(2, 128) - 1 print("---------------------------------------------------") print(i, "轮密钥", hex(key1)) plain = AesSingle(key1, plain, i)
-
需要用到GF(2^8)域上的乘法操作,算法写在multi_Num.py中,传送门。
@Nickname4th Hainu University 2018.12.9
另,该算法已经作为课程作业上交,学弟学妹可以借鉴,但是不能照搬,否则后果自负。
创作不易,望支持。
基于Python整数移位、与操作的AES加密算法
最新推荐文章于 2024-06-14 11:20:52 发布