コード例 #1
0
        /// <summary>
        /// Calculates the authpath for tree in layer h which starts with seed[h] additionally computes the rootSignature of underlaying root
        /// </summary>
        ///
        /// <param name="LowerRoot">Stores the root of the lower tree</param>
        /// <param name="CurrentStack">Stack used for the treehash instance created by this method</param>
        /// <param name="Seed">Starting seeds</param>
        /// <param name="H">Actual layer</param>
        /// <returns>An initialized GMSSRootCalc</returns>
        private GMSSRootCalc GenerateCurrentAuthpathAndRoot(byte[] LowerRoot, List <byte[]> CurrentStack, byte[] Seed, int H)
        {
            byte[] help    = new byte[_mdLength];
            byte[] OTSseed = new byte[_mdLength];
            OTSseed = _gmssRand.NextSeed(Seed);
            WinternitzOTSignature ots;
            // data structure that constructs the whole tree and stores the initial values for treehash, Auth and retain
            GMSSRootCalc treeToConstruct = new GMSSRootCalc(_heightOfTrees[H], m_K[H], GetDigest(_msgDigestType));

            treeToConstruct.Initialize(CurrentStack);

            // generate the first leaf
            if (H == _numLayer - 1)
            {
                ots  = new WinternitzOTSignature(OTSseed, GetDigest(_msgDigestType), _otsIndex[H]);
                help = ots.GetPublicKey();
            }
            else
            {
                // for all layers except the lowest, generate the signature of the underlying root
                // and reuse this signature to compute the first leaf of acual layer more efficiently (by verifiing the signature)
                ots = new WinternitzOTSignature(OTSseed, GetDigest(_msgDigestType), _otsIndex[H]);
                _currentRootSigs[H] = ots.GetSignature(LowerRoot);
                WinternitzOTSVerify otsver = new WinternitzOTSVerify(GetDigest(_msgDigestType), _otsIndex[H]);
                help = otsver.Verify(LowerRoot, _currentRootSigs[H]);
            }

            // update the tree with the first leaf
            treeToConstruct.Update(help);
            int seedForTreehashIndex = 3;
            int count = 0;

            // update the tree 2^(H) - 1 times, from the second to the last leaf
            for (int i = 1; i < (1 << _heightOfTrees[H]); i++)
            {
                // initialize the seeds for the leaf generation with index 3 * 2^h
                if (i == seedForTreehashIndex && count < _heightOfTrees[H] - m_K[H])
                {
                    treeToConstruct.InitializeTreehashSeed(Seed, count);
                    seedForTreehashIndex *= 2;
                    count++;
                }

                OTSseed = _gmssRand.NextSeed(Seed);
                ots     = new WinternitzOTSignature(OTSseed, GetDigest(_msgDigestType), _otsIndex[H]);
                treeToConstruct.Update(ots.GetPublicKey());
            }

            if (treeToConstruct.IsFinished())
            {
                return(treeToConstruct);
            }

            return(null);
        }
コード例 #2
0
        /// <summary>
        /// This function signs the message that has been updated, making use of the private key.
        /// <para>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.</para>
        /// </summary>
        ///
        /// <param name="Message">The message</param>
        ///
        /// <returns>The signature of the message</returns>
        private byte[] GenerateSignature(byte[] Message)
        {
            byte[] otsSig = new byte[_mdLength];
            byte[] authPathBytes;
            byte[] indexBytes;

            otsSig = _Ots.GetSignature(Message);
            // get concatenated lowest layer tree authentication path
            authPathBytes = GMSSUtil.ConcatenateArray(_currentAuthPaths[_numLayer - 1]);
            // put lowest layer index into a byte array
            indexBytes = GMSSUtil.IntToBytesLittleEndian(_index[_numLayer - 1]);
            // create first part of GMSS signature
            byte[] gmssSigFirstPart = new byte[indexBytes.Length + otsSig.Length + authPathBytes.Length];
            Array.Copy(indexBytes, 0, gmssSigFirstPart, 0, indexBytes.Length);
            Array.Copy(otsSig, 0, gmssSigFirstPart, indexBytes.Length, otsSig.Length);
            Array.Copy(authPathBytes, 0, gmssSigFirstPart, (indexBytes.Length + otsSig.Length), authPathBytes.Length);
            // create initial array with length 0 for iteration
            byte[] gmssSigNextPart = new byte[0];

            for (int i = _numLayer - 1 - 1; i >= 0; i--)
            {
                // get concatenated next tree authentication path
                authPathBytes = GMSSUtil.ConcatenateArray(_currentAuthPaths[i]);
                // put next tree index into a byte array
                indexBytes = GMSSUtil.IntToBytesLittleEndian(_index[i]);
                // create help array and copy actual gmssSig into it
                byte[] helpGmssSig = new byte[gmssSigNextPart.Length];
                Array.Copy(gmssSigNextPart, 0, helpGmssSig, 0, gmssSigNextPart.Length);
                // adjust length of gmssSigNextPart for adding next part
                gmssSigNextPart = new byte[helpGmssSig.Length + indexBytes.Length + _subtreeRootSig[i].Length + authPathBytes.Length];
                // copy old data (help array) and new data in gmssSigNextPart
                Array.Copy(helpGmssSig, 0, gmssSigNextPart, 0, helpGmssSig.Length);
                Array.Copy(indexBytes, 0, gmssSigNextPart, helpGmssSig.Length, indexBytes.Length);
                Array.Copy(_subtreeRootSig[i], 0, gmssSigNextPart, (helpGmssSig.Length + indexBytes.Length), _subtreeRootSig[i].Length);
                Array.Copy(authPathBytes, 0, gmssSigNextPart, (helpGmssSig.Length + indexBytes.Length + _subtreeRootSig[i].Length), authPathBytes.Length);
            }

            // concatenate the two parts of the GMSS signature
            byte[] gmssSig = new byte[gmssSigFirstPart.Length + gmssSigNextPart.Length];
            Array.Copy(gmssSigFirstPart, 0, gmssSig, 0, gmssSigFirstPart.Length);
            Array.Copy(gmssSigNextPart, 0, gmssSig, gmssSigFirstPart.Length, gmssSigNextPart.Length);

            // return the GMSS signature
            return(gmssSig);
        }