what-the-bank/sources/org/bouncycastle/pqc/crypto/gmss/GMSSSigner.java

198 lines
9.4 KiB
Java

package org.bouncycastle.pqc.crypto.gmss;
import java.lang.reflect.Array;
import java.security.SecureRandom;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.Digest;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.pqc.crypto.MessageSigner;
import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
import org.bouncycastle.pqc.crypto.gmss.util.GMSSUtil;
import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify;
import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature;
import org.bouncycastle.util.Arrays;
/* loaded from: classes6.dex */
public class GMSSSigner implements MessageSigner {
private byte[][][] currentAuthPaths;
private GMSSDigestProvider digestProvider;
private GMSSParameters gmssPS;
private GMSSRandom gmssRandom;
private GMSSUtil gmssUtil = new GMSSUtil();
private int[] index;
GMSSKeyParameters key;
private int mdLength;
private Digest messDigestOTS;
private Digest messDigestTrees;
private int numLayer;
private WinternitzOTSignature ots;
private byte[] pubKeyBytes;
private SecureRandom random;
private byte[][] subtreeRootSig;
@Override // org.bouncycastle.pqc.crypto.MessageSigner
public boolean verifySignature(byte[] bArr, byte[] bArr2) {
this.messDigestOTS.reset();
int i = 0;
for (int i2 = this.numLayer - 1; i2 >= 0; i2--) {
WinternitzOTSVerify winternitzOTSVerify = new WinternitzOTSVerify(this.digestProvider.get(), this.gmssPS.getWinternitzParameter()[i2]);
int signatureLength = winternitzOTSVerify.getSignatureLength();
int bytesToIntLittleEndian = this.gmssUtil.bytesToIntLittleEndian(bArr2, i);
int i3 = i + 4;
byte[] bArr3 = new byte[signatureLength];
System.arraycopy(bArr2, i3, bArr3, 0, signatureLength);
i = i3 + signatureLength;
bArr = winternitzOTSVerify.Verify(bArr, bArr3);
if (bArr == null) {
System.err.println("OTS Public Key is null in GMSSSignature.verify");
return false;
}
byte[][] bArr4 = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.gmssPS.getHeightOfTrees()[i2], this.mdLength);
for (byte[] bArr5 : bArr4) {
System.arraycopy(bArr2, i, bArr5, 0, this.mdLength);
i += this.mdLength;
}
byte[] bArr6 = new byte[this.mdLength];
int length = (1 << bArr4.length) + bytesToIntLittleEndian;
for (int i4 = 0; i4 < bArr4.length; i4++) {
int i5 = this.mdLength;
int i6 = i5 << 1;
byte[] bArr7 = new byte[i6];
if (length % 2 == 0) {
System.arraycopy(bArr, 0, bArr7, 0, i5);
byte[] bArr8 = bArr4[i4];
int i7 = this.mdLength;
System.arraycopy(bArr8, 0, bArr7, i7, i7);
} else {
System.arraycopy(bArr4[i4], 0, bArr7, 0, i5);
System.arraycopy(bArr, 0, bArr7, this.mdLength, bArr.length);
length--;
}
length /= 2;
this.messDigestTrees.update(bArr7, 0, i6);
bArr = new byte[this.messDigestTrees.getDigestSize()];
this.messDigestTrees.doFinal(bArr, 0);
}
}
return Arrays.areEqual(this.pubKeyBytes, bArr);
}
@Override // org.bouncycastle.pqc.crypto.MessageSigner
public void init(boolean z, CipherParameters cipherParameters) {
if (!z) {
this.key = (GMSSPublicKeyParameters) cipherParameters;
initVerify();
return;
}
if (cipherParameters instanceof ParametersWithRandom) {
ParametersWithRandom parametersWithRandom = (ParametersWithRandom) cipherParameters;
this.random = parametersWithRandom.getRandom();
this.key = (GMSSPrivateKeyParameters) parametersWithRandom.getParameters();
} else {
this.random = new SecureRandom();
this.key = (GMSSPrivateKeyParameters) cipherParameters;
}
initSign();
}
@Override // org.bouncycastle.pqc.crypto.MessageSigner
public byte[] generateSignature(byte[] bArr) {
byte[] bArr2 = new byte[this.mdLength];
byte[] signature = this.ots.getSignature(bArr);
byte[] concatenateArray = this.gmssUtil.concatenateArray(this.currentAuthPaths[this.numLayer - 1]);
byte[] intToBytesLittleEndian = this.gmssUtil.intToBytesLittleEndian(this.index[this.numLayer - 1]);
int length = intToBytesLittleEndian.length + signature.length + concatenateArray.length;
byte[] bArr3 = new byte[length];
System.arraycopy(intToBytesLittleEndian, 0, bArr3, 0, intToBytesLittleEndian.length);
System.arraycopy(signature, 0, bArr3, intToBytesLittleEndian.length, signature.length);
System.arraycopy(concatenateArray, 0, bArr3, intToBytesLittleEndian.length + signature.length, concatenateArray.length);
byte[] bArr4 = new byte[0];
for (int i = this.numLayer - 2; i >= 0; i--) {
byte[] concatenateArray2 = this.gmssUtil.concatenateArray(this.currentAuthPaths[i]);
byte[] intToBytesLittleEndian2 = this.gmssUtil.intToBytesLittleEndian(this.index[i]);
int length2 = bArr4.length;
byte[] bArr5 = new byte[length2];
System.arraycopy(bArr4, 0, bArr5, 0, bArr4.length);
bArr4 = new byte[intToBytesLittleEndian2.length + length2 + this.subtreeRootSig[i].length + concatenateArray2.length];
System.arraycopy(bArr5, 0, bArr4, 0, length2);
System.arraycopy(intToBytesLittleEndian2, 0, bArr4, length2, intToBytesLittleEndian2.length);
byte[] bArr6 = this.subtreeRootSig[i];
System.arraycopy(bArr6, 0, bArr4, intToBytesLittleEndian2.length + length2, bArr6.length);
System.arraycopy(concatenateArray2, 0, bArr4, length2 + intToBytesLittleEndian2.length + this.subtreeRootSig[i].length, concatenateArray2.length);
}
byte[] bArr7 = new byte[bArr4.length + length];
System.arraycopy(bArr3, 0, bArr7, 0, length);
System.arraycopy(bArr4, 0, bArr7, length, bArr4.length);
return bArr7;
}
private void initVerify() {
this.messDigestTrees.reset();
GMSSPublicKeyParameters gMSSPublicKeyParameters = (GMSSPublicKeyParameters) this.key;
this.pubKeyBytes = gMSSPublicKeyParameters.getPublicKey();
GMSSParameters parameters = gMSSPublicKeyParameters.getParameters();
this.gmssPS = parameters;
this.numLayer = parameters.getNumOfLayers();
}
private void initSign() {
int i;
this.messDigestTrees.reset();
GMSSPrivateKeyParameters gMSSPrivateKeyParameters = (GMSSPrivateKeyParameters) this.key;
if (gMSSPrivateKeyParameters.isUsed()) {
throw new IllegalStateException("Private key already used");
}
if (gMSSPrivateKeyParameters.getIndex(0) >= gMSSPrivateKeyParameters.getNumLeafs(0)) {
throw new IllegalStateException("No more signatures can be generated");
}
GMSSParameters parameters = gMSSPrivateKeyParameters.getParameters();
this.gmssPS = parameters;
this.numLayer = parameters.getNumOfLayers();
byte[] bArr = gMSSPrivateKeyParameters.getCurrentSeeds()[this.numLayer - 1];
int i2 = this.mdLength;
byte[] bArr2 = new byte[i2];
byte[] bArr3 = new byte[i2];
System.arraycopy(bArr, 0, bArr3, 0, i2);
this.ots = new WinternitzOTSignature(this.gmssRandom.nextSeed(bArr3), this.digestProvider.get(), this.gmssPS.getWinternitzParameter()[this.numLayer - 1]);
byte[][][] currentAuthPaths = gMSSPrivateKeyParameters.getCurrentAuthPaths();
this.currentAuthPaths = new byte[this.numLayer][];
int i3 = 0;
while (true) {
i = this.numLayer;
if (i3 >= i) {
break;
}
this.currentAuthPaths[i3] = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, currentAuthPaths[i3].length, this.mdLength);
int i4 = 0;
while (true) {
byte[][] bArr4 = currentAuthPaths[i3];
if (i4 < bArr4.length) {
System.arraycopy(bArr4[i4], 0, this.currentAuthPaths[i3][i4], 0, this.mdLength);
i4++;
}
}
i3++;
}
this.index = new int[i];
System.arraycopy(gMSSPrivateKeyParameters.getIndex(), 0, this.index, 0, this.numLayer);
this.subtreeRootSig = new byte[this.numLayer - 1];
for (int i5 = 0; i5 < this.numLayer - 1; i5++) {
byte[] subtreeRootSig = gMSSPrivateKeyParameters.getSubtreeRootSig(i5);
byte[][] bArr5 = this.subtreeRootSig;
byte[] bArr6 = new byte[subtreeRootSig.length];
bArr5[i5] = bArr6;
System.arraycopy(subtreeRootSig, 0, bArr6, 0, subtreeRootSig.length);
}
gMSSPrivateKeyParameters.markUsed();
}
public GMSSSigner(GMSSDigestProvider gMSSDigestProvider) {
this.digestProvider = gMSSDigestProvider;
Digest digest = gMSSDigestProvider.get();
this.messDigestTrees = digest;
this.messDigestOTS = digest;
this.mdLength = digest.getDigestSize();
this.gmssRandom = new GMSSRandom(this.messDigestTrees);
}
}