C 理解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]<&

查看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]<<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执行)