代碼中定義了以下常量表(均為標準值):
g_arrayIP[64]:初始置換表g_arrayE[48]:擴展置換表(32→48 位)g_matrixNSBox[8][64]:8 個 S 盒(6→4 位)g_arrayP[32]:P 置換表g_arrayIP_1[64]:逆初始置換表g_arrayPC_1[56]:PC-1 密鑰壓縮置換(64→56)g_arrayPC_2[48]:PC-2 子密鑰壓縮置換(56→48)g_arrayLs[16]:每輪循環左移位數#define BitTransform(array, len, source, dest) \
{ \
__int64 bts = source; \
int bti; \
dest = 0; \
for (bti = 0; bti < len; bti++) { \
if (array[bti] >= 0 && (bts & g_arrayMask[array[bti]])) \
dest |= g_arrayMask[bti]; \
} \
}
g_arrayMask[64] 預計算 1ULL << i,避免運行時移位開銷。void DESSubKeys(__int64 key, __int64 K[16], int mode) {
__int64 temp;
// PC-1 置換:64->56
BitTransform(g_arrayPC_1, 56, key, temp);
for (int j = 0; j < 16; j++) {
// 循環左移
__int64 src = temp;
int shift = g_arrayLs[j];
temp = ((src & g_arrayLsMask[shift]) << (28 - shift)) |
((src & ~g_arrayLsMask[shift]) >> shift);
// PC-2 置換:56->48(存入 64 位變量,高 16 位為 0)
BitTransform(g_arrayPC_2, 64, temp, K[j]);
}
// 解密時反轉子密鑰順序
if (mode == DES_MODE_DECRYPT) {
for (int j = 0; j < 8; j++) {
__int64 t = K[j]; K[j] = K[15-j]; K[15-j] = t;
}
}
}
__int64 DES64(__int64 subkeys[16], __int64 data) {
__int64 out;
// IP 置換
BitTransform(g_arrayIP, 64, data, out);
__int32* pSrc = (__int32*)&out; // 高 32 位 L,低 32 位 R
for (int i = 0; i < 16; i++) {
__int64 R = pSrc[1];
// F 函數
// 1. E 擴展 32->48
BitTransform(g_arrayE, 64, R, R);
// 2. 與子密鑰異或
R ^= subkeys[i];
// 3. S 盒代換 48->32
__int32 SOut = 0;
char* pR = (char*)&R; // 視為 8 字節,每字節 6 位有效
for (int sbi = 7; sbi >= 0; sbi--) {
SOut <<= 4;
SOut |= g_matrixNSBox[sbi][pR[sbi]];
}
R = SOut;
// 4. P 置換
BitTransform(g_arrayP, 32, R, R);
// Feistel 交換
__int32 L = pSrc[0];
pSrc[0] = pSrc[1];
pSrc[1] = L ^ (__int32)R;
}
// 最後交換 L/R
__int32 t = pSrc[0]; pSrc[0] = pSrc[1]; pSrc[1] = t;
// IP⁻¹ 置換
BitTransform(g_arrayIP_1, 64, out, out);
return out;
}
#include <stdio.h>
#include <stdint.h>
int main() {
uint64_t key = 0x133457799BBCDFF1; // 64 位密鑰(含校驗位)
uint64_t plain = 0x0123456789ABCDEF;
uint64_t K[16];
DESSubKeys(key, K, DES_MODE_ENCRYPT);
uint64_t cipher = DES64(K, plain);
printf("Cipher: %016llX\n", cipher);
// 解密
DESSubKeys(key, K, DES_MODE_DECRYPT);
uint64_t dec = DES64(K, cipher);
printf("Decrypted: %016llX\n", dec);
return 0;
}
g_arrayMask 避免循環中移位。理解 DES 的 Feistel 結構、S 盒非線性設計、密鑰調度細節,是學習現代分組密碼(AES、SM4)的基石。實戰中請直接調用 OpenSSL EVP_des_ecb 等成熟庫,避免自行實現引入旁路攻擊風險。