119 lines
3.7 KiB
Java
119 lines
3.7 KiB
Java
package com.cscn;
|
||
|
||
/**
|
||
* 辅助工具:装载/存储、位运算、线性变换、打印等。
|
||
*/
|
||
public final class Zuc256Util {
|
||
|
||
private Zuc256Util() {}
|
||
|
||
/** 辅助方法:从字节数组取出 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位
|
||
putU16(p, offset, vhi);
|
||
// 写低16位
|
||
putU16(p, (short)(offset + 2), vlo);
|
||
}
|
||
|
||
/** 辅助方法:将16位整数(short)写入字节数组,高字节在前 */
|
||
public static void putU16(byte[] p, short offset, short v) {
|
||
p[offset] = (byte) ((v >> 8) & 0xFF);
|
||
p[offset + 1] = (byte) (v & 0xFF);
|
||
}
|
||
|
||
|
||
// === 31/32 位运算 ===
|
||
|
||
/** 31位加法 */
|
||
public static int add31(int a, int b) {
|
||
long sum = (long)a + b;
|
||
return (int) ((sum & 0x7FFFFFFF) + (sum >> 31));
|
||
}
|
||
|
||
/** 31位旋转 */
|
||
public static int rot31(int a, int k) {
|
||
return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF;
|
||
}
|
||
|
||
/** 32位旋转 */
|
||
public static int rot32(int a, int k) {
|
||
return (a << k) | (a >>> (32 - k));
|
||
}
|
||
|
||
/**
|
||
* L1函数
|
||
*/
|
||
public static int L1(int x) {
|
||
return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24);
|
||
}
|
||
|
||
/**
|
||
* L2函数
|
||
*/
|
||
public static int L2(int x) {
|
||
return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30);
|
||
}
|
||
|
||
/** 创建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;
|
||
}
|
||
|
||
/** 创建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);
|
||
}
|
||
|
||
|
||
/** 提取IV */
|
||
public static void extractIv(byte[] input25Byte, byte[] output23Byte) {
|
||
if (input25Byte == null || output23Byte == null) return;
|
||
|
||
// 复制前17字节
|
||
System.arraycopy(input25Byte, 0, output23Byte, 0, 17);
|
||
|
||
// 处理剩余8字节
|
||
byte[] src = new byte[8];
|
||
for (int 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();
|
||
}
|
||
}
|