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

189 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.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;
/* loaded from: classes6.dex */
public class RC6Engine implements BlockCipher {
private static final int LGW = 5;
private static final int P32 = -1209970333;
private static final int Q32 = -1640531527;
private static final int _noRounds = 20;
private static final int bytesPerWord = 4;
private static final int wordSize = 32;
private int[] _S = null;
private boolean forEncryption;
private int rotateLeft(int i, int i2) {
return (i << i2) | (i >>> (-i2));
}
private int rotateRight(int i, int i2) {
return (i >>> i2) | (i << (-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) {
int blockSize = getBlockSize();
if (this._S == null) {
throw new IllegalStateException("RC6 engine not initialised");
}
if (i + blockSize > bArr.length) {
throw new DataLengthException("input buffer too short");
}
if (blockSize + i2 <= 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) {
this.forEncryption = z;
setKey(((KeyParameter) cipherParameters).getKey());
} else {
StringBuilder sb = new StringBuilder("invalid parameter passed to RC6 init - ");
sb.append(cipherParameters.getClass().getName());
throw new IllegalArgumentException(sb.toString());
}
}
@Override // org.bouncycastle.crypto.BlockCipher
public String getAlgorithmName() {
return "RC6";
}
private void wordToBytes(int i, byte[] bArr, int i2) {
for (int i3 = 0; i3 < 4; i3++) {
bArr[i3 + i2] = (byte) i;
i >>>= 8;
}
}
private void setKey(byte[] bArr) {
int[] iArr;
int length = (bArr.length + 3) / 4;
int length2 = (bArr.length + 3) / 4;
int[] iArr2 = new int[length2];
for (int length3 = bArr.length - 1; length3 >= 0; length3--) {
int i = length3 / 4;
iArr2[i] = (iArr2[i] << 8) + (bArr[length3] & UnsignedBytes.MAX_VALUE);
}
int[] iArr3 = new int[44];
this._S = iArr3;
iArr3[0] = P32;
int i2 = 1;
while (true) {
iArr = this._S;
if (i2 >= iArr.length) {
break;
}
iArr[i2] = iArr[i2 - 1] - 1640531527;
i2++;
}
int length4 = length2 > iArr.length ? length2 * 3 : iArr.length * 3;
int i3 = 0;
int i4 = 0;
int i5 = 0;
int i6 = 0;
for (int i7 = 0; i7 < length4; i7++) {
int[] iArr4 = this._S;
i4 = rotateLeft(iArr4[i3] + i4 + i5, 3);
iArr4[i3] = i4;
i5 = rotateLeft(iArr2[i6] + i4 + i5, i5 + i4);
iArr2[i6] = i5;
i3 = (i3 + 1) % this._S.length;
i6 = (i6 + 1) % length2;
}
}
private int encryptBlock(byte[] bArr, int i, byte[] bArr2, int i2) {
int bytesToWord = bytesToWord(bArr, i);
int bytesToWord2 = bytesToWord(bArr, i + 4);
int bytesToWord3 = bytesToWord(bArr, i + 8);
int bytesToWord4 = bytesToWord(bArr, i + 12);
int[] iArr = this._S;
int i3 = bytesToWord2 + iArr[0];
int i4 = bytesToWord4 + iArr[1];
int i5 = 1;
while (i5 <= 20) {
int rotateLeft = rotateLeft(((i3 << 1) + 1) * i3, 5);
int rotateLeft2 = rotateLeft(((i4 << 1) + 1) * i4, 5);
int rotateLeft3 = rotateLeft(bytesToWord ^ rotateLeft, rotateLeft2);
int i6 = i5 << 1;
int i7 = this._S[i6];
i5++;
int rotateLeft4 = rotateLeft(bytesToWord3 ^ rotateLeft2, rotateLeft) + this._S[i6 + 1];
bytesToWord3 = i4;
i4 = rotateLeft3 + i7;
bytesToWord = i3;
i3 = rotateLeft4;
}
int[] iArr2 = this._S;
int i8 = iArr2[42];
int i9 = iArr2[43];
wordToBytes(bytesToWord + i8, bArr2, i2);
wordToBytes(i3, bArr2, i2 + 4);
wordToBytes(bytesToWord3 + i9, bArr2, i2 + 8);
wordToBytes(i4, bArr2, i2 + 12);
return 16;
}
private int decryptBlock(byte[] bArr, int i, byte[] bArr2, int i2) {
int bytesToWord = bytesToWord(bArr, i);
int bytesToWord2 = bytesToWord(bArr, i + 4);
int bytesToWord3 = bytesToWord(bArr, i + 8);
int bytesToWord4 = bytesToWord(bArr, i + 12);
int[] iArr = this._S;
int i3 = bytesToWord3 - iArr[43];
int i4 = bytesToWord - iArr[42];
int i5 = bytesToWord4;
int i6 = i3;
int i7 = bytesToWord2;
int i8 = i4;
int i9 = 20;
while (i9 > 0) {
int rotateLeft = rotateLeft(((i8 << 1) + 1) * i8, 5);
int rotateLeft2 = rotateLeft(((i6 << 1) + 1) * i6, 5);
int i10 = i9 << 1;
int rotateRight = rotateRight(i7 - this._S[i10 + 1], rotateLeft);
i9--;
int rotateRight2 = rotateRight(i5 - this._S[i10], rotateLeft2) ^ rotateLeft;
i5 = i6;
i6 = rotateRight ^ rotateLeft2;
i7 = i8;
i8 = rotateRight2;
}
int[] iArr2 = this._S;
int i11 = iArr2[1];
int i12 = iArr2[0];
wordToBytes(i8, bArr2, i2);
wordToBytes(i7 - i12, bArr2, i2 + 4);
wordToBytes(i6, bArr2, i2 + 8);
wordToBytes(i5 - i11, bArr2, i2 + 12);
return 16;
}
private int bytesToWord(byte[] bArr, int i) {
int i2 = 0;
for (int i3 = 3; i3 >= 0; i3--) {
i2 = (i2 << 8) + (bArr[i3 + i] & UnsignedBytes.MAX_VALUE);
}
return i2;
}
}