Exemple #1
0
 /// <summary>
 /// This constructor regenerates a prior GMSSLeaf object
 /// </summary>
 /// 
 /// <param name="Digest">The hash function</param>
 /// <param name="OtsIndex">The status bytes</param>
 /// <param name="NumLeafs">The status ints</param>
 public GMSSLeaf(IDigest Digest, byte[][] OtsIndex, int[] NumLeafs)
 {
     _ctr1 = NumLeafs[0];
     _ctr2 = NumLeafs[1];
     _steps = NumLeafs[2];
     _W = NumLeafs[3];
     _msgDigestOTS = Digest;
     _gmssRandom = new GMSSRandom(_msgDigestOTS);
     // calulate keysize for private key and the help array
     _mdsize = _msgDigestOTS.DigestSize;
     int mdsizeBit = _mdsize << 3;
     int messagesize = (int)Math.Ceiling((double)(mdsizeBit) / (double)_W);
     int checksumsize = GetLog((messagesize << _W) + 1);
     _keysize = messagesize + (int)Math.Ceiling((double)checksumsize / (double)_W);
     _twoPowerW = 1 << _W;
     // initialize arrays
     _privateKeyOTS = OtsIndex[0];
     _seed = OtsIndex[1];
     _concHashs = OtsIndex[2];
     _leaf = OtsIndex[3];
 }
        /// <summary>
        /// The constructor generates an OTS key pair, using <c>seed0</c> and the PRNG
        /// </summary>
        /// 
        /// <param name="Seed">The seed for the PRGN</param>
        /// <param name="Digest">The used hash function</param>
        /// <param name="W">The Winternitz parameter</param>
        public WinternitzOTSignature(byte[] Seed, IDigest Digest, int W)
        {
            _W = W;
            _msgDigestOTS = Digest;
            _gmssRandom = new GMSSRandom(_msgDigestOTS);
            // calulate keysize for private and public key and also the help array
            _mdsize = _msgDigestOTS.DigestSize;
            int mdsizeBit = _mdsize << 3;
            _msgSize = (int)Math.Ceiling((double)(mdsizeBit) / (double)W);
            _ckmSize = GetLog((_msgSize << W) + 1);
            _keysize = _msgSize + (int)Math.Ceiling((double)_ckmSize / (double)W);
            // define the private key messagesize
            _privateKeyOTS = ArrayUtils.CreateJagged<byte[][]>(_keysize, _mdsize);
            // gmssRandom.setSeed(seed0);
            byte[] dummy = new byte[_mdsize];
            Array.Copy(Seed, 0, dummy, 0, dummy.Length);

            // generate random bytes and assign them to the private key
            for (int i = 0; i < _keysize; i++)
                _privateKeyOTS[i] = _gmssRandom.NextSeed(dummy);
        }
Exemple #3
0
        /// <summary>
        /// This constructor regenerates a prior GMSSRootSig object used by the GMSSPrivateKeyASN.1 class
        /// </summary>
        /// 
        /// <param name="Digest">The hash function</param>
        /// <param name="StatByte">The status byte array</param>
        /// <param name="StatInt">The status int array</param>
        public GMSSRootSig(IDigest Digest, byte[][] StatByte, int[] StatInt)
        {
            _msgDigestOTS = Digest;
            _gmssRand = new GMSSRandom(_msgDigestOTS);
            _Counter = StatInt[0];
            _testCtr = StatInt[1];
            _iI = StatInt[2];
            _R = StatInt[3];
            _steps = StatInt[4];
            _keySize = StatInt[5];
            _height = StatInt[6];
            _W = StatInt[7];
            _chkSum = StatInt[8];
            _mdSize = _msgDigestOTS.DigestSize;
            _K = (1 << _W) - 1;
            int mdsizeBit = _mdSize << 3;
            _msgSize = (int)Math.Ceiling((double)(mdsizeBit) / (double)_W);
            _privateKeyOTS = StatByte[0];
            _otsSeed = StatByte[1];
            _msgHash = StatByte[2];
            _sgnCode = StatByte[3];

            _test8 = ((StatByte[4][0] & 0xff)) |
                ((long)(StatByte[4][1] & 0xff) << 8) |
                ((long)(StatByte[4][2] & 0xff) << 16) |
                ((long)(StatByte[4][3] & 0xff)) << 24 |
                ((long)(StatByte[4][4] & 0xff)) << 32 |
                ((long)(StatByte[4][5] & 0xff)) << 40 |
                ((long)(StatByte[4][6] & 0xff)) << 48 |
                ((long)(StatByte[4][7] & 0xff)) << 56;

            _big8 = ((StatByte[4][8] & 0xff)) |
                ((long)(StatByte[4][9] & 0xff) << 8) |
                ((long)(StatByte[4][10] & 0xff) << 16) |
                ((long)(StatByte[4][11] & 0xff)) << 24 |
                ((long)(StatByte[4][12] & 0xff)) << 32 |
                ((long)(StatByte[4][13] & 0xff)) << 40 |
                ((long)(StatByte[4][14] & 0xff)) << 48 |
                ((long)(StatByte[4][15] & 0xff)) << 56;
        }
Exemple #4
0
        /// <summary>
        /// The constructor generates an OTS key pair, using <c>seed0</c> and the PRNG
        /// </summary>
        ///
        /// <param name="Seed">The seed for the PRGN</param>
        /// <param name="Digest">The used hash function</param>
        /// <param name="W">The Winternitz parameter</param>
        public WinternitzOTSignature(byte[] Seed, IDigest Digest, int W)
        {
            _W            = W;
            _msgDigestOTS = Digest;
            _gmssRandom   = new GMSSRandom(_msgDigestOTS);
            // calulate keysize for private and public key and also the help array
            _mdsize = _msgDigestOTS.DigestSize;
            int mdsizeBit = _mdsize << 3;

            _msgSize  = (int)Math.Ceiling((double)(mdsizeBit) / (double)W);
            _ckmSize  = GetLog((_msgSize << W) + 1);
            m_keySize = _msgSize + (int)Math.Ceiling((double)_ckmSize / (double)W);
            // define the private key messagesize
            _privateKeyOTS = ArrayUtils.CreateJagged <byte[][]>(m_keySize, _mdsize);
            // gmssRandom.setSeed(seed0);
            byte[] dummy = new byte[_mdsize];
            Array.Copy(Seed, 0, dummy, 0, dummy.Length);

            // generate random bytes and assign them to the private key
            for (int i = 0; i < m_keySize; i++)
            {
                _privateKeyOTS[i] = _gmssRandom.NextSeed(dummy);
            }
        }
Exemple #5
0
 /// <summary>
 /// Initialize this class
 /// </summary>
 /// 
 /// <param name="CipherParams">The GMSS cipher used to encrypt the hash</param>
 public GMSSSign(GMSSParameters CipherParams)
 {
     _gmssPS = CipherParams;
     _msgDigestTrees = GetDigest(CipherParams.DigestEngine);
     _msgDigestOTS = _msgDigestTrees;
     _mdLength = _msgDigestTrees.DigestSize;
     _gmssRandom = new GMSSRandom(_msgDigestTrees);
 }
 /// <summary>
 /// Copy Constructor
 /// </summary>
 /// 
 /// <param name="PrivateKey">The GMSSPrivateKey to copy</param>
 private GMSSPrivateKey(GMSSPrivateKey PrivateKey)
 {
     _index = ArrayUtils.Clone(PrivateKey._index);
     _currentSeeds = GMSSUtil.Clone(PrivateKey._currentSeeds);
     _nextNextSeeds = GMSSUtil.Clone(PrivateKey._nextNextSeeds);
     _currentAuthPaths = GMSSUtil.Clone(PrivateKey._currentAuthPaths);
     _nextAuthPaths = GMSSUtil.Clone(PrivateKey._nextAuthPaths);
     _keep = GMSSUtil.Clone(PrivateKey._keep);
     _currentTreehash = PrivateKey._currentTreehash;
     _nextTreehash = PrivateKey._nextTreehash;
     _currentStack = PrivateKey._currentStack;
     _nextStack = PrivateKey._nextStack;
     _currentRetain = PrivateKey._currentRetain;
     _nextRetain = PrivateKey._nextRetain;
     _nextNextLeaf = PrivateKey._nextNextLeaf; //N
     _upperLeaf = PrivateKey._upperLeaf; //N
     _upperTreehashLeaf = PrivateKey._upperTreehashLeaf; //N
     _minTreehash = PrivateKey._minTreehash; //N
     _nextRoot = GMSSUtil.Clone(PrivateKey._nextRoot);
     _nextNextRoot = PrivateKey._nextNextRoot; //N
     _currentRootSig = PrivateKey._currentRootSig;
     _nextRootSig = PrivateKey._nextRootSig; //N
     _gmssPS = PrivateKey._gmssPS;
     _msgDigestType = PrivateKey._msgDigestType;
     _heightOfTrees = PrivateKey._heightOfTrees;
     _otsIndex = PrivateKey._otsIndex;
     _K = PrivateKey._K;
     _numLayer = PrivateKey._numLayer;
     _msgDigestTrees = PrivateKey._msgDigestTrees;
     _mdLength = PrivateKey._mdLength;
     _gmssRandom = PrivateKey._gmssRandom;
     _numLeafs = PrivateKey._numLeafs;
 }
        /// <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;
            }
        }
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_index != null)
                    {
                        Array.Clear(_index, 0, _index.Length);
                        _index = null;
                    }
                    if (_currentSeeds != null)
                    {
                        Array.Clear(_currentSeeds, 0, _currentSeeds.Length);
                        _currentSeeds = null;
                    }
                    if (_nextNextSeeds != null)
                    {
                        Array.Clear(_nextNextSeeds, 0, _nextNextSeeds.Length);
                        _nextNextSeeds = null;
                    }
                    if (_currentAuthPaths != null)
                    {
                        Array.Clear(_currentAuthPaths, 0, _currentAuthPaths.Length);
                        _currentAuthPaths = null;
                    }
                    if (_nextAuthPaths != null)
                    {
                        Array.Clear(_nextAuthPaths, 0, _nextAuthPaths.Length);
                        _nextAuthPaths = null;
                    }
                    if (_currentTreehash != null)
                    {
                        for (int i = 0; i < _currentTreehash.Length; i++)
                        {
                            for (int j = 0; j < _currentTreehash[i].Length; j++)
                                _currentTreehash[i][j].Dispose();
                        }
                        _nextAuthPaths = null;
                    }
                    if (_nextTreehash != null)
                    {
                        for (int i = 0; i < _nextTreehash.Length; i++)
                        {
                            for (int j = 0; j < _nextTreehash[i].Length; j++)
                                _nextTreehash[i][j].Dispose();
                        }
                        _nextAuthPaths = null;
                    }
                    if (_currentStack != null)
                    {
                        Array.Clear(_currentStack, 0, _currentStack.Length);
                        _currentStack = null;
                    }
                    if (_nextStack != null)
                    {
                        Array.Clear(_nextStack, 0, _nextStack.Length);
                        _nextStack = null;
                    }
                    if (_currentRetain != null)
                    {
                        Array.Clear(_currentRetain, 0, _currentRetain.Length);
                        _currentRetain = null;
                    }
                    if (_nextRetain != null)
                    {
                        Array.Clear(_nextRetain, 0, _nextRetain.Length);
                        _nextRetain = null;
                    }
                    if (_keep != null)
                    {
                        Array.Clear(_keep, 0, _keep.Length);
                        _keep = null;
                    }
                    if (_nextNextLeaf != null)
                    {
                        for (int i = 0; i < _nextNextLeaf.Length; i++)
                            _nextNextLeaf[i].Dispose();
                        _nextNextLeaf = null;
                    }
                    if (_upperLeaf != null)
                    {
                        for (int i = 0; i < _upperLeaf.Length; i++)
                            _upperLeaf[i].Dispose();
                        _upperLeaf = null;
                    }
                    if (_upperTreehashLeaf != null)
                    {
                        for (int i = 0; i < _upperTreehashLeaf.Length; i++)
                            _upperTreehashLeaf[i].Dispose();
                        _upperTreehashLeaf = null;
                    }
                    if (_minTreehash != null)
                    {
                        Array.Clear(_minTreehash, 0, _minTreehash.Length);
                        _minTreehash = null;
                    }
                    if (_gmssPS != null)
                    {
                        _gmssPS.Dispose();
                        _gmssPS = null;
                    }
                    if (_nextRoot != null)
                    {
                        Array.Clear(_nextRoot, 0, _nextRoot.Length);
                        _nextRoot = null;
                    }
                    if (_nextNextRoot != null)
                    {
                        for (int i = 0; i < _nextNextRoot.Length; i++)
                            _nextNextRoot[i].Dispose();
                        _nextNextRoot = null;
                    }
                    if (_currentRootSig != null)
                    {
                        Array.Clear(_currentRootSig, 0, _currentRootSig.Length);
                        _currentRootSig = null;
                    }
                    if (_nextRootSig != null)
                    {
                        for (int i = 0; i < _nextRootSig.Length; i++)
                            _nextRootSig[i].Dispose();
                        _nextRootSig = null;
                    }
                    if (_heightOfTrees != null)
                    {
                        Array.Clear(_heightOfTrees, 0, _heightOfTrees.Length);
                        _heightOfTrees = null;
                    }
                    if (_otsIndex != null)
                    {
                        Array.Clear(_otsIndex, 0, _otsIndex.Length);
                        _otsIndex = null;
                    }
                    if (_K != null)
                    {
                        Array.Clear(_K, 0, _K.Length);
                        _K = null;
                    }
                    if (_numLeafs != null)
                    {
                        Array.Clear(_numLeafs, 0, _numLeafs.Length);
                        _numLeafs = null;
                    }
                    if (_msgDigestTrees != null)
                    {
                        _msgDigestTrees.Dispose();
                        _msgDigestTrees = null;
                    }
                    if (_gmssRandom != null)
                    {
                        _gmssRandom.Dispose();
                        _gmssRandom = null;
                    }
                    _mdLength = 0;
                    _numLayer = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }
Exemple #9
0
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_msgDigestOTS != null)
                    {
                        _msgDigestOTS.Dispose();
                        _msgDigestOTS = null;
                    }
                    if (_privateKeyOTS != null)
                    {
                        Array.Clear(_privateKeyOTS, 0, _privateKeyOTS.Length);
                        _privateKeyOTS = null;
                    }
                    if (_msgHash != null)
                    {
                        Array.Clear(_msgHash, 0, _msgHash.Length);
                        _msgHash = null;
                    }
                    if (_sgnCode != null)
                    {
                        Array.Clear(_sgnCode, 0, _sgnCode.Length);
                        _sgnCode = null;
                    }
                    if (_gmssRand != null)
                    {
                        _gmssRand.Dispose();
                        _gmssRand = null;
                    }
                    if (_otsSeed != null)
                    {
                        Array.Clear(_otsSeed, 0, _otsSeed.Length);
                        _otsSeed = null;
                    }
                    _mdSize = 0;
                    _keySize = 0;
                    _W = 0;
                    _msgSize = 0;
                    _K = 0;
                    _R = 0;
                    _testCtr = 0;
                    _Counter = 0;
                    _iI = 0;
                    _test8 = 0;
                    _big8 = 0;
                    _steps = 0;
                    _chkSum = 0;
                    _height = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }
        /// <summary>
        /// Use an initialized prng to generate the key; use this constructor with an Rng that requires pre-initialization, i.e. PBPrng
        /// </summary>
        /// 
        /// <param name="CiphersParams">The GMSSParameters instance containing the cipher settings</param>
        /// <param name="RngEngine">An initialized random generator instance</param>
        public GMSSKeyGenerator(GMSSParameters CiphersParams, IRandom RngEngine)
        {
            _gmssParams = CiphersParams;
            _msgDigestType = CiphersParams.DigestEngine;
            _rndEngineType = _gmssParams.RandomEngine;
            _msDigestTree = GetDigest(CiphersParams.DigestEngine);
            // construct randomizer
            _gmssRand = new GMSSRandom(_msDigestTree);
            // set mdLength
            _mdLength = _msDigestTree.DigestSize;
            // construct Random for initial seed generation
            _rndEngine = RngEngine;

            Initialize();
        }
Exemple #11
0
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_msgDigestOTS != null)
                    {
                        _msgDigestOTS.Dispose();
                        _msgDigestOTS = null;
                    }
                    if (_gmssRandom != null)
                    {
                        _gmssRandom.Dispose();
                        _gmssRandom = null;
                    }
                    if (_leaf != null)
                    {
                        Array.Clear(_leaf, 0, _leaf.Length);
                        _leaf = null;
                    }
                    if (_concHashs != null)
                    {
                        Array.Clear(_concHashs, 0, _concHashs.Length);
                        _concHashs = null;
                    }
                    if (_seed != null)
                    {
                        Array.Clear(_seed, 0, _seed.Length);
                        _seed = null;
                    }
                    if (_privateKeyOTS != null)
                    {
                        Array.Clear(_privateKeyOTS, 0, _privateKeyOTS.Length);
                        _privateKeyOTS = null;
                    }
                    _mdsize = 0;
                    _keysize = 0;
                    _ctr1 = 0;
                    _ctr2 = 0;
                    _twoPowerW = 0;
                    _W = 0;
                    _steps = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }
Exemple #12
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);
 }
Exemple #13
0
 /// <summary>
 /// Updates the nextSeed of this treehash instance one step needed for the schedulng of the seeds
 /// </summary>
 /// 
 /// <param name="GmssRand">The prng used for the seeds</param>
 public void UpdateNextSeed(GMSSRandom GmssRand)
 {
     GmssRand.NextSeed(_seedNext);
 }
Exemple #14
0
        /// <summary>
        /// Calculates one update of the treehash instance, i.e. creates a new leaf and hashes if possible
        /// </summary>
        /// 
        /// <param name="GmssRand">An instance of the PRNG</param>
        /// <param name="Leaf">The byte value of the leaf needed for the update</param>
        public void Update(GMSSRandom GmssRand, byte[] Leaf)
        {
            if (_isFinished)
                return;
            if (!_isInitialized)
                return;

            byte[] help = new byte[_msgDigestTree.DigestSize];
            int helpHeight = -1;

            GmssRand.NextSeed(_seedActive);

            // if treehash gets first update
            if (_firstNode == null)
            {
                _firstNode = Leaf;
                _firstNodeHeight = 0;
            }
            else
            {
                // store the new node in help array, do not push it on the stack
                help = Leaf;
                helpHeight = 0;

                // hash the nodes on the stack if possible
                while (_tailLength > 0 && helpHeight == ((int)_heightOfNodes[_heightOfNodes.Count - 1]))
                {
                    // put top element of the stack and help node in array 'tobehashed'
                    // and hash them together, put result again in help array
                    byte[] toBeHashed = new byte[_msgDigestTree.DigestSize << 1];

                    // pop element from stack
                    Array.Copy(_tailStack[_tailStack.Count - 1], 0, toBeHashed, 0, _msgDigestTree.DigestSize);
                    _tailStack.RemoveAt(_tailStack.Count - 1);
                    _heightOfNodes.RemoveAt(_heightOfNodes.Count - 1);

                    Array.Copy(help, 0, toBeHashed, _msgDigestTree.DigestSize, _msgDigestTree.DigestSize);
                    _msgDigestTree.BlockUpdate(toBeHashed, 0, toBeHashed.Length);
                    help = new byte[_msgDigestTree.DigestSize];
                    _msgDigestTree.DoFinal(help, 0);

                    // increase help height, stack was reduced by one element
                    helpHeight++;
                    _tailLength--;
                }

                // push the new node on the stack
                _tailStack.Add(help);
                _heightOfNodes.Add(helpHeight);
                _tailLength++;

                // finally check whether the top node on stack and the first node in treehash have same height.
                // If so hash them together and store them in treehash
                if (((int)_heightOfNodes[_heightOfNodes.Count - 1] == _firstNodeHeight))
                {
                    byte[] toBeHashed = new byte[_msgDigestTree.DigestSize << 1];
                    Array.Copy(_firstNode, 0, toBeHashed, 0, _msgDigestTree.DigestSize);
                    // pop element from tailStack and copy it into help2 array
                    Array.Copy(_tailStack[_tailStack.Count - 1], 0, toBeHashed, _msgDigestTree.DigestSize, _msgDigestTree.DigestSize);
                    _tailStack.RemoveAt(_tailStack.Count - 1);
                    _heightOfNodes.RemoveAt(_heightOfNodes.Count - 1);
                    // store new element in firstNode, stack is then empty
                    _msgDigestTree.BlockUpdate(toBeHashed, 0, toBeHashed.Length);
                    _firstNode = new byte[_msgDigestTree.DigestSize];
                    _msgDigestTree.DoFinal(_firstNode, 0);
                    _firstNodeHeight++;
                    // empty the stack
                    _tailLength = 0;
                }
            }

            // check if treehash instance is completed
            if (_firstNodeHeight == _maxHeight)
                _isFinished = true;
        }
Exemple #15
0
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_msgDigestTrees != null)
                    {
                        _msgDigestTrees.Dispose();
                        _msgDigestTrees = null;
                    }
                    if (_gmssRandom != null)
                    {
                        _gmssRandom.Dispose();
                        _gmssRandom = null;
                    }
                    if (_index != null)
                    {
                        Array.Clear(_index, 0, _index.Length);
                        _index = null;
                    }
                    if (_currentAuthPaths != null)
                    {
                        Array.Clear(_currentAuthPaths, 0, _currentAuthPaths.Length);
                        _currentAuthPaths = null;
                    }
                    if (_subtreeRootSig != null)
                    {
                        Array.Clear(_subtreeRootSig, 0, _subtreeRootSig.Length);
                        _subtreeRootSig = null;
                    }
                    _mdLength = 0;
                    _numLayer = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }
        /// <summary>
        /// Initialize this class
        /// </summary>
        /// 
        /// <param name="CiphersParams">The GMSSParameters instance containing the cipher settings</param>
        /// 
        /// <exception cref="CryptoAsymmetricSignException">Thrown if a Prng that requires pre-initialization is specified; (wrong constructor)</exception>
        public GMSSKeyGenerator(GMSSParameters CiphersParams)
        {
            if (CiphersParams.RandomEngine == Prngs.PBPrng)
                throw new CryptoAsymmetricSignException("GMSSKeyGenerator:Ctor", "Passphrase based digest and CTR generators must be pre-initialized, use the other constructor!", new ArgumentException());

            _gmssParams = CiphersParams;
            _msgDigestType = CiphersParams.DigestEngine;
            _rndEngineType = _gmssParams.RandomEngine;
            _msDigestTree = GetDigest(CiphersParams.DigestEngine);
            // construct randomizer
            _gmssRand = new GMSSRandom(_msDigestTree);
            // set mdLength
            _mdLength = _msDigestTree.DigestSize;
            // construct Random for initial seed generation
            _rndEngine = GetPrng(_rndEngineType);

            Initialize();
        }
Exemple #17
0
        /// <summary>
        /// The constructor precomputes some needed variables for distributed leaf calculation
        /// </summary>
        /// 
        /// <param name="Digest">The hash function</param>
        /// <param name="W">The winterniz parameter of that tree the leaf is computed for</param>
        /// <param name="NumLeafs">The number of leafs of the tree from where the distributed computation is called</param>
        /// <param name="Seed">The hash seed value</param>
        public GMSSLeaf(IDigest Digest, int W, int NumLeafs, byte[] Seed)
        {
            _W = W;
            _msgDigestOTS = Digest;
            _gmssRandom = new GMSSRandom(_msgDigestOTS);
            // calulate keysize for private key and the help array
            _mdsize = _msgDigestOTS.DigestSize;
            int mdsizeBit = _mdsize << 3;
            int messagesize = (int)Math.Ceiling((double)(mdsizeBit) / (double)W);
            int checksumsize = GetLog((messagesize << W) + 1);
            _keysize = messagesize + (int)Math.Ceiling((double)checksumsize / (double)W);
            _twoPowerW = 1 << W;
            // calculate steps ((2^w)-1)*keysize + keysize + 1 / (2^h -1)
            _steps = (int)Math.Ceiling((double)(((1 << W) - 1) * _keysize + 1 + _keysize) / (double)(NumLeafs));
            // initialize arrays
            _seed = new byte[_mdsize];
            _leaf = new byte[_mdsize];
            _privateKeyOTS = new byte[_mdsize];
            _concHashs = new byte[_mdsize * _keysize];

            InitLeafCalc(Seed);
        }
        private void Dispose(bool Disposing)
        {
            if (!_isDisposed && Disposing)
            {
                try
                {
                    if (_gmssRand != null)
                    {
                        _gmssRand.Dispose();
                        _gmssRand = null;
                    }
                    if (_rndEngine != null)
                    {
                        _rndEngine.Dispose();
                        _rndEngine = null;
                    }
                    if (_msDigestTree != null)
                    {
                        _msDigestTree.Dispose();
                        _msDigestTree = null;
                    }
                    if (_currentSeeds != null)
                    {
                        Array.Clear(_currentSeeds, 0, _currentSeeds.Length);
                        _currentSeeds = null;
                    }
                    if (_nextNextSeeds != null)
                    {
                        Array.Clear(_nextNextSeeds, 0, _nextNextSeeds.Length);
                        _nextNextSeeds = null;
                    }
                    if (_currentRootSigs != null)
                    {
                        Array.Clear(_currentRootSigs, 0, _currentRootSigs.Length);
                        _currentRootSigs = null;
                    }
                    if (_currentRootSigs != null)
                    {
                        Array.Clear(_currentRootSigs, 0, _currentRootSigs.Length);
                        _currentRootSigs = null;
                    }
                    _mdLength = 0;
                }
                catch { }

                _isDisposed = true;
            }
        }
Exemple #19
0
 /// <summary>
 /// The constructor generates the PRNG and initializes some variables
 /// </summary>
 /// 
 /// <param name="Digest">The hash function</param>
 /// <param name="W">The winternitz parameter</param>
 /// <param name="Height">The heigth of the tree</param>
 public GMSSRootSig(IDigest Digest, int W, int Height)
 {
     _msgDigestOTS = Digest;
     _gmssRand = new GMSSRandom(_msgDigestOTS);
     _mdSize = _msgDigestOTS.DigestSize;
     _W = W;
     _height = Height;
     _K = (1 << W) - 1;
     int mdsizeBit = _mdSize << 3;
     _msgSize = (int)Math.Ceiling((double)(mdsizeBit) / (double)W);
 }