PRESENT密码的按位运算

问题描述

我试图理解用于生成回合密钥的按位操作。下面是给我的代码

O3:X3

我的理解是(1)我们向左旋转了61位(我实现了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 ),并且(2)将sBox应用于最左边的4位,以及(3)对具有位的循环计数器进行XOR 15-19。但是,对于按位运算,我不理解**和+的含义。任何解释将不胜感激!

解决方法

让我们考虑一下代码中的以下行,希望所有操作都将变得清晰:

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个零。因此,将两个数字加在一起时,每个数字只有零,而另一个有数据。 +实际上只是将它们放在一起。

如果要遵循Python的计算方法,可以使用print {0.b}.format(key)查看数字的二进制字符串表示形式。