S-DES实现:如何使用各个位?

时间:2013-11-27 20:43:09

标签: c algorithm encryption bit-manipulation des

我有一个要求我们实现S-DES(简化DES)的任务,该算法包括很多位排列,移位以及异或。

显然,实现这一点的最快方法是使用位操作,例如:

char CLS(char key, int shift){
    char skey;
    skey = (key << shift) | (key >> (8 - shift)) 
    return skey;
}

/* Get 8-bit subkey from 10-bit key */
char permute(short int key){
    short int i;
    short int k1[] = { BIT_6, BIT_3, BIT_7, BIT_4, BIT_8, BIT_5, BIT_10, BIT_9 }; // SDES spec
    char sk1 = '\0';

    for(i = 0; i < 8; i++){
        sk1 = (sk1 << 1) | (key & k1[i]);
    }
}

...

这很简单。但是,如何有效地获取这些位?使用像fread()这样的东西,我一次只能读取1个字节,并将其提供给SDES算法,但是这大大低估了CPU的使用率,因为我不仅仅是读取和加密1个字节。一次一个字节,我也会一次写1个字节的加密数据到磁盘!当然必须有更好的方法。

我能想到的唯一替代方法是将每个字节视为一个char数组并以这种方式操作这些位,但这不仅会增加内存开销:我仍然会遇到1个字节的问题时间我不能使用移位操作,而是需要使用临时数组和数组索引。

我希望稍微改善这种行为,但我能想到的只是将更大的块带入内存。例如,我可以使用fread()将4K数据块读入char数组[4096]然后使用它,而不是从磁盘逐个读取4096个字节。

但是,我不确定这是否是我能做的全部,因为它是一个简单的算法。是否可以进行进一步的改进,或者它是否能达到最佳状态?

如果有人想看看,here是S-DES算法的规范。

1 个答案:

答案 0 :(得分:3)

如果要加速算法,可以在字节数组上并行加密,例如使用OpenMP。正如DarkSquirrel42在评论中指出的那样,为了提高速度,您还应该使用查找表将函数替换为permute函数:

#define LUT_SIZE 1024
static char lookup_table[LUT_SIZE];

/* Get 8-bit subkey from 10-bit key */
char permute(short int key)
{
    // SDES spec
    short int k1[] = { BIT_6, BIT_3, BIT_7, BIT_4, BIT_8, BIT_5, BIT_10, BIT_9 }; 
    char sk1 = '\0';

    for (short int i = 0; i < 8; i++) {
        sk1 = (sk1 << 1) | (key & k1[i]);
    }
    return sk1;
}

void init_lut()
{
    for (short int i = 0; i < LUT_SIZE; i++) {
        lookup_table[i] = permute(i);
    }
}

char permute_fast(short int key)
{
    if (key < 0 || key >= LUT_SIZE) {
        //error handling
        return 0;
    }
    return lookup_table[key];
}