243 lines
11 KiB
Java
243 lines
11 KiB
Java
package org.bouncycastle.pqc.crypto.gmss;
|
||
|
||
import java.lang.reflect.Array;
|
||
import java.security.SecureRandom;
|
||
import java.util.Vector;
|
||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
||
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
|
||
import org.bouncycastle.crypto.Digest;
|
||
import org.bouncycastle.crypto.KeyGenerationParameters;
|
||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||
import org.bouncycastle.pqc.crypto.gmss.util.GMSSRandom;
|
||
import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSVerify;
|
||
import org.bouncycastle.pqc.crypto.gmss.util.WinternitzOTSignature;
|
||
|
||
/* loaded from: classes6.dex */
|
||
public class GMSSKeyPairGenerator implements AsymmetricCipherKeyPairGenerator {
|
||
public static final String OID = "1.3.6.1.4.1.8301.3.1.3.3";
|
||
private int[] K;
|
||
private byte[][] currentRootSigs;
|
||
private byte[][] currentSeeds;
|
||
private GMSSDigestProvider digestProvider;
|
||
private GMSSParameters gmssPS;
|
||
private GMSSKeyGenerationParameters gmssParams;
|
||
private GMSSRandom gmssRandom;
|
||
private int[] heightOfTrees;
|
||
private boolean initialized = false;
|
||
private int mdLength;
|
||
private Digest messDigestTree;
|
||
private byte[][] nextNextSeeds;
|
||
private int numLayer;
|
||
private int[] otsIndex;
|
||
|
||
public void initialize(KeyGenerationParameters keyGenerationParameters) {
|
||
GMSSKeyGenerationParameters gMSSKeyGenerationParameters = (GMSSKeyGenerationParameters) keyGenerationParameters;
|
||
this.gmssParams = gMSSKeyGenerationParameters;
|
||
GMSSParameters gMSSParameters = new GMSSParameters(gMSSKeyGenerationParameters.getParameters().getNumOfLayers(), this.gmssParams.getParameters().getHeightOfTrees(), this.gmssParams.getParameters().getWinternitzParameter(), this.gmssParams.getParameters().getK());
|
||
this.gmssPS = gMSSParameters;
|
||
this.numLayer = gMSSParameters.getNumOfLayers();
|
||
this.heightOfTrees = this.gmssPS.getHeightOfTrees();
|
||
this.otsIndex = this.gmssPS.getWinternitzParameter();
|
||
this.K = this.gmssPS.getK();
|
||
this.currentSeeds = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.numLayer, this.mdLength);
|
||
this.nextNextSeeds = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.numLayer - 1, this.mdLength);
|
||
SecureRandom secureRandom = new SecureRandom();
|
||
for (int i = 0; i < this.numLayer; i++) {
|
||
secureRandom.nextBytes(this.currentSeeds[i]);
|
||
this.gmssRandom.nextSeed(this.currentSeeds[i]);
|
||
}
|
||
this.initialized = true;
|
||
}
|
||
|
||
public void initialize(int i, SecureRandom secureRandom) {
|
||
GMSSKeyGenerationParameters gMSSKeyGenerationParameters;
|
||
if (i <= 10) {
|
||
gMSSKeyGenerationParameters = new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(1, new int[]{10}, new int[]{3}, new int[]{2}));
|
||
} else {
|
||
gMSSKeyGenerationParameters = i <= 20 ? new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(2, new int[]{10, 10}, new int[]{5, 4}, new int[]{2, 2})) : new GMSSKeyGenerationParameters(secureRandom, new GMSSParameters(4, new int[]{10, 10, 10, 10}, new int[]{9, 9, 9, 3}, new int[]{2, 2, 2, 2}));
|
||
}
|
||
initialize(gMSSKeyGenerationParameters);
|
||
}
|
||
|
||
@Override // org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator
|
||
public void init(KeyGenerationParameters keyGenerationParameters) {
|
||
initialize(keyGenerationParameters);
|
||
}
|
||
|
||
@Override // org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator
|
||
public AsymmetricCipherKeyPair generateKeyPair() {
|
||
return genKeyPair();
|
||
}
|
||
|
||
private void initializeDefault() {
|
||
initialize(new GMSSKeyGenerationParameters(new SecureRandom(), new GMSSParameters(4, new int[]{10, 10, 10, 10}, new int[]{3, 3, 3, 3}, new int[]{2, 2, 2, 2})));
|
||
}
|
||
|
||
private GMSSRootCalc generateNextAuthpathAndRoot(Vector vector, byte[] bArr, int i) {
|
||
byte[] bArr2 = new byte[this.numLayer];
|
||
GMSSRootCalc gMSSRootCalc = new GMSSRootCalc(this.heightOfTrees[i], this.K[i], this.digestProvider);
|
||
gMSSRootCalc.initialize(vector);
|
||
int i2 = 3;
|
||
int i3 = 0;
|
||
int i4 = 0;
|
||
while (true) {
|
||
int i5 = this.heightOfTrees[i];
|
||
if (i3 >= (1 << i5)) {
|
||
break;
|
||
}
|
||
if (i3 == i2 && i4 < i5 - this.K[i]) {
|
||
gMSSRootCalc.initializeTreehashSeed(bArr, i4);
|
||
i2 <<= 1;
|
||
i4++;
|
||
}
|
||
gMSSRootCalc.update(new WinternitzOTSignature(this.gmssRandom.nextSeed(bArr), this.digestProvider.get(), this.otsIndex[i]).getPublicKey());
|
||
i3++;
|
||
}
|
||
if (gMSSRootCalc.wasFinished()) {
|
||
return gMSSRootCalc;
|
||
}
|
||
System.err.println("N<EFBFBD>chster Baum noch nicht fertig konstruiert!!!");
|
||
return null;
|
||
}
|
||
|
||
private GMSSRootCalc generateCurrentAuthpathAndRoot(byte[] bArr, Vector vector, byte[] bArr2, int i) {
|
||
byte[] Verify;
|
||
int i2 = this.mdLength;
|
||
byte[] bArr3 = new byte[i2];
|
||
byte[] bArr4 = new byte[i2];
|
||
byte[] nextSeed = this.gmssRandom.nextSeed(bArr2);
|
||
GMSSRootCalc gMSSRootCalc = new GMSSRootCalc(this.heightOfTrees[i], this.K[i], this.digestProvider);
|
||
gMSSRootCalc.initialize(vector);
|
||
if (i == this.numLayer - 1) {
|
||
Verify = new WinternitzOTSignature(nextSeed, this.digestProvider.get(), this.otsIndex[i]).getPublicKey();
|
||
} else {
|
||
this.currentRootSigs[i] = new WinternitzOTSignature(nextSeed, this.digestProvider.get(), this.otsIndex[i]).getSignature(bArr);
|
||
Verify = new WinternitzOTSVerify(this.digestProvider.get(), this.otsIndex[i]).Verify(bArr, this.currentRootSigs[i]);
|
||
}
|
||
gMSSRootCalc.update(Verify);
|
||
int i3 = 3;
|
||
int i4 = 0;
|
||
int i5 = 1;
|
||
while (true) {
|
||
int i6 = this.heightOfTrees[i];
|
||
if (i5 >= (1 << i6)) {
|
||
break;
|
||
}
|
||
if (i5 == i3 && i4 < i6 - this.K[i]) {
|
||
gMSSRootCalc.initializeTreehashSeed(bArr2, i4);
|
||
i3 <<= 1;
|
||
i4++;
|
||
}
|
||
gMSSRootCalc.update(new WinternitzOTSignature(this.gmssRandom.nextSeed(bArr2), this.digestProvider.get(), this.otsIndex[i]).getPublicKey());
|
||
i5++;
|
||
}
|
||
if (gMSSRootCalc.wasFinished()) {
|
||
return gMSSRootCalc;
|
||
}
|
||
System.err.println("Baum noch nicht fertig konstruiert!!!");
|
||
return null;
|
||
}
|
||
|
||
private AsymmetricCipherKeyPair genKeyPair() {
|
||
int i;
|
||
int i2;
|
||
if (!this.initialized) {
|
||
initializeDefault();
|
||
}
|
||
int i3 = this.numLayer;
|
||
byte[][][] bArr = new byte[i3][];
|
||
int i4 = i3 - 1;
|
||
byte[][][] bArr2 = new byte[i4][];
|
||
Treehash[][] treehashArr = new Treehash[i3];
|
||
Treehash[][] treehashArr2 = new Treehash[i4];
|
||
Vector[] vectorArr = new Vector[i3];
|
||
Vector[] vectorArr2 = new Vector[i4];
|
||
Vector[][] vectorArr3 = new Vector[i3];
|
||
Vector[][] vectorArr4 = new Vector[i4];
|
||
int i5 = 0;
|
||
while (true) {
|
||
i = this.numLayer;
|
||
if (i5 >= i) {
|
||
break;
|
||
}
|
||
bArr[i5] = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.heightOfTrees[i5], this.mdLength);
|
||
int i6 = this.heightOfTrees[i5];
|
||
treehashArr[i5] = new Treehash[i6 - this.K[i5]];
|
||
if (i5 > 0) {
|
||
int i7 = i5 - 1;
|
||
bArr2[i7] = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, i6, this.mdLength);
|
||
treehashArr2[i7] = new Treehash[this.heightOfTrees[i5] - this.K[i5]];
|
||
}
|
||
vectorArr[i5] = new Vector();
|
||
if (i5 > 0) {
|
||
vectorArr2[i5 - 1] = new Vector();
|
||
}
|
||
i5++;
|
||
}
|
||
byte[][] bArr3 = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, i, this.mdLength);
|
||
byte[][] bArr4 = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.numLayer - 1, this.mdLength);
|
||
byte[][] bArr5 = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, this.numLayer, this.mdLength);
|
||
int i8 = 0;
|
||
while (true) {
|
||
i2 = this.numLayer;
|
||
if (i8 >= i2) {
|
||
break;
|
||
}
|
||
System.arraycopy(this.currentSeeds[i8], 0, bArr5[i8], 0, this.mdLength);
|
||
i8++;
|
||
bArr4 = bArr4;
|
||
}
|
||
byte[][] bArr6 = bArr4;
|
||
this.currentRootSigs = (byte[][]) Array.newInstance((Class<?>) Byte.TYPE, i2 - 1, this.mdLength);
|
||
int i9 = this.numLayer - 1;
|
||
while (i9 >= 0) {
|
||
GMSSRootCalc gMSSRootCalc = new GMSSRootCalc(this.heightOfTrees[i9], this.K[i9], this.digestProvider);
|
||
try {
|
||
gMSSRootCalc = i9 == this.numLayer + (-1) ? generateCurrentAuthpathAndRoot(null, vectorArr[i9], bArr5[i9], i9) : generateCurrentAuthpathAndRoot(bArr3[i9 + 1], vectorArr[i9], bArr5[i9], i9);
|
||
} catch (Exception unused) {
|
||
}
|
||
int i10 = 0;
|
||
while (i10 < this.heightOfTrees[i9]) {
|
||
System.arraycopy(gMSSRootCalc.getAuthPath()[i10], 0, bArr[i9][i10], 0, this.mdLength);
|
||
i10++;
|
||
vectorArr = vectorArr;
|
||
bArr = bArr;
|
||
}
|
||
vectorArr3[i9] = gMSSRootCalc.getRetain();
|
||
treehashArr[i9] = gMSSRootCalc.getTreehash();
|
||
System.arraycopy(gMSSRootCalc.getRoot(), 0, bArr3[i9], 0, this.mdLength);
|
||
i9--;
|
||
vectorArr = vectorArr;
|
||
bArr = bArr;
|
||
}
|
||
byte[][][] bArr7 = bArr;
|
||
Vector[] vectorArr5 = vectorArr;
|
||
int i11 = this.numLayer - 2;
|
||
while (i11 >= 0) {
|
||
int i12 = i11 + 1;
|
||
GMSSRootCalc generateNextAuthpathAndRoot = generateNextAuthpathAndRoot(vectorArr2[i11], bArr5[i12], i12);
|
||
int i13 = 0;
|
||
while (i13 < this.heightOfTrees[i12]) {
|
||
System.arraycopy(generateNextAuthpathAndRoot.getAuthPath()[i13], 0, bArr2[i11][i13], 0, this.mdLength);
|
||
i13++;
|
||
vectorArr3 = vectorArr3;
|
||
}
|
||
vectorArr4[i11] = generateNextAuthpathAndRoot.getRetain();
|
||
treehashArr2[i11] = generateNextAuthpathAndRoot.getTreehash();
|
||
System.arraycopy(generateNextAuthpathAndRoot.getRoot(), 0, bArr6[i11], 0, this.mdLength);
|
||
System.arraycopy(bArr5[i12], 0, this.nextNextSeeds[i11], 0, this.mdLength);
|
||
i11--;
|
||
vectorArr3 = vectorArr3;
|
||
}
|
||
return new AsymmetricCipherKeyPair((AsymmetricKeyParameter) new GMSSPublicKeyParameters(bArr3[0], this.gmssPS), (AsymmetricKeyParameter) new GMSSPrivateKeyParameters(this.currentSeeds, this.nextNextSeeds, bArr7, bArr2, treehashArr, treehashArr2, vectorArr5, vectorArr2, vectorArr3, vectorArr4, bArr6, this.currentRootSigs, this.gmssPS, this.digestProvider));
|
||
}
|
||
|
||
public GMSSKeyPairGenerator(GMSSDigestProvider gMSSDigestProvider) {
|
||
this.digestProvider = gMSSDigestProvider;
|
||
Digest digest = gMSSDigestProvider.get();
|
||
this.messDigestTree = digest;
|
||
this.mdLength = digest.getDigestSize();
|
||
this.gmssRandom = new GMSSRandom(this.messDigestTree);
|
||
}
|
||
}
|