diff options
Diffstat (limited to 'core/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java')
-rw-r--r-- | core/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java | 301 |
1 files changed, 0 insertions, 301 deletions
diff --git a/core/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java b/core/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java deleted file mode 100644 index 979e759b..00000000 --- a/core/src/main/java/org/bouncycastle/pqc/crypto/rainbow/RainbowSigner.java +++ /dev/null @@ -1,301 +0,0 @@ -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; - -/** - * It implements the sign and verify functions for the Rainbow Signature Scheme. - * Here the message, which has to be signed, is updated. The use of - * different hash functions is possible. - * <p> - * Detailed information about the signature and the verify-method is to be found - * in the paper of Jintai Ding, Dieter Schmidt: Rainbow, a New Multivariable - * Polynomial Signature Scheme. ACNS 2005: 164-175 - * (http://dx.doi.org/10.1007/11496137_12) - */ -public class RainbowSigner - implements MessageSigner -{ - // Source of randomness - private SecureRandom random; - - // The length of a document that can be signed with the privKey - int signableDocumentLength; - - // Container for the oil and vinegar variables of all the layers - private short[] x; - - private ComputeInField cf = new ComputeInField(); - - RainbowKeyParameters key; - - public void init(boolean forSigning, - CipherParameters param) - { - if (forSigning) - { - if (param instanceof ParametersWithRandom) - { - ParametersWithRandom rParam = (ParametersWithRandom)param; - - this.random = rParam.getRandom(); - this.key = (RainbowPrivateKeyParameters)rParam.getParameters(); - - } - else - { - - this.random = new SecureRandom(); - this.key = (RainbowPrivateKeyParameters)param; - } - } - else - { - this.key = (RainbowPublicKeyParameters)param; - } - - this.signableDocumentLength = this.key.getDocLength(); - } - - - /** - * initial operations before solving the Linear equation system. - * - * @param layer the current layer for which a LES is to be solved. - * @param msg the message that should be signed. - * @return Y_ the modified document needed for solving LES, (Y_ = - * A1^{-1}*(Y-b1)) linear map L1 = A1 x + b1. - */ - private short[] initSign(Layer[] layer, short[] msg) - { - - /* preparation: Modifies the document with the inverse of L1 */ - // tmp = Y - b1: - short[] tmpVec = new short[msg.length]; - - tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB1(), msg); - - // Y_ = A1^{-1} * (Y - b1) : - short[] Y_ = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA1(), tmpVec); - - /* generates the vinegar vars of the first layer at random */ - for (int i = 0; i < layer[0].getVi(); i++) - { - x[i] = (short)random.nextInt(); - x[i] = (short)(x[i] & GF2Field.MASK); - } - - return Y_; - } - - /** - * This function signs the message that has been updated, making use of the - * private key. - * <p> - * For computing the signature, L1 and L2 are needed, as well as LES should - * be solved for each layer in order to find the Oil-variables in the layer. - * <p> - * The Vinegar-variables of the first layer are random generated. - * - * @param message the message - * @return the signature of the message. - */ - public byte[] generateSignature(byte[] message) - { - Layer[] layer = ((RainbowPrivateKeyParameters)this.key).getLayers(); - int numberOfLayers = layer.length; - - x = new short[((RainbowPrivateKeyParameters)this.key).getInvA2().length]; // all variables - - short[] Y_; // modified document - short[] y_i; // part of Y_ each polynomial - int counter; // index of the current part of the doc - - short[] solVec; // the solution of LES pro layer - short[] tmpVec; - - // the signature as an array of shorts: - short[] signature; - // the signature as a byte-array: - byte[] S = new byte[layer[numberOfLayers - 1].getViNext()]; - - short[] msgHashVals = makeMessageRepresentative(message); - - // shows if an exception is caught - boolean ok; - do - { - ok = true; - counter = 0; - try - { - Y_ = initSign(layer, msgHashVals); - - for (int i = 0; i < numberOfLayers; i++) - { - - y_i = new short[layer[i].getOi()]; - solVec = new short[layer[i].getOi()]; // solution of LES - - /* copy oi elements of Y_ into y_i */ - for (int k = 0; k < layer[i].getOi(); k++) - { - y_i[k] = Y_[counter]; - counter++; // current index of Y_ - } - - /* - * plug in the vars of the previous layer in order to get - * the vars of the current layer - */ - solVec = cf.solveEquation(layer[i].plugInVinegars(x), y_i); - - if (solVec == null) - { // LES is not solveable - throw new Exception("LES is not solveable!"); - } - - /* copy the new vars into the x-array */ - for (int j = 0; j < solVec.length; j++) - { - x[layer[i].getVi() + j] = solVec[j]; - } - } - - /* apply the inverse of L2: (signature = A2^{-1}*(b2+x)) */ - tmpVec = cf.addVect(((RainbowPrivateKeyParameters)this.key).getB2(), x); - signature = cf.multiplyMatrix(((RainbowPrivateKeyParameters)this.key).getInvA2(), tmpVec); - - /* cast signature from short[] to byte[] */ - for (int i = 0; i < S.length; i++) - { - S[i] = ((byte)signature[i]); - } - } - catch (Exception se) - { - // if one of the LESs was not solveable - sign again - ok = false; - } - } - while (!ok); - /* return the signature in bytes */ - return S; - } - - /** - * This function verifies the signature of the message that has been - * updated, with the aid of the public key. - * - * @param message the message - * @param signature the signature of the message - * @return true if the signature has been verified, false otherwise. - */ - public boolean verifySignature(byte[] message, byte[] signature) - { - short[] sigInt = new short[signature.length]; - short tmp; - - for (int i = 0; i < signature.length; i++) - { - tmp = (short)signature[i]; - tmp &= (short)0xff; - sigInt[i] = tmp; - } - - short[] msgHashVal = makeMessageRepresentative(message); - - // verify - short[] verificationResult = verifySignatureIntern(sigInt); - - // compare - boolean verified = true; - if (msgHashVal.length != verificationResult.length) - { - return false; - } - for (int i = 0; i < msgHashVal.length; i++) - { - verified = verified && msgHashVal[i] == verificationResult[i]; - } - - return verified; - } - - /** - * Signature verification using public key - * - * @param signature vector of dimension n - * @return document hash of length n - v1 - */ - private short[] verifySignatureIntern(short[] signature) - { - - short[][] coeff_quadratic = ((RainbowPublicKeyParameters)this.key).getCoeffQuadratic(); - short[][] coeff_singular = ((RainbowPublicKeyParameters)this.key).getCoeffSingular(); - short[] coeff_scalar = ((RainbowPublicKeyParameters)this.key).getCoeffScalar(); - - short[] rslt = new short[coeff_quadratic.length];// n - v1 - int n = coeff_singular[0].length; - int offset = 0; // array position - short tmp = 0; // for scalar - - for (int p = 0; p < coeff_quadratic.length; p++) - { // no of polynomials - offset = 0; - for (int x = 0; x < n; x++) - { - // calculate quadratic terms - for (int y = x; y < n; y++) - { - tmp = GF2Field.multElem(coeff_quadratic[p][offset], - GF2Field.multElem(signature[x], signature[y])); - rslt[p] = GF2Field.addElem(rslt[p], tmp); - offset++; - } - // calculate singular terms - tmp = GF2Field.multElem(coeff_singular[p][x], signature[x]); - rslt[p] = GF2Field.addElem(rslt[p], tmp); - } - // add scalar - rslt[p] = GF2Field.addElem(rslt[p], coeff_scalar[p]); - } - - return rslt; - } - - /** - * This function creates the representative of the message which gets signed - * or verified. - * - * @param message the message - * @return message representative - */ - private short[] makeMessageRepresentative(byte[] message) - { - // the message representative - short[] output = new short[this.signableDocumentLength]; - - int h = 0; - int i = 0; - do - { - if (i >= message.length) - { - break; - } - output[i] = (short)message[h]; - output[i] &= (short)0xff; - h++; - i++; - } - while (i < output.length); - - return output; - } -} |