位置加密applet基本实现,目录下包含c java参考代码、打包工具、说明文档、 #2
@@ -1,5 +1,7 @@
|
|||||||
package com.cscn;
|
package com.cscn;
|
||||||
|
|
||||||
|
import javacard.framework.Util;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
||||||
*/
|
*/
|
||||||
@@ -7,6 +9,13 @@ public final class Zuc256Util {
|
|||||||
|
|
||||||
private 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) */
|
/** 辅助方法:从字节数组取出 32 位整数,存放到 short[2] (lo, hi) */
|
||||||
public static void getU32(byte[] p, short offset, short[] out32 /* len=2 */) {
|
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[0] = (short) (((p[offset + 2] & 0xFF) << 8) | (p[offset + 3] & 0xFF)); //低16位
|
||||||
@@ -21,81 +30,286 @@ public final class Zuc256Util {
|
|||||||
// p[offset + 2] = (byte) (v >> 8);
|
// p[offset + 2] = (byte) (v >> 8);
|
||||||
// p[offset + 3] = (byte) v;
|
// p[offset + 3] = (byte) v;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
|
/** 辅助方法:将32位整数(vlo=低16位, vhi=高16位)写入字节数组 */
|
||||||
public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
public static void putU32(byte[] p, short offset, short vlo, short vhi) {
|
||||||
// 写高16位
|
// 写高16位
|
||||||
putU16(p, offset, vhi);
|
p[offset] = (byte) ((vhi >> 8) & 0xFF);
|
||||||
// 写低16位
|
p[offset + 1] = (byte) (vhi & 0xFF);
|
||||||
putU16(p, (short)(offset + 2), vlo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** 辅助方法:将16位整数(short)写入字节数组,高字节在前 */
|
// 写低16位
|
||||||
public static void putU16(byte[] p, short offset, short v) {
|
p[offset + 2] = (byte) ((vlo >> 8) & 0xFF);
|
||||||
p[offset] = (byte) ((v >> 8) & 0xFF);
|
p[offset + 3] = (byte) (vlo & 0xFF);
|
||||||
p[offset + 1] = (byte) (v & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// === 31/32 位运算 ===
|
// === 31/32 位运算 ===
|
||||||
|
|
||||||
/** 31位加法 */
|
// /** 31位加法 */
|
||||||
public static int add31(int a, int b) {
|
// public static int add31(int a, int b) {
|
||||||
long sum = (long)a + b;
|
// long sum = (long)a + b;
|
||||||
return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
// return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
||||||
}
|
// }
|
||||||
|
/** 31位加法: (a+b) mod (2^31 - 1)
|
||||||
/** 31位旋转 */
|
* 输入: a_lo=低16位, a_hi=高15位
|
||||||
public static int rot31(int a, int k) {
|
* b_lo=低16位, b_hi=高15位
|
||||||
return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
* 输出: out[0]=lo, out[1]=hi
|
||||||
}
|
|
||||||
|
|
||||||
/** 32位旋转 */
|
|
||||||
public static int rot32(int a, int k) {
|
|
||||||
return (a << k) | (a >>> (32 - k));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* L1函数
|
|
||||||
*/
|
*/
|
||||||
public static int L1(int x) {
|
public static void add31(short a_lo, short a_hi, short b_lo, short b_hi, short[] out /* len==2 */) {
|
||||||
return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
|
// ---- 低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;
|
||||||
* L2函数
|
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 int L2(int x) {
|
public static void rot31(short a_lo, short a_hi, short k, short[] out /* len==2 */) {
|
||||||
return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
k = (short)(k % 31); // 限制在 0..30
|
||||||
|
if (k == 0) {
|
||||||
|
out[0] = a_lo;
|
||||||
|
out[1] = (short)(a_hi & 0x7FFF);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 创建31位无符号整数 */
|
// 拆成 31 位数组 [bit0..bit30]
|
||||||
public static int makeU31(int a, int b, int c, int d) {
|
short[] bits = new short[31];
|
||||||
return (((a & 0xFF) << 23) |
|
for (short i = 0; i < 16; i++) {
|
||||||
((b & 0xFF) << 16) |
|
bits[i] = (short)((a_lo >>> i) & 1);
|
||||||
((c & 0xFF) << 8) |
|
}
|
||||||
(d & 0xFF)) & 0x7FFFFFFF;
|
for (short i = 0; i < 15; i++) {
|
||||||
|
bits[16 + i] = (short)((a_hi >>> i) & 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 创建32位无符号整数 */
|
// 旋转
|
||||||
public static int makeU32(int a, int b, int c, int d) {
|
short[] resBits = new short[31];
|
||||||
return ((a & 0xFF) << 24) |
|
for (short i = 0; i < 31; i++) {
|
||||||
((b & 0xFF) << 16) |
|
short j = (short)((i + k) % 31);
|
||||||
((c & 0xFF) << 8) |
|
resBits[j] = bits[i];
|
||||||
(d & 0xFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 拼回 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 */
|
/** 提取IV */
|
||||||
public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||||||
if (input25Byte == null || output23Byte == null) return;
|
if (input25Byte == null || output23Byte == null) return;
|
||||||
|
|
||||||
// 复制前17字节
|
// 复制前17字节
|
||||||
System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
Util.arrayCopyNonAtomic(input25Byte, (short)0, output23Byte, (short)0, (short)17);
|
||||||
|
|
||||||
|
|
||||||
// 处理剩余8字节
|
// 处理剩余8字节
|
||||||
byte[] src = new byte[8];
|
byte[] src = new byte[8];
|
||||||
for (int i = 0; i < 8; i++) {
|
for (short i = 0; i < 8; i++) {
|
||||||
src[i] = (byte) (input25Byte[17 + i] & 0x3F);
|
src[i] = (byte) (input25Byte[17 + i] & 0x3F);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,12 +321,12 @@ public final class Zuc256Util {
|
|||||||
output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 打印十六进制(调试用,TODO 生产/JC 环境可移除) */
|
/** 打印/*十六进制(调试用,TODO 生产/JC 环境可移除) *//*
|
||||||
public static void printHex(String label, byte[] data, int len) {
|
public static void printHex(String label, byte[] data, int len) {
|
||||||
System.out.print(label + ": ");
|
System.out.print(label + ": ");
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
System.out.printf("%02x ", data[i] & 0xFF);
|
System.out.printf("%02x ", data[i] & 0xFF);
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user