基于Python整数移位、与操作的AES加密算法

  1. 主算法
    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)
    

     

  2. 需要用到GF(2^8)域上的乘法操作,算法写在multi_Num.py中,传送门
    @Nickname4th  Hainu University  2018.12.9
    另,该算法已经作为课程作业上交,学弟学妹可以借鉴,但是不能照搬,否则后果自负。
    创作不易,望支持。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值