Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.bouncycastle.pqc.crypto.rainbow;
  
  
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.

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();
 
 
     public void init(boolean forSigning,
                      CipherParameters param)
     {
         if (forSigning)
         {
             if (param instanceof ParametersWithRandom)
             {
                 ParametersWithRandom rParam = (ParametersWithRandom)param;
 
                 this. = rParam.getRandom();
                 this. = (RainbowPrivateKeyParameters)rParam.getParameters();
 
             }
             else
             {
 
                 this. = new SecureRandom();
                 this. = (RainbowPrivateKeyParameters)param;
             }
         }
         else
         {
             this. = (RainbowPublicKeyParameters)param;
         }
 
         this. = this..getDocLength();
     }


    
initial operations before solving the Linear equation system.

Parameters:
layer the current layer for which a LES is to be solved.
msg the message that should be signed.
Returns:
Y_ the modified document needed for solving LES, (Y_ = A1^{-1}*(Y-b1)) linear map L1 = A1 x + b1.
 
     private short[] initSign(Layer[] layershort[] msg)
     {
 
         /* preparation: Modifies the document with the inverse of L1 */
         // tmp = Y - b1:
         short[] tmpVec = new short[msg.length];
 
         tmpVec = .addVect(((RainbowPrivateKeyParameters)this.).getB1(), msg);
 
         // Y_ = A1^{-1} * (Y - b1) :
         short[] Y_ = .multiplyMatrix(((RainbowPrivateKeyParameters)this.).getInvA1(), tmpVec);
 
         /* generates the vinegar vars of the first layer at random */
         for (int i = 0; i < layer[0].getVi(); i++)
         {
             [i] = (short).nextInt();
             [i] = (short)([i] & .);
         }
 
         return Y_;
     }

    
This function signs the message that has been updated, making use of the private key.

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.

The Vinegar-variables of the first layer are random generated.

Parameters:
message the message
Returns:
the signature of the message.
    public byte[] generateSignature(byte[] message)
    {
        Layer[] layer = ((RainbowPrivateKeyParameters)this.).getLayers();
        int numberOfLayers = layer.length;
         = new short[((RainbowPrivateKeyParameters)this.).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(layermsgHashVals);
                for (int i = 0; i < numberOfLayersi++)
                {
                    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 = .solveEquation(layer[i].plugInVinegars(), 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.lengthj++)
                    {
                        [layer[i].getVi() + j] = solVec[j];
                    }
                }
                /* apply the inverse of L2: (signature = A2^{-1}*(b2+x)) */
                tmpVec = .addVect(((RainbowPrivateKeyParameters)this.).getB2(), );
                signature = .multiplyMatrix(((RainbowPrivateKeyParameters)this.).getInvA2(), tmpVec);
                /* cast signature from short[] to byte[] */
                for (int i = 0; i < S.lengthi++)
                {
                    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.

Parameters:
message the message
signature the signature of the message
Returns:
true if the signature has been verified, false otherwise.
    public boolean verifySignature(byte[] messagebyte[] signature)
    {
        short[] sigInt = new short[signature.length];
        short tmp;
        for (int i = 0; i < signature.lengthi++)
        {
            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.lengthi++)
        {
            verified = verified && msgHashVal[i] == verificationResult[i];
        }
        return verified;
    }

    
Signature verification using public key

Parameters:
signature vector of dimension n
Returns:
document hash of length n - v1
    private short[] verifySignatureIntern(short[] signature)
    {
        short[][] coeff_quadratic = ((RainbowPublicKeyParameters)this.).getCoeffQuadratic();
        short[][] coeff_singular = ((RainbowPublicKeyParameters)this.).getCoeffSingular();
        short[] coeff_scalar = ((RainbowPublicKeyParameters)this.).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.lengthp++)
        { // no of polynomials
            offset = 0;
            for (int x = 0; x < nx++)
            {
                // calculate quadratic terms
                for (int y = xy < ny++)
                {
                    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.

Parameters:
message the message
Returns:
message representative
    private short[] makeMessageRepresentative(byte[] message)
    {
        // the message representative
        short[] output = new short[this.];
        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;
    }
New to GrepCode? Check out our FAQ X