package com.cscn; import javacard.framework.APDU; import javacard.framework.ISO7816; import javacard.framework.ISOException; import javacard.framework.JCSystem; import javacard.framework.Util; /** * 仅做一次“自检调用”: * 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ? * 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ? * Response: 2字节 [encMatch, dblEncRestored],1=真,0=假 */ public final class Method { // ======= 已按你提供的数据填充 ======= // Key: 32字节 private static final byte[] KEY32 = { (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66, (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66 }; // IV // private static final byte[] IV23 = { // (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, // (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66, // (byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7 // }; private static final byte[] IV25 = { (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37, (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66, (byte)0x67,(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36, (byte)0x37 }; // Input: 明文(38字节) private static final byte[] INPUT = { (byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF, (byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8, (byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B, (byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34, (byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30 }; // EncResult: 期望密文(38字节) private static final byte[] ENC_EXPECTED = { (byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5, (byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27, (byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D, (byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9, (byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2 }; // ====================================== // 输入数据缓冲区最大值 static final short MAX_DATA_BLOCK_SIZE = 128; // 运行时缓冲:放RAM,避免写EEPROM byte[] ctx_buf; short ctx_buflen; //todo test byte[] buf1; // Enc(Input) //todo test byte[] buf2; // Enc(Enc(Input)) -> 应为 Input // LFSR: 原 int[16] -> hi/lo 各 16 public short[] LFSR_hi; public short[] LFSR_lo; // R1, R2: 原 int -> hi/lo public short R1_hi; public short R1_lo; public short R2_hi; public short R2_lo; byte[] stmsi; byte[] location_data; byte[] location_res_data; byte[] update_key_buf; short[] rot31_bits; short[] rot31_resBits; short[] L1_t; short[] L1_acc; short[] L2_t; short[] L2_acc; byte[] extract_iv_last8; byte[] extracted_iv_23; short[] add64_tmp; short[] zuc256SetMacKey_D; short[] zuc256SetMacKey_TMP; short[] zuc256SetMacKey_X0; short[] zuc256SetMacKey_X1; short[] zuc256SetMacKey_X2; short[] zuc256SetMacKey_R1; short[] zuc256SetMacKey_R2; short[] zuc256SetMacKey_W; short[] zuc256SetMacKey_W1; short[] zuc256SetMacKey_W2; short[] zuc256SetMacKey_U; short[] zuc256SetMacKey_V; short[] zuc256SetMacKey_T; short[] zuc256SetMacKey_T2; short[] zuc256SetMacKey_tmp; short[] zuc256SetMacKey_A; short[] zuc256SetMacKey_tmp32; short[] zuc256SetMacKey_tmp64; short[] zuc256SetMacKey_low31; short[] zuc256SetMacKey_r31; short[] zuc256SetMacKey_v64; short[] zuc256SetMacKey_vv; short[] updateZuc256EncryptCtx_ks; short[] updateZuc256EncryptCtx_plain; short[] updateZuc256EncryptCtx_res; short[] updateZuc256EncryptCtx_ks_hi; short[] updateZuc256EncryptCtx_ks_lo; short[] updateZuc256EncryptCtx_word; short[] zuc256GenerateKeyword_X0 ; short[] zuc256GenerateKeyword_X1 ; short[] zuc256GenerateKeyword_X2 ; short[] zuc256GenerateKeyword_X3 ; short[] zuc256GenerateKeyword_R1 ; short[] zuc256GenerateKeyword_R2 ; short[] zuc256GenerateKeyword_W1 ; short[] zuc256GenerateKeyword_W2 ; short[] zuc256GenerateKeyword_U ; short[] zuc256GenerateKeyword_V ; short[] zuc256GenerateKeyword_Z ; short[] zuc256GenerateKeyword_TMP0; short[] zuc256GenerateKeyword_TMP1; short[] zuc256GenerateKeyword_A; short[] zuc256GenerateKeyword_tmp32; short[] zuc256GenerateKeyword_tmp64; short[] zuc256GenerateKeyword_low31; short[] zuc256GenerateKeyword_r31; short[] zuc256GenerateKeyword_low31b; short[] zuc256GenerateKeyword_r31b; short[] zuc256GenerateKeyword_v64; short[] zuc256GenerateKeystream_tmp; short[] finishZuc256EncryptCtx_ks; byte[] finishZuc256EncryptCtx_keystreamBytes; public Method() { // key list tmp buffer, lenth must equal with key_store(flash)! update_key_buf = JCSystem.makeTransientByteArray((short)120, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 算法内部使用23Byte IV extracted_iv_23 = JCSystem.makeTransientByteArray((short)23, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); ctx_buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // todo buf1 if not use, delete please buf1 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // todo buf2 if not use, delete please buf2 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); location_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); location_res_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); rot31_bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); rot31_resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); L1_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); L1_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); L2_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); L2_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); extract_iv_last8 = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); add64_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存储 makeU31 输出 (lo,hi) zuc256SetMacKey_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器 zuc256SetMacKey_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256SetMacKey_vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); updateZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); updateZuc256EncryptCtx_plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); updateZuc256EncryptCtx_res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); updateZuc256EncryptCtx_ks_hi = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET); updateZuc256EncryptCtx_ks_lo = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时:装一个32位字 updateZuc256EncryptCtx_word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 工作寄存器(32位值的临时 out32 缓冲,全用short[2])[lo, hi] zuc256GenerateKeyword_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_Z = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器,初始全0 zuc256GenerateKeyword_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存一个32位数 (lo,hi) zuc256GenerateKeyword_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);; // 保存移位后的64位数 zuc256GenerateKeyword_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_r31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); zuc256GenerateKeyword_v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 临时存放一个 32 位关键字 zuc256GenerateKeystream_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); finishZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); finishZuc256EncryptCtx_keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); } //todo test public void testZuc256(APDU apdu) { byte[] apduBuf = apdu.getBuffer(); // 第一次:Enc(Input) initZuc256EncryptCtx(KEY32, IV25); updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1); finishZuc256EncryptCtx(buf1, (short) INPUT.length); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥 boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0); // 第二次:Enc(Enc(Input)) 应还原 Input initZuc256EncryptCtx(KEY32, IV25); updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2); finishZuc256EncryptCtx(buf2, (short) INPUT.length); boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0); // 返回 2 字节结果:[encMatch, dblOk],1=真, 0=假 apduBuf[0] = (byte)(encMatch ? 1 : 0); apduBuf[1] = (byte)(dblOk ? 1 : 0); short outLen = 2; apdu.setOutgoing(); apdu.setOutgoingLength(outLen); apdu.sendBytes((short)0, outLen); } /** * encryptLocationZuc256 * 输入: stmsi[6], data[5] * 输出: out[5] */ private void encryptLocationZuc256(byte[] stmsi, byte[] data, byte[] out) { initZuc256EncryptCtx(KEY32, IV25); updateZuc256EncryptCtx(data, (short) 5, out); finishZuc256EncryptCtx(out, (short) 5); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥 } /** * APDU处理函数 */ public short locationEncryptZuc(byte[] buffer, short off, short len, byte[] key_store) { // 至少要有 12 个字节:1+1+1+6+5 if (len < (short)12) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // === 解析入参 === byte inType = buffer[(short)(off + 0)]; // 类型 A1 byte inLen = buffer[(short)(off + 1)]; // 长度 0x0C byte secParam = buffer[(short)(off + 2)]; // 安全参数 // STMSI Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6); // data Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5); // === 生成 fakedata === encryptLocationZuc256(stmsi, location_data, location_res_data); // === 出参组装 === buffer[(short)(off + 0)] = (byte)0xA1; // 类型 buffer[(short)(off + 1)] = (byte)0x06; // 长度 buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取 Util.arrayCopyNonAtomic(location_res_data, (short)0, buffer, (short)(off + 3), (short)5); return (short)8; // 出参总长度 } public short updateKey(byte[] buffer, short off, short len, byte[] key_store) { final short SLOT_SIZE = 40; // 每个槽固定40字节 final short HDR_LEN = 4; // 报文头长度: [0]=keyLenField, [1]=alg, [2]=keyId, [3]=ver // === 解析头 === byte keyLenField = buffer[(short)(off + 0)]; // 包含头部+密钥的总长度 byte alg = buffer[(short)(off + 1)]; byte keyId = buffer[(short)(off + 2)]; byte ver = buffer[(short)(off + 3)]; // 计算实际密钥长度 short realKeyLen = (short)(keyLenField - (byte)3); // 长度字段 = key长度 + 3字节头 if (realKeyLen <= 0) { ISOException.throwIt(ISO7816.SW_DATA_INVALID); // key长度不合法 } // 检查APDU长度和key长度是否匹配 if (len != (short)(HDR_LEN + realKeyLen)) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } if (len > SLOT_SIZE) { ISOException.throwIt(ISO7816.SW_WRONG_LENGTH); } // === 将原有 key_store 拷贝到 RAM,避免直接覆盖 EEPROM (可选) === Util.arrayCopyNonAtomic(key_store, (short)0, update_key_buf, (short)0, (short)key_store.length); // === 遍历槽,找到匹配的 (alg, keyId, ver),否则找空槽 === short slots = (short)(key_store.length / SLOT_SIZE); short target = -1; for (short i = 0; i < slots; i++) { short base = (short)(i * SLOT_SIZE); byte algOld = key_store[(short)(base + 1)]; byte keyIdOld = key_store[(short)(base + 2)]; byte verOld = key_store[(short)(base + 3)]; if (algOld == alg && keyId == keyIdOld && ver == verOld) { target = i; // 找到已存在的,覆盖它 break; } if (key_store[base] == (byte)0x00 && target == -1) { target = i; // 找到第一个空槽 } } if (target == -1) { ISOException.throwIt(ISO7816.SW_FILE_FULL); // 没有空位 } // === 覆盖写入本次APDU的头+密钥数据 === short base = (short)(target * SLOT_SIZE); // 先清空槽 Util.arrayFillNonAtomic(key_store, base, SLOT_SIZE, (byte)0x00); // 再写入APDU传入的头+数据 (len 个字节) Util.arrayCopyNonAtomic(buffer, off, key_store, base, len); return 0; // 无返回数据 } // === zuc256Util // /** 辅助方法:将字节数组转换为32位整数 */ // public static int getU32(byte[] p, int offset) { // return ((p[offset] & 0xFF) << 24) | // ((p[offset + 1] & 0xFF) << 16) | // ((p[offset + 2] & 0xFF) << 8) | // (p[offset + 3] & 0xFF); // } /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */ public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) { out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位 out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位 } // /** 辅助方法:将32位整数转换为字节数组 */ // public static void putU32(byte[] p, int offset, int v) { // p[offset] = (byte) (v >> 24); // p[offset + 1] = (byte) (v >> 16); // p[offset + 2] = (byte) (v >> 8); // p[offset + 3] = (byte) v; // } /** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */ public static void putU32(byte[] p, short offset, short vlo, short vhi) { // 写高16位 p[offset] = (byte) ((vhi >> 8) & 0xFF); p[(short)(offset + 1)] = (byte) (vhi & 0xFF); // 写低16位 p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF); p[(short)(offset + 3)] = (byte) (vlo & 0xFF); } // === 31/32 位运算 === // /** 31位加法 */ // public static int add31(int a, int b) { // long sum = (long)a + b; // return (int) ((sum & 0x7FFFFFFF) + (sum >> 31)); // } /** 31位加法: (a+b) mod (2^31 - 1) * 输入: a_lo=低16位, a_hi=高15位 * b_lo=低16位, b_hi=高15位 * 输出: out[0]=lo, out[1]=hi */ public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) { // ---- 低16位相加 ---- short lo = (short)(a_lo + b_lo); short carry = (short)( ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0 ? 1 : 0 ); // ---- 高15位相加 + 进位 ---- short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry); // 提取第31位(hi_raw bit15) short topbit = (short)((hi_raw >>> 15) & 1); short hi = (short)(hi_raw & 0x7FFF); // 保留15位 // ---- 若第31位=1,再+1 ---- if (topbit == 1) { short lo2 = (short)(lo + 1); short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位 lo = lo2; hi = (short)((hi + c2) & 0x7FFF); } out[0] = lo; out[1] = hi; } // /** 31位旋转 */ // public static int rot31(int a, int k) { // return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF; // } /** 31位循环左移: (a <<< k) mod (2^31 -1) * 输入: a_lo=低16位, a_hi=高15位 * 输出: out[0]=lo, out[1]=hi */ public void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) { k = (short)(k % 31); // 限制在 0..30 if (k == 0) { out[0] = a_lo; out[1] = (short)(a_hi & 0x7FFF); return; } // 拆成 31 位数组 [bit0..bit30] for (short i = 0; i < 16; i++) { rot31_bits[i] = (short)((a_lo >>> i) & 1); } for (short i = 0; i < 15; i++) { rot31_bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1); } // 旋转 for (short i = 0; i < 31; i++) { short j = (short)((i + k) % 31); rot31_resBits[j] = rot31_bits[i]; } // 拼回 lo, hi short lo = 0; for (short i = 0; i < 16; i++) { lo = (short)(lo | (rot31_resBits[i] << i)); } short hi = 0; for (short i = 0; i < 15; i++) { hi = (short)(hi | (rot31_resBits[(short)(16 + i)] << i)); } out[0] = lo; out[1] = hi; } // /** 32位旋转 */ // public static int rot32(int a, int k) { // return (a << k) | (a >>> (32 - k)); // } /** 32位循环左移: (a<< 0) { // 先做 1 位循环左移 // 注意:short 在 >>> 时会先提升为 int,所以下面都再用 &1 取最低位,避免符号扩展影响 nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1)); nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1)); hi = nw_hi; lo = nw_lo; k--; } out[0] = lo; // 低16位 out[1] = hi; // 高16位 } // /** // * L1函数 // */ // public static int L1(int x) { // return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); // } /** * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24) * 输入: x_lo, x_hi * 输出: out[0]=lo, out[1]=hi */ public void L1(short x_lo, short x_hi, short[] out /*len==2*/) { // acc = x L1_acc[0] = x_lo; L1_acc[1] = x_hi; // acc ^= rot32(x, 2) rot32(x_lo, x_hi, (short)2, L1_t); L1_acc[0] ^= L1_t[0]; L1_acc[1] ^= L1_t[1]; // acc ^= rot32(x, 10) rot32(x_lo, x_hi, (short)10, L1_t); L1_acc[0] ^= L1_t[0]; L1_acc[1] ^= L1_t[1]; // acc ^= rot32(x, 18) rot32(x_lo, x_hi, (short)18, L1_t); L1_acc[0] ^= L1_t[0]; L1_acc[1] ^= L1_t[1]; // acc ^= rot32(x, 24) rot32(x_lo, x_hi, (short)24, L1_t); L1_acc[0] ^= L1_t[0]; L1_acc[1] ^= L1_t[1]; out[0] = L1_acc[0]; out[1] = L1_acc[1]; } // /** // * L2函数 // */ // public static int L2(int x) { // return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); // } /** * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30) * 输入: x_lo, x_hi * 输出: out[0]=lo, out[1]=hi */ public void L2(short x_lo, short x_hi, short[] out /*len==2*/) { // acc = x L2_acc[0] = x_lo; L2_acc[1] = x_hi; // acc ^= rot32(x, 8) rot32(x_lo, x_hi, (short)8, L2_t); L2_acc[0] ^= L2_t[0]; L2_acc[1] ^= L2_t[1]; // acc ^= rot32(x, 14) rot32(x_lo, x_hi, (short)14, L2_t); L2_acc[0] ^= L2_t[0]; L2_acc[1] ^= L2_t[1]; // acc ^= rot32(x, 22) rot32(x_lo, x_hi, (short)22, L2_t); L2_acc[0] ^= L2_t[0]; L2_acc[1] ^= L2_t[1]; // acc ^= rot32(x, 30) rot32(x_lo, x_hi, (short)30, L2_t); L2_acc[0] ^= L2_t[0]; L2_acc[1] ^= L2_t[1]; out[0] = L2_acc[0]; out[1] = L2_acc[1]; } // /** 创建31位无符号整数 */ // public static int makeU31(int a, int b, int c, int d) { // return (((a & 0xFF) << 23) | // ((b & 0xFF) << 16) | // ((c & 0xFF) << 8) | // (d & 0xFF)) & 0x7FFFFFFF; // } /** 创建31位无符号整数,结果放到 out[0]=lo, out[1]=hi(15位) */ public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) { // 四个字节 short b0 = (short)(a & 0xFF); // 最高字节 short b1 = (short)(b & 0xFF); short b2 = (short)(c & 0xFF); short b3 = (short)(d & 0xFF); // 最低字节 // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3 // lo = 低16位 out[0] = (short)((b2 << 8) | b3); // hi = 高15位(丢弃 bit31) out[1] = (short)((b0 << 7) | b1); } // /** 创建32位无符号整数 */ // public static int makeU32(int a, int b, int c, int d) { // return ((a & 0xFF) << 24) | // ((b & 0xFF) << 16) | // ((c & 0xFF) << 8) | // (d & 0xFF); // } /** 创建32位无符号整数,结果放到 out[0]=lo, out[1]=hi */ public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) { // 四个字节 short b0 = (short)(a & 0xFF); // 最高字节 short b1 = (short)(b & 0xFF); short b2 = (short)(c & 0xFF); short b3 = (short)(d & 0xFF); // 最低字节 // lo = 低16位 out[0] = (short)((b2 << 8) | b3); // hi = 高16位 out[1] = (short)((b0 << 8) | b1); } /** 提取IV */ public void extractIv(byte[] input25Byte, byte[] output23Byte) { if (input25Byte == null || output23Byte == null) return; // 复制前17字节 Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17); // 处理剩余8字节 for (short i = 0; i < 8; i++) { extract_iv_last8[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F); } output23Byte[17] = (byte) ((extract_iv_last8[0] << 2) | (extract_iv_last8[1] >>> 4)); output23Byte[18] = (byte) (((extract_iv_last8[1] & 0x0F) << 4) | (extract_iv_last8[2] >>> 2)); output23Byte[19] = (byte) (((extract_iv_last8[2] & 0x03) << 6) | extract_iv_last8[3]); output23Byte[20] = (byte) ((extract_iv_last8[4] << 2) | (extract_iv_last8[5] >>> 4)); output23Byte[21] = (byte) (((extract_iv_last8[5] & 0x0F) << 4) | (extract_iv_last8[6] >>> 2)); output23Byte[22] = (byte) (((extract_iv_last8[6] & 0x03) << 6) | extract_iv_last8[7]); } /** * 32位加法: (a_hi:a_lo) + (b_hi:b_lo) * out[0] = lo, out[1] = hi */ static void add32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len=2*/) { // ---- 低16位 ---- short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF)); short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8); short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF); short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF); short lo_high = (short)(a_lo_hi + b_lo_hi + carry0); short carry1 = (short)(lo_high >>> 8); short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF)); // ---- 高16位 ---- short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1); short carry2 = (short)(hi_low >>> 8); short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF); short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF); short hi_high = (short)(a_hi_hi + b_hi_hi + carry2); short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF)); // ---- 输出 ---- out[0] = lo_res; out[1] = hi_res; } /** * 32位加法 + 返回进位(只用 short) * 输入: (a_hi:a_lo) + (b_hi:b_lo) * 输出: out[0]=lo, out[1]=hi * 返回: 最终进位(0/1) */ static short add32_with_carry(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len=2 */) { // ---- 低16位:分两段8位相加 ---- short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510 short c0 = (short)(s0 >>> 8); // 0/1 short s1 = (short)(((a_lo >>> 8) & (short)0x00FF) + ((b_lo >>> 8) & (short)0x00FF) + c0); // 0..511 short c1 = (short)(s1 >>> 8); // 0/1 short lo = (short)((s1 << 8) | (s0 & (short)0x00FF)); // ---- 高16位:再分两段8位相加,并加上 c1 ---- short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1); short c2 = (short)(s2 >>> 8); // 0/1 short s3 = (short)(((a_hi >>> 8) & (short)0x00FF) + ((b_hi >>> 8) & (short)0x00FF) + c2); // 0..511 short c3 = (short)(s3 >>> 8); // 最终进位 0/1 short hi = (short)((s3 << 8) | (s2 & (short)0x00FF)); out[0] = lo; out[1] = hi; return (short)(c3 & 1); } /** * 64位加法: a4 + b4 -> a4 * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword) */ void add64(short[] a, short[] b) { // 低 32 位 short carry = add32_with_carry(a[0], a[1], b[0], b[1], add64_tmp); a[0] = add64_tmp[0]; a[1] = add64_tmp[1]; // 高 32 位 + carry add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], add64_tmp); a[2] = add64_tmp[0]; a[3] = add64_tmp[1]; } // 32位异或 public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) { out[0] = (short)(a_lo ^ b_lo); out[1] = (short)(a_hi ^ b_hi); } /** * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32), * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。 */ static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) { short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0; if (k >= 16) { a3 = a2; // 0 a2 = a1; // 原 hi16 a1 = a0; // 原 lo16 a0 = 0; k = (short)(k - 16); } while (k > 0) { short c0 = (short)((a0 >>> 15) & 1); short c1 = (short)((a1 >>> 15) & 1); short c2 = (short)((a2 >>> 15) & 1); a3 = (short)((a3 << 1) | c2); a2 = (short)((a2 << 1) | c1); a1 = (short)((a1 << 1) | c0); a0 = (short)(a0 << 1); k--; } a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3; } /** * (A & 0x7FFFFFFF),结果放在 out[4],只保留低32位并清掉最高bit。 */ static void and64_7FFFFFFF_to32(short[] A, short[] out) { out[0] = A[0]; // lo16 out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit) out[2] = 0; out[3] = 0; } /** * 64位无符号右移 31 位 * 输入: A[0..3] (short[4], A[0]最低16位) * 输出: out[0..3] */ static void shr64u_31(short[] A, short[] out) { // 先拼出 64bit 的逻辑,逐段右移 // A >>> 31 = (A >>> 16) >>> 15 // 先右移 16,相当于丢掉 A[0],整体右移一半字 out[0] = A[1]; // 原 A[1] -> 新低16位 out[1] = A[2]; // 原 A[2] out[2] = A[3]; // 原 A[3] out[3] = 0; // 高位补0 // 再右移 15 位 short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位 short c1 = (short)((out[1] & (short)0xFFFF) >>> 15); short c2 = (short)((out[2] & (short)0xFFFF) >>> 15); out[0] = (short)((c0 & 0x0001) | (out[1] << 1)); out[1] = (short)((c1 & 0x0001) | (out[2] << 1)); out[2] = (short)(c2 & 0x0001); } /** * 32位无符号右移 1 位 * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位) * 输出: out[0]=lo, out[1]=hi */ static void shr32u1(short lo, short hi, short[] out) { // >>>1:先处理低16位 short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15)); short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF); out[0] = nwLo; out[1] = nwHi; } //===zuc256core /** 初始化状态(Key + IV) */ public void initState(byte[] key32, byte[] iv) { zuc256SetMacKey(key32, iv, (short)0); } /** 生成单个密钥字 */ public void zuc256GenerateKeyword(short[] out) { // int[] LFSR = state.LFSR; // int R1 = state.R1; // int R2 = state.R2; // int X0, X1, X2, X3; // int W1, W2, U, V; // int Z; // 载入 R1,R2 zuc256GenerateKeyword_R1[0] = R1_lo; zuc256GenerateKeyword_R1[1] = R1_hi; zuc256GenerateKeyword_R2[0] = R2_lo; zuc256GenerateKeyword_R2[1] = R2_hi; // BitReconstruction4 short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); // 左移产生的进位 zuc256GenerateKeyword_X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001)); // hi zuc256GenerateKeyword_X0[0] = LFSR_lo[14]; // lo // X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15) zuc256GenerateKeyword_X1[1] = LFSR_lo[11]; zuc256GenerateKeyword_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1)); // X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15) zuc256GenerateKeyword_X2[1] = LFSR_lo[7]; zuc256GenerateKeyword_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1)); // X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15) zuc256GenerateKeyword_X3[1] = LFSR_lo[2]; zuc256GenerateKeyword_X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1)); // ---- 输入:X0,X1,X2,X3,R1,R2 均为 short[2]; 输出:Z,W1,W2,U,V ---- // Z = X3 ^ ((X0 ^ R1) + R2) xor32(zuc256GenerateKeyword_X0[0], zuc256GenerateKeyword_X0[1], zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_TMP0); // TMP0 = X0 ^ R1 add32(zuc256GenerateKeyword_TMP0[0], zuc256GenerateKeyword_TMP0[1], zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_TMP1); // TMP1 = TMP0 + R2 xor32(zuc256GenerateKeyword_X3[0], zuc256GenerateKeyword_X3[1], zuc256GenerateKeyword_TMP1[0], zuc256GenerateKeyword_TMP1[1], zuc256GenerateKeyword_Z); // Z = X3 ^ TMP1 // F_(X1, X2) // W1 = R1 + X1 add32(zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_X1[0], zuc256GenerateKeyword_X1[1], zuc256GenerateKeyword_W1); // W2 = R2 ^ X2 xor32(zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_X2[0], zuc256GenerateKeyword_X2[1], zuc256GenerateKeyword_W2); // U = L1((W1 << 16) | (W2 >>> 16)) // (W1<<16): lo=0, hi=W1_lo // (W2>>>16): lo=W2_hi, hi=0 // OR 结果: lo=W2_hi, hi=W1_lo L1(zuc256GenerateKeyword_W2[1], zuc256GenerateKeyword_W1[0], zuc256GenerateKeyword_U); // V = L2((W2 << 16) | (W1 >>> 16)) // (W2<<16): lo=0, hi=W2_lo // (W1>>>16): lo=W1_hi, hi=0 // OR 结果: lo=W1_hi, hi=W2_lo L2(zuc256GenerateKeyword_W1[1], zuc256GenerateKeyword_W2[0], zuc256GenerateKeyword_V); // R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], // Zuc256Tables.S1[(U >>> 16) & 0xFF], // Zuc256Tables.S0[(U >>> 8) & 0xFF], // Zuc256Tables.S1[U & 0xFF]); makeU32( (short)(Zuc256Tables.S0[((zuc256GenerateKeyword_U[1] >>> 8) & 0xFF)] & 0xFF), // (U >>> 24) & 0xFF (short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[1] & 0xFF)] & 0xFF), // (U >>> 16) & 0xFF (short)(Zuc256Tables.S0[((zuc256GenerateKeyword_U[0] >>> 8) & 0xFF)] & 0xFF), // (U >>> 8) & 0xFF (short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[0] & 0xFF)] & 0xFF), // (U >>> 0) & 0xFF zuc256GenerateKeyword_R1); // R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], // Zuc256Tables.S1[(V >>> 16) & 0xFF], // Zuc256Tables.S0[(V >>> 8) & 0xFF], // Zuc256Tables.S1[V & 0xFF]); makeU32( (short)(Zuc256Tables.S0[((zuc256GenerateKeyword_V[1] >>> 8) & 0xFF)] & 0xFF), // (V >>> 24) & 0xFF (short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[1] & 0xFF)] & 0xFF), // (V >>> 16) & 0xFF (short)(Zuc256Tables.S0[((zuc256GenerateKeyword_V[0] >>> 8) & 0xFF)] & 0xFF), // (V >>> 8) & 0xFF (short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[0] & 0xFF)] & 0xFF), // (V >>> 0) & 0xFF zuc256GenerateKeyword_R2); // // LFSRWithWorkMode // long a = LFSR[0]; // a += (long)LFSR[0] << 8; // a += (long)LFSR[4] << 20; // a += (long)LFSR[10] << 21; // a += (long)LFSR[13] << 17; // a += (long)LFSR[15] << 15; // ---- 先准备累加器 A (64位) ---- zuc256GenerateKeyword_A[0] = 0; zuc256GenerateKeyword_A[1] = 0; zuc256GenerateKeyword_A[2] = 0; zuc256GenerateKeyword_A[3] = 0; // 临时缓冲 // a = LFSR[0] zuc256GenerateKeyword_tmp32[0] = LFSR_lo[0]; zuc256GenerateKeyword_tmp32[1] = LFSR_hi[0]; create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)0); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a += (LFSR[0] << 8) create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)8); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a += (LFSR[4] << 20) zuc256GenerateKeyword_tmp32[0] = LFSR_lo[4]; zuc256GenerateKeyword_tmp32[1] = LFSR_hi[4]; create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)20); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a += (LFSR[10] << 21) zuc256GenerateKeyword_tmp32[0] = LFSR_lo[10]; zuc256GenerateKeyword_tmp32[1] = LFSR_hi[10]; create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)21); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a += (LFSR[13] << 17) zuc256GenerateKeyword_tmp32[0] = LFSR_lo[13]; zuc256GenerateKeyword_tmp32[1] = LFSR_hi[13]; create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)17); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a += (LFSR[15] << 15) zuc256GenerateKeyword_tmp32[0] = LFSR_lo[15]; zuc256GenerateKeyword_tmp32[1] = LFSR_hi[15]; create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)15); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64); // a = (a & 0x7FFFFFFF) + (a >>> 31); // ---- 第一次折叠:a = (a & 0x7FFFFFFF) + (a >>> 31) ---- and64_7FFFFFFF_to32(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31); // low31 = A & 0x7FFFFFFF shr64u_31(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31); // r31 = A >>> 31 zuc256GenerateKeyword_A[0]=0; zuc256GenerateKeyword_A[1]=0; zuc256GenerateKeyword_A[2]=0; zuc256GenerateKeyword_A[3]=0; add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31); add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31); // int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); // ---- 第二次折叠,得到 v(32位)---- and64_7FFFFFFF_to32(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31b); shr64u_31(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31b); zuc256GenerateKeyword_v64[0]=0; zuc256GenerateKeyword_v64[1]=0; zuc256GenerateKeyword_v64[2]=0; zuc256GenerateKeyword_v64[3]=0; add64(zuc256GenerateKeyword_v64, zuc256GenerateKeyword_low31b); add64(zuc256GenerateKeyword_v64, zuc256GenerateKeyword_r31b); // v = 32位,取 v64 的低两段 short v_lo = zuc256GenerateKeyword_v64[0]; short v_hi = (short)(zuc256GenerateKeyword_v64[1] & 0x7FFF); // 只保留31位 // System.arraycopy(LFSR, 1, LFSR, 0, 15); // LFSR_lo 向左移 for (short i = 0; i < (short)15; i++) { LFSR_lo[i] = LFSR_lo[(short)(i + 1)]; } // LFSR_hi 向左移 for (short i = 0; i < (short)15; i++) { LFSR_hi[i] = LFSR_hi[(short)(i + 1)]; } // LFSR[15] = v; // ---- 写回 LFSR[15] ---- LFSR_lo[15] = v_lo; LFSR_hi[15] = v_hi; // state.R1 = R1; // state.R2 = R2; R1_lo = zuc256GenerateKeyword_R1[0]; R1_hi = zuc256GenerateKeyword_R1[1]; R2_lo = zuc256GenerateKeyword_R2[0]; R2_hi = zuc256GenerateKeyword_R2[1]; // return Z; out[0] = zuc256GenerateKeyword_Z[0]; out[1] = zuc256GenerateKeyword_Z[1]; } // 生成指定长度的密钥流 public void zuc256GenerateKeystream(short nwords, short[] keystream_hi, short[] keystream_lo) { for (short i = 0; i < nwords; i++) { // 生成一个关键字 -> tmp[0]=lo, tmp[1]=hi zuc256GenerateKeyword(zuc256GenerateKeystream_tmp); // 存入输出数组 keystream_lo[i] = zuc256GenerateKeystream_tmp[0]; keystream_hi[i] = zuc256GenerateKeystream_tmp[1]; } } // 初始化MAC密钥 private void zuc256SetMacKey(byte[] K, byte[] IV, short macbits) { for(short i=0; i<2; i++) { zuc256SetMacKey_R1[i] = (short) 0; zuc256SetMacKey_R2[i] = (short) 0; } for(short i=0; i<4; i++) { zuc256SetMacKey_A[i] = (short) 0; zuc256SetMacKey_vv[i] = (short) 0; zuc256SetMacKey_v64[i] = (short) 0; } // short[] zuc256SetMacKey_D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_W = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_U = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_V = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_T = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] zuc256SetMacKey_T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // int IV17 = (IV[17] & 0xFF) >> 2; // int IV18 = ((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >> 4); // int IV19 = ((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >> 6); // int IV20 = IV[19] & 0x3F; // int IV21 = (IV[20] & 0xFF) >> 2; // int IV22 = ((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >> 4); // int IV23 = ((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >> 6); // int IV24 = IV[22] & 0x3F; // IV 拆分 short IV17 = (short)((IV[17] & 0xFF) >>> 2); short IV18 = (short)(((IV[17] & 0x03) << 4) | ((IV[18] & 0xFF) >>> 4)); short IV19 = (short)(((IV[18] & 0x0F) << 2) | ((IV[19] & 0xFF) >>> 6)); short IV20 = (short)(IV[19] & 0x3F); short IV21 = (short)((IV[20] & 0xFF) >>> 2); short IV22 = (short)(((IV[20] & 0x03) << 4) | ((IV[21] & 0xFF) >>> 4)); short IV23 = (short)(((IV[21] & 0x0F) << 2) | ((IV[22] & 0xFF) >>> 6)); short IV24 = (short)(IV[22] & 0x3F); // D = (macbits / 32 < 3) ? Zuc256Tables.ZUC256_D[macbits / 32] : Zuc256Tables.ZUC256_D[3]; short row = (short)((macbits / 32) < 3 ? (macbits / 32) : 3); Zuc256Tables.getDRow(row, zuc256SetMacKey_D, (short)0); Zuc256Tables.getDRow(row, zuc256SetMacKey_D, (short)0); // 逐项装载 LFSR // LFSR[0] = makeU31(K[0] & 0xFF, D[0], K[21] & 0xFF, K[16] & 0xFF); makeU31((short)(K[0] & 0xFF), (short)zuc256SetMacKey_D[0], (short)(K[21] & 0xFF), (short)(K[16] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[0] = zuc256SetMacKey_tmp[0]; LFSR_hi[0] = zuc256SetMacKey_tmp[1]; // LFSR[1] = makeU31(K[1] & 0xFF, D[1], K[22] & 0xFF, K[17] & 0xFF); makeU31((short)(K[1] & 0xFF), (short)zuc256SetMacKey_D[1], (short)(K[22] & 0xFF), (short)(K[17] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[1] = zuc256SetMacKey_tmp[0]; LFSR_hi[1] = zuc256SetMacKey_tmp[1]; // LFSR[2] = makeU31(K[2] & 0xFF, D[2], K[23] & 0xFF, K[18] & 0xFF); makeU31((short)(K[2] & 0xFF), (short)zuc256SetMacKey_D[2], (short)(K[23] & 0xFF), (short)(K[18] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[2] = zuc256SetMacKey_tmp[0]; LFSR_hi[2] = zuc256SetMacKey_tmp[1]; // LFSR[3] = makeU31(K[3] & 0xFF, D[3], K[24] & 0xFF, K[19] & 0xFF); makeU31((short)(K[3] & 0xFF), (short)zuc256SetMacKey_D[3], (short)(K[24] & 0xFF), (short)(K[19] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[3] = zuc256SetMacKey_tmp[0]; LFSR_hi[3] = zuc256SetMacKey_tmp[1]; // LFSR[4] = makeU31(K[4] & 0xFF, D[4], K[25] & 0xFF, K[20] & 0xFF); makeU31((short)(K[4] & 0xFF), (short)zuc256SetMacKey_D[4], (short)(K[25] & 0xFF), (short)(K[20] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[4] = zuc256SetMacKey_tmp[0]; LFSR_hi[4] = zuc256SetMacKey_tmp[1]; // LFSR[5] = makeU31(IV[0] & 0xFF, (D[5] | IV17), K[5] & 0xFF, K[26] & 0xFF); makeU31((short)(IV[0] & 0xFF), (short)(zuc256SetMacKey_D[5] | IV17), (short)(K[5] & 0xFF), (short)(K[26] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[5] = zuc256SetMacKey_tmp[0]; LFSR_hi[5] = zuc256SetMacKey_tmp[1]; // LFSR[6] = makeU31(IV[1] & 0xFF, (D[6] | IV18), K[6] & 0xFF, K[27] & 0xFF); makeU31((short)(IV[1] & 0xFF), (short)(zuc256SetMacKey_D[6] | IV18), (short)(K[6] & 0xFF), (short)(K[27] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[6] = zuc256SetMacKey_tmp[0]; LFSR_hi[6] = zuc256SetMacKey_tmp[1]; // LFSR[7] = makeU31(IV[10] & 0xFF, (D[7] | IV19), K[7] & 0xFF, IV[2] & 0xFF); makeU31((short)(IV[10] & 0xFF), (short)(zuc256SetMacKey_D[7] | IV19), (short)(K[7] & 0xFF), (short)(IV[2] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[7] = zuc256SetMacKey_tmp[0]; LFSR_hi[7] = zuc256SetMacKey_tmp[1]; // LFSR[8] = makeU31(K[8] & 0xFF, (D[8] | IV20), IV[3] & 0xFF, IV[11] & 0xFF); makeU31((short)(K[8] & 0xFF), (short)(zuc256SetMacKey_D[8] | IV20), (short)(IV[3] & 0xFF), (short)(IV[11] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[8] = zuc256SetMacKey_tmp[0]; LFSR_hi[8] = zuc256SetMacKey_tmp[1]; // LFSR[9] = makeU31(K[9] & 0xFF, (D[9] | IV21), IV[12] & 0xFF, IV[4] & 0xFF); makeU31((short)(K[9] & 0xFF), (short)(zuc256SetMacKey_D[9] | IV21), (short)(IV[12] & 0xFF), (short)(IV[4] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[9] = zuc256SetMacKey_tmp[0]; LFSR_hi[9] = zuc256SetMacKey_tmp[1]; // LFSR[10] = makeU31(IV[5] & 0xFF, (D[10] | IV22), K[10] & 0xFF, K[28] & 0xFF); makeU31((short)(IV[5] & 0xFF), (short)(zuc256SetMacKey_D[10] | IV22), (short)(K[10] & 0xFF), (short)(K[28] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[10] = zuc256SetMacKey_tmp[0]; LFSR_hi[10] = zuc256SetMacKey_tmp[1]; // LFSR[11] = makeU31(K[11] & 0xFF, (D[11] | IV23), IV[6] & 0xFF, IV[13] & 0xFF); makeU31((short)(K[11] & 0xFF), (short)(zuc256SetMacKey_D[11] | IV23), (short)(IV[6] & 0xFF), (short)(IV[13] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[11] = zuc256SetMacKey_tmp[0]; LFSR_hi[11] = zuc256SetMacKey_tmp[1]; // LFSR[12] = makeU31(K[12] & 0xFF, (D[12] | IV24), IV[7] & 0xFF, IV[14] & 0xFF); makeU31((short)(K[12] & 0xFF), (short)(zuc256SetMacKey_D[12] | IV24), (short)(IV[7] & 0xFF), (short)(IV[14] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[12] = zuc256SetMacKey_tmp[0]; LFSR_hi[12] = zuc256SetMacKey_tmp[1]; // LFSR[13] = makeU31(K[13] & 0xFF, D[13], IV[15] & 0xFF, IV[8] & 0xFF); makeU31((short)(K[13] & 0xFF), (short)zuc256SetMacKey_D[13], (short)(IV[15] & 0xFF), (short)(IV[8] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[13] = zuc256SetMacKey_tmp[0]; LFSR_hi[13] = zuc256SetMacKey_tmp[1]; // LFSR[14] = makeU31(K[14] & 0xFF, (D[14] | (K[31] >>> 4)), IV[16] & 0xFF, IV[9] & 0xFF); makeU31((short)(K[14] & 0xFF), (short)(zuc256SetMacKey_D[14] | ((K[31] & 0xFF) >>> 4)), (short)(IV[16] & 0xFF), (short)(IV[9] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[14] = zuc256SetMacKey_tmp[0]; LFSR_hi[14] = zuc256SetMacKey_tmp[1]; // LFSR[15] = makeU31(K[15] & 0xFF, (D[15] | (K[31] & 0x0F)), K[30] & 0xFF, K[29] & 0xFF); makeU31((short)(K[15] & 0xFF), (short)(zuc256SetMacKey_D[15] | (K[31] & 0x0F)), (short)(K[30] & 0xFF), (short)(K[29] & 0xFF), zuc256SetMacKey_tmp); LFSR_lo[15] = zuc256SetMacKey_tmp[0]; LFSR_hi[15] = zuc256SetMacKey_tmp[1]; short c15_2 = 0; for (short i = 0; i < 32; i++) { // BitReconstruction3 // X0 = ((LFSR[15] & 0x7FFF8000) << 1) | (LFSR[14] & 0xFFFF); // X0 = ((L15 & 0x7FFF8000)<<1) | (L14 & 0xFFFF) c15_2 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15); zuc256SetMacKey_X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15_2 & 0x0001)); zuc256SetMacKey_X0[0] = LFSR_lo[14]; // X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); // X1 = ((L11 & 0xFFFF)<<16) | (L9>>>15) zuc256SetMacKey_X1[1] = LFSR_lo[11]; zuc256SetMacKey_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1)); // X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); // X2 = ((L7 & 0xFFFF)<<16) | (L5>>>15) zuc256SetMacKey_X2[1] = LFSR_lo[7]; zuc256SetMacKey_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1)); // F(X0, X1, X2) // W = (X0 ^ R1) + R2 xor32(zuc256SetMacKey_X0[0], zuc256SetMacKey_X0[1], zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_TMP); add32(zuc256SetMacKey_TMP[0], zuc256SetMacKey_TMP[1], zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_W); // W1 = R1 + X1 add32(zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_X1[0], zuc256SetMacKey_X1[1], zuc256SetMacKey_W1); // W2 = R2 ^ X2 xor32(zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_X2[0], zuc256SetMacKey_X2[1], zuc256SetMacKey_W2); // U = L1((W1<<16) | (W2>>>16)) L1(zuc256SetMacKey_W2[1], zuc256SetMacKey_W1[0], zuc256SetMacKey_U); // V = L2((W2<<16) | (W1>>>16)) L2(zuc256SetMacKey_W1[1], zuc256SetMacKey_W2[0], zuc256SetMacKey_V); // R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], // Zuc256Tables.S1[(U >>> 16) & 0xFF], // Zuc256Tables.S0[(U >>> 8) & 0xFF], // Zuc256Tables.S1[U & 0xFF]); // // R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], // Zuc256Tables.S1[(V >>> 16) & 0xFF], // Zuc256Tables.S0[(V >>> 8) & 0xFF], // Zuc256Tables.S1[V & 0xFF]); // 更新 R1,R2 makeU32( (short)(Zuc256Tables.S0[((zuc256SetMacKey_U[1] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_U[1] & 0xFF)] & 0xFF), (short)(Zuc256Tables.S0[((zuc256SetMacKey_U[0] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_U[0] & 0xFF)] & 0xFF), zuc256SetMacKey_R1); makeU32( (short)(Zuc256Tables.S0[((zuc256SetMacKey_V[1] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_V[1] & 0xFF)] & 0xFF), (short)(Zuc256Tables.S0[((zuc256SetMacKey_V[0] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_V[0] & 0xFF)] & 0xFF), zuc256SetMacKey_R2); // LFSRWithInitialisationMode(W >> 1) // int v = LFSR[0]; zuc256SetMacKey_V[0] = LFSR_lo[0]; zuc256SetMacKey_V[1] = LFSR_hi[0]; // v = add31(v, rot31(LFSR[0], 8)) rot31(LFSR_lo[0], LFSR_hi[0], (short)8, zuc256SetMacKey_T); add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V); // v = add31(v, rot31(LFSR[4], 20)); rot31(LFSR_lo[4], LFSR_hi[4], (short)20, zuc256SetMacKey_T); add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V); // v = add31(v, rot31(LFSR[10], 21)); rot31(LFSR_lo[10], LFSR_hi[10], (short)21, zuc256SetMacKey_T); add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V); // v = add31(v, rot31(LFSR[13], 17)); rot31(LFSR_lo[13], LFSR_hi[13], (short)17, zuc256SetMacKey_T); add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V); // v = add31(v, rot31(LFSR[15], 15)); rot31(LFSR_lo[15], LFSR_hi[15], (short)15, zuc256SetMacKey_T); add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T[0], zuc256SetMacKey_T[1], zuc256SetMacKey_V); // v = add31(v, W >>> 1); shr32u1(zuc256SetMacKey_W[0], zuc256SetMacKey_W[1], zuc256SetMacKey_T2); // T2[0]=lo, T2[1]=hi(无符号>>>1) zuc256SetMacKey_T2[1] = (short)(zuc256SetMacKey_T2[1] & (short)0xFFFF); // 只保留31位 add31(zuc256SetMacKey_V[0], zuc256SetMacKey_V[1], zuc256SetMacKey_T2[0], zuc256SetMacKey_T2[1], zuc256SetMacKey_V); // System.arraycopy(LFSR, 1, LFSR, 0, 15) // 相当于 System.arraycopy(LFSR_lo, 1, LFSR_lo, 0, 15); for (short j = 0; j < (short)15; j++) { LFSR_lo[j] = LFSR_lo[(short)(j + 1)]; } // 相当于 System.arraycopy(LFSR_hi, 1, LFSR_hi, 0, 15); for (short j = 0; j < (short)15; j++) { LFSR_hi[j] = LFSR_hi[(short)(j + 1)]; } // LFSR[15] = v; LFSR_lo[15] = zuc256SetMacKey_V[0]; LFSR_hi[15] = (short)(zuc256SetMacKey_V[1] & 0x7FFF); } // BitReconstruction2 // X1 = ((LFSR[11] & 0xFFFF) << 16) | (LFSR[9] >>> 15); zuc256SetMacKey_X1[1] = LFSR_lo[11]; zuc256SetMacKey_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1)); // X2 = ((LFSR[7] & 0xFFFF) << 16) | (LFSR[5] >>> 15); zuc256SetMacKey_X2[1] = LFSR_lo[7]; zuc256SetMacKey_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1)); // F_(X1, X2) // W1 = R1 + X1; add32(zuc256SetMacKey_R1[0], zuc256SetMacKey_R1[1], zuc256SetMacKey_X1[0], zuc256SetMacKey_X1[1], zuc256SetMacKey_W1); // W1 = R1 + X1 // W2 = R2 ^ X2; xor32(zuc256SetMacKey_R2[0], zuc256SetMacKey_R2[1], zuc256SetMacKey_X2[0], zuc256SetMacKey_X2[1], zuc256SetMacKey_W2); // W2 = R2 ^ X2 // U = L1((W1 << 16) | (W2 >>> 16)); // U = L1((W1<<16)|(W2>>>16)) → lo=W2_hi, hi=W1_lo L1(zuc256SetMacKey_W2[1], zuc256SetMacKey_W1[0], zuc256SetMacKey_U); // V = L2((W2 << 16) | (W1 >>> 16)); // V = L2((W2<<16)|(W1>>>16)) → lo=W1_hi, hi=W2_lo L2(zuc256SetMacKey_W1[1], zuc256SetMacKey_W2[0], zuc256SetMacKey_V); // R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF], // Zuc256Tables.S1[(U >>> 16) & 0xFF], // Zuc256Tables.S0[(U >>> 8) & 0xFF], // Zuc256Tables.S1[U & 0xFF]); makeU32( (short)(Zuc256Tables.S0[((zuc256SetMacKey_U[1] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_U[1] & 0xFF)] & 0xFF), (short)(Zuc256Tables.S0[((zuc256SetMacKey_U[0] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_U[0] & 0xFF)] & 0xFF), zuc256SetMacKey_R1); // R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF], // Zuc256Tables.S1[(V >>> 16) & 0xFF], // Zuc256Tables.S0[(V >>> 8) & 0xFF], // Zuc256Tables.S1[V & 0xFF]); makeU32( (short)(Zuc256Tables.S0[((zuc256SetMacKey_V[1] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_V[1] & 0xFF)] & 0xFF), (short)(Zuc256Tables.S0[((zuc256SetMacKey_V[0] >>> 8) & 0xFF)] & 0xFF), (short)(Zuc256Tables.S1[(zuc256SetMacKey_V[0] & 0xFF)] & 0xFF), zuc256SetMacKey_R2); // ---- LFSRWithWorkMode ---- // LFSRWithWorkMode // long a = LFSR[0]; zuc256SetMacKey_tmp32[0] = LFSR_lo[0]; zuc256SetMacKey_tmp32[1] = LFSR_hi[0]; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)0); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a += (long)LFSR[0] << 8; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)8); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a += (long)LFSR[4] << 20; zuc256SetMacKey_tmp32[0] = LFSR_lo[4]; zuc256SetMacKey_tmp32[1] = LFSR_hi[4]; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)20); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a += (long)LFSR[10] << 21; zuc256SetMacKey_tmp32[0] = LFSR_lo[10]; zuc256SetMacKey_tmp32[1] = LFSR_hi[10]; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)21); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a += (long)LFSR[13] << 17; zuc256SetMacKey_tmp32[0] = LFSR_lo[13]; zuc256SetMacKey_tmp32[1] = LFSR_hi[13]; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)17); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a += (long)LFSR[15] << 15; zuc256SetMacKey_tmp32[0] = LFSR_lo[15]; zuc256SetMacKey_tmp32[1] = LFSR_hi[15]; create_64b_from_32b(zuc256SetMacKey_tmp64, zuc256SetMacKey_tmp32, (short)15); add64(zuc256SetMacKey_A, zuc256SetMacKey_tmp64); // a = (a & 0x7FFFFFFF) + (a >>> 31); and64_7FFFFFFF_to32(zuc256SetMacKey_A, zuc256SetMacKey_low31); shr64u_31(zuc256SetMacKey_A, zuc256SetMacKey_r31); add64(zuc256SetMacKey_v64, zuc256SetMacKey_low31); add64(zuc256SetMacKey_v64, zuc256SetMacKey_r31); // int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31)); and64_7FFFFFFF_to32(zuc256SetMacKey_v64, zuc256SetMacKey_low31); shr64u_31(zuc256SetMacKey_v64, zuc256SetMacKey_r31); add64(zuc256SetMacKey_vv, zuc256SetMacKey_low31); add64(zuc256SetMacKey_vv, zuc256SetMacKey_r31); short v_lo = zuc256SetMacKey_vv[0]; short v_hi = (short)(zuc256SetMacKey_vv[1] & 0x7FFF); // LFSR左移 // System.arraycopy(LFSR, 1, LFSR, 0, 15); // LFSR_lo 向左移 for (short i = 0; i < (short)15; i++) { LFSR_lo[i] = LFSR_lo[(short)(i + 1)]; } // LFSR_hi 向左移 for (short i = 0; i < (short)15; i++) { LFSR_hi[i] = LFSR_hi[(short)(i + 1)]; } // LFSR[15] = v; LFSR_lo[15] = v_lo; LFSR_hi[15] = v_hi; R1_lo = zuc256SetMacKey_R1[0]; R1_hi = zuc256SetMacKey_R1[1]; R2_lo = zuc256SetMacKey_R2[0]; R2_hi = zuc256SetMacKey_R2[1]; } //===zuc256Encryptctx // 初始化加密上下文 public void initZuc256EncryptCtx(byte[] key32, byte[] iv_in_25) { extractIv(iv_in_25, extracted_iv_23); // Arrays.fill(this.buf, (byte) 0); for (short i = 0; i < (short)this.ctx_buf.length; i++) { this.ctx_buf[i] = (byte)0; } this.ctx_buflen = 0; initState(key32, extracted_iv_23); } // 分阶段处理加密数据 public void updateZuc256EncryptCtx(byte[] in, short inlen, byte[] out) { if (in == null || out == null || inlen == 0) return; short inPos = 0; // 输入偏移 short outPos = 0; // 输出偏移 // 处理缓冲区中剩余的非4字节数据 if (this.ctx_buflen > 0) { // int need = 4 - this.buflen; short need = (short)(4 - this.ctx_buflen); // int copy = Math.min(inlen, need); short copy = (short)((inlen < need) ? inlen : need); // 替代 System.arraycopy(in, 0, this.buf, this.buflen, copy); Util.arrayCopyNonAtomic(in, (short)0, this.ctx_buf, this.ctx_buflen, copy); this.ctx_buflen += copy; // 调整输入指针和长度 // byte[] newIn = new byte[inlen - copy]; // if (inlen - copy > 0) { // System.arraycopy(in, copy, newIn, 0, inlen - copy); // } // in = newIn; // inlen -= copy; // 推进输入指针与剩余长度 inPos += copy; inlen -= copy; // 缓冲区已满,处理一个完整的4字节块 if (this.ctx_buflen == 4) { // int keystream = zuc256GenerateKeyword(this.state); zuc256GenerateKeyword(updateZuc256EncryptCtx_ks); // ks[0]=lo, ks[1]=hi // int plain = getU32(this.buf, 0); // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi getU32(this.ctx_buf, (short)0, updateZuc256EncryptCtx_plain); // putU32(out, 0, plain ^ keystream); // plain ^ ks → res xor32(updateZuc256EncryptCtx_plain[0], updateZuc256EncryptCtx_plain[1], updateZuc256EncryptCtx_ks[0], updateZuc256EncryptCtx_ks[1], updateZuc256EncryptCtx_res); // 写回 out 的前4字节 putU32(out, (short)0, updateZuc256EncryptCtx_res[0], updateZuc256EncryptCtx_res[1]); this.ctx_buflen = 0; // Arrays.fill(this.buf, (byte) 0); for (short i = 0; i < (short)this.ctx_buf.length; i++) { this.ctx_buf[i] = (byte)0; } // 调整输出指针 // byte[] newOut = new byte[out.length - 4]; // if (out.length - 4 > 0) { // System.arraycopy(out, 4, newOut, 0, out.length - 4); // } // out = newOut; // 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。 outPos += 4; } } // 处理完整的4字节块 // int fullBlocks = inlen / 4; short fullBlocks = (short) (inlen / 4); if (fullBlocks > 0) { // int[] keystream = new int[fullBlocks]; // zuc256GenerateKeystream(this.state, fullBlocks, keystream); zuc256GenerateKeystream(fullBlocks, updateZuc256EncryptCtx_ks_hi, updateZuc256EncryptCtx_ks_lo); // 逐块异或加密 for (short i = 0; i < fullBlocks; i++) { // int plain = getU32(in, i * 4); short off = (short) (i << 2); // i*4 // 读明文 getU32(in, (short)(inPos+off), updateZuc256EncryptCtx_word); // word[0]=lo, word[1]=hi // putU32(out, i * 4, plain ^ keystream[i]); // XOR keystream updateZuc256EncryptCtx_word[0] = (short)(updateZuc256EncryptCtx_word[0] ^ updateZuc256EncryptCtx_ks_lo[i]); updateZuc256EncryptCtx_word[1] = (short)(updateZuc256EncryptCtx_word[1] ^ updateZuc256EncryptCtx_ks_hi[i]); // 写密文 putU32(out, (short) (outPos+off), updateZuc256EncryptCtx_word[0], updateZuc256EncryptCtx_word[1]); } // 调整输入指针和长度 // int processed = fullBlocks * 4; short processed = (short)(fullBlocks * 4); // byte[] newIn = new byte[inlen - processed]; // if (inlen - processed > 0) { // System.arraycopy(in, processed, newIn, 0, inlen - processed); // } // in = newIn; // inlen -= processed; // 推进输入/输出指针与剩余长度 inPos += processed; inlen -= processed; outPos += processed; } // 缓存剩余不足4字节的数据 if (inlen > 0) { // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen); Util.arrayCopyNonAtomic(in, (short)inPos, this.ctx_buf, (short)0, inlen); this.ctx_buflen = inlen; } } // 完成加密处理 public void finishZuc256EncryptCtx(byte[] out, short outLen) { if (out == null) return; // 处理缓冲区中剩余的不足4字节数据 if (this.ctx_buflen > 0) { // int keystream = zuc256GenerateKeyword(this.state); // 生成一个 32-bit 密钥字:ks[0]=lo16, ks[1]=hi16 zuc256GenerateKeyword(finishZuc256EncryptCtx_ks); // byte[] keystreamBytes = new byte[4]; // putU32(keystreamBytes, 0, keystream); putU32(finishZuc256EncryptCtx_keystreamBytes, (short)0, finishZuc256EncryptCtx_ks[0], finishZuc256EncryptCtx_ks[1]); // 逐字节异或 short outOffset = (short)(outLen - this.ctx_buflen); for (short i = 0; i < this.ctx_buflen; i++) { out[(short)(i+outOffset)] = (byte) (this.ctx_buf[i] ^ finishZuc256EncryptCtx_keystreamBytes[i]); } } // 清理上下文 // Arrays.fill(this.buf, (byte) 0); for(short i=0; i<4; i++) { this.ctx_buf[i] = (byte)0; } this.ctx_buflen = 0; // Arrays.fill(this.state.LFSR, 0); // LFSR 全部清零(高低位数组各 16 个元素) for (short i = 0; i < 16; i++) { LFSR_lo[i] = 0; LFSR_hi[i] = 0; } // this.state.R1 = 0; // this.state.R2 = 0; // R1、R2 清零 R1_lo = 0; R1_hi = 0; R2_lo = 0; R2_hi = 0; } }