/// <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();
        }
        /// <summary>
        /// This function generates the invertible affine linear map L2 = A2*x + b2.
        /// <para>The translation part b2, is stored in a separate array.
        /// The inverse of the matrix-part of L2 A2inv is also computed here.
        /// This linear map hides the output of the map F. It is on k^(n).</para>
        /// </summary>
        private void GenerateL2()
        {
            // dimension = n = vi[last]
            int dim = _VI[_VI.Length - 1];
            _A2 = ArrayUtils.CreateJagged<short[][]>(dim, dim);
            _A2Inv = null;

            using (ComputeInField cif = new ComputeInField())
            {
                // generation of A2 at random
                while (_A2Inv == null)
                {
                    for (int i = 0; i < dim; i++)
                    {
                        for (int j = 0; j < dim; j++)
                            _A2[i][j] = (short)(_rngEngine.Next() & GF2Field.MASK);
                    }
                    _A2Inv = cif.Inverse(_A2);
                }
            }
            // generation of the translation vector at random
            _B2 = new short[dim];
            for (int i = 0; i < dim; i++)
                _B2[i] = (short)(_rngEngine.Next() & GF2Field.MASK);
        }
Esempio n. 3
0
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_dgtEngine != null)
                    {
                        _dgtEngine.Dispose();
                        _dgtEngine = null;
                    }
                    if (_rndEngine != null)
                    {
                        _rndEngine.Dispose();
                        _rndEngine = null;
                    }
                    if (_cptIf != null)
                    {
                        _cptIf.Dispose();
                        _cptIf = null;
                    }
                    if (_X != null)
                    {
                        Array.Clear(_X, 0, _X.Length);
                        _X = null;
                    }
                }
                catch { }

                _isDisposed = true;
            }
        }