C 理解raiden密码:代码中未定义的行为?
查看raiden密码,不确定我是否理解密码:C 理解raiden密码:代码中未定义的行为?,c,encryption,undefined-behavior,C,Encryption,Undefined Behavior,查看raiden密码,不确定我是否理解密码: void raiden(unsigned long *in,unsigned long *res,unsigned long *key) { unsigned long b0=in[0],b1=in[1],i,k[4]={key[0],key[1],key[2],key[3]},sk; for(i=0; i< 16; i++) { sk=k[i%4]=((k[0]+k[1])+((k[2]-k[3])ˆ(k[0]<&
void raiden(unsigned long *in,unsigned long *res,unsigned long *key)
{
unsigned long b0=in[0],b1=in[1],i,k[4]={key[0],key[1],key[2],key[3]},sk;
for(i=0; i< 16; i++)
{
sk=k[i%4]=((k[0]+k[1])+((k[2]-k[3])ˆ(k[0]<<k[2])));
b0 += ((sk+b1)<<9)ˆ((sk-b1)ˆ((sk+b1)>>14));
b1 += ((sk+b0)<<9)ˆ((sk-b0)ˆ((sk+b0)>>14));
}
res[0]=b0;
res[1]=b1;
}
void raiden(无符号长*英寸、无符号长*分辨率、无符号长*键)
{
无符号长b0=in[0],b1=in[1],i,k[4]={key[0],key[1],key[2],key[3]},sk;
对于(i=0;i<16;i++)
{
sk=k[i%4]=((k[0]+k[1])+((k[2]-k[3])ˆ(k[0]不知道你为什么对这个特殊的密码感兴趣,它似乎没有得到太多的发展。从可用的小片段信息来看,键[0]到键[3]似乎被视为32位量。如果是这样,表达式(k[0]据我所知,雷登是一个OK算法,没有已知的陷阱,但它没有真正的测试和标准化。它的工作非常类似于它的密码类的其余部分,它应该与之相称,但很难说清楚。我在一些非关键应用中使用了好几次,在那里至少真的很好。有些数据的真实性可以得到保证,但没有实际的要求
该算法唯一的缺点是其推荐的实现仅在C中提供,并且它使用带溢出操作的按位移位,根据平台上的编译器(不同版本的GCC、IAR、Keil等),溢出操作的工作方式可能有所不同(GCC对于x86和ARM给出了类似的汇编指令,但是它们在实际硬件上的执行结果是不同的),并且在选择的编程语言(C、java、D和C++实现中可以不同地工作)。因此,不同的设备和程序很有可能在功能结果上产生不同的意见
为了克服这个问题,我对原始代码进行了一点修改,使其与平台无关,同时保留了总体思路,希望保留大部分原始性能和其他特征。这里包括一个简单的MAC实现。这不是一个完美的解决方案,代码看起来有点难看,但它工作得很好到目前为止,它在我测试过的所有平台上都给出了相同的结果,并且应该比原来的平台更容易理解
享受吧!当然,如果你还需要的话
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
#include <string.h> // memcpy, memset and the others are defined here
// Platform-independent cyclic shifts. Rewrite as functions when needed.
#define BitsCount( val ) ( sizeof( val ) * CHAR_BIT )
#define Shift( val, steps ) ( steps % BitsCount( val ) )
#define ROL( val, steps ) ( ( val << Shift( val, steps ) ) | ( val >> ( BitsCount( val ) - Shift( val, steps ) ) ) )
#define ROR( val, steps ) ( ( val >> Shift( val, steps ) ) | ( val << ( BitsCount( val ) - Shift( val, steps ) ) ) )
void RaidenEncoder(const uint32_t key[4], const uint32_t data[2], uint32_t result[2])
{
uint32_t k[4];
uint32_t b0 = data[0], b1 = data[1];
register int8_t i;
k[0]=key[0]; k[1]=key[1]; k[2]=key[2]; k[3]=key[3];
for (i=0; i<16; i++) {
register uint32_t sk;
sk = k[i%4] = ((k[0]+k[1])+((k[2]+k[3])^ROL(k[0],k[2])));
b0 += ((sk+b1)<<9) ^ ((sk-b1)^((sk+b1)>>14));
b1 += ((sk+b0)<<9) ^ ((sk-b0)^((sk+b0)>>14));
}
result[0] = b0;
result[1] = b1;
}
void RaidenDecoder(const uint32_t key[4], const uint32_t data[2], uint32_t result[2])
{
register uint32_t b0 = data[0], b1 = data[1];
register int8_t i;
uint32_t k[4];
uint32_t subkeys[16];
k[0]=key[0]; k[1]=key[1]; k[2]=key[2]; k[3]=key[3];
//Prepare subkeys
for(i=0; i<16; i++) {
k[i%4]=((k[0]+k[1])+((k[2]+k[3])^ROL(k[0],k[2])));
subkeys[i]=k[i%4];
}
for(i=15; i>=0; i--) {
//Process is applied in the inverse order
b1 -= ((subkeys[i]+b0)<<9)^((subkeys[i]-b0)^((subkeys[i]+b0)>>14));
b0 -= ((subkeys[i]+b1)<<9)^((subkeys[i]-b1)^((subkeys[i]+b1)>>14));
}
result[0]=b0;
result[1]=b1;
}
// Message authentication code checking function (64-bit digests and 128-bit keys are used).
bool CheckRaidenMAC(const uint32_t key[4], const uint32_t mac[2], uint8_t* data, const uint32_t length)
{
register uint32_t i;
uint32_t stage_result[2] = {0,0}; // We use fixed all-zero init vector
uint32_t encoder_input[2] = {0,0};
uint8_t remainder_length = length%8;
// Process data length information as the first stage
encoder_input[0] = length;
RaidenEncoder(key, encoder_input, stage_result);
// Calculate the MAC
for (i=0;i<length;i+=8) {
encoder_input[0] = stage_result[0] ^ *((uint32_t*)&data[i]);
encoder_input[1] = stage_result[1] ^ *((uint32_t*)&data[i+1]);
RaidenEncoder(key, encoder_input, stage_result);
}
// Check if we need to add padding to calculate the final stage
if (remainder_length) {
// Load the data remainder
memcpy(&encoder_input[0], &data[length-remainder_length], remainder_length);
// Put in zero padding
memset(&encoder_input[remainder_length], 0, 8-remainder_length);
// Process the last stage
encoder_input[0] ^= stage_result[0];
encoder_input[1] ^= stage_result[1];
RaidenEncoder(key, encoder_input, stage_result);
}
// Check if our digest matches the provided one
return ((mac[0] == stage_result[0]) && (mac[1] == stage_result[1]));
}
#包括
#包括
#包括
#include//memcpy、memset和其他定义如下
//与平台无关的循环移位。需要时重写为函数。
#定义BitsCount(val)(大小(val)*字符位)
#定义班次(val,步骤)(步骤%BITSCONT(val))
#定义ROL(val,步骤)((val>(BitScont(val)-Shift(val,步骤)))
#定义ROR(val,steps)((val>>Shift(val,steps))|(val为什么有人知道“raiden”密码是什么?也许你可以包含一个带有一些附加信息和上下文的链接。你的代码片段从何而来?上面的代码是定义的。使用无符号数学,结果被定义为换行。(模ULONG_MAX+1)@GregS Maybe 1)“这是一个旋转,…为什么要使用移位”C没有旋转,所以旋转是用移位的组合来完成的。2)建议使用uint32\u t
,因为无符号长位长度可能是32、64等等。@chux:expression(k[0]如果#2是目的,那么代码可以通过执行k[0]来修复,我个人更喜欢(k[2]&31)而不是进行模运算。看起来所需的效果是no.2,示例代码在英特尔硬件上执行,通常在汇编级别执行(即,SHL EAX,0x21是有效命令,但将作为SHL EAX,1执行)