我正在尝试理解生成圆键的按位运算。下面是给我的代码:
def generateRoundkeys80(key, rounds):
"""Generate the roundkeys for a 80-bit key
Input:
key: the key as a 80-bit integer
rounds: the number of rounds as an integer
Output: list of 64-bit roundkeys as integers"""
roundkeys = []
for i in xrange(1, rounds + 1): # (K1 ... K32)
# rawkey: used in comments to show what happens at bitlevel
# rawKey[0:64]
roundkeys.append(key >> 16)
# 1. Shift
# rawKey[19:len(rawKey)]+rawKey[0:19]
key = ((key & (2 ** 19 - 1)) << 61) + (key >> 19)
# 2. SBox
# rawKey[76:80] = S(rawKey[76:80])
key = (Sbox[key >> 76] << 76) + (key & (2 ** 76 - 1))
#3. Salt
#rawKey[15:20] ^ i
key ^= i << 15
return roundkeys
我所理解的是,(1)我们进行61位的左旋转(我实现了key = (key << 61)|(key >> (len(key) - 61))
),(2)将sbox应用到最左边的4位,(3) XOR ( 15-19位)的圆形计数器。但是,当涉及到按位操作时,我不理解**和to +的含义。任何解释都将不胜感激!
发布于 2020-10-12 15:20:48
让我们在代码中考虑下面一行,希望所有操作都会变得清晰起来:
key = ((key & (2 ** 19 - 1)) << 61) + (key >> 19)
让我们从表达式(2 ** 19 - 1)
开始。运算符**
是指数运算。在您介绍的代码中,它用于构造将用作操作掩码的二进制数字。例如,二进制中的数字2 ** 19
将是"1“,后面是19个零。2 ** 19 - 1
数是19个。
当您执行(key & (2 ** 19 - 1))
时,它是按位排列的,这将给您提供键的最后19个位,而<< 61
将在右边添加61个零,因此您将得到键的最后19个位数,后面是61个零。
(key >> 19)
将在键中转储最右边的19个数字,并将其余的数字向上移动,在左侧填充19个零。所以当你把这两个数字相加时,每个数字只有零,而另一个数字有数据。+
实际上只是将它们组合在一起。
您可以使用print {0.b}.format(key)
查看数字的二进制字符串表示形式,如果您想遵循Python的计算。
https://stackoverflow.com/questions/64319438
复制相似问题