what-the-bank/sources/org/bouncycastle/crypto/generators/SCrypt.java

133 lines
4.8 KiB
Java
Raw Normal View History

2024-07-27 18:17:47 +07:00
package org.bouncycastle.crypto.generators;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.engines.Salsa20Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Pack;
/* loaded from: classes6.dex */
public class SCrypt {
public static byte[] generate(byte[] bArr, byte[] bArr2, int i, int i2, int i3, int i4) {
if (bArr == null) {
throw new IllegalArgumentException("Passphrase P must be provided.");
}
if (bArr2 == null) {
throw new IllegalArgumentException("Salt S must be provided.");
}
if (i <= 1) {
throw new IllegalArgumentException("Cost parameter N must be > 1.");
}
if (i2 == 1 && i > 65536) {
throw new IllegalArgumentException("Cost parameter N must be > 1 and < 65536.");
}
if (i2 <= 0) {
throw new IllegalArgumentException("Block size r must be >= 1.");
}
int i5 = Integer.MAX_VALUE / (i2 << 10);
if (i3 > 0 && i3 <= i5) {
if (i4 > 0) {
return MFcrypt(bArr, bArr2, i, i2, i3, i4);
}
throw new IllegalArgumentException("Generated key length dkLen must be >= 1.");
}
StringBuilder sb = new StringBuilder("Parallelisation parameter p must be >= 1 and <= ");
sb.append(i5);
sb.append(" (based on block size r of ");
sb.append(i2);
sb.append(")");
throw new IllegalArgumentException(sb.toString());
}
private static void Xor(int[] iArr, int[] iArr2, int i, int[] iArr3) {
for (int length = iArr3.length - 1; length >= 0; length--) {
iArr3[length] = iArr[length] ^ iArr2[i + length];
}
}
private static byte[] SingleIterationPBKDF2(byte[] bArr, byte[] bArr2, int i) {
PKCS5S2ParametersGenerator pKCS5S2ParametersGenerator = new PKCS5S2ParametersGenerator(new SHA256Digest());
pKCS5S2ParametersGenerator.init(bArr, bArr2, 1);
return ((KeyParameter) pKCS5S2ParametersGenerator.generateDerivedMacParameters(i << 3)).getKey();
}
private static void SMix(int[] iArr, int i, int i2, int i3) {
int i4 = i3 << 5;
int[] iArr2 = new int[16];
int[] iArr3 = new int[16];
int[] iArr4 = new int[i4];
int[] iArr5 = new int[i4];
int[][] iArr6 = new int[i2];
try {
System.arraycopy(iArr, i, iArr5, 0, i4);
for (int i5 = 0; i5 < i2; i5++) {
iArr6[i5] = Arrays.clone(iArr5);
BlockMix(iArr5, iArr2, iArr3, iArr4, i3);
}
for (int i6 = 0; i6 < i2; i6++) {
Xor(iArr5, iArr6[iArr5[i4 - 16] & (i2 - 1)], 0, iArr5);
BlockMix(iArr5, iArr2, iArr3, iArr4, i3);
}
System.arraycopy(iArr5, 0, iArr, i, i4);
ClearAll(iArr6);
ClearAll(new int[][]{iArr5, iArr2, iArr3, iArr4});
} catch (Throwable th) {
ClearAll(iArr6);
ClearAll(new int[][]{iArr5, iArr2, iArr3, iArr4});
throw th;
}
}
private static byte[] MFcrypt(byte[] bArr, byte[] bArr2, int i, int i2, int i3, int i4) {
int i5 = i2 << 7;
byte[] SingleIterationPBKDF2 = SingleIterationPBKDF2(bArr, bArr2, i3 * i5);
int[] iArr = null;
try {
int length = SingleIterationPBKDF2.length >>> 2;
iArr = new int[length];
Pack.littleEndianToInt(SingleIterationPBKDF2, 0, iArr);
for (int i6 = 0; i6 < length; i6 += i5 >>> 2) {
SMix(iArr, i6, i, i2);
}
Pack.intToLittleEndian(iArr, SingleIterationPBKDF2, 0);
return SingleIterationPBKDF2(bArr, SingleIterationPBKDF2, i4);
} finally {
Clear(SingleIterationPBKDF2);
Clear(iArr);
}
}
private static void ClearAll(int[][] iArr) {
for (int[] iArr2 : iArr) {
Clear(iArr2);
}
}
private static void Clear(int[] iArr) {
if (iArr != null) {
Arrays.fill(iArr, 0);
}
}
private static void Clear(byte[] bArr) {
if (bArr != null) {
Arrays.fill(bArr, (byte) 0);
}
}
private static void BlockMix(int[] iArr, int[] iArr2, int[] iArr3, int[] iArr4, int i) {
System.arraycopy(iArr, iArr.length - 16, iArr2, 0, 16);
int length = iArr.length;
int i2 = 0;
int i3 = 0;
for (int i4 = i << 1; i4 > 0; i4--) {
Xor(iArr2, iArr, i2, iArr3);
Salsa20Engine.salsaCore(8, iArr3, iArr2);
System.arraycopy(iArr2, 0, iArr4, i3, 16);
i3 = ((length >>> 1) + i2) - i3;
i2 += 16;
}
System.arraycopy(iArr4, 0, iArr, 0, iArr4.length);
}
}