public GMSSLeaf NextLeaf() { GMSSLeaf nextLeaf = new GMSSLeaf(this); nextLeaf.UpdateLeafCalc(); return(nextLeaf); }
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; }
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); }
/// <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; } }
/// <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); } }
public GMSSLeaf NextLeaf() { GMSSLeaf nextLeaf = new GMSSLeaf(this); nextLeaf.UpdateLeafCalc(); return nextLeaf; }
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); }