1576 lines
62 KiB
Java
1576 lines
62 KiB
Java
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[] 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
|
||
};
|
||
|
||
// ======================================
|
||
|
||
// 输入数据缓冲区最大值
|
||
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_src;
|
||
|
||
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() {
|
||
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);
|
||
|
||
update_key_buf = JCSystem.makeTransientByteArray((short)80, 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_src = 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_src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
|
||
}
|
||
|
||
output23Byte[17] = (byte) ((extract_iv_src[0] << 2) | (extract_iv_src[1] >>> 4));
|
||
output23Byte[18] = (byte) (((extract_iv_src[1] & 0x0F) << 4) | (extract_iv_src[2] >>> 2));
|
||
output23Byte[19] = (byte) (((extract_iv_src[2] & 0x03) << 6) | extract_iv_src[3]);
|
||
output23Byte[20] = (byte) ((extract_iv_src[4] << 2) | (extract_iv_src[5] >>> 4));
|
||
output23Byte[21] = (byte) (((extract_iv_src[5] & 0x0F) << 4) | (extract_iv_src[6] >>> 2));
|
||
output23Byte[22] = (byte) (((extract_iv_src[6] & 0x03) << 6) | extract_iv_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)
|
||
*/
|
||
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));
|
||
// ---- 第二次折叠,得到 v(32位)----
|
||
|
||
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) {
|
||
// 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, 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.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;
|
||
}
|
||
}
|