145 lines
5.9 KiB
Java
145 lines
5.9 KiB
Java
package org.bouncycastle.pqc.crypto.rainbow;
|
|
|
|
import java.security.SecureRandom;
|
|
import org.bouncycastle.crypto.CipherParameters;
|
|
import org.bouncycastle.crypto.params.ParametersWithRandom;
|
|
import org.bouncycastle.pqc.crypto.MessageSigner;
|
|
import org.bouncycastle.pqc.crypto.rainbow.util.ComputeInField;
|
|
import org.bouncycastle.pqc.crypto.rainbow.util.GF2Field;
|
|
|
|
/* loaded from: classes6.dex */
|
|
public class RainbowSigner implements MessageSigner {
|
|
private ComputeInField cf = new ComputeInField();
|
|
RainbowKeyParameters key;
|
|
private SecureRandom random;
|
|
int signableDocumentLength;
|
|
private short[] x;
|
|
|
|
@Override // org.bouncycastle.pqc.crypto.MessageSigner
|
|
public boolean verifySignature(byte[] bArr, byte[] bArr2) {
|
|
short[] sArr = new short[bArr2.length];
|
|
for (int i = 0; i < bArr2.length; i++) {
|
|
sArr[i] = (short) (bArr2[i] & 255);
|
|
}
|
|
short[] makeMessageRepresentative = makeMessageRepresentative(bArr);
|
|
short[] verifySignatureIntern = verifySignatureIntern(sArr);
|
|
if (makeMessageRepresentative.length != verifySignatureIntern.length) {
|
|
return false;
|
|
}
|
|
boolean z = true;
|
|
for (int i2 = 0; i2 < makeMessageRepresentative.length; i2++) {
|
|
z = z && makeMessageRepresentative[i2] == verifySignatureIntern[i2];
|
|
}
|
|
return z;
|
|
}
|
|
|
|
@Override // org.bouncycastle.pqc.crypto.MessageSigner
|
|
public void init(boolean z, CipherParameters cipherParameters) {
|
|
RainbowKeyParameters rainbowKeyParameters;
|
|
if (!z) {
|
|
rainbowKeyParameters = (RainbowPublicKeyParameters) cipherParameters;
|
|
} else {
|
|
if (cipherParameters instanceof ParametersWithRandom) {
|
|
ParametersWithRandom parametersWithRandom = (ParametersWithRandom) cipherParameters;
|
|
this.random = parametersWithRandom.getRandom();
|
|
this.key = (RainbowPrivateKeyParameters) parametersWithRandom.getParameters();
|
|
this.signableDocumentLength = this.key.getDocLength();
|
|
}
|
|
this.random = new SecureRandom();
|
|
rainbowKeyParameters = (RainbowPrivateKeyParameters) cipherParameters;
|
|
}
|
|
this.key = rainbowKeyParameters;
|
|
this.signableDocumentLength = this.key.getDocLength();
|
|
}
|
|
|
|
@Override // org.bouncycastle.pqc.crypto.MessageSigner
|
|
public byte[] generateSignature(byte[] bArr) {
|
|
short[] initSign;
|
|
int i;
|
|
int i2;
|
|
int i3;
|
|
Layer[] layers = ((RainbowPrivateKeyParameters) this.key).getLayers();
|
|
int length = layers.length;
|
|
this.x = new short[((RainbowPrivateKeyParameters) this.key).getInvA2().length];
|
|
int viNext = layers[length - 1].getViNext();
|
|
byte[] bArr2 = new byte[viNext];
|
|
while (true) {
|
|
try {
|
|
initSign = initSign(layers, makeMessageRepresentative(bArr));
|
|
i3 = 0;
|
|
break;
|
|
} catch (Exception unused) {
|
|
}
|
|
}
|
|
for (i2 = 0; i2 < length; i2++) {
|
|
short[] sArr = new short[layers[i2].getOi()];
|
|
short[] sArr2 = new short[layers[i2].getOi()];
|
|
for (int i4 = 0; i4 < layers[i2].getOi(); i4++) {
|
|
sArr[i4] = initSign[i3];
|
|
i3++;
|
|
}
|
|
short[] solveEquation = this.cf.solveEquation(layers[i2].plugInVinegars(this.x), sArr);
|
|
if (solveEquation == null) {
|
|
throw new Exception("LES is not solveable!");
|
|
}
|
|
for (int i5 = 0; i5 < solveEquation.length; i5++) {
|
|
this.x[layers[i2].getVi() + i5] = solveEquation[i5];
|
|
}
|
|
}
|
|
short[] multiplyMatrix = this.cf.multiplyMatrix(((RainbowPrivateKeyParameters) this.key).getInvA2(), this.cf.addVect(((RainbowPrivateKeyParameters) this.key).getB2(), this.x));
|
|
for (i = 0; i < viNext; i++) {
|
|
bArr2[i] = (byte) multiplyMatrix[i];
|
|
}
|
|
return bArr2;
|
|
}
|
|
|
|
private short[] verifySignatureIntern(short[] sArr) {
|
|
short[][] coeffQuadratic = ((RainbowPublicKeyParameters) this.key).getCoeffQuadratic();
|
|
short[][] coeffSingular = ((RainbowPublicKeyParameters) this.key).getCoeffSingular();
|
|
short[] coeffScalar = ((RainbowPublicKeyParameters) this.key).getCoeffScalar();
|
|
short[] sArr2 = new short[coeffQuadratic.length];
|
|
int length = coeffSingular[0].length;
|
|
for (int i = 0; i < coeffQuadratic.length; i++) {
|
|
int i2 = 0;
|
|
for (int i3 = 0; i3 < length; i3++) {
|
|
for (int i4 = i3; i4 < length; i4++) {
|
|
sArr2[i] = GF2Field.addElem(sArr2[i], GF2Field.multElem(coeffQuadratic[i][i2], GF2Field.multElem(sArr[i3], sArr[i4])));
|
|
i2++;
|
|
}
|
|
sArr2[i] = GF2Field.addElem(sArr2[i], GF2Field.multElem(coeffSingular[i][i3], sArr[i3]));
|
|
}
|
|
sArr2[i] = GF2Field.addElem(sArr2[i], coeffScalar[i]);
|
|
}
|
|
return sArr2;
|
|
}
|
|
|
|
private short[] makeMessageRepresentative(byte[] bArr) {
|
|
int i = this.signableDocumentLength;
|
|
short[] sArr = new short[i];
|
|
int i2 = 0;
|
|
int i3 = 0;
|
|
while (i2 < bArr.length) {
|
|
short s = bArr[i3];
|
|
sArr[i2] = s;
|
|
sArr[i2] = (short) (s & 255);
|
|
i3++;
|
|
i2++;
|
|
if (i2 >= i) {
|
|
break;
|
|
}
|
|
}
|
|
return sArr;
|
|
}
|
|
|
|
private short[] initSign(Layer[] layerArr, short[] sArr) {
|
|
short[] sArr2 = new short[sArr.length];
|
|
short[] multiplyMatrix = this.cf.multiplyMatrix(((RainbowPrivateKeyParameters) this.key).getInvA1(), this.cf.addVect(((RainbowPrivateKeyParameters) this.key).getB1(), sArr));
|
|
for (int i = 0; i < layerArr[0].getVi(); i++) {
|
|
this.x[i] = (short) this.random.nextInt();
|
|
short[] sArr3 = this.x;
|
|
sArr3[i] = (short) (sArr3[i] & 255);
|
|
}
|
|
return multiplyMatrix;
|
|
}
|
|
}
|