c++ - serpent 加密密钥调度,如何填充密钥以扩展为 256 位
问题描述
我试图从头开始实现蛇加密算法作为个人项目,现在我被它的密钥调度部分所困扰。根据唯一的文档,https://www.cl.cam.ac.uk/~rja14/Papers/serpent.pdf,我需要将密钥填充为 256,以便开始生成子密钥。
如何在不依赖外部库的情况下应用填充。
这是我写的代码,我不是 100% 肯定会引导我实现我想要实现的目标
void prekeyexpasion(unsigned char * key,unsigned char * expandedkeys){
//padd the key to 256
int originalkeylen = strlen((const char*)key);
int lenOfPaddedkey = originalkeylen;
if(lenOfPaddedkey % 32 !=0){
lenOfPaddedkey = (lenOfPaddedkey / 32 + 1) * 32;
}
unsigned char * paddedkey = new unsigned char[lenOfPaddedkey];
for (int i = 0; i < lenOfPaddedkey; i++){
if ( i >= originalkeylen){
paddedkey[i] = 1;
}
else{
paddedkey[i] = key[i];
}
}
//expand to 33 128bit subkeys
//split per 128bit subkeys to 8 32 bit subsubkey
}
解决方案
让我们看一下标准,假设本文开头指出的小端表示:
用户密钥长度是可变的,但出于本次提交的目的,我们将其固定为 128、192 或 256 位;少于 256 位的短密钥映射到 256 位的全长密钥,方法是在 MSB 端附加一个“1”位,后跟所需数量的“0”位以组成 256 位。
然后看看你的代码:
int originalkeylen = strlen((const char*)key);
首先,密钥不是密码。它是二进制字符串,而不是文本字符串。这意味着strlen
不能在键上使用。相反,密钥的大小应该在提供时包含在密钥中(或者您应该使用更高级别的构造来传递密钥,毕竟这是 C++,而不是 C)。
int lenOfPaddedkey = originalkeylen;
一般来说,我永远不会为变量分配不正确的值,即使不是暂时的。
if(lenOfPaddedkey % 32 !=0){
lenOfPaddedkey = (lenOfPaddedkey / 32 + 1) * 32;
}
您首先使用警卫检查密钥大小是否正确。在这种情况下% 32
不需要,您不妨使用lenOfPaddedkey != 32
. 除此之外,lenOfPaddedkey / 32
将始终为零,因此整行也可能是int lenOfPaddedkey = 32
,这应该是正确的。但是,如果它总是 32,为什么还需要一个变量呢?
unsigned char * paddedkey = new unsigned char[lenOfPaddedkey];
嗯,我不喜欢在char *
这里使用,但是好的,我们有一个由字节组成的新缓冲区。请注意,此调用不会初始化为零,请参阅此处了解更多信息。
for (int i = 0; i < lenOfPaddedkey; i++){
好的,很好,虽然只是输入一个 32 字面量(作为常量 /#define
可能会加快速度)。
if ( i >= originalkeylen){
paddedkey[i] = 1;
}
这是不正确的,应该只添加一位/字节,然后添加零位/字节。
else{
paddedkey[i] = key[i];
}
是的,仅使用库调用来复制字节可能会更快。
反而:
检查密钥的大小,应为 16、24 或 32 字节;
创建4 个值
padded_key
的缓冲区;int32_t
将字节复制到
padded_key
缓冲区中(看看这个答案,注意 C++ 整数是一个未定义的混乱);如果需要,执行填充:
一种。如果 2
int32_t
用于 128 位密钥,则将 3rd 设置int32_t
为值 1 并将 finalint32_t
设置为零;湾。如果 3
int32_t
用于 192 位密钥,则将第 4 个设置int32_t
为值 1。
现在您可以根据 32 位字中的填充键继续进行键扩展(您可能首先需要更大的缓冲区吗?)。
推荐阅读
- java - 在按下 Tab 按钮后,编辑 JTable 中的单元格似乎会改变表格的行为
- python - 验证码验证 Python Django
- jquery - jQuery Validate 插件未按预期工作
- pandas - 如何根据整数索引返回一个列值和熊猫中的另一个列值?
- c# - 如何输入 CMD 文本(密码)并检查安全性是否开启?
- sympy - SymPy 简化不能 2*3**n/3 ---> 2*3**(n-1)
- angular - 如何使用 Protractor 打字稿点击 ng-href 和 buttontext
- logging - 为什么我在 Clojure 中使用 taoensso.timbre.appenders.3rd-party.gelf appender 的 Graylog 消息不可读?
- function-points - 创建和更新是否被视为功能点估计的单独“外部输入”?
- java - 使用 Java RegEx 解析 BibTeX 记录