Example #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);
        }
Example #2
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);
        }
Example #3
0
        public static GMSSRootCalc[] Clone(GMSSRootCalc[] Data)
        {
            if (Data == null)
            {
                return(null);
            }

            GMSSRootCalc[] copy = new GMSSRootCalc[Data.Length];
            Array.Copy(Data, 0, copy, 0, Data.Length);

            return(copy);
        }
Example #4
0
        /// <summary>
        /// Generate an encryption Key pair
        /// </summary>
        ///
        /// <returns>A GMSSKeyPair containing public and private keys</returns>
        public IAsymmetricKeyPair GenerateKeyPair()
        {
            // initialize authenticationPaths and treehash instances
            byte[][][]        currentAuthPaths = new byte[_numLayer][][];
            byte[][][]        nextAuthPaths    = new byte[_numLayer - 1][][];
            Treehash[][]      currentTreehash  = new Treehash[_numLayer][];
            Treehash[][]      nextTreehash     = new Treehash[_numLayer - 1][];
            List <byte[]>[]   currentStack     = new List <byte[]> [_numLayer];
            List <byte[]>[]   nextStack        = new List <byte[]> [_numLayer - 1];
            List <byte[]>[][] currentRetain    = new List <byte[]> [_numLayer][];
            List <byte[]>[][] nextRetain       = new List <byte[]> [_numLayer - 1][];

            for (int i = 0; i < _numLayer; i++)
            {
                currentAuthPaths[i] = ArrayUtils.CreateJagged <byte[][]>(_heightOfTrees[i], _mdLength);//new byte[heightOfTrees[i]][mdLength];
                currentTreehash[i]  = new Treehash[_heightOfTrees[i] - m_K[i]];

                if (i > 0)
                {
                    nextAuthPaths[i - 1] = ArrayUtils.CreateJagged <byte[][]>(_heightOfTrees[i], _mdLength);//new byte[heightOfTrees[i]][mdLength];
                    nextTreehash[i - 1]  = new Treehash[_heightOfTrees[i] - m_K[i]];
                }

                currentStack[i] = new List <byte[]>();
                if (i > 0)
                {
                    nextStack[i - 1] = new List <byte[]>();
                }
            }

            // initialize roots
            byte[][] currentRoots = ArrayUtils.CreateJagged <byte[][]>(_numLayer, _mdLength);
            byte[][] nextRoots    = ArrayUtils.CreateJagged <byte[][]>(_numLayer - 1, _mdLength);
            // initialize seeds
            byte[][] seeds = ArrayUtils.CreateJagged <byte[][]>(_numLayer, _mdLength);

            // initialize seeds[] by copying starting-seeds of first trees of each layer
            for (int i = 0; i < _numLayer; i++)
            {
                Array.Copy(_currentSeeds[i], 0, seeds[i], 0, _mdLength);
            }

            // initialize rootSigs
            _currentRootSigs = ArrayUtils.CreateJagged <byte[][]>(_numLayer - 1, _mdLength);//new byte[numLayer - 1][mdLength];

            // calculation of current authpaths and current rootsigs (AUTHPATHS, SIG) from bottom up to the root
            for (int h = _numLayer - 1; h >= 0; h--)
            {
                GMSSRootCalc tree = new GMSSRootCalc(_heightOfTrees[h], m_K[h], GetDigest(_msgDigestType));
                try
                {
                    // on lowest layer no lower root is available, so just call the method with null as first parameter
                    if (h == _numLayer - 1)
                    {
                        tree = GenerateCurrentAuthpathAndRoot(null, currentStack[h], seeds[h], h);
                    }
                    else
                    {
                        // otherwise call the method with the former computed root value
                        tree = GenerateCurrentAuthpathAndRoot(currentRoots[h + 1], currentStack[h], seeds[h], h);
                    }
                }
                catch
                {
                }

                // set initial values needed for the private key construction
                for (int i = 0; i < _heightOfTrees[h]; i++)
                {
                    Array.Copy(tree.GetAuthPath()[i], 0, currentAuthPaths[h][i], 0, _mdLength);
                }

                currentRetain[h]   = tree.GetRetain();
                currentTreehash[h] = tree.GetTreehash();
                Array.Copy(tree.GetRoot(), 0, currentRoots[h], 0, _mdLength);
            }

            // calculation of next authpaths and next roots (AUTHPATHS+, ROOTS+)
            for (int h = _numLayer - 2; h >= 0; h--)
            {
                GMSSRootCalc tree = GenerateNextAuthpathAndRoot(nextStack[h], seeds[h + 1], h + 1);

                // set initial values needed for the private key construction
                for (int i = 0; i < _heightOfTrees[h + 1]; i++)
                {
                    Array.Copy(tree.GetAuthPath()[i], 0, nextAuthPaths[h][i], 0, _mdLength);
                }

                nextRetain[h]   = tree.GetRetain();
                nextTreehash[h] = tree.GetTreehash();
                Array.Copy(tree.GetRoot(), 0, nextRoots[h], 0, _mdLength);
                // create seed for the Merkle tree after next (nextNextSeeds) SEEDs++
                Array.Copy(seeds[h + 1], 0, _nextNextSeeds[h], 0, _mdLength);
            }

            // generate JDKGMSSPublicKey
            int[]  len   = new int[] { currentRoots[0].Length };
            byte[] btlen = new byte[4];
            Buffer.BlockCopy(len, 0, btlen, 0, btlen.Length);

            GMSSPublicKey pubKey = new GMSSPublicKey(ArrayUtils.Concat(btlen, currentRoots[0]));

            // generate the JDKGMSSPrivateKey
            GMSSPrivateKey privKey = new GMSSPrivateKey(_currentSeeds, _nextNextSeeds, currentAuthPaths, nextAuthPaths, currentTreehash,
                                                        nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextRoots, _currentRootSigs, _gmssParams, _msgDigestType);

            // return the KeyPair
            return(new GMSSKeyPair(pubKey, privKey));
        }