示例#1
0
        public GMSSLeaf NextLeaf()
        {
            GMSSLeaf nextLeaf = new GMSSLeaf(this);

            nextLeaf.UpdateLeafCalc();

            return(nextLeaf);
        }
示例#2
0
        public static GMSSLeaf[] Clone(GMSSLeaf[] Data)
        {
            if (Data == null)
                return null;

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

            return copy;
        }
示例#3
0
 private GMSSLeaf(GMSSLeaf original)
 {
     _msgDigestOTS  = original._msgDigestOTS;
     _mdsize        = original._mdsize;
     m_keySize      = original.m_keySize;
     _gmssRandom    = original._gmssRandom;
     _leaf          = ArrayUtils.Clone(original._leaf);
     _concHashs     = ArrayUtils.Clone(original._concHashs);
     _ctr1          = original._ctr1;
     _ctr2          = original._ctr2;
     _twoPowerW     = original._twoPowerW;
     _W             = original._W;
     _steps         = original._steps;
     _seed          = ArrayUtils.Clone(original._seed);
     _privateKeyOTS = ArrayUtils.Clone(original._privateKeyOTS);
 }
示例#4
0
        /// <summary>
        /// 
        /// </summary>
        /// 
        /// <param name="Index">The tree indices</param>
        /// <param name="CurrentSeeds">A seed for the generation of private OTS keys for the current subtrees</param>
        /// <param name="NextNextSeeds">A seed for the generation of private OTS keys for the next subtrees</param>
        /// <param name="CurrentAuthPaths">Array of current authentication paths</param>
        /// <param name="NextAuthPaths">Array of next authentication paths</param>
        /// <param name="Keep">Keep array for the authPath algorithm</param>
        /// <param name="CurrentTreehash">Treehash for authPath algorithm of current tree</param>
        /// <param name="NextTreehash">Treehash for authPath algorithm of next tree (TREE+)</param>
        /// <param name="CurrentStack">Shared stack for authPath algorithm of current tree</param>
        /// <param name="NextStack">Shared stack for authPath algorithm of next tree (TREE+)</param>
        /// <param name="CurrentRetain">Retain stack for authPath algorithm of current tree</param>
        /// <param name="NextRetain">Retain stack for authPath algorithm of next tree (TREE+)</param>
        /// <param name="NextNextLeaf">Array of upcoming leafs of the tree after next (LEAF++) of each layer</param>
        /// <param name="UpperLeaf">Needed for precomputation of upper nodes</param>
        /// <param name="UpperTreehashLeaf">Needed for precomputation of upper treehash nodes</param>
        /// <param name="MinTreehash">Index of next treehash instance to receive an update</param>
        /// <param name="NextRoot">The roots of the next trees (ROOT+)</param>
        /// <param name="NextNextRoot">The roots of the tree after next (ROOT++)</param>
        /// <param name="CurrentRootSig">Array of signatures of the roots of the current subtrees (SIG)</param>
        /// <param name="NextRootSig">Array of signatures of the roots of the next subtree (SIG+)</param>
        /// <param name="ParameterSet">The GMSS Parameterset</param>
        /// <param name="Digest">The digest type</param>
        internal GMSSPrivateKey(int[] Index, byte[][] CurrentSeeds, byte[][] NextNextSeeds, byte[][][] CurrentAuthPaths, byte[][][] NextAuthPaths, byte[][][] Keep,
            Treehash[][] CurrentTreehash, Treehash[][] NextTreehash, List<byte[]>[] CurrentStack, List<byte[]>[] NextStack, List<byte[]>[][] CurrentRetain, List<byte[]>[][] NextRetain,
            GMSSLeaf[] NextNextLeaf, GMSSLeaf[] UpperLeaf, GMSSLeaf[] UpperTreehashLeaf, int[] MinTreehash, byte[][] NextRoot, GMSSRootCalc[] NextNextRoot, byte[][] CurrentRootSig,
            GMSSRootSig[] NextRootSig, GMSSParameters ParameterSet, Digests Digest)
        {
            _msgDigestType = Digest;
            // construct message digest
            _msgDigestTrees = GetDigest(Digest);
            _mdLength = _msgDigestTrees.DigestSize;
            // Parameter
            _gmssPS = ParameterSet;
            _otsIndex = ParameterSet.WinternitzParameter;
            _K = ParameterSet.K;
            _heightOfTrees = ParameterSet.HeightOfTrees;
            // initialize numLayer
            _numLayer = _gmssPS.NumLayers;

            // initialize index if null
            if (Index == null)
            {
                _index = new int[_numLayer];
                for (int i = 0; i < _numLayer; i++)
                    _index[i] = 0;
            }
            else
            {
                _index = Index;
            }

            _currentSeeds = CurrentSeeds;
            _nextNextSeeds = NextNextSeeds;
            _currentAuthPaths = CurrentAuthPaths;
            _nextAuthPaths = NextAuthPaths;

            // initialize keep if null
            if (Keep == null)
            {
                _keep = new byte[_numLayer][][];

                for (int i = 0; i < _numLayer; i++)
                    _keep[i] = ArrayUtils.CreateJagged<byte[][]>((int)Math.Floor((decimal)_heightOfTrees[i] / 2), _mdLength);
            }
            else
            {
                _keep = Keep;
            }

            // initialize stack if null
            if (CurrentStack == null)
            {
                _currentStack = new List<byte[]>[_numLayer];
                for (int i = 0; i < _numLayer; i++)
                    _currentStack[i] = new List<byte[]>();
            }
            else
            {
                _currentStack = CurrentStack;
            }

            // initialize nextStack if null
            if (NextStack == null)
            {
                _nextStack = new List<byte[]>[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                    _nextStack[i] = new List<byte[]>();
            }
            else
            {
                _nextStack = NextStack;
            }

            _currentTreehash = CurrentTreehash;
            _nextTreehash = NextTreehash;
            _currentRetain = CurrentRetain;
            _nextRetain = NextRetain;
            _nextRoot = NextRoot;

            if (NextNextRoot == null)
            {
                NextNextRoot = new GMSSRootCalc[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                    NextNextRoot[i] = new GMSSRootCalc(_heightOfTrees[i + 1], _K[i + 1], GetDigest(Digest));
            }
            else
            {
                _nextNextRoot = NextNextRoot;
            }
            _currentRootSig = CurrentRootSig;

            // calculate numLeafs
            _numLeafs = new int[_numLayer];
            for (int i = 0; i < _numLayer; i++)
                _numLeafs[i] = 1 << _heightOfTrees[i];

            // construct PRNG
            _gmssRandom = new GMSSRandom(_msgDigestTrees);

            if (_numLayer > 1)
            {
                // construct the nextNextLeaf (LEAFs++) array for upcoming leafs in
                // tree after next (TREE++)
                if (NextNextLeaf == null)
                {
                    _nextNextLeaf = new GMSSLeaf[_numLayer - 2];
                    for (int i = 0; i < _numLayer - 2; i++)
                        _nextNextLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i + 1], _numLeafs[i + 2], _nextNextSeeds[i]);
                }
                else
                {
                    _nextNextLeaf = NextNextLeaf;
                }
            }
            else
            {
                _nextNextLeaf = new GMSSLeaf[0];
            }

            // construct the upperLeaf array for upcoming leafs in tree over the
            // actual
            if (UpperLeaf == null)
            {
                _upperLeaf = new GMSSLeaf[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                    _upperLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i], _numLeafs[i + 1], _currentSeeds[i]);
            }
            else
            {
                _upperLeaf = UpperLeaf;
            }

            // construct the leafs for upcoming leafs in treehashs in tree over the actual
            if (UpperTreehashLeaf == null)
            {
                _upperTreehashLeaf = new GMSSLeaf[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                    _upperTreehashLeaf[i] = new GMSSLeaf(GetDigest(Digest), _otsIndex[i], _numLeafs[i + 1]);
            }
            else
            {
                _upperTreehashLeaf = UpperTreehashLeaf;
            }

            if (MinTreehash == null)
            {
                _minTreehash = new int[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                    _minTreehash[i] = -1;
            }
            else
            {
                _minTreehash = MinTreehash;
            }

            // construct the nextRootSig (RootSig++)
            byte[] dummy = new byte[_mdLength];
            byte[] OTSseed = new byte[_mdLength];

            if (NextRootSig == null)
            {
                _nextRootSig = new GMSSRootSig[_numLayer - 1];
                for (int i = 0; i < _numLayer - 1; i++)
                {
                    Array.Copy(CurrentSeeds[i], 0, dummy, 0, _mdLength);
                    _gmssRandom.NextSeed(dummy);
                    OTSseed = _gmssRandom.NextSeed(dummy);
                    _nextRootSig[i] = new GMSSRootSig(GetDigest(Digest), _otsIndex[i], _heightOfTrees[i + 1]);
                    _nextRootSig[i].InitSign(OTSseed, NextRoot[i]);
                }
            }
            else
            {
                _nextRootSig = NextRootSig;
            }
        }
示例#5
0
        /// <summary>
        /// This method computes the authpath (AUTH) for the current tree.
        /// Additionally the root signature for the next tree (SIG+), the authpath
        /// (AUTH++) and root (ROOT++) for the tree after next in layer
        /// <c>layer</c>, and the LEAF++^1 for the next next tree in the
        /// layer above are updated This method is used by nextKey()
        /// </summary>
        /// 
        /// <param name="Layer"></param>
        private void UpdateKey(int Layer)
        {
            // current tree processing of actual layer //
            // compute upcoming authpath for current Tree (AUTH)
            ComputeAuthPaths(Layer);

            // distributed calculations part //
            // not for highest tree layer
            if (Layer > 0)
            {
                // compute (partial) next leaf on TREE++ (not on layer 1 and 0)
                if (Layer > 1)
                    _nextNextLeaf[Layer - 1 - 1] = _nextNextLeaf[Layer - 1 - 1].NextLeaf();

                // compute (partial) next leaf on tree above (not on layer 0)
                _upperLeaf[Layer - 1] = _upperLeaf[Layer - 1].NextLeaf();
                // compute (partial) next leaf for all treehashs on tree above (not on layer 0)
                int t = (int)Math.Floor((double)(GetNumLeafs(Layer) * 2) / (double)(_heightOfTrees[Layer - 1] - _K[Layer - 1]));

                if (_index[Layer] % t == 1)
                {
                    // take precomputed node for treehash update
                    if (_index[Layer] > 1 && _minTreehash[Layer - 1] >= 0)
                    {
                        byte[] leaf = _upperTreehashLeaf[Layer - 1].GetLeaf();
                        // if update is required use the precomputed leaf to update treehash
                        try
                        {
                            _currentTreehash[Layer - 1][_minTreehash[Layer - 1]].Update(_gmssRandom, leaf);
                        }
                        catch
                        {
                        }
                    }

                    // initialize next leaf precomputation //
                    // get lowest index of treehashs
                    _minTreehash[Layer - 1] = GetMinTreehashIndex(Layer - 1);

                    if (_minTreehash[Layer - 1] >= 0)
                    {
                        // initialize leaf
                        byte[] seed = _currentTreehash[Layer - 1][_minTreehash[Layer - 1]].GetSeedActive();
                        _upperTreehashLeaf[Layer - 1] = new GMSSLeaf(GetDigest(_msgDigestType), _otsIndex[Layer - 1], t, seed);
                        _upperTreehashLeaf[Layer - 1] = _upperTreehashLeaf[Layer - 1].NextLeaf();
                    }

                }
                else
                {
                    // update the upper leaf for the treehash one step
                    if (_minTreehash[Layer - 1] >= 0)
                        _upperTreehashLeaf[Layer - 1] = _upperTreehashLeaf[Layer - 1].NextLeaf();
                }

                // compute (partial) the signature of ROOT+ (RootSig+) (not on top layer)
                _nextRootSig[Layer - 1].UpdateSign();
                // compute (partial) AUTHPATH++ & ROOT++ (not on top layer)
                // init root and authpath calculation for tree after next (AUTH++, ROOT++)
                if (_index[Layer] == 1)
                    _nextNextRoot[Layer - 1].Initialize(new List<byte[]>());

                // update root and authpath calculation for tree after next (AUTH++, ROOT++)
                UpdateNextNextAuthRoot(Layer);
            }
        }
示例#6
0
        public GMSSLeaf NextLeaf()
        {
            GMSSLeaf nextLeaf = new GMSSLeaf(this);
            nextLeaf.UpdateLeafCalc();

            return nextLeaf;
        }
示例#7
0
 private GMSSLeaf(GMSSLeaf original)
 {
     _msgDigestOTS = original._msgDigestOTS;
     _mdsize = original._mdsize;
     _keysize = original._keysize;
     _gmssRandom = original._gmssRandom;
     _leaf = ArrayUtils.Clone(original._leaf);
     _concHashs = ArrayUtils.Clone(original._concHashs);
     _ctr1 = original._ctr1;
     _ctr2 = original._ctr2;
     _twoPowerW = original._twoPowerW;
     _W = original._W;
     _steps = original._steps;
     _seed = ArrayUtils.Clone(original._seed);
     _privateKeyOTS = ArrayUtils.Clone(original._privateKeyOTS);
 }