Files
se-algo/Project/Src/com/cscn/Zuc256EncryptCtx.java
2025-09-05 15:15:33 +08:00

132 lines
3.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.cscn;
import java.util.Arrays;
import static com.cscn.Zuc256Core.zuc256GenerateKeystream;
import static com.cscn.Zuc256Core.zuc256GenerateKeyword;
import static com.cscn.Zuc256Util.getU32;
import static com.cscn.Zuc256Util.putU32;
/**
* 加密上下文类
*/
public final class Zuc256EncryptCtx {
Zuc256State state;
byte[] buf;
int buflen;
public Zuc256EncryptCtx(Zuc256State state, byte[] buf){
this.state = state;
this.buf = buf;
}
public Zuc256EncryptCtx(Zuc256State state){
this.state = state;
this.buf = new byte[4];
}
public Zuc256EncryptCtx(){
this.state = new Zuc256State();
this.buf = new byte[4];
}
// 初始化加密上下文
public void init(byte[] key32, byte[] iv) {
Arrays.fill(this.buf, (byte) 0);
this.buflen = 0;
Zuc256Core.initState(this.state, key32, iv);
}
// 分阶段处理加密数据
public void update(byte[] in, int inlen, byte[] out) {
if (in == null || out == null || inlen == 0) return;
// 处理缓冲区中剩余的非4字节数据
if (this.buflen > 0) {
int need = 4 - this.buflen;
int copy = Math.min(inlen, need);
System.arraycopy(in, 0, this.buf, this.buflen, copy);
this.buflen += copy;
// 调整输入指针和长度
byte[] newIn = new byte[inlen - copy];
if (inlen - copy > 0) {
System.arraycopy(in, copy, newIn, 0, inlen - copy);
}
in = newIn;
inlen -= copy;
// 缓冲区已满处理一个完整的4字节块
if (this.buflen == 4) {
int keystream = zuc256GenerateKeyword(this.state);
int plain = getU32(this.buf, 0);
putU32(out, 0, plain ^ keystream);
this.buflen = 0;
Arrays.fill(this.buf, (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;
}
}
// 处理完整的4字节块
int fullBlocks = inlen / 4;
if (fullBlocks > 0) {
int[] keystream = new int[fullBlocks];
zuc256GenerateKeystream(this.state, fullBlocks, keystream);
// 逐块异或加密
for (int i = 0; i < fullBlocks; i++) {
int plain = getU32(in, i * 4);
putU32(out, i * 4, plain ^ keystream[i]);
}
// 调整输入指针和长度
int processed = fullBlocks * 4;
byte[] newIn = new byte[inlen - processed];
if (inlen - processed > 0) {
System.arraycopy(in, processed, newIn, 0, inlen - processed);
}
in = newIn;
inlen -= processed;
}
// 缓存剩余不足4字节的数据
if (inlen > 0) {
System.arraycopy(in, 0, this.buf, 0, inlen);
this.buflen = inlen;
}
}
// 完成加密处理
public void finish(byte[] out) {
if (this == null || out == null) return;
// 处理缓冲区中剩余的不足4字节数据
if (this.buflen > 0) {
int keystream = zuc256GenerateKeyword(this.state);
byte[] keystreamBytes = new byte[4];
putU32(keystreamBytes, 0, keystream);
// 逐字节异或
for (int i = 0; i < this.buflen; i++) {
out[i] = (byte) (this.buf[i] ^ keystreamBytes[i]);
}
}
// 清理上下文
Arrays.fill(this.buf, (byte) 0);
this.buflen = 0;
Arrays.fill(this.state.LFSR, 0);
this.state.R1 = 0;
this.state.R2 = 0;
}
}