Compare commits

...

8 Commits

Author SHA1 Message Date
zcy
4dcf92584c Merge remote-tracking branch 'origin/main' into zcy_dev_cap
# Conflicts:
#	Project/Src/com/cscn/Zuc256EncryptCtx.java
#	Project/Src/com/cscn/Zuc256Tables.java
#	src/com/zuc/zuc256/Zuc256MacCtx.java
#	src/com/zuc/zuc256/Zuc256State.java
2025-09-05 17:20:38 +08:00
qzh
8893172ea9 适配card short类型,取消int long 2025-09-05 16:40:12 +08:00
zcy
b331864cee Zuc256Util int运算改short 2025-09-05 16:25:32 +08:00
zcy
747ac56a68 移植中 2025-09-05 15:55:46 +08:00
zcy
2310d0aca1 初始化 2025-09-05 15:16:21 +08:00
zcy
e8b2fa9c65 初始化 2025-09-05 15:15:33 +08:00
zcy
5122f8eade gradle+jcdk 构建最精简applet 2025-09-03 20:57:53 +08:00
zcy
11c46c5557 Merge pull request 'zcy_dev 将单文件ZUC256拆分为多文件,并封装init update final 方法' (#1) from zcy_dev into main
Reviewed-on: https://59.110.142.199:3333/qzh/se-algo/pulls/1
2025-09-03 09:09:06 +00:00
740 changed files with 17595 additions and 1869 deletions

2
.gitignore vendored
View File

@@ -4,4 +4,6 @@ __pycache__
.vscode
*.class
/out/
/.gradle/
/.idea/
/Project/bin/

56
Bat/GenCap.bat Normal file
View File

@@ -0,0 +1,56 @@
@ECHO OFF
@REM SET PATH=""
@rem %JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Converter %*
SET _BUILD_DIR=%CD%
SET _PROJ_PATH="%_BUILD_DIR%\.."
SET _DELIVERY_PATH=%_BUILD_DIR%\Delivery
SET _SRC_PATH=%_PROJ_PATH%\Project\Src
SET _CAP_PATH=%_PROJ_PATH%\Project\bin\com\cscn\javacard
SET _OUT_PATH=%_PROJ_PATH%\Project\bin
SET _TOOLS_PATH=%_PROJ_PATH%\Tools
CD ..\Project
DEL /Q %_DELIVERY_PATH%\*.*
DEL /Q %_CAP_PATH%\*.*
RMDIR /S /Q %_OUT_PATH%
MKDIR %_OUT_PATH%
REM PAUSE
SET JAVA_HOME=%_TOOLS_PATH%\jdk1.5.0_19
SET JC_HOME=%_TOOLS_PATH%\jcdk222
SET PATH=%JAVA_HOME%\bin;%JC_HOME%\bin;%PATH%
SET EXT_API_PATH=%_TOOLS_PATH%\ext_api
SET _JavaC_HOME=%_TOOLS_PATH%\jdk1.5.0_19\jre\bin
SET _CLASS_PATH=%_TOOLS_PATH%\jcdk222\lib\api.jar;%EXT_API_PATH%\gp221.jar
SET JCDK_EXPORT_DIR=%_TOOLS_PATH%\api_exp\JCDK222
SET PROJ_EXPORT_DIR=%_OUT_PATH%
SET EXT_EXPORT_DIR=%_TOOLS_PATH%\api_exp\gp221
SET EXPORT_DIR=%JCDK_EXPORT_DIR%;%PROJ_EXPORT_DIR%;%EXT_EXPORT_DIR%
REM COMPILE JAVA TO CLASS
ECHO **********************************************
ECHO *** Compile Java Source Code ***
ECHO **********************************************
ECHO Setting Build Path
REM use <-verbose> display compile info
REM SET COMPILE_PARAM=-nowarn -verbose
SET COMPILE_PARAM= -nowarn
ECHO Compiling Java Card API source code
Call javac %COMPILE_PARAM% -classpath %_CLASS_PATH% %_SRC_PATH%\*.java -d %_OUT_PATH% -g
ECHO **********************************************
ECHO *** Convert Java Card Assembly File ***
ECHO **********************************************
CALL converter -nowarn -i -classdir .\bin -exportpath %EXPORT_DIR% -out EXP CAP -applet 0xA0:0x00:0x00:0x03:0x00:0x73:0x74:0x61:0x72:0x2E:0x61:0x70:0x70 com.cscn.XwSecurity com.cscn 0xA0:0x00:0x00:0x03:0x00:0x73:0x74:0x61:0x72:0x2E:0x70:0x6B:0x67 1.0
ECHO **********************************************
ECHO *** Copy Exp and Cap File ***
ECHO **********************************************
COPY %_CAP_PATH%\*.* %_BUILD_DIR%\Delivery\
PAUSE

18
LICENSE
View File

@@ -1,18 +0,0 @@
MIT License
Copyright (c) 2025 gj
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,19 @@
package com.cscn;
import javacard.framework.APDU;
public class Method {
public void processData(APDU apdu)
{
// TODO Auto-generated method stub
}
public void updateKey(APDU apdu)
{
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,82 @@
/**
*
*/
package com.cscn;
import javacard.framework.APDU;
import javacard.framework.Applet;
import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import org.globalplatform.GPSystem;
import org.globalplatform.SecureChannel;
/**
* @author liuww
*
*/
public class XwSecurity extends Applet {
public static final byte INS_PROCESS_DATA = (byte)0xCA;
public static final byte INS_STORE_DATA = (byte)0xE2;
public static final byte INS_INITIAL_UPDATE = (byte)0x50;
public static final byte INS_EXTERNAL_AUTH = (byte)0x82;
private Method method;
public XwSecurity(byte[] bArray, short bOffset, byte bLength) {
// TODO Auto-generated constructor stub
method = new Method();
register(bArray, (short)(bOffset + 1), bArray[bOffset]);
}
public static void install(byte[] bArray, short bOffset, byte bLength)
{
// GP-compliant JavaCard applet registration
new XwSecurity(bArray, bOffset, bLength);
}
public void process(APDU apdu)
{
// Good practice: Return 9000 on SELECT
if(selectingApplet())
{
return;
}
if(method == null) {
return;
}
byte[] buf = apdu.getBuffer();
switch (buf[ISO7816.OFFSET_INS])
{
case INS_INITIAL_UPDATE:
SecureChannel sc = GPSystem.getSecureChannel();
sc.processSecurity(apdu);
break;
case INS_EXTERNAL_AUTH:
sc = GPSystem.getSecureChannel();
sc.processSecurity(apdu);
break;
case INS_PROCESS_DATA:
method.processData(apdu);
break;
case INS_STORE_DATA:
method.updateKey(apdu);
break;
default:
// good practice: If you don't know the INStruction, say so:
ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
}
}
}

View File

@@ -1,12 +1,14 @@
package com.zuc.zuc256;
package com.cscn;
import static com.zuc.zuc256.Zuc256Util.L1;
import static com.zuc.zuc256.Zuc256Util.L2;
import static com.zuc.zuc256.Zuc256Util.add31;
import static com.zuc.zuc256.Zuc256Util.makeU31;
import static com.zuc.zuc256.Zuc256Util.makeU32;
import static com.zuc.zuc256.Zuc256Util.rot31;
import static com.cscn.Zuc256Util.L1;
import static com.cscn.Zuc256Util.L2;
import static com.cscn.Zuc256Util.add31;
import static com.cscn.Zuc256Util.add31_pair;
import static com.cscn.Zuc256Util.makeU31;
import static com.cscn.Zuc256Util.makeU32;
import static com.cscn.Zuc256Util.rot31;
import static com.cscn.Zuc256Util.rot31_pair;
/**
* ZUC-256 核心状态初始化密钥字生成密钥流生成

View File

@@ -0,0 +1,66 @@
//package com.cscn;
//
///**
// * 演示主函数
// */
//public final class Zuc256Demo {
//
// public static void main(String[] args) {
// // 1. 明文
// byte[] plaintext = "ZUC256对称加解密测试:1234567890".getBytes();
// int plaintextLen = plaintext.length;
// System.out.println("明文: " + new String(plaintext));
// printHex("明文(十六进制)", plaintext, plaintextLen);
//
// // 2. 密钥(32字节ASCII)
// byte[] key = "0123456789abcdef0123456789abcdef".getBytes();
// printHex("密钥", key, 32);
//
// // 3. 初始向量(25字节ASCII)
// byte[] inputIv25Byte = "0123456789abcdefg01234567".getBytes();
// byte[] iv = new byte[23];
// extractIv(inputIv25Byte, iv);
// printHex("提取后的IV", iv, 23);
//
// // 4. 分配加密/解密缓冲区
// byte[] ciphertext = new byte[plaintextLen];
// byte[] decryptedtext = new byte[plaintextLen];
//
// // 5. 加密
// Zuc256State stateEnc = new Zuc256State();
// Zuc256Core.initState(stateEnc, key, iv);
// zuc256Crypt(stateEnc, plaintext, plaintextLen, ciphertext);
// printHex("密文", ciphertext, plaintextLen);
//
// // 6. 解密(重新初始化状态)
// Zuc256State stateDec = new Zuc256State();
// Zuc256Core.initState(stateDec, key, iv);
// zuc256Crypt(stateDec, ciphertext, plaintextLen, decryptedtext);
// printHex("解密后", decryptedtext, plaintextLen);
// System.out.println("解密文本: " + new String(decryptedtext));
//
// // 7. 验证结果
// if (Arrays.equals(plaintext, decryptedtext)) {
// System.out.println("=== 测试成功: 解密结果与明文一致 ===");
// } else {
// System.out.println("=== 测试失败: 解密结果与明文不一致 ===");
// }
// }
//
// // 一次性加密
// public static void zuc256Crypt(Zuc256State state, byte[] in, int inlen, byte[] out) {
// if (state == null || in == null || out == null) return;
//
// Zuc256EncryptCtx ctx = new Zuc256EncryptCtx(state);
//
// // 执行加解密
// ctx.update(in, inlen, out);
// int remainingOffset = (inlen / 4) * 4;
// byte[] finishOut = new byte[out.length - remainingOffset];
// if (finishOut.length > 0) {
// System.arraycopy(out, remainingOffset, finishOut, 0, finishOut.length);
// }
// ctx.finish(finishOut);
// System.arraycopy(finishOut, 0, out, remainingOffset, finishOut.length);
// }
//}

View File

@@ -0,0 +1,141 @@
package com.zuc.zuc256;
import javacard.framework.JCSystem;
import javacard.framework.Util;
/**
* 加密上下文类Java Card兼容版本
*/
public final class Zuc256EncryptCtx {
Zuc256State state;
byte[] buf;
short buflen;
// 构造函数 - 使用已分配的缓冲区
public Zuc256EncryptCtx(Zuc256State state, byte[] buf) {
this.state = state;
this.buf = buf;
this.buflen = 0;
}
// 构造函数 - 自动分配缓冲区
public Zuc256EncryptCtx(Zuc256State state) {
this.state = state;
this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.CLEAR_ON_DESELECT);
this.buflen = 0;
}
// 构造函数 - 完整初始化
public Zuc256EncryptCtx() {
this.state = new Zuc256State();
this.buf = JCSystem.makeTransientByteArray((short)4, JCSystem.CLEAR_ON_DESELECT);
this.buflen = 0;
}
// 初始化加密上下文
public void init(byte[] key32, short keyOff, short keyLen, byte[] iv, short ivOff, short ivLen) {
// 清空缓冲区
Util.arrayFillNonAtomic(buf, (short)0, (short)buf.length, (byte)0);
this.buflen = 0;
// 初始化状态
Zuc256Core.initState(this.state, key32, keyOff, keyLen, iv, ivOff, ivLen);
}
// 分阶段处理加密数据
public void update(byte[] in, short inOff, short inlen, byte[] out, short outOff) {
if (in == null || out == null || inlen == 0) return;
short currentInOff = inOff;
short currentOutOff = outOff;
// 处理缓冲区中剩余的非4字节数据
if (this.buflen > 0) {
short need = (short)(4 - this.buflen);
short copy = (short)Math.min(inlen, need);
// 复制数据到缓冲区
Util.arrayCopyNonAtomic(in, currentInOff, this.buf, this.buflen, copy);
this.buflen += copy;
// 调整输入指针和长度
currentInOff += copy;
inlen -= copy;
// 缓冲区已满处理一个完整的4字节块
if (this.buflen == 4) {
short keystream = zuc256GenerateKeyword(this.state);
short plain = getU16(this.buf, (short)0); // 改为16位操作
putU16(out, currentOutOff, (short)(plain ^ keystream));
// 重置缓冲区
this.buflen = 0;
Util.arrayFillNonAtomic(this.buf, (short)0, (short)this.buf.length, (byte)0);
// 调整输出指针
currentOutOff += 2; // 16位数据占2字节
}
}
// 处理完整的2字节块Java Card 16位操作
if (inlen > 0) {
short fullBlocks = (short)(inlen / 2); // 16位块
if (fullBlocks > 0) {
short[] keystream = JCSystem.makeTransientShortArray(fullBlocks, JCSystem.CLEAR_ON_DESELECT);
zuc256GenerateKeystream(this.state, fullBlocks, keystream);
// 逐块异或加密
for (short i = 0; i < fullBlocks; i++) {
short plain = getU16(in, (short)(currentInOff + (short)(i * 2)));
putU16(out, (short)(currentOutOff + (short)(i * 2)), (short)(plain ^ keystream[i]));
}
// 调整输入指针和长度
short processed = (short)(fullBlocks * 2);
currentInOff += processed;
inlen -= processed;
}
// 缓存剩余不足2字节的数据
if (inlen > 0) {
Util.arrayCopyNonAtomic(in, currentInOff, this.buf, (short)0, inlen);
this.buflen = inlen;
}
}
}
// 完成加密处理
public void finish(byte[] out, short outOff) {
if (out == null) return;
// 处理缓冲区中剩余的不足2字节数据
if (this.buflen > 0) {
short keystream = zuc256GenerateKeyword(this.state);
byte[] keystreamBytes = JCSystem.makeTransientByteArray((short)2, JCSystem.CLEAR_ON_DESELECT);
putU16(keystreamBytes, (short)0, keystream);
// 逐字节异或
for (short i = 0; i < this.buflen; i++) {
out[(short)(outOff + i)] = (byte)(this.buf[i] ^ keystreamBytes[i]);
}
}
// 清理上下文
Util.arrayFillNonAtomic(this.buf, (short)0, (short)this.buf.length, (byte)0);
this.buflen = 0;
// 清理状态
Util.arrayFillNonAtomic(this.state.LFSR, (short)0, (short)this.state.LFSR.length, (short)0);
this.state.R1 = 0;
this.state.R2 = 0;
}
// 16位数据读取替代原32位实现
private short getU16(byte[] buf, short off) {
return (short)(((buf[off] & 0xFF) << 8) | (buf[(short)(off + 1)] & 0xFF));
}
// 16位数据写入替代原32位实现
private void putU16(byte[] buf, short off, short value) {
buf[off] = (byte)((value >>> 8) & 0xFF);
buf[(short)(off + 1)] = (byte)(value & 0xFF);
}
}

View File

@@ -0,0 +1,31 @@
package com.cscn;
/**
* MAC上下文类JavaCard版int 拆分为两个 short
*/
public final class Zuc256MacCtx {
// LFSR: 原本 int[16],拆成 hi/lo 各 16 short
short[] LFSR_hi = new short[16];
short[] LFSR_lo = new short[16];
// R1、R2: 原本 int拆成 hi/lo
short R1_hi;
short R1_lo;
short R2_hi;
short R2_lo;
// 缓冲区
byte[] buf = new byte[4];
short buflen;
// T: 原本 int[4],拆成 hi/lo
short[] T_hi = new short[4];
short[] T_lo = new short[4];
// K0: 原本 int[4],拆成 hi/lo
short[] K0_hi = new short[4];
short[] K0_lo = new short[4];
// macbits: 原本 int改成 short 足够
short macbits;
}

View File

@@ -0,0 +1,16 @@
package com.cscn;
/**
* ZUC状态类JavaCard版int 拆为 hi/lo short
*/
public final class Zuc256State {
// LFSR: 原 int[16] -> hi/lo 各 16
public short[] LFSR_hi = new short[16];
public short[] LFSR_lo = new short[16];
// R1, R2: 原 int -> hi/lo
public short R1_hi;
public short R1_lo;
public short R2_hi;
public short R2_lo;
}

View File

@@ -1,15 +1,17 @@
package com.zuc.zuc256;
package com.cscn;
/**
* 常量表S0/S1 ZUC256_D
* 注意JavaCard 目标环境建议将表定义为 static final 数组 int/short 存放
* 适配说明已将 32bit int 数组改为 16bit short 数组符合JavaCard 16bit能力要求
*/
public final class Zuc256Tables {
// 私有构造函数防止类被实例化
private Zuc256Tables() {}
// S盒S0, S1
public static final int[] S0 = {
public static final short[] S0 = {
0x3e,0x72,0x5b,0x47,0xca,0xe0,0x00,0x33,0x04,0xd1,0x54,0x98,0x09,0xb9,0x6d,0xcb,
0x7b,0x1b,0xf9,0x32,0xaf,0x9d,0x6a,0xa5,0xb8,0x2d,0xfc,0x1d,0x08,0x53,0x03,0x90,
0x4d,0x4e,0x84,0x99,0xe4,0xce,0xd9,0x91,0xdd,0xb6,0x85,0x48,0x8b,0x29,0x6e,0xac,
@@ -28,7 +30,7 @@ public final class Zuc256Tables {
0x8d,0x27,0x1a,0xdb,0x81,0xb3,0xa0,0xf4,0x45,0x7a,0x19,0xdf,0xee,0x78,0x34,0x60
};
public static final int[] S1 = {
public static final short[] S1 = {
0x55,0xc2,0x63,0x71,0x3b,0xc8,0x47,0x86,0x9f,0x3c,0xda,0x5b,0x29,0xaa,0xfd,0x77,
0x8c,0xc5,0x94,0x0c,0xa6,0x1a,0x13,0x00,0xe3,0xa8,0x16,0x72,0x40,0xf9,0xf8,0x42,
0x44,0x26,0x68,0x96,0x81,0xd9,0x45,0x3e,0x10,0x76,0xc6,0xa7,0x8b,0x39,0x43,0xe1,
@@ -48,12 +50,12 @@ public final class Zuc256Tables {
};
/**
* 常量数组 D
* 常量数组 D16bit short二维数组适配
*/
public static final int[][] ZUC256_D = {
public static final short[][] ZUC256_D = {
{0x22,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
{0x22,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
{0x23,0x2F,0x24,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30},
{0x23,0x2F,0x25,0x2A,0x6D,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x52,0x10,0x30}
};
}
}

View File

@@ -0,0 +1,332 @@
package com.cscn;
import javacard.framework.Util;
/**
* 辅助工具:装载/存储、位运算、线性变换、打印等。
*/
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[offset + 2] & 0xFF) << 8) | (p[offset + 3] & 0xFF)); //低16位
out32[1] = (short) (((p[offset] & 0xFF) << 8) | (p[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[offset + 1] = (byte) (vhi & 0xFF);
// 写低16位
p[offset + 2] = (byte) ((vlo >> 8) & 0xFF);
p[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)(((lo & 0xFFFF) < (a_lo & 0xFFFF)) ? 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 = new short[31];
for (short i = 0; i < 16; i++) {
bits[i] = (short)((a_lo >>> i) & 1);
}
for (short i = 0; i < 15; i++) {
bits[16 + i] = (short)((a_hi >>> i) & 1);
}
// 旋转
short[] resBits = new short[31];
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[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
if (k == 0) {
out[0] = a_lo;
out[1] = a_hi;
return;
}
short lo, hi;
if (k < 16) {
// 左移 k
lo = (short)(a_lo << k);
hi = (short)(a_hi << k);
// 把溢出部分拼接
lo |= (short)((a_hi & 0xFFFF) >>> (16 - k));
hi |= (short)((a_lo & 0xFFFF) >>> (16 - k));
} else {
short s = (short)(k - 16);
lo = (short)(a_hi << s);
hi = (short)(a_lo << s);
lo |= (short)((a_lo & 0xFFFF) >>> (16 - s));
hi |= (short)((a_hi & 0xFFFF) >>> (16 - s));
}
out[0] = lo;
out[1] = hi;
}
// /**
// * 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 = new short[2];
short[] acc = new short[2];
// 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 = new short[2];
short[] acc = new short[2];
// 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 & 0x7F) << 8) | 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 = new byte[8];
for (short i = 0; i < 8; i++) {
src[i] = (byte) (input25Byte[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]);
}
/** 打印/*十六进制调试用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();
}*/
}

View File

@@ -1,40 +0,0 @@
import os
from SCons.Script import *
# 导入环境
Import('env')
# 项目根目录
CWD = os.getcwd()
# 收集源码(.c 和 .S 文件)
sources = Glob(os.path.join(CWD, 'src/*.c')) + Glob(os.path.join(CWD, 'src/*.S'))
# 编译选项
cpppath = [
CWD,
os.path.join(CWD, 'inc'), # 仅使用项目内的头文件目录
]
# 确保 build 目录存在
BUILD_DIR = 'build'
if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR)
# 逐个编译源码生成目标文件(输出到 build 目录)
objs = []
for src in sources:
src_path = str(src) # 转换为字符串路径
obj_name = os.path.basename(src_path).replace('.c', '.o').replace('.S', '.o')
obj_path = os.path.join(CWD, BUILD_DIR, obj_name)
obj = env.Object(
target=obj_path,
source=src_path,
CPPPATH=cpppath,
)
objs.append(obj)
# 返回目标文件列表,给 SConstruct 链接用
Return('objs')

View File

@@ -1,47 +0,0 @@
import os
from SCons.Script import *
# 确保 build 目录存在
BUILD_DIR = 'build'
if not os.path.exists(BUILD_DIR):
os.makedirs(BUILD_DIR)
# 导入配置(修改为导入algo.py)
from algo import *
# 初始化构建环境
env = Environment(
tools=['default'],
CC=CC,
CXX=CXX,
AS=AS,
AR=AR,
LINK=LINK,
CCFLAGS=CFLAGS,
CXXFLAGS=CFLAGS,
ASFLAGS=AFLAGS,
LINKFLAGS=LFLAGS,
CPPPATH=['inc'], # 仅使用项目内的头文件目录
)
# 递归构建源码(SConscript 负责收集编译文件)
src_objs = env.SConscript('SConscript', exports='env')
# 链接生成 elf 文件(输出到 build 目录)
elf_target = os.path.join(BUILD_DIR, TARGET_NAME)
elf_file = env.Program(elf_target, src_objs)
# 后处理:生成 bin、asm 等文件
post_commands = env.Command(
os.path.join(BUILD_DIR, 'post_actions'), # 虚拟目标,确保命令执行
elf_file,
POST_ACTION
)
# 关联默认构建目标(执行 scons 时默认编译+后处理)
Default(elf_file)
Default(post_commands)
# 清理规则(删除 build 目录及内容)
Clean(elf_file, BUILD_DIR)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Tools/ext_api/gp221.jar Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.apdutool.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.capdump.CapDump %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.jcasm.cap.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Converter %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

BIN
Tools/jcdk222/bin/cref.exe Normal file

Binary file not shown.

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.converter.Exp2Text %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.jcwde.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

Binary file not shown.

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.scriptgen.Main %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.Verifier %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.VerifyExp %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

View File

@@ -0,0 +1,25 @@
@echo off
REM
REM Copyright 2005 Sun Microsystems, Inc. All rights reserved.
REM Use is subject to license terms.
REM
if "%OS%" == "Windows_NT" setlocal
if not "%JAVA_HOME%" == "" goto check_tool
echo Please set the JAVA_HOME environment variable.
goto end
:check_tool
if not "%JC_HOME%" == "" goto doit
echo Please set the JC_HOME environment variable.
goto end
:doit
set _CLASSES=%JC_HOME%\lib\apduio.jar;%JC_HOME%\lib\apdutool.jar;%JC_HOME%\lib\jcwde.jar;%JC_HOME%\lib\converter.jar;%JC_HOME%\lib\scriptgen.jar;%JC_HOME%\lib\offcardverifier.jar;%JC_HOME%\lib\api.jar;%JC_HOME%\lib\installer.jar;%JC_HOME%\lib\capdump.jar;%JC_HOME%\samples\classes;%CLASSPATH%;
%JAVA_HOME%\bin\java -classpath %_CLASSES% com.sun.javacard.offcardverifier.VerifyRev %*
goto end
:end
if "%OS%" == "Windows_NT" endlocal

Binary file not shown.

Binary file not shown.

BIN
Tools/jcdk222/lib/api.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Tools/jcdk222/lib/jcwde.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More