what-the-bank/sources/org/bouncycastle/crypto/engines/NoekeonEngine.java

186 lines
6.5 KiB
Java
Raw Permalink Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.crypto.engines;
import com.google.common.base.Ascii;
import com.google.common.primitives.UnsignedBytes;
import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.crypto.OutputLengthException;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.tls.CipherSuite;
/* loaded from: classes6.dex */
public class NoekeonEngine implements BlockCipher {
private static final int genericSize = 16;
private static final int[] nullVector = {0, 0, 0, 0};
private static final int[] roundConstants = {128, 27, 54, 108, 216, CipherSuite.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, 77, CipherSuite.TLS_DHE_RSA_WITH_SEED_CBC_SHA, 47, 94, 188, 99, 198, 151, 53, 106, 212};
private boolean _forEncryption;
private int[] state = new int[4];
private int[] subKeys = new int[4];
private int[] decryptKeys = new int[4];
private boolean _initialised = false;
private int rotl(int i, int i2) {
return (i << i2) | (i >>> (32 - i2));
}
@Override // org.bouncycastle.crypto.BlockCipher
public int getBlockSize() {
return 16;
}
@Override // org.bouncycastle.crypto.BlockCipher
public void reset() {
}
@Override // org.bouncycastle.crypto.BlockCipher
public int processBlock(byte[] bArr, int i, byte[] bArr2, int i2) {
if (!this._initialised) {
StringBuilder sb = new StringBuilder();
sb.append(getAlgorithmName());
sb.append(" not initialised");
throw new IllegalStateException(sb.toString());
}
if (i + 16 > bArr.length) {
throw new DataLengthException("input buffer too short");
}
if (i2 + 16 <= bArr2.length) {
return this._forEncryption ? encryptBlock(bArr, i, bArr2, i2) : decryptBlock(bArr, i, bArr2, i2);
}
throw new OutputLengthException("output buffer too short");
}
@Override // org.bouncycastle.crypto.BlockCipher
public void init(boolean z, CipherParameters cipherParameters) {
if (!(cipherParameters instanceof KeyParameter)) {
StringBuilder sb = new StringBuilder("invalid parameter passed to Noekeon init - ");
sb.append(cipherParameters.getClass().getName());
throw new IllegalArgumentException(sb.toString());
}
this._forEncryption = z;
this._initialised = true;
setKey(((KeyParameter) cipherParameters).getKey());
}
@Override // org.bouncycastle.crypto.BlockCipher
public String getAlgorithmName() {
return "Noekeon";
}
private void theta(int[] iArr, int[] iArr2) {
int i = iArr[0] ^ iArr[2];
int rotl = i ^ (rotl(i, 8) ^ rotl(i, 24));
iArr[1] = iArr[1] ^ rotl;
iArr[3] = rotl ^ iArr[3];
for (int i2 = 0; i2 < 4; i2++) {
iArr[i2] = iArr[i2] ^ iArr2[i2];
}
int i3 = iArr[1] ^ iArr[3];
int rotl2 = i3 ^ (rotl(i3, 8) ^ rotl(i3, 24));
iArr[0] = iArr[0] ^ rotl2;
iArr[2] = rotl2 ^ iArr[2];
}
private void setKey(byte[] bArr) {
this.subKeys[0] = bytesToIntBig(bArr, 0);
this.subKeys[1] = bytesToIntBig(bArr, 4);
this.subKeys[2] = bytesToIntBig(bArr, 8);
this.subKeys[3] = bytesToIntBig(bArr, 12);
}
private void pi2(int[] iArr) {
iArr[1] = rotl(iArr[1], 31);
iArr[2] = rotl(iArr[2], 27);
iArr[3] = rotl(iArr[3], 30);
}
private void pi1(int[] iArr) {
iArr[1] = rotl(iArr[1], 1);
iArr[2] = rotl(iArr[2], 5);
iArr[3] = rotl(iArr[3], 2);
}
private void intToBytesBig(int i, byte[] bArr, int i2) {
bArr[i2] = (byte) (i >>> 24);
bArr[i2 + 1] = (byte) (i >>> 16);
bArr[i2 + 2] = (byte) (i >>> 8);
bArr[i2 + 3] = (byte) i;
}
private void gamma(int[] iArr) {
int i = iArr[1];
int i2 = iArr[3];
int i3 = iArr[2];
int i4 = i ^ ((~i2) & (~i3));
iArr[1] = i4;
int i5 = iArr[0] ^ (i3 & i4);
iArr[0] = i5;
iArr[3] = i5;
iArr[0] = i2;
int i6 = ((i2 ^ i4) ^ i5) ^ i3;
iArr[2] = i6;
int i7 = i4 ^ ((~i5) & (~i6));
iArr[1] = i7;
iArr[0] = (i6 & i7) ^ i2;
}
private int encryptBlock(byte[] bArr, int i, byte[] bArr2, int i2) {
this.state[0] = bytesToIntBig(bArr, i);
this.state[1] = bytesToIntBig(bArr, i + 4);
this.state[2] = bytesToIntBig(bArr, i + 8);
this.state[3] = bytesToIntBig(bArr, i + 12);
int i3 = 0;
while (i3 < 16) {
int[] iArr = this.state;
iArr[0] = iArr[0] ^ roundConstants[i3];
theta(iArr, this.subKeys);
pi1(this.state);
gamma(this.state);
pi2(this.state);
i3++;
}
int[] iArr2 = this.state;
iArr2[0] = roundConstants[i3] ^ iArr2[0];
theta(iArr2, this.subKeys);
intToBytesBig(this.state[0], bArr2, i2);
intToBytesBig(this.state[1], bArr2, i2 + 4);
intToBytesBig(this.state[2], bArr2, i2 + 8);
intToBytesBig(this.state[3], bArr2, i2 + 12);
return 16;
}
private int decryptBlock(byte[] bArr, int i, byte[] bArr2, int i2) {
this.state[0] = bytesToIntBig(bArr, i);
this.state[1] = bytesToIntBig(bArr, i + 4);
this.state[2] = bytesToIntBig(bArr, i + 8);
this.state[3] = bytesToIntBig(bArr, i + 12);
int[] iArr = this.subKeys;
System.arraycopy(iArr, 0, this.decryptKeys, 0, iArr.length);
theta(this.decryptKeys, nullVector);
int i3 = 16;
while (true) {
theta(this.state, this.decryptKeys);
int[] iArr2 = this.state;
if (i3 <= 0) {
int i4 = roundConstants[i3] ^ iArr2[0];
iArr2[0] = i4;
intToBytesBig(i4, bArr2, i2);
intToBytesBig(this.state[1], bArr2, i2 + 4);
intToBytesBig(this.state[2], bArr2, i2 + 8);
intToBytesBig(this.state[3], bArr2, i2 + 12);
return 16;
}
iArr2[0] = iArr2[0] ^ roundConstants[i3];
pi1(iArr2);
gamma(this.state);
pi2(this.state);
i3--;
}
}
private int bytesToIntBig(byte[] bArr, int i) {
byte b = bArr[i];
return (bArr[i + 3] & UnsignedBytes.MAX_VALUE) | ((bArr[i + 1] & UnsignedBytes.MAX_VALUE) << 16) | (b << Ascii.CAN) | ((bArr[i + 2] & UnsignedBytes.MAX_VALUE) << 8);
}
}