From dec1fecc162026af73d28e0be99629ab0356bb40 Mon Sep 17 00:00:00 2001 From: zcy Date: Tue, 9 Sep 2025 01:30:35 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8method=E9=87=8C=E9=9D=A2=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=AE=9A=E4=B9=89=E7=BC=93=E5=AD=98=E5=8F=98=E9=87=8F?= =?UTF-8?q?=EF=BC=8C=E6=89=80=E6=9C=89=E5=87=BD=E6=95=B0=E5=85=A8=E5=A1=9E?= =?UTF-8?q?=E5=88=B0=E4=B8=80=E8=B5=B7=EF=BC=8C=E5=A4=A7=E5=B0=8F=E9=A9=BC?= =?UTF-8?q?=E5=B3=B0=E4=B8=8B=E5=88=92=E7=BA=BF=E5=85=A8=E5=A4=A7=E5=86=99?= =?UTF-8?q?=E5=8F=98=E9=87=8F=E5=90=8D=E6=B7=B7=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Project/Src/com/cscn/Method.java | 1386 +++++++++++++++++++- Project/Src/com/cscn/Method_old.java | 681 ++++++++++ Project/Src/com/cscn/Zuc256Core.java | 1188 ++++++++--------- Project/Src/com/cscn/Zuc256EncryptCtx.java | 424 +++--- Project/Src/com/cscn/Zuc256MacCtx.java | 64 +- Project/Src/com/cscn/Zuc256State.java | 47 +- Project/Src/com/cscn/Zuc256Util.java | 978 +++++++------- 7 files changed, 3397 insertions(+), 1371 deletions(-) create mode 100644 Project/Src/com/cscn/Method_old.java diff --git a/Project/Src/com/cscn/Method.java b/Project/Src/com/cscn/Method.java index a2979ec..2d7ca3b 100644 --- a/Project/Src/com/cscn/Method.java +++ b/Project/Src/com/cscn/Method.java @@ -52,35 +52,209 @@ public final class Method { // ====================================== // 运行时缓冲:放RAM,避免写EEPROM - private final Zuc256EncryptCtx ctx; + byte[] ctx_buf; + short ctx_buflen; + byte[] buf1; // Enc(Input) + 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 = new Zuc256EncryptCtx(); // 仅创建一次 + // start todo + 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); + buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); + buf2 = JCSystem.makeTransientByteArray(L, 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(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); + updateZuc256EncryptCtx_ks_lo = JCSystem.makeTransientShortArray(fullBlocks, 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); + } public void processData(APDU apdu) { short L = (short) INPUT.length; - byte[] buf1; // Enc(Input) - byte[] buf2; // Enc(Enc(Input)) -> 应为 Input - buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - buf2 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); byte[] apduBuf = apdu.getBuffer(); // 第一次:Enc(Input) - ctx.init(KEY32, IV25); - Zuc256State tmpState = ctx.state; - ctx.update(INPUT, (short) INPUT.length, buf1); - ctx.finish(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥 + initZuc256EncryptCtx(KEY32, IV25); + updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1); + finishZuc256EncryptCtx(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥 - Zuc256State tmpState2 = ctx.state; boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0); // 第二次:Enc(Enc(Input)) 应还原 Input - ctx.init(KEY32, IV25); - ctx.update(buf1, (short) INPUT.length, buf2); - ctx.finish(buf2); + initZuc256EncryptCtx(KEY32, IV25); + updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2); + finishZuc256EncryptCtx(buf2); boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0); // 返回 2 字节结果:[encMatch, dblOk],1=真, 0=假 @@ -120,22 +294,19 @@ public final class Method { byte secParam = buffer[(short)(off + 2)]; // 安全参数 // STMSI - byte[] stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6); // data - byte[] data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - Util.arrayCopyNonAtomic(buffer, (short)(off + 9), data, (short)0, (short)5); + Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5); // === 生成 fakedata === - byte[] fakedata = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - makeFakeData(stmsi, data, fakedata); + makeFakeData(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(fakedata, (short)0, buffer, (short)(off + 3), (short)5); + Util.arrayCopyNonAtomic(location_res_data, (short)0, buffer, (short)(off + 3), (short)5); return (short)8; // 出参总长度 } @@ -167,8 +338,7 @@ public final class Method { } // === 将原有 key_store 拷贝到 RAM,避免直接覆盖 EEPROM (可选) === - byte[] key_buf = JCSystem.makeTransientByteArray((short)80, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - Util.arrayCopyNonAtomic(key_store, (short)0, key_buf, (short)0, (short)key_store.length); + 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); @@ -202,4 +372,1176 @@ public final class Method { 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<< 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) { +// 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) { + 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)(out.length - 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; + } } diff --git a/Project/Src/com/cscn/Method_old.java b/Project/Src/com/cscn/Method_old.java new file mode 100644 index 0000000..981ae83 --- /dev/null +++ b/Project/Src/com/cscn/Method_old.java @@ -0,0 +1,681 @@ +//package com.cscn; +// +//import javacard.framework.APDU; +//import javacard.framework.ISO7816; +//import javacard.framework.ISOException; +//import javacard.framework.JCSystem; +//import javacard.framework.Util; +// +// +///** +// * 仅做一次“自检调用”: +// * 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ? +// * 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ? +// * Response: 2字节 [encMatch, dblEncRestored],1=真,0=假 +// */ +//public final class Method_old { +// // ======= 已按你提供的数据填充 ======= +// +// // Key: 32字节 +// private static final byte[] KEY32 = { +// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, +// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66, +// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, +// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66 +// }; +// +// // IV +// private static final byte[] IV25 = {//todo 23 -> 25 +// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, +// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66, +// (byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7 +// }; +// +// // Input: 明文(38字节) +// private static final byte[] INPUT = { +// (byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF, +// (byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8, +// (byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B, +// (byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34, +// (byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30 +// }; +// +// // EncResult: 期望密文(38字节) +// private static final byte[] ENC_EXPECTED = { +// (byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5, +// (byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27, +// (byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D, +// (byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9, +// (byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2 +// }; +// +// // ====================================== +// +// // 运行时缓冲:放RAM,避免写EEPROM +// private final Zuc256EncryptCtx ctx; +// +// public Method_old() { +// ctx = new Zuc256EncryptCtx(); // 仅创建一次 +// } +// +// +// public void processData(APDU apdu) { +// short L = (short) INPUT.length; +// byte[] buf1; // Enc(Input) +// byte[] buf2; // Enc(Enc(Input)) -> 应为 Input +// buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// buf2 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// byte[] apduBuf = apdu.getBuffer(); +// +// // 第一次:Enc(Input) +// ctx.initZuc256EncryptCtx(KEY32, IV25); +// Zuc256State tmpState = ctx.state; +// ctx.updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1); +// ctx.finishZuc256EncryptCtx(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥 +// +// Zuc256State tmpState2 = ctx.state; +// boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0); +// +// // 第二次:Enc(Enc(Input)) 应还原 Input +// ctx.initZuc256EncryptCtx(KEY32, IV25); +// ctx.updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2); +// ctx.finishZuc256EncryptCtx(buf2); +// boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0); +// +// // 返回 2 字节结果:[encMatch, dblOk],1=真, 0=假 +// apduBuf[0] = (byte)(encMatch ? 1 : 0); +// apduBuf[1] = (byte)(dblOk ? 1 : 0); +// short outLen = 2; +// +// apdu.setOutgoing(); +// apdu.setOutgoingLength(outLen); +// apdu.sendBytes((short)0, outLen); +// } +// +// /** +// * fake数据生成函数 +// * 输入: stmsi[6], data[5] +// * 输出: fakedata[5] +// */ +// private void makeFakeData(byte[] stmsi, byte[] data, byte[] fakedata) { +// // 示例:逐字节异或 stmsi 前5字节 +// for (short i = 0; i < (short)5; i++) { +// fakedata[i] = (byte)(data[i]); +// } +// } +// +// /** +// * APDU处理函数 +// */ +// public short processDataFake(byte[] buffer, short off, short len, byte[] key_store) { +// // 至少要有 12 个字节:1+1+1+6+5 +// if (len < (short)12) { +// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); +// } +// +// // === 解析入参 === +// byte inType = buffer[(short)(off + 0)]; // 类型 A1 +// byte inLen = buffer[(short)(off + 1)]; // 长度 0x0C +// byte secParam = buffer[(short)(off + 2)]; // 安全参数 +// +// // STMSI +// byte[] stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6); +// +// // data +// byte[] data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// Util.arrayCopyNonAtomic(buffer, (short)(off + 9), data, (short)0, (short)5); +// +// // === 生成 fakedata === +// byte[] fakedata = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// makeFakeData(stmsi, data, fakedata); +// +// // === 出参组装 === +// buffer[(short)(off + 0)] = (byte)0xA1; // 类型 +// buffer[(short)(off + 1)] = (byte)0x06; // 长度 +// buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取 +// Util.arrayCopyNonAtomic(fakedata, (short)0, buffer, (short)(off + 3), (short)5); +// +// return (short)8; // 出参总长度 +// } +// +// +// +// public short updateKey(byte[] buffer, short off, short len, byte[] key_store) { +// final short SLOT_SIZE = 40; // 每个槽固定40字节 +// final short HDR_LEN = 4; // 报文头长度: [0]=keyLenField, [1]=alg, [2]=keyId, [3]=ver +// +// // === 解析头 === +// byte keyLenField = buffer[(short)(off + 0)]; // 包含头部+密钥的总长度 +// byte alg = buffer[(short)(off + 1)]; +// byte keyId = buffer[(short)(off + 2)]; +// byte ver = buffer[(short)(off + 3)]; +// +// // 计算实际密钥长度 +// short realKeyLen = (short)(keyLenField - (byte)3); // 长度字段 = key长度 + 3字节头 +// if (realKeyLen <= 0) { +// ISOException.throwIt(ISO7816.SW_DATA_INVALID); // key长度不合法 +// } +// +// // 检查APDU长度和key长度是否匹配 +// if (len != (short)(HDR_LEN + realKeyLen)) { +// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); +// } +// if (len > SLOT_SIZE) { +// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); +// } +// +// // === 将原有 key_store 拷贝到 RAM,避免直接覆盖 EEPROM (可选) === +// byte[] key_buf = JCSystem.makeTransientByteArray((short)80, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// Util.arrayCopyNonAtomic(key_store, (short)0, key_buf, (short)0, (short)key_store.length); +// +// // === 遍历槽,找到匹配的 (alg, keyId, ver),否则找空槽 === +// short slots = (short)(key_store.length / SLOT_SIZE); +// short target = -1; +// for (short i = 0; i < slots; i++) { +// short base = (short)(i * SLOT_SIZE); +// byte algOld = key_store[(short)(base + 1)]; +// byte keyIdOld = key_store[(short)(base + 2)]; +// byte verOld = key_store[(short)(base + 3)]; +// +// if (algOld == alg && keyId == keyIdOld && ver == verOld) { +// target = i; // 找到已存在的,覆盖它 +// break; +// } +// if (key_store[base] == (byte)0x00 && target == -1) { +// target = i; // 找到第一个空槽 +// } +// } +// +// if (target == -1) { +// ISOException.throwIt(ISO7816.SW_FILE_FULL); // 没有空位 +// } +// +// // === 覆盖写入本次APDU的头+密钥数据 === +// short base = (short)(target * SLOT_SIZE); +// // 先清空槽 +// Util.arrayFillNonAtomic(key_store, base, SLOT_SIZE, (byte)0x00); +// // 再写入APDU传入的头+数据 (len 个字节) +// Util.arrayCopyNonAtomic(buffer, off, key_store, base, len); +// +// return 0; // 无返回数据 +// } +// +// // === zuc256Util +// +//// /** 辅助方法:将字节数组转换为32位整数 */ +//// public static int getU32(byte[] p, int offset) { +//// return ((p[offset] & 0xFF) << 24) | +//// ((p[offset + 1] & 0xFF) << 16) | +//// ((p[offset + 2] & 0xFF) << 8) | +//// (p[offset + 3] & 0xFF); +//// } +// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */ +// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) { +// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位 +// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位 +// } +// +// +//// /** 辅助方法:将32位整数转换为字节数组 */ +//// public static void putU32(byte[] p, int offset, int v) { +//// p[offset] = (byte) (v >> 24); +//// p[offset + 1] = (byte) (v >> 16); +//// p[offset + 2] = (byte) (v >> 8); +//// p[offset + 3] = (byte) v; +//// } +// /** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */ +// public static void putU32(byte[] p, short offset, short vlo, short vhi) { +// // 写高16位 +// p[offset] = (byte) ((vhi >> 8) & 0xFF); +// p[(short)(offset + 1)] = (byte) (vhi & 0xFF); +// +// // 写低16位 +// p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF); +// p[(short)(offset + 3)] = (byte) (vlo & 0xFF); +// } +// +// +// // === 31/32 位运算 === +// +//// /** 31位加法 */ +//// public static int add31(int a, int b) { +//// long sum = (long)a + b; +//// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31)); +//// } +// /** 31位加法: (a+b) mod (2^31 - 1) +// * 输入: a_lo=低16位, a_hi=高15位 +// * b_lo=低16位, b_hi=高15位 +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) { +// // ---- 低16位相加 ---- +// short lo = (short)(a_lo + b_lo); +// short carry = (short)( +// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0 +// ? 1 : 0 +// ); +// // ---- 高15位相加 + 进位 ---- +// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry); +// +// // 提取第31位(hi_raw bit15) +// short topbit = (short)((hi_raw >>> 15) & 1); +// short hi = (short)(hi_raw & 0x7FFF); // 保留15位 +// +// // ---- 若第31位=1,再+1 ---- +// if (topbit == 1) { +// short lo2 = (short)(lo + 1); +// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位 +// lo = lo2; +// hi = (short)((hi + c2) & 0x7FFF); +// } +// +// out[0] = lo; +// out[1] = hi; +// } +// +// +//// /** 31位旋转 */ +//// public static int rot31(int a, int k) { +//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF; +//// } +// /** 31位循环左移: (a <<< k) mod (2^31 -1) +// * 输入: a_lo=低16位, a_hi=高15位 +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) { +// k = (short)(k % 31); // 限制在 0..30 +// if (k == 0) { +// out[0] = a_lo; +// out[1] = (short)(a_hi & 0x7FFF); +// return; +// } +// +// // 拆成 31 位数组 [bit0..bit30] +// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 16; i++) { +// bits[i] = (short)((a_lo >>> i) & 1); +// } +// for (short i = 0; i < 15; i++) { +// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1); +// } +// +// // 旋转 +// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 31; i++) { +// short j = (short)((i + k) % 31); +// resBits[j] = bits[i]; +// } +// +// // 拼回 lo, hi +// short lo = 0; +// for (short i = 0; i < 16; i++) { +// lo = (short)(lo | (resBits[i] << i)); +// } +// short hi = 0; +// for (short i = 0; i < 15; i++) { +// hi = (short)(hi | (resBits[(short)(16 + i)] << i)); +// } +// +// out[0] = lo; +// out[1] = hi; +// } +// +// +//// /** 32位旋转 */ +//// public static int rot32(int a, int k) { +//// return (a << k) | (a >>> (32 - k)); +//// } +// /** 32位循环左移: (a<< 0) { +// // 先做 1 位循环左移 +// // 注意:short 在 >>> 时会先提升为 int,所以下面都再用 &1 取最低位,避免符号扩展影响 +// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1)); +// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1)); +// hi = nw_hi; +// lo = nw_lo; +// k--; +// } +// out[0] = lo; // 低16位 +// out[1] = hi; // 高16位 +// } +// +// +//// /** +//// * L1函数 +//// */ +//// public static int L1(int x) { +//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); +//// } +// /** +// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24) +// * 输入: x_lo, x_hi +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) { +// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // acc = x +// acc[0] = x_lo; +// acc[1] = x_hi; +// +// // acc ^= rot32(x, 2) +// rot32(x_lo, x_hi, (short)2, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 10) +// rot32(x_lo, x_hi, (short)10, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 18) +// rot32(x_lo, x_hi, (short)18, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 24) +// rot32(x_lo, x_hi, (short)24, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// out[0] = acc[0]; +// out[1] = acc[1]; +// } +// +// +//// /** +//// * L2函数 +//// */ +//// public static int L2(int x) { +//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); +//// } +// /** +// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30) +// * 输入: x_lo, x_hi +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) { +// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // acc = x +// acc[0] = x_lo; +// acc[1] = x_hi; +// +// // acc ^= rot32(x, 8) +// rot32(x_lo, x_hi, (short)8, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 14) +// rot32(x_lo, x_hi, (short)14, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 22) +// rot32(x_lo, x_hi, (short)22, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 30) +// rot32(x_lo, x_hi, (short)30, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// out[0] = acc[0]; +// out[1] = acc[1]; +// } +// +// +//// /** 创建31位无符号整数 */ +//// public static int makeU31(int a, int b, int c, int d) { +//// return (((a & 0xFF) << 23) | +//// ((b & 0xFF) << 16) | +//// ((c & 0xFF) << 8) | +//// (d & 0xFF)) & 0x7FFFFFFF; +//// } +// /** 创建31位无符号整数,结果放到 out[0]=lo, out[1]=hi(15位) */ +// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) { +// // 四个字节 +// short b0 = (short)(a & 0xFF); // 最高字节 +// short b1 = (short)(b & 0xFF); +// short b2 = (short)(c & 0xFF); +// short b3 = (short)(d & 0xFF); // 最低字节 +// +// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3 +// // lo = 低16位 +// out[0] = (short)((b2 << 8) | b3); +// +// // hi = 高15位(丢弃 bit31) +// out[1] = (short)((b0 << 7) | b1); +// } +// +// +//// /** 创建32位无符号整数 */ +//// public static int makeU32(int a, int b, int c, int d) { +//// return ((a & 0xFF) << 24) | +//// ((b & 0xFF) << 16) | +//// ((c & 0xFF) << 8) | +//// (d & 0xFF); +//// } +// /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */ +// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) { +// // 四个字节 +// short b0 = (short)(a & 0xFF); // 最高字节 +// short b1 = (short)(b & 0xFF); +// short b2 = (short)(c & 0xFF); +// short b3 = (short)(d & 0xFF); // 最低字节 +// +// // lo = 低16位 +// out[0] = (short)((b2 << 8) | b3); +// +// // hi = 高16位 +// out[1] = (short)((b0 << 8) | b1); +// } +// +// +// +// /** 提取IV */ +// public static void extractIv(byte[] input25Byte, byte[] output23Byte) { +// if (input25Byte == null || output23Byte == null) return; +// +// // 复制前17字节 +// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17); +// +// +// // 处理剩余8字节 +// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 8; i++) { +// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F); +// } +// +// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4)); +// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2)); +// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]); +// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4)); +// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2)); +// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]); +// } +// +// /** +// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo) +// * out[0] = lo, out[1] = hi +// */ +// static void add32(short a_lo, short a_hi, +// short b_lo, short b_hi, +// short[] out /*len=2*/) { +// +// // ---- 低16位 ---- +// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF)); +// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8); +// +// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF); +// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF); +// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0); +// short carry1 = (short)(lo_high >>> 8); +// +// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF)); +// +// // ---- 高16位 ---- +// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1); +// short carry2 = (short)(hi_low >>> 8); +// +// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF); +// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF); +// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2); +// +// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF)); +// +// // ---- 输出 ---- +// out[0] = lo_res; +// out[1] = hi_res; +// } +// +// /** +// * 32位加法 + 返回进位(只用 short) +// * 输入: (a_hi:a_lo) + (b_hi:b_lo) +// * 输出: out[0]=lo, out[1]=hi +// * 返回: 最终进位(0/1) +// */ +// static short add32_with_carry(short a_lo, short a_hi, +// short b_lo, short b_hi, +// short[] out /* len=2 */) { +// // ---- 低16位:分两段8位相加 ---- +// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510 +// short c0 = (short)(s0 >>> 8); // 0/1 +// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF) +// + ((b_lo >>> 8) & (short)0x00FF) +// + c0); // 0..511 +// short c1 = (short)(s1 >>> 8); // 0/1 +// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF)); +// +// // ---- 高16位:再分两段8位相加,并加上 c1 ---- +// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1); +// short c2 = (short)(s2 >>> 8); // 0/1 +// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF) +// + ((b_hi >>> 8) & (short)0x00FF) +// + c2); // 0..511 +// short c3 = (short)(s3 >>> 8); // 最终进位 0/1 +// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF)); +// +// out[0] = lo; +// out[1] = hi; +// return (short)(c3 & 1); +// } +// +// +// +// /** +// * 64位加法: a4 + b4 -> a4 +// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword) +// */ +// static void add64(short[] a, short[] b) { +// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // 低 32 位 +// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp); +// a[0] = tmp[0]; +// a[1] = tmp[1]; +// +// // 高 32 位 + carry +// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp); +// a[2] = tmp[0]; +// a[3] = tmp[1]; +// } +// +// +// +// // 32位异或 +// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) { +// out[0] = (short)(a_lo ^ b_lo); +// out[1] = (short)(a_hi ^ b_hi); +// } +// +// /** +// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32), +// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。 +// */ +// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) { +// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0; +// +// if (k >= 16) { +// a3 = a2; // 0 +// a2 = a1; // 原 hi16 +// a1 = a0; // 原 lo16 +// a0 = 0; +// k = (short)(k - 16); +// } +// +// while (k > 0) { +// short c0 = (short)((a0 >>> 15) & 1); +// short c1 = (short)((a1 >>> 15) & 1); +// short c2 = (short)((a2 >>> 15) & 1); +// +// a3 = (short)((a3 << 1) | c2); +// a2 = (short)((a2 << 1) | c1); +// a1 = (short)((a1 << 1) | c0); +// a0 = (short)(a0 << 1); +// k--; +// } +// +// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3; +// } +// +// +// /** +// * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。 +// */ +// static void and64_7FFFFFFF_to32(short[] A, short[] out) { +// out[0] = A[0]; // lo16 +// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit) +// out[2] = 0; +// out[3] = 0; +// } +// +// /** +// * 64位无符号右移 31 位 +// * 输入: A[0..3] (short[4], A[0]最低16位) +// * 输出: out[0..3] +// */ +// static void shr64u_31(short[] A, short[] out) { +// // 先拼出 64bit 的逻辑,逐段右移 +// // A >>> 31 = (A >>> 16) >>> 15 +// +// // 先右移 16,相当于丢掉 A[0],整体右移一半字 +// out[0] = A[1]; // 原 A[1] -> 新低16位 +// out[1] = A[2]; // 原 A[2] +// out[2] = A[3]; // 原 A[3] +// out[3] = 0; // 高位补0 +// +// // 再右移 15 位 +// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位 +// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15); +// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15); +// +// out[0] = (short)((c0 & 0x0001) | (out[1] << 1)); +// out[1] = (short)((c1 & 0x0001) | (out[2] << 1)); +// out[2] = (short)(c2 & 0x0001); +// } +// +// /** +// * 32位无符号右移 1 位 +// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位) +// * 输出: out[0]=lo, out[1]=hi +// */ +// static void shr32u1(short lo, short hi, short[] out) { +// // >>>1:先处理低16位 +// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15)); +// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF); +// +// out[0] = nwLo; +// out[1] = nwHi; +// } +// +// +//} diff --git a/Project/Src/com/cscn/Zuc256Core.java b/Project/Src/com/cscn/Zuc256Core.java index c0e1834..bd2b0c1 100644 --- a/Project/Src/com/cscn/Zuc256Core.java +++ b/Project/Src/com/cscn/Zuc256Core.java @@ -1,595 +1,595 @@ -package com.cscn; - - -import javacard.framework.JCSystem; - -import static com.cscn.Zuc256Util.L1; -import static com.cscn.Zuc256Util.L2; -import static com.cscn.Zuc256Util.add31; -import static com.cscn.Zuc256Util.add32; -import static com.cscn.Zuc256Util.add64; -import static com.cscn.Zuc256Util.and64_7FFFFFFF_to32; -import static com.cscn.Zuc256Util.create_64b_from_32b; -import static com.cscn.Zuc256Util.makeU31; -import static com.cscn.Zuc256Util.makeU32; -import static com.cscn.Zuc256Util.rot31; -import static com.cscn.Zuc256Util.shr32u1; -import static com.cscn.Zuc256Util.shr64u_31; -import static com.cscn.Zuc256Util.xor32; - -/** - * ZUC-256 核心:状态初始化、密钥字生成、密钥流生成。 - */ -public class Zuc256Core { - - private Zuc256Core() {} - - /** 初始化状态(Key + IV) */ - public static void initState(Zuc256State state, byte[] key32, byte[] iv) { - zuc256SetMacKey(state, key32, iv, (short)0); - } - - /** 生成单个密钥字 */ - public static void zuc256GenerateKeyword(Zuc256State state, short[] out) { -// int[] LFSR = state.LFSR; -// int R1 = state.R1; -// int R2 = state.R2; -// int X0, X1, X2, X3; -// int W1, W2, U, V; -// int Z; - - short[] LFSR_hi = state.LFSR_hi; - short[] LFSR_lo = state.LFSR_lo; - - // 工作寄存器(32位值的临时 out32 缓冲,全用short[2])[lo, hi] - short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] TMP2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // 载入 R1,R2 - R1[0] = state.R1_lo; - R1[1] = state.R1_hi; - R2[0] = state.R2_lo; - R2[1] = state.R2_hi; - - - // BitReconstruction4 - short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位 - X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi - X0[0] = LFSR_lo[14]; // lo - - // X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15) - X1[1] = LFSR_lo[11]; - X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1)); - - // X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15) - X2[1] = LFSR_lo[7]; - X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1)); - - // X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15) - X3[1] = LFSR_lo[2]; - X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1)); - - - - // ---- 输入:X0,X1,X2,X3,R1,R2 均为 short[2]; 输出:Z,W1,W2,U,V ---- - - // Z = X3 ^ ((X0 ^ R1) + R2) - xor32(X0[0], X0[1], R1[0], R1[1], TMP0); // TMP0 = X0 ^ R1 - add32(TMP0[0], TMP0[1], R2[0], R2[1], TMP1); // TMP1 = TMP0 + R2 - xor32(X3[0], X3[1], TMP1[0], TMP1[1], Z); // Z = X3 ^ TMP1 - - // F_(X1, X2) - // W1 = R1 + X1 - add32(R1[0], R1[1], X1[0], X1[1], W1); - - // W2 = R2 ^ X2 - xor32(R2[0], R2[1], X2[0], X2[1], W2); - - // U = L1((W1 << 16) | (W2 >>> 16)) - // (W1<<16): lo=0, hi=W1_lo - // (W2>>>16): lo=W2_hi, hi=0 - // OR 结果: lo=W2_hi, hi=W1_lo - L1(W2[1], W1[0], U); - - // V = L2((W2 << 16) | (W1 >>> 16)) - // (W2<<16): lo=0, hi=W2_lo - // (W1>>>16): lo=W1_hi, hi=0 - // OR 结果: lo=W1_hi, hi=W2_lo - L2(W1[1], W2[0], V); - - -// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], -// Zuc256Tables.S1[(U >>> 16) & 0xFF], -// Zuc256Tables.S0[(U >>> 8) & 0xFF], -// Zuc256Tables.S1[U & 0xFF]); - makeU32( - (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF - (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF - (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF - (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF - R1); - -// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], -// Zuc256Tables.S1[(V >>> 16) & 0xFF], -// Zuc256Tables.S0[(V >>> 8) & 0xFF], -// Zuc256Tables.S1[V & 0xFF]); - makeU32( - (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF - (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF - (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF - (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF - R2); - - - -// // LFSRWithWorkMode -// long a = LFSR[0]; -// a += (long)LFSR[0] << 8; -// a += (long)LFSR[4] << 20; -// a += (long)LFSR[10] << 21; -// a += (long)LFSR[13] << 17; -// a += (long)LFSR[15] << 15; - // ---- 先准备累加器 A (64位) ---- - short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器,初始全0 - A[0] = 0; A[1] = 0; A[2] = 0; A[3] = 0; - - // 临时缓冲 - short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi) - short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数 - - // a = LFSR[0] - tmp32[0] = state.LFSR_lo[0]; - tmp32[1] = state.LFSR_hi[0]; - create_64b_from_32b(tmp64, tmp32, (short)0); - add64(A, tmp64); - - // a += (LFSR[0] << 8) - create_64b_from_32b(tmp64, tmp32, (short)8); - add64(A, tmp64); - - // a += (LFSR[4] << 20) - tmp32[0] = state.LFSR_lo[4]; - tmp32[1] = state.LFSR_hi[4]; - create_64b_from_32b(tmp64, tmp32, (short)20); - add64(A, tmp64); - - // a += (LFSR[10] << 21) - tmp32[0] = state.LFSR_lo[10]; - tmp32[1] = state.LFSR_hi[10]; - create_64b_from_32b(tmp64, tmp32, (short)21); - add64(A, tmp64); - - // a += (LFSR[13] << 17) - tmp32[0] = state.LFSR_lo[13]; - tmp32[1] = state.LFSR_hi[13]; - create_64b_from_32b(tmp64, tmp32, (short)17); - add64(A, tmp64); - - // a += (LFSR[15] << 15) - tmp32[0] = state.LFSR_lo[15]; - tmp32[1] = state.LFSR_hi[15]; - create_64b_from_32b(tmp64, tmp32, (short)15); - add64(A, tmp64); - -// a = (a & 0x7FFFFFFF) + (a >>> 31); - // ---- 第一次折叠:a = (a & 0x7FFFFFFF) + (a >>> 31) ---- - short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - and64_7FFFFFFF_to32(A, low31); // low31 = A & 0x7FFFFFFF - shr64u_31(A, r31); // r31 = A >>> 31 - - A[0]=0; A[1]=0; A[2]=0; A[3]=0; - add64(A, low31); - add64(A, r31); -// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); - // ---- 第二次折叠,得到 v(32位)---- - short[] low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - and64_7FFFFFFF_to32(A, low31b); - shr64u_31(A, r31b); - - v64[0]=0; v64[1]=0; v64[2]=0; v64[3]=0; - add64(v64, low31b); - add64(v64, r31b); - - // v = 32位,取 v64 的低两段 - short v_lo = v64[0]; - short v_hi = (short)(v64[1] & 0x7FFF); // 只保留31位 - -// System.arraycopy(LFSR, 1, LFSR, 0, 15); - // LFSR_lo 向左移 - for (short i = 0; i < (short)15; i++) { - state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)]; - } - // LFSR_hi 向左移 - for (short i = 0; i < (short)15; i++) { - state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)]; - } - -// LFSR[15] = v; - // ---- 写回 LFSR[15] ---- - state.LFSR_lo[15] = v_lo; - state.LFSR_hi[15] = v_hi; - -// state.R1 = R1; -// state.R2 = R2; - state.R1_lo = R1[0]; - state.R1_hi = R1[1]; - - state.R2_lo = R2[0]; - state.R2_hi = R2[1]; - - -// return Z; - out[0] = Z[0]; - out[1] = Z[1]; - - } - - // 生成指定长度的密钥流 - public static void zuc256GenerateKeystream(Zuc256State state, - short nwords, - short[] keystream_hi, - short[] keystream_lo) { - // 临时存放一个 32 位关键字 - short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - for (short i = 0; i < nwords; i++) { - // 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi - zuc256GenerateKeyword(state, tmp); - // 存入输出数组 - keystream_lo[i] = tmp[0]; - keystream_hi[i] = tmp[1]; - } - } - - - - - // 初始化MAC密钥 - private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) { - short[] D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - -// int IV17 = (IV[17] & 0xFF) >> 2; -// int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4); -// int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6); -// int IV20 = IV[19] & 0x3F; -// int IV21 = (IV[20] & 0xFF) >> 2; -// int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4); -// int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6); -// int IV24 = IV[22] & 0x3F; - // IV 拆分 - short IV17 = (short)((IV[17] & 0xFF) >>> 2); - short IV18 = (short)(((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >>> 4)); - short IV19 = (short)(((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >>> 6)); - short IV20 = (short)(IV[19] & 0x3F); - short IV21 = (short)((IV[20] & 0xFF) >>> 2); - short IV22 = (short)(((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >>> 4)); - short IV23 = (short)(((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >>> 6)); - short IV24 = (short)(IV[22] & 0x3F); - -// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3]; - short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3); - Zuc256Tables.getDRow(row, D, (short)0); - Zuc256Tables.getDRow(row, D, (short)0); - - - short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi) - - // 逐项装载 LFSR -// LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF); - makeU31((short)(K[0] & 0xFF), (short)D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), tmp); - state.LFSR_lo[0] = tmp[0]; state.LFSR_hi[0] = tmp[1]; - -// LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF); - makeU31((short)(K[1] & 0xFF), (short)D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), tmp); - state.LFSR_lo[1] = tmp[0]; state.LFSR_hi[1] = tmp[1]; - -// LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF); - makeU31((short)(K[2] & 0xFF), (short)D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), tmp); - state.LFSR_lo[2] = tmp[0]; state.LFSR_hi[2] = tmp[1]; - -// LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF); - makeU31((short)(K[3] & 0xFF), (short)D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), tmp); - state.LFSR_lo[3] = tmp[0]; state.LFSR_hi[3] = tmp[1]; - -// LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF); - makeU31((short)(K[4] & 0xFF), (short)D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), tmp); - state.LFSR_lo[4] = tmp[0]; state.LFSR_hi[4] = tmp[1]; - -// LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF); - makeU31((short)(IV[0] & 0xFF), (short)(D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), tmp); - state.LFSR_lo[5] = tmp[0]; state.LFSR_hi[5] = tmp[1]; - -// LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF); - makeU31((short)(IV[1] & 0xFF), (short)(D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), tmp); - state.LFSR_lo[6] = tmp[0]; state.LFSR_hi[6] = tmp[1]; - -// LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF); - makeU31((short)(IV[10] & 0xFF), (short)(D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), tmp); - state.LFSR_lo[7] = tmp[0]; state.LFSR_hi[7] = tmp[1]; - -// LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF); - makeU31((short)(K[8] & 0xFF), (short)(D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), tmp); - state.LFSR_lo[8] = tmp[0]; state.LFSR_hi[8] = tmp[1]; - -// LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF); - makeU31((short)(K[9] & 0xFF), (short)(D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), tmp); - state.LFSR_lo[9] = tmp[0]; state.LFSR_hi[9] = tmp[1]; - -// LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF); - makeU31((short)(IV[5] & 0xFF), (short)(D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), tmp); - state.LFSR_lo[10] = tmp[0]; state.LFSR_hi[10] = tmp[1]; - -// LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF); - makeU31((short)(K[11] & 0xFF), (short)(D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), tmp); - state.LFSR_lo[11] = tmp[0]; state.LFSR_hi[11] = tmp[1]; - -// LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF); - makeU31((short)(K[12] & 0xFF), (short)(D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), tmp); - state.LFSR_lo[12] = tmp[0]; state.LFSR_hi[12] = tmp[1]; - -// LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF); - makeU31((short)(K[13] & 0xFF), (short)D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), tmp); - state.LFSR_lo[13] = tmp[0]; state.LFSR_hi[13] = tmp[1]; - -// LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF); - makeU31((short)(K[14] & 0xFF), (short)(D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), tmp); - state.LFSR_lo[14] = tmp[0]; state.LFSR_hi[14] = tmp[1]; - -// LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF); - makeU31((short)(K[15] & 0xFF), (short)(D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), tmp); - state.LFSR_lo[15] = tmp[0]; state.LFSR_hi[15] = tmp[1]; - - - short c15_2 = 0; - for (short i = 0; i < 32; i++) { - // BitReconstruction3 -// X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); - // X0 = ((L15 & 0x7FFF8000)<<1) | (L14 & 0xFFFF) - c15_2 = (short)((state.LFSR_lo[15] & (short)0x8000) >>> 15); - X0[1] = (short)(((state.LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001)); - X0[0] = state.LFSR_lo[14]; - -// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); - // X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15) - X1[1] = state.LFSR_lo[11]; - X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1)); - -// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); - // X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15) - X2[1] = state.LFSR_lo[7]; - X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1)); - - - - // F(X0, X1, X2) - // W = (X0 ^ R1) + R2 - xor32(X0[0], X0[1], R1[0], R1[1], TMP); - add32(TMP[0], TMP[1], R2[0], R2[1], W); - - // W1 = R1 + X1 - add32(R1[0], R1[1], X1[0], X1[1], W1); - - // W2 = R2 ^ X2 - xor32(R2[0], R2[1], X2[0], X2[1], W2); - - // U = L1((W1<<16) | (W2>>>16)) - L1(W2[1], W1[0], U); - - // V = L2((W2<<16) | (W1>>>16)) - L2(W1[1], W2[0], V); - -// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], -// Zuc256Tables.S1[(U >>> 16) & 0xFF], -// Zuc256Tables.S0[(U >>> 8) & 0xFF], -// Zuc256Tables.S1[U & 0xFF]); +//package com.cscn; +// +// +//import javacard.framework.JCSystem; +// +//import static com.cscn.Zuc256Util.L1; +//import static com.cscn.Zuc256Util.L2; +//import static com.cscn.Zuc256Util.add31; +//import static com.cscn.Zuc256Util.add32; +//import static com.cscn.Zuc256Util.add64; +//import static com.cscn.Zuc256Util.and64_7FFFFFFF_to32; +//import static com.cscn.Zuc256Util.create_64b_from_32b; +//import static com.cscn.Zuc256Util.makeU31; +//import static com.cscn.Zuc256Util.makeU32; +//import static com.cscn.Zuc256Util.rot31; +//import static com.cscn.Zuc256Util.shr32u1; +//import static com.cscn.Zuc256Util.shr64u_31; +//import static com.cscn.Zuc256Util.xor32; +// +///** +// * ZUC-256 核心:状态初始化、密钥字生成、密钥流生成。 +// */ +//public class Zuc256Core { +// +// private Zuc256Core() {} +// +// /** 初始化状态(Key + IV) */ +// public static void initState(Zuc256State state, byte[] key32, byte[] iv) { +// zuc256SetMacKey(state, key32, iv, (short)0); +// } +// +// /** 生成单个密钥字 */ +// public static void zuc256GenerateKeyword(Zuc256State state, short[] out) { +//// int[] LFSR = state.LFSR; +//// int R1 = state.R1; +//// int R2 = state.R2; +//// int X0, X1, X2, X3; +//// int W1, W2, U, V; +//// int Z; +// +// short[] LFSR_hi = state.LFSR_hi; +// short[] LFSR_lo = state.LFSR_lo; +// +// // 工作寄存器(32位值的临时 out32 缓冲,全用short[2])[lo, hi] +// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] TMP2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // 载入 R1,R2 +// R1[0] = state.R1_lo; +// R1[1] = state.R1_hi; +// R2[0] = state.R2_lo; +// R2[1] = state.R2_hi; +// +// +// // BitReconstruction4 +// short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位 +// X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi +// X0[0] = LFSR_lo[14]; // lo +// +// // X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15) +// X1[1] = LFSR_lo[11]; +// X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1)); +// +// // X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15) +// X2[1] = LFSR_lo[7]; +// X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1)); +// +// // X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15) +// X3[1] = LFSR_lo[2]; +// X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1)); +// +// +// +// // ---- 输入:X0,X1,X2,X3,R1,R2 均为 short[2]; 输出:Z,W1,W2,U,V ---- +// +// // Z = X3 ^ ((X0 ^ R1) + R2) +// xor32(X0[0], X0[1], R1[0], R1[1], TMP0); // TMP0 = X0 ^ R1 +// add32(TMP0[0], TMP0[1], R2[0], R2[1], TMP1); // TMP1 = TMP0 + R2 +// xor32(X3[0], X3[1], TMP1[0], TMP1[1], Z); // Z = X3 ^ TMP1 +// +// // F_(X1, X2) +// // W1 = R1 + X1 +// add32(R1[0], R1[1], X1[0], X1[1], W1); +// +// // W2 = R2 ^ X2 +// xor32(R2[0], R2[1], X2[0], X2[1], W2); +// +// // U = L1((W1 << 16) | (W2 >>> 16)) +// // (W1<<16): lo=0, hi=W1_lo +// // (W2>>>16): lo=W2_hi, hi=0 +// // OR 结果: lo=W2_hi, hi=W1_lo +// L1(W2[1], W1[0], U); +// +// // V = L2((W2 << 16) | (W1 >>> 16)) +// // (W2<<16): lo=0, hi=W2_lo +// // (W1>>>16): lo=W1_hi, hi=0 +// // OR 结果: lo=W1_hi, hi=W2_lo +// L2(W1[1], W2[0], V); +// +// +//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], +//// Zuc256Tables.S1[(U >>> 16) & 0xFF], +//// Zuc256Tables.S0[(U >>> 8) & 0xFF], +//// Zuc256Tables.S1[U & 0xFF]); +// makeU32( +// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF +// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF +// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF +// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF +// R1); +// +//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], +//// Zuc256Tables.S1[(V >>> 16) & 0xFF], +//// Zuc256Tables.S0[(V >>> 8) & 0xFF], +//// Zuc256Tables.S1[V & 0xFF]); +// makeU32( +// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF +// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF +// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF +// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF +// R2); +// +// +// +//// // LFSRWithWorkMode +//// long a = LFSR[0]; +//// a += (long)LFSR[0] << 8; +//// a += (long)LFSR[4] << 20; +//// a += (long)LFSR[10] << 21; +//// a += (long)LFSR[13] << 17; +//// a += (long)LFSR[15] << 15; +// // ---- 先准备累加器 A (64位) ---- +// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器,初始全0 +// A[0] = 0; A[1] = 0; A[2] = 0; A[3] = 0; +// +// // 临时缓冲 +// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi) +// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数 +// +// // a = LFSR[0] +// tmp32[0] = state.LFSR_lo[0]; +// tmp32[1] = state.LFSR_hi[0]; +// create_64b_from_32b(tmp64, tmp32, (short)0); +// add64(A, tmp64); +// +// // a += (LFSR[0] << 8) +// create_64b_from_32b(tmp64, tmp32, (short)8); +// add64(A, tmp64); +// +// // a += (LFSR[4] << 20) +// tmp32[0] = state.LFSR_lo[4]; +// tmp32[1] = state.LFSR_hi[4]; +// create_64b_from_32b(tmp64, tmp32, (short)20); +// add64(A, tmp64); +// +// // a += (LFSR[10] << 21) +// tmp32[0] = state.LFSR_lo[10]; +// tmp32[1] = state.LFSR_hi[10]; +// create_64b_from_32b(tmp64, tmp32, (short)21); +// add64(A, tmp64); +// +// // a += (LFSR[13] << 17) +// tmp32[0] = state.LFSR_lo[13]; +// tmp32[1] = state.LFSR_hi[13]; +// create_64b_from_32b(tmp64, tmp32, (short)17); +// add64(A, tmp64); +// +// // a += (LFSR[15] << 15) +// tmp32[0] = state.LFSR_lo[15]; +// tmp32[1] = state.LFSR_hi[15]; +// create_64b_from_32b(tmp64, tmp32, (short)15); +// add64(A, tmp64); +// +//// a = (a & 0x7FFFFFFF) + (a >>> 31); +// // ---- 第一次折叠:a = (a & 0x7FFFFFFF) + (a >>> 31) ---- +// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// and64_7FFFFFFF_to32(A, low31); // low31 = A & 0x7FFFFFFF +// shr64u_31(A, r31); // r31 = A >>> 31 +// +// A[0]=0; A[1]=0; A[2]=0; A[3]=0; +// add64(A, low31); +// add64(A, r31); +//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); +// // ---- 第二次折叠,得到 v(32位)---- +// short[] low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// and64_7FFFFFFF_to32(A, low31b); +// shr64u_31(A, r31b); +// +// v64[0]=0; v64[1]=0; v64[2]=0; v64[3]=0; +// add64(v64, low31b); +// add64(v64, r31b); +// +// // v = 32位,取 v64 的低两段 +// short v_lo = v64[0]; +// short v_hi = (short)(v64[1] & 0x7FFF); // 只保留31位 +// +//// System.arraycopy(LFSR, 1, LFSR, 0, 15); +// // LFSR_lo 向左移 +// for (short i = 0; i < (short)15; i++) { +// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)]; +// } +// // LFSR_hi 向左移 +// for (short i = 0; i < (short)15; i++) { +// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)]; +// } +// +//// LFSR[15] = v; +// // ---- 写回 LFSR[15] ---- +// state.LFSR_lo[15] = v_lo; +// state.LFSR_hi[15] = v_hi; +// +//// state.R1 = R1; +//// state.R2 = R2; +// state.R1_lo = R1[0]; +// state.R1_hi = R1[1]; +// +// state.R2_lo = R2[0]; +// state.R2_hi = R2[1]; +// +// +//// return Z; +// out[0] = Z[0]; +// out[1] = Z[1]; +// +// } +// +// // 生成指定长度的密钥流 +// public static void zuc256GenerateKeystream(Zuc256State state, +// short nwords, +// short[] keystream_hi, +// short[] keystream_lo) { +// // 临时存放一个 32 位关键字 +// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < nwords; i++) { +// // 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi +// zuc256GenerateKeyword(state, tmp); +// // 存入输出数组 +// keystream_lo[i] = tmp[0]; +// keystream_hi[i] = tmp[1]; +// } +// } +// +// +// +// +// // 初始化MAC密钥 +// private static void zuc256SetMacKey(Zuc256State state, byte[] K, byte[] IV, short macbits) { +// short[] D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// +//// int IV17 = (IV[17] & 0xFF) >> 2; +//// int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4); +//// int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6); +//// int IV20 = IV[19] & 0x3F; +//// int IV21 = (IV[20] & 0xFF) >> 2; +//// int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4); +//// int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6); +//// int IV24 = IV[22] & 0x3F; +// // IV 拆分 +// short IV17 = (short)((IV[17] & 0xFF) >>> 2); +// short IV18 = (short)(((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >>> 4)); +// short IV19 = (short)(((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >>> 6)); +// short IV20 = (short)(IV[19] & 0x3F); +// short IV21 = (short)((IV[20] & 0xFF) >>> 2); +// short IV22 = (short)(((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >>> 4)); +// short IV23 = (short)(((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >>> 6)); +// short IV24 = (short)(IV[22] & 0x3F); +// +//// D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3]; +// short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3); +// Zuc256Tables.getDRow(row, D, (short)0); +// Zuc256Tables.getDRow(row, D, (short)0); +// +// +// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi) +// +// // 逐项装载 LFSR +//// LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF); +// makeU31((short)(K[0] & 0xFF), (short)D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), tmp); +// state.LFSR_lo[0] = tmp[0]; state.LFSR_hi[0] = tmp[1]; +// +//// LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF); +// makeU31((short)(K[1] & 0xFF), (short)D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), tmp); +// state.LFSR_lo[1] = tmp[0]; state.LFSR_hi[1] = tmp[1]; +// +//// LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF); +// makeU31((short)(K[2] & 0xFF), (short)D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), tmp); +// state.LFSR_lo[2] = tmp[0]; state.LFSR_hi[2] = tmp[1]; +// +//// LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF); +// makeU31((short)(K[3] & 0xFF), (short)D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), tmp); +// state.LFSR_lo[3] = tmp[0]; state.LFSR_hi[3] = tmp[1]; +// +//// LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF); +// makeU31((short)(K[4] & 0xFF), (short)D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), tmp); +// state.LFSR_lo[4] = tmp[0]; state.LFSR_hi[4] = tmp[1]; +// +//// LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF); +// makeU31((short)(IV[0] & 0xFF), (short)(D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), tmp); +// state.LFSR_lo[5] = tmp[0]; state.LFSR_hi[5] = tmp[1]; +// +//// LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF); +// makeU31((short)(IV[1] & 0xFF), (short)(D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), tmp); +// state.LFSR_lo[6] = tmp[0]; state.LFSR_hi[6] = tmp[1]; +// +//// LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF); +// makeU31((short)(IV[10] & 0xFF), (short)(D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), tmp); +// state.LFSR_lo[7] = tmp[0]; state.LFSR_hi[7] = tmp[1]; +// +//// LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF); +// makeU31((short)(K[8] & 0xFF), (short)(D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), tmp); +// state.LFSR_lo[8] = tmp[0]; state.LFSR_hi[8] = tmp[1]; +// +//// LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF); +// makeU31((short)(K[9] & 0xFF), (short)(D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), tmp); +// state.LFSR_lo[9] = tmp[0]; state.LFSR_hi[9] = tmp[1]; +// +//// LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF); +// makeU31((short)(IV[5] & 0xFF), (short)(D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), tmp); +// state.LFSR_lo[10] = tmp[0]; state.LFSR_hi[10] = tmp[1]; +// +//// LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF); +// makeU31((short)(K[11] & 0xFF), (short)(D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), tmp); +// state.LFSR_lo[11] = tmp[0]; state.LFSR_hi[11] = tmp[1]; +// +//// LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF); +// makeU31((short)(K[12] & 0xFF), (short)(D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), tmp); +// state.LFSR_lo[12] = tmp[0]; state.LFSR_hi[12] = tmp[1]; +// +//// LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF); +// makeU31((short)(K[13] & 0xFF), (short)D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), tmp); +// state.LFSR_lo[13] = tmp[0]; state.LFSR_hi[13] = tmp[1]; +// +//// LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF); +// makeU31((short)(K[14] & 0xFF), (short)(D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), tmp); +// state.LFSR_lo[14] = tmp[0]; state.LFSR_hi[14] = tmp[1]; +// +//// LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF); +// makeU31((short)(K[15] & 0xFF), (short)(D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), tmp); +// state.LFSR_lo[15] = tmp[0]; state.LFSR_hi[15] = tmp[1]; +// +// +// short c15_2 = 0; +// for (short i = 0; i < 32; i++) { +// // BitReconstruction3 +//// X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); +// // X0 = ((L15 & 0x7FFF8000)<<1) | (L14 & 0xFFFF) +// c15_2 = (short)((state.LFSR_lo[15] & (short)0x8000) >>> 15); +// X0[1] = (short)(((state.LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001)); +// X0[0] = state.LFSR_lo[14]; +// +//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); +// // X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15) +// X1[1] = state.LFSR_lo[11]; +// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1)); +// +//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); +// // X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15) +// X2[1] = state.LFSR_lo[7]; +// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1)); +// +// +// +// // F(X0, X1, X2) +// // W = (X0 ^ R1) + R2 +// xor32(X0[0], X0[1], R1[0], R1[1], TMP); +// add32(TMP[0], TMP[1], R2[0], R2[1], W); +// +// // W1 = R1 + X1 +// add32(R1[0], R1[1], X1[0], X1[1], W1); +// +// // W2 = R2 ^ X2 +// xor32(R2[0], R2[1], X2[0], X2[1], W2); +// +// // U = L1((W1<<16) | (W2>>>16)) +// L1(W2[1], W1[0], U); +// +// // V = L2((W2<<16) | (W1>>>16)) +// L2(W1[1], W2[0], V); +// +//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], +//// Zuc256Tables.S1[(U >>> 16) & 0xFF], +//// Zuc256Tables.S0[(U >>> 8) & 0xFF], +//// Zuc256Tables.S1[U & 0xFF]); +//// +//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], +//// Zuc256Tables.S1[(V >>> 16) & 0xFF], +//// Zuc256Tables.S0[(V >>> 8) & 0xFF], +//// Zuc256Tables.S1[V & 0xFF]); +// // 更新 R1,R2 +// makeU32( +// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), +// R1); +// +// makeU32( +// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), +// R2); +// +// // LFSRWithInitialisationMode(W >> 1) +//// int v = LFSR[0]; +// V[0] = state.LFSR_lo[0]; +// V[1] = state.LFSR_hi[0]; +// +// // v = add31(v, rot31(state.LFSR[0], 8)) +// rot31(state.LFSR_lo[0], state.LFSR_hi[0], (short)8, T); +// add31(V[0], V[1], T[0], T[1], V); +// +//// v = add31(v, rot31(state.LFSR[4], 20)); +// rot31(state.LFSR_lo[4], state.LFSR_hi[4], (short)20, T); +// add31(V[0], V[1], T[0], T[1], V); +// +//// v = add31(v, rot31(state.LFSR[10], 21)); +// rot31(state.LFSR_lo[10], state.LFSR_hi[10], (short)21, T); +// add31(V[0], V[1], T[0], T[1], V); +// +//// v = add31(v, rot31(state.LFSR[13], 17)); +// rot31(state.LFSR_lo[13], state.LFSR_hi[13], (short)17, T); +// add31(V[0], V[1], T[0], T[1], V); +// +//// v = add31(v, rot31(state.LFSR[15], 15)); +// rot31(state.LFSR_lo[15], state.LFSR_hi[15], (short)15, T); +// add31(V[0], V[1], T[0], T[1], V); +// +//// v = add31(v, W >>> 1); +// shr32u1(W[0], W[1], T2); // T2[0]=lo, T2[1]=hi(无符号>>>1) +// T2[1] = (short)(T2[1] & (short)0xFFFF); // 只保留31位 +// add31(V[0], V[1], T2[0], T2[1], V); +// +// // System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15) +//// 相当于 System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15); +// for (short j = 0; j < (short)15; j++) { +// state.LFSR_lo[j] = state.LFSR_lo[(short)(j + 1)]; +// } +//// 相当于 System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15); +// for (short j = 0; j < (short)15; j++) { +// state.LFSR_hi[j] = state.LFSR_hi[(short)(j + 1)]; +// } +// +//// state.LFSR[15] = v; +// state.LFSR_lo[15] = V[0]; +// state.LFSR_hi[15] = (short)(V[1] & 0x7FFF); +// } +// +// // BitReconstruction2 +//// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); +// X1[1] = state.LFSR_lo[11]; +// X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1)); +// +//// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); +// X2[1] = state.LFSR_lo[7]; +// X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1)); +// +// // F_(X1, X2) +//// W1 = R1 + X1; +// add32(R1[0], R1[1], X1[0], X1[1], W1); // W1 = R1 + X1 +//// W2 = R2 ^ X2; +// xor32(R2[0], R2[1], X2[0], X2[1], W2); // W2 = R2 ^ X2 +// +//// U = L1((W1 << 16) | (W2 >>> 16)); +// // U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo +// L1(W2[1], W1[0], U); +// +//// V = L2((W2 << 16) | (W1 >>> 16)); +// // V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo +// L2(W1[1], W2[0], V); +// +//// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], +//// Zuc256Tables.S1[(U >>> 16) & 0xFF], +//// Zuc256Tables.S0[(U >>> 8) & 0xFF], +//// Zuc256Tables.S1[U & 0xFF]); +// makeU32( +// (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), +// R1); +// +//// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], +//// Zuc256Tables.S1[(V >>> 16) & 0xFF], +//// Zuc256Tables.S0[(V >>> 8) & 0xFF], +//// Zuc256Tables.S1[V & 0xFF]); +// makeU32( +// (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), +// (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), +// R2); +// +// // ---- LFSRWithWorkMode ---- +// short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 64位累加器 +// short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// +// // LFSRWithWorkMode +//// long a = LFSR[0]; +// tmp32[0] = state.LFSR_lo[0]; +// tmp32[1] = state.LFSR_hi[0]; +// create_64b_from_32b(tmp64, tmp32, (short)0); add64(A, tmp64); +// +//// a += (long)LFSR[0] << 8; +// create_64b_from_32b(tmp64, tmp32, (short)8); add64(A, tmp64); +// +//// a += (long)LFSR[4] << 20; +// tmp32[0] = state.LFSR_lo[4]; tmp32[1] = state.LFSR_hi[4]; +// create_64b_from_32b(tmp64, tmp32, (short)20); add64(A, tmp64); +// +//// a += (long)LFSR[10] << 21; +// tmp32[0] = state.LFSR_lo[10]; tmp32[1] = state.LFSR_hi[10]; +// create_64b_from_32b(tmp64, tmp32, (short)21); add64(A, tmp64); +// +//// a += (long)LFSR[13] << 17; +// tmp32[0] = state.LFSR_lo[13]; tmp32[1] = state.LFSR_hi[13]; +// create_64b_from_32b(tmp64, tmp32, (short)17); add64(A, tmp64); +// +//// a += (long)LFSR[15] << 15; +// tmp32[0] = state.LFSR_lo[15]; tmp32[1] = state.LFSR_hi[15]; +// create_64b_from_32b(tmp64, tmp32, (short)15); add64(A, tmp64); +// +//// a = (a & 0x7FFFFFFF) + (a >>> 31); +// short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// and64_7FFFFFFF_to32(A, low31); +// shr64u_31(A, r31); +// +// short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// add64(v64, low31); +// add64(v64, r31); +// +//// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); +// and64_7FFFFFFF_to32(v64, low31); +// shr64u_31(v64, r31); +// short[] vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; +// add64(vv, low31); +// add64(vv, r31); +// +// short v_lo = vv[0]; +// short v_hi = (short)(vv[1] & 0x7FFF); +// +//// LFSR左移 +//// System.arraycopy(LFSR, 1, LFSR, 0, 15); +// // LFSR_lo 向左移 +// for (short i = 0; i < (short)15; i++) { +// state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)]; +// } +// // LFSR_hi 向左移 +// for (short i = 0; i < (short)15; i++) { +// state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)]; +// } +// +//// LFSR[15] = v; +// state.LFSR_lo[15] = v_lo; +// state.LFSR_hi[15] = v_hi; +// +// state.R1_lo = R1[0]; state.R1_hi = R1[1]; +// state.R2_lo = R2[0]; state.R2_hi = R2[1]; +// } +//} // -// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], -// Zuc256Tables.S1[(V >>> 16) & 0xFF], -// Zuc256Tables.S0[(V >>> 8) & 0xFF], -// Zuc256Tables.S1[V & 0xFF]); - // 更新 R1,R2 - makeU32( - (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), - R1); - - makeU32( - (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), - R2); - - // LFSRWithInitialisationMode(W >> 1) -// int v = LFSR[0]; - V[0] = state.LFSR_lo[0]; - V[1] = state.LFSR_hi[0]; - - // v = add31(v, rot31(state.LFSR[0], 8)) - rot31(state.LFSR_lo[0], state.LFSR_hi[0], (short)8, T); - add31(V[0], V[1], T[0], T[1], V); - -// v = add31(v, rot31(state.LFSR[4], 20)); - rot31(state.LFSR_lo[4], state.LFSR_hi[4], (short)20, T); - add31(V[0], V[1], T[0], T[1], V); - -// v = add31(v, rot31(state.LFSR[10], 21)); - rot31(state.LFSR_lo[10], state.LFSR_hi[10], (short)21, T); - add31(V[0], V[1], T[0], T[1], V); - -// v = add31(v, rot31(state.LFSR[13], 17)); - rot31(state.LFSR_lo[13], state.LFSR_hi[13], (short)17, T); - add31(V[0], V[1], T[0], T[1], V); - -// v = add31(v, rot31(state.LFSR[15], 15)); - rot31(state.LFSR_lo[15], state.LFSR_hi[15], (short)15, T); - add31(V[0], V[1], T[0], T[1], V); - -// v = add31(v, W >>> 1); - shr32u1(W[0], W[1], T2); // T2[0]=lo, T2[1]=hi(无符号>>>1) - T2[1] = (short)(T2[1] & (short)0xFFFF); // 只保留31位 - add31(V[0], V[1], T2[0], T2[1], V); - - // System.arraycopy(state.LFSR, 1, state.LFSR, 0, 15) -// 相当于 System.arraycopy(state.LFSR_lo, 1, state.LFSR_lo, 0, 15); - for (short j = 0; j < (short)15; j++) { - state.LFSR_lo[j] = state.LFSR_lo[(short)(j + 1)]; - } -// 相当于 System.arraycopy(state.LFSR_hi, 1, state.LFSR_hi, 0, 15); - for (short j = 0; j < (short)15; j++) { - state.LFSR_hi[j] = state.LFSR_hi[(short)(j + 1)]; - } - -// state.LFSR[15] = v; - state.LFSR_lo[15] = V[0]; - state.LFSR_hi[15] = (short)(V[1] & 0x7FFF); - } - - // BitReconstruction2 -// X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); - X1[1] = state.LFSR_lo[11]; - X1[0] = (short)((((state.LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[9] << 1)); - -// X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); - X2[1] = state.LFSR_lo[7]; - X2[0] = (short)((((state.LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (state.LFSR_hi[5] << 1)); - - // F_(X1, X2) -// W1 = R1 + X1; - add32(R1[0], R1[1], X1[0], X1[1], W1); // W1 = R1 + X1 -// W2 = R2 ^ X2; - xor32(R2[0], R2[1], X2[0], X2[1], W2); // W2 = R2 ^ X2 - -// U = L1((W1 << 16) | (W2 >>> 16)); - // U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo - L1(W2[1], W1[0], U); - -// V = L2((W2 << 16) | (W1 >>> 16)); - // V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo - L2(W1[1], W2[0], V); - -// R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], -// Zuc256Tables.S1[(U >>> 16) & 0xFF], -// Zuc256Tables.S0[(U >>> 8) & 0xFF], -// Zuc256Tables.S1[U & 0xFF]); - makeU32( - (short)(Zuc256Tables.S0[((U[1] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(U[1] & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S0[((U[0] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(U[0] & 0xFF)] & 0xFF), - R1); - -// R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], -// Zuc256Tables.S1[(V >>> 16) & 0xFF], -// Zuc256Tables.S0[(V >>> 8) & 0xFF], -// Zuc256Tables.S1[V & 0xFF]); - makeU32( - (short)(Zuc256Tables.S0[((V[1] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(V[1] & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S0[((V[0] >>> 8) & 0xFF)] & 0xFF), - (short)(Zuc256Tables.S1[(V[0] & 0xFF)] & 0xFF), - R2); - - // ---- LFSRWithWorkMode ---- - short[] A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 64位累加器 - short[] tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - short[] tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - - // LFSRWithWorkMode -// long a = LFSR[0]; - tmp32[0] = state.LFSR_lo[0]; - tmp32[1] = state.LFSR_hi[0]; - create_64b_from_32b(tmp64, tmp32, (short)0); add64(A, tmp64); - -// a += (long)LFSR[0] << 8; - create_64b_from_32b(tmp64, tmp32, (short)8); add64(A, tmp64); - -// a += (long)LFSR[4] << 20; - tmp32[0] = state.LFSR_lo[4]; tmp32[1] = state.LFSR_hi[4]; - create_64b_from_32b(tmp64, tmp32, (short)20); add64(A, tmp64); - -// a += (long)LFSR[10] << 21; - tmp32[0] = state.LFSR_lo[10]; tmp32[1] = state.LFSR_hi[10]; - create_64b_from_32b(tmp64, tmp32, (short)21); add64(A, tmp64); - -// a += (long)LFSR[13] << 17; - tmp32[0] = state.LFSR_lo[13]; tmp32[1] = state.LFSR_hi[13]; - create_64b_from_32b(tmp64, tmp32, (short)17); add64(A, tmp64); - -// a += (long)LFSR[15] << 15; - tmp32[0] = state.LFSR_lo[15]; tmp32[1] = state.LFSR_hi[15]; - create_64b_from_32b(tmp64, tmp32, (short)15); add64(A, tmp64); - -// a = (a & 0x7FFFFFFF) + (a >>> 31); - short[] low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - short[] r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - and64_7FFFFFFF_to32(A, low31); - shr64u_31(A, r31); - - short[] v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - add64(v64, low31); - add64(v64, r31); - -// int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); - and64_7FFFFFFF_to32(v64, low31); - shr64u_31(v64, r31); - short[] vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; - add64(vv, low31); - add64(vv, r31); - - short v_lo = vv[0]; - short v_hi = (short)(vv[1] & 0x7FFF); - -// LFSR左移 -// System.arraycopy(LFSR, 1, LFSR, 0, 15); - // LFSR_lo 向左移 - for (short i = 0; i < (short)15; i++) { - state.LFSR_lo[i] = state.LFSR_lo[(short)(i + 1)]; - } - // LFSR_hi 向左移 - for (short i = 0; i < (short)15; i++) { - state.LFSR_hi[i] = state.LFSR_hi[(short)(i + 1)]; - } - -// LFSR[15] = v; - state.LFSR_lo[15] = v_lo; - state.LFSR_hi[15] = v_hi; - - state.R1_lo = R1[0]; state.R1_hi = R1[1]; - state.R2_lo = R2[0]; state.R2_hi = R2[1]; - } -} - diff --git a/Project/Src/com/cscn/Zuc256EncryptCtx.java b/Project/Src/com/cscn/Zuc256EncryptCtx.java index eef3c0c..7c675ff 100644 --- a/Project/Src/com/cscn/Zuc256EncryptCtx.java +++ b/Project/Src/com/cscn/Zuc256EncryptCtx.java @@ -1,214 +1,214 @@ -package com.cscn; - -import javacard.framework.JCSystem; -import javacard.framework.Util; - -import static com.cscn.Zuc256Core.zuc256GenerateKeystream; -import static com.cscn.Zuc256Core.zuc256GenerateKeyword; -import static com.cscn.Zuc256Util.getU32; -import static com.cscn.Zuc256Util.putU32; -import static com.cscn.Zuc256Util.xor32; - - -/** - * 加密上下文类 - */ -public final class Zuc256EncryptCtx { - Zuc256State state; - byte[] buf; - short buflen; - - public Zuc256EncryptCtx(Zuc256State state, byte[] buf){ - this.state = state; - this.buf = buf; - } - - public Zuc256EncryptCtx(Zuc256State state){ - this.state = state; - this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - } - - public Zuc256EncryptCtx(){ - this.state = new Zuc256State(); //todo how to put in ram? - this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - } - - // 初始化加密上下文 - public void init(byte[] key32, byte[] iv) { -// Arrays.fill(this.buf, (byte) 0); - for (short i = 0; i < (short)this.buf.length; i++) { - this.buf[i] = (byte)0; - } - this.buflen = 0; - Zuc256Core.initState(this.state, key32, iv); - } - - // 分阶段处理加密数据 - public void update(byte[] in, short inlen, byte[] out) { - if (in == null || out == null || inlen == 0) return; - - short inPos = 0; // 输入偏移 - short outPos = 0; // 输出偏移 - - // 处理缓冲区中剩余的非4字节数据 - if (this.buflen > 0) { -// int need = 4 - this.buflen; - short need = (short)(4 - this.buflen); -// int copy = Math.min(inlen, need); - short copy = (short)((inlen < need) ? inlen : need); - - // 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy); - Util.arrayCopyNonAtomic(in, (short)0, this.buf, this.buflen, copy); - - this.buflen += copy; - - // 调整输入指针和长度 -// byte[] newIn = new byte[inlen - copy]; -// if (inlen - copy > 0) { -// System.arraycopy(in, copy, newIn, 0, inlen - copy); -// } -// in = newIn; -// inlen -= copy; - // 推进输入指针与剩余长度 - inPos += copy; - inlen -= copy; - - // 缓冲区已满,处理一个完整的4字节块 - if (this.buflen == 4) { -// int keystream = zuc256GenerateKeyword(this.state); - short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi - -// int plain = getU32(this.buf, 0); - // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi - short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - getU32(this.buf, (short)0, plain); - -// putU32(out, 0, plain ^ keystream); - // plain ^ ks → res - short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - xor32(plain[0], plain[1], ks[0], ks[1], res); - // 写回 out 的前4字节 - putU32(out, (short)0, res[0], res[1]); - - this.buflen = 0; -// Arrays.fill(this.buf, (byte) 0); - for (short i = 0; i < (short)this.buf.length; i++) { - this.buf[i] = (byte)0; - } - - // 调整输出指针 -// byte[] newOut = new byte[out.length - 4]; -// if (out.length - 4 > 0) { -// System.arraycopy(out, 4, newOut, 0, out.length - 4); +//package com.cscn; +// +//import javacard.framework.JCSystem; +//import javacard.framework.Util; +// +//import static com.cscn.Zuc256Core.zuc256GenerateKeystream; +//import static com.cscn.Zuc256Core.zuc256GenerateKeyword; +//import static com.cscn.Zuc256Util.getU32; +//import static com.cscn.Zuc256Util.putU32; +//import static com.cscn.Zuc256Util.xor32; +// +// +///** +// * 加密上下文类 +// */ +//public final class Zuc256EncryptCtx { +// Zuc256State state; +// byte[] buf; +// short buflen; +// +// public Zuc256EncryptCtx(Zuc256State state, byte[] buf){ +// this.state = state; +// this.buf = buf; +// } +// +// public Zuc256EncryptCtx(Zuc256State state){ +// this.state = state; +// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// } +// +// public Zuc256EncryptCtx(){ +// this.state = new Zuc256State(); //todo how to put in ram? +// this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// } +// +// // 初始化加密上下文 +// public void initZuc256EncryptCtx(byte[] key32, byte[] iv) { +//// Arrays.fill(this.buf, (byte) 0); +// for (short i = 0; i < (short)this.buf.length; i++) { +// this.buf[i] = (byte)0; +// } +// this.buflen = 0; +// Zuc256Core.initState(this.state, key32, iv); +// } +// +// // 分阶段处理加密数据 +// public void updateZuc256EncryptCtx(byte[] in, short inlen, byte[] out) { +// if (in == null || out == null || inlen == 0) return; +// +// short inPos = 0; // 输入偏移 +// short outPos = 0; // 输出偏移 +// +// // 处理缓冲区中剩余的非4字节数据 +// if (this.buflen > 0) { +//// int need = 4 - this.buflen; +// short need = (short)(4 - this.buflen); +//// int copy = Math.min(inlen, need); +// short copy = (short)((inlen < need) ? inlen : need); +// +// // 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy); +// Util.arrayCopyNonAtomic(in, (short)0, this.buf, this.buflen, copy); +// +// this.buflen += copy; +// +// // 调整输入指针和长度 +//// byte[] newIn = new byte[inlen - copy]; +//// if (inlen - copy > 0) { +//// System.arraycopy(in, copy, newIn, 0, inlen - copy); +//// } +//// in = newIn; +//// inlen -= copy; +// // 推进输入指针与剩余长度 +// inPos += copy; +// inlen -= copy; +// +// // 缓冲区已满,处理一个完整的4字节块 +// if (this.buflen == 4) { +//// int keystream = zuc256GenerateKeyword(this.state); +// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi +// +//// int plain = getU32(this.buf, 0); +// // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi +// short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// getU32(this.buf, (short)0, plain); +// +//// putU32(out, 0, plain ^ keystream); +// // plain ^ ks → res +// short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// xor32(plain[0], plain[1], ks[0], ks[1], res); +// // 写回 out 的前4字节 +// putU32(out, (short)0, res[0], res[1]); +// +// this.buflen = 0; +//// Arrays.fill(this.buf, (byte) 0); +// for (short i = 0; i < (short)this.buf.length; i++) { +// this.buf[i] = (byte)0; // } -// out = newOut; - // 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。 - outPos += 4; - } - } - - // 处理完整的4字节块 -// int fullBlocks = inlen / 4; - short fullBlocks = (short) (inlen / 4); - if (fullBlocks > 0) { -// int[] keystream = new int[fullBlocks]; - short[] ks_hi = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] ks_lo = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - -// zuc256GenerateKeystream(this.state, fullBlocks, keystream); - zuc256GenerateKeystream(this.state, fullBlocks, ks_hi, ks_lo); - - // 临时:装一个32位字 - short[] word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // 逐块异或加密 - for (short i = 0; i < fullBlocks; i++) { -// int plain = getU32(in, i * 4); - short off = (short) (i << 2); // i*4 - // 读明文 - getU32(in, (short)(inPos+off), word); // word[0]=lo, word[1]=hi - -// putU32(out, i * 4, plain ^ keystream[i]); - // XOR keystream - word[0] = (short)(word[0] ^ ks_lo[i]); - word[1] = (short)(word[1] ^ ks_hi[i]); - // 写密文 - putU32(out, (short) (outPos+off), word[0], word[1]); - } - - // 调整输入指针和长度 -// int processed = fullBlocks * 4; - short processed = (short)(fullBlocks * 4); - -// byte[] newIn = new byte[inlen - processed]; -// if (inlen - processed > 0) { -// System.arraycopy(in, processed, newIn, 0, inlen - processed); +// +// // 调整输出指针 +//// 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; // } -// in = newIn; -// inlen -= processed; - // 推进输入/输出指针与剩余长度 - inPos += processed; - inlen -= processed; - outPos += processed; - } - - // 缓存剩余不足4字节的数据 - if (inlen > 0) { - // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen); - Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen); - - this.buflen = inlen; - } - } - - // 完成加密处理 - public void finish(byte[] out) { - if (out == null) return; - - // 处理缓冲区中剩余的不足4字节数据 - if (this.buflen > 0) { -// int keystream = zuc256GenerateKeyword(this.state); - // 生成一个 32-bit 密钥字:ks[0]=lo16, ks[1]=hi16 - short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - zuc256GenerateKeyword(this.state, ks); - -// byte[] keystreamBytes = new byte[4]; -// putU32(keystreamBytes, 0, keystream); - byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - putU32(keystreamBytes, (short)0, ks[0], ks[1]); - - // 逐字节异或 - short outOffset = (short)(out.length - this.buflen); - for (short i = 0; i < this.buflen; i++) { - out[(short)(i+outOffset)] = (byte) (this.buf[i] ^ keystreamBytes[i]); - } - } - - - - // 清理上下文 -// Arrays.fill(this.buf, (byte) 0); - for(short i=0; i<4; i++) { - this.buf[i] = (byte)0; - } - - this.buflen = 0; - -// Arrays.fill(this.state.LFSR, 0); - // LFSR 全部清零(高低位数组各 16 个元素) - for (short i = 0; i < 16; i++) { - this.state.LFSR_lo[i] = 0; - this.state.LFSR_hi[i] = 0; - } - - -// this.state.R1 = 0; -// this.state.R2 = 0; -// R1、R2 清零 - this.state.R1_lo = 0; - this.state.R1_hi = 0; - this.state.R2_lo = 0; - this.state.R2_hi = 0; - } -} +// } +// +// // 处理完整的4字节块 +//// int fullBlocks = inlen / 4; +// short fullBlocks = (short) (inlen / 4); +// if (fullBlocks > 0) { +//// int[] keystream = new int[fullBlocks]; +// short[] ks_hi = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] ks_lo = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +//// zuc256GenerateKeystream(this.state, fullBlocks, keystream); +// zuc256GenerateKeystream(this.state, fullBlocks, ks_hi, ks_lo); +// +// // 临时:装一个32位字 +// short[] word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // 逐块异或加密 +// for (short i = 0; i < fullBlocks; i++) { +//// int plain = getU32(in, i * 4); +// short off = (short) (i << 2); // i*4 +// // 读明文 +// getU32(in, (short)(inPos+off), word); // word[0]=lo, word[1]=hi +// +//// putU32(out, i * 4, plain ^ keystream[i]); +// // XOR keystream +// word[0] = (short)(word[0] ^ ks_lo[i]); +// word[1] = (short)(word[1] ^ ks_hi[i]); +// // 写密文 +// putU32(out, (short) (outPos+off), word[0], word[1]); +// } +// +// // 调整输入指针和长度 +//// int processed = fullBlocks * 4; +// short processed = (short)(fullBlocks * 4); +// +//// byte[] newIn = new byte[inlen - processed]; +//// if (inlen - processed > 0) { +//// System.arraycopy(in, processed, newIn, 0, inlen - processed); +//// } +//// in = newIn; +//// inlen -= processed; +// // 推进输入/输出指针与剩余长度 +// inPos += processed; +// inlen -= processed; +// outPos += processed; +// } +// +// // 缓存剩余不足4字节的数据 +// if (inlen > 0) { +// // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen); +// Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen); +// +// this.buflen = inlen; +// } +// } +// +// // 完成加密处理 +// public void finishZuc256EncryptCtx(byte[] out) { +// if (out == null) return; +// +// // 处理缓冲区中剩余的不足4字节数据 +// if (this.buflen > 0) { +//// int keystream = zuc256GenerateKeyword(this.state); +// // 生成一个 32-bit 密钥字:ks[0]=lo16, ks[1]=hi16 +// short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// zuc256GenerateKeyword(this.state, ks); +// +//// byte[] keystreamBytes = new byte[4]; +//// putU32(keystreamBytes, 0, keystream); +// byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// putU32(keystreamBytes, (short)0, ks[0], ks[1]); +// +// // 逐字节异或 +// short outOffset = (short)(out.length - this.buflen); +// for (short i = 0; i < this.buflen; i++) { +// out[(short)(i+outOffset)] = (byte) (this.buf[i] ^ keystreamBytes[i]); +// } +// } +// +// +// +// // 清理上下文 +//// Arrays.fill(this.buf, (byte) 0); +// for(short i=0; i<4; i++) { +// this.buf[i] = (byte)0; +// } +// +// this.buflen = 0; +// +//// Arrays.fill(this.state.LFSR, 0); +// // LFSR 全部清零(高低位数组各 16 个元素) +// for (short i = 0; i < 16; i++) { +// this.state.LFSR_lo[i] = 0; +// this.state.LFSR_hi[i] = 0; +// } +// +// +//// this.state.R1 = 0; +//// this.state.R2 = 0; +//// R1、R2 清零 +// this.state.R1_lo = 0; +// this.state.R1_hi = 0; +// this.state.R2_lo = 0; +// this.state.R2_hi = 0; +// } +//} diff --git a/Project/Src/com/cscn/Zuc256MacCtx.java b/Project/Src/com/cscn/Zuc256MacCtx.java index 2511593..fc53e8b 100644 --- a/Project/Src/com/cscn/Zuc256MacCtx.java +++ b/Project/Src/com/cscn/Zuc256MacCtx.java @@ -1,32 +1,32 @@ -package com.cscn; - -/** - * MAC上下文类(JavaCard版,int 拆分为两个 short) - */ -public final class Zuc256MacCtx { - // LFSR: 原本 int[16],拆成 hi/lo 各 16 short - short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - //todo -> ram - short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // R1、R2: 原本 int,拆成 hi/lo - short R1_hi; - short R1_lo; - short R2_hi; - short R2_lo; - - // 缓冲区 - byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short buflen; - - // T: 原本 int[4],拆成 hi/lo - short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] T_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // K0: 原本 int[4],拆成 hi/lo - short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // macbits: 原本 int,改成 short 足够 - short macbits; -} +//package com.cscn; +// +///** +// * MAC上下文类(JavaCard版,int 拆分为两个 short) +// */ +//public final class Zuc256MacCtx { +// // LFSR: 原本 int[16],拆成 hi/lo 各 16 short +// short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// //todo -> ram +// short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // R1、R2: 原本 int,拆成 hi/lo +// short R1_hi; +// short R1_lo; +// short R2_hi; +// short R2_lo; +// +// // 缓冲区 +// byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short buflen; +// +// // T: 原本 int[4],拆成 hi/lo +// short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] T_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // K0: 原本 int[4],拆成 hi/lo +// short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // macbits: 原本 int,改成 short 足够 +// short macbits; +//} diff --git a/Project/Src/com/cscn/Zuc256State.java b/Project/Src/com/cscn/Zuc256State.java index 5ea302b..14640d6 100644 --- a/Project/Src/com/cscn/Zuc256State.java +++ b/Project/Src/com/cscn/Zuc256State.java @@ -1,22 +1,25 @@ -package com.cscn; - -/** - * ZUC状态类(JavaCard版,int 拆为 hi/lo short) - */ -public class Zuc256State { - // LFSR: 原 int[16] -> hi/lo 各 16 - public short[] LFSR_hi; - public short[] LFSR_lo; - - // R1, R2: 原 int -> hi/lo - public short R1_hi; - public short R1_lo; - public short R2_hi; - public short R2_lo; - - public Zuc256State() { - this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - this.LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - } -} +//package com.cscn; +// +///** +// * ZUC状态类(JavaCard版,int 拆为 hi/lo short) +// */ +//public class Zuc256State { +// // LFSR: 原 int[16] -> hi/lo 各 16 +// public short[] LFSR_hi; +// public short[] LFSR_lo; +// +// // R1, R2: 原 int -> hi/lo +// public short R1_hi; +// public short R1_lo; +// public short R2_hi; +// public short R2_lo; +// +// public Zuc256State() { +// this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// this.LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// } +// public Zuc256State(short[] LSFR_HIGH, short[] LSFR_LOW) { +// this.LFSR_hi = LSFR_HIGH; +// this.LFSR_lo = LSFR_LOW; +// } +//} diff --git a/Project/Src/com/cscn/Zuc256Util.java b/Project/Src/com/cscn/Zuc256Util.java index d2ee8db..a000336 100644 --- a/Project/Src/com/cscn/Zuc256Util.java +++ b/Project/Src/com/cscn/Zuc256Util.java @@ -1,497 +1,497 @@ -package com.cscn; - -import javacard.framework.Util; -import javacard.framework.JCSystem; - -/** - * 辅助工具:装载/存储、位运算、线性变换、打印等。 - */ -public final class Zuc256Util { - - private Zuc256Util() {} - -// /** 辅助方法:将字节数组转换为32位整数 */ -// public static int getU32(byte[] p, int offset) { -// return ((p[offset] & 0xFF) << 24) | -// ((p[offset + 1] & 0xFF) << 16) | -// ((p[offset + 2] & 0xFF) << 8) | -// (p[offset + 3] & 0xFF); +//package com.cscn; +// +//import javacard.framework.Util; +//import javacard.framework.JCSystem; +// +///** +// * 辅助工具:装载/存储、位运算、线性变换、打印等。 +// */ +//public final class Zuc256Util { +// +// private Zuc256Util() {} +// +//// /** 辅助方法:将字节数组转换为32位整数 */ +//// public static int getU32(byte[] p, int offset) { +//// return ((p[offset] & 0xFF) << 24) | +//// ((p[offset + 1] & 0xFF) << 16) | +//// ((p[offset + 2] & 0xFF) << 8) | +//// (p[offset + 3] & 0xFF); +//// } +// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */ +// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) { +// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位 +// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位 // } - /** 辅助方法:从字节数组取出 32 位整数,存放到 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位整数转换为字节数组 */ +//// 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); // } - /** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */ - public static void putU32(byte[] p, short offset, short vlo, short vhi) { - // 写高16位 - p[offset] = (byte) ((vhi >> 8) & 0xFF); - p[(short)(offset + 1)] = (byte) (vhi & 0xFF); - - // 写低16位 - p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF); - p[(short)(offset + 3)] = (byte) (vlo & 0xFF); - } - - - // === 31/32 位运算 === - -// /** 31位加法 */ -// public static int add31(int a, int b) { -// long sum = (long)a + b; -// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31)); -// } - /** 31位加法: (a+b) mod (2^31 - 1) - * 输入: a_lo=低16位, a_hi=高15位 - * b_lo=低16位, b_hi=高15位 - * 输出: out[0]=lo, out[1]=hi - */ - public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) { - // ---- 低16位相加 ---- - short lo = (short)(a_lo + b_lo); - short carry = (short)( - ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0 - ? 1 : 0 - ); - // ---- 高15位相加 + 进位 ---- - short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry); - - // 提取第31位(hi_raw bit15) - short topbit = (short)((hi_raw >>> 15) & 1); - short hi = (short)(hi_raw & 0x7FFF); // 保留15位 - - // ---- 若第31位=1,再+1 ---- - if (topbit == 1) { - short lo2 = (short)(lo + 1); - short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位 - lo = lo2; - hi = (short)((hi + c2) & 0x7FFF); - } - - out[0] = lo; - out[1] = hi; - } - - -// /** 31位旋转 */ -// public static int rot31(int a, int k) { -// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF; -// } - /** 31位循环左移: (a <<< k) mod (2^31 -1) - * 输入: a_lo=低16位, a_hi=高15位 - * 输出: out[0]=lo, out[1]=hi - */ - public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) { - k = (short)(k % 31); // 限制在 0..30 - if (k == 0) { - out[0] = a_lo; - out[1] = (short)(a_hi & 0x7FFF); - return; - } - - // 拆成 31 位数组 [bit0..bit30] - short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - for (short i = 0; i < 16; i++) { - bits[i] = (short)((a_lo >>> i) & 1); - } - for (short i = 0; i < 15; i++) { - bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1); - } - - // 旋转 - short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - for (short i = 0; i < 31; i++) { - short j = (short)((i + k) % 31); - resBits[j] = bits[i]; - } - - // 拼回 lo, hi - short lo = 0; - for (short i = 0; i < 16; i++) { - lo = (short)(lo | (resBits[i] << i)); - } - short hi = 0; - for (short i = 0; i < 15; i++) { - hi = (short)(hi | (resBits[(short)(16 + i)] << i)); - } - - out[0] = lo; - out[1] = hi; - } - - -// /** 32位旋转 */ -// public static int rot32(int a, int k) { -// return (a << k) | (a >>> (32 - k)); -// } - /** 32位循环左移: (a<< 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函数 +// +// +// // === 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 int L1(int x) { -// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); +// 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; // } - /** - * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24) - * 输入: x_lo, x_hi - * 输出: out[0]=lo, out[1]=hi - */ - public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) { - short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // acc = x - acc[0] = x_lo; - acc[1] = x_hi; - - // acc ^= rot32(x, 2) - rot32(x_lo, x_hi, (short)2, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 10) - rot32(x_lo, x_hi, (short)10, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 18) - rot32(x_lo, x_hi, (short)18, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 24) - rot32(x_lo, x_hi, (short)24, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - out[0] = acc[0]; - out[1] = acc[1]; - } - - -// /** -// * L2函数 +// +// +//// /** 31位旋转 */ +//// public static int rot31(int a, int k) { +//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF; +//// } +// /** 31位循环左移: (a <<< k) mod (2^31 -1) +// * 输入: a_lo=低16位, a_hi=高15位 +// * 输出: out[0]=lo, out[1]=hi // */ -// public static int L2(int x) { -// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); +// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) { +// k = (short)(k % 31); // 限制在 0..30 +// if (k == 0) { +// out[0] = a_lo; +// out[1] = (short)(a_hi & 0x7FFF); +// return; +// } +// +// // 拆成 31 位数组 [bit0..bit30] +// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 16; i++) { +// bits[i] = (short)((a_lo >>> i) & 1); +// } +// for (short i = 0; i < 15; i++) { +// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1); +// } +// +// // 旋转 +// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 31; i++) { +// short j = (short)((i + k) % 31); +// resBits[j] = bits[i]; +// } +// +// // 拼回 lo, hi +// short lo = 0; +// for (short i = 0; i < 16; i++) { +// lo = (short)(lo | (resBits[i] << i)); +// } +// short hi = 0; +// for (short i = 0; i < 15; i++) { +// hi = (short)(hi | (resBits[(short)(16 + i)] << i)); +// } +// +// out[0] = lo; +// out[1] = hi; // } - /** - * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30) - * 输入: x_lo, x_hi - * 输出: out[0]=lo, out[1]=hi - */ - public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) { - short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // acc = x - acc[0] = x_lo; - acc[1] = x_hi; - - // acc ^= rot32(x, 8) - rot32(x_lo, x_hi, (short)8, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 14) - rot32(x_lo, x_hi, (short)14, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 22) - rot32(x_lo, x_hi, (short)22, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - // acc ^= rot32(x, 30) - rot32(x_lo, x_hi, (short)30, t); - acc[0] ^= t[0]; - acc[1] ^= t[1]; - - out[0] = acc[0]; - out[1] = acc[1]; - } - - -// /** 创建31位无符号整数 */ -// public static int makeU31(int a, int b, int c, int d) { -// return (((a & 0xFF) << 23) | -// ((b & 0xFF) << 16) | -// ((c & 0xFF) << 8) | -// (d & 0xFF)) & 0x7FFFFFFF; +// +// +//// /** 32位旋转 */ +//// public static int rot32(int a, int k) { +//// return (a << k) | (a >>> (32 - k)); +//// } +// /** 32位循环左移: (a<< 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位 // } - /** 创建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); +// +// +//// /** +//// * L1函数 +//// */ +//// public static int L1(int x) { +//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); +//// } +// /** +// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24) +// * 输入: x_lo, x_hi +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) { +// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // acc = x +// acc[0] = x_lo; +// acc[1] = x_hi; +// +// // acc ^= rot32(x, 2) +// rot32(x_lo, x_hi, (short)2, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 10) +// rot32(x_lo, x_hi, (short)10, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 18) +// rot32(x_lo, x_hi, (short)18, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 24) +// rot32(x_lo, x_hi, (short)24, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// out[0] = acc[0]; +// out[1] = acc[1]; // } - /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */ - public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) { - // 四个字节 - short b0 = (short)(a & 0xFF); // 最高字节 - short b1 = (short)(b & 0xFF); - short b2 = (short)(c & 0xFF); - short b3 = (short)(d & 0xFF); // 最低字节 - - // lo = 低16位 - out[0] = (short)((b2 << 8) | b3); - - // hi = 高16位 - out[1] = (short)((b0 << 8) | b1); - } - - - - /** 提取IV */ - public static void extractIv(byte[] input25Byte, byte[] output23Byte) { - if (input25Byte == null || output23Byte == null) return; - - // 复制前17字节 - Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17); - - - // 处理剩余8字节 - byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - for (short i = 0; i < 8; i++) { - src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F); - } - - output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4)); - output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2)); - output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]); - output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4)); - output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2)); - output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]); - } - - /** - * 32位加法: (a_hi:a_lo) + (b_hi:b_lo) - * out[0] = lo, out[1] = hi - */ - static void add32(short a_lo, short a_hi, - short b_lo, short b_hi, - short[] out /*len=2*/) { - - // ---- 低16位 ---- - short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF)); - short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8); - - short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF); - short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF); - short lo_high = (short)(a_lo_hi + b_lo_hi + carry0); - short carry1 = (short)(lo_high >>> 8); - - short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF)); - - // ---- 高16位 ---- - short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1); - short carry2 = (short)(hi_low >>> 8); - - short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF); - short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF); - short hi_high = (short)(a_hi_hi + b_hi_hi + carry2); - - short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF)); - - // ---- 输出 ---- - out[0] = lo_res; - out[1] = hi_res; - } - - /** - * 32位加法 + 返回进位(只用 short) - * 输入: (a_hi:a_lo) + (b_hi:b_lo) - * 输出: out[0]=lo, out[1]=hi - * 返回: 最终进位(0/1) - */ - static short add32_with_carry(short a_lo, short a_hi, - short b_lo, short b_hi, - short[] out /* len=2 */) { - // ---- 低16位:分两段8位相加 ---- - short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510 - short c0 = (short)(s0 >>> 8); // 0/1 - short s1 = (short)(((a_lo >>> 8) & (short)0x00FF) - + ((b_lo >>> 8) & (short)0x00FF) - + c0); // 0..511 - short c1 = (short)(s1 >>> 8); // 0/1 - short lo = (short)((s1 << 8) | (s0 & (short)0x00FF)); - - // ---- 高16位:再分两段8位相加,并加上 c1 ---- - short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1); - short c2 = (short)(s2 >>> 8); // 0/1 - short s3 = (short)(((a_hi >>> 8) & (short)0x00FF) - + ((b_hi >>> 8) & (short)0x00FF) - + c2); // 0..511 - short c3 = (short)(s3 >>> 8); // 最终进位 0/1 - short hi = (short)((s3 << 8) | (s2 & (short)0x00FF)); - - out[0] = lo; - out[1] = hi; - return (short)(c3 & 1); - } - - - - /** - * 64位加法: a4 + b4 -> a4 - * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword) - */ - static void add64(short[] a, short[] b) { - short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); - - // 低 32 位 - short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp); - a[0] = tmp[0]; - a[1] = tmp[1]; - - // 高 32 位 + carry - add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp); - a[2] = tmp[0]; - a[3] = tmp[1]; - } - - - - // 32位异或 - public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) { - out[0] = (short)(a_lo ^ b_lo); - out[1] = (short)(a_hi ^ b_hi); - } - - /** - * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32), - * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。 - */ - static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) { - short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0; - - if (k >= 16) { - a3 = a2; // 0 - a2 = a1; // 原 hi16 - a1 = a0; // 原 lo16 - a0 = 0; - k = (short)(k - 16); - } - - while (k > 0) { - short c0 = (short)((a0 >>> 15) & 1); - short c1 = (short)((a1 >>> 15) & 1); - short c2 = (short)((a2 >>> 15) & 1); - - a3 = (short)((a3 << 1) | c2); - a2 = (short)((a2 << 1) | c1); - a1 = (short)((a1 << 1) | c0); - a0 = (short)(a0 << 1); - k--; - } - - a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3; - } - - - /** - * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。 - */ - static void and64_7FFFFFFF_to32(short[] A, short[] out) { - out[0] = A[0]; // lo16 - out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit) - out[2] = 0; - out[3] = 0; - } - - /** - * 64位无符号右移 31 位 - * 输入: A[0..3] (short[4], A[0]最低16位) - * 输出: out[0..3] - */ - static void shr64u_31(short[] A, short[] out) { - // 先拼出 64bit 的逻辑,逐段右移 - // A >>> 31 = (A >>> 16) >>> 15 - - // 先右移 16,相当于丢掉 A[0],整体右移一半字 - out[0] = A[1]; // 原 A[1] -> 新低16位 - out[1] = A[2]; // 原 A[2] - out[2] = A[3]; // 原 A[3] - out[3] = 0; // 高位补0 - - // 再右移 15 位 - short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位 - short c1 = (short)((out[1] & (short)0xFFFF) >>> 15); - short c2 = (short)((out[2] & (short)0xFFFF) >>> 15); - - out[0] = (short)((c0 & 0x0001) | (out[1] << 1)); - out[1] = (short)((c1 & 0x0001) | (out[2] << 1)); - out[2] = (short)(c2 & 0x0001); - } - - /** - * 32位无符号右移 1 位 - * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位) - * 输出: out[0]=lo, out[1]=hi - */ - static void shr32u1(short lo, short hi, short[] out) { - // >>>1:先处理低16位 - short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15)); - short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF); - - out[0] = nwLo; - out[1] = nwHi; - } - - - - - /** 打印/*十六进制(调试用,TODO 生产/JC 环境可移除) *//* - public static void printHex(String label, byte[] data, int len) { - System.out.print(label + ": "); - for (int i = 0; i < len; i++) { - System.out.printf("%02x ", data[i] & 0xFF); - } - System.out.println(); - }*/ -} +// +// +//// /** +//// * L2函数 +//// */ +//// public static int L2(int x) { +//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); +//// } +// /** +// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30) +// * 输入: x_lo, x_hi +// * 输出: out[0]=lo, out[1]=hi +// */ +// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) { +// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // acc = x +// acc[0] = x_lo; +// acc[1] = x_hi; +// +// // acc ^= rot32(x, 8) +// rot32(x_lo, x_hi, (short)8, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 14) +// rot32(x_lo, x_hi, (short)14, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 22) +// rot32(x_lo, x_hi, (short)22, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// // acc ^= rot32(x, 30) +// rot32(x_lo, x_hi, (short)30, t); +// acc[0] ^= t[0]; +// acc[1] ^= t[1]; +// +// out[0] = acc[0]; +// out[1] = acc[1]; +// } +// +// +//// /** 创建31位无符号整数 */ +//// public static int makeU31(int a, int b, int c, int d) { +//// return (((a & 0xFF) << 23) | +//// ((b & 0xFF) << 16) | +//// ((c & 0xFF) << 8) | +//// (d & 0xFF)) & 0x7FFFFFFF; +//// } +// /** 创建31位无符号整数,结果放到 out[0]=lo, out[1]=hi(15位) */ +// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) { +// // 四个字节 +// short b0 = (short)(a & 0xFF); // 最高字节 +// short b1 = (short)(b & 0xFF); +// short b2 = (short)(c & 0xFF); +// short b3 = (short)(d & 0xFF); // 最低字节 +// +// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3 +// // lo = 低16位 +// out[0] = (short)((b2 << 8) | b3); +// +// // hi = 高15位(丢弃 bit31) +// out[1] = (short)((b0 << 7) | b1); +// } +// +// +//// /** 创建32位无符号整数 */ +//// public static int makeU32(int a, int b, int c, int d) { +//// return ((a & 0xFF) << 24) | +//// ((b & 0xFF) << 16) | +//// ((c & 0xFF) << 8) | +//// (d & 0xFF); +//// } +// /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */ +// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) { +// // 四个字节 +// short b0 = (short)(a & 0xFF); // 最高字节 +// short b1 = (short)(b & 0xFF); +// short b2 = (short)(c & 0xFF); +// short b3 = (short)(d & 0xFF); // 最低字节 +// +// // lo = 低16位 +// out[0] = (short)((b2 << 8) | b3); +// +// // hi = 高16位 +// out[1] = (short)((b0 << 8) | b1); +// } +// +// +// +// /** 提取IV */ +// public static void extractIv(byte[] input25Byte, byte[] output23Byte) { +// if (input25Byte == null || output23Byte == null) return; +// +// // 复制前17字节 +// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17); +// +// +// // 处理剩余8字节 +// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// for (short i = 0; i < 8; i++) { +// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F); +// } +// +// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4)); +// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2)); +// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]); +// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4)); +// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2)); +// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]); +// } +// +// /** +// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo) +// * out[0] = lo, out[1] = hi +// */ +// static void add32(short a_lo, short a_hi, +// short b_lo, short b_hi, +// short[] out /*len=2*/) { +// +// // ---- 低16位 ---- +// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF)); +// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8); +// +// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF); +// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF); +// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0); +// short carry1 = (short)(lo_high >>> 8); +// +// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF)); +// +// // ---- 高16位 ---- +// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1); +// short carry2 = (short)(hi_low >>> 8); +// +// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF); +// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF); +// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2); +// +// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF)); +// +// // ---- 输出 ---- +// out[0] = lo_res; +// out[1] = hi_res; +// } +// +// /** +// * 32位加法 + 返回进位(只用 short) +// * 输入: (a_hi:a_lo) + (b_hi:b_lo) +// * 输出: out[0]=lo, out[1]=hi +// * 返回: 最终进位(0/1) +// */ +// static short add32_with_carry(short a_lo, short a_hi, +// short b_lo, short b_hi, +// short[] out /* len=2 */) { +// // ---- 低16位:分两段8位相加 ---- +// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510 +// short c0 = (short)(s0 >>> 8); // 0/1 +// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF) +// + ((b_lo >>> 8) & (short)0x00FF) +// + c0); // 0..511 +// short c1 = (short)(s1 >>> 8); // 0/1 +// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF)); +// +// // ---- 高16位:再分两段8位相加,并加上 c1 ---- +// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1); +// short c2 = (short)(s2 >>> 8); // 0/1 +// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF) +// + ((b_hi >>> 8) & (short)0x00FF) +// + c2); // 0..511 +// short c3 = (short)(s3 >>> 8); // 最终进位 0/1 +// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF)); +// +// out[0] = lo; +// out[1] = hi; +// return (short)(c3 & 1); +// } +// +// +// +// /** +// * 64位加法: a4 + b4 -> a4 +// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword) +// */ +// static void add64(short[] a, short[] b) { +// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); +// +// // 低 32 位 +// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp); +// a[0] = tmp[0]; +// a[1] = tmp[1]; +// +// // 高 32 位 + carry +// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp); +// a[2] = tmp[0]; +// a[3] = tmp[1]; +// } +// +// +// +// // 32位异或 +// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) { +// out[0] = (short)(a_lo ^ b_lo); +// out[1] = (short)(a_hi ^ b_hi); +// } +// +// /** +// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32), +// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。 +// */ +// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) { +// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0; +// +// if (k >= 16) { +// a3 = a2; // 0 +// a2 = a1; // 原 hi16 +// a1 = a0; // 原 lo16 +// a0 = 0; +// k = (short)(k - 16); +// } +// +// while (k > 0) { +// short c0 = (short)((a0 >>> 15) & 1); +// short c1 = (short)((a1 >>> 15) & 1); +// short c2 = (short)((a2 >>> 15) & 1); +// +// a3 = (short)((a3 << 1) | c2); +// a2 = (short)((a2 << 1) | c1); +// a1 = (short)((a1 << 1) | c0); +// a0 = (short)(a0 << 1); +// k--; +// } +// +// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3; +// } +// +// +// /** +// * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。 +// */ +// static void and64_7FFFFFFF_to32(short[] A, short[] out) { +// out[0] = A[0]; // lo16 +// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit) +// out[2] = 0; +// out[3] = 0; +// } +// +// /** +// * 64位无符号右移 31 位 +// * 输入: A[0..3] (short[4], A[0]最低16位) +// * 输出: out[0..3] +// */ +// static void shr64u_31(short[] A, short[] out) { +// // 先拼出 64bit 的逻辑,逐段右移 +// // A >>> 31 = (A >>> 16) >>> 15 +// +// // 先右移 16,相当于丢掉 A[0],整体右移一半字 +// out[0] = A[1]; // 原 A[1] -> 新低16位 +// out[1] = A[2]; // 原 A[2] +// out[2] = A[3]; // 原 A[3] +// out[3] = 0; // 高位补0 +// +// // 再右移 15 位 +// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位 +// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15); +// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15); +// +// out[0] = (short)((c0 & 0x0001) | (out[1] << 1)); +// out[1] = (short)((c1 & 0x0001) | (out[2] << 1)); +// out[2] = (short)(c2 & 0x0001); +// } +// +// /** +// * 32位无符号右移 1 位 +// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位) +// * 输出: out[0]=lo, out[1]=hi +// */ +// static void shr32u1(short lo, short hi, short[] out) { +// // >>>1:先处理低16位 +// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15)); +// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF); +// +// out[0] = nwLo; +// out[1] = nwHi; +// } +// +// +// +// +// /** 打印/*十六进制(调试用,TODO 生产/JC 环境可移除) *//* +// public static void printHex(String label, byte[] data, int len) { +// System.out.print(label + ": "); +// for (int i = 0; i < len; i++) { +// System.out.printf("%02x ", data[i] & 0xFF); +// } +// System.out.println(); +// }*/ +//}