调整目录结构
This commit is contained in:
28
ref_c_java/zuc256_c/inc/type.h
Normal file
28
ref_c_java/zuc256_c/inc/type.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
#ifndef __TYPE_H
|
||||
#define __TYPE_H
|
||||
|
||||
#include <stdint.h>
|
||||
/* IO definitions */
|
||||
#define __I volatile const /* defines 'read only' permissions */
|
||||
|
||||
#define __O volatile /* defines 'write only' permissions */
|
||||
#define __IO volatile /* defines 'read / write' permissions */
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
typedef __IO uint64_t vu64;
|
||||
typedef __IO uint32_t vu32;
|
||||
typedef __IO uint16_t vu16;
|
||||
typedef __IO uint8_t vu8;
|
||||
|
||||
typedef __I uint64_t vuc64; /* Read Only */
|
||||
typedef __I uint32_t vuc32; /* Read Only */
|
||||
typedef __I uint16_t vuc16; /* Read Only */
|
||||
typedef __I uint8_t vuc8; /* Read Only */
|
||||
|
||||
|
||||
#endif /*__TYPE_H*/
|
||||
89
ref_c_java/zuc256_c/inc/zuc256.h
Normal file
89
ref_c_java/zuc256_c/inc/zuc256.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2025. Institute of Information Engineering, CAS
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file: zuc256.h
|
||||
* @brief: zuc256模块对外接口声明
|
||||
* @author: QZH <qinzhenghui@iie.ac.cn>
|
||||
* @version: 1.0.0
|
||||
* @date: 2025-09-01
|
||||
*
|
||||
* @attention: 接口使用注意事项
|
||||
*/
|
||||
#ifndef __ZUC256_H
|
||||
#define __ZUC256_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// 类型定义
|
||||
typedef uint32_t ZUC_UINT31; // 31位无符号整数
|
||||
typedef uint8_t ZUC_UINT7; // 7位无符号整数
|
||||
typedef uint8_t ZUC_UINT6; // 6位无符号整数
|
||||
typedef uint32_t ZUC_UINT32; // 32位无符号整数
|
||||
// ZUC状态结构体
|
||||
typedef struct {
|
||||
ZUC_UINT31 LFSR[16]; // 线性反馈移位寄存器
|
||||
uint32_t R1; // 寄存器1
|
||||
uint32_t R2; // 寄存器2
|
||||
} ZUC_STATE;
|
||||
typedef ZUC_STATE ZUC256_STATE;
|
||||
// 加密上下文结构体(用于分阶段处理)
|
||||
typedef struct {
|
||||
ZUC_STATE state; // 基础ZUC状态
|
||||
uint8_t buf[4]; // 输入缓冲区(处理非4字节对齐数据)
|
||||
size_t buflen; // 缓冲区中有效字节数
|
||||
} ZUC256_ENCRYPT_CTX;
|
||||
// ZUC256 MAC 上下文结构体
|
||||
typedef struct {
|
||||
ZUC_UINT31 LFSR[16]; // ZUC256 线性反馈移位寄存器
|
||||
uint32_t R1; // 非线性函数寄存器R1
|
||||
uint32_t R2; // 非线性函数寄存器R2
|
||||
uint8_t buf[4]; // 数据缓存(处理不足4字节的待认证数据)
|
||||
size_t buflen; // 缓存中有效数据长度(0~3)
|
||||
uint32_t T[4]; // MAC 累加器(支持最大128位MAC,4个32位字)
|
||||
uint32_t K0[4]; // MAC 初始密钥字(与T长度匹配)
|
||||
int macbits; // MAC 输出位数(32/64/128,按32位对齐)
|
||||
} ZUC256_MAC_CTX;
|
||||
|
||||
// 初始化ZUC256状态
|
||||
void zuc256_init(ZUC_STATE *state, const uint8_t K[32], const uint8_t IV[23]);
|
||||
|
||||
// 生成单个密钥字
|
||||
uint32_t zuc256_generate_keyword(ZUC_STATE *state);
|
||||
|
||||
// 生成指定长度的密钥流
|
||||
void zuc256_generate_keystream(ZUC_STATE *state, size_t nwords, uint32_t *keystream);
|
||||
|
||||
// 初始化加密上下文
|
||||
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(ZUC_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 */
|
||||
|
||||
64
ref_c_java/zuc256_c/src/main.c
Normal file
64
ref_c_java/zuc256_c/src/main.c
Normal file
@@ -0,0 +1,64 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "zuc256.h"
|
||||
|
||||
// 打印字节数组为十六进制
|
||||
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. 明文
|
||||
uint8_t plaintext[] = "ZUC256对称加解密测试:1234567890";
|
||||
size_t plaintext_len = strlen((char*)plaintext);
|
||||
printf("明文: %s\n", plaintext);
|
||||
print_hex("明文(十六进制)", plaintext, plaintext_len);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 5. 加密
|
||||
ZUC_STATE state;
|
||||
zuc256_init(&state, key, iv);
|
||||
zuc256_crypt(&state, plaintext, plaintext_len, ciphertext);
|
||||
print_hex("密文", ciphertext, plaintext_len);
|
||||
|
||||
// 6. 解密(重新初始化状态)
|
||||
zuc256_init(&state, key, iv);
|
||||
zuc256_crypt(&state, ciphertext, plaintext_len, decryptedtext);
|
||||
print_hex("解密后", decryptedtext, plaintext_len);
|
||||
printf("解密文本: %s\n", decryptedtext);
|
||||
|
||||
// 7. 验证结果
|
||||
if (memcmp(plaintext, decryptedtext, plaintext_len) == 0) {
|
||||
printf("=== 测试成功: 解密结果与明文一致 ===\n");
|
||||
} else {
|
||||
printf("=== 测试失败: 解密结果与明文不一致 ===\n");
|
||||
}
|
||||
|
||||
// 8. 释放内存
|
||||
free(ciphertext);
|
||||
free(decryptedtext);
|
||||
|
||||
return 0;
|
||||
}
|
||||
618
ref_c_java/zuc256_c/src/zuc256.c
Normal file
618
ref_c_java/zuc256_c/src/zuc256.c
Normal file
@@ -0,0 +1,618 @@
|
||||
/*
|
||||
* Copyright (C) 2025. Institute of Information Engineering, CAS
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* @file: zuc256.c
|
||||
* @brief: zuc256 的纯c代码
|
||||
* @author: QZH <qinzhenghui@iie.ac.cn>
|
||||
* @version: 1.0.0
|
||||
* @date: 2025-09-01
|
||||
*
|
||||
* @note: 无
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2025-08-04 QZH 创建文件
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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 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,
|
||||
};
|
||||
|
||||
// 常量数组D
|
||||
|
||||
#define F_(X1,X2) \
|
||||
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])
|
||||
|
||||
#define F(X0,X1,X2) \
|
||||
((X0 ^ R1) + R2); \
|
||||
F_(X1, X2)
|
||||
#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))))
|
||||
|
||||
#define L1(X) \
|
||||
((X) ^ \
|
||||
ROT32((X), 2) ^ \
|
||||
ROT32((X), 10) ^ \
|
||||
ROT32((X), 18) ^ \
|
||||
ROT32((X), 24))
|
||||
|
||||
#define L2(X) \
|
||||
((X) ^ \
|
||||
ROT32((X), 8) ^ \
|
||||
ROT32((X), 14) ^ \
|
||||
ROT32((X), 22) ^ \
|
||||
ROT32((X), 30))
|
||||
|
||||
|
||||
#define LFSRWithInitialisationMode(u) \
|
||||
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
|
||||
|
||||
#define LFSRWithWorkMode() \
|
||||
{ \
|
||||
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; \
|
||||
}
|
||||
|
||||
#define BitReconstruction2(X1,X2) \
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >> 15); \
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >> 15)
|
||||
|
||||
#define BitReconstruction3(X0,X1,X2) \
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); \
|
||||
BitReconstruction2(X1,X2)
|
||||
|
||||
#define BitReconstruction4(X0,X1,X2,X3) \
|
||||
BitReconstruction3(X0,X1,X2); \
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >> 15)
|
||||
|
||||
#define MAKEU32(a, b, c, d) \
|
||||
(((uint32_t)(a) << 24) | \
|
||||
((uint32_t)(b) << 16) | \
|
||||
((uint32_t)(c) << 8) | \
|
||||
((uint32_t)(d)))
|
||||
|
||||
#define ZUC256_MAKEU31(a,b,c,d) \
|
||||
(((uint32_t)(a) << 23) | \
|
||||
((uint32_t)(b) << 16) | \
|
||||
((uint32_t)(c) << 8) | \
|
||||
(uint32_t)(d)) & 0x7FFFFFFF /* 确保31位 */
|
||||
|
||||
|
||||
// 辅助函数:字节序转换
|
||||
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];
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
static void zuc256_set_mac_key(ZUC_STATE *key, const uint8_t K[32],
|
||||
const uint8_t IV[23], int macbits)
|
||||
{
|
||||
ZUC_UINT31 *LFSR = key->LFSR;
|
||||
uint32_t R1, R2;
|
||||
uint32_t X0, X1, X2;
|
||||
uint32_t W, W1, W2, U, V;
|
||||
const ZUC_UINT7 *D;
|
||||
int i;
|
||||
|
||||
ZUC_UINT6 IV17 = IV[17] >> 2;
|
||||
ZUC_UINT6 IV18 = ((IV[17] & 0x3) << 4) | (IV[18] >> 4);
|
||||
ZUC_UINT6 IV19 = ((IV[18] & 0xf) << 2) | (IV[19] >> 6);
|
||||
ZUC_UINT6 IV20 = IV[19] & 0x3f;
|
||||
ZUC_UINT6 IV21 = IV[20] >> 2;
|
||||
ZUC_UINT6 IV22 = ((IV[20] & 0x3) << 4) | (IV[21] >> 4);
|
||||
ZUC_UINT6 IV23 = ((IV[21] & 0xf) << 2) | (IV[22] >> 6);
|
||||
ZUC_UINT6 IV24 = IV[22] & 0x3f;
|
||||
|
||||
D = macbits/32 < 3 ? ZUC256_D[macbits/32] : ZUC256_D[3];
|
||||
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)), IV[16], IV[9]);
|
||||
LFSR[15] = ZUC256_MAKEU31(K[15], (D[15] | (K[31] & 0x0F)), K[30], K[29]);
|
||||
|
||||
R1 = 0;
|
||||
R2 = 0;
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
BitReconstruction3(X0, X1, X2);
|
||||
W = F(X0, X1, X2);
|
||||
LFSRWithInitialisationMode(W >> 1);
|
||||
}
|
||||
|
||||
BitReconstruction2(X1, X2);
|
||||
F_(X1, X2);
|
||||
LFSRWithWorkMode();
|
||||
|
||||
key->R1 = R1;
|
||||
key->R2 = R2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 初始化ZUC256状态
|
||||
void zuc256_init(ZUC_STATE *key, const uint8_t K[32],
|
||||
const uint8_t IV[23])
|
||||
{
|
||||
if (!key || !K || !IV) return;
|
||||
zuc256_set_mac_key(key, K, IV, 0);
|
||||
}
|
||||
// 生成单个密钥字
|
||||
uint32_t zuc256_generate_keyword(ZUC_STATE *state) {
|
||||
ZUC_UINT31 *LFSR = state->LFSR;
|
||||
uint32_t R1 = state->R1;
|
||||
uint32_t R2 = state->R2;
|
||||
uint32_t X0, X1, X2, X3;
|
||||
uint32_t W1, W2, U, V;
|
||||
uint32_t Z;
|
||||
|
||||
BitReconstruction4(X0, X1, X2, X3);
|
||||
Z = X3 ^ F(X0, X1, X2);
|
||||
LFSRWithWorkMode();
|
||||
|
||||
state->R1 = R1;
|
||||
state->R2 = R2;
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
void zuc256_generate_keystream(ZUC_STATE *state, size_t nwords, uint32_t *keystream) {
|
||||
ZUC_UINT31 *LFSR = state->LFSR;
|
||||
uint32_t R1 = state->R1;
|
||||
uint32_t R2 = state->R2;
|
||||
uint32_t X0, X1, X2, X3;
|
||||
uint32_t W1, W2, U, V;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < nwords; i ++) {
|
||||
/*
|
||||
BitReconstruction4(X0, X1, X2, X3);
|
||||
keystream[i] = X3 ^ F(X0, X1, X2);
|
||||
LFSRWithWorkMode();
|
||||
*/
|
||||
uint32_t T0, T1, T2, T3, T4, T5, T6, T7;
|
||||
uint64_t a;
|
||||
int j;
|
||||
|
||||
// expand BitReconstruction4(X0, X1, X2, X3)
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0x0000FFFF) << 16) | (LFSR[ 9] >> 15);
|
||||
X2 = ((LFSR[ 7] & 0x0000FFFF) << 16) | (LFSR[ 5] >> 15);
|
||||
X3 = ((LFSR[ 2] & 0x0000FFFF) << 16) | (LFSR[ 0] >> 15);
|
||||
|
||||
//keystream[i] = X3 ^ F(X0, X1, X2);
|
||||
keystream[i] = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >> 16));
|
||||
V = L2((W2 << 16) | (W1 >> 16));
|
||||
|
||||
// table lookup together makes 10% faster
|
||||
T0 = S0[(U >> 24) ];
|
||||
T2 = S0[(U >> 8) & 0xFF];
|
||||
T4 = S0[(V >> 24) ];
|
||||
T6 = S0[(V >> 8) & 0xFF];
|
||||
|
||||
T1 = S1[(U >> 16) & 0xFF];
|
||||
T3 = S1[(U ) & 0xFF];
|
||||
T5 = S1[(V >> 16) & 0xFF];
|
||||
T7 = S1[(V ) & 0xFF];
|
||||
|
||||
R1 = MAKEU32(T0, T1, T2, T3);
|
||||
R2 = MAKEU32(T4, T5, T6, T7);
|
||||
|
||||
// expand LFSRWithWorkMode()
|
||||
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;
|
||||
}
|
||||
|
||||
state->R1 = R1;
|
||||
state->R2 = R2;
|
||||
}
|
||||
|
||||
|
||||
// 初始化加密上下文
|
||||
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字节块
|
||||
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]);
|
||||
}
|
||||
|
||||
free(keystream);
|
||||
in += full_blocks * 4;
|
||||
inlen -= full_blocks * 4;
|
||||
out += full_blocks * 4;
|
||||
}
|
||||
}
|
||||
|
||||
// 缓存剩余不足4字节的数据
|
||||
if (inlen > 0) {
|
||||
memcpy(ctx->buf, in, inlen);
|
||||
ctx->buflen = inlen;
|
||||
}
|
||||
}
|
||||
|
||||
// 完成加密处理(处理剩余数据并清理上下文)
|
||||
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(ZUC_STATE *state, const uint8_t *in, size_t inlen, uint8_t *out) {
|
||||
if (!state || !in || !out) return;
|
||||
|
||||
ZUC256_ENCRYPT_CTX ctx;
|
||||
// 修复1:初始化ctx内存(仅清空,不调用zuc256_encrypt_init)
|
||||
memset(&ctx, 0, sizeof(ZUC256_ENCRYPT_CTX));
|
||||
// 修复2:将传入的合法state复制到ctx->state,复用已有状态(含K/IV对应的初始化结果)
|
||||
memcpy(&ctx.state, state, sizeof(ZUC_STATE));
|
||||
|
||||
// 正常执行加解密(使用复用的state)
|
||||
zuc256_encrypt_update(&ctx, in, inlen, out);
|
||||
// 计算剩余数据的偏移:(inlen / 4)*4 是完整4字节块的长度,剩余数据从这里开始
|
||||
size_t remaining_offset = (inlen / 4) * 4;
|
||||
zuc256_encrypt_finish(&ctx, out + remaining_offset);
|
||||
|
||||
// 修复3:将ctx->state的最新状态回写到传入的state(确保后续连续加解密的状态正确)
|
||||
memcpy(state, &ctx.state, sizeof(ZUC_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];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化ZUC256 MAC上下文
|
||||
* @param ctx:MAC上下文指针(输出)
|
||||
* @param key:256位密钥(32字节,输入)
|
||||
* @param iv:23字节初始向量(输入)
|
||||
* @param macbits:期望MAC输出位数(32/64/128,自动调整范围:<32→32,>128→128)
|
||||
*/
|
||||
void zuc256_mac_init(ZUC256_MAC_CTX *ctx, const uint8_t key[32],
|
||||
const uint8_t iv[23], int macbits)
|
||||
{
|
||||
if (macbits < 32)
|
||||
macbits = 32;
|
||||
else if (macbits > 64)
|
||||
macbits = 128;
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
zuc256_set_mac_key((ZUC256_STATE *)ctx, key, iv, macbits);
|
||||
zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->T);
|
||||
zuc256_generate_keystream((ZUC256_STATE *)ctx, macbits/32, ctx->K0);
|
||||
ctx->macbits = (macbits/32) * 32;
|
||||
}
|
||||
/**
|
||||
* @brief 更新ZUC256 MAC待认证数据(支持分块输入)
|
||||
* @param ctx:已初始化的MAC上下文(输入/输出)
|
||||
* @param data:待认证数据块(输入,可NULL)
|
||||
* @param len:待认证数据长度(字节,输入,0则无操作)
|
||||
*/
|
||||
void zuc256_mac_update(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t len)
|
||||
{
|
||||
ZUC_UINT32 K1, M;
|
||||
size_t n = ctx->macbits / 32;
|
||||
size_t i, j;
|
||||
|
||||
if (!data || !len) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->buflen) {
|
||||
size_t num = sizeof(ctx->buf) - ctx->buflen;
|
||||
if (len < num) {
|
||||
memcpy(ctx->buf + ctx->buflen, data, len);
|
||||
ctx->buflen += len;
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(ctx->buf + ctx->buflen, data, num);
|
||||
M = GETU32(ctx->buf);
|
||||
ctx->buflen = 0;
|
||||
|
||||
K1 = zuc256_generate_keyword((ZUC_STATE *)ctx);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (M & 0x80000000) {
|
||||
for (j = 0; j < n; j++) {
|
||||
ctx->T[j] ^= ctx->K0[j];
|
||||
}
|
||||
}
|
||||
M <<= 1;
|
||||
for (j = 0; j < n - 1; j++) {
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31);
|
||||
}
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31);
|
||||
K1 <<= 1;
|
||||
}
|
||||
|
||||
data += num;
|
||||
len -= num;
|
||||
}
|
||||
|
||||
while (len >= 4) {
|
||||
M = GETU32(data);
|
||||
K1 = zuc256_generate_keyword((ZUC_STATE *)ctx);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
if (M & 0x80000000) {
|
||||
for (j = 0; j < n; j++) {
|
||||
ctx->T[j] ^= ctx->K0[j];
|
||||
}
|
||||
}
|
||||
M <<= 1;
|
||||
for (j = 0; j < n - 1; j++) {
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31);
|
||||
}
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31);
|
||||
K1 <<= 1;
|
||||
}
|
||||
|
||||
data += 4;
|
||||
len -= 4;
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(ctx->buf, data, len);
|
||||
ctx->buflen = len;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief 完成ZUC256 MAC计算,输出最终认证码
|
||||
* @param ctx:已更新数据的MAC上下文(输入/输出,调用后清空)
|
||||
* @param data:最后一块待认证数据(可NULL,若需补充不足1字节的比特)
|
||||
* @param nbits:最后一块数据的额外比特数(0~7,仅当data非NULL时有效)
|
||||
* @param mac:MAC输出缓冲区(需提前分配至少 ctx->macbits/8 字节空间)
|
||||
*/
|
||||
void zuc256_mac_finish(ZUC256_MAC_CTX *ctx, const uint8_t *data, size_t nbits, uint8_t *mac)
|
||||
{
|
||||
ZUC_UINT32 K1, M;
|
||||
size_t n = ctx->macbits/32;
|
||||
size_t i, j;
|
||||
|
||||
|
||||
if (!data)
|
||||
nbits = 0;
|
||||
|
||||
if (nbits >= 8) {
|
||||
zuc256_mac_update(ctx, data, nbits/8);
|
||||
data += nbits/8;
|
||||
nbits %= 8;
|
||||
}
|
||||
|
||||
if (nbits)
|
||||
ctx->buf[ctx->buflen] = *data;
|
||||
|
||||
if (ctx->buflen || nbits) {
|
||||
M = GETU32(ctx->buf);
|
||||
K1 = zuc256_generate_keyword((ZUC_STATE *)ctx);
|
||||
|
||||
|
||||
for (i = 0; i < ctx->buflen * 8 + nbits; i++) {
|
||||
if (M & 0x80000000) {
|
||||
for (j = 0; j < n; j++) {
|
||||
ctx->T[j] ^= ctx->K0[j];
|
||||
}
|
||||
}
|
||||
M <<= 1;
|
||||
for (j = 0; j < n - 1; j++) {
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (ctx->K0[j + 1] >> 31);
|
||||
}
|
||||
ctx->K0[j] = (ctx->K0[j] << 1) | (K1 >> 31);
|
||||
K1 <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < n; j++) {
|
||||
ctx->T[j] ^= ctx->K0[j];
|
||||
PUTU32(mac, ctx->T[j]);
|
||||
mac += 4;
|
||||
}
|
||||
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
}
|
||||
/**
|
||||
* @brief 一次性ZUC256 MAC计算(简化接口,适用于非流式数据
|
||||
* @param K:256位密钥(32字节,输入)
|
||||
* @param IV:23字节初始向量(输入)
|
||||
* @param data:待认证数据(输入,可NULL)
|
||||
* @param len:待认证数据长度(字节,输入)
|
||||
* @param macbits:MAC输出位数(32/64/128,输入)
|
||||
* @param mac:MAC输出缓冲区(输出,需提前分配空间)
|
||||
*/
|
||||
void zuc256_mac(const uint8_t K[32], const uint8_t IV[23], const uint8_t *data, size_t len, int macbits, uint8_t *mac) {
|
||||
ZUC256_MAC_CTX ctx;
|
||||
zuc256_mac_init(&ctx, K, IV, macbits);
|
||||
if (data && len > 0) {
|
||||
zuc256_mac_update(&ctx, data, len);
|
||||
}
|
||||
zuc256_mac_finish(&ctx, NULL, 0, mac);
|
||||
}
|
||||
552
ref_c_java/zuc256_java/zuc256.java
Normal file
552
ref_c_java/zuc256_java/zuc256.java
Normal file
@@ -0,0 +1,552 @@
|
||||
import java.util.Arrays;
|
||||
|
||||
public class zuc256 {
|
||||
// S盒定义
|
||||
private static final int[] S0 = {
|
||||
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
|
||||
};
|
||||
|
||||
private static final int[] S1 = {
|
||||
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
|
||||
};
|
||||
|
||||
// 常量数组D
|
||||
private static final int[][] ZUC256_D = {
|
||||
{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}
|
||||
};
|
||||
|
||||
// ZUC状态类
|
||||
public static class ZUCState {
|
||||
int[] LFSR = new int[16]; // 线性反馈移位寄存器
|
||||
int R1; // 寄存器1
|
||||
int R2; // 寄存器2
|
||||
}
|
||||
|
||||
// 加密上下文类
|
||||
public static class ZUC256EncryptCtx {
|
||||
ZUCState state = new ZUCState();
|
||||
byte[] buf = new byte[4];
|
||||
int buflen;
|
||||
}
|
||||
|
||||
// MAC上下文类
|
||||
public static class ZUC256MacCtx {
|
||||
int[] LFSR = new int[16];
|
||||
int R1;
|
||||
int R2;
|
||||
byte[] buf = new byte[4];
|
||||
int buflen;
|
||||
int[] T = new int[4];
|
||||
int[] K0 = new int[4];
|
||||
int macbits;
|
||||
}
|
||||
|
||||
// 辅助方法:将字节数组转换为32位整数
|
||||
private static int getU32(byte[] p, int offset) {
|
||||
return ((p[offset] & 0xFF) << 24) |
|
||||
((p[offset + 1] & 0xFF) << 16) |
|
||||
((p[offset + 2] & 0xFF) << 8) |
|
||||
(p[offset + 3] & 0xFF);
|
||||
}
|
||||
|
||||
// 辅助方法:将32位整数转换为字节数组
|
||||
private static void putU32(byte[] p, int offset, int v) {
|
||||
p[offset] = (byte) (v >> 24);
|
||||
p[offset + 1] = (byte) (v >> 16);
|
||||
p[offset + 2] = (byte) (v >> 8);
|
||||
p[offset + 3] = (byte) v;
|
||||
}
|
||||
|
||||
// 31位加法
|
||||
private static int add31(int a, int b) {
|
||||
long sum = (long)a + b;
|
||||
return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
||||
}
|
||||
|
||||
// 31位旋转
|
||||
private static int rot31(int a, int k) {
|
||||
return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
// 32位旋转
|
||||
private static int rot32(int a, int k) {
|
||||
return (a << k) | (a >>> (32 - k));
|
||||
}
|
||||
|
||||
// L1函数
|
||||
private static int L1(int x) {
|
||||
return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
|
||||
}
|
||||
|
||||
// L2函数
|
||||
private static int L2(int x) {
|
||||
return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
||||
}
|
||||
|
||||
// 初始化MAC密钥
|
||||
private static void zuc256SetMacKey(ZUCState key, byte[] K, byte[] IV, int macbits) {
|
||||
int[] LFSR = key.LFSR;
|
||||
int R1 = 0;
|
||||
int R2 = 0;
|
||||
int X0, X1, X2;
|
||||
int W, W1, W2, U, V;
|
||||
int[] D;
|
||||
|
||||
int IV17 = (IV[17] & 0xFF) >> 2;
|
||||
int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4);
|
||||
int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6);
|
||||
int IV20 = IV[19] & 0x3F;
|
||||
int IV21 = (IV[20] & 0xFF) >> 2;
|
||||
int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4);
|
||||
int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6);
|
||||
int IV24 = IV[22] & 0x3F;
|
||||
|
||||
D = (macbits / 32 < 3) ? ZUC256_D[macbits / 32] : ZUC256_D[3];
|
||||
|
||||
LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF);
|
||||
LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF);
|
||||
LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF);
|
||||
LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF);
|
||||
LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF);
|
||||
LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF);
|
||||
LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF);
|
||||
LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF);
|
||||
LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF);
|
||||
LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF);
|
||||
LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF);
|
||||
LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF);
|
||||
LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF);
|
||||
LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF);
|
||||
LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF);
|
||||
LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
// BitReconstruction3
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
|
||||
// F(X0, X1, X2)
|
||||
W = (X0 ^ R1) + R2;
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(S0[(U >>> 24) & 0xFF],
|
||||
S1[(U >>> 16) & 0xFF],
|
||||
S0[(U >>> 8) & 0xFF],
|
||||
S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(S0[(V >>> 24) & 0xFF],
|
||||
S1[(V >>> 16) & 0xFF],
|
||||
S0[(V >>> 8) & 0xFF],
|
||||
S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithInitialisationMode(W >> 1)
|
||||
int v = LFSR[0];
|
||||
v = add31(v, rot31(LFSR[0], 8));
|
||||
v = add31(v, rot31(LFSR[4], 20));
|
||||
v = add31(v, rot31(LFSR[10], 21));
|
||||
v = add31(v, rot31(LFSR[13], 17));
|
||||
v = add31(v, rot31(LFSR[15], 15));
|
||||
v = add31(v, W >>> 1);
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
}
|
||||
|
||||
// BitReconstruction2
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(S0[(U >>> 24) & 0xFF],
|
||||
S1[(U >>> 16) & 0xFF],
|
||||
S0[(U >>> 8) & 0xFF],
|
||||
S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(S0[(V >>> 24) & 0xFF],
|
||||
S1[(V >>> 16) & 0xFF],
|
||||
S0[(V >>> 8) & 0xFF],
|
||||
S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
|
||||
key.R1 = R1;
|
||||
key.R2 = R2;
|
||||
}
|
||||
|
||||
// 创建31位无符号整数
|
||||
private static int makeU31(int a, int b, int c, int d) {
|
||||
return (((a & 0xFF) << 23) |
|
||||
((b & 0xFF) << 16) |
|
||||
((c & 0xFF) << 8) |
|
||||
(d & 0xFF)) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
// 创建32位无符号整数
|
||||
private static int makeU32(int a, int b, int c, int d) {
|
||||
return ((a & 0xFF) << 24) |
|
||||
((b & 0xFF) << 16) |
|
||||
((c & 0xFF) << 8) |
|
||||
(d & 0xFF);
|
||||
}
|
||||
|
||||
// 初始化ZUC256状态
|
||||
public static void zuc256Init(ZUCState state, byte[] K, byte[] IV) {
|
||||
zuc256SetMacKey(state, K, IV, 0);
|
||||
}
|
||||
|
||||
// 生成单个密钥字
|
||||
public static int zuc256GenerateKeyword(ZUCState state) {
|
||||
int[] LFSR = state.LFSR;
|
||||
int R1 = state.R1;
|
||||
int R2 = state.R2;
|
||||
int X0, X1, X2, X3;
|
||||
int W1, W2, U, V;
|
||||
int Z;
|
||||
|
||||
// BitReconstruction4
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
|
||||
|
||||
Z = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(S0[(U >>> 24) & 0xFF],
|
||||
S1[(U >>> 16) & 0xFF],
|
||||
S0[(U >>> 8) & 0xFF],
|
||||
S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(S0[(V >>> 24) & 0xFF],
|
||||
S1[(V >>> 16) & 0xFF],
|
||||
S0[(V >>> 8) & 0xFF],
|
||||
S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
|
||||
state.R1 = R1;
|
||||
state.R2 = R2;
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
// 生成指定长度的密钥流
|
||||
public static void zuc256GenerateKeystream(ZUCState state, int nwords, int[] keystream) {
|
||||
int[] LFSR = state.LFSR;
|
||||
int R1 = state.R1;
|
||||
int R2 = state.R2;
|
||||
int X0, X1, X2, X3;
|
||||
int W1, W2, U, V;
|
||||
|
||||
for (int i = 0; i < nwords; i++) {
|
||||
// BitReconstruction4
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
|
||||
|
||||
keystream[i] = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
// S盒查找
|
||||
int T0 = S0[(U >>> 24) & 0xFF] & 0xFF;
|
||||
int T2 = S0[(U >>> 8) & 0xFF] & 0xFF;
|
||||
int T4 = S0[(V >>> 24) & 0xFF] & 0xFF;
|
||||
int T6 = S0[(V >>> 8) & 0xFF] & 0xFF;
|
||||
|
||||
int T1 = S1[(U >>> 16) & 0xFF] & 0xFF;
|
||||
int T3 = S1[U & 0xFF] & 0xFF;
|
||||
int T5 = S1[(V >>> 16) & 0xFF] & 0xFF;
|
||||
int T7 = S1[V & 0xFF] & 0xFF;
|
||||
|
||||
R1 = makeU32(T0, T1, T2, T3);
|
||||
R2 = makeU32(T4, T5, T6, T7);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
}
|
||||
|
||||
state.R1 = R1;
|
||||
state.R2 = R2;
|
||||
}
|
||||
|
||||
// 初始化加密上下文
|
||||
public static void zuc256EncryptInit(ZUC256EncryptCtx ctx, byte[] K, byte[] IV) {
|
||||
Arrays.fill(ctx.buf, (byte) 0);
|
||||
ctx.buflen = 0;
|
||||
zuc256Init(ctx.state, K, IV);
|
||||
}
|
||||
|
||||
// 分阶段处理加密数据
|
||||
public static void zuc256EncryptUpdate(ZUC256EncryptCtx ctx, byte[] in, int inlen, byte[] out) {
|
||||
if (in == null || out == null || inlen == 0) return;
|
||||
|
||||
// 处理缓冲区中剩余的非4字节数据
|
||||
if (ctx.buflen > 0) {
|
||||
int need = 4 - ctx.buflen;
|
||||
int copy = Math.min(inlen, need);
|
||||
|
||||
System.arraycopy(in, 0, ctx.buf, ctx.buflen, copy);
|
||||
ctx.buflen += copy;
|
||||
|
||||
// 调整输入指针和长度
|
||||
byte[] newIn = new byte[inlen - copy];
|
||||
if (inlen - copy > 0) {
|
||||
System.arraycopy(in, copy, newIn, 0, inlen - copy);
|
||||
}
|
||||
in = newIn;
|
||||
inlen -= copy;
|
||||
|
||||
// 缓冲区已满,处理一个完整的4字节块
|
||||
if (ctx.buflen == 4) {
|
||||
int keystream = zuc256GenerateKeyword(ctx.state);
|
||||
int plain = getU32(ctx.buf, 0);
|
||||
putU32(out, 0, plain ^ keystream);
|
||||
|
||||
ctx.buflen = 0;
|
||||
Arrays.fill(ctx.buf, (byte) 0);
|
||||
|
||||
// 调整输出指针
|
||||
byte[] newOut = new byte[out.length - 4];
|
||||
if (out.length - 4 > 0) {
|
||||
System.arraycopy(out, 4, newOut, 0, out.length - 4);
|
||||
}
|
||||
out = newOut;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理完整的4字节块
|
||||
int fullBlocks = inlen / 4;
|
||||
if (fullBlocks > 0) {
|
||||
int[] keystream = new int[fullBlocks];
|
||||
zuc256GenerateKeystream(ctx.state, fullBlocks, keystream);
|
||||
|
||||
// 逐块异或加密
|
||||
for (int i = 0; i < fullBlocks; i++) {
|
||||
int plain = getU32(in, i * 4);
|
||||
putU32(out, i * 4, plain ^ keystream[i]);
|
||||
}
|
||||
|
||||
// 调整输入指针和长度
|
||||
int processed = fullBlocks * 4;
|
||||
byte[] newIn = new byte[inlen - processed];
|
||||
if (inlen - processed > 0) {
|
||||
System.arraycopy(in, processed, newIn, 0, inlen - processed);
|
||||
}
|
||||
in = newIn;
|
||||
inlen -= processed;
|
||||
}
|
||||
|
||||
// 缓存剩余不足4字节的数据
|
||||
if (inlen > 0) {
|
||||
System.arraycopy(in, 0, ctx.buf, 0, inlen);
|
||||
ctx.buflen = inlen;
|
||||
}
|
||||
}
|
||||
|
||||
// 完成加密处理
|
||||
public static void zuc256EncryptFinish(ZUC256EncryptCtx ctx, byte[] out) {
|
||||
if (ctx == null || out == null) return;
|
||||
|
||||
// 处理缓冲区中剩余的不足4字节数据
|
||||
if (ctx.buflen > 0) {
|
||||
int keystream = zuc256GenerateKeyword(ctx.state);
|
||||
byte[] keystreamBytes = new byte[4];
|
||||
putU32(keystreamBytes, 0, keystream);
|
||||
|
||||
// 逐字节异或
|
||||
for (int i = 0; i < ctx.buflen; i++) {
|
||||
out[i] = (byte) (ctx.buf[i] ^ keystreamBytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理上下文
|
||||
Arrays.fill(ctx.buf, (byte) 0);
|
||||
ctx.buflen = 0;
|
||||
Arrays.fill(ctx.state.LFSR, 0);
|
||||
ctx.state.R1 = 0;
|
||||
ctx.state.R2 = 0;
|
||||
}
|
||||
|
||||
// 一次性加密函数
|
||||
public static void zuc256Crypt(ZUCState state, byte[] in, int inlen, byte[] out) {
|
||||
if (state == null || in == null || out == null) return;
|
||||
|
||||
ZUC256EncryptCtx ctx = new ZUC256EncryptCtx();
|
||||
// 复制状态
|
||||
System.arraycopy(state.LFSR, 0, ctx.state.LFSR, 0, state.LFSR.length);
|
||||
ctx.state.R1 = state.R1;
|
||||
ctx.state.R2 = state.R2;
|
||||
|
||||
// 执行加解密
|
||||
zuc256EncryptUpdate(ctx, in, inlen, out);
|
||||
int remainingOffset = (inlen / 4) * 4;
|
||||
byte[] finishOut = new byte[out.length - remainingOffset];
|
||||
if (finishOut.length > 0) {
|
||||
System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
|
||||
}
|
||||
zuc256EncryptFinish(ctx, finishOut);
|
||||
System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
|
||||
|
||||
// 更新状态
|
||||
System.arraycopy(ctx.state.LFSR, 0, state.LFSR, 0, ctx.state.LFSR.length);
|
||||
state.R1 = ctx.state.R1;
|
||||
state.R2 = ctx.state.R2;
|
||||
}
|
||||
|
||||
// 提取IV
|
||||
public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||||
if (input25Byte == null || output23Byte == null) return;
|
||||
|
||||
// 复制前17字节
|
||||
System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
||||
|
||||
// 处理剩余8字节
|
||||
byte[] src = new byte[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
src[i] = (byte) (input25Byte[17 + i] & 0x3F);
|
||||
}
|
||||
|
||||
output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
||||
output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
|
||||
output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
|
||||
output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
|
||||
output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
|
||||
output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
||||
}
|
||||
|
||||
// 打印字节数组为十六进制
|
||||
public static void printHex(String label, byte[] data, int len) {
|
||||
System.out.print(label + ": ");
|
||||
for (int i = 0; i < len; i++) {
|
||||
System.out.printf("%02x ", data[i] & 0xFF);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
// 主函数,验证ZUC256加解密功能
|
||||
public static void main(String[] args) {
|
||||
// 1. 明文
|
||||
byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
|
||||
int plaintextLen = plaintext.length;
|
||||
System.out.println("明文: " + new String(plaintext));
|
||||
printHex("明文(十六进制)", plaintext, plaintextLen);
|
||||
|
||||
// 2. 密钥(32字节ASCII)
|
||||
byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
|
||||
printHex("密钥", key, 32);
|
||||
|
||||
// 3. 初始向量(25字节ASCII)
|
||||
byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
|
||||
byte[] iv = new byte[23];
|
||||
extractIv(inputIv25Byte, iv);
|
||||
printHex("提取后的IV", iv, 23);
|
||||
|
||||
// 4. 分配加密/解密缓冲区
|
||||
byte[] ciphertext = new byte[plaintextLen];
|
||||
byte[] decryptedtext = new byte[plaintextLen];
|
||||
|
||||
// 5. 加密
|
||||
ZUCState state = new ZUCState();
|
||||
zuc256Init(state, key, iv);
|
||||
zuc256Crypt(state, plaintext, plaintextLen, ciphertext);
|
||||
printHex("密文", ciphertext, plaintextLen);
|
||||
|
||||
// 6. 解密(重新初始化状态)
|
||||
zuc256Init(state, key, iv);
|
||||
zuc256Crypt(state, ciphertext, plaintextLen, decryptedtext);
|
||||
printHex("解密后", decryptedtext, plaintextLen);
|
||||
System.out.println("解密文本: " + new String(decryptedtext));
|
||||
|
||||
// 7. 验证结果
|
||||
if (Arrays.equals(plaintext, decryptedtext)) {
|
||||
System.out.println("=== 测试成功: 解密结果与明文一致 ===");
|
||||
} else {
|
||||
System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
|
||||
}
|
||||
}
|
||||
}
|
||||
295
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Core.java
Normal file
295
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Core.java
Normal file
@@ -0,0 +1,295 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
|
||||
import static com.zuc.zuc256.Zuc256Util.L1;
|
||||
import static com.zuc.zuc256.Zuc256Util.L2;
|
||||
import static com.zuc.zuc256.Zuc256Util.add31;
|
||||
import static com.zuc.zuc256.Zuc256Util.makeU31;
|
||||
import static com.zuc.zuc256.Zuc256Util.makeU32;
|
||||
import static com.zuc.zuc256.Zuc256Util.rot31;
|
||||
|
||||
/**
|
||||
* ZUC-256 核心:状态初始化、密钥字生成、密钥流生成。
|
||||
*/
|
||||
public final class Zuc256Core {
|
||||
|
||||
private Zuc256Core() {}
|
||||
|
||||
/** 初始化状态(Key + IV) */
|
||||
public static void initState(Zuc256State state, byte[] key32, byte[] iv) {
|
||||
zuc256SetMacKey(state, key32, iv, 0);
|
||||
}
|
||||
|
||||
/** 生成单个密钥字 */
|
||||
public static int generateKeyword(Zuc256State state) {
|
||||
int[] LFSR = state.LFSR;
|
||||
int R1 = state.R1;
|
||||
int R2 = state.R2;
|
||||
int X0, X1, X2, X3;
|
||||
int W1, W2, U, V;
|
||||
int Z;
|
||||
|
||||
// BitReconstruction4
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
|
||||
|
||||
Z = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
|
||||
state.R1 = R1;
|
||||
state.R2 = R2;
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
// 生成指定长度的密钥流
|
||||
public static void zuc256GenerateKeystream(Zuc256State state, int nwords, int[] keystream) {
|
||||
int[] LFSR = state.LFSR;
|
||||
int R1 = state.R1;
|
||||
int R2 = state.R2;
|
||||
int X0, X1, X2, X3;
|
||||
int W1, W2, U, V;
|
||||
|
||||
for (int i = 0; i < nwords; i++) {
|
||||
// BitReconstruction4
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
|
||||
|
||||
keystream[i] = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
// S盒查找
|
||||
int T0 = Zuc256Tables.S0[(U >>> 24) & 0xFF] & 0xFF;
|
||||
int T2 = Zuc256Tables.S0[(U >>> 8) & 0xFF] & 0xFF;
|
||||
int T4 = Zuc256Tables.S0[(V >>> 24) & 0xFF] & 0xFF;
|
||||
int T6 = Zuc256Tables.S0[(V >>> 8) & 0xFF] & 0xFF;
|
||||
|
||||
int T1 = Zuc256Tables.S1[(U >>> 16) & 0xFF] & 0xFF;
|
||||
int T3 = Zuc256Tables.S1[U & 0xFF] & 0xFF;
|
||||
int T5 = Zuc256Tables.S1[(V >>> 16) & 0xFF] & 0xFF;
|
||||
int T7 = Zuc256Tables.S1[V & 0xFF] & 0xFF;
|
||||
|
||||
R1 = makeU32(T0, T1, T2, T3);
|
||||
R2 = makeU32(T4, T5, T6, T7);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
}
|
||||
|
||||
state.R1 = R1;
|
||||
state.R2 = R2;
|
||||
}
|
||||
|
||||
|
||||
// 生成单个密钥字
|
||||
public static int zuc256GenerateKeyword(Zuc256State state) {
|
||||
int[] LFSR = state.LFSR;
|
||||
int R1 = state.R1;
|
||||
int R2 = state.R2;
|
||||
int X0, X1, X2, X3;
|
||||
int W1, W2, U, V;
|
||||
int Z;
|
||||
|
||||
// BitReconstruction4
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
X3 = ((LFSR[2] & 0xFFFF) << 16) | (LFSR[0] >>> 15);
|
||||
|
||||
Z = X3 ^ ((X0 ^ R1) + R2);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
|
||||
state.R1 = R1;
|
||||
state.R2 = R2;
|
||||
|
||||
return Z;
|
||||
}
|
||||
|
||||
|
||||
// 初始化MAC密钥
|
||||
private static void zuc256SetMacKey(Zuc256State key, byte[] K, byte[] IV, int macbits) {
|
||||
int[] LFSR = key.LFSR;
|
||||
int R1 = 0;
|
||||
int R2 = 0;
|
||||
int X0, X1, X2;
|
||||
int W, W1, W2, U, V;
|
||||
int[] D;
|
||||
|
||||
int IV17 = (IV[17] & 0xFF) >> 2;
|
||||
int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4);
|
||||
int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6);
|
||||
int IV20 = IV[19] & 0x3F;
|
||||
int IV21 = (IV[20] & 0xFF) >> 2;
|
||||
int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4);
|
||||
int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6);
|
||||
int IV24 = IV[22] & 0x3F;
|
||||
|
||||
D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3];
|
||||
|
||||
LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF);
|
||||
LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF);
|
||||
LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF);
|
||||
LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF);
|
||||
LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF);
|
||||
LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF);
|
||||
LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF);
|
||||
LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF);
|
||||
LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF);
|
||||
LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF);
|
||||
LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF);
|
||||
LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF);
|
||||
LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF);
|
||||
LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF);
|
||||
LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF);
|
||||
LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF);
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
// BitReconstruction3
|
||||
X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
|
||||
// F(X0, X1, X2)
|
||||
W = (X0 ^ R1) + R2;
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithInitialisationMode(W >> 1)
|
||||
int v = LFSR[0];
|
||||
v = add31(v, rot31(LFSR[0], 8));
|
||||
v = add31(v, rot31(LFSR[4], 20));
|
||||
v = add31(v, rot31(LFSR[10], 21));
|
||||
v = add31(v, rot31(LFSR[13], 17));
|
||||
v = add31(v, rot31(LFSR[15], 15));
|
||||
int t = W >>> 1;
|
||||
v = add31(v, t);
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
}
|
||||
|
||||
// BitReconstruction2
|
||||
X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
|
||||
// F_(X1, X2)
|
||||
W1 = R1 + X1;
|
||||
W2 = R2 ^ X2;
|
||||
U = L1((W1 << 16) | (W2 >>> 16));
|
||||
V = L2((W2 << 16) | (W1 >>> 16));
|
||||
|
||||
R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[U & 0xFF]);
|
||||
|
||||
R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
Zuc256Tables.S1[V & 0xFF]);
|
||||
|
||||
// LFSRWithWorkMode
|
||||
long a = LFSR[0];
|
||||
a += (long)LFSR[0] << 8;
|
||||
a += (long)LFSR[4] << 20;
|
||||
a += (long)LFSR[10] << 21;
|
||||
a += (long)LFSR[13] << 17;
|
||||
a += (long)LFSR[15] << 15;
|
||||
a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
|
||||
System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
LFSR[15] = v;
|
||||
|
||||
key.R1 = R1;
|
||||
key.R2 = R2;
|
||||
}
|
||||
}
|
||||
|
||||
74
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Demo.java
Normal file
74
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Demo.java
Normal file
@@ -0,0 +1,74 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.zuc.zuc256.Zuc256Util.extractIv;
|
||||
import static com.zuc.zuc256.Zuc256Util.printHex;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 演示主函数
|
||||
*/
|
||||
public final class Zuc256Demo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 1. 明文
|
||||
// byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
|
||||
byte[] plaintext = {(byte)0xaa, (byte)0xbb, (byte)0xcc, (byte)0xdd, (byte)0xee};
|
||||
int plaintextLen = plaintext.length;
|
||||
System.out.println("明文: " + new String(plaintext));
|
||||
printHex("明文(十六进制)", plaintext, plaintextLen);
|
||||
|
||||
// 2. 密钥(32字节ASCII)
|
||||
byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
|
||||
printHex("密钥", key, 32);
|
||||
|
||||
// 3. 初始向量(25字节ASCII)
|
||||
byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
|
||||
byte[] iv = new byte[23];
|
||||
extractIv(inputIv25Byte, iv);
|
||||
printHex("提取后的IV", iv, 23);
|
||||
|
||||
// 4. 分配加密/解密缓冲区
|
||||
byte[] ciphertext = new byte[plaintextLen];
|
||||
byte[] decryptedtext = new byte[plaintextLen];
|
||||
|
||||
// 5. 加密
|
||||
Zuc256State stateEnc = new Zuc256State();
|
||||
Zuc256Core.initState(stateEnc, key, iv);
|
||||
zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
|
||||
printHex("密文", ciphertext, plaintextLen);
|
||||
|
||||
// 6. 解密(重新初始化状态)
|
||||
Zuc256State stateDec = new Zuc256State();
|
||||
Zuc256Core.initState(stateDec, key, iv);
|
||||
zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
|
||||
printHex("解密后", decryptedtext, plaintextLen);
|
||||
System.out.println("解密文本: " + new String(decryptedtext));
|
||||
|
||||
// 7. 验证结果
|
||||
if (Arrays.equals(plaintext, decryptedtext)) {
|
||||
System.out.println("=== 测试成功: 解密结果与明文一致 ===");
|
||||
} else {
|
||||
System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
|
||||
}
|
||||
}
|
||||
|
||||
// 一次性加密
|
||||
public static void zuc256Crypt(Zuc256State state, byte[] in, int inlen, byte[] out) {
|
||||
if (state == null || in == null || out == null) return;
|
||||
|
||||
Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
|
||||
|
||||
// 执行加解密
|
||||
ctx.update(in, inlen, out);
|
||||
int remainingOffset = (inlen / 4) * 4;
|
||||
byte[] finishOut = new byte[out.length - remainingOffset];
|
||||
if (finishOut.length > 0) {
|
||||
System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
|
||||
}
|
||||
ctx.finish(finishOut);
|
||||
System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
|
||||
}
|
||||
}
|
||||
131
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256EncryptCtx.java
Normal file
131
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256EncryptCtx.java
Normal file
@@ -0,0 +1,131 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeystream;
|
||||
import static com.zuc.zuc256.Zuc256Core.zuc256GenerateKeyword;
|
||||
import static com.zuc.zuc256.Zuc256Util.getU32;
|
||||
import static com.zuc.zuc256.Zuc256Util.putU32;
|
||||
|
||||
|
||||
/**
|
||||
* 加密上下文类
|
||||
*/
|
||||
public final class Zuc256EncryptCtx {
|
||||
Zuc256State state;
|
||||
byte[] buf;
|
||||
int buflen;
|
||||
|
||||
public Zuc256EncryptCtx(Zuc256State state, byte[] buf){
|
||||
this.state = state;
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
public Zuc256EncryptCtx(Zuc256State state){
|
||||
this.state = state;
|
||||
this.buf = new byte[4];
|
||||
}
|
||||
|
||||
public Zuc256EncryptCtx(){
|
||||
this.state = new Zuc256State();
|
||||
this.buf = new byte[4];
|
||||
}
|
||||
|
||||
// 初始化加密上下文
|
||||
public void init(byte[] key32, byte[] iv) {
|
||||
Arrays.fill(this.buf, (byte) 0);
|
||||
this.buflen = 0;
|
||||
Zuc256Core.initState(this.state, key32, iv);
|
||||
}
|
||||
|
||||
// 分阶段处理加密数据
|
||||
public void update(byte[] in, int inlen, byte[] out) {
|
||||
if (in == null || out == null || inlen == 0) return;
|
||||
|
||||
// 处理缓冲区中剩余的非4字节数据
|
||||
if (this.buflen > 0) {
|
||||
int need = 4 - this.buflen;
|
||||
int copy = Math.min(inlen, need);
|
||||
|
||||
System.arraycopy(in, 0, this.buf, this.buflen, copy);
|
||||
this.buflen += copy;
|
||||
|
||||
// 调整输入指针和长度
|
||||
byte[] newIn = new byte[inlen - copy];
|
||||
if (inlen - copy > 0) {
|
||||
System.arraycopy(in, copy, newIn, 0, inlen - copy);
|
||||
}
|
||||
in = newIn;
|
||||
inlen -= copy;
|
||||
|
||||
// 缓冲区已满,处理一个完整的4字节块
|
||||
if (this.buflen == 4) {
|
||||
int keystream = zuc256GenerateKeyword(this.state);
|
||||
int plain = getU32(this.buf, 0);
|
||||
putU32(out, 0, plain ^ keystream);
|
||||
|
||||
this.buflen = 0;
|
||||
Arrays.fill(this.buf, (byte) 0);
|
||||
|
||||
// 调整输出指针
|
||||
byte[] newOut = new byte[out.length - 4];
|
||||
if (out.length - 4 > 0) {
|
||||
System.arraycopy(out, 4, newOut, 0, out.length - 4);
|
||||
}
|
||||
out = newOut;
|
||||
}
|
||||
}
|
||||
|
||||
// 处理完整的4字节块
|
||||
int fullBlocks = inlen / 4;
|
||||
if (fullBlocks > 0) {
|
||||
int[] keystream = new int[fullBlocks];
|
||||
zuc256GenerateKeystream(this.state, fullBlocks, keystream);
|
||||
|
||||
// 逐块异或加密
|
||||
for (int i = 0; i < fullBlocks; i++) {
|
||||
int plain = getU32(in, i * 4);
|
||||
putU32(out, i * 4, plain ^ keystream[i]);
|
||||
}
|
||||
|
||||
// 调整输入指针和长度
|
||||
int processed = fullBlocks * 4;
|
||||
byte[] newIn = new byte[inlen - processed];
|
||||
if (inlen - processed > 0) {
|
||||
System.arraycopy(in, processed, newIn, 0, inlen - processed);
|
||||
}
|
||||
in = newIn;
|
||||
inlen -= processed;
|
||||
}
|
||||
|
||||
// 缓存剩余不足4字节的数据
|
||||
if (inlen > 0) {
|
||||
System.arraycopy(in, 0, this.buf, 0, inlen);
|
||||
this.buflen = inlen;
|
||||
}
|
||||
}
|
||||
|
||||
// 完成加密处理
|
||||
public void finish(byte[] out) {
|
||||
if (this == null || out == null) return;
|
||||
|
||||
// 处理缓冲区中剩余的不足4字节数据
|
||||
if (this.buflen > 0) {
|
||||
int keystream = zuc256GenerateKeyword(this.state);
|
||||
byte[] keystreamBytes = new byte[4];
|
||||
putU32(keystreamBytes, 0, keystream);
|
||||
|
||||
// 逐字节异或
|
||||
for (int i = 0; i < this.buflen; i++) {
|
||||
out[i] = (byte) (this.buf[i] ^ keystreamBytes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理上下文
|
||||
Arrays.fill(this.buf, (byte) 0);
|
||||
this.buflen = 0;
|
||||
Arrays.fill(this.state.LFSR, 0);
|
||||
this.state.R1 = 0;
|
||||
this.state.R2 = 0;
|
||||
}
|
||||
}
|
||||
15
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256MacCtx.java
Normal file
15
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256MacCtx.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
/**
|
||||
* MAC上下文类
|
||||
*/
|
||||
public final class Zuc256MacCtx {
|
||||
int[] LFSR = new int[16];
|
||||
int R1;
|
||||
int R2;
|
||||
byte[] buf = new byte[4];
|
||||
int buflen;
|
||||
int[] T = new int[4];
|
||||
int[] K0 = new int[4];
|
||||
int macbits;
|
||||
}
|
||||
10
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256State.java
Normal file
10
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256State.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
/**
|
||||
* ZUC状态类
|
||||
*/
|
||||
public final class Zuc256State {
|
||||
int[] LFSR = new int[16]; // 线性反馈移位寄存器
|
||||
int R1; // 寄存器1
|
||||
int R2; // 寄存器2
|
||||
}
|
||||
59
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Tables.java
Normal file
59
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Tables.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
/**
|
||||
* 常量表:S0/S1 与 ZUC256_D。
|
||||
* 注意:JavaCard 目标环境建议将表定义为 static final 数组,按 int/short 存放。
|
||||
*/
|
||||
public final class Zuc256Tables {
|
||||
|
||||
private Zuc256Tables() {}
|
||||
|
||||
// S盒:S0, S1
|
||||
public static final int[] S0 = {
|
||||
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
|
||||
};
|
||||
|
||||
public static final int[] S1 = {
|
||||
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
|
||||
};
|
||||
|
||||
/**
|
||||
* 常量数组 D
|
||||
*/
|
||||
public static final int[][] ZUC256_D = {
|
||||
{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}
|
||||
};
|
||||
}
|
||||
112
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Util.java
Normal file
112
ref_c_java/zuc256_java_2/com/zuc/zuc256/Zuc256Util.java
Normal file
@@ -0,0 +1,112 @@
|
||||
package com.zuc.zuc256;
|
||||
|
||||
/**
|
||||
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
||||
*/
|
||||
public final class Zuc256Util {
|
||||
|
||||
private Zuc256Util() {}
|
||||
|
||||
/** 辅助方法:将字节数组转换为32位整数 */
|
||||
public static int getU32(byte[] p, int offset) {
|
||||
return ((p[offset] & 0xFF) << 24) |
|
||||
((p[offset + 1] & 0xFF) << 16) |
|
||||
((p[offset + 2] & 0xFF) << 8) |
|
||||
(p[offset + 3] & 0xFF);
|
||||
}
|
||||
|
||||
/** 辅助方法:将32位整数转换为字节数组 */
|
||||
public static void putU32(byte[] p, int offset, int v) {
|
||||
p[offset] = (byte) (v >> 24);
|
||||
p[offset + 1] = (byte) (v >> 16);
|
||||
p[offset + 2] = (byte) (v >> 8);
|
||||
p[offset + 3] = (byte) v;
|
||||
}
|
||||
|
||||
// === 31/32 位运算 ===
|
||||
|
||||
/** 31位加法 */
|
||||
public static int add31(int a, int b) {
|
||||
long sum = (long)a + b;
|
||||
long q = (sum & 0x7FFFFFFF);
|
||||
long w = (sum >> 31);
|
||||
long e = q+w;
|
||||
return (int) (e);
|
||||
}
|
||||
|
||||
/** 31位旋转 */
|
||||
public static int rot31(int a, int k) {
|
||||
return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/** 32位旋转 */
|
||||
public static int rot32(int a, int k) {
|
||||
int t = (a << k) | (a >>> (32 - k));
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* L1函数
|
||||
*/
|
||||
public static int L1(int x) {
|
||||
return x ^
|
||||
rot32(x, 2) ^
|
||||
rot32(x, 10) ^
|
||||
rot32(x, 18) ^
|
||||
rot32(x, 24);
|
||||
}
|
||||
|
||||
/**
|
||||
* L2函数
|
||||
*/
|
||||
public static int L2(int x) {
|
||||
return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
||||
}
|
||||
|
||||
/** 创建31位无符号整数 */
|
||||
public static int makeU31(int a, int b, int c, int d) {
|
||||
return (((a & 0xFF) << 23) |
|
||||
((b & 0xFF) << 16) |
|
||||
((c & 0xFF) << 8) |
|
||||
(d & 0xFF)) & 0x7FFFFFFF;
|
||||
}
|
||||
|
||||
/** 创建32位无符号整数 */
|
||||
public static int makeU32(int a, int b, int c, int d) {
|
||||
return ((a & 0xFF) << 24) |
|
||||
((b & 0xFF) << 16) |
|
||||
((c & 0xFF) << 8) |
|
||||
(d & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
/** 提取IV */
|
||||
public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||||
if (input25Byte == null || output23Byte == null) return;
|
||||
|
||||
// 复制前17字节
|
||||
System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
||||
|
||||
// 处理剩余8字节
|
||||
byte[] src = new byte[8];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
src[i] = (byte) (input25Byte[17 + i] & 0x3F);
|
||||
}
|
||||
|
||||
output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
||||
output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
|
||||
output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
|
||||
output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
|
||||
output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
|
||||
output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
||||
}
|
||||
|
||||
/** 打印十六进制(调试用,TODO 生产/JC 环境可移除) */
|
||||
public static void printHex(String label, byte[] data, int len) {
|
||||
System.out.print(label + ": ");
|
||||
for (int i = 0; i < len; i++) {
|
||||
System.out.printf("%02x ", data[i] & 0xFF);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
681
ref_c_java/zuc256_javacard_old/Method_old.java
Normal file
681
ref_c_java/zuc256_javacard_old/Method_old.java
Normal file
@@ -0,0 +1,681 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
//import javacard.framework.APDU;
|
||||
//import javacard.framework.ISO7816;
|
||||
//import javacard.framework.ISOException;
|
||||
//import javacard.framework.JCSystem;
|
||||
//import javacard.framework.Util;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * 仅做一次“自检调用”:
|
||||
// * 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ?
|
||||
// * 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ?
|
||||
// * Response: 2字节 [encMatch, dblEncRestored],1=真,0=假
|
||||
// */
|
||||
//public final class Method_old {
|
||||
// // ======= 已按你提供的数据填充 =======
|
||||
//
|
||||
// // Key: 32字节
|
||||
// private static final byte[] KEY32 = {
|
||||
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
|
||||
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
|
||||
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
|
||||
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66
|
||||
// };
|
||||
//
|
||||
// // IV
|
||||
// private static final byte[] IV25 = {//todo 23 -> 25
|
||||
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
|
||||
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
|
||||
// (byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7
|
||||
// };
|
||||
//
|
||||
// // Input: 明文(38字节)
|
||||
// private static final byte[] INPUT = {
|
||||
// (byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF,
|
||||
// (byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8,
|
||||
// (byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B,
|
||||
// (byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,
|
||||
// (byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30
|
||||
// };
|
||||
//
|
||||
// // EncResult: 期望密文(38字节)
|
||||
// private static final byte[] ENC_EXPECTED = {
|
||||
// (byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5,
|
||||
// (byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27,
|
||||
// (byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D,
|
||||
// (byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9,
|
||||
// (byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2
|
||||
// };
|
||||
//
|
||||
// // ======================================
|
||||
//
|
||||
// // 运行时缓冲:放RAM,避免写EEPROM
|
||||
// private final Zuc256EncryptCtx ctx;
|
||||
//
|
||||
// public Method_old() {
|
||||
// ctx = new Zuc256EncryptCtx(); // 仅创建一次
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public void processData(APDU apdu) {
|
||||
// short L = (short) INPUT.length;
|
||||
// byte[] buf1; // Enc(Input)
|
||||
// byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
|
||||
// buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// buf2 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// byte[] apduBuf = apdu.getBuffer();
|
||||
//
|
||||
// // 第一次:Enc(Input)
|
||||
// ctx.initZuc256EncryptCtx(KEY32, IV25);
|
||||
// Zuc256State tmpState = ctx.state;
|
||||
// ctx.updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1);
|
||||
// ctx.finishZuc256EncryptCtx(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
|
||||
//
|
||||
// Zuc256State tmpState2 = ctx.state;
|
||||
// boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0);
|
||||
//
|
||||
// // 第二次:Enc(Enc(Input)) 应还原 Input
|
||||
// ctx.initZuc256EncryptCtx(KEY32, IV25);
|
||||
// ctx.updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2);
|
||||
// ctx.finishZuc256EncryptCtx(buf2);
|
||||
// boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0);
|
||||
//
|
||||
// // 返回 2 字节结果:[encMatch, dblOk],1=真, 0=假
|
||||
// apduBuf[0] = (byte)(encMatch ? 1 : 0);
|
||||
// apduBuf[1] = (byte)(dblOk ? 1 : 0);
|
||||
// short outLen = 2;
|
||||
//
|
||||
// apdu.setOutgoing();
|
||||
// apdu.setOutgoingLength(outLen);
|
||||
// apdu.sendBytes((short)0, outLen);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * fake数据生成函数
|
||||
// * 输入: stmsi[6], data[5]
|
||||
// * 输出: fakedata[5]
|
||||
// */
|
||||
// private void makeFakeData(byte[] stmsi, byte[] data, byte[] fakedata) {
|
||||
// // 示例:逐字节异或 stmsi 前5字节
|
||||
// for (short i = 0; i < (short)5; i++) {
|
||||
// fakedata[i] = (byte)(data[i]);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * APDU处理函数
|
||||
// */
|
||||
// public short processDataFake(byte[] buffer, short off, short len, byte[] key_store) {
|
||||
// // 至少要有 12 个字节:1+1+1+6+5
|
||||
// if (len < (short)12) {
|
||||
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
// }
|
||||
//
|
||||
// // === 解析入参 ===
|
||||
// byte inType = buffer[(short)(off + 0)]; // 类型 A1
|
||||
// byte inLen = buffer[(short)(off + 1)]; // 长度 0x0C
|
||||
// byte secParam = buffer[(short)(off + 2)]; // 安全参数
|
||||
//
|
||||
// // STMSI
|
||||
// byte[] stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6);
|
||||
//
|
||||
// // data
|
||||
// byte[] data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// Util.arrayCopyNonAtomic(buffer, (short)(off + 9), data, (short)0, (short)5);
|
||||
//
|
||||
// // === 生成 fakedata ===
|
||||
// byte[] fakedata = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// makeFakeData(stmsi, data, fakedata);
|
||||
//
|
||||
// // === 出参组装 ===
|
||||
// buffer[(short)(off + 0)] = (byte)0xA1; // 类型
|
||||
// buffer[(short)(off + 1)] = (byte)0x06; // 长度
|
||||
// buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取
|
||||
// Util.arrayCopyNonAtomic(fakedata, (short)0, buffer, (short)(off + 3), (short)5);
|
||||
//
|
||||
// return (short)8; // 出参总长度
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// public short updateKey(byte[] buffer, short off, short len, byte[] key_store) {
|
||||
// final short SLOT_SIZE = 40; // 每个槽固定40字节
|
||||
// final short HDR_LEN = 4; // 报文头长度: [0]=keyLenField, [1]=alg, [2]=keyId, [3]=ver
|
||||
//
|
||||
// // === 解析头 ===
|
||||
// byte keyLenField = buffer[(short)(off + 0)]; // 包含头部+密钥的总长度
|
||||
// byte alg = buffer[(short)(off + 1)];
|
||||
// byte keyId = buffer[(short)(off + 2)];
|
||||
// byte ver = buffer[(short)(off + 3)];
|
||||
//
|
||||
// // 计算实际密钥长度
|
||||
// short realKeyLen = (short)(keyLenField - (byte)3); // 长度字段 = key长度 + 3字节头
|
||||
// if (realKeyLen <= 0) {
|
||||
// ISOException.throwIt(ISO7816.SW_DATA_INVALID); // key长度不合法
|
||||
// }
|
||||
//
|
||||
// // 检查APDU长度和key长度是否匹配
|
||||
// if (len != (short)(HDR_LEN + realKeyLen)) {
|
||||
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
// }
|
||||
// if (len > SLOT_SIZE) {
|
||||
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
|
||||
// }
|
||||
//
|
||||
// // === 将原有 key_store 拷贝到 RAM,避免直接覆盖 EEPROM (可选) ===
|
||||
// byte[] key_buf = JCSystem.makeTransientByteArray((short)80, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// Util.arrayCopyNonAtomic(key_store, (short)0, key_buf, (short)0, (short)key_store.length);
|
||||
//
|
||||
// // === 遍历槽,找到匹配的 (alg, keyId, ver),否则找空槽 ===
|
||||
// short slots = (short)(key_store.length / SLOT_SIZE);
|
||||
// short target = -1;
|
||||
// for (short i = 0; i < slots; i++) {
|
||||
// short base = (short)(i * SLOT_SIZE);
|
||||
// byte algOld = key_store[(short)(base + 1)];
|
||||
// byte keyIdOld = key_store[(short)(base + 2)];
|
||||
// byte verOld = key_store[(short)(base + 3)];
|
||||
//
|
||||
// if (algOld == alg && keyId == keyIdOld && ver == verOld) {
|
||||
// target = i; // 找到已存在的,覆盖它
|
||||
// break;
|
||||
// }
|
||||
// if (key_store[base] == (byte)0x00 && target == -1) {
|
||||
// target = i; // 找到第一个空槽
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (target == -1) {
|
||||
// ISOException.throwIt(ISO7816.SW_FILE_FULL); // 没有空位
|
||||
// }
|
||||
//
|
||||
// // === 覆盖写入本次APDU的头+密钥数据 ===
|
||||
// short base = (short)(target * SLOT_SIZE);
|
||||
// // 先清空槽
|
||||
// Util.arrayFillNonAtomic(key_store, base, SLOT_SIZE, (byte)0x00);
|
||||
// // 再写入APDU传入的头+数据 (len 个字节)
|
||||
// Util.arrayCopyNonAtomic(buffer, off, key_store, base, len);
|
||||
//
|
||||
// return 0; // 无返回数据
|
||||
// }
|
||||
//
|
||||
// // === zuc256Util
|
||||
//
|
||||
//// /** 辅助方法:将字节数组转换为32位整数 */
|
||||
//// public static int getU32(byte[] p, int offset) {
|
||||
//// return ((p[offset] & 0xFF) << 24) |
|
||||
//// ((p[offset + 1] & 0xFF) << 16) |
|
||||
//// ((p[offset + 2] & 0xFF) << 8) |
|
||||
//// (p[offset + 3] & 0xFF);
|
||||
//// }
|
||||
// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
|
||||
// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
|
||||
// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
|
||||
// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 辅助方法:将32位整数转换为字节数组 */
|
||||
//// public static void putU32(byte[] p, int offset, int v) {
|
||||
//// p[offset] = (byte) (v >> 24);
|
||||
//// p[offset + 1] = (byte) (v >> 16);
|
||||
//// p[offset + 2] = (byte) (v >> 8);
|
||||
//// p[offset + 3] = (byte) v;
|
||||
//// }
|
||||
// /** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
|
||||
// public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
||||
// // 写高16位
|
||||
// p[offset] = (byte) ((vhi >> 8) & 0xFF);
|
||||
// p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
|
||||
//
|
||||
// // 写低16位
|
||||
// p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
|
||||
// p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // === 31/32 位运算 ===
|
||||
//
|
||||
//// /** 31位加法 */
|
||||
//// public static int add31(int a, int b) {
|
||||
//// long sum = (long)a + b;
|
||||
//// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
||||
//// }
|
||||
// /** 31位加法: (a+b) mod (2^31 - 1)
|
||||
// * 输入: a_lo=低16位, a_hi=高15位
|
||||
// * b_lo=低16位, b_hi=高15位
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
|
||||
// // ---- 低16位相加 ----
|
||||
// short lo = (short)(a_lo + b_lo);
|
||||
// short carry = (short)(
|
||||
// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
|
||||
// ? 1 : 0
|
||||
// );
|
||||
// // ---- 高15位相加 + 进位 ----
|
||||
// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
|
||||
//
|
||||
// // 提取第31位(hi_raw bit15)
|
||||
// short topbit = (short)((hi_raw >>> 15) & 1);
|
||||
// short hi = (short)(hi_raw & 0x7FFF); // 保留15位
|
||||
//
|
||||
// // ---- 若第31位=1,再+1 ----
|
||||
// if (topbit == 1) {
|
||||
// short lo2 = (short)(lo + 1);
|
||||
// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
|
||||
// lo = lo2;
|
||||
// hi = (short)((hi + c2) & 0x7FFF);
|
||||
// }
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 31位旋转 */
|
||||
//// public static int rot31(int a, int k) {
|
||||
//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
||||
//// }
|
||||
// /** 31位循环左移: (a <<< k) mod (2^31 -1)
|
||||
// * 输入: a_lo=低16位, a_hi=高15位
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
|
||||
// k = (short)(k % 31); // 限制在 0..30
|
||||
// if (k == 0) {
|
||||
// out[0] = a_lo;
|
||||
// out[1] = (short)(a_hi & 0x7FFF);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 拆成 31 位数组 [bit0..bit30]
|
||||
// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 16; i++) {
|
||||
// bits[i] = (short)((a_lo >>> i) & 1);
|
||||
// }
|
||||
// for (short i = 0; i < 15; i++) {
|
||||
// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
|
||||
// }
|
||||
//
|
||||
// // 旋转
|
||||
// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 31; i++) {
|
||||
// short j = (short)((i + k) % 31);
|
||||
// resBits[j] = bits[i];
|
||||
// }
|
||||
//
|
||||
// // 拼回 lo, hi
|
||||
// short lo = 0;
|
||||
// for (short i = 0; i < 16; i++) {
|
||||
// lo = (short)(lo | (resBits[i] << i));
|
||||
// }
|
||||
// short hi = 0;
|
||||
// for (short i = 0; i < 15; i++) {
|
||||
// hi = (short)(hi | (resBits[(short)(16 + i)] << i));
|
||||
// }
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 32位旋转 */
|
||||
//// public static int rot32(int a, int k) {
|
||||
//// return (a << k) | (a >>> (32 - k));
|
||||
//// }
|
||||
// /** 32位循环左移: (a<<<k) */
|
||||
// public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
|
||||
// k = (short)(k & 31); // 0..31
|
||||
// short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
|
||||
// while (k > 0) {
|
||||
// // 先做 1 位循环左移
|
||||
// // 注意:short 在 >>> 时会先提升为 int,所以下面都再用 &1 取最低位,避免符号扩展影响
|
||||
// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
|
||||
// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
|
||||
// hi = nw_hi;
|
||||
// lo = nw_lo;
|
||||
// k--;
|
||||
// }
|
||||
// out[0] = lo; // 低16位
|
||||
// out[1] = hi; // 高16位
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /**
|
||||
//// * L1函数
|
||||
//// */
|
||||
//// public static int L1(int x) {
|
||||
//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
|
||||
//// }
|
||||
// /**
|
||||
// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
|
||||
// * 输入: x_lo, x_hi
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
|
||||
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // acc = x
|
||||
// acc[0] = x_lo;
|
||||
// acc[1] = x_hi;
|
||||
//
|
||||
// // acc ^= rot32(x, 2)
|
||||
// rot32(x_lo, x_hi, (short)2, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 10)
|
||||
// rot32(x_lo, x_hi, (short)10, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 18)
|
||||
// rot32(x_lo, x_hi, (short)18, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 24)
|
||||
// rot32(x_lo, x_hi, (short)24, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// out[0] = acc[0];
|
||||
// out[1] = acc[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /**
|
||||
//// * L2函数
|
||||
//// */
|
||||
//// public static int L2(int x) {
|
||||
//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
||||
//// }
|
||||
// /**
|
||||
// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
|
||||
// * 输入: x_lo, x_hi
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
|
||||
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // acc = x
|
||||
// acc[0] = x_lo;
|
||||
// acc[1] = x_hi;
|
||||
//
|
||||
// // acc ^= rot32(x, 8)
|
||||
// rot32(x_lo, x_hi, (short)8, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 14)
|
||||
// rot32(x_lo, x_hi, (short)14, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 22)
|
||||
// rot32(x_lo, x_hi, (short)22, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 30)
|
||||
// rot32(x_lo, x_hi, (short)30, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// out[0] = acc[0];
|
||||
// out[1] = acc[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 创建31位无符号整数 */
|
||||
//// public static int makeU31(int a, int b, int c, int d) {
|
||||
//// return (((a & 0xFF) << 23) |
|
||||
//// ((b & 0xFF) << 16) |
|
||||
//// ((c & 0xFF) << 8) |
|
||||
//// (d & 0xFF)) & 0x7FFFFFFF;
|
||||
//// }
|
||||
// /** 创建31位无符号整数,结果放到 out[0]=lo, out[1]=hi(15位) */
|
||||
// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
|
||||
// // 四个字节
|
||||
// short b0 = (short)(a & 0xFF); // 最高字节
|
||||
// short b1 = (short)(b & 0xFF);
|
||||
// short b2 = (short)(c & 0xFF);
|
||||
// short b3 = (short)(d & 0xFF); // 最低字节
|
||||
//
|
||||
// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
|
||||
// // lo = 低16位
|
||||
// out[0] = (short)((b2 << 8) | b3);
|
||||
//
|
||||
// // hi = 高15位(丢弃 bit31)
|
||||
// out[1] = (short)((b0 << 7) | b1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 创建32位无符号整数 */
|
||||
//// public static int makeU32(int a, int b, int c, int d) {
|
||||
//// return ((a & 0xFF) << 24) |
|
||||
//// ((b & 0xFF) << 16) |
|
||||
//// ((c & 0xFF) << 8) |
|
||||
//// (d & 0xFF);
|
||||
//// }
|
||||
// /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */
|
||||
// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) {
|
||||
// // 四个字节
|
||||
// short b0 = (short)(a & 0xFF); // 最高字节
|
||||
// short b1 = (short)(b & 0xFF);
|
||||
// short b2 = (short)(c & 0xFF);
|
||||
// short b3 = (short)(d & 0xFF); // 最低字节
|
||||
//
|
||||
// // lo = 低16位
|
||||
// out[0] = (short)((b2 << 8) | b3);
|
||||
//
|
||||
// // hi = 高16位
|
||||
// out[1] = (short)((b0 << 8) | b1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /** 提取IV */
|
||||
// public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||||
// if (input25Byte == null || output23Byte == null) return;
|
||||
//
|
||||
// // 复制前17字节
|
||||
// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
|
||||
//
|
||||
//
|
||||
// // 处理剩余8字节
|
||||
// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 8; i++) {
|
||||
// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
|
||||
// }
|
||||
//
|
||||
// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
||||
// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
|
||||
// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
|
||||
// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
|
||||
// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
|
||||
// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo)
|
||||
// * out[0] = lo, out[1] = hi
|
||||
// */
|
||||
// static void add32(short a_lo, short a_hi,
|
||||
// short b_lo, short b_hi,
|
||||
// short[] out /*len=2*/) {
|
||||
//
|
||||
// // ---- 低16位 ----
|
||||
// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF));
|
||||
// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8);
|
||||
//
|
||||
// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF);
|
||||
// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF);
|
||||
// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0);
|
||||
// short carry1 = (short)(lo_high >>> 8);
|
||||
//
|
||||
// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF));
|
||||
//
|
||||
// // ---- 高16位 ----
|
||||
// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1);
|
||||
// short carry2 = (short)(hi_low >>> 8);
|
||||
//
|
||||
// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF);
|
||||
// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF);
|
||||
// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2);
|
||||
//
|
||||
// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF));
|
||||
//
|
||||
// // ---- 输出 ----
|
||||
// out[0] = lo_res;
|
||||
// out[1] = hi_res;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位加法 + 返回进位(只用 short)
|
||||
// * 输入: (a_hi:a_lo) + (b_hi:b_lo)
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// * 返回: 最终进位(0/1)
|
||||
// */
|
||||
// static short add32_with_carry(short a_lo, short a_hi,
|
||||
// short b_lo, short b_hi,
|
||||
// short[] out /* len=2 */) {
|
||||
// // ---- 低16位:分两段8位相加 ----
|
||||
// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510
|
||||
// short c0 = (short)(s0 >>> 8); // 0/1
|
||||
// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF)
|
||||
// + ((b_lo >>> 8) & (short)0x00FF)
|
||||
// + c0); // 0..511
|
||||
// short c1 = (short)(s1 >>> 8); // 0/1
|
||||
// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF));
|
||||
//
|
||||
// // ---- 高16位:再分两段8位相加,并加上 c1 ----
|
||||
// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1);
|
||||
// short c2 = (short)(s2 >>> 8); // 0/1
|
||||
// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF)
|
||||
// + ((b_hi >>> 8) & (short)0x00FF)
|
||||
// + c2); // 0..511
|
||||
// short c3 = (short)(s3 >>> 8); // 最终进位 0/1
|
||||
// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF));
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// return (short)(c3 & 1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 64位加法: a4 + b4 -> a4
|
||||
// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword)
|
||||
// */
|
||||
// static void add64(short[] a, short[] b) {
|
||||
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // 低 32 位
|
||||
// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp);
|
||||
// a[0] = tmp[0];
|
||||
// a[1] = tmp[1];
|
||||
//
|
||||
// // 高 32 位 + carry
|
||||
// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp);
|
||||
// a[2] = tmp[0];
|
||||
// a[3] = tmp[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 32位异或
|
||||
// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) {
|
||||
// out[0] = (short)(a_lo ^ b_lo);
|
||||
// out[1] = (short)(a_hi ^ b_hi);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32),
|
||||
// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。
|
||||
// */
|
||||
// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) {
|
||||
// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0;
|
||||
//
|
||||
// if (k >= 16) {
|
||||
// a3 = a2; // 0
|
||||
// a2 = a1; // 原 hi16
|
||||
// a1 = a0; // 原 lo16
|
||||
// a0 = 0;
|
||||
// k = (short)(k - 16);
|
||||
// }
|
||||
//
|
||||
// while (k > 0) {
|
||||
// short c0 = (short)((a0 >>> 15) & 1);
|
||||
// short c1 = (short)((a1 >>> 15) & 1);
|
||||
// short c2 = (short)((a2 >>> 15) & 1);
|
||||
//
|
||||
// a3 = (short)((a3 << 1) | c2);
|
||||
// a2 = (short)((a2 << 1) | c1);
|
||||
// a1 = (short)((a1 << 1) | c0);
|
||||
// a0 = (short)(a0 << 1);
|
||||
// k--;
|
||||
// }
|
||||
//
|
||||
// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。
|
||||
// */
|
||||
// static void and64_7FFFFFFF_to32(short[] A, short[] out) {
|
||||
// out[0] = A[0]; // lo16
|
||||
// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit)
|
||||
// out[2] = 0;
|
||||
// out[3] = 0;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 64位无符号右移 31 位
|
||||
// * 输入: A[0..3] (short[4], A[0]最低16位)
|
||||
// * 输出: out[0..3]
|
||||
// */
|
||||
// static void shr64u_31(short[] A, short[] out) {
|
||||
// // 先拼出 64bit 的逻辑,逐段右移
|
||||
// // A >>> 31 = (A >>> 16) >>> 15
|
||||
//
|
||||
// // 先右移 16,相当于丢掉 A[0],整体右移一半字
|
||||
// out[0] = A[1]; // 原 A[1] -> 新低16位
|
||||
// out[1] = A[2]; // 原 A[2]
|
||||
// out[2] = A[3]; // 原 A[3]
|
||||
// out[3] = 0; // 高位补0
|
||||
//
|
||||
// // 再右移 15 位
|
||||
// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位
|
||||
// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15);
|
||||
// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15);
|
||||
//
|
||||
// out[0] = (short)((c0 & 0x0001) | (out[1] << 1));
|
||||
// out[1] = (short)((c1 & 0x0001) | (out[2] << 1));
|
||||
// out[2] = (short)(c2 & 0x0001);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位无符号右移 1 位
|
||||
// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位)
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// static void shr32u1(short lo, short hi, short[] out) {
|
||||
// // >>>1:先处理低16位
|
||||
// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15));
|
||||
// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF);
|
||||
//
|
||||
// out[0] = nwLo;
|
||||
// out[1] = nwHi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//}
|
||||
595
ref_c_java/zuc256_javacard_old/Zuc256Core.java
Normal file
595
ref_c_java/zuc256_javacard_old/Zuc256Core.java
Normal file
@@ -0,0 +1,595 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
//
|
||||
//import javacard.framework.JCSystem;
|
||||
//
|
||||
//import static com.cscn.Zuc256Util.L1;
|
||||
//import static com.cscn.Zuc256Util.L2;
|
||||
//import static com.cscn.Zuc256Util.add31;
|
||||
//import static com.cscn.Zuc256Util.add32;
|
||||
//import static com.cscn.Zuc256Util.add64;
|
||||
//import static com.cscn.Zuc256Util.and64_7FFFFFFF_to32;
|
||||
//import static com.cscn.Zuc256Util.create_64b_from_32b;
|
||||
//import static com.cscn.Zuc256Util.makeU31;
|
||||
//import static com.cscn.Zuc256Util.makeU32;
|
||||
//import static com.cscn.Zuc256Util.rot31;
|
||||
//import static com.cscn.Zuc256Util.shr32u1;
|
||||
//import static com.cscn.Zuc256Util.shr64u_31;
|
||||
//import static com.cscn.Zuc256Util.xor32;
|
||||
//
|
||||
///**
|
||||
// * ZUC-256 核心:状态初始化、密钥字生成、密钥流生成。
|
||||
// */
|
||||
//public class Zuc256Core {
|
||||
//
|
||||
// private Zuc256Core() {}
|
||||
//
|
||||
// /** 初始化状态(Key + IV) */
|
||||
// public static void initState(Zuc256State state, byte[] key32, byte[] iv) {
|
||||
// zuc256SetMacKey(state, key32, iv, (short)0);
|
||||
// }
|
||||
//
|
||||
// /** 生成单个密钥字 */
|
||||
// public static void zuc256GenerateKeyword(Zuc256State state, short[] out) {
|
||||
//// int[] LFSR = state.LFSR;
|
||||
//// int R1 = state.R1;
|
||||
//// int R2 = state.R2;
|
||||
//// int X0, X1, X2, X3;
|
||||
//// int W1, W2, U, V;
|
||||
//// int Z;
|
||||
//
|
||||
// short[] LFSR_hi = state.LFSR_hi;
|
||||
// short[] LFSR_lo = state.LFSR_lo;
|
||||
//
|
||||
// // 工作寄存器(32位值的临时 out32 缓冲,全用short[2])[lo, hi]
|
||||
// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] TMP2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // 载入 R1,R2
|
||||
// R1[0] = state.R1_lo;
|
||||
// R1[1] = state.R1_hi;
|
||||
// R2[0] = state.R2_lo;
|
||||
// R2[1] = state.R2_hi;
|
||||
//
|
||||
//
|
||||
// // BitReconstruction4
|
||||
// short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位
|
||||
// X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi
|
||||
// X0[0] = LFSR_lo[14]; // lo
|
||||
//
|
||||
// // X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15)
|
||||
// X1[1] = LFSR_lo[11];
|
||||
// X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));
|
||||
//
|
||||
// // X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15)
|
||||
// X2[1] = LFSR_lo[7];
|
||||
// X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));
|
||||
//
|
||||
// // X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15)
|
||||
// X3[1] = LFSR_lo[2];
|
||||
// X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1));
|
||||
//
|
||||
//
|
||||
//
|
||||
// // ---- 输入:X0,X1,X2,X3,R1,R2 均为 short[2]; 输出:Z,W1,W2,U,V ----
|
||||
//
|
||||
// // Z = X3 ^ ((X0 ^ R1) + R2)
|
||||
// xor32(X0[0], X0[1], R1[0], R1[1], TMP0); // TMP0 = X0 ^ R1
|
||||
// add32(TMP0[0], TMP0[1], R2[0], R2[1], TMP1); // TMP1 = TMP0 + R2
|
||||
// xor32(X3[0], X3[1], TMP1[0], TMP1[1], Z); // Z = X3 ^ TMP1
|
||||
//
|
||||
// // F_(X1, X2)
|
||||
// // W1 = R1 + X1
|
||||
// add32(R1[0], R1[1], X1[0], X1[1], W1);
|
||||
//
|
||||
// // W2 = R2 ^ X2
|
||||
// xor32(R2[0], R2[1], X2[0], X2[1], W2);
|
||||
//
|
||||
// // U = L1((W1 << 16) | (W2 >>> 16))
|
||||
// // (W1<<16): lo=0, hi=W1_lo
|
||||
// // (W2>>>16): lo=W2_hi, hi=0
|
||||
// // OR 结果: lo=W2_hi, hi=W1_lo
|
||||
// L1(W2[1], W1[0], U);
|
||||
//
|
||||
// // V = L2((W2 << 16) | (W1 >>> 16))
|
||||
// // (W2<<16): lo=0, hi=W2_lo
|
||||
// // (W1>>>16): lo=W1_hi, hi=0
|
||||
// // OR 结果: lo=W1_hi, hi=W2_lo
|
||||
// L2(W1[1], W2[0], V);
|
||||
//
|
||||
//
|
||||
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[U & 0xFF]);
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF
|
||||
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF
|
||||
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF
|
||||
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF
|
||||
// R1);
|
||||
//
|
||||
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[V & 0xFF]);
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF
|
||||
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF
|
||||
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF
|
||||
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF
|
||||
// R2);
|
||||
//
|
||||
//
|
||||
//
|
||||
//// // LFSRWithWorkMode
|
||||
//// long a = LFSR[0];
|
||||
//// a += (long)LFSR[0] << 8;
|
||||
//// a += (long)LFSR[4] << 20;
|
||||
//// a += (long)LFSR[10] << 21;
|
||||
//// a += (long)LFSR[13] << 17;
|
||||
//// a += (long)LFSR[15] << 15;
|
||||
// // ---- 先准备累加器 A (64位) ----
|
||||
// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器,初始全0
|
||||
// A[0] = 0; A[1] = 0; A[2] = 0; A[3] = 0;
|
||||
//
|
||||
// // 临时缓冲
|
||||
// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi)
|
||||
// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数
|
||||
//
|
||||
// // a = LFSR[0]
|
||||
// tmp32[0] = state.LFSR_lo[0];
|
||||
// tmp32[1] = state.LFSR_hi[0];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)0);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
// // a += (LFSR[0] << 8)
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)8);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
// // a += (LFSR[4] << 20)
|
||||
// tmp32[0] = state.LFSR_lo[4];
|
||||
// tmp32[1] = state.LFSR_hi[4];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)20);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
// // a += (LFSR[10] << 21)
|
||||
// tmp32[0] = state.LFSR_lo[10];
|
||||
// tmp32[1] = state.LFSR_hi[10];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)21);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
// // a += (LFSR[13] << 17)
|
||||
// tmp32[0] = state.LFSR_lo[13];
|
||||
// tmp32[1] = state.LFSR_hi[13];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)17);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
// // a += (LFSR[15] << 15)
|
||||
// tmp32[0] = state.LFSR_lo[15];
|
||||
// tmp32[1] = state.LFSR_hi[15];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)15);
|
||||
// add64(A, tmp64);
|
||||
//
|
||||
//// a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
// // ---- 第一次折叠:a = (a & 0x7FFFFFFF) + (a >>> 31) ----
|
||||
// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// and64_7FFFFFFF_to32(A, low31); // low31 = A & 0x7FFFFFFF
|
||||
// shr64u_31(A, r31); // r31 = A >>> 31
|
||||
//
|
||||
// A[0]=0; A[1]=0; A[2]=0; A[3]=0;
|
||||
// add64(A, low31);
|
||||
// add64(A, r31);
|
||||
//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
// // ---- 第二次折叠,得到 v(32位)----
|
||||
// short[] low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// and64_7FFFFFFF_to32(A, low31b);
|
||||
// shr64u_31(A, r31b);
|
||||
//
|
||||
// v64[0]=0; v64[1]=0; v64[2]=0; v64[3]=0;
|
||||
// add64(v64, low31b);
|
||||
// add64(v64, r31b);
|
||||
//
|
||||
// // v = 32位,取 v64 的低两段
|
||||
// short v_lo = v64[0];
|
||||
// short v_hi = (short)(v64[1] & 0x7FFF); // 只保留31位
|
||||
//
|
||||
//// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
// // LFSR_lo 向左移
|
||||
// for (short i = 0; i < (short)15; i++) {
|
||||
// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
|
||||
// }
|
||||
// // LFSR_hi 向左移
|
||||
// for (short i = 0; i < (short)15; i++) {
|
||||
// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
|
||||
// }
|
||||
//
|
||||
//// LFSR[15] = v;
|
||||
// // ---- 写回 LFSR[15] ----
|
||||
// state.LFSR_lo[15] = v_lo;
|
||||
// state.LFSR_hi[15] = v_hi;
|
||||
//
|
||||
//// state.R1 = R1;
|
||||
//// state.R2 = R2;
|
||||
// state.R1_lo = R1[0];
|
||||
// state.R1_hi = R1[1];
|
||||
//
|
||||
// state.R2_lo = R2[0];
|
||||
// state.R2_hi = R2[1];
|
||||
//
|
||||
//
|
||||
//// return Z;
|
||||
// out[0] = Z[0];
|
||||
// out[1] = Z[1];
|
||||
//
|
||||
// }
|
||||
//
|
||||
// // 生成指定长度的密钥流
|
||||
// public static void zuc256GenerateKeystream(Zuc256State state,
|
||||
// short nwords,
|
||||
// short[] keystream_hi,
|
||||
// short[] keystream_lo) {
|
||||
// // 临时存放一个 32 位关键字
|
||||
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < nwords; i++) {
|
||||
// // 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi
|
||||
// zuc256GenerateKeyword(state, tmp);
|
||||
// // 存入输出数组
|
||||
// keystream_lo[i] = tmp[0];
|
||||
// keystream_hi[i] = tmp[1];
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 初始化MAC密钥
|
||||
// private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) {
|
||||
// short[] D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
//
|
||||
//// int IV17 = (IV[17] & 0xFF) >> 2;
|
||||
//// int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4);
|
||||
//// int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6);
|
||||
//// int IV20 = IV[19] & 0x3F;
|
||||
//// int IV21 = (IV[20] & 0xFF) >> 2;
|
||||
//// int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4);
|
||||
//// int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6);
|
||||
//// int IV24 = IV[22] & 0x3F;
|
||||
// // IV 拆分
|
||||
// short IV17 = (short)((IV[17] & 0xFF) >>> 2);
|
||||
// short IV18 = (short)(((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >>> 4));
|
||||
// short IV19 = (short)(((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >>> 6));
|
||||
// short IV20 = (short)(IV[19] & 0x3F);
|
||||
// short IV21 = (short)((IV[20] & 0xFF) >>> 2);
|
||||
// short IV22 = (short)(((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >>> 4));
|
||||
// short IV23 = (short)(((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >>> 6));
|
||||
// short IV24 = (short)(IV[22] & 0x3F);
|
||||
//
|
||||
//// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3];
|
||||
// short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3);
|
||||
// Zuc256Tables.getDRow(row, D, (short)0);
|
||||
// Zuc256Tables.getDRow(row, D, (short)0);
|
||||
//
|
||||
//
|
||||
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi)
|
||||
//
|
||||
// // 逐项装载 LFSR
|
||||
//// LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF);
|
||||
// makeU31((short)(K[0] & 0xFF), (short)D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), tmp);
|
||||
// state.LFSR_lo[0] = tmp[0]; state.LFSR_hi[0] = tmp[1];
|
||||
//
|
||||
//// LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF);
|
||||
// makeU31((short)(K[1] & 0xFF), (short)D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), tmp);
|
||||
// state.LFSR_lo[1] = tmp[0]; state.LFSR_hi[1] = tmp[1];
|
||||
//
|
||||
//// LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF);
|
||||
// makeU31((short)(K[2] & 0xFF), (short)D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), tmp);
|
||||
// state.LFSR_lo[2] = tmp[0]; state.LFSR_hi[2] = tmp[1];
|
||||
//
|
||||
//// LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF);
|
||||
// makeU31((short)(K[3] & 0xFF), (short)D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), tmp);
|
||||
// state.LFSR_lo[3] = tmp[0]; state.LFSR_hi[3] = tmp[1];
|
||||
//
|
||||
//// LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF);
|
||||
// makeU31((short)(K[4] & 0xFF), (short)D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), tmp);
|
||||
// state.LFSR_lo[4] = tmp[0]; state.LFSR_hi[4] = tmp[1];
|
||||
//
|
||||
//// LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF);
|
||||
// makeU31((short)(IV[0] & 0xFF), (short)(D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), tmp);
|
||||
// state.LFSR_lo[5] = tmp[0]; state.LFSR_hi[5] = tmp[1];
|
||||
//
|
||||
//// LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF);
|
||||
// makeU31((short)(IV[1] & 0xFF), (short)(D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), tmp);
|
||||
// state.LFSR_lo[6] = tmp[0]; state.LFSR_hi[6] = tmp[1];
|
||||
//
|
||||
//// LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF);
|
||||
// makeU31((short)(IV[10] & 0xFF), (short)(D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), tmp);
|
||||
// state.LFSR_lo[7] = tmp[0]; state.LFSR_hi[7] = tmp[1];
|
||||
//
|
||||
//// LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF);
|
||||
// makeU31((short)(K[8] & 0xFF), (short)(D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), tmp);
|
||||
// state.LFSR_lo[8] = tmp[0]; state.LFSR_hi[8] = tmp[1];
|
||||
//
|
||||
//// LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF);
|
||||
// makeU31((short)(K[9] & 0xFF), (short)(D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), tmp);
|
||||
// state.LFSR_lo[9] = tmp[0]; state.LFSR_hi[9] = tmp[1];
|
||||
//
|
||||
//// LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF);
|
||||
// makeU31((short)(IV[5] & 0xFF), (short)(D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), tmp);
|
||||
// state.LFSR_lo[10] = tmp[0]; state.LFSR_hi[10] = tmp[1];
|
||||
//
|
||||
//// LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF);
|
||||
// makeU31((short)(K[11] & 0xFF), (short)(D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), tmp);
|
||||
// state.LFSR_lo[11] = tmp[0]; state.LFSR_hi[11] = tmp[1];
|
||||
//
|
||||
//// LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF);
|
||||
// makeU31((short)(K[12] & 0xFF), (short)(D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), tmp);
|
||||
// state.LFSR_lo[12] = tmp[0]; state.LFSR_hi[12] = tmp[1];
|
||||
//
|
||||
//// LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF);
|
||||
// makeU31((short)(K[13] & 0xFF), (short)D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), tmp);
|
||||
// state.LFSR_lo[13] = tmp[0]; state.LFSR_hi[13] = tmp[1];
|
||||
//
|
||||
//// LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF);
|
||||
// makeU31((short)(K[14] & 0xFF), (short)(D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), tmp);
|
||||
// state.LFSR_lo[14] = tmp[0]; state.LFSR_hi[14] = tmp[1];
|
||||
//
|
||||
//// LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF);
|
||||
// makeU31((short)(K[15] & 0xFF), (short)(D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), tmp);
|
||||
// state.LFSR_lo[15] = tmp[0]; state.LFSR_hi[15] = tmp[1];
|
||||
//
|
||||
//
|
||||
// short c15_2 = 0;
|
||||
// for (short i = 0; i < 32; i++) {
|
||||
// // BitReconstruction3
|
||||
//// X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF);
|
||||
// // X0 = ((L15 & 0x7FFF8000)<<1) | (L14 & 0xFFFF)
|
||||
// c15_2 = (short)((state.LFSR_lo[15] & (short)0x8000) >>> 15);
|
||||
// X0[1] = (short)(((state.LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001));
|
||||
// X0[0] = state.LFSR_lo[14];
|
||||
//
|
||||
//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
// // X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15)
|
||||
// X1[1] = state.LFSR_lo[11];
|
||||
// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1));
|
||||
//
|
||||
//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
// // X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15)
|
||||
// X2[1] = state.LFSR_lo[7];
|
||||
// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1));
|
||||
//
|
||||
//
|
||||
//
|
||||
// // F(X0, X1, X2)
|
||||
// // W = (X0 ^ R1) + R2
|
||||
// xor32(X0[0], X0[1], R1[0], R1[1], TMP);
|
||||
// add32(TMP[0], TMP[1], R2[0], R2[1], W);
|
||||
//
|
||||
// // W1 = R1 + X1
|
||||
// add32(R1[0], R1[1], X1[0], X1[1], W1);
|
||||
//
|
||||
// // W2 = R2 ^ X2
|
||||
// xor32(R2[0], R2[1], X2[0], X2[1], W2);
|
||||
//
|
||||
// // U = L1((W1<<16) | (W2>>>16))
|
||||
// L1(W2[1], W1[0], U);
|
||||
//
|
||||
// // V = L2((W2<<16) | (W1>>>16))
|
||||
// L2(W1[1], W2[0], V);
|
||||
//
|
||||
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[U & 0xFF]);
|
||||
////
|
||||
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[V & 0xFF]);
|
||||
// // 更新 R1,R2
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF),
|
||||
// R1);
|
||||
//
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF),
|
||||
// R2);
|
||||
//
|
||||
// // LFSRWithInitialisationMode(W >> 1)
|
||||
//// int v = LFSR[0];
|
||||
// V[0] = state.LFSR_lo[0];
|
||||
// V[1] = state.LFSR_hi[0];
|
||||
//
|
||||
// // v = add31(v, rot31(state.LFSR[0], 8))
|
||||
// rot31(state.LFSR_lo[0], state.LFSR_hi[0], (short)8, T);
|
||||
// add31(V[0], V[1], T[0], T[1], V);
|
||||
//
|
||||
//// v = add31(v, rot31(state.LFSR[4], 20));
|
||||
// rot31(state.LFSR_lo[4], state.LFSR_hi[4], (short)20, T);
|
||||
// add31(V[0], V[1], T[0], T[1], V);
|
||||
//
|
||||
//// v = add31(v, rot31(state.LFSR[10], 21));
|
||||
// rot31(state.LFSR_lo[10], state.LFSR_hi[10], (short)21, T);
|
||||
// add31(V[0], V[1], T[0], T[1], V);
|
||||
//
|
||||
//// v = add31(v, rot31(state.LFSR[13], 17));
|
||||
// rot31(state.LFSR_lo[13], state.LFSR_hi[13], (short)17, T);
|
||||
// add31(V[0], V[1], T[0], T[1], V);
|
||||
//
|
||||
//// v = add31(v, rot31(state.LFSR[15], 15));
|
||||
// rot31(state.LFSR_lo[15], state.LFSR_hi[15], (short)15, T);
|
||||
// add31(V[0], V[1], T[0], T[1], V);
|
||||
//
|
||||
//// v = add31(v, W >>> 1);
|
||||
// shr32u1(W[0], W[1], T2); // T2[0]=lo, T2[1]=hi(无符号>>>1)
|
||||
// T2[1] = (short)(T2[1] & (short)0xFFFF); // 只保留31位
|
||||
// add31(V[0], V[1], T2[0], T2[1], V);
|
||||
//
|
||||
// // System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15)
|
||||
//// 相当于 System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15);
|
||||
// for (short j = 0; j < (short)15; j++) {
|
||||
// state.LFSR_lo[j] = state.LFSR_lo[(short)(j + 1)];
|
||||
// }
|
||||
//// 相当于 System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15);
|
||||
// for (short j = 0; j < (short)15; j++) {
|
||||
// state.LFSR_hi[j] = state.LFSR_hi[(short)(j + 1)];
|
||||
// }
|
||||
//
|
||||
//// state.LFSR[15] = v;
|
||||
// state.LFSR_lo[15] = V[0];
|
||||
// state.LFSR_hi[15] = (short)(V[1] & 0x7FFF);
|
||||
// }
|
||||
//
|
||||
// // BitReconstruction2
|
||||
//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
|
||||
// X1[1] = state.LFSR_lo[11];
|
||||
// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1));
|
||||
//
|
||||
//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
|
||||
// X2[1] = state.LFSR_lo[7];
|
||||
// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1));
|
||||
//
|
||||
// // F_(X1, X2)
|
||||
//// W1 = R1 + X1;
|
||||
// add32(R1[0], R1[1], X1[0], X1[1], W1); // W1 = R1 + X1
|
||||
//// W2 = R2 ^ X2;
|
||||
// xor32(R2[0], R2[1], X2[0], X2[1], W2); // W2 = R2 ^ X2
|
||||
//
|
||||
//// U = L1((W1 << 16) | (W2 >>> 16));
|
||||
// // U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo
|
||||
// L1(W2[1], W1[0], U);
|
||||
//
|
||||
//// V = L2((W2 << 16) | (W1 >>> 16));
|
||||
// // V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo
|
||||
// L2(W1[1], W2[0], V);
|
||||
//
|
||||
//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(U >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(U >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[U & 0xFF]);
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF),
|
||||
// R1);
|
||||
//
|
||||
//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
|
||||
//// Zuc256Tables.S1[(V >>> 16) & 0xFF],
|
||||
//// Zuc256Tables.S0[(V >>> 8) & 0xFF],
|
||||
//// Zuc256Tables.S1[V & 0xFF]);
|
||||
// makeU32(
|
||||
// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF),
|
||||
// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF),
|
||||
// R2);
|
||||
//
|
||||
// // ---- LFSRWithWorkMode ----
|
||||
// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 64位累加器
|
||||
// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
//
|
||||
// // LFSRWithWorkMode
|
||||
//// long a = LFSR[0];
|
||||
// tmp32[0] = state.LFSR_lo[0];
|
||||
// tmp32[1] = state.LFSR_hi[0];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)0); add64(A, tmp64);
|
||||
//
|
||||
//// a += (long)LFSR[0] << 8;
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)8); add64(A, tmp64);
|
||||
//
|
||||
//// a += (long)LFSR[4] << 20;
|
||||
// tmp32[0] = state.LFSR_lo[4]; tmp32[1] = state.LFSR_hi[4];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)20); add64(A, tmp64);
|
||||
//
|
||||
//// a += (long)LFSR[10] << 21;
|
||||
// tmp32[0] = state.LFSR_lo[10]; tmp32[1] = state.LFSR_hi[10];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)21); add64(A, tmp64);
|
||||
//
|
||||
//// a += (long)LFSR[13] << 17;
|
||||
// tmp32[0] = state.LFSR_lo[13]; tmp32[1] = state.LFSR_hi[13];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)17); add64(A, tmp64);
|
||||
//
|
||||
//// a += (long)LFSR[15] << 15;
|
||||
// tmp32[0] = state.LFSR_lo[15]; tmp32[1] = state.LFSR_hi[15];
|
||||
// create_64b_from_32b(tmp64, tmp32, (short)15); add64(A, tmp64);
|
||||
//
|
||||
//// a = (a & 0x7FFFFFFF) + (a >>> 31);
|
||||
// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
// and64_7FFFFFFF_to32(A, low31);
|
||||
// shr64u_31(A, r31);
|
||||
//
|
||||
// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
// add64(v64, low31);
|
||||
// add64(v64, r31);
|
||||
//
|
||||
//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
|
||||
// and64_7FFFFFFF_to32(v64, low31);
|
||||
// shr64u_31(v64, r31);
|
||||
// short[] vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;
|
||||
// add64(vv, low31);
|
||||
// add64(vv, r31);
|
||||
//
|
||||
// short v_lo = vv[0];
|
||||
// short v_hi = (short)(vv[1] & 0x7FFF);
|
||||
//
|
||||
//// LFSR左移
|
||||
//// System.arraycopy(LFSR, 1, LFSR, 0, 15);
|
||||
// // LFSR_lo 向左移
|
||||
// for (short i = 0; i < (short)15; i++) {
|
||||
// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)];
|
||||
// }
|
||||
// // LFSR_hi 向左移
|
||||
// for (short i = 0; i < (short)15; i++) {
|
||||
// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)];
|
||||
// }
|
||||
//
|
||||
//// LFSR[15] = v;
|
||||
// state.LFSR_lo[15] = v_lo;
|
||||
// state.LFSR_hi[15] = v_hi;
|
||||
//
|
||||
// state.R1_lo = R1[0]; state.R1_hi = R1[1];
|
||||
// state.R2_lo = R2[0]; state.R2_hi = R2[1];
|
||||
// }
|
||||
//}
|
||||
//
|
||||
66
ref_c_java/zuc256_javacard_old/Zuc256Demo.java
Normal file
66
ref_c_java/zuc256_javacard_old/Zuc256Demo.java
Normal file
@@ -0,0 +1,66 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
///**
|
||||
// * 演示主函数
|
||||
// */
|
||||
//public final class Zuc256Demo {
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
// // 1. 明文
|
||||
// byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
|
||||
// int plaintextLen = plaintext.length;
|
||||
// System.out.println("明文: " + new String(plaintext));
|
||||
// printHex("明文(十六进制)", plaintext, plaintextLen);
|
||||
//
|
||||
// // 2. 密钥(32字节ASCII)
|
||||
// byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
|
||||
// printHex("密钥", key, 32);
|
||||
//
|
||||
// // 3. 初始向量(25字节ASCII)
|
||||
// byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
|
||||
// byte[] iv = new byte[23];
|
||||
// extractIv(inputIv25Byte, iv);
|
||||
// printHex("提取后的IV", iv, 23);
|
||||
//
|
||||
// // 4. 分配加密/解密缓冲区
|
||||
// byte[] ciphertext = new byte[plaintextLen];
|
||||
// byte[] decryptedtext = new byte[plaintextLen];
|
||||
//
|
||||
// // 5. 加密
|
||||
// Zuc256State stateEnc = new Zuc256State();
|
||||
// Zuc256Core.initState(stateEnc, key, iv);
|
||||
// zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
|
||||
// printHex("密文", ciphertext, plaintextLen);
|
||||
//
|
||||
// // 6. 解密(重新初始化状态)
|
||||
// Zuc256State stateDec = new Zuc256State();
|
||||
// Zuc256Core.initState(stateDec, key, iv);
|
||||
// zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
|
||||
// printHex("解密后", decryptedtext, plaintextLen);
|
||||
// System.out.println("解密文本: " + new String(decryptedtext));
|
||||
//
|
||||
// // 7. 验证结果
|
||||
// if (Arrays.equals(plaintext, decryptedtext)) {
|
||||
// System.out.println("=== 测试成功: 解密结果与明文一致 ===");
|
||||
// } else {
|
||||
// System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 一次性加密
|
||||
// public static void zuc256Crypt(Zuc256State state, byte[] in, int inlen, byte[] out) {
|
||||
// if (state == null || in == null || out == null) return;
|
||||
//
|
||||
// Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
|
||||
//
|
||||
// // 执行加解密
|
||||
// ctx.update(in, inlen, out);
|
||||
// int remainingOffset = (inlen / 4) * 4;
|
||||
// byte[] finishOut = new byte[out.length - remainingOffset];
|
||||
// if (finishOut.length > 0) {
|
||||
// System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
|
||||
// }
|
||||
// ctx.finish(finishOut);
|
||||
// System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
|
||||
// }
|
||||
//}
|
||||
214
ref_c_java/zuc256_javacard_old/Zuc256EncryptCtx.java
Normal file
214
ref_c_java/zuc256_javacard_old/Zuc256EncryptCtx.java
Normal file
@@ -0,0 +1,214 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
//import javacard.framework.JCSystem;
|
||||
//import javacard.framework.Util;
|
||||
//
|
||||
//import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
|
||||
//import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
|
||||
//import static com.cscn.Zuc256Util.getU32;
|
||||
//import static com.cscn.Zuc256Util.putU32;
|
||||
//import static com.cscn.Zuc256Util.xor32;
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * 加密上下文类
|
||||
// */
|
||||
//public final class Zuc256EncryptCtx {
|
||||
// Zuc256State state;
|
||||
// byte[] buf;
|
||||
// short buflen;
|
||||
//
|
||||
// public Zuc256EncryptCtx(Zuc256State state, byte[] buf){
|
||||
// this.state = state;
|
||||
// this.buf = buf;
|
||||
// }
|
||||
//
|
||||
// public Zuc256EncryptCtx(Zuc256State state){
|
||||
// this.state = state;
|
||||
// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// }
|
||||
//
|
||||
// public Zuc256EncryptCtx(){
|
||||
// this.state = new Zuc256State(); //todo how to put in ram?
|
||||
// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// }
|
||||
//
|
||||
// // 初始化加密上下文
|
||||
// public void initZuc256EncryptCtx(byte[] key32, byte[] iv) {
|
||||
//// Arrays.fill(this.buf, (byte) 0);
|
||||
// for (short i = 0; i < (short)this.buf.length; i++) {
|
||||
// this.buf[i] = (byte)0;
|
||||
// }
|
||||
// this.buflen = 0;
|
||||
// Zuc256Core.initState(this.state, key32, iv);
|
||||
// }
|
||||
//
|
||||
// // 分阶段处理加密数据
|
||||
// public void updateZuc256EncryptCtx(byte[] in, short inlen, byte[] out) {
|
||||
// if (in == null || out == null || inlen == 0) return;
|
||||
//
|
||||
// short inPos = 0; // 输入偏移
|
||||
// short outPos = 0; // 输出偏移
|
||||
//
|
||||
// // 处理缓冲区中剩余的非4字节数据
|
||||
// if (this.buflen > 0) {
|
||||
//// int need = 4 - this.buflen;
|
||||
// short need = (short)(4 - this.buflen);
|
||||
//// int copy = Math.min(inlen, need);
|
||||
// short copy = (short)((inlen < need) ? inlen : need);
|
||||
//
|
||||
// // 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy);
|
||||
// Util.arrayCopyNonAtomic(in, (short)0, this.buf, this.buflen, copy);
|
||||
//
|
||||
// this.buflen += copy;
|
||||
//
|
||||
// // 调整输入指针和长度
|
||||
//// byte[] newIn = new byte[inlen - copy];
|
||||
//// if (inlen - copy > 0) {
|
||||
//// System.arraycopy(in, copy, newIn, 0, inlen - copy);
|
||||
//// }
|
||||
//// in = newIn;
|
||||
//// inlen -= copy;
|
||||
// // 推进输入指针与剩余长度
|
||||
// inPos += copy;
|
||||
// inlen -= copy;
|
||||
//
|
||||
// // 缓冲区已满,处理一个完整的4字节块
|
||||
// if (this.buflen == 4) {
|
||||
//// int keystream = zuc256GenerateKeyword(this.state);
|
||||
// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi
|
||||
//
|
||||
//// int plain = getU32(this.buf, 0);
|
||||
// // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi
|
||||
// short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// getU32(this.buf, (short)0, plain);
|
||||
//
|
||||
//// putU32(out, 0, plain ^ keystream);
|
||||
// // plain ^ ks → res
|
||||
// short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// xor32(plain[0], plain[1], ks[0], ks[1], res);
|
||||
// // 写回 out 的前4字节
|
||||
// putU32(out, (short)0, res[0], res[1]);
|
||||
//
|
||||
// this.buflen = 0;
|
||||
//// Arrays.fill(this.buf, (byte) 0);
|
||||
// for (short i = 0; i < (short)this.buf.length; i++) {
|
||||
// this.buf[i] = (byte)0;
|
||||
// }
|
||||
//
|
||||
// // 调整输出指针
|
||||
//// byte[] newOut = new byte[out.length - 4];
|
||||
//// if (out.length - 4 > 0) {
|
||||
//// System.arraycopy(out, 4, newOut, 0, out.length - 4);
|
||||
//// }
|
||||
//// out = newOut;
|
||||
// // 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。
|
||||
// outPos += 4;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 处理完整的4字节块
|
||||
//// int fullBlocks = inlen / 4;
|
||||
// short fullBlocks = (short) (inlen / 4);
|
||||
// if (fullBlocks > 0) {
|
||||
//// int[] keystream = new int[fullBlocks];
|
||||
// short[] ks_hi = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] ks_lo = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
//// zuc256GenerateKeystream(this.state, fullBlocks, keystream);
|
||||
// zuc256GenerateKeystream(this.state, fullBlocks, ks_hi, ks_lo);
|
||||
//
|
||||
// // 临时:装一个32位字
|
||||
// short[] word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // 逐块异或加密
|
||||
// for (short i = 0; i < fullBlocks; i++) {
|
||||
//// int plain = getU32(in, i * 4);
|
||||
// short off = (short) (i << 2); // i*4
|
||||
// // 读明文
|
||||
// getU32(in, (short)(inPos+off), word); // word[0]=lo, word[1]=hi
|
||||
//
|
||||
//// putU32(out, i * 4, plain ^ keystream[i]);
|
||||
// // XOR keystream
|
||||
// word[0] = (short)(word[0] ^ ks_lo[i]);
|
||||
// word[1] = (short)(word[1] ^ ks_hi[i]);
|
||||
// // 写密文
|
||||
// putU32(out, (short) (outPos+off), word[0], word[1]);
|
||||
// }
|
||||
//
|
||||
// // 调整输入指针和长度
|
||||
//// int processed = fullBlocks * 4;
|
||||
// short processed = (short)(fullBlocks * 4);
|
||||
//
|
||||
//// byte[] newIn = new byte[inlen - processed];
|
||||
//// if (inlen - processed > 0) {
|
||||
//// System.arraycopy(in, processed, newIn, 0, inlen - processed);
|
||||
//// }
|
||||
//// in = newIn;
|
||||
//// inlen -= processed;
|
||||
// // 推进输入/输出指针与剩余长度
|
||||
// inPos += processed;
|
||||
// inlen -= processed;
|
||||
// outPos += processed;
|
||||
// }
|
||||
//
|
||||
// // 缓存剩余不足4字节的数据
|
||||
// if (inlen > 0) {
|
||||
// // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen);
|
||||
// Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen);
|
||||
//
|
||||
// this.buflen = inlen;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // 完成加密处理
|
||||
// public void finishZuc256EncryptCtx(byte[] out) {
|
||||
// if (out == null) return;
|
||||
//
|
||||
// // 处理缓冲区中剩余的不足4字节数据
|
||||
// if (this.buflen > 0) {
|
||||
//// int keystream = zuc256GenerateKeyword(this.state);
|
||||
// // 生成一个 32-bit 密钥字:ks[0]=lo16, ks[1]=hi16
|
||||
// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// zuc256GenerateKeyword(this.state, ks);
|
||||
//
|
||||
//// byte[] keystreamBytes = new byte[4];
|
||||
//// putU32(keystreamBytes, 0, keystream);
|
||||
// byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// putU32(keystreamBytes, (short)0, ks[0], ks[1]);
|
||||
//
|
||||
// // 逐字节异或
|
||||
// short outOffset = (short)(out.length - this.buflen);
|
||||
// for (short i = 0; i < this.buflen; i++) {
|
||||
// out[(short)(i+outOffset)] = (byte) (this.buf[i] ^ keystreamBytes[i]);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 清理上下文
|
||||
//// Arrays.fill(this.buf, (byte) 0);
|
||||
// for(short i=0; i<4; i++) {
|
||||
// this.buf[i] = (byte)0;
|
||||
// }
|
||||
//
|
||||
// this.buflen = 0;
|
||||
//
|
||||
//// Arrays.fill(this.state.LFSR, 0);
|
||||
// // LFSR 全部清零(高低位数组各 16 个元素)
|
||||
// for (short i = 0; i < 16; i++) {
|
||||
// this.state.LFSR_lo[i] = 0;
|
||||
// this.state.LFSR_hi[i] = 0;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// this.state.R1 = 0;
|
||||
//// this.state.R2 = 0;
|
||||
//// R1、R2 清零
|
||||
// this.state.R1_lo = 0;
|
||||
// this.state.R1_hi = 0;
|
||||
// this.state.R2_lo = 0;
|
||||
// this.state.R2_hi = 0;
|
||||
// }
|
||||
//}
|
||||
32
ref_c_java/zuc256_javacard_old/Zuc256MacCtx.java
Normal file
32
ref_c_java/zuc256_javacard_old/Zuc256MacCtx.java
Normal file
@@ -0,0 +1,32 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
///**
|
||||
// * MAC上下文类(JavaCard版,int 拆分为两个 short)
|
||||
// */
|
||||
//public final class Zuc256MacCtx {
|
||||
// // LFSR: 原本 int[16],拆成 hi/lo 各 16 short
|
||||
// short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// //todo -> ram
|
||||
// short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // R1、R2: 原本 int,拆成 hi/lo
|
||||
// short R1_hi;
|
||||
// short R1_lo;
|
||||
// short R2_hi;
|
||||
// short R2_lo;
|
||||
//
|
||||
// // 缓冲区
|
||||
// byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short buflen;
|
||||
//
|
||||
// // T: 原本 int[4],拆成 hi/lo
|
||||
// short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] T_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // K0: 原本 int[4],拆成 hi/lo
|
||||
// short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // macbits: 原本 int,改成 short 足够
|
||||
// short macbits;
|
||||
//}
|
||||
25
ref_c_java/zuc256_javacard_old/Zuc256State.java
Normal file
25
ref_c_java/zuc256_javacard_old/Zuc256State.java
Normal file
@@ -0,0 +1,25 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
///**
|
||||
// * ZUC状态类(JavaCard版,int 拆为 hi/lo short)
|
||||
// */
|
||||
//public class Zuc256State {
|
||||
// // LFSR: 原 int[16] -> hi/lo 各 16
|
||||
// public short[] LFSR_hi;
|
||||
// public short[] LFSR_lo;
|
||||
//
|
||||
// // R1, R2: 原 int -> hi/lo
|
||||
// public short R1_hi;
|
||||
// public short R1_lo;
|
||||
// public short R2_hi;
|
||||
// public short R2_lo;
|
||||
//
|
||||
// public Zuc256State() {
|
||||
// this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// this.LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// }
|
||||
// public Zuc256State(short[] LSFR_HIGH, short[] LSFR_LOW) {
|
||||
// this.LFSR_hi = LSFR_HIGH;
|
||||
// this.LFSR_lo = LSFR_LOW;
|
||||
// }
|
||||
//}
|
||||
497
ref_c_java/zuc256_javacard_old/Zuc256Util.java
Normal file
497
ref_c_java/zuc256_javacard_old/Zuc256Util.java
Normal file
@@ -0,0 +1,497 @@
|
||||
//package com.cscn;
|
||||
//
|
||||
//import javacard.framework.Util;
|
||||
//import javacard.framework.JCSystem;
|
||||
//
|
||||
///**
|
||||
// * 辅助工具:装载/存储、位运算、线性变换、打印等。
|
||||
// */
|
||||
//public final class Zuc256Util {
|
||||
//
|
||||
// private Zuc256Util() {}
|
||||
//
|
||||
//// /** 辅助方法:将字节数组转换为32位整数 */
|
||||
//// public static int getU32(byte[] p, int offset) {
|
||||
//// return ((p[offset] & 0xFF) << 24) |
|
||||
//// ((p[offset + 1] & 0xFF) << 16) |
|
||||
//// ((p[offset + 2] & 0xFF) << 8) |
|
||||
//// (p[offset + 3] & 0xFF);
|
||||
//// }
|
||||
// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
|
||||
// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
|
||||
// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
|
||||
// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 辅助方法:将32位整数转换为字节数组 */
|
||||
//// public static void putU32(byte[] p, int offset, int v) {
|
||||
//// p[offset] = (byte) (v >> 24);
|
||||
//// p[offset + 1] = (byte) (v >> 16);
|
||||
//// p[offset + 2] = (byte) (v >> 8);
|
||||
//// p[offset + 3] = (byte) v;
|
||||
//// }
|
||||
// /** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
|
||||
// public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
||||
// // 写高16位
|
||||
// p[offset] = (byte) ((vhi >> 8) & 0xFF);
|
||||
// p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
|
||||
//
|
||||
// // 写低16位
|
||||
// p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
|
||||
// p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // === 31/32 位运算 ===
|
||||
//
|
||||
//// /** 31位加法 */
|
||||
//// public static int add31(int a, int b) {
|
||||
//// long sum = (long)a + b;
|
||||
//// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
||||
//// }
|
||||
// /** 31位加法: (a+b) mod (2^31 - 1)
|
||||
// * 输入: a_lo=低16位, a_hi=高15位
|
||||
// * b_lo=低16位, b_hi=高15位
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
|
||||
// // ---- 低16位相加 ----
|
||||
// short lo = (short)(a_lo + b_lo);
|
||||
// short carry = (short)(
|
||||
// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
|
||||
// ? 1 : 0
|
||||
// );
|
||||
// // ---- 高15位相加 + 进位 ----
|
||||
// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
|
||||
//
|
||||
// // 提取第31位(hi_raw bit15)
|
||||
// short topbit = (short)((hi_raw >>> 15) & 1);
|
||||
// short hi = (short)(hi_raw & 0x7FFF); // 保留15位
|
||||
//
|
||||
// // ---- 若第31位=1,再+1 ----
|
||||
// if (topbit == 1) {
|
||||
// short lo2 = (short)(lo + 1);
|
||||
// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
|
||||
// lo = lo2;
|
||||
// hi = (short)((hi + c2) & 0x7FFF);
|
||||
// }
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 31位旋转 */
|
||||
//// public static int rot31(int a, int k) {
|
||||
//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
||||
//// }
|
||||
// /** 31位循环左移: (a <<< k) mod (2^31 -1)
|
||||
// * 输入: a_lo=低16位, a_hi=高15位
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
|
||||
// k = (short)(k % 31); // 限制在 0..30
|
||||
// if (k == 0) {
|
||||
// out[0] = a_lo;
|
||||
// out[1] = (short)(a_hi & 0x7FFF);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // 拆成 31 位数组 [bit0..bit30]
|
||||
// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 16; i++) {
|
||||
// bits[i] = (short)((a_lo >>> i) & 1);
|
||||
// }
|
||||
// for (short i = 0; i < 15; i++) {
|
||||
// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
|
||||
// }
|
||||
//
|
||||
// // 旋转
|
||||
// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 31; i++) {
|
||||
// short j = (short)((i + k) % 31);
|
||||
// resBits[j] = bits[i];
|
||||
// }
|
||||
//
|
||||
// // 拼回 lo, hi
|
||||
// short lo = 0;
|
||||
// for (short i = 0; i < 16; i++) {
|
||||
// lo = (short)(lo | (resBits[i] << i));
|
||||
// }
|
||||
// short hi = 0;
|
||||
// for (short i = 0; i < 15; i++) {
|
||||
// hi = (short)(hi | (resBits[(short)(16 + i)] << i));
|
||||
// }
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 32位旋转 */
|
||||
//// public static int rot32(int a, int k) {
|
||||
//// return (a << k) | (a >>> (32 - k));
|
||||
//// }
|
||||
// /** 32位循环左移: (a<<<k) */
|
||||
// public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
|
||||
// k = (short)(k & 31); // 0..31
|
||||
// short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
|
||||
// while (k > 0) {
|
||||
// // 先做 1 位循环左移
|
||||
// // 注意:short 在 >>> 时会先提升为 int,所以下面都再用 &1 取最低位,避免符号扩展影响
|
||||
// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
|
||||
// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
|
||||
// hi = nw_hi;
|
||||
// lo = nw_lo;
|
||||
// k--;
|
||||
// }
|
||||
// out[0] = lo; // 低16位
|
||||
// out[1] = hi; // 高16位
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /**
|
||||
//// * L1函数
|
||||
//// */
|
||||
//// public static int L1(int x) {
|
||||
//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
|
||||
//// }
|
||||
// /**
|
||||
// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
|
||||
// * 输入: x_lo, x_hi
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
|
||||
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // acc = x
|
||||
// acc[0] = x_lo;
|
||||
// acc[1] = x_hi;
|
||||
//
|
||||
// // acc ^= rot32(x, 2)
|
||||
// rot32(x_lo, x_hi, (short)2, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 10)
|
||||
// rot32(x_lo, x_hi, (short)10, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 18)
|
||||
// rot32(x_lo, x_hi, (short)18, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 24)
|
||||
// rot32(x_lo, x_hi, (short)24, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// out[0] = acc[0];
|
||||
// out[1] = acc[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /**
|
||||
//// * L2函数
|
||||
//// */
|
||||
//// public static int L2(int x) {
|
||||
//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
||||
//// }
|
||||
// /**
|
||||
// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
|
||||
// * 输入: x_lo, x_hi
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
|
||||
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // acc = x
|
||||
// acc[0] = x_lo;
|
||||
// acc[1] = x_hi;
|
||||
//
|
||||
// // acc ^= rot32(x, 8)
|
||||
// rot32(x_lo, x_hi, (short)8, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 14)
|
||||
// rot32(x_lo, x_hi, (short)14, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 22)
|
||||
// rot32(x_lo, x_hi, (short)22, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// // acc ^= rot32(x, 30)
|
||||
// rot32(x_lo, x_hi, (short)30, t);
|
||||
// acc[0] ^= t[0];
|
||||
// acc[1] ^= t[1];
|
||||
//
|
||||
// out[0] = acc[0];
|
||||
// out[1] = acc[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 创建31位无符号整数 */
|
||||
//// public static int makeU31(int a, int b, int c, int d) {
|
||||
//// return (((a & 0xFF) << 23) |
|
||||
//// ((b & 0xFF) << 16) |
|
||||
//// ((c & 0xFF) << 8) |
|
||||
//// (d & 0xFF)) & 0x7FFFFFFF;
|
||||
//// }
|
||||
// /** 创建31位无符号整数,结果放到 out[0]=lo, out[1]=hi(15位) */
|
||||
// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
|
||||
// // 四个字节
|
||||
// short b0 = (short)(a & 0xFF); // 最高字节
|
||||
// short b1 = (short)(b & 0xFF);
|
||||
// short b2 = (short)(c & 0xFF);
|
||||
// short b3 = (short)(d & 0xFF); // 最低字节
|
||||
//
|
||||
// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
|
||||
// // lo = 低16位
|
||||
// out[0] = (short)((b2 << 8) | b3);
|
||||
//
|
||||
// // hi = 高15位(丢弃 bit31)
|
||||
// out[1] = (short)((b0 << 7) | b1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//// /** 创建32位无符号整数 */
|
||||
//// public static int makeU32(int a, int b, int c, int d) {
|
||||
//// return ((a & 0xFF) << 24) |
|
||||
//// ((b & 0xFF) << 16) |
|
||||
//// ((c & 0xFF) << 8) |
|
||||
//// (d & 0xFF);
|
||||
//// }
|
||||
// /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */
|
||||
// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) {
|
||||
// // 四个字节
|
||||
// short b0 = (short)(a & 0xFF); // 最高字节
|
||||
// short b1 = (short)(b & 0xFF);
|
||||
// short b2 = (short)(c & 0xFF);
|
||||
// short b3 = (short)(d & 0xFF); // 最低字节
|
||||
//
|
||||
// // lo = 低16位
|
||||
// out[0] = (short)((b2 << 8) | b3);
|
||||
//
|
||||
// // hi = 高16位
|
||||
// out[1] = (short)((b0 << 8) | b1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /** 提取IV */
|
||||
// public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||||
// if (input25Byte == null || output23Byte == null) return;
|
||||
//
|
||||
// // 复制前17字节
|
||||
// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
|
||||
//
|
||||
//
|
||||
// // 处理剩余8字节
|
||||
// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
// for (short i = 0; i < 8; i++) {
|
||||
// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
|
||||
// }
|
||||
//
|
||||
// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
|
||||
// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
|
||||
// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
|
||||
// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
|
||||
// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
|
||||
// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo)
|
||||
// * out[0] = lo, out[1] = hi
|
||||
// */
|
||||
// static void add32(short a_lo, short a_hi,
|
||||
// short b_lo, short b_hi,
|
||||
// short[] out /*len=2*/) {
|
||||
//
|
||||
// // ---- 低16位 ----
|
||||
// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF));
|
||||
// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8);
|
||||
//
|
||||
// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF);
|
||||
// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF);
|
||||
// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0);
|
||||
// short carry1 = (short)(lo_high >>> 8);
|
||||
//
|
||||
// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF));
|
||||
//
|
||||
// // ---- 高16位 ----
|
||||
// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1);
|
||||
// short carry2 = (short)(hi_low >>> 8);
|
||||
//
|
||||
// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF);
|
||||
// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF);
|
||||
// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2);
|
||||
//
|
||||
// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF));
|
||||
//
|
||||
// // ---- 输出 ----
|
||||
// out[0] = lo_res;
|
||||
// out[1] = hi_res;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位加法 + 返回进位(只用 short)
|
||||
// * 输入: (a_hi:a_lo) + (b_hi:b_lo)
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// * 返回: 最终进位(0/1)
|
||||
// */
|
||||
// static short add32_with_carry(short a_lo, short a_hi,
|
||||
// short b_lo, short b_hi,
|
||||
// short[] out /* len=2 */) {
|
||||
// // ---- 低16位:分两段8位相加 ----
|
||||
// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510
|
||||
// short c0 = (short)(s0 >>> 8); // 0/1
|
||||
// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF)
|
||||
// + ((b_lo >>> 8) & (short)0x00FF)
|
||||
// + c0); // 0..511
|
||||
// short c1 = (short)(s1 >>> 8); // 0/1
|
||||
// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF));
|
||||
//
|
||||
// // ---- 高16位:再分两段8位相加,并加上 c1 ----
|
||||
// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1);
|
||||
// short c2 = (short)(s2 >>> 8); // 0/1
|
||||
// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF)
|
||||
// + ((b_hi >>> 8) & (short)0x00FF)
|
||||
// + c2); // 0..511
|
||||
// short c3 = (short)(s3 >>> 8); // 最终进位 0/1
|
||||
// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF));
|
||||
//
|
||||
// out[0] = lo;
|
||||
// out[1] = hi;
|
||||
// return (short)(c3 & 1);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 64位加法: a4 + b4 -> a4
|
||||
// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword)
|
||||
// */
|
||||
// static void add64(short[] a, short[] b) {
|
||||
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
|
||||
//
|
||||
// // 低 32 位
|
||||
// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp);
|
||||
// a[0] = tmp[0];
|
||||
// a[1] = tmp[1];
|
||||
//
|
||||
// // 高 32 位 + carry
|
||||
// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp);
|
||||
// a[2] = tmp[0];
|
||||
// a[3] = tmp[1];
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// // 32位异或
|
||||
// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) {
|
||||
// out[0] = (short)(a_lo ^ b_lo);
|
||||
// out[1] = (short)(a_hi ^ b_hi);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32),
|
||||
// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。
|
||||
// */
|
||||
// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) {
|
||||
// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0;
|
||||
//
|
||||
// if (k >= 16) {
|
||||
// a3 = a2; // 0
|
||||
// a2 = a1; // 原 hi16
|
||||
// a1 = a0; // 原 lo16
|
||||
// a0 = 0;
|
||||
// k = (short)(k - 16);
|
||||
// }
|
||||
//
|
||||
// while (k > 0) {
|
||||
// short c0 = (short)((a0 >>> 15) & 1);
|
||||
// short c1 = (short)((a1 >>> 15) & 1);
|
||||
// short c2 = (short)((a2 >>> 15) & 1);
|
||||
//
|
||||
// a3 = (short)((a3 << 1) | c2);
|
||||
// a2 = (short)((a2 << 1) | c1);
|
||||
// a1 = (short)((a1 << 1) | c0);
|
||||
// a0 = (short)(a0 << 1);
|
||||
// k--;
|
||||
// }
|
||||
//
|
||||
// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。
|
||||
// */
|
||||
// static void and64_7FFFFFFF_to32(short[] A, short[] out) {
|
||||
// out[0] = A[0]; // lo16
|
||||
// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit)
|
||||
// out[2] = 0;
|
||||
// out[3] = 0;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 64位无符号右移 31 位
|
||||
// * 输入: A[0..3] (short[4], A[0]最低16位)
|
||||
// * 输出: out[0..3]
|
||||
// */
|
||||
// static void shr64u_31(short[] A, short[] out) {
|
||||
// // 先拼出 64bit 的逻辑,逐段右移
|
||||
// // A >>> 31 = (A >>> 16) >>> 15
|
||||
//
|
||||
// // 先右移 16,相当于丢掉 A[0],整体右移一半字
|
||||
// out[0] = A[1]; // 原 A[1] -> 新低16位
|
||||
// out[1] = A[2]; // 原 A[2]
|
||||
// out[2] = A[3]; // 原 A[3]
|
||||
// out[3] = 0; // 高位补0
|
||||
//
|
||||
// // 再右移 15 位
|
||||
// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位
|
||||
// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15);
|
||||
// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15);
|
||||
//
|
||||
// out[0] = (short)((c0 & 0x0001) | (out[1] << 1));
|
||||
// out[1] = (short)((c1 & 0x0001) | (out[2] << 1));
|
||||
// out[2] = (short)(c2 & 0x0001);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 32位无符号右移 1 位
|
||||
// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位)
|
||||
// * 输出: out[0]=lo, out[1]=hi
|
||||
// */
|
||||
// static void shr32u1(short lo, short hi, short[] out) {
|
||||
// // >>>1:先处理低16位
|
||||
// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15));
|
||||
// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF);
|
||||
//
|
||||
// out[0] = nwLo;
|
||||
// out[1] = nwHi;
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// /** 打印/*十六进制(调试用,TODO 生产/JC 环境可移除) *//*
|
||||
// public static void printHex(String label, byte[] data, int len) {
|
||||
// System.out.print(label + ": ");
|
||||
// for (int i = 0; i < len; i++) {
|
||||
// System.out.printf("%02x ", data[i] & 0xFF);
|
||||
// }
|
||||
// System.out.println();
|
||||
// }*/
|
||||
//}
|
||||
Reference in New Issue
Block a user