Exemple #1
0
        /// <summary>
        /// Calculates the authpath and root for tree in layer h which starts with seed[h]
        /// </summary>
        ///
        /// <param name="NextStack">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 GenerateNextAuthpathAndRoot(List <byte[]> NextStack, byte[] Seed, int H)
        {
            byte[] OTSseed = new byte[_numLayer];
            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(NextStack);
            int seedForTreehashIndex = 3;
            int count = 0;

            // update the tree 2^(H) times, from the first to the last leaf
            for (int i = 0; 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);
        }
Exemple #2
0
        /// <summary>
        /// Initializes the signature algorithm for signing a message
        /// </summary>
        private void InitSign()
        {
            _msgDigestTrees.Reset();
            // set private key and take from it ots key, auth, tree and key counter, rootSign
            GMSSPrivateKey gmssPrivateKey = (GMSSPrivateKey)m_asmKey;

            if (gmssPrivateKey.IsUsed)
            {
                throw new Exception("Private key already used");
            }

            // check if last signature has been generated
            if (gmssPrivateKey.GetCurrentIndex(0) >= gmssPrivateKey.GetNumLeafs(0))
            {
                throw new Exception("No more signatures can be generated");
            }

            // get numLayer
            _numLayer = _gmssPS.NumLayers;

            // get OTS Instance of lowest layer
            byte[] seed    = gmssPrivateKey.CurrentSeeds[_numLayer - 1];
            byte[] OTSSeed = new byte[_mdLength];
            byte[] dummy   = new byte[_mdLength];
            Array.Copy(seed, 0, dummy, 0, _mdLength);
            OTSSeed = _gmssRandom.NextSeed(dummy);
            _Ots    = new WinternitzOTSignature(OTSSeed, GetDigest(_gmssPS.DigestEngine), _gmssPS.WinternitzParameter[_numLayer - 1]);

            byte[][][] helpCurrentAuthPaths = gmssPrivateKey.CurrentAuthPaths;
            _currentAuthPaths = new byte[_numLayer][][];

            // copy the main tree authentication path
            for (int j = 0; j < _numLayer; j++)
            {
                _currentAuthPaths[j] = ArrayUtils.CreateJagged <byte[][]>(helpCurrentAuthPaths[j].Length, _mdLength);
                for (int i = 0; i < helpCurrentAuthPaths[j].Length; i++)
                {
                    Array.Copy(helpCurrentAuthPaths[j][i], 0, _currentAuthPaths[j][i], 0, _mdLength);
                }
            }

            // copy index
            _index = new int[_numLayer];
            Array.Copy(gmssPrivateKey.Index, 0, _index, 0, _numLayer);

            // copy subtreeRootSig
            byte[] helpSubtreeRootSig;
            _subtreeRootSig = new byte[_numLayer - 1][];
            for (int i = 0; i < _numLayer - 1; i++)
            {
                helpSubtreeRootSig = gmssPrivateKey.SubtreeRootSig(i);
                _subtreeRootSig[i] = new byte[helpSubtreeRootSig.Length];
                Array.Copy(helpSubtreeRootSig, 0, _subtreeRootSig[i], 0, helpSubtreeRootSig.Length);
            }

            if (gmssPrivateKey.GetCurrentIndex(0) >= gmssPrivateKey.GetNumLeafs(0))
            {
                gmssPrivateKey.IsUsed = true;
            }
        }
Exemple #3
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);
        }