Files
se-algo/Src/com/cscn/Method.java
2025-09-09 10:36:33 +08:00

1587 lines
63 KiB
Java
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 {
// ======= 已按你提供的数据填充 =======
// 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[] IV23 = {
// (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
// };
private static final byte[] IV25 = {
(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)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,
(byte)0x37
};
// 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
};
// ======================================
// 输入数据缓冲区最大值
static final short MAX_DATA_BLOCK_SIZE = 128;
// 运行时缓冲放RAM避免写EEPROM
byte[] ctx_buf;
short ctx_buflen;
//todo test
byte[] buf1; // Enc(Input)
//todo test
byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
// 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;
byte[] stmsi;
byte[] location_data;
byte[] location_res_data;
byte[] update_key_buf;
short[] rot31_bits;
short[] rot31_resBits;
short[] L1_t;
short[] L1_acc;
short[] L2_t;
short[] L2_acc;
byte[] extract_iv_last8;
byte[] extracted_iv_23;
short[] add64_tmp;
short[] zuc256SetMacKey_D;
short[] zuc256SetMacKey_TMP;
short[] zuc256SetMacKey_X0;
short[] zuc256SetMacKey_X1;
short[] zuc256SetMacKey_X2;
short[] zuc256SetMacKey_R1;
short[] zuc256SetMacKey_R2;
short[] zuc256SetMacKey_W;
short[] zuc256SetMacKey_W1;
short[] zuc256SetMacKey_W2;
short[] zuc256SetMacKey_U;
short[] zuc256SetMacKey_V;
short[] zuc256SetMacKey_T;
short[] zuc256SetMacKey_T2;
short[] zuc256SetMacKey_tmp;
short[] zuc256SetMacKey_A;
short[] zuc256SetMacKey_tmp32;
short[] zuc256SetMacKey_tmp64;
short[] zuc256SetMacKey_low31;
short[] zuc256SetMacKey_r31;
short[] zuc256SetMacKey_v64;
short[] zuc256SetMacKey_vv;
short[] updateZuc256EncryptCtx_ks;
short[] updateZuc256EncryptCtx_plain;
short[] updateZuc256EncryptCtx_res;
short[] updateZuc256EncryptCtx_ks_hi;
short[] updateZuc256EncryptCtx_ks_lo;
short[] updateZuc256EncryptCtx_word;
short[] zuc256GenerateKeyword_X0 ;
short[] zuc256GenerateKeyword_X1 ;
short[] zuc256GenerateKeyword_X2 ;
short[] zuc256GenerateKeyword_X3 ;
short[] zuc256GenerateKeyword_R1 ;
short[] zuc256GenerateKeyword_R2 ;
short[] zuc256GenerateKeyword_W1 ;
short[] zuc256GenerateKeyword_W2 ;
short[] zuc256GenerateKeyword_U ;
short[] zuc256GenerateKeyword_V ;
short[] zuc256GenerateKeyword_Z ;
short[] zuc256GenerateKeyword_TMP0;
short[] zuc256GenerateKeyword_TMP1;
short[] zuc256GenerateKeyword_A;
short[] zuc256GenerateKeyword_tmp32;
short[] zuc256GenerateKeyword_tmp64;
short[] zuc256GenerateKeyword_low31;
short[] zuc256GenerateKeyword_r31;
short[] zuc256GenerateKeyword_low31b;
short[] zuc256GenerateKeyword_r31b;
short[] zuc256GenerateKeyword_v64;
short[] zuc256GenerateKeystream_tmp;
short[] finishZuc256EncryptCtx_ks;
byte[] finishZuc256EncryptCtx_keystreamBytes;
public Method() {
// key list tmp buffer, lenth must equal with key_store(flash)!
update_key_buf = JCSystem.makeTransientByteArray((short)120, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// 算法内部使用23Byte IV
extracted_iv_23 = JCSystem.makeTransientByteArray((short)23, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
ctx_buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// todo buf1 if not use, delete please
buf1 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// todo buf2 if not use, delete please
buf2 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
location_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
location_res_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
rot31_bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
rot31_resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
L1_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
L1_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
L2_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
L2_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
extract_iv_last8 = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
add64_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi)
zuc256SetMacKey_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器
zuc256SetMacKey_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256SetMacKey_vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
updateZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
updateZuc256EncryptCtx_plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
updateZuc256EncryptCtx_res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
updateZuc256EncryptCtx_ks_hi = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
updateZuc256EncryptCtx_ks_lo = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// 临时装一个32位字
updateZuc256EncryptCtx_word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// 工作寄存器32位值的临时 out32 缓冲全用short[2][lo, hi]
zuc256GenerateKeyword_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器初始全0
zuc256GenerateKeyword_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi)
zuc256GenerateKeyword_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数
zuc256GenerateKeyword_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
zuc256GenerateKeyword_v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// 临时存放一个 32 位关键字
zuc256GenerateKeystream_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
finishZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
finishZuc256EncryptCtx_keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
}
//todo test
public void testZuc256(APDU apdu) {
byte[] apduBuf = apdu.getBuffer();
// 第一次Enc(Input)
initZuc256EncryptCtx(KEY32, IV25);
updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1);
finishZuc256EncryptCtx(buf1, (short) INPUT.length); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0);
// 第二次Enc(Enc(Input)) 应还原 Input
initZuc256EncryptCtx(KEY32, IV25);
updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2);
finishZuc256EncryptCtx(buf2, (short) INPUT.length);
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);
}
/**
* encryptLocationZuc256
* 输入: stmsi[6], data[5]
* 输出: out[5]
*/
private void encryptLocationZuc256(byte[] stmsi, byte[] data, byte[] out) {
initZuc256EncryptCtx(KEY32, IV25);
updateZuc256EncryptCtx(data, (short) 5, out);
finishZuc256EncryptCtx(out, (short) 5); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
}
/**
* APDU处理函数
*/
public short locationEncryptZuc(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
Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6);
// data
Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5);
// === 生成 fakedata ===
encryptLocationZuc256(stmsi, location_data, location_res_data);
// === 出参组装 ===
buffer[(short)(off + 0)] = (byte)0xA1; // 类型
buffer[(short)(off + 1)] = (byte)0x06; // 长度
buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取
Util.arrayCopyNonAtomic(location_res_data, (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 (可选) ===
Util.arrayCopyNonAtomic(key_store, (short)0, update_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 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]
for (short i = 0; i < 16; i++) {
rot31_bits[i] = (short)((a_lo >>> i) & 1);
}
for (short i = 0; i < 15; i++) {
rot31_bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
}
// 旋转
for (short i = 0; i < 31; i++) {
short j = (short)((i + k) % 31);
rot31_resBits[j] = rot31_bits[i];
}
// 拼回 lo, hi
short lo = 0;
for (short i = 0; i < 16; i++) {
lo = (short)(lo | (rot31_resBits[i] << i));
}
short hi = 0;
for (short i = 0; i < 15; i++) {
hi = (short)(hi | (rot31_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 void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
// acc = x
L1_acc[0] = x_lo;
L1_acc[1] = x_hi;
// acc ^= rot32(x, 2)
rot32(x_lo, x_hi, (short)2, L1_t);
L1_acc[0] ^= L1_t[0];
L1_acc[1] ^= L1_t[1];
// acc ^= rot32(x, 10)
rot32(x_lo, x_hi, (short)10, L1_t);
L1_acc[0] ^= L1_t[0];
L1_acc[1] ^= L1_t[1];
// acc ^= rot32(x, 18)
rot32(x_lo, x_hi, (short)18, L1_t);
L1_acc[0] ^= L1_t[0];
L1_acc[1] ^= L1_t[1];
// acc ^= rot32(x, 24)
rot32(x_lo, x_hi, (short)24, L1_t);
L1_acc[0] ^= L1_t[0];
L1_acc[1] ^= L1_t[1];
out[0] = L1_acc[0];
out[1] = L1_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 void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
// acc = x
L2_acc[0] = x_lo;
L2_acc[1] = x_hi;
// acc ^= rot32(x, 8)
rot32(x_lo, x_hi, (short)8, L2_t);
L2_acc[0] ^= L2_t[0];
L2_acc[1] ^= L2_t[1];
// acc ^= rot32(x, 14)
rot32(x_lo, x_hi, (short)14, L2_t);
L2_acc[0] ^= L2_t[0];
L2_acc[1] ^= L2_t[1];
// acc ^= rot32(x, 22)
rot32(x_lo, x_hi, (short)22, L2_t);
L2_acc[0] ^= L2_t[0];
L2_acc[1] ^= L2_t[1];
// acc ^= rot32(x, 30)
rot32(x_lo, x_hi, (short)30, L2_t);
L2_acc[0] ^= L2_t[0];
L2_acc[1] ^= L2_t[1];
out[0] = L2_acc[0];
out[1] = L2_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 void extractIv(byte[] input25Byte, byte[] output23Byte) {
if (input25Byte == null || output23Byte == null) return;
// 复制前17字节
Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
// 处理剩余8字节
for (short i = 0; i < 8; i++) {
extract_iv_last8[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
}
output23Byte[17] = (byte) ((extract_iv_last8[0] << 2) | (extract_iv_last8[1] >>> 4));
output23Byte[18] = (byte) (((extract_iv_last8[1] & 0x0F) << 4) | (extract_iv_last8[2] >>> 2));
output23Byte[19] = (byte) (((extract_iv_last8[2] & 0x03) << 6) | extract_iv_last8[3]);
output23Byte[20] = (byte) ((extract_iv_last8[4] << 2) | (extract_iv_last8[5] >>> 4));
output23Byte[21] = (byte) (((extract_iv_last8[5] & 0x0F) << 4) | (extract_iv_last8[6] >>> 2));
output23Byte[22] = (byte) (((extract_iv_last8[6] & 0x03) << 6) | extract_iv_last8[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)
*/
void add64(short[] a, short[] b) {
// 低 32 位
short carry = add32_with_carry(a[0], a[1], b[0], b[1], add64_tmp);
a[0] = add64_tmp[0];
a[1] = add64_tmp[1];
// 高 32 位 + carry
add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], add64_tmp);
a[2] = add64_tmp[0];
a[3] = add64_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;
}
//===zuc256core
/** 初始化状态Key + IV */
public void initState(byte[] key32, byte[] iv) {
zuc256SetMacKey(key32, iv, (short)0);
}
/** 生成单个密钥字 */
public void zuc256GenerateKeyword(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;
// 载入 R1,R2
zuc256GenerateKeyword_R1[0] = R1_lo;
zuc256GenerateKeyword_R1[1] = R1_hi;
zuc256GenerateKeyword_R2[0] = R2_lo;
zuc256GenerateKeyword_R2[1] = R2_hi;
// BitReconstruction4
short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位
zuc256GenerateKeyword_X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi
zuc256GenerateKeyword_X0[0] = LFSR_lo[14]; // lo
// X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15)
zuc256GenerateKeyword_X1[1] = LFSR_lo[11];
zuc256GenerateKeyword_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));
// X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15)
zuc256GenerateKeyword_X2[1] = LFSR_lo[7];
zuc256GenerateKeyword_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));
// X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15)
zuc256GenerateKeyword_X3[1] = LFSR_lo[2];
zuc256GenerateKeyword_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(zuc256GenerateKeyword_X0[0], zuc256GenerateKeyword_X0[1], zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_TMP0); // TMP0 = X0 ^ R1
add32(zuc256GenerateKeyword_TMP0[0], zuc256GenerateKeyword_TMP0[1], zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_TMP1); // TMP1 = TMP0 + R2
xor32(zuc256GenerateKeyword_X3[0], zuc256GenerateKeyword_X3[1], zuc256GenerateKeyword_TMP1[0], zuc256GenerateKeyword_TMP1[1], zuc256GenerateKeyword_Z); // Z = X3 ^ TMP1
// F_(X1, X2)
// W1 = R1 + X1
add32(zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_X1[0], zuc256GenerateKeyword_X1[1], zuc256GenerateKeyword_W1);
// W2 = R2 ^ X2
xor32(zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_X2[0], zuc256GenerateKeyword_X2[1], zuc256GenerateKeyword_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(zuc256GenerateKeyword_W2[1], zuc256GenerateKeyword_W1[0], zuc256GenerateKeyword_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(zuc256GenerateKeyword_W1[1], zuc256GenerateKeyword_W2[0], zuc256GenerateKeyword_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[((zuc256GenerateKeyword_U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF
(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF
(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF
(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF
zuc256GenerateKeyword_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[((zuc256GenerateKeyword_V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF
(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF
(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF
(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF
zuc256GenerateKeyword_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位) ----
zuc256GenerateKeyword_A[0] = 0;
zuc256GenerateKeyword_A[1] = 0;
zuc256GenerateKeyword_A[2] = 0;
zuc256GenerateKeyword_A[3] = 0;
// 临时缓冲
// a = LFSR[0]
zuc256GenerateKeyword_tmp32[0] = LFSR_lo[0];
zuc256GenerateKeyword_tmp32[1] = LFSR_hi[0];
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)0);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a += (LFSR[0] << 8)
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)8);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a += (LFSR[4] << 20)
zuc256GenerateKeyword_tmp32[0] = LFSR_lo[4];
zuc256GenerateKeyword_tmp32[1] = LFSR_hi[4];
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)20);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a += (LFSR[10] << 21)
zuc256GenerateKeyword_tmp32[0] = LFSR_lo[10];
zuc256GenerateKeyword_tmp32[1] = LFSR_hi[10];
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)21);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a += (LFSR[13] << 17)
zuc256GenerateKeyword_tmp32[0] = LFSR_lo[13];
zuc256GenerateKeyword_tmp32[1] = LFSR_hi[13];
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)17);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a += (LFSR[15] << 15)
zuc256GenerateKeyword_tmp32[0] = LFSR_lo[15];
zuc256GenerateKeyword_tmp32[1] = LFSR_hi[15];
create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)15);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);
// a = (a & 0x7FFFFFFF) + (a >>> 31);
// ---- 第一次折叠a = (a & 0x7FFFFFFF) + (a >>> 31) ----
and64_7FFFFFFF_to32(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31); // low31 = A & 0x7FFFFFFF
shr64u_31(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31); // r31 = A >>> 31
zuc256GenerateKeyword_A[0]=0; zuc256GenerateKeyword_A[1]=0; zuc256GenerateKeyword_A[2]=0; zuc256GenerateKeyword_A[3]=0;
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31);
add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31);
// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
// ---- 第二次折叠,得到 v32位----
and64_7FFFFFFF_to32(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31b);
shr64u_31(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31b);
zuc256GenerateKeyword_v64[0]=0;
zuc256GenerateKeyword_v64[1]=0;
zuc256GenerateKeyword_v64[2]=0;
zuc256GenerateKeyword_v64[3]=0;
add64(zuc256GenerateKeyword_v64, zuc256GenerateKeyword_low31b);
add64(zuc256GenerateKeyword_v64, zuc256GenerateKeyword_r31b);
// v = 32位取 v64 的低两段
short v_lo = zuc256GenerateKeyword_v64[0];
short v_hi = (short)(zuc256GenerateKeyword_v64[1] & 0x7FFF); // 只保留31位
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
// LFSR_lo 向左移
for (short i = 0; i < (short)15; i++) {
LFSR_lo[i] = LFSR_lo[(short)(i + 1)];
}
// LFSR_hi 向左移
for (short i = 0; i < (short)15; i++) {
LFSR_hi[i] = LFSR_hi[(short)(i + 1)];
}
// LFSR[15] = v;
// ---- 写回 LFSR[15] ----
LFSR_lo[15] = v_lo;
LFSR_hi[15] = v_hi;
// state.R1 = R1;
// state.R2 = R2;
R1_lo = zuc256GenerateKeyword_R1[0];
R1_hi = zuc256GenerateKeyword_R1[1];
R2_lo = zuc256GenerateKeyword_R2[0];
R2_hi = zuc256GenerateKeyword_R2[1];
// return Z;
out[0] = zuc256GenerateKeyword_Z[0];
out[1] = zuc256GenerateKeyword_Z[1];
}
// 生成指定长度的密钥流
public void zuc256GenerateKeystream(short nwords,
short[] keystream_hi,
short[] keystream_lo) {
for (short i = 0; i < nwords; i++) {
// 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi
zuc256GenerateKeyword(zuc256GenerateKeystream_tmp);
// 存入输出数组
keystream_lo[i] = zuc256GenerateKeystream_tmp[0];
keystream_hi[i] = zuc256GenerateKeystream_tmp[1];
}
}
// 初始化MAC密钥
private void zuc256SetMacKey(byte[] K, byte[] IV, short macbits) {
for(short i=0; i<2; i++) {
zuc256SetMacKey_R1[i] = (short) 0;
zuc256SetMacKey_R2[i] = (short) 0;
}
for(short i=0; i<4; i++) {
zuc256SetMacKey_A[i] = (short) 0;
zuc256SetMacKey_vv[i] = (short) 0;
zuc256SetMacKey_v64[i] = (short) 0;
}
// short[] zuc256SetMacKey_D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] zuc256SetMacKey_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, zuc256SetMacKey_D, (short)0);
Zuc256Tables.getDRow(row, zuc256SetMacKey_D, (short)0);
// 逐项装载 LFSR
// LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF);
makeU31((short)(K[0] & 0xFF), (short)zuc256SetMacKey_D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[0] = zuc256SetMacKey_tmp[0]; LFSR_hi[0] = zuc256SetMacKey_tmp[1];
// LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF);
makeU31((short)(K[1] & 0xFF), (short)zuc256SetMacKey_D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[1] = zuc256SetMacKey_tmp[0]; LFSR_hi[1] = zuc256SetMacKey_tmp[1];
// LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF);
makeU31((short)(K[2] & 0xFF), (short)zuc256SetMacKey_D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[2] = zuc256SetMacKey_tmp[0]; LFSR_hi[2] = zuc256SetMacKey_tmp[1];
// LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF);
makeU31((short)(K[3] & 0xFF), (short)zuc256SetMacKey_D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[3] = zuc256SetMacKey_tmp[0]; LFSR_hi[3] = zuc256SetMacKey_tmp[1];
// LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF);
makeU31((short)(K[4] & 0xFF), (short)zuc256SetMacKey_D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[4] = zuc256SetMacKey_tmp[0]; LFSR_hi[4] = zuc256SetMacKey_tmp[1];
// LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF);
makeU31((short)(IV[0] & 0xFF), (short)(zuc256SetMacKey_D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[5] = zuc256SetMacKey_tmp[0]; LFSR_hi[5] = zuc256SetMacKey_tmp[1];
// LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF);
makeU31((short)(IV[1] & 0xFF), (short)(zuc256SetMacKey_D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[6] = zuc256SetMacKey_tmp[0]; LFSR_hi[6] = zuc256SetMacKey_tmp[1];
// LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF);
makeU31((short)(IV[10] & 0xFF), (short)(zuc256SetMacKey_D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[7] = zuc256SetMacKey_tmp[0]; LFSR_hi[7] = zuc256SetMacKey_tmp[1];
// LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF);
makeU31((short)(K[8] & 0xFF), (short)(zuc256SetMacKey_D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[8] = zuc256SetMacKey_tmp[0]; LFSR_hi[8] = zuc256SetMacKey_tmp[1];
// LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF);
makeU31((short)(K[9] & 0xFF), (short)(zuc256SetMacKey_D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[9] = zuc256SetMacKey_tmp[0]; LFSR_hi[9] = zuc256SetMacKey_tmp[1];
// LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF);
makeU31((short)(IV[5] & 0xFF), (short)(zuc256SetMacKey_D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[10] = zuc256SetMacKey_tmp[0]; LFSR_hi[10] = zuc256SetMacKey_tmp[1];
// LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF);
makeU31((short)(K[11] & 0xFF), (short)(zuc256SetMacKey_D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[11] = zuc256SetMacKey_tmp[0]; LFSR_hi[11] = zuc256SetMacKey_tmp[1];
// LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF);
makeU31((short)(K[12] & 0xFF), (short)(zuc256SetMacKey_D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[12] = zuc256SetMacKey_tmp[0]; LFSR_hi[12] = zuc256SetMacKey_tmp[1];
// LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF);
makeU31((short)(K[13] & 0xFF), (short)zuc256SetMacKey_D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[13] = zuc256SetMacKey_tmp[0]; LFSR_hi[13] = zuc256SetMacKey_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)(zuc256SetMacKey_D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[14] = zuc256SetMacKey_tmp[0]; LFSR_hi[14] = zuc256SetMacKey_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)(zuc256SetMacKey_D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), zuc256SetMacKey_tmp);
LFSR_lo[15] = zuc256SetMacKey_tmp[0]; LFSR_hi[15] = zuc256SetMacKey_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)((LFSR_lo[15] & (short)0x8000) >>> 15);
zuc256SetMacKey_X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001));
zuc256SetMacKey_X0[0] = LFSR_lo[14];
// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
// X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15)
zuc256SetMacKey_X1[1] = LFSR_lo[11];
zuc256SetMacKey_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));
// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
// X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15)
zuc256SetMacKey_X2[1] = LFSR_lo[7];
zuc256SetMacKey_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));
// F(X0, X1, X2)
// W = (X0 ^ R1) + R2
xor32(zuc256SetMacKey_X0[0], zuc256SetMacKey_X0[1], zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_TMP);
add32(zuc256SetMacKey_TMP[0], zuc256SetMacKey_TMP[1], zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_W);
// W1 = R1 + X1
add32(zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_X1[0], zuc256SetMacKey_X1[1], zuc256SetMacKey_W1);
// W2 = R2 ^ X2
xor32(zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_X2[0], zuc256SetMacKey_X2[1], zuc256SetMacKey_W2);
// U = L1((W1<<16) | (W2>>>16))
L1(zuc256SetMacKey_W2[1], zuc256SetMacKey_W1[0], zuc256SetMacKey_U);
// V = L2((W2<<16) | (W1>>>16))
L2(zuc256SetMacKey_W1[1], zuc256SetMacKey_W2[0], zuc256SetMacKey_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[((zuc256SetMacKey_U[1] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_U[1] & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S0[((zuc256SetMacKey_U[0] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_U[0] & 0xFF)] & 0xFF),
zuc256SetMacKey_R1);
makeU32(
(short)(Zuc256Tables.S0[((zuc256SetMacKey_V[1] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_V[1] & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S0[((zuc256SetMacKey_V[0] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_V[0] & 0xFF)] & 0xFF),
zuc256SetMacKey_R2);
// LFSRWithInitialisationMode(W >> 1)
// int v = LFSR[0];
zuc256SetMacKey_V[0] = LFSR_lo[0];
zuc256SetMacKey_V[1] = LFSR_hi[0];
// v = add31(v, rot31(LFSR[0], 8))
rot31(LFSR_lo[0], LFSR_hi[0], (short)8, zuc256SetMacKey_T);
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V);
// v = add31(v, rot31(LFSR[4], 20));
rot31(LFSR_lo[4], LFSR_hi[4], (short)20, zuc256SetMacKey_T);
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V);
// v = add31(v, rot31(LFSR[10], 21));
rot31(LFSR_lo[10], LFSR_hi[10], (short)21, zuc256SetMacKey_T);
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V);
// v = add31(v, rot31(LFSR[13], 17));
rot31(LFSR_lo[13], LFSR_hi[13], (short)17, zuc256SetMacKey_T);
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V);
// v = add31(v, rot31(LFSR[15], 15));
rot31(LFSR_lo[15], LFSR_hi[15], (short)15, zuc256SetMacKey_T);
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V);
// v = add31(v, W >>> 1);
shr32u1(zuc256SetMacKey_W[0], zuc256SetMacKey_W[1], zuc256SetMacKey_T2); // T2[0]=lo, T2[1]=hi无符号>>>1
zuc256SetMacKey_T2[1] = (short)(zuc256SetMacKey_T2[1] & (short)0xFFFF); // 只保留31位
add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T2[0], zuc256SetMacKey_T2[1], zuc256SetMacKey_V);
// System.arraycopy(LFSR, 1, LFSR, 0, 15)
// 相当于 System.arraycopy(LFSR_lo, 1, LFSR_lo, 0, 15);
for (short j = 0; j < (short)15; j++) {
LFSR_lo[j] = LFSR_lo[(short)(j + 1)];
}
// 相当于 System.arraycopy(LFSR_hi, 1, LFSR_hi, 0, 15);
for (short j = 0; j < (short)15; j++) {
LFSR_hi[j] = LFSR_hi[(short)(j + 1)];
}
// LFSR[15] = v;
LFSR_lo[15] = zuc256SetMacKey_V[0];
LFSR_hi[15] = (short)(zuc256SetMacKey_V[1] & 0x7FFF);
}
// BitReconstruction2
// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15);
zuc256SetMacKey_X1[1] = LFSR_lo[11];
zuc256SetMacKey_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));
// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15);
zuc256SetMacKey_X2[1] = LFSR_lo[7];
zuc256SetMacKey_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));
// F_(X1, X2)
// W1 = R1 + X1;
add32(zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_X1[0], zuc256SetMacKey_X1[1], zuc256SetMacKey_W1); // W1 = R1 + X1
// W2 = R2 ^ X2;
xor32(zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_X2[0], zuc256SetMacKey_X2[1], zuc256SetMacKey_W2); // W2 = R2 ^ X2
// U = L1((W1 << 16) | (W2 >>> 16));
// U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo
L1(zuc256SetMacKey_W2[1], zuc256SetMacKey_W1[0], zuc256SetMacKey_U);
// V = L2((W2 << 16) | (W1 >>> 16));
// V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo
L2(zuc256SetMacKey_W1[1], zuc256SetMacKey_W2[0], zuc256SetMacKey_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[((zuc256SetMacKey_U[1] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_U[1] & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S0[((zuc256SetMacKey_U[0] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_U[0] & 0xFF)] & 0xFF),
zuc256SetMacKey_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[((zuc256SetMacKey_V[1] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_V[1] & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S0[((zuc256SetMacKey_V[0] >>> 8) & 0xFF)] & 0xFF),
(short)(Zuc256Tables.S1[(zuc256SetMacKey_V[0] & 0xFF)] & 0xFF),
zuc256SetMacKey_R2);
// ---- LFSRWithWorkMode ----
// LFSRWithWorkMode
// long a = LFSR[0];
zuc256SetMacKey_tmp32[0] = LFSR_lo[0];
zuc256SetMacKey_tmp32[1] = LFSR_hi[0];
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)0);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a += (long)LFSR[0] << 8;
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)8);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a += (long)LFSR[4] << 20;
zuc256SetMacKey_tmp32[0] = LFSR_lo[4]; zuc256SetMacKey_tmp32[1] = LFSR_hi[4];
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)20);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a += (long)LFSR[10] << 21;
zuc256SetMacKey_tmp32[0] = LFSR_lo[10]; zuc256SetMacKey_tmp32[1] = LFSR_hi[10];
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)21);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a += (long)LFSR[13] << 17;
zuc256SetMacKey_tmp32[0] = LFSR_lo[13]; zuc256SetMacKey_tmp32[1] = LFSR_hi[13];
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)17);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a += (long)LFSR[15] << 15;
zuc256SetMacKey_tmp32[0] = LFSR_lo[15]; zuc256SetMacKey_tmp32[1] = LFSR_hi[15];
create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)15);
add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64);
// a = (a & 0x7FFFFFFF) + (a >>> 31);
and64_7FFFFFFF_to32(zuc256SetMacKey_A, zuc256SetMacKey_low31);
shr64u_31(zuc256SetMacKey_A, zuc256SetMacKey_r31);
add64(zuc256SetMacKey_v64, zuc256SetMacKey_low31);
add64(zuc256SetMacKey_v64, zuc256SetMacKey_r31);
// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
and64_7FFFFFFF_to32(zuc256SetMacKey_v64, zuc256SetMacKey_low31);
shr64u_31(zuc256SetMacKey_v64, zuc256SetMacKey_r31);
add64(zuc256SetMacKey_vv, zuc256SetMacKey_low31);
add64(zuc256SetMacKey_vv, zuc256SetMacKey_r31);
short v_lo = zuc256SetMacKey_vv[0];
short v_hi = (short)(zuc256SetMacKey_vv[1] & 0x7FFF);
// LFSR左移
// System.arraycopy(LFSR, 1, LFSR, 0, 15);
// LFSR_lo 向左移
for (short i = 0; i < (short)15; i++) {
LFSR_lo[i] = LFSR_lo[(short)(i + 1)];
}
// LFSR_hi 向左移
for (short i = 0; i < (short)15; i++) {
LFSR_hi[i] = LFSR_hi[(short)(i + 1)];
}
// LFSR[15] = v;
LFSR_lo[15] = v_lo;
LFSR_hi[15] = v_hi;
R1_lo = zuc256SetMacKey_R1[0]; R1_hi = zuc256SetMacKey_R1[1];
R2_lo = zuc256SetMacKey_R2[0]; R2_hi = zuc256SetMacKey_R2[1];
}
//===zuc256Encryptctx
// 初始化加密上下文
public void initZuc256EncryptCtx(byte[] key32, byte[] iv_in_25) {
extractIv(iv_in_25, extracted_iv_23);
// Arrays.fill(this.buf, (byte) 0);
for (short i = 0; i < (short)this.ctx_buf.length; i++) {
this.ctx_buf[i] = (byte)0;
}
this.ctx_buflen = 0;
initState(key32, extracted_iv_23);
}
// 分阶段处理加密数据
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.ctx_buflen > 0) {
// int need = 4 - this.buflen;
short need = (short)(4 - this.ctx_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.ctx_buf, this.ctx_buflen, copy);
this.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;
// 推进输入指针与剩余长度
inPos += copy;
inlen -= copy;
// 缓冲区已满处理一个完整的4字节块
if (this.ctx_buflen == 4) {
// int keystream = zuc256GenerateKeyword(this.state);
zuc256GenerateKeyword(updateZuc256EncryptCtx_ks); // ks[0]=lo, ks[1]=hi
// int plain = getU32(this.buf, 0);
// 取出 4 字节明文 → plain[0]=lo, plain[1]=hi
getU32(this.ctx_buf, (short)0, updateZuc256EncryptCtx_plain);
// putU32(out, 0, plain ^ keystream);
// plain ^ ks → res
xor32(updateZuc256EncryptCtx_plain[0], updateZuc256EncryptCtx_plain[1], updateZuc256EncryptCtx_ks[0], updateZuc256EncryptCtx_ks[1], updateZuc256EncryptCtx_res);
// 写回 out 的前4字节
putU32(out, (short)0, updateZuc256EncryptCtx_res[0], updateZuc256EncryptCtx_res[1]);
this.ctx_buflen = 0;
// Arrays.fill(this.buf, (byte) 0);
for (short i = 0; i < (short)this.ctx_buf.length; i++) {
this.ctx_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];
// zuc256GenerateKeystream(this.state, fullBlocks, keystream);
zuc256GenerateKeystream(fullBlocks, updateZuc256EncryptCtx_ks_hi, updateZuc256EncryptCtx_ks_lo);
// 逐块异或加密
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), updateZuc256EncryptCtx_word); // word[0]=lo, word[1]=hi
// putU32(out, i * 4, plain ^ keystream[i]);
// XOR keystream
updateZuc256EncryptCtx_word[0] = (short)(updateZuc256EncryptCtx_word[0] ^ updateZuc256EncryptCtx_ks_lo[i]);
updateZuc256EncryptCtx_word[1] = (short)(updateZuc256EncryptCtx_word[1] ^ updateZuc256EncryptCtx_ks_hi[i]);
// 写密文
putU32(out, (short) (outPos+off), updateZuc256EncryptCtx_word[0], updateZuc256EncryptCtx_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.ctx_buf, (short)0, inlen);
this.ctx_buflen = inlen;
}
}
// 完成加密处理
public void finishZuc256EncryptCtx(byte[] out, short outLen) {
if (out == null) return;
// 处理缓冲区中剩余的不足4字节数据
if (this.ctx_buflen > 0) {
// int keystream = zuc256GenerateKeyword(this.state);
// 生成一个 32-bit 密钥字ks[0]=lo16, ks[1]=hi16
zuc256GenerateKeyword(finishZuc256EncryptCtx_ks);
// byte[] keystreamBytes = new byte[4];
// putU32(keystreamBytes, 0, keystream);
putU32(finishZuc256EncryptCtx_keystreamBytes, (short)0, finishZuc256EncryptCtx_ks[0], finishZuc256EncryptCtx_ks[1]);
// 逐字节异或
short outOffset = (short)(outLen - this.ctx_buflen);
for (short i = 0; i < this.ctx_buflen; i++) {
out[(short)(i+outOffset)] = (byte) (this.ctx_buf[i] ^ finishZuc256EncryptCtx_keystreamBytes[i]);
}
}
// 清理上下文
// Arrays.fill(this.buf, (byte) 0);
for(short i=0; i<4; i++) {
this.ctx_buf[i] = (byte)0;
}
this.ctx_buflen = 0;
// Arrays.fill(this.state.LFSR, 0);
// LFSR 全部清零(高低位数组各 16 个元素)
for (short i = 0; i < 16; i++) {
LFSR_lo[i] = 0;
LFSR_hi[i] = 0;
}
// this.state.R1 = 0;
// this.state.R2 = 0;
// R1、R2 清零
R1_lo = 0;
R1_hi = 0;
R2_lo = 0;
R2_hi = 0;
}
}