Exemple #1
0
        /// <summary>
        /// The quadratic (or mixed) terms of the public key are compacted from a n x
        /// n matrix per polynomial to an upper diagonal matrix stored in one integer
        /// array of n (n + 1) / 2 elements per polynomial.
        /// <para>The ordering of elements is lexicographic and the result is updating _pubQuadratic,
        /// which stores the quadratic elements of the public key.</para>
        /// </summary>
        /// <param name="Quadratic">A 3-dimensional array containing a n x n Matrix for each of the n - v1 polynomials</param>
        private void CompactPublicKey(short[][][] Quadratic)
        {
            int polynomials = Quadratic.Length;
            int n           = Quadratic[0].Length;
            int entries     = n * (n + 1) / 2;// the small gauss

            _pubQuadratic = ArrayUtils.CreateJagged <short[][]>(polynomials, entries);
            int offset = 0;

            for (int p = 0; p < polynomials; p++)
            {
                offset = 0;
                for (int x = 0; x < n; x++)
                {
                    for (int y = x; y < n; y++)
                    {
                        if (y == x)
                        {
                            _pubQuadratic[p][offset] = Quadratic[p][x][y];
                        }
                        else
                        {
                            _pubQuadratic[p][offset] = GF2Field.AddElem(Quadratic[p][x][y], Quadratic[p][y][x]);
                        }

                        offset++;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Signature verification using public key
        /// </summary>
        ///
        /// <param name="Signature">The signature vector of dimension n</param>
        /// <returns>Returns document hash of length n - v1</returns>
        private short[] VerifySignatureIntern(short[] Signature)
        {
            short[][] coeffQuadratic = ((RNBWPublicKey)this.m_asmKey).CoeffQuadratic;
            short[][] coeffSingular  = ((RNBWPublicKey)this.m_asmKey).CoeffSingular;
            short[]   coeffScalar    = ((RNBWPublicKey)this.m_asmKey).CoeffScalar;

            short[] rslt   = new short[coeffQuadratic.Length]; // n - v1
            int     n      = coeffSingular[0].Length;
            int     offset = 0;                                // array position
            short   tmp    = 0;                                // for scalar

            for (int p = 0; p < coeffQuadratic.Length; p++)
            {
                offset = 0;
                for (int x = 0; x < n; x++)
                {
                    // calculate quadratic terms
                    for (int y = x; y < n; y++)
                    {
                        tmp     = GF2Field.MultElem(coeffQuadratic[p][offset], GF2Field.MultElem(Signature[x], Signature[y]));
                        rslt[p] = GF2Field.AddElem(rslt[p], tmp);
                        offset++;
                    }
                    // calculate singular terms
                    tmp     = GF2Field.MultElem(coeffSingular[p][x], Signature[x]);
                    rslt[p] = GF2Field.AddElem(rslt[p], tmp);
                }
                // add scalar
                rslt[p] = GF2Field.AddElem(rslt[p], coeffScalar[p]);
            }

            return(rslt);
        }
Exemple #3
0
        /// <summary>
        /// This function computes the public key from the private key.
        /// <para>The composition of F with L2 is computed, followed by applying L1 to the composition's result.
        /// The singular and scalar values constitute to the public key as is, the quadratic terms are compacted in CompactPublicKey.</para>
        /// </summary>
        private void ComputePublicKey()
        {
            ComputeInField cif  = new ComputeInField();
            int            rows = _VI[_VI.Length - 1] - _VI[0];
            int            vars = _VI[_VI.Length - 1];

            // Fpub
            short[][][] coeffQuadratic3d = ArrayUtils.CreateJagged <short[][][]>(rows, vars, vars);
            _pubSingular = ArrayUtils.CreateJagged <short[][]>(rows, vars);
            _pubScalar   = new short[rows];
            // Coefficients of layers of Private Key F
            short[][][] coeffAlpha;
            short[][][] coeffBeta;
            short[][]   coeffGamma;
            short[]     coeffEta;
            // Needed for counters;
            int oils = 0;
            int vins = 0;
            // current row (polynomial)
            int crntRow = 0;

            short[] vectTmp = new short[vars]; // vector tmp;
            short   sclrTmp = 0;

            // Composition of F and L2: Insert L2 = A2*x+b2 in F
            for (int l = 0; l < _layers.Length; l++)
            {
                // get coefficients of current layer
                coeffAlpha = _layers[l].CoeffAlpha;
                coeffBeta  = _layers[l].CoeffBeta;
                coeffGamma = _layers[l].CoeffGamma;
                coeffEta   = _layers[l].CoeffEta;
                oils       = coeffAlpha[0].Length;
                vins       = coeffBeta[0].Length;

                // compute polynomials of layer
                for (int p = 0; p < oils; p++)
                {
                    // multiply alphas
                    for (int x1 = 0; x1 < oils; x1++)
                    {
                        for (int x2 = 0; x2 < vins; x2++)
                        {
                            // multiply polynomial1 with polynomial2
                            vectTmp = cif.MultVect(coeffAlpha[p][x1][x2], _A2[x1 + vins]);
                            coeffQuadratic3d[crntRow + p] = cif.AddSquareMatrix(coeffQuadratic3d[crntRow + p], cif.MultVects(vectTmp, _A2[x2]));
                            // mul poly1 with scalar2
                            vectTmp = cif.MultVect(_B2[x2], vectTmp);
                            _pubSingular[crntRow + p] = cif.AddVect(vectTmp, _pubSingular[crntRow + p]);
                            // mul scalar1 with poly2
                            vectTmp = cif.MultVect(coeffAlpha[p][x1][x2], _A2[x2]);
                            vectTmp = cif.MultVect(_B2[x1 + vins], vectTmp);
                            _pubSingular[crntRow + p] = cif.AddVect(vectTmp, _pubSingular[crntRow + p]);
                            // mul scalar1 with scalar2
                            sclrTmp = GF2Field.MultElem(coeffAlpha[p][x1][x2], _B2[x1 + vins]);
                            _pubScalar[crntRow + p] = GF2Field.AddElem(_pubScalar[crntRow + p], GF2Field.MultElem(sclrTmp, _B2[x2]));
                        }
                    }

                    // multiply betas
                    for (int x1 = 0; x1 < vins; x1++)
                    {
                        for (int x2 = 0; x2 < vins; x2++)
                        {
                            // multiply polynomial1 with polynomial2
                            vectTmp = cif.MultVect(coeffBeta[p][x1][x2], _A2[x1]);
                            coeffQuadratic3d[crntRow + p] = cif.AddSquareMatrix(coeffQuadratic3d[crntRow + p], cif.MultVects(vectTmp, _A2[x2]));
                            // mul poly1 with scalar2
                            vectTmp = cif.MultVect(_B2[x2], vectTmp);
                            _pubSingular[crntRow + p] = cif.AddVect(vectTmp, _pubSingular[crntRow + p]);
                            // mul scalar1 with poly2
                            vectTmp = cif.MultVect(coeffBeta[p][x1][x2], _A2[x2]);
                            vectTmp = cif.MultVect(_B2[x1], vectTmp);
                            _pubSingular[crntRow + p] = cif.AddVect(vectTmp, _pubSingular[crntRow + p]);
                            // mul scalar1 with scalar2
                            sclrTmp = GF2Field.MultElem(coeffBeta[p][x1][x2], _B2[x1]);
                            _pubScalar[crntRow + p] = GF2Field.AddElem(_pubScalar[crntRow + p], GF2Field.MultElem(sclrTmp, _B2[x2]));
                        }
                    }

                    // multiply gammas
                    for (int n = 0; n < vins + oils; n++)
                    {
                        // mul poly with scalar
                        vectTmp = cif.MultVect(coeffGamma[p][n], _A2[n]);
                        _pubSingular[crntRow + p] = cif.AddVect(vectTmp, _pubSingular[crntRow + p]);
                        // mul scalar with scalar
                        _pubScalar[crntRow + p] = GF2Field.AddElem(_pubScalar[crntRow + p], GF2Field.MultElem(coeffGamma[p][n], _B2[n]));
                    }
                    // add eta
                    _pubScalar[crntRow + p] = GF2Field.AddElem(_pubScalar[crntRow + p], coeffEta[p]);
                }

                crntRow = crntRow + oils;
            }

            // Apply L1 = A1*x+b1 to composition of F and L2
            // temporary coefficient arrays
            short[][][] tmpQuad = ArrayUtils.CreateJagged <short[][][]>(rows, vars, vars);
            short[][]   tmpSing = ArrayUtils.CreateJagged <short[][]>(rows, vars);
            short[]     tmpScal = new short[rows];

            for (int r = 0; r < rows; r++)
            {
                for (int q = 0; q < _A1.Length; q++)
                {
                    tmpQuad[r] = cif.AddSquareMatrix(tmpQuad[r], cif.MultMatrix(_A1[r][q], coeffQuadratic3d[q]));
                    tmpSing[r] = cif.AddVect(tmpSing[r], cif.MultVect(_A1[r][q], _pubSingular[q]));
                    tmpScal[r] = GF2Field.AddElem(tmpScal[r], GF2Field.MultElem(_A1[r][q], _pubScalar[q]));
                }

                tmpScal[r] = GF2Field.AddElem(tmpScal[r], _B1[r]);
            }

            // set public key
            coeffQuadratic3d = tmpQuad;
            _pubSingular     = tmpSing;
            _pubScalar       = tmpScal;

            CompactPublicKey(coeffQuadratic3d);
            cif.Dispose();
        }