package com.cscn;

import javacard.framework.APDU;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;


/**
 * 仅做一次“自检调用”：
 * 1) ctx.init(KEY, IV); Enc(Input) == EncExpected ?
 * 2) ctx.init(KEY, IV); Enc(Enc(Input)) == Input ?
 * Response: 2字节 [encMatch, dblEncRestored]，1=真，0=假
 */
public final class Method {
	// ======= 已按你提供的数据填充 =======

	// Key: 32字节
	private static final byte[] KEY32 = {
			(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
			(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
			(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
			(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66
	};

	// IV
//	private static final byte[] IV23 = {
//			(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
//			(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
//			(byte)0x67,(byte)0xC3,(byte)0x1C,(byte)0xB3,(byte)0xD3,(byte)0x5D,(byte)0xB7
//	};
	private static final byte[] IV25 = {
		(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,(byte)0x37,
		(byte)0x38,(byte)0x39,(byte)0x61,(byte)0x62,(byte)0x63,(byte)0x64,(byte)0x65,(byte)0x66,
		(byte)0x67,(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,(byte)0x35,(byte)0x36,
		(byte)0x37
	};

	// Input: 明文（38字节）
	private static final byte[] INPUT = {
			(byte)0x5A,(byte)0x55,(byte)0x43,(byte)0x32,(byte)0x35,(byte)0x36,(byte)0xE5,(byte)0xAF,
			(byte)0xB9,(byte)0xE7,(byte)0xA7,(byte)0xB0,(byte)0xE5,(byte)0x8A,(byte)0xA0,(byte)0xE8,
			(byte)0xA7,(byte)0xA3,(byte)0xE5,(byte)0xAF,(byte)0x86,(byte)0xE6,(byte)0xB5,(byte)0x8B,
			(byte)0xE8,(byte)0xAF,(byte)0x95,(byte)0x3A,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,
			(byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x30
	};

	// EncResult: 期望密文（38字节）
	private static final byte[] ENC_EXPECTED = {
			(byte)0x6C,(byte)0xEE,(byte)0x3C,(byte)0xFA,(byte)0xDE,(byte)0xBB,(byte)0xCB,(byte)0xE5,
			(byte)0x33,(byte)0x51,(byte)0x07,(byte)0x07,(byte)0x90,(byte)0x25,(byte)0x93,(byte)0x27,
			(byte)0x94,(byte)0xF5,(byte)0x18,(byte)0x70,(byte)0xEF,(byte)0x71,(byte)0x72,(byte)0x7D,
			(byte)0xBA,(byte)0x8D,(byte)0xBF,(byte)0x4F,(byte)0x61,(byte)0xC9,(byte)0xA8,(byte)0xE9,
			(byte)0xFF,(byte)0x19,(byte)0xF9,(byte)0xF9,(byte)0xE2,(byte)0xD2
	};

	// ======================================

	// 输入数据缓冲区最大值
	static final short MAX_DATA_BLOCK_SIZE = 128;
	// 运行时缓冲：放RAM，避免写EEPROM
	byte[] ctx_buf;
	short ctx_buflen;

	//todo test
	byte[] buf1; // Enc(Input)
	//todo test
	byte[] buf2; // Enc(Enc(Input)) -> 应为 Input

	// LFSR: 原 int[16] -> hi/lo 各 16
	public short[] LFSR_hi;
	public short[] LFSR_lo;

	// R1, R2: 原 int -> hi/lo
	public short R1_hi;
	public short R1_lo;
	public short R2_hi;
	public short R2_lo;

	byte[] stmsi;
	byte[] location_data;
	byte[] location_res_data;

	byte[] update_key_buf;

	short[] rot31_bits;
	short[] rot31_resBits;

	short[] L1_t;
	short[] L1_acc;

	short[] L2_t;
	short[] L2_acc;

	byte[] extract_iv_last8;
	byte[] extracted_iv_23;

	short[] add64_tmp;

	short[] zuc256SetMacKey_D;
	short[] zuc256SetMacKey_TMP;
	short[] zuc256SetMacKey_X0;
	short[] zuc256SetMacKey_X1;
	short[] zuc256SetMacKey_X2;
	short[] zuc256SetMacKey_R1;
	short[] zuc256SetMacKey_R2;
	short[] zuc256SetMacKey_W;
	short[] zuc256SetMacKey_W1;
	short[] zuc256SetMacKey_W2;
	short[] zuc256SetMacKey_U;
	short[] zuc256SetMacKey_V;
	short[] zuc256SetMacKey_T;
	short[] zuc256SetMacKey_T2;

	short[] zuc256SetMacKey_tmp;

	short[] zuc256SetMacKey_A;
	short[] zuc256SetMacKey_tmp32;
	short[] zuc256SetMacKey_tmp64;
	short[] zuc256SetMacKey_low31;
	short[] zuc256SetMacKey_r31;
	short[] zuc256SetMacKey_v64;
	short[] zuc256SetMacKey_vv;

	short[] updateZuc256EncryptCtx_ks;
	short[] updateZuc256EncryptCtx_plain;
	short[] updateZuc256EncryptCtx_res;
	short[] updateZuc256EncryptCtx_ks_hi;
	short[] updateZuc256EncryptCtx_ks_lo;
	short[] updateZuc256EncryptCtx_word;

	short[] zuc256GenerateKeyword_X0 ;
	short[] zuc256GenerateKeyword_X1 ;
	short[] zuc256GenerateKeyword_X2 ;
	short[] zuc256GenerateKeyword_X3 ;
	short[] zuc256GenerateKeyword_R1 ;
	short[] zuc256GenerateKeyword_R2 ;
	short[] zuc256GenerateKeyword_W1 ;
	short[] zuc256GenerateKeyword_W2 ;
	short[] zuc256GenerateKeyword_U  ;
	short[] zuc256GenerateKeyword_V  ;
	short[] zuc256GenerateKeyword_Z  ;
	short[] zuc256GenerateKeyword_TMP0;
	short[] zuc256GenerateKeyword_TMP1;
	short[] zuc256GenerateKeyword_A;
	short[] zuc256GenerateKeyword_tmp32;
	short[] zuc256GenerateKeyword_tmp64;
	short[] zuc256GenerateKeyword_low31;
	short[] zuc256GenerateKeyword_r31;
	short[] zuc256GenerateKeyword_low31b;
	short[] zuc256GenerateKeyword_r31b;
	short[] zuc256GenerateKeyword_v64;

	short[] zuc256GenerateKeystream_tmp;

	short[] finishZuc256EncryptCtx_ks;
	byte[] finishZuc256EncryptCtx_keystreamBytes;


	public Method() {
		// key list tmp buffer, lenth must equal with key_store(flash)!
		update_key_buf = JCSystem.makeTransientByteArray((short)120, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		// 算法内部使用23Byte IV
		extracted_iv_23 = JCSystem.makeTransientByteArray((short)23, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		ctx_buf = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
        LFSR_hi = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
        LFSR_lo = JCSystem.makeTransientShortArray((short)16, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		// todo buf1 if not use, delete please
		buf1 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		// todo buf2 if not use, delete please
		buf2 = JCSystem.makeTransientByteArray(MAX_DATA_BLOCK_SIZE, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		stmsi = JCSystem.makeTransientByteArray((short)6, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		location_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		location_res_data = JCSystem.makeTransientByteArray((short)5, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		rot31_bits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		rot31_resBits = JCSystem.makeTransientShortArray((short)31, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		L1_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		L1_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		L2_t = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		L2_acc = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		extract_iv_last8 = JCSystem.makeTransientByteArray((short)8, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		add64_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		zuc256SetMacKey_D = JCSystem.makeTransientShortArray(Zuc256Tables.D_COLS, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_TMP = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_W  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_U  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_V  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_T  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_T2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		zuc256SetMacKey_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);  // 临时存储 makeU31 输出 (lo,hi)

		zuc256SetMacKey_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET); // 64位累加器
		zuc256SetMacKey_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_r31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_v64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256SetMacKey_vv = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		updateZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		updateZuc256EncryptCtx_plain = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		updateZuc256EncryptCtx_res = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		updateZuc256EncryptCtx_ks_hi = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		updateZuc256EncryptCtx_ks_lo = JCSystem.makeTransientShortArray((short)(MAX_DATA_BLOCK_SIZE/4), JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
// 临时：装一个32位字
		updateZuc256EncryptCtx_word = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		// 工作寄存器（32位值的临时 out32 缓冲，全用short[2]）[lo, hi]
		zuc256GenerateKeyword_X0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_X1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_X2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_X3 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		zuc256GenerateKeyword_R1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_R2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_W1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_W2 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_U  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_V  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_Z  = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_TMP0 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_TMP1 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_A = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);  // 64位累加器，初始全0
		zuc256GenerateKeyword_tmp32 = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;   // 保存一个32位数 (lo,hi)
		zuc256GenerateKeyword_tmp64 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);;   // 保存移位后的64位数
		zuc256GenerateKeyword_low31 = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_r31   = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_low31b = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_r31b   = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		zuc256GenerateKeyword_v64    = JCSystem.makeTransientShortArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		// 临时存放一个 32 位关键字
		zuc256GenerateKeystream_tmp = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

		finishZuc256EncryptCtx_ks = JCSystem.makeTransientShortArray((short)2, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);
		finishZuc256EncryptCtx_keystreamBytes = JCSystem.makeTransientByteArray((short)4, JCSystem.MEMORY_TYPE_TRANSIENT_RESET);

	}


	//todo test
	public void testZuc256(APDU apdu) {

		byte[] apduBuf = apdu.getBuffer();

		// 第一次：Enc(Input)
		initZuc256EncryptCtx(KEY32, IV25);
		updateZuc256EncryptCtx(INPUT, (short) INPUT.length, buf1);
		finishZuc256EncryptCtx(buf1, (short) INPUT.length); // 若 Input 长度为 4 的倍数则通常无副作用，留着更稳妥

		boolean encMatch = (Util.arrayCompare(buf1, (short)0, ENC_EXPECTED, (short)0, (short)INPUT.length) == 0);

		// 第二次：Enc(Enc(Input)) 应还原 Input
		initZuc256EncryptCtx(KEY32, IV25);
		updateZuc256EncryptCtx(buf1, (short) INPUT.length, buf2);
		finishZuc256EncryptCtx(buf2, (short) INPUT.length);
		boolean dblOk = (Util.arrayCompare(buf2, (short)0, INPUT, (short)0, (short)INPUT.length) == 0);

		// 返回 2 字节结果：[encMatch, dblOk]，1=真, 0=假
		apduBuf[0] = (byte)(encMatch ? 1 : 0);
		apduBuf[1] = (byte)(dblOk    ? 1 : 0);
		short outLen = 2;

		apdu.setOutgoing();
		apdu.setOutgoingLength(outLen);
		apdu.sendBytes((short)0, outLen);
	}

	/**
	 * encryptLocationZuc256
	 * 输入: stmsi[6], data[5]
	 * 输出: out[5]
	 */
	private void encryptLocationZuc256(byte[] stmsi, byte[] data, byte[] out) {
		initZuc256EncryptCtx(KEY32, IV25);
		updateZuc256EncryptCtx(data, (short) 5, out);
		finishZuc256EncryptCtx(out, (short) 5); // 若 Input 长度为 4 的倍数则通常无副作用，留着更稳妥
	}

	/**
	 * APDU处理函数
	 */
	public short locationEncryptZuc(byte[] buffer, short off, short len, byte[] key_store) {
		// 至少要有 12 个字节：1+1+1+6+5
		if (len < (short)12) {
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		}

		// === 解析入参 ===
		byte inType   = buffer[(short)(off + 0)]; // 类型 A1
		byte inLen    = buffer[(short)(off + 1)]; // 长度 0x0C
		byte secParam = buffer[(short)(off + 2)]; // 安全参数

		// STMSI
		Util.arrayCopyNonAtomic(buffer, (short)(off + 3), stmsi, (short)0, (short)6);

		// data
		Util.arrayCopyNonAtomic(buffer, (short)(off + 9), location_data, (short)0, (short)5);

		// === 生成 fakedata ===
		encryptLocationZuc256(stmsi, location_data, location_res_data);

		// === 出参组装 ===
		buffer[(short)(off + 0)] = (byte)0xA1; // 类型
		buffer[(short)(off + 1)] = (byte)0x06; // 长度
		buffer[(short)(off + 2)] = (byte)0x01; // 密钥选取
		Util.arrayCopyNonAtomic(location_res_data, (short)0, buffer, (short)(off + 3), (short)5);

		return (short)8; // 出参总长度
	}



	public short updateKey(byte[] buffer, short off, short len, byte[] key_store) {
		final short SLOT_SIZE = 40; // 每个槽固定40字节
		final short HDR_LEN   = 4;  // 报文头长度: [0]=keyLenField, [1]=alg, [2]=keyId, [3]=ver

		// === 解析头 ===
		byte keyLenField = buffer[(short)(off + 0)]; // 包含头部+密钥的总长度
		byte alg   = buffer[(short)(off + 1)];
		byte keyId = buffer[(short)(off + 2)];
		byte ver   = buffer[(short)(off + 3)];

		// 计算实际密钥长度
		short realKeyLen = (short)(keyLenField - (byte)3); // 长度字段 = key长度 + 3字节头
		if (realKeyLen <= 0) {
			ISOException.throwIt(ISO7816.SW_DATA_INVALID); // key长度不合法
		}

		// 检查APDU长度和key长度是否匹配
		if (len != (short)(HDR_LEN + realKeyLen)) {
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		}
		if (len > SLOT_SIZE) {
			ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
		}

		// === 将原有 key_store 拷贝到 RAM，避免直接覆盖 EEPROM (可选) ===
		Util.arrayCopyNonAtomic(key_store, (short)0, update_key_buf, (short)0, (short)key_store.length);

		// === 遍历槽，找到匹配的 (alg, keyId, ver)，否则找空槽 ===
		short slots = (short)(key_store.length / SLOT_SIZE);
		short target = -1;
		for (short i = 0; i < slots; i++) {
			short base = (short)(i * SLOT_SIZE);
			byte algOld   = key_store[(short)(base + 1)];
			byte keyIdOld = key_store[(short)(base + 2)];
			byte verOld   = key_store[(short)(base + 3)];

			if (algOld == alg && keyId == keyIdOld && ver == verOld) {
				target = i; // 找到已存在的，覆盖它
				break;
			}
			if (key_store[base] == (byte)0x00 && target == -1) {
				target = i; // 找到第一个空槽
			}
		}

		if (target == -1) {
			ISOException.throwIt(ISO7816.SW_FILE_FULL); // 没有空位
		}

		// === 覆盖写入本次APDU的头+密钥数据 ===
		short base = (short)(target * SLOT_SIZE);
		// 先清空槽
		Util.arrayFillNonAtomic(key_store, base, SLOT_SIZE, (byte)0x00);
		// 再写入APDU传入的头+数据 (len 个字节)
		Util.arrayCopyNonAtomic(buffer, off, key_store, base, len);

		return 0; // 无返回数据
	}

	// === zuc256Util

//    /** 辅助方法：将字节数组转换为32位整数 */
//    public static int getU32(byte[] p, int offset) {
//        return ((p[offset] & 0xFF) << 24) |
//                ((p[offset + 1] & 0xFF) << 16) |
//                ((p[offset + 2] & 0xFF) << 8) |
//                (p[offset + 3] & 0xFF);
//    }
	/** 辅助方法：从字节数组取出 32 位整数，存放到 short[2] (lo, hi) */
	public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
		out32[0] = (short) (((p[(short)(offset + 2)] & 0xFF) << 8) | (p[(short)(offset + 3)] & 0xFF)); //低16位
		out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[(short)(offset + 1)] & 0xFF)); //高16位
	}


//    /** 辅助方法：将32位整数转换为字节数组 */
//    public static void putU32(byte[] p, int offset, int v) {
//        p[offset] = (byte) (v >> 24);
//        p[offset + 1] = (byte) (v >> 16);
//        p[offset + 2] = (byte) (v >> 8);
//        p[offset + 3] = (byte) v;
//    }
	/** 辅助方法：将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
	public static void putU32(byte[] p, short offset, short vlo, short vhi) {
		// 写高16位
		p[offset]     = (byte) ((vhi >> 8) & 0xFF);
		p[(short)(offset + 1)] = (byte) (vhi & 0xFF);

		// 写低16位
		p[(short)(offset + 2)] = (byte) ((vlo >> 8) & 0xFF);
		p[(short)(offset + 3)] = (byte) (vlo & 0xFF);
	}


	// === 31/32 位运算 ===

//    /** 31位加法 */
//    public static int add31(int a, int b) {
//        long sum = (long)a + b;
//        return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
//    }
	/** 31位加法: (a+b) mod (2^31 - 1)
	 * 输入: a_lo=低16位, a_hi=高15位
	 *      b_lo=低16位, b_hi=高15位
	 * 输出: out[0]=lo, out[1]=hi
	 */
	public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
		// ---- 低16位相加 ----
		short lo = (short)(a_lo + b_lo);
		short carry = (short)(
				( ( (short)( (a_lo & b_lo) | ((a_lo | b_lo) & (short)~lo) ) ) & (short)0x8000 ) != 0
						? 1 : 0
		);
		// ---- 高15位相加 + 进位 ----
		short hi_raw = (short)((short)((a_hi & 0x7FFF) + (b_hi & 0x7FFF)) + carry);

		// 提取第31位（hi_raw bit15）
		short topbit = (short)((hi_raw >>> 15) & 1);
		short hi = (short)(hi_raw & 0x7FFF); // 保留15位

		// ---- 若第31位=1，再+1 ----
		if (topbit == 1) {
			short lo2 = (short)(lo + 1);
			short c2 = (short)((lo2 == 0) ? 1 : 0); // lo溢出时进位
			lo = lo2;
			hi = (short)((hi + c2) & 0x7FFF);
		}

		out[0] = lo;
		out[1] = hi;
	}


//    /** 31位旋转 */
//    public static int rot31(int a, int k) {
//        return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
//    }
	/** 31位循环左移: (a <<< k) mod (2^31 -1)
	 * 输入: a_lo=低16位, a_hi=高15位
	 * 输出: out[0]=lo, out[1]=hi
	 */
	public void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
		k = (short)(k % 31); // 限制在 0..30
		if (k == 0) {
			out[0] = a_lo;
			out[1] = (short)(a_hi & 0x7FFF);
			return;
		}

		// 拆成 31 位数组 [bit0..bit30]
		for (short i = 0; i < 16; i++) {
			rot31_bits[i] = (short)((a_lo >>> i) & 1);
		}
		for (short i = 0; i < 15; i++) {
			rot31_bits[(short)(16 + i)] = (short)((a_hi >>> i) & 1);
		}

		// 旋转
		for (short i = 0; i < 31; i++) {
			short j = (short)((i + k) % 31);
			rot31_resBits[j] = rot31_bits[i];
		}

		// 拼回 lo, hi
		short lo = 0;
		for (short i = 0; i < 16; i++) {
			lo = (short)(lo | (rot31_resBits[i] << i));
		}
		short hi = 0;
		for (short i = 0; i < 15; i++) {
			hi = (short)(hi | (rot31_resBits[(short)(16 + i)] << i));
		}

		out[0] = lo;
		out[1] = hi;
	}


//    /** 32位旋转 */
//    public static int rot32(int a, int k) {
//        return (a << k) | (a >>> (32 - k));
//    }
	/** 32位循环左移: (a<<<k) */
	public static void rot32(short a_lo, short a_hi, short k, short[] out /*len==2*/) {
		k = (short)(k & 31);          // 0..31
		short lo = a_lo, hi = a_hi, nw_hi, nw_lo;
		while (k > 0) {
			// 先做 1 位循环左移
			// 注意：short 在 >>> 时会先提升为 int，所以下面都再用 &1 取最低位，避免符号扩展影响
			nw_hi = (short)((hi << 1) | ((lo >>> 15) & 1));
			nw_lo = (short)((lo << 1) | ((hi >>> 15) & 1));
			hi = nw_hi;
			lo = nw_lo;
			k--;
		}
		out[0] = lo;    // 低16位
		out[1] = hi;    // 高16位
	}


//    /**
//     * L1函数
//     */
//    public static int L1(int x) {
//        return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
//    }
	/**
	 * L1函数: x ^ (x<<<2) ^ (x<<<10) ^ (x<<<18) ^ (x<<<24)
	 * 输入:  x_lo, x_hi
	 * 输出: out[0]=lo, out[1]=hi
	 */
	public void L1(short x_lo, short x_hi, short[] out /*len==2*/) {

		// acc = x
		L1_acc[0] = x_lo;
		L1_acc[1] = x_hi;

		// acc ^= rot32(x, 2)
		rot32(x_lo, x_hi, (short)2, L1_t);
		L1_acc[0] ^= L1_t[0];
		L1_acc[1] ^= L1_t[1];

		// acc ^= rot32(x, 10)
		rot32(x_lo, x_hi, (short)10, L1_t);
		L1_acc[0] ^= L1_t[0];
		L1_acc[1] ^= L1_t[1];

		// acc ^= rot32(x, 18)
		rot32(x_lo, x_hi, (short)18, L1_t);
		L1_acc[0] ^= L1_t[0];
		L1_acc[1] ^= L1_t[1];

		// acc ^= rot32(x, 24)
		rot32(x_lo, x_hi, (short)24, L1_t);
		L1_acc[0] ^= L1_t[0];
		L1_acc[1] ^= L1_t[1];

		out[0] = L1_acc[0];
		out[1] = L1_acc[1];
	}


//    /**
//     * L2函数
//     */
//    public static int L2(int x) {
//        return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
//    }
	/**
	 * L2函数: x ^ (x<<<8) ^ (x<<<14) ^ (x<<<22) ^ (x<<<30)
	 * 输入:  x_lo, x_hi
	 * 输出: out[0]=lo, out[1]=hi
	 */
	public void L2(short x_lo, short x_hi, short[] out /*len==2*/) {

		// acc = x
		L2_acc[0] = x_lo;
		L2_acc[1] = x_hi;

		// acc ^= rot32(x, 8)
		rot32(x_lo, x_hi, (short)8, L2_t);
		L2_acc[0] ^= L2_t[0];
		L2_acc[1] ^= L2_t[1];

		// acc ^= rot32(x, 14)
		rot32(x_lo, x_hi, (short)14, L2_t);
		L2_acc[0] ^= L2_t[0];
		L2_acc[1] ^= L2_t[1];

		// acc ^= rot32(x, 22)
		rot32(x_lo, x_hi, (short)22, L2_t);
		L2_acc[0] ^= L2_t[0];
		L2_acc[1] ^= L2_t[1];

		// acc ^= rot32(x, 30)
		rot32(x_lo, x_hi, (short)30, L2_t);
		L2_acc[0] ^= L2_t[0];
		L2_acc[1] ^= L2_t[1];

		out[0] = L2_acc[0];
		out[1] = L2_acc[1];
	}


//    /** 创建31位无符号整数 */
//    public static int makeU31(int a, int b, int c, int d) {
//        return (((a & 0xFF) << 23) |
//                ((b & 0xFF) << 16) |
//                ((c & 0xFF) << 8) |
//                (d & 0xFF)) & 0x7FFFFFFF;
//    }
	/** 创建31位无符号整数，结果放到 out[0]=lo, out[1]=hi(15位) */
	public static void makeU31(short a, short b, short c, short d, short[] out /*len==2*/) {
		// 四个字节
		short b0 = (short)(a & 0xFF); // 最高字节
		short b1 = (short)(b & 0xFF);
		short b2 = (short)(c & 0xFF);
		short b3 = (short)(d & 0xFF); // 最低字节

		// 拼成 32 位: b0<<24 | b1<<16 | b2<<8 | b3
		// lo = 低16位
		out[0] = (short)((b2 << 8) | b3);

		// hi = 高15位（丢弃 bit31）
		out[1] = (short)((b0 << 7) | b1);
	}


//    /** 创建32位无符号整数 */
//    public static int makeU32(int a, int b, int c, int d) {
//        return ((a & 0xFF) << 24) |
//                ((b & 0xFF) << 16) |
//                ((c & 0xFF) << 8) |
//                (d & 0xFF);
//    }
	/** 创建32位无符号整数，结果放到 out[0]=lo, out[1]=hi */
	public static void makeU32(short a, short b, short c, short d, short[] out /*len==2*/) {
		// 四个字节
		short b0 = (short)(a & 0xFF); // 最高字节
		short b1 = (short)(b & 0xFF);
		short b2 = (short)(c & 0xFF);
		short b3 = (short)(d & 0xFF); // 最低字节

		// lo = 低16位
		out[0] = (short)((b2 << 8) | b3);

		// hi = 高16位
		out[1] = (short)((b0 << 8) | b1);
	}



	/** 提取IV */
	public void extractIv(byte[] input25Byte, byte[] output23Byte) {
		if (input25Byte == null || output23Byte == null) return;

		// 复制前17字节
		Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);


		// 处理剩余8字节
		for (short i = 0; i < 8; i++) {
			extract_iv_last8[i] = (byte) (input25Byte[(short)(17 + i)] & 0x3F);
		}

		output23Byte[17] = (byte) ((extract_iv_last8[0] << 2) | (extract_iv_last8[1] >>> 4));
		output23Byte[18] = (byte) (((extract_iv_last8[1] & 0x0F) << 4) | (extract_iv_last8[2] >>> 2));
		output23Byte[19] = (byte) (((extract_iv_last8[2] & 0x03) << 6) | extract_iv_last8[3]);
		output23Byte[20] = (byte) ((extract_iv_last8[4] << 2) | (extract_iv_last8[5] >>> 4));
		output23Byte[21] = (byte) (((extract_iv_last8[5] & 0x0F) << 4) | (extract_iv_last8[6] >>> 2));
		output23Byte[22] = (byte) (((extract_iv_last8[6] & 0x03) << 6) | extract_iv_last8[7]);
	}

	/**
	 * 32位加法: (a_hi:a_lo) + (b_hi:b_lo)
	 * out[0] = lo, out[1] = hi
	 */
	static void add32(short a_lo, short a_hi,
					  short b_lo, short b_hi,
					  short[] out /*len=2*/) {

		// ---- 低16位 ----
		short lo_low  = (short)((a_lo & 0x00FF) + (b_lo & 0x00FF));
		short carry0  = (short)(((a_lo & 0x00FF) + (b_lo & 0x00FF)) >>> 8);

		short a_lo_hi = (short)((a_lo >>> 8) & 0x00FF);
		short b_lo_hi = (short)((b_lo >>> 8) & 0x00FF);
		short lo_high = (short)(a_lo_hi + b_lo_hi + carry0);
		short carry1  = (short)(lo_high >>> 8);

		short lo_res  = (short)((lo_high << 8) | (lo_low & 0x00FF));

		// ---- 高16位 ----
		short hi_low  = (short)((a_hi & 0x00FF) + (b_hi & 0x00FF) + carry1);
		short carry2  = (short)(hi_low >>> 8);

		short a_hi_hi = (short)((a_hi >>> 8) & 0x00FF);
		short b_hi_hi = (short)((b_hi >>> 8) & 0x00FF);
		short hi_high = (short)(a_hi_hi + b_hi_hi + carry2);

		short hi_res  = (short)((hi_high << 8) | (hi_low & 0x00FF));

		// ---- 输出 ----
		out[0] = lo_res;
		out[1] = hi_res;
	}

	/**
	 * 32位加法 + 返回进位（只用 short）
	 * 输入: (a_hi:a_lo) + (b_hi:b_lo)
	 * 输出: out[0]=lo, out[1]=hi
	 * 返回: 最终进位(0/1)
	 */
	static short add32_with_carry(short a_lo, short a_hi,
								  short b_lo, short b_hi,
								  short[] out /* len=2 */) {
		// ---- 低16位：分两段8位相加 ----
		short s0 = (short)((a_lo & (short)0x00FF) + (b_lo & (short)0x00FF));   // 0..510
		short c0 = (short)(s0 >>> 8);                                          // 0/1
		short s1 = (short)(((a_lo >>> 8) & (short)0x00FF)
				+ ((b_lo >>> 8) & (short)0x00FF)
				+ c0);                                                // 0..511
		short c1 = (short)(s1 >>> 8);                                          // 0/1
		short lo = (short)((s1 << 8) | (s0 & (short)0x00FF));

		// ---- 高16位：再分两段8位相加，并加上 c1 ----
		short s2 = (short)((a_hi & (short)0x00FF) + (b_hi & (short)0x00FF) + c1);
		short c2 = (short)(s2 >>> 8);                                          // 0/1
		short s3 = (short)(((a_hi >>> 8) & (short)0x00FF)
				+ ((b_hi >>> 8) & (short)0x00FF)
				+ c2);                                                // 0..511
		short c3 = (short)(s3 >>> 8);                                          // 最终进位 0/1
		short hi = (short)((s3 << 8) | (s2 & (short)0x00FF));

		out[0] = lo;
		out[1] = hi;
		return (short)(c3 & 1);
	}



	/**
	 * 64位加法: a4 + b4 -> a4
	 * 输入输出: short[4]，低到高 (a[0]=lo16, a[1]=hi16, a[2]=lo16 of high dword, a[3]=hi16 of high dword)
	 */
	void add64(short[] a, short[] b) {

		// 低 32 位
		short carry = add32_with_carry(a[0], a[1], b[0], b[1], add64_tmp);
		a[0] = add64_tmp[0];
		a[1] = add64_tmp[1];

		// 高 32 位 + carry
		add32((short)(a[2] + (short)(carry & (short)0x0001)), a[3], b[2], b[3], add64_tmp);
		a[2] = add64_tmp[0];
		a[3] = add64_tmp[1];
	}



	// 32位异或
	public static void xor32(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /*len==2*/) {
		out[0] = (short)(a_lo ^ b_lo);
		out[1] = (short)(a_hi ^ b_hi);
	}

	/**
	 * 把32位数 b (b[0]=lo, b[1]=hi) 左移 k 位 (0 <= k < 32)，
	 * 结果放到64位数 a (a[0]=最低16位 ... a[3]=最高16位)。
	 */
	static void create_64b_from_32b(short[] a/*len=4*/, short[] b/*len=2*/, short k) {
		short a0 = b[0], a1 = b[1], a2 = 0, a3 = 0;

		if (k >= 16) {
			a3 = a2;       // 0
			a2 = a1;       // 原 hi16
			a1 = a0;       // 原 lo16
			a0 = 0;
			k  = (short)(k - 16);
		}

		while (k > 0) {
			short c0 = (short)((a0 >>> 15) & 1);
			short c1 = (short)((a1 >>> 15) & 1);
			short c2 = (short)((a2 >>> 15) & 1);

			a3 = (short)((a3 << 1) | c2);
			a2 = (short)((a2 << 1) | c1);
			a1 = (short)((a1 << 1) | c0);
			a0 = (short)(a0 << 1);
			k--;
		}

		a[0] = a0; a[1] = a1; a[2] = a2; a[3] = a3;
	}


	/**
	 * (A & 0x7FFFFFFF)，结果放在 out[4]，只保留低32位并清掉最高bit。
	 */
	static void and64_7FFFFFFF_to32(short[] A, short[] out) {
		out[0] = A[0];                       // lo16
		out[1] = (short)(A[1] & 0x7FFF);     // hi16 (清除最高bit)
		out[2] = 0;
		out[3] = 0;
	}

	/**
	 * 64位无符号右移 31 位
	 * 输入:  A[0..3] (short[4], A[0]最低16位)
	 * 输出:  out[0..3]
	 */
	static void shr64u_31(short[] A, short[] out) {
		// 先拼出 64bit 的逻辑，逐段右移
		// A >>> 31 = (A >>> 16) >>> 15

		// 先右移 16，相当于丢掉 A[0]，整体右移一半字
		out[0] = A[1];   // 原 A[1] -> 新低16位
		out[1] = A[2];   // 原 A[2]
		out[2] = A[3];   // 原 A[3]
		out[3] = 0;      // 高位补0

		// 再右移 15 位
		short c0 = (short)((out[0] & (short)0xFFFF) >>> 15);  // out[0] 最后一位变进位
		short c1 = (short)((out[1] & (short)0xFFFF) >>> 15);
		short c2 = (short)((out[2] & (short)0xFFFF) >>> 15);

		out[0] = (short)((c0 & 0x0001) | (out[1] << 1));
		out[1] = (short)((c1 & 0x0001) | (out[2] << 1));
		out[2] = (short)(c2 & 0x0001);
	}

	/**
	 * 32位无符号右移 1 位
	 * 输入:  lo,hi (short) 表示 32 位数 (hi:高16位, lo:低16位)
	 * 输出:  out[0]=lo, out[1]=hi
	 */
	static void shr32u1(short lo, short hi, short[] out) {
		// >>>1：先处理低16位
		short nwLo = (short)(((((lo & (short)0xFFFF) >>> 1) & (short)0x7FFF)) | ((hi & 0x0001) << 15));
		short nwHi = (short)(((hi & (short)0xFFFF) >>> 1) & (short)0x7FFF);

		out[0] = nwLo;
		out[1] = nwHi;
	}


	//===zuc256core

	/** 初始化状态（Key + IV） */
	public void initState(byte[] key32, byte[] iv) {
		zuc256SetMacKey(key32, iv, (short)0);
	}

	/** 生成单个密钥字 */
	public void zuc256GenerateKeyword(short[] out) {
//        int[] LFSR = state.LFSR;
//        int R1 = state.R1;
//        int R2 = state.R2;
//        int X0, X1, X2, X3;
//        int W1, W2, U, V;
//        int Z;



		// 载入 R1,R2
		zuc256GenerateKeyword_R1[0] = R1_lo;
		zuc256GenerateKeyword_R1[1] = R1_hi;
		zuc256GenerateKeyword_R2[0] = R2_lo;
		zuc256GenerateKeyword_R2[1] = R2_hi;


		// BitReconstruction4
		short c15 = (short)((LFSR_lo[15] & (short)0x8000) >>> 15);           // 左移产生的进位
		zuc256GenerateKeyword_X0[1] = (short)(((LFSR_hi[15] & (short)0x7FFF) << 1) | (short)(c15 & 0x0001));         // hi
		zuc256GenerateKeyword_X0[0] = LFSR_lo[14];                                          // lo

		// X1 = ((L11 & 0xFFFF) << 16) | (L9 >>> 15)
		zuc256GenerateKeyword_X1[1] = LFSR_lo[11];
		zuc256GenerateKeyword_X1[0] = (short)((((LFSR_lo[9] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[9] << 1));

		// X2 = ((L7 & 0xFFFF) << 16) | (L5 >>> 15)
		zuc256GenerateKeyword_X2[1] = LFSR_lo[7];
		zuc256GenerateKeyword_X2[0] = (short)((((LFSR_lo[5] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[5] << 1));

		// X3 = ((L2 & 0xFFFF) << 16) | (L0 >>> 15)
		zuc256GenerateKeyword_X3[1] = LFSR_lo[2];
		zuc256GenerateKeyword_X3[0] = (short)((((LFSR_lo[0] & (short)0x8000) >>> 15) & 0X0001) | (LFSR_hi[0] << 1));



		// ---- 输入：X0,X1,X2,X3,R1,R2 均为 short[2]; 输出：Z,W1,W2,U,V ----

		// Z = X3 ^ ((X0 ^ R1) + R2)
		xor32(zuc256GenerateKeyword_X0[0], zuc256GenerateKeyword_X0[1], zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_TMP0);        // TMP0 = X0 ^ R1
		add32(zuc256GenerateKeyword_TMP0[0],  zuc256GenerateKeyword_TMP0[1],  zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_TMP1);       // TMP1 = TMP0 + R2
		xor32(zuc256GenerateKeyword_X3[0], zuc256GenerateKeyword_X3[1], zuc256GenerateKeyword_TMP1[0], zuc256GenerateKeyword_TMP1[1], zuc256GenerateKeyword_Z);        // Z = X3 ^ TMP1

		// F_(X1, X2)
		// W1 = R1 + X1
		add32(zuc256GenerateKeyword_R1[0], zuc256GenerateKeyword_R1[1], zuc256GenerateKeyword_X1[0], zuc256GenerateKeyword_X1[1], zuc256GenerateKeyword_W1);

		// W2 = R2 ^ X2
		xor32(zuc256GenerateKeyword_R2[0], zuc256GenerateKeyword_R2[1], zuc256GenerateKeyword_X2[0], zuc256GenerateKeyword_X2[1], zuc256GenerateKeyword_W2);

		// U = L1((W1 << 16) | (W2 >>> 16))
		// (W1<<16):  lo=0,     hi=W1_lo
		// (W2>>>16): lo=W2_hi, hi=0
		// OR 结果：  lo=W2_hi, hi=W1_lo
		L1(zuc256GenerateKeyword_W2[1], zuc256GenerateKeyword_W1[0], zuc256GenerateKeyword_U);

		// V = L2((W2 << 16) | (W1 >>> 16))
		// (W2<<16):  lo=0,     hi=W2_lo
		// (W1>>>16): lo=W1_hi, hi=0
		// OR 结果：  lo=W1_hi, hi=W2_lo
		L2(zuc256GenerateKeyword_W1[1], zuc256GenerateKeyword_W2[0], zuc256GenerateKeyword_V);


//        R1 = makeU32(Zuc256Tables.S0[(U >>> 24) & 0xFF],
//                Zuc256Tables.S1[(U >>> 16) & 0xFF],
//                Zuc256Tables.S0[(U >>> 8) & 0xFF],
//                Zuc256Tables.S1[U & 0xFF]);
		makeU32(
				(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_U[1] >>> 8) & 0xFF)] & 0xFF),  // (U >>> 24) & 0xFF
				(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[1] & 0xFF)] & 0xFF),          // (U >>> 16) & 0xFF
				(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_U[0] >>> 8) & 0xFF)] & 0xFF),  // (U >>> 8)  & 0xFF
				(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_U[0] & 0xFF)] & 0xFF),          // (U >>> 0)  & 0xFF
				zuc256GenerateKeyword_R1);

//        R2 = makeU32(Zuc256Tables.S0[(V >>> 24) & 0xFF],
//                Zuc256Tables.S1[(V >>> 16) & 0xFF],
//                Zuc256Tables.S0[(V >>> 8) & 0xFF],
//                Zuc256Tables.S1[V & 0xFF]);
		makeU32(
				(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_V[1] >>> 8) & 0xFF)] & 0xFF),  // (V >>> 24) & 0xFF
				(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[1] & 0xFF)] & 0xFF),          // (V >>> 16) & 0xFF
				(short)(Zuc256Tables.S0[((zuc256GenerateKeyword_V[0] >>> 8) & 0xFF)] & 0xFF),  // (V >>> 8)  & 0xFF
				(short)(Zuc256Tables.S1[(zuc256GenerateKeyword_V[0] & 0xFF)] & 0xFF),          // (V >>> 0)  & 0xFF
				zuc256GenerateKeyword_R2);



//        // LFSRWithWorkMode
//        long a = LFSR[0];
//        a += (long)LFSR[0] << 8;
//        a += (long)LFSR[4] << 20;
//        a += (long)LFSR[10] << 21;
//        a += (long)LFSR[13] << 17;
//        a += (long)LFSR[15] << 15;
		// ---- 先准备累加器 A (64位) ----
		zuc256GenerateKeyword_A[0] = 0;
		zuc256GenerateKeyword_A[1] = 0;
		zuc256GenerateKeyword_A[2] = 0;
		zuc256GenerateKeyword_A[3] = 0;

		// 临时缓冲

		// a = LFSR[0]
		zuc256GenerateKeyword_tmp32[0] = LFSR_lo[0];
		zuc256GenerateKeyword_tmp32[1] = LFSR_hi[0];
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)0);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

		// a += (LFSR[0] << 8)
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)8);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

		// a += (LFSR[4] << 20)
		zuc256GenerateKeyword_tmp32[0] = LFSR_lo[4];
		zuc256GenerateKeyword_tmp32[1] = LFSR_hi[4];
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)20);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

		// a += (LFSR[10] << 21)
		zuc256GenerateKeyword_tmp32[0] = LFSR_lo[10];
		zuc256GenerateKeyword_tmp32[1] = LFSR_hi[10];
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)21);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

		// a += (LFSR[13] << 17)
		zuc256GenerateKeyword_tmp32[0] = LFSR_lo[13];
		zuc256GenerateKeyword_tmp32[1] = LFSR_hi[13];
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)17);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

		// a += (LFSR[15] << 15)
		zuc256GenerateKeyword_tmp32[0] = LFSR_lo[15];
		zuc256GenerateKeyword_tmp32[1] = LFSR_hi[15];
		create_64b_from_32b(zuc256GenerateKeyword_tmp64, zuc256GenerateKeyword_tmp32, (short)15);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_tmp64);

//        a = (a & 0x7FFFFFFF) + (a >>> 31);
		// ---- 第一次折叠：a = (a & 0x7FFFFFFF) + (a >>> 31) ----

		and64_7FFFFFFF_to32(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31);       // low31 = A & 0x7FFFFFFF
		shr64u_31(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31);          // r31   = A >>> 31

		zuc256GenerateKeyword_A[0]=0; zuc256GenerateKeyword_A[1]=0; zuc256GenerateKeyword_A[2]=0; zuc256GenerateKeyword_A[3]=0;
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_low31);
		add64(zuc256GenerateKeyword_A, zuc256GenerateKeyword_r31);
//        int v = (int) ((a & 0x7FFFFFFF) + (a >>> 31));
		// ---- 第二次折叠，得到 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;
	}
}
