在method里面统一定义缓存变量,所有函数全塞到一起,大小驼峰下划线全大写变量名混用

This commit is contained in:
zcy
2025-09-09 01:30:35 +08:00
parent fe4e0ff4e6
commit dec1fecc16
7 changed files with 3397 additions and 1371 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,681 @@
//package com.cscn;
//
//import javacard.framework.APDU;
//import javacard.framework.ISO7816;
//import javacard.framework.ISOException;
//import javacard.framework.JCSystem;
//import javacard.framework.Util;
//
//
///**
// * 仅做一次“自检调用”:
// * 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ?
// * 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ?
// * Response: 2字节 [encMatch, dblEncRestored]1=真0=假
// */
//public final class Method_old {
// // ======= 已按你提供的数据填充 =======
//
// // Key: 32字节
// private static final byte[] KEY32 = {
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66
// };
//
// // IV
// private static final byte[] IV25 = {//todo 23 -> 25
// (byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
// (byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
// (byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7
// };
//
// // Input: 明文38字节
// private static final byte[] INPUT = {
// (byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF,
// (byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8,
// (byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B,
// (byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,
// (byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30
// };
//
// // EncResult: 期望密文38字节
// private static final byte[] ENC_EXPECTED = {
// (byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5,
// (byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27,
// (byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D,
// (byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9,
// (byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2
// };
//
// // ======================================
//
// // 运行时缓冲放RAM避免写EEPROM
// private final Zuc256EncryptCtx ctx;
//
// public Method_old() {
// ctx = new Zuc256EncryptCtx(); // 仅创建一次
// }
//
//
// public void processData(APDU apdu) {
// short L = (short) INPUT.length;
// byte[] buf1; // Enc(Input)
// byte[] buf2; // Enc(Enc(Input)) -> 应为 Input
// buf1 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// buf2 = JCSystem.makeTransientByteArray(L, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// byte[] apduBuf = apdu.getBuffer();
//
// // 第一次Enc(Input)
// ctx.initZuc256EncryptCtx(KEY32, IV25);
// Zuc256State tmpState = ctx.state;
// ctx.updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1);
// ctx.finishZuc256EncryptCtx(buf1); // 若 Input 长度为 4 的倍数则通常无副作用,留着更稳妥
//
// Zuc256State tmpState2 = ctx.state;
// boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0);
//
// // 第二次Enc(Enc(Input)) 应还原 Input
// ctx.initZuc256EncryptCtx(KEY32, IV25);
// ctx.updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2);
// ctx.finishZuc256EncryptCtx(buf2);
// boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0);
//
// // 返回 2 字节结果:[encMatch, dblOk]1=真, 0=假
// apduBuf[0] = (byte)(encMatch ? 1 : 0);
// apduBuf[1] = (byte)(dblOk ? 1 : 0);
// short outLen = 2;
//
// apdu.setOutgoing();
// apdu.setOutgoingLength(outLen);
// apdu.sendBytes((short)0, outLen);
// }
//
// /**
// * fake数据生成函数
// * 输入: stmsi[6], data[5]
// * 输出: fakedata[5]
// */
// private void makeFakeData(byte[] stmsi, byte[] data, byte[] fakedata) {
// // 示例:逐字节异或 stmsi 前5字节
// for (short i = 0; i < (short)5; i++) {
// fakedata[i] = (byte)(data[i]);
// }
// }
//
// /**
// * APDU处理函数
// */
// public short processDataFake(byte[] buffer, short off, short len, byte[] key_store) {
// // 至少要有 12 个字节1+1+1+6+5
// if (len < (short)12) {
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
// }
//
// // === 解析入参 ===
// byte inType = buffer[(short)(off + 0)]; // 类型 A1
// byte inLen = buffer[(short)(off + 1)]; // 长度 0x0C
// byte secParam = buffer[(short)(off + 2)]; // 安全参数
//
// // STMSI
// byte[] stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6);
//
// // data
// byte[] data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// Util.arrayCopyNonAtomic(buffer, (short)(off + 9), data, (short)0, (short)5);
//
// // === 生成 fakedata ===
// byte[] fakedata = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// makeFakeData(stmsi, data, fakedata);
//
// // === 出参组装 ===
// buffer[(short)(off + 0)] = (byte)0xA1; // 类型
// buffer[(short)(off + 1)] = (byte)0x06; // 长度
// buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取
// Util.arrayCopyNonAtomic(fakedata, (short)0, buffer, (short)(off + 3), (short)5);
//
// return (short)8; // 出参总长度
// }
//
//
//
// public short updateKey(byte[] buffer, short off, short len, byte[] key_store) {
// final short SLOT_SIZE = 40; // 每个槽固定40字节
// final short HDR_LEN = 4; // 报文头长度: [0]=keyLenField, [1]=alg, [2]=keyId, [3]=ver
//
// // === 解析头 ===
// byte keyLenField = buffer[(short)(off + 0)]; // 包含头部+密钥的总长度
// byte alg = buffer[(short)(off + 1)];
// byte keyId = buffer[(short)(off + 2)];
// byte ver = buffer[(short)(off + 3)];
//
// // 计算实际密钥长度
// short realKeyLen = (short)(keyLenField - (byte)3); // 长度字段 = key长度 + 3字节头
// if (realKeyLen <= 0) {
// ISOException.throwIt(ISO7816.SW_DATA_INVALID); // key长度不合法
// }
//
// // 检查APDU长度和key长度是否匹配
// if (len != (short)(HDR_LEN + realKeyLen)) {
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
// }
// if (len > SLOT_SIZE) {
// ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
// }
//
// // === 将原有 key_store 拷贝到 RAM避免直接覆盖 EEPROM (可选) ===
// byte[] key_buf = JCSystem.makeTransientByteArray((short)80, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// Util.arrayCopyNonAtomic(key_store, (short)0, key_buf, (short)0, (short)key_store.length);
//
// // === 遍历槽,找到匹配的 (alg, keyId, ver),否则找空槽 ===
// short slots = (short)(key_store.length / SLOT_SIZE);
// short target = -1;
// for (short i = 0; i < slots; i++) {
// short base = (short)(i * SLOT_SIZE);
// byte algOld = key_store[(short)(base + 1)];
// byte keyIdOld = key_store[(short)(base + 2)];
// byte verOld = key_store[(short)(base + 3)];
//
// if (algOld == alg && keyId == keyIdOld && ver == verOld) {
// target = i; // 找到已存在的,覆盖它
// break;
// }
// if (key_store[base] == (byte)0x00 && target == -1) {
// target = i; // 找到第一个空槽
// }
// }
//
// if (target == -1) {
// ISOException.throwIt(ISO7816.SW_FILE_FULL); // 没有空位
// }
//
// // === 覆盖写入本次APDU的头+密钥数据 ===
// short base = (short)(target * SLOT_SIZE);
// // 先清空槽
// Util.arrayFillNonAtomic(key_store, base, SLOT_SIZE, (byte)0x00);
// // 再写入APDU传入的头+数据 (len 个字节)
// Util.arrayCopyNonAtomic(buffer, off, key_store, base, len);
//
// return 0; // 无返回数据
// }
//
// // === zuc256Util
//
//// /** 辅助方法将字节数组转换为32位整数 */
//// public static int getU32(byte[] p, int offset) {
//// return ((p[offset] & 0xFF) << 24) |
//// ((p[offset + 1] & 0xFF) << 16) |
//// ((p[offset + 2] & 0xFF) << 8) |
//// (p[offset + 3] & 0xFF);
//// }
// /** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
// public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
// out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
// out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
// }
//
//
//// /** 辅助方法将32位整数转换为字节数组 */
//// public static void putU32(byte[] p, int offset, int v) {
//// p[offset] = (byte) (v >> 24);
//// p[offset + 1] = (byte) (v >> 16);
//// p[offset + 2] = (byte) (v >> 8);
//// p[offset + 3] = (byte) v;
//// }
// /** 辅助方法将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
// public static void putU32(byte[] p, short offset, short vlo, short vhi) {
// // 写高16位
// p[offset] = (byte) ((vhi >> 8) & 0xFF);
// p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
//
// // 写低16位
// p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
// p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
// }
//
//
// // === 31/32 位运算 ===
//
//// /** 31位加法 */
//// public static int add31(int a, int b) {
//// long sum = (long)a + b;
//// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
//// }
// /** 31位加法: (a+b) mod (2^31 - 1)
// * 输入: a_lo=低16位, a_hi=高15位
// * b_lo=低16位, b_hi=高15位
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
// // ---- 低16位相加 ----
// short lo = (short)(a_lo + b_lo);
// short carry = (short)(
// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
// ? 1 : 0
// );
// // ---- 高15位相加 + 进位 ----
// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
//
// // 提取第31位hi_raw bit15
// short topbit = (short)((hi_raw >>> 15) & 1);
// short hi = (short)(hi_raw & 0x7FFF); // 保留15位
//
// // ---- 若第31位=1再+1 ----
// if (topbit == 1) {
// short lo2 = (short)(lo + 1);
// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
// lo = lo2;
// hi = (short)((hi + c2) & 0x7FFF);
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 31位旋转 */
//// public static int rot31(int a, int k) {
//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
//// }
// /** 31位循环左移: (a <<< k) mod (2^31 -1)
// * 输入: a_lo=低16位, a_hi=高15位
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
// k = (short)(k % 31); // 限制在 0..30
// if (k == 0) {
// out[0] = a_lo;
// out[1] = (short)(a_hi & 0x7FFF);
// return;
// }
//
// // 拆成 31 位数组 [bit0..bit30]
// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 16; i++) {
// bits[i] = (short)((a_lo >>> i) & 1);
// }
// for (short i = 0; i < 15; i++) {
// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
// }
//
// // 旋转
// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 31; i++) {
// short j = (short)((i + k) % 31);
// resBits[j] = bits[i];
// }
//
// // 拼回 lo, hi
// short lo = 0;
// for (short i = 0; i < 16; i++) {
// lo = (short)(lo | (resBits[i] << i));
// }
// short hi = 0;
// for (short i = 0; i < 15; i++) {
// hi = (short)(hi | (resBits[(short)(16 + i)] << i));
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 32位旋转 */
//// public static int rot32(int a, int k) {
//// return (a << k) | (a >>> (32 - k));
//// }
// /** 32位循环左移: (a<<<k) */
// public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
// k = (short)(k & 31); // 0..31
// short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
// while (k > 0) {
// // 先做 1 位循环左移
// // 注意short 在 >>> 时会先提升为 int所以下面都再用 &1 取最低位,避免符号扩展影响
// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
// hi = nw_hi;
// lo = nw_lo;
// k--;
// }
// out[0] = lo; // 低16位
// out[1] = hi; // 高16位
// }
//
//
//// /**
//// * L1函数
//// */
//// public static int L1(int x) {
//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
//// }
// /**
// * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
// * 输入: x_lo, x_hi
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // acc = x
// acc[0] = x_lo;
// acc[1] = x_hi;
//
// // acc ^= rot32(x, 2)
// rot32(x_lo, x_hi, (short)2, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 10)
// rot32(x_lo, x_hi, (short)10, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 18)
// rot32(x_lo, x_hi, (short)18, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 24)
// rot32(x_lo, x_hi, (short)24, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// out[0] = acc[0];
// out[1] = acc[1];
// }
//
//
//// /**
//// * L2函数
//// */
//// public static int L2(int x) {
//// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
//// }
// /**
// * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
// * 输入: x_lo, x_hi
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
// short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // acc = x
// acc[0] = x_lo;
// acc[1] = x_hi;
//
// // acc ^= rot32(x, 8)
// rot32(x_lo, x_hi, (short)8, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 14)
// rot32(x_lo, x_hi, (short)14, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 22)
// rot32(x_lo, x_hi, (short)22, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// // acc ^= rot32(x, 30)
// rot32(x_lo, x_hi, (short)30, t);
// acc[0] ^= t[0];
// acc[1] ^= t[1];
//
// out[0] = acc[0];
// out[1] = acc[1];
// }
//
//
//// /** 创建31位无符号整数 */
//// public static int makeU31(int a, int b, int c, int d) {
//// return (((a & 0xFF) << 23) |
//// ((b & 0xFF) << 16) |
//// ((c & 0xFF) << 8) |
//// (d & 0xFF)) & 0x7FFFFFFF;
//// }
// /** 创建31位无符号整数结果放到 out[0]=lo, out[1]=hi(15位) */
// public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
// // 四个字节
// short b0 = (short)(a & 0xFF); // 最高字节
// short b1 = (short)(b & 0xFF);
// short b2 = (short)(c & 0xFF);
// short b3 = (short)(d & 0xFF); // 最低字节
//
// // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
// // lo = 低16位
// out[0] = (short)((b2 << 8) | b3);
//
// // hi = 高15位丢弃 bit31
// out[1] = (short)((b0 << 7) | b1);
// }
//
//
//// /** 创建32位无符号整数 */
//// public static int makeU32(int a, int b, int c, int d) {
//// return ((a & 0xFF) << 24) |
//// ((b & 0xFF) << 16) |
//// ((c & 0xFF) << 8) |
//// (d & 0xFF);
//// }
// /** 创建32位无符号整数结果放到 out[0]=lo, out[1]=hi */
// public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) {
// // 四个字节
// short b0 = (short)(a & 0xFF); // 最高字节
// short b1 = (short)(b & 0xFF);
// short b2 = (short)(c & 0xFF);
// short b3 = (short)(d & 0xFF); // 最低字节
//
// // lo = 低16位
// out[0] = (short)((b2 << 8) | b3);
//
// // hi = 高16位
// out[1] = (short)((b0 << 8) | b1);
// }
//
//
//
// /** 提取IV */
// public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
// if (input25Byte == null || output23Byte == null) return;
//
// // 复制前17字节
// Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
//
//
// // 处理剩余8字节
// byte[] src = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 8; i++) {
// src[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
// }
//
// output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4));
// output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2));
// output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]);
// output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4));
// output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2));
// output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
// }
//
// /**
// * 32位加法: (a_hi:a_lo) + (b_hi:b_lo)
// * out[0] = lo, out[1] = hi
// */
// static void add32(short a_lo, short a_hi,
// short b_lo, short b_hi,
// short[] out /*len=2*/) {
//
// // ---- 低16位 ----
// short lo_low = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF));
// short carry0 = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8);
//
// short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF);
// short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF);
// short lo_high = (short)(a_lo_hi + b_lo_hi + carry0);
// short carry1 = (short)(lo_high >>> 8);
//
// short lo_res = (short)((lo_high << 8) | (lo_low & 0x00FF));
//
// // ---- 高16位 ----
// short hi_low = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1);
// short carry2 = (short)(hi_low >>> 8);
//
// short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF);
// short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF);
// short hi_high = (short)(a_hi_hi + b_hi_hi + carry2);
//
// short hi_res = (short)((hi_high << 8) | (hi_low & 0x00FF));
//
// // ---- 输出 ----
// out[0] = lo_res;
// out[1] = hi_res;
// }
//
// /**
// * 32位加法 + 返回进位(只用 short
// * 输入: (a_hi:a_lo) + (b_hi:b_lo)
// * 输出: out[0]=lo, out[1]=hi
// * 返回: 最终进位(0/1)
// */
// static short add32_with_carry(short a_lo, short a_hi,
// short b_lo, short b_hi,
// short[] out /* len=2 */) {
// // ---- 低16位分两段8位相加 ----
// short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF)); // 0..510
// short c0 = (short)(s0 >>> 8); // 0/1
// short s1 = (short)(((a_lo >>> 8) & (short)0x00FF)
// + ((b_lo >>> 8) & (short)0x00FF)
// + c0); // 0..511
// short c1 = (short)(s1 >>> 8); // 0/1
// short lo = (short)((s1 << 8) | (s0 & (short)0x00FF));
//
// // ---- 高16位再分两段8位相加并加上 c1 ----
// short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1);
// short c2 = (short)(s2 >>> 8); // 0/1
// short s3 = (short)(((a_hi >>> 8) & (short)0x00FF)
// + ((b_hi >>> 8) & (short)0x00FF)
// + c2); // 0..511
// short c3 = (short)(s3 >>> 8); // 最终进位 0/1
// short hi = (short)((s3 << 8) | (s2 & (short)0x00FF));
//
// out[0] = lo;
// out[1] = hi;
// return (short)(c3 & 1);
// }
//
//
//
// /**
// * 64位加法: a4 + b4 -> a4
// * 输入输出: short[4],低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword)
// */
// static void add64(short[] a, short[] b) {
// short[] tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// // 低 32 位
// short carry = add32_with_carry(a[0], a[1], b[0], b[1], tmp);
// a[0] = tmp[0];
// a[1] = tmp[1];
//
// // 高 32 位 + carry
// add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], tmp);
// a[2] = tmp[0];
// a[3] = tmp[1];
// }
//
//
//
// // 32位异或
// public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) {
// out[0] = (short)(a_lo ^ b_lo);
// out[1] = (short)(a_hi ^ b_hi);
// }
//
// /**
// * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32)
// * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。
// */
// static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) {
// short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0;
//
// if (k >= 16) {
// a3 = a2; // 0
// a2 = a1; // 原 hi16
// a1 = a0; // 原 lo16
// a0 = 0;
// k = (short)(k - 16);
// }
//
// while (k > 0) {
// short c0 = (short)((a0 >>> 15) & 1);
// short c1 = (short)((a1 >>> 15) & 1);
// short c2 = (short)((a2 >>> 15) & 1);
//
// a3 = (short)((a3 << 1) | c2);
// a2 = (short)((a2 << 1) | c1);
// a1 = (short)((a1 << 1) | c0);
// a0 = (short)(a0 << 1);
// k--;
// }
//
// a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3;
// }
//
//
// /**
// * (A & 0x7FFFFFFF),结果放在 out[4]只保留低32位并清掉最高bit。
// */
// static void and64_7FFFFFFF_to32(short[] A, short[] out) {
// out[0] = A[0]; // lo16
// out[1] = (short)(A[1] & 0x7FFF); // hi16 (清除最高bit)
// out[2] = 0;
// out[3] = 0;
// }
//
// /**
// * 64位无符号右移 31 位
// * 输入: A[0..3] (short[4], A[0]最低16位)
// * 输出: out[0..3]
// */
// static void shr64u_31(short[] A, short[] out) {
// // 先拼出 64bit 的逻辑,逐段右移
// // A >>> 31 = (A >>> 16) >>> 15
//
// // 先右移 16相当于丢掉 A[0],整体右移一半字
// out[0] = A[1]; // 原 A[1] -> 新低16位
// out[1] = A[2]; // 原 A[2]
// out[2] = A[3]; // 原 A[3]
// out[3] = 0; // 高位补0
//
// // 再右移 15 位
// short c0 = (short)((out[0] & (short)0xFFFF) >>> 15); // out[0] 最后一位变进位
// short c1 = (short)((out[1] & (short)0xFFFF) >>> 15);
// short c2 = (short)((out[2] & (short)0xFFFF) >>> 15);
//
// out[0] = (short)((c0 & 0x0001) | (out[1] << 1));
// out[1] = (short)((c1 & 0x0001) | (out[2] << 1));
// out[2] = (short)(c2 & 0x0001);
// }
//
// /**
// * 32位无符号右移 1 位
// * 输入: lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位)
// * 输出: out[0]=lo, out[1]=hi
// */
// static void shr32u1(short lo, short hi, short[] out) {
// // >>>1先处理低16位
// short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15));
// short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF);
//
// out[0] = nwLo;
// out[1] = nwHi;
// }
//
//
//}

File diff suppressed because it is too large Load Diff

View File

@@ -1,214 +1,214 @@
package com.cscn; //package com.cscn;
//
import javacard.framework.JCSystem; //import javacard.framework.JCSystem;
import javacard.framework.Util; //import javacard.framework.Util;
//
import static com.cscn.Zuc256Core.zuc256GenerateKeystream; //import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
import static com.cscn.Zuc256Core.zuc256GenerateKeyword; //import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
import static com.cscn.Zuc256Util.getU32; //import static com.cscn.Zuc256Util.getU32;
import static com.cscn.Zuc256Util.putU32; //import static com.cscn.Zuc256Util.putU32;
import static com.cscn.Zuc256Util.xor32; //import static com.cscn.Zuc256Util.xor32;
//
//
/** ///**
* 加密上下文类 // * 加密上下文类
*/ // */
public final class Zuc256EncryptCtx { //public final class Zuc256EncryptCtx {
Zuc256State state; // Zuc256State state;
byte[] buf; // byte[] buf;
short buflen; // short buflen;
//
public Zuc256EncryptCtx(Zuc256State state, byte[] buf){ // public Zuc256EncryptCtx(Zuc256State state, byte[] buf){
this.state = state; // this.state = state;
this.buf = buf; // 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; //
// 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; // inlen -= copy;
// 推进输入指针与剩余长度 //
inPos += copy; // // 缓冲区已满处理一个完整的4字节块
inlen -= copy; // if (this.buflen == 4) {
//// int keystream = zuc256GenerateKeyword(this.state);
// 缓冲区已满处理一个完整的4字节块 // short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
if (this.buflen == 4) { // zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi
// int keystream = zuc256GenerateKeyword(this.state); //
short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// int plain = getU32(this.buf, 0);
zuc256GenerateKeyword(this.state, ks); // ks[0]=lo, ks[1]=hi // // 取出 4 字节明文 → plain[0]=lo, plain[1]=hi
// short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// int plain = getU32(this.buf, 0); // getU32(this.buf, (short)0, plain);
// 取出 4 字节明文 → plain[0]=lo, plain[1]=hi //
short[] plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// putU32(out, 0, plain ^ keystream);
getU32(this.buf, (short)0, plain); // // plain ^ ks → res
// short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// putU32(out, 0, plain ^ keystream); // xor32(plain[0], plain[1], ks[0], ks[1], res);
// plain ^ ks → res // // 写回 out 的前4字节
short[] res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // putU32(out, (short)0, res[0], res[1]);
xor32(plain[0], plain[1], ks[0], ks[1], res); //
// 写回 out 的前4字节 // this.buflen = 0;
putU32(out, (short)0, res[0], res[1]); //// Arrays.fill(this.buf, (byte) 0);
// for (short i = 0; i < (short)this.buf.length; i++) {
this.buflen = 0; // this.buf[i] = (byte)0;
// Arrays.fill(this.buf, (byte) 0);
for (short i = 0; i < (short)this.buf.length; i++) {
this.buf[i] = (byte)0;
}
// 调整输出指针
// byte[] newOut = new byte[out.length - 4];
// if (out.length - 4 > 0) {
// System.arraycopy(out, 4, newOut, 0, out.length - 4);
// } // }
// out = newOut; //
// 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。 // // 调整输出指针
outPos += 4; //// byte[] newOut = new byte[out.length - 4];
} //// if (out.length - 4 > 0) {
} //// System.arraycopy(out, 4, newOut, 0, out.length - 4);
//// }
// 处理完整的4字节块 //// out = newOut;
// int fullBlocks = inlen / 4; // // 这里C实现就是直接指针+4的。JavaSE实现搞这个new干嘛。。
short fullBlocks = (short) (inlen / 4); // outPos += 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; // }
//
// // 处理完整的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; // inlen -= processed;
// 推进输入/输出指针与剩余长度 // outPos += processed;
inPos += processed; // }
inlen -= processed; //
outPos += processed; // // 缓存剩余不足4字节的数据
} // if (inlen > 0) {
// // 等价于 System.arraycopy(in, 0, this.buf, 0, inlen);
// 缓存剩余不足4字节的数据 // Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen);
if (inlen > 0) { //
// 等价于 System.arraycopy(in, 0, this.buf, 0, inlen); // this.buflen = inlen;
Util.arrayCopyNonAtomic(in, (short)inPos, this.buf, (short)0, inlen); // }
// }
this.buflen = inlen; //
} // // 完成加密处理
} // public void finishZuc256EncryptCtx(byte[] out) {
// if (out == null) return;
// 完成加密处理 //
public void finish(byte[] out) { // // 处理缓冲区中剩余的不足4字节数据
if (out == null) return; // if (this.buflen > 0) {
//// int keystream = zuc256GenerateKeyword(this.state);
// 处理缓冲区中剩余的不足4字节数据 // // 生成一个 32-bit 密钥字ks[0]=lo16, ks[1]=hi16
if (this.buflen > 0) { // short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// int keystream = zuc256GenerateKeyword(this.state); // zuc256GenerateKeyword(this.state, ks);
// 生成一个 32-bit 密钥字ks[0]=lo16, ks[1]=hi16 //
short[] ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// byte[] keystreamBytes = new byte[4];
zuc256GenerateKeyword(this.state, ks); //// putU32(keystreamBytes, 0, keystream);
// byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// byte[] keystreamBytes = new byte[4]; // putU32(keystreamBytes, (short)0, ks[0], ks[1]);
// 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]);
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;
// 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);
this.buflen = 0; // // LFSR 全部清零(高低位数组各 16 个元素)
// for (short i = 0; i < 16; i++) {
// Arrays.fill(this.state.LFSR, 0); // this.state.LFSR_lo[i] = 0;
// LFSR 全部清零(高低位数组各 16 个元素) // this.state.LFSR_hi[i] = 0;
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 = 0; // this.state.R1_lo = 0;
// this.state.R2 = 0; // this.state.R1_hi = 0;
// R1、R2 清零 // this.state.R2_lo = 0;
this.state.R1_lo = 0; // this.state.R2_hi = 0;
this.state.R1_hi = 0; // }
this.state.R2_lo = 0; //}
this.state.R2_hi = 0;
}
}

View File

@@ -1,32 +1,32 @@
package com.cscn; //package com.cscn;
//
/** ///**
* MAC上下文类JavaCard版int 拆分为两个 short // * MAC上下文类JavaCard版int 拆分为两个 short
*/ // */
public final class Zuc256MacCtx { //public final class Zuc256MacCtx {
// LFSR: 原本 int[16],拆成 hi/lo 各 16 short // // LFSR: 原本 int[16],拆成 hi/lo 各 16 short
short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//todo -> ram // //todo -> ram
short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// R1、R2: 原本 int拆成 hi/lo // // R1、R2: 原本 int拆成 hi/lo
short R1_hi; // short R1_hi;
short R1_lo; // short R1_lo;
short R2_hi; // short R2_hi;
short R2_lo; // short R2_lo;
//
// 缓冲区 // // 缓冲区
byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // byte[] buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
short buflen; // short buflen;
//
// T: 原本 int[4],拆成 hi/lo // // T: 原本 int[4],拆成 hi/lo
short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] T_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
short[] T_lo = 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 // // K0: 原本 int[4],拆成 hi/lo
short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] K0_hi = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // short[] K0_lo = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
//
// macbits: 原本 int改成 short 足够 // // macbits: 原本 int改成 short 足够
short macbits; // short macbits;
} //}

View File

@@ -1,22 +1,25 @@
package com.cscn; //package com.cscn;
//
/** ///**
* ZUC状态类JavaCard版int 拆为 hi/lo short // * ZUC状态类JavaCard版int 拆为 hi/lo short
*/ // */
public class Zuc256State { //public class Zuc256State {
// LFSR: 原 int[16] -> hi/lo 各 16 // // LFSR: 原 int[16] -> hi/lo 各 16
public short[] LFSR_hi; // public short[] LFSR_hi;
public short[] LFSR_lo; // public short[] LFSR_lo;
//
// R1, R2: 原 int -> hi/lo // // R1, R2: 原 int -> hi/lo
public short R1_hi; // public short R1_hi;
public short R1_lo; // public short R1_lo;
public short R2_hi; // public short R2_hi;
public short R2_lo; // public short R2_lo;
//
public Zuc256State() { // public Zuc256State() {
this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // this.LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
this.LFSR_lo = 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;
// }
//}

View File

@@ -1,497 +1,497 @@
package com.cscn; //package com.cscn;
//
import javacard.framework.Util; //import javacard.framework.Util;
import javacard.framework.JCSystem; //import javacard.framework.JCSystem;
//
/**
* 辅助工具:装载/存储、位运算、线性变换、打印等。
*/
public final class Zuc256Util {
private Zuc256Util() {}
// /** 辅助方法将字节数组转换为32位整数 */
// public static int getU32(byte[] p, int offset) {
// return ((p[offset] & 0xFF) << 24) |
// ((p[offset + 1] & 0xFF) << 16) |
// ((p[offset + 2] & 0xFF) << 8) |
// (p[offset + 3] & 0xFF);
// }
/** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
}
// /** 辅助方法将32位整数转换为字节数组 */
// public static void putU32(byte[] p, int offset, int v) {
// p[offset] = (byte) (v >> 24);
// p[offset + 1] = (byte) (v >> 16);
// p[offset + 2] = (byte) (v >> 8);
// p[offset + 3] = (byte) v;
// }
/** 辅助方法将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
public static void putU32(byte[] p, short offset, short vlo, short vhi) {
// 写高16位
p[offset] = (byte) ((vhi >> 8) & 0xFF);
p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
// 写低16位
p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
}
// === 31/32 位运算 ===
// /** 31位加法 */
// public static int add31(int a, int b) {
// long sum = (long)a + b;
// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
// }
/** 31位加法: (a+b) mod (2^31 - 1)
* 输入: a_lo=低16位, a_hi=高15位
* b_lo=低16位, b_hi=高15位
* 输出: out[0]=lo, out[1]=hi
*/
public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
// ---- 低16位相加 ----
short lo = (short)(a_lo + b_lo);
short carry = (short)(
( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
? 1 : 0
);
// ---- 高15位相加 + 进位 ----
short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
// 提取第31位hi_raw bit15
short topbit = (short)((hi_raw >>> 15) & 1);
short hi = (short)(hi_raw & 0x7FFF); // 保留15位
// ---- 若第31位=1再+1 ----
if (topbit == 1) {
short lo2 = (short)(lo + 1);
short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
lo = lo2;
hi = (short)((hi + c2) & 0x7FFF);
}
out[0] = lo;
out[1] = hi;
}
// /** 31位旋转 */
// public static int rot31(int a, int k) {
// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
// }
/** 31位循环左移: (a <<< k) mod (2^31 -1)
* 输入: a_lo=低16位, a_hi=高15位
* 输出: out[0]=lo, out[1]=hi
*/
public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
k = (short)(k % 31); // 限制在 0..30
if (k == 0) {
out[0] = a_lo;
out[1] = (short)(a_hi & 0x7FFF);
return;
}
// 拆成 31 位数组 [bit0..bit30]
short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
for (short i = 0; i < 16; i++) {
bits[i] = (short)((a_lo >>> i) & 1);
}
for (short i = 0; i < 15; i++) {
bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
}
// 旋转
short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
for (short i = 0; i < 31; i++) {
short j = (short)((i + k) % 31);
resBits[j] = bits[i];
}
// 拼回 lo, hi
short lo = 0;
for (short i = 0; i < 16; i++) {
lo = (short)(lo | (resBits[i] << i));
}
short hi = 0;
for (short i = 0; i < 15; i++) {
hi = (short)(hi | (resBits[(short)(16 + i)] << i));
}
out[0] = lo;
out[1] = hi;
}
// /** 32位旋转 */
// public static int rot32(int a, int k) {
// return (a << k) | (a >>> (32 - k));
// }
/** 32位循环左移: (a<<<k) */
public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
k = (short)(k & 31); // 0..31
short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
while (k > 0) {
// 先做 1 位循环左移
// 注意short 在 >>> 时会先提升为 int所以下面都再用 &1 取最低位,避免符号扩展影响
nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
hi = nw_hi;
lo = nw_lo;
k--;
}
out[0] = lo; // 低16位
out[1] = hi; // 高16位
}
///** ///**
// * L1函数 // * 辅助工具:装载/存储、位运算、线性变换、打印等。
// */ // */
// public static int L1(int x) { //public final class Zuc256Util {
// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); //
// 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位
// } // }
/** //
* L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24) //
* 输入: x_lo, x_hi //// /** 辅助方法将32位整数转换为字节数组 */
* 输出: out[0]=lo, out[1]=hi //// public static void putU32(byte[] p, int offset, int v) {
*/ //// p[offset] = (byte) (v >> 24);
public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) { //// p[offset + 1] = (byte) (v >> 16);
short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// p[offset + 2] = (byte) (v >> 8);
short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// p[offset + 3] = (byte) v;
//// }
// acc = x // /** 辅助方法将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
acc[0] = x_lo; // public static void putU32(byte[] p, short offset, short vlo, short vhi) {
acc[1] = x_hi; // // 写高16位
// p[offset] = (byte) ((vhi >> 8) & 0xFF);
// acc ^= rot32(x, 2) // p[(short)(offset + 1)] = (byte) (vhi & 0xFF);
rot32(x_lo, x_hi, (short)2, t); //
acc[0] ^= t[0]; // // 写低16位
acc[1] ^= t[1]; // p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
// p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
// acc ^= rot32(x, 10) // }
rot32(x_lo, x_hi, (short)10, t); //
acc[0] ^= t[0]; //
acc[1] ^= t[1]; // // === 31/32 位运算 ===
//
// acc ^= rot32(x, 18) //// /** 31位加法 */
rot32(x_lo, x_hi, (short)18, t); //// public static int add31(int a, int b) {
acc[0] ^= t[0]; //// long sum = (long)a + b;
acc[1] ^= t[1]; //// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
//// }
// acc ^= rot32(x, 24) // /** 31位加法: (a+b) mod (2^31 - 1)
rot32(x_lo, x_hi, (short)24, t); // * 输入: a_lo=低16位, a_hi=高15位
acc[0] ^= t[0]; // * b_lo=低16位, b_hi=高15位
acc[1] ^= t[1]; // * 输出: out[0]=lo, out[1]=hi
// */
out[0] = acc[0]; // public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
out[1] = acc[1]; // // ---- 低16位相加 ----
} // short lo = (short)(a_lo + b_lo);
// short carry = (short)(
// ( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
// ? 1 : 0
// );
// // ---- 高15位相加 + 进位 ----
// short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);
//
// // 提取第31位hi_raw bit15
// short topbit = (short)((hi_raw >>> 15) & 1);
// short hi = (short)(hi_raw & 0x7FFF); // 保留15位
//
// // ---- 若第31位=1再+1 ----
// if (topbit == 1) {
// short lo2 = (short)(lo + 1);
// short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
// lo = lo2;
// hi = (short)((hi + c2) & 0x7FFF);
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 31位旋转 */
//// public static int rot31(int a, int k) {
//// return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
//// }
// /** 31位循环左移: (a <<< k) mod (2^31 -1)
// * 输入: a_lo=低16位, a_hi=高15位
// * 输出: out[0]=lo, out[1]=hi
// */
// public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
// k = (short)(k % 31); // 限制在 0..30
// if (k == 0) {
// out[0] = a_lo;
// out[1] = (short)(a_hi & 0x7FFF);
// return;
// }
//
// // 拆成 31 位数组 [bit0..bit30]
// short[] bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 16; i++) {
// bits[i] = (short)((a_lo >>> i) & 1);
// }
// for (short i = 0; i < 15; i++) {
// bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
// }
//
// // 旋转
// short[] resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// for (short i = 0; i < 31; i++) {
// short j = (short)((i + k) % 31);
// resBits[j] = bits[i];
// }
//
// // 拼回 lo, hi
// short lo = 0;
// for (short i = 0; i < 16; i++) {
// lo = (short)(lo | (resBits[i] << i));
// }
// short hi = 0;
// for (short i = 0; i < 15; i++) {
// hi = (short)(hi | (resBits[(short)(16 + i)] << i));
// }
//
// out[0] = lo;
// out[1] = hi;
// }
//
//
//// /** 32位旋转 */
//// public static int rot32(int a, int k) {
//// return (a << k) | (a >>> (32 - k));
//// }
// /** 32位循环左移: (a<<<k) */
// public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
// k = (short)(k & 31); // 0..31
// short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
// while (k > 0) {
// // 先做 1 位循环左移
// // 注意short 在 >>> 时会先提升为 int所以下面都再用 &1 取最低位,避免符号扩展影响
// nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
// nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
// hi = nw_hi;
// lo = nw_lo;
// k--;
// }
// out[0] = lo; // 低16位
// out[1] = hi; // 高16位
// }
//
//
//// /**
//// * L1函数
//// */
//// public static int L1(int x) {
//// return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
//// }
// /** // /**
// * L2函数 // * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
// * 输入: x_lo, x_hi
// * 输出: out[0]=lo, out[1]=hi
// */ // */
// public static int L2(int x) { // public static void L1(short x_lo, short x_hi, short[] out /*len==2*/) {
// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); // 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函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30) //
* 输入: x_lo, x_hi //// /**
* 输出: out[0]=lo, out[1]=hi //// * L2函数
*/ //// */
public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) { //// public static int L2(int x) {
short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); //// }
// /**
// acc = x // * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
acc[0] = x_lo; // * 输入: x_lo, x_hi
acc[1] = x_hi; // * 输出: out[0]=lo, out[1]=hi
// */
// acc ^= rot32(x, 8) // public static void L2(short x_lo, short x_hi, short[] out /*len==2*/) {
rot32(x_lo, x_hi, (short)8, t); // short[] t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
acc[0] ^= t[0]; // short[] acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
acc[1] ^= t[1]; //
// // acc = x
// acc ^= rot32(x, 14) // acc[0] = x_lo;
rot32(x_lo, x_hi, (short)14, t); // acc[1] = x_hi;
acc[0] ^= t[0]; //
acc[1] ^= t[1]; // // acc ^= rot32(x, 8)
// rot32(x_lo, x_hi, (short)8, t);
// acc ^= rot32(x, 22) // acc[0] ^= t[0];
rot32(x_lo, x_hi, (short)22, t); // acc[1] ^= t[1];
acc[0] ^= t[0]; //
acc[1] ^= t[1]; // // acc ^= rot32(x, 14)
// rot32(x_lo, x_hi, (short)14, t);
// acc ^= rot32(x, 30) // acc[0] ^= t[0];
rot32(x_lo, x_hi, (short)30, t); // acc[1] ^= t[1];
acc[0] ^= t[0]; //
acc[1] ^= t[1]; // // acc ^= rot32(x, 22)
// rot32(x_lo, x_hi, (short)22, t);
out[0] = acc[0]; // acc[0] ^= t[0];
out[1] = acc[1]; // acc[1] ^= t[1];
} //
// // acc ^= rot32(x, 30)
// rot32(x_lo, x_hi, (short)30, t);
// /** 创建31位无符号整数 */ // acc[0] ^= t[0];
// public static int makeU31(int a, int b, int c, int d) { // acc[1] ^= t[1];
// return (((a & 0xFF) << 23) | //
// ((b & 0xFF) << 16) | // out[0] = acc[0];
// ((c & 0xFF) << 8) | // out[1] = acc[1];
// (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*/) { //
// 四个字节 //// /** 创建31位无符号整数 */
short b0 = (short)(a & 0xFF); // 最高字节 //// public static int makeU31(int a, int b, int c, int d) {
short b1 = (short)(b & 0xFF); //// return (((a & 0xFF) << 23) |
short b2 = (short)(c & 0xFF); //// ((b & 0xFF) << 16) |
short b3 = (short)(d & 0xFF); // 最低字节 //// ((c & 0xFF) << 8) |
//// (d & 0xFF)) & 0x7FFFFFFF;
// 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3 //// }
// lo = 低16位 // /** 创建31位无符号整数结果放到 out[0]=lo, out[1]=hi(15位) */
out[0] = (short)((b2 << 8) | b3); // public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
// // 四个字节
// hi = 高15位丢弃 bit31 // short b0 = (short)(a & 0xFF); // 最高字节
out[1] = (short)((b0 << 7) | b1); // short b1 = (short)(b & 0xFF);
} // short b2 = (short)(c & 0xFF);
// short b3 = (short)(d & 0xFF); // 最低字节
//
// /** 创建32位无符号整数 */ // // 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
// public static int makeU32(int a, int b, int c, int d) { // // lo = 低16位
// return ((a & 0xFF) << 24) | // out[0] = (short)((b2 << 8) | b3);
// ((b & 0xFF) << 16) | //
// ((c & 0xFF) << 8) | // // hi = 高15位丢弃 bit31
// (d & 0xFF); // 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();
// }*/
//} //}
/** 创建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();
}*/
}