diff --git a/inc/zuc256.h b/inc/zuc256.h index a8a7d63..9a4d91b 100644 --- a/inc/zuc256.h +++ b/inc/zuc256.h @@ -3,57 +3,48 @@ #include #include +#include -// 上下文结构体:存储算法状态 +// 类型定义 +typedef uint32_t ZUC_UINT31; // 31位无符号整数 +typedef uint8_t ZUC_UINT7; // 7位无符号整数 +typedef uint8_t ZUC_UINT6; // 6位无符号整数 + +// ZUC状态结构体 typedef struct { - uint32_t key[8]; // 256位密钥(拆分为8个32位字) - uint32_t iv[4]; // 128位IV(拆分为4个32位字) - uint32_t LFSR[16]; // 线性反馈移位寄存器 - uint32_t NFSR[16]; // 非线性反馈移位寄存器 - uint32_t R1, R2; // 密钥流生成辅助寄存器 - uint32_t ks_buf; // 密钥流缓存(处理非4字节对齐数据) - size_t ks_buf_len; // 缓存的密钥流字节数(0~3) -} ZUC256_CTX; + ZUC_UINT31 LFSR[16]; // 线性反馈移位寄存器 + uint32_t R1; // 寄存器1 + uint32_t R2; // 寄存器2 +} ZUC256_STATE; -// 错误码定义 -#define ZUC256_SUCCESS 0 // 成功 -#define ZUC256_ERR_NULL -1 // 空指针错误 -#define ZUC256_ERR_KEYLEN -2 // 密钥长度错误(需32字节) -#define ZUC256_ERR_IVLEN -3 // IV长度错误(需16字节) +// 加密上下文结构体(用于分阶段处理) +typedef struct { + ZUC256_STATE state; // 基础ZUC状态 + uint8_t buf[4]; // 输入缓冲区(处理非4字节对齐数据) + size_t buflen; // 缓冲区中有效字节数 +} ZUC256_ENCRYPT_CTX; -// 公共接口声明 -/** - * @brief 初始化ZUC256上下文 - * @param ctx 上下文指针(需提前分配内存) - * @param key 256位密钥(32字节) - * @param iv 128位初始向量(16字节) - * @return 成功返回ZUC256_SUCCESS,失败返回错误码 - */ -int ZUC256_Init(ZUC256_CTX *ctx, const uint8_t *key, const uint8_t *iv); +// 初始化ZUC256状态 +void zuc256_init(ZUC256_STATE *state, const uint8_t K[32], const uint8_t IV[23]); -/** - * @brief 分块处理数据(加密/解密) - * @param ctx 已初始化的上下文 - * @param out 输出缓冲区(长度需≥in_len) - * @param in 输入数据 - * @param in_len 输入数据长度(字节) - * @return 成功返回ZUC256_SUCCESS,失败返回错误码 - */ -int ZUC256_Update(ZUC256_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len); +// 生成单个密钥字 +uint32_t zuc256_generate_keyword(ZUC256_STATE *state); -/** - * @brief 结束处理(流密码无实际操作,仅对齐接口) - * @param ctx 上下文指针 - * @param out 输出缓冲区(可为NULL) - * @return 成功返回ZUC256_SUCCESS,失败返回错误码 - */ -int ZUC256_Final(ZUC256_CTX *ctx, uint8_t *out); +// 生成指定长度的密钥流 +void zuc256_generate_keystream(ZUC256_STATE *state, size_t nwords, uint32_t *keystream); -/** - * @brief 清理上下文(清空敏感数据) - * @param ctx 上下文指针 - */ -void ZUC256_Cleanup(ZUC256_CTX *ctx); +// 初始化加密上下文 +void zuc256_encrypt_init(ZUC256_ENCRYPT_CTX *ctx, const uint8_t K[32], const uint8_t IV[23]); +// 分阶段处理加密数据(支持流式输入) +void zuc256_encrypt_update(ZUC256_ENCRYPT_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out); + +// 完成加密处理(处理剩余数据并清理上下文) +void zuc256_encrypt_finish(ZUC256_ENCRYPT_CTX *ctx, uint8_t *out); + +// 一次性加密函数 +void zuc256_crypt(ZUC256_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out); + +void extract_iv(const uint8_t *input_25byte, uint8_t *output_23byte); #endif /*__ZUC256_H */ \ No newline at end of file diff --git a/src/main.c b/src/main.c index 25009a6..e24f70c 100644 --- a/src/main.c +++ b/src/main.c @@ -2,73 +2,63 @@ #include #include "zuc256.h" -// 测试ZUC256加密解密功能 +// 打印字节数组为十六进制 +void print_hex(const char *label, const uint8_t *data, size_t len) { + printf("%s: ", label); + for (size_t i = 0; i < len; i++) { + printf("%02x ", data[i]); + } + printf("\n"); +} + int main() { - // 1. 测试参数(256位密钥=32字节,128位IV=16字节) - uint8_t key[32] = "0123456789abcdef0123456789abcdef"; // 32字节密钥 - uint8_t iv[16] = "0123456789abcdef"; // 16字节IV - uint8_t plaintext[] = "Hello ZUC256! This is a test of the encryption algorithm."; - size_t plaintext_len = strlen((const char *)plaintext); - uint8_t ciphertext[1024] = {0}; // 密文缓冲区 - uint8_t decrypted[1024] = {0}; // 解密后缓冲区 + // 1. 明文 + uint8_t plaintext[] = "ZUC256对称加解密测试:1234567890"; + size_t plaintext_len = strlen((char*)plaintext); + printf("明文: %s\n", plaintext); + print_hex("明文(十六进制)", plaintext, plaintext_len); - // 2. 初始化加密上下文并加密 - ZUC256_CTX enc_ctx; - int ret = ZUC256_Init(&enc_ctx, key, iv); - if (ret != ZUC256_SUCCESS) { - printf("加密初始化失败!错误码: %d\n", ret); - return -1; + // 2. 密钥(32字节ASCII) + uint8_t key[32] = "0123456789abcdef0123456789abcdef"; + print_hex("密钥", key, 32); + + // 3. 初始向量(25字节ASCII) + //注:初始向量长度为184bit分布到25个字节中,前面17个初始向量为8bit字节,后面8个初始向量为6bit字节(占据一个字节的低6位) + uint8_t input_iv_25byte[25] = "0123456789abcdefg01234567"; + uint8_t iv[23]; + extract_iv(input_iv_25byte, iv); + print_hex("提取后的IV", iv, 23); + + // 4. 分配加密/解密缓冲区 + uint8_t *ciphertext = (uint8_t*)malloc(plaintext_len); + uint8_t *decryptedtext = (uint8_t*)malloc(plaintext_len); + if (!ciphertext || !decryptedtext) { + printf("内存分配失败\n"); + return 1; } - ret = ZUC256_Update(&enc_ctx, ciphertext, plaintext, plaintext_len); - if (ret != ZUC256_SUCCESS) { - printf("加密处理失败!错误码: %d\n", ret); - ZUC256_Cleanup(&enc_ctx); - return -1; - } + // 5. 加密 + ZUC256_STATE state; + zuc256_init(&state, key, iv); + zuc256_crypt(&state, plaintext, plaintext_len, ciphertext); + print_hex("密文", ciphertext, plaintext_len); - ret = ZUC256_Final(&enc_ctx, NULL); - if (ret != ZUC256_SUCCESS) { - printf("加密结束失败!错误码: %d\n", ret); - } - ZUC256_Cleanup(&enc_ctx); // 清理加密上下文(敏感数据) + // 6. 解密(重新初始化状态) + zuc256_init(&state, key, iv); + zuc256_crypt(&state, ciphertext, plaintext_len, decryptedtext); + print_hex("解密后", decryptedtext, plaintext_len); + printf("解密文本: %s\n", decryptedtext); - // 3. 初始化解密上下文并解密(流密码加密解密使用相同接口) - ZUC256_CTX dec_ctx; - ret = ZUC256_Init(&dec_ctx, key, iv); - if (ret != ZUC256_SUCCESS) { - printf("解密初始化失败!错误码: %d\n", ret); - return -1; - } - - ret = ZUC256_Update(&dec_ctx, decrypted, ciphertext, plaintext_len); - if (ret != ZUC256_SUCCESS) { - printf("解密处理失败!错误码: %d\n", ret); - ZUC256_Cleanup(&dec_ctx); - return -1; - } - - ret = ZUC256_Final(&dec_ctx, NULL); - if (ret != ZUC256_SUCCESS) { - printf("解密结束失败!错误码: %d\n", ret); - } - ZUC256_Cleanup(&dec_ctx); // 清理解密上下文 - - // 4. 输出结果并验证 - printf("原文: %s\n", plaintext); - printf("密文: "); - for (size_t i = 0; i < plaintext_len; i++) { - printf("%02x", ciphertext[i]); // 密文以十六进制显示 - } - printf("\n解密后: %s\n", decrypted); - - // 验证解密结果是否与原文一致 - if (memcmp(plaintext, decrypted, plaintext_len) == 0) { - printf("\n测试通过:加密解密一致!\n"); + // 7. 验证结果 + if (memcmp(plaintext, decryptedtext, plaintext_len) == 0) { + printf("=== 测试成功: 解密结果与明文一致 ===\n"); } else { - printf("\n测试失败:解密结果与原文不一致!\n"); - return -1; + printf("=== 测试失败: 解密结果与明文不一致 ===\n"); } + // 8. 释放内存 + free(ciphertext); + free(decryptedtext); + return 0; } \ No newline at end of file diff --git a/src/zuc256.c b/src/zuc256.c index c620240..5b5612d 100644 --- a/src/zuc256.c +++ b/src/zuc256.c @@ -1,262 +1,383 @@ -#include "zuc256.h" + +#include #include - -// 内部工具函数和常量(static隐藏,不暴露给外部) - -// S盒(ZUC标准S盒与AES一致) -static const uint8_t ZUC256_S0[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +#include "zuc256.h" +// S盒定义 +static const uint8_t S0[256] = { + 0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb, + 0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90, + 0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac, + 0xcd,0xc1,0xf8,0x1e,0x73,0x43,0x69,0xc6,0xb5,0xbd,0xfd,0x39,0x63,0x20,0xd4,0x38, + 0x76,0x7d,0xb2,0xa7,0xcf,0xed,0x57,0xc5,0xf3,0x2c,0xbb,0x14,0x21,0x06,0x55,0x9b, + 0xe3,0xef,0x5e,0x31,0x4f,0x7f,0x5a,0xa4,0x0d,0x82,0x51,0x49,0x5f,0xba,0x58,0x1c, + 0x4a,0x16,0xd5,0x17,0xa8,0x92,0x24,0x1f,0x8c,0xff,0xd8,0xae,0x2e,0x01,0xd3,0xad, + 0x3b,0x4b,0xda,0x46,0xeb,0xc9,0xde,0x9a,0x8f,0x87,0xd7,0x3a,0x80,0x6f,0x2f,0xc8, + 0xb1,0xb4,0x37,0xf7,0x0a,0x22,0x13,0x28,0x7c,0xcc,0x3c,0x89,0xc7,0xc3,0x96,0x56, + 0x07,0xbf,0x7e,0xf0,0x0b,0x2b,0x97,0x52,0x35,0x41,0x79,0x61,0xa6,0x4c,0x10,0xfe, + 0xbc,0x26,0x95,0x88,0x8a,0xb0,0xa3,0xfb,0xc0,0x18,0x94,0xf2,0xe1,0xe5,0xe9,0x5d, + 0xd0,0xdc,0x11,0x66,0x64,0x5c,0xec,0x59,0x42,0x75,0x12,0xf5,0x74,0x9c,0xaa,0x23, + 0x0e,0x86,0xab,0xbe,0x2a,0x02,0xe7,0x67,0xe6,0x44,0xa2,0x6c,0xc2,0x93,0x9f,0xf1, + 0xf6,0xfa,0x36,0xd2,0x50,0x68,0x9e,0x62,0x71,0x15,0x3d,0xd6,0x40,0xc4,0xe2,0x0f, + 0x8e,0x83,0x77,0x6b,0x25,0x05,0x3f,0x0c,0x30,0xea,0x70,0xb7,0xa1,0xe8,0xa9,0x65, + 0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60, }; -static const uint8_t ZUC256_S1[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +static const uint8_t S1[256] = { + 0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77, + 0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42, + 0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1, + 0x3a,0xb5,0x56,0x2a,0xc0,0x6d,0xb3,0x05,0x22,0x66,0xbf,0xdc,0x0b,0xfa,0x62,0x48, + 0xdd,0x20,0x11,0x06,0x36,0xc9,0xc1,0xcf,0xf6,0x27,0x52,0xbb,0x69,0xf5,0xd4,0x87, + 0x7f,0x84,0x4c,0xd2,0x9c,0x57,0xa4,0xbc,0x4f,0x9a,0xdf,0xfe,0xd6,0x8d,0x7a,0xeb, + 0x2b,0x53,0xd8,0x5c,0xa1,0x14,0x17,0xfb,0x23,0xd5,0x7d,0x30,0x67,0x73,0x08,0x09, + 0xee,0xb7,0x70,0x3f,0x61,0xb2,0x19,0x8e,0x4e,0xe5,0x4b,0x93,0x8f,0x5d,0xdb,0xa9, + 0xad,0xf1,0xae,0x2e,0xcb,0x0d,0xfc,0xf4,0x2d,0x46,0x6e,0x1d,0x97,0xe8,0xd1,0xe9, + 0x4d,0x37,0xa5,0x75,0x5e,0x83,0x9e,0xab,0x82,0x9d,0xb9,0x1c,0xe0,0xcd,0x49,0x89, + 0x01,0xb6,0xbd,0x58,0x24,0xa2,0x5f,0x38,0x78,0x99,0x15,0x90,0x50,0xb8,0x95,0xe4, + 0xd0,0x91,0xc7,0xce,0xed,0x0f,0xb4,0x6f,0xa0,0xcc,0xf0,0x02,0x4a,0x79,0xc3,0xde, + 0xa3,0xef,0xea,0x51,0xe6,0x6b,0x18,0xec,0x1b,0x2c,0x80,0xf7,0x74,0xe7,0xff,0x21, + 0x5a,0x6a,0x54,0x1e,0x41,0x31,0x92,0x35,0xc4,0x33,0x07,0x0a,0xba,0x7e,0x0e,0x34, + 0x88,0xb1,0x98,0x7c,0xf3,0x3d,0x60,0x6c,0x7b,0xca,0xd3,0x1f,0x32,0x65,0x04,0x28, + 0x64,0xbe,0x85,0x9b,0x2f,0x59,0x8a,0xd7,0xb0,0x25,0xac,0xaf,0x12,0x03,0xe2,0xf2, }; -// 循环左移工具函数 -static uint32_t zuc256_rotl(uint32_t value, uint8_t shift) { - return ((value << shift) | (value >> (32 - shift))); -} +// 常量数组D +static const ZUC_UINT7 ZUC256_D[][16] = { + {0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, + {0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40, + 0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}, +}; -// 非线性函数F(ZUC核心变换) -static uint32_t zuc256_F(uint32_t X0, uint32_t X1, uint32_t X2) { - uint32_t W1, W2, temp; - uint8_t b[4], c[4]; +// 核心宏定义 +#define ADD31(a,b) a += (b); a = (a & 0x7fffffff) + (a >> 31) +#define ROT31(a,k) ((((a) << (k)) | ((a) >> (31 - (k)))) & 0x7FFFFFFF) +#define ROT32(a,k) (((a) << (k)) | ((a) >> (32 - (k)))) - // 分解X0→字节→S0置换 - b[0] = (X0 >> 24) & 0xFF; - b[1] = (X0 >> 16) & 0xFF; - b[2] = (X0 >> 8) & 0xFF; - b[3] = X0 & 0xFF; - b[0] = ZUC256_S0[b[0]]; - b[1] = ZUC256_S0[b[1]]; - b[2] = ZUC256_S0[b[2]]; - b[3] = ZUC256_S0[b[3]]; - W1 = ((uint32_t)b[0] << 24) | ((uint32_t)b[1] << 16) | ((uint32_t)b[2] << 8) | b[3]; +#define L1(X) \ + ((X) ^ \ + ROT32((X), 2) ^ \ + ROT32((X), 10) ^ \ + ROT32((X), 18) ^ \ + ROT32((X), 24)) - // 分解X1→字节→S1置换 - c[0] = (X1 >> 24) & 0xFF; - c[1] = (X1 >> 16) & 0xFF; - c[2] = (X1 >> 8) & 0xFF; - c[3] = X1 & 0xFF; - c[0] = ZUC256_S1[c[0]]; - c[1] = ZUC256_S1[c[1]]; - c[2] = ZUC256_S1[c[2]]; - c[3] = ZUC256_S1[c[3]]; - W2 = ((uint32_t)c[0] << 24) | ((uint32_t)c[1] << 16) | ((uint32_t)c[2] << 8) | c[3]; +#define L2(X) \ + ((X) ^ \ + ROT32((X), 8) ^ \ + ROT32((X), 14) ^ \ + ROT32((X), 22) ^ \ + ROT32((X), 30)) - // ZUC标准F函数计算 - temp = (W1 ^ W2) ^ zuc256_rotl(W1 ^ W2, 16) ^ zuc256_rotl(W1 ^ W2, 12) - ^ zuc256_rotl(W1 ^ W2, 8) ^ zuc256_rotl(W1 ^ W2, 7); - return temp ^ X2; -} +#define LFSRWithInitialisationMode(u, LFSR, V) \ + V = LFSR[0]; \ + ADD31(V, ROT31(LFSR[ 0], 8)); \ + ADD31(V, ROT31(LFSR[ 4], 20)); \ + ADD31(V, ROT31(LFSR[10], 21)); \ + ADD31(V, ROT31(LFSR[13], 17)); \ + ADD31(V, ROT31(LFSR[15], 15)); \ + ADD31(V, (u)); \ + {int j; for (j=0; j<15;j++) LFSR[j]=LFSR[j+1];} \ + LFSR[15] = V -// 生成32位密钥流字(内部使用) -static int zuc256_gen_ks_word(ZUC256_CTX *ctx, uint32_t *ks_word) { - if (ctx == NULL || ks_word == NULL) { - return ZUC256_ERR_NULL; +#define LFSRWithWorkMode(LFSR, V) \ + { \ + int j; \ + uint64_t a = LFSR[0]; \ + a += ((uint64_t)LFSR[ 0]) << 8; \ + a += ((uint64_t)LFSR[ 4]) << 20; \ + a += ((uint64_t)LFSR[10]) << 21; \ + a += ((uint64_t)LFSR[13]) << 17; \ + a += ((uint64_t)LFSR[15]) << 15; \ + a = (a & 0x7fffffff) + (a >> 31); \ + V = (uint32_t)((a & 0x7fffffff) + (a >> 31)); \ + for (j = 0; j < 15; j++) \ + LFSR[j] = LFSR[j+1]; \ + LFSR[15] = V; \ } - uint32_t X0, X1, X2, F_res; +#define BitReconstruction2(X1,X2, LFSR) \ + X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \ + X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15) - // 计算F函数输入 - X0 = ctx->NFSR[15]; - X1 = ctx->LFSR[15] ^ ctx->NFSR[11]; - X2 = ctx->LFSR[14]; - F_res = zuc256_F(X0, X1, X2); +#define BitReconstruction3(X0,X1,X2, LFSR) \ + X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \ + BitReconstruction2(X1,X2, LFSR) - // 更新辅助寄存器R1/R2 - ctx->R1 = zuc256_rotl(ctx->R1, 1) ^ (F_res >> 1); - ctx->R2 = zuc256_rotl(ctx->R2, 1) ^ (F_res & 0x1); +#define BitReconstruction4(X0,X1,X2,X3, LFSR) \ + BitReconstruction3(X0,X1,X2, LFSR); \ + X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15) - // 生成32位密钥流 - *ks_word = ctx->LFSR[15] ^ ctx->R1 ^ ctx->R2; +#define MAKEU32(a, b, c, d) \ + (((uint32_t)(a) << 24) | \ + ((uint32_t)(b) << 16) | \ + ((uint32_t)(c) << 8) | \ + ((uint32_t)(d))) - // LFSR移位更新(ZUC标准反馈多项式) - uint32_t lfsr_feedback = ctx->LFSR[15] ^ (ctx->LFSR[11] & ctx->LFSR[12]) ^ ctx->LFSR[9]; - memmove(&ctx->LFSR[1], &ctx->LFSR[0], sizeof(ctx->LFSR) - sizeof(uint32_t)); - ctx->LFSR[0] = lfsr_feedback; +#define ZUC256_MAKEU31(a,b,c,d) \ + (((uint32_t)(a) << 23) | \ + ((uint32_t)(b) << 16) | \ + ((uint32_t)(c) << 8) | \ + (uint32_t)(d)) & 0x7FFFFFFF /* 确保31位 */ - // NFSR移位更新(ZUC标准反馈多项式) - uint32_t nfsr_feedback = ctx->NFSR[15] ^ ctx->NFSR[13] ^ ctx->NFSR[10] ^ ctx->NFSR[0] - ^ (ctx->NFSR[0] & ctx->NFSR[2]) ^ (ctx->NFSR[1] & ctx->NFSR[3]) - ^ (ctx->NFSR[0] & ctx->NFSR[1] & ctx->NFSR[4]); - memmove(&ctx->NFSR[1], &ctx->NFSR[0], sizeof(ctx->NFSR) - sizeof(uint32_t)); - ctx->NFSR[0] = nfsr_feedback; +//F_函数宏 +#define F_(X1,X2) do { \ + uint32_t W1, W2, U, V; \ + W1 = R1 + X1; \ + W2 = R2 ^ X2; \ + U = L1((W1 << 16) | (W2 >> 16)); \ + V = L2((W2 << 16) | (W1 >> 16)); \ + R1 = MAKEU32(S0[U >> 24], \ + S1[(U >> 16) & 0xFF], \ + S0[(U >> 8) & 0xFF], \ + S1[U & 0xFF]); \ + R2 = MAKEU32(S0[V >> 24], \ + S1[(V >> 16) & 0xFF], \ + S0[(V >> 8) & 0xFF], \ + S1[V & 0xFF]); \ +} while(0) - return ZUC256_SUCCESS; +//F函数宏 +#define F(X0,X1,X2) ({ \ + uint32_t result; \ + result = ((X0 ^ R1) + R2) & 0xFFFFFFFF; \ + F_(X1, X2); \ + result; \ +}) +// 辅助函数:字节序转换 +static inline uint32_t GETU32(const uint8_t *p) { + return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | + ((uint32_t)p[2] << 8) | (uint32_t)p[3]; } - -// 初始化LFSR/NFSR寄存器 -static int zuc256_init_regs(ZUC256_CTX *ctx) { - if (ctx == NULL) { - return ZUC256_ERR_NULL; - } - - uint32_t F_res; +static inline void PUTU32(uint8_t *p, uint32_t v) { + p[0] = (uint8_t)(v >> 24); + p[1] = (uint8_t)(v >> 16); + p[2] = (uint8_t)(v >> 8); + p[3] = (uint8_t)v; +} +// 设置MAC密钥(内部使用) +static void zuc256_set_mac_key(ZUC256_STATE *key, const uint8_t K[32], + const uint8_t IV[23], int macbits) +{ + ZUC_UINT31 *LFSR = key->LFSR; + uint32_t R1 = 0, R2 = 0; + uint32_t X0, X1, X2, W; + const ZUC_UINT7 *D; int i; + uint32_t V; - // 加载密钥到寄存器前8位(0~7) - for (i = 0; i < 8; i++) { - ctx->LFSR[i] = ctx->key[i]; - ctx->NFSR[i] = ctx->key[i]; - } + // 从IV中提取扩展位 + ZUC_UINT6 IV17 = (IV[17] >> 2) & 0x3F; + ZUC_UINT6 IV18 = (((IV[17] & 0x3) << 4) | (IV[18] >> 4)) & 0x3F; + ZUC_UINT6 IV19 = (((IV[18] & 0xF) << 2) | (IV[19] >> 6)) & 0x3F; + ZUC_UINT6 IV20 = (IV[19] & 0x3F) & 0x3F; + ZUC_UINT6 IV21 = (IV[20] >> 2) & 0x3F; + ZUC_UINT6 IV22 = (((IV[20] & 0x3) << 4) | (IV[21] >> 4)) & 0x3F; + ZUC_UINT6 IV23 = (((IV[21] & 0xF) << 2) | (IV[22] >> 6)) & 0x3F; + ZUC_UINT6 IV24 = (IV[22] & 0x3F) & 0x3F; - // 修复:用IV循环填充寄存器后8位(8~15),避免越界 - // IV共4个元素(0~3),通过(i-8)%4循环访问 - for (i = 8; i < 16; i++) { - ctx->LFSR[i] = ctx->iv[(i - 8) % 4]; // 索引范围:0~3,安全访问 - ctx->NFSR[i] = ctx->iv[(i - 8) % 4]; - } + // 选择合适的D数组 + D = (macbits/32 < 3) ? ZUC256_D[macbits/32] : ZUC256_D[3]; - // 32次迭代打乱初始状态(ZUC强制步骤) + // 初始化LFSR状态 + LFSR[0] = ZUC256_MAKEU31(K[0], D[0], K[21], K[16]); + LFSR[1] = ZUC256_MAKEU31(K[1], D[1], K[22], K[17]); + LFSR[2] = ZUC256_MAKEU31(K[2], D[2], K[23], K[18]); + LFSR[3] = ZUC256_MAKEU31(K[3], D[3], K[24], K[19]); + LFSR[4] = ZUC256_MAKEU31(K[4], D[4], K[25], K[20]); + LFSR[5] = ZUC256_MAKEU31(IV[0], (D[5] | IV17), K[5], K[26]); + LFSR[6] = ZUC256_MAKEU31(IV[1], (D[6] | IV18), K[6], K[27]); + LFSR[7] = ZUC256_MAKEU31(IV[10], (D[7] | IV19), K[7], IV[2]); + LFSR[8] = ZUC256_MAKEU31(K[8], (D[8] | IV20), IV[3], IV[11]); + LFSR[9] = ZUC256_MAKEU31(K[9], (D[9] | IV21), IV[12], IV[4]); + LFSR[10] = ZUC256_MAKEU31(IV[5], (D[10] | IV22), K[10], K[28]); + LFSR[11] = ZUC256_MAKEU31(K[11], (D[11] | IV23), IV[6], IV[13]); + LFSR[12] = ZUC256_MAKEU31(K[12], (D[12] | IV24), IV[7], IV[14]); + LFSR[13] = ZUC256_MAKEU31(K[13], D[13], IV[15], IV[8]); + LFSR[14] = ZUC256_MAKEU31(K[14], (D[14] | ((K[31] >> 4) & 0x0F)), IV[16], IV[9]); + LFSR[15] = ZUC256_MAKEU31(K[15], (D[15] | (K[31] & 0x0F)), K[30], K[29]); + + + + // 32轮初始迭代 for (i = 0; i < 32; i++) { - uint32_t X0 = ctx->NFSR[15]; - uint32_t X1 = ctx->LFSR[15] ^ ctx->NFSR[11]; - uint32_t X2 = ctx->LFSR[14]; - F_res = zuc256_F(X0, X1, X2); - - // LFSR移位(带F函数反馈) - uint32_t lfsr_feedback = ctx->LFSR[15] ^ (ctx->LFSR[11] & ctx->LFSR[12]) ^ ctx->LFSR[9] ^ F_res; - memmove(&ctx->LFSR[1], &ctx->LFSR[0], sizeof(ctx->LFSR) - sizeof(uint32_t)); - ctx->LFSR[0] = lfsr_feedback; - - // NFSR移位(带F函数反馈) - uint32_t nfsr_feedback = ctx->NFSR[15] ^ ctx->NFSR[13] ^ ctx->NFSR[10] ^ ctx->NFSR[0] - ^ (ctx->NFSR[0] & ctx->NFSR[2]) ^ (ctx->NFSR[1] & ctx->NFSR[3]) - ^ (ctx->NFSR[0] & ctx->NFSR[1] & ctx->NFSR[4]) ^ F_res; - memmove(&ctx->NFSR[1], &ctx->NFSR[0], sizeof(ctx->NFSR) - sizeof(uint32_t)); - ctx->NFSR[0] = nfsr_feedback; + BitReconstruction3(X0, X1, X2, LFSR); + W = F(X0, X1, X2); + LFSRWithInitialisationMode(W >> 1, LFSR, V); } - // 初始化辅助寄存器和密钥流缓存 - ctx->R1 = 0; - ctx->R2 = 0; - ctx->ks_buf = 0; - ctx->ks_buf_len = 0; + // 切换到工作模式 + BitReconstruction2(X1, X2, LFSR); + F_(X1, X2); + LFSRWithWorkMode(LFSR, V); - return ZUC256_SUCCESS; + // 保存寄存器状态 + key->R1 = R1; + key->R2 = R2; } -int ZUC256_Init(ZUC256_CTX *ctx, const uint8_t *key, const uint8_t *iv) { - // 参数合法性检查 - if (ctx == NULL || key == NULL || iv == NULL) { - return ZUC256_ERR_NULL; - } - - // 清空上下文(避免敏感数据残留) - memset(ctx, 0, sizeof(ZUC256_CTX)); - - // 加载密钥(32字节→8个32位字,大端序) - for (int i = 0; i < 8; i++) { - ctx->key[i] = ((uint32_t)key[4*i] << 24) | ((uint32_t)key[4*i + 1] << 16) - | ((uint32_t)key[4*i + 2] << 8) | (uint32_t)key[4*i + 3]; - } - - // 加载IV(16字节→4个32位字,大端序) - for (int i = 0; i < 4; i++) { - ctx->iv[i] = ((uint32_t)iv[4*i] << 24) | ((uint32_t)iv[4*i + 1] << 16) - | ((uint32_t)iv[4*i + 2] << 8) | (uint32_t)iv[4*i + 3]; - } - - // 初始化寄存器 - return zuc256_init_regs(ctx); +// 初始化ZUC256状态 +void zuc256_init(ZUC256_STATE *state, const uint8_t K[32], const uint8_t IV[23]) { + if (!state || !K || !IV) return; + zuc256_set_mac_key(state, K, IV, 0); } +// 生成单个密钥字 +uint32_t zuc256_generate_keyword(ZUC256_STATE *state) { + if (!state) return 0; -int ZUC256_Update(ZUC256_CTX *ctx, uint8_t *out, const uint8_t *in, size_t in_len) { - if (ctx == NULL || out == NULL || in == NULL) { - return ZUC256_ERR_NULL; + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1 = state->R1; + uint32_t R2 = state->R2; + uint32_t X0, X1, X2, X3; + uint32_t Z, V; + + BitReconstruction4(X0, X1, X2, X3, LFSR); + Z = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(LFSR, V); + + // 更新状态 + state->R1 = R1; + state->R2 = R2; + + + return Z; +} + +// 生成指定长度的密钥流 +void zuc256_generate_keystream(ZUC256_STATE *state, size_t nwords, uint32_t *keystream) { + if (!state || !keystream || nwords == 0) return; + + ZUC_UINT31 *LFSR = state->LFSR; + uint32_t R1 = state->R1; + uint32_t R2 = state->R2; + uint32_t X0, X1, X2, X3; + uint32_t V; + size_t i; + + for (i = 0; i < nwords; i++) { + BitReconstruction4(X0, X1, X2, X3, LFSR); + keystream[i] = X3 ^ F(X0, X1, X2); + LFSRWithWorkMode(LFSR, V); } - uint8_t *ks_buf_ptr = (uint8_t *)&ctx->ks_buf; - size_t i = 0; + // 更新状态 + state->R1 = R1; + state->R2 = R2; - // 处理缓存中残留的密钥流(解决非4字节对齐数据) - if (ctx->ks_buf_len > 0 && in_len > 0) { - for (; i < in_len && ctx->ks_buf_len < 4; i++, ctx->ks_buf_len++) { - out[i] = in[i] ^ ks_buf_ptr[ctx->ks_buf_len]; - } - // 缓存用尽,重置长度 - if (ctx->ks_buf_len == 4) { - ctx->ks_buf_len = 0; +} + +// 初始化加密上下文 +void zuc256_encrypt_init(ZUC256_ENCRYPT_CTX *ctx, const uint8_t K[32], const uint8_t IV[23]) { + if (!ctx) return; + memset(ctx, 0, sizeof(*ctx)); + zuc256_init(&ctx->state, K, IV); +} + +// 分阶段处理加密数据(支持流式输入) +void zuc256_encrypt_update(ZUC256_ENCRYPT_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out) { + if (!ctx || !in || !out || inlen == 0) return; + + // 先处理缓冲区中剩余的非4字节数据 + if (ctx->buflen > 0) { + size_t need = 4 - ctx->buflen; + size_t copy = (inlen < need) ? inlen : need; + + memcpy(ctx->buf + ctx->buflen, in, copy); + ctx->buflen += copy; + in += copy; + inlen -= copy; + + // 缓冲区已满,处理一个完整的4字节块 + if (ctx->buflen == 4) { + uint32_t keystream = zuc256_generate_keyword(&ctx->state); + uint32_t plain = GETU32(ctx->buf); + PUTU32(out, plain ^ keystream); + + ctx->buflen = 0; + memset(ctx->buf, 0, 4); // 清空缓冲区 + out += 4; } } // 处理完整的4字节块 - if (i < in_len) { - size_t remaining = in_len - i; - size_t full_blocks = remaining / 4; - size_t rem_bytes = remaining % 4; - - // 完整块处理 - for (size_t b = 0; b < full_blocks; b++) { - uint32_t ks_word; - if (zuc256_gen_ks_word(ctx, &ks_word) != ZUC256_SUCCESS) { - return ZUC256_ERR_NULL; + size_t full_blocks = inlen / 4; + if (full_blocks > 0) { + size_t keystream_len = full_blocks; + uint32_t *keystream = (uint32_t*)malloc(keystream_len * sizeof(uint32_t)); + if (keystream) { + zuc256_generate_keystream(&ctx->state, keystream_len, keystream); + + // 逐块异或加密 + for (size_t i = 0; i < full_blocks; i++) { + uint32_t plain = GETU32(in + i*4); + PUTU32(out + i*4, plain ^ keystream[i]); } - // 密钥流与数据异或(流密码加解密统一逻辑) - out[i + 4*b + 0] = in[i + 4*b + 0] ^ ((ks_word >> 24) & 0xFF); - out[i + 4*b + 1] = in[i + 4*b + 1] ^ ((ks_word >> 16) & 0xFF); - out[i + 4*b + 2] = in[i + 4*b + 2] ^ ((ks_word >> 8) & 0xFF); - out[i + 4*b + 3] = in[i + 4*b + 3] ^ (ks_word & 0xFF); - } - - // 处理剩余不足4字节的数据(存入缓存) - if (rem_bytes > 0) { - uint32_t ks_word; - if (zuc256_gen_ks_word(ctx, &ks_word) != ZUC256_SUCCESS) { - return ZUC256_ERR_NULL; - } - ctx->ks_buf = ks_word; - for (size_t r = 0; r < rem_bytes; r++) { - out[i + 4*full_blocks + r] = in[i + 4*full_blocks + r] ^ ks_buf_ptr[r]; - } - ctx->ks_buf_len = rem_bytes; + + free(keystream); + in += full_blocks * 4; + inlen -= full_blocks * 4; + out += full_blocks * 4; } } - return ZUC256_SUCCESS; -} - -int ZUC256_Final(ZUC256_CTX *ctx, uint8_t *out) { - // 流密码无收尾操作,仅检查上下文合法性 - (void)out; // 未使用参数,避免编译警告 - return (ctx == NULL) ? ZUC256_ERR_NULL : ZUC256_SUCCESS; -} - -void ZUC256_Cleanup(ZUC256_CTX *ctx) { - if (ctx != NULL) { - memset(ctx, 0, sizeof(ZUC256_CTX)); // 覆盖敏感数据,防止泄露 + // 缓存剩余不足4字节的数据 + if (inlen > 0) { + memcpy(ctx->buf, in, inlen); + ctx->buflen = inlen; } } - \ No newline at end of file + +// 完成加密处理(处理剩余数据并清理上下文) +void zuc256_encrypt_finish(ZUC256_ENCRYPT_CTX *ctx, uint8_t *out) { + if (!ctx || !out) return; + + // 处理缓冲区中剩余的不足4字节数据 + if (ctx->buflen > 0) { + uint32_t keystream = zuc256_generate_keyword(&ctx->state); + uint8_t keystream_bytes[4]; + PUTU32(keystream_bytes, keystream); + + // 逐字节异或 + for (size_t i = 0; i < ctx->buflen; i++) { + out[i] = ctx->buf[i] ^ keystream_bytes[i]; + } + } + + // 清理上下文(安全考虑) + memset(ctx, 0, sizeof(*ctx)); +} + +// 一次性加密函数(ZUC加密和解密相同) +void zuc256_crypt(ZUC256_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out) { + if (!state || !in || !out) return; + + ZUC256_ENCRYPT_CTX ctx; + zuc256_encrypt_init(&ctx, NULL, NULL); + memcpy(&ctx.state, state, sizeof(ZUC256_STATE)); // 复制当前状态 + + zuc256_encrypt_update(&ctx, in, inlen, out); + zuc256_encrypt_finish(&ctx, out + (inlen / 4) * 4); + + memcpy(state, &ctx.state, sizeof(ZUC256_STATE)); // 回写状态 +} +void extract_iv(const uint8_t *input_25byte, uint8_t *output_23byte) { + if (!input_25byte || !output_23byte) return; + for (int i = 0; i < 17; i++) { + output_23byte[i] = input_25byte[i]; + } + uint8_t src[8]; + for (int i = 0; i < 8; i++) { + src[i] = input_25byte[17 + i] & 0x3F; + } + output_23byte[17] = (src[0] << 2) | (src[1] >> 4); + output_23byte[18] = ((src[1] & 0x0F) << 4) | (src[2] >> 2); + output_23byte[19] = ((src[2] & 0x03) << 6) | src[3]; + output_23byte[20] = (src[4] << 2) | (src[5] >> 4); + output_23byte[21] = ((src[5] & 0x0F) << 4) | (src[6] >> 2); + output_23byte[22] = ((src[6] & 0x03) << 6) | src[7]; + +} \ No newline at end of file