コード例 #1
0
ファイル: Hss.cs プロジェクト: usnistgov/ACVP-Server
        // From email with Scott Fluhrer:
        // To generate the SEED for a child LMS tree, we will adapt algorithm A by using the
        // I value of the parent LMS tree the q value to be the LMS index of the child, and the i value to be 65534.
        // Algorithm A:
        // x_q[i] = H(I || u32str(q) || u16str(i) || u8str(0xff) || SEED).
        // UPDATE: Generate child I from algorithm A using the I value of the parent LMS tree, the q value
        // to be the LMS index of the child, and the i value to be 65535; the I value will be the first 128 bits of the hash.
        public Hss(int layers, LmsType[] lmsTypes, LmotsType[] lmotsTypes,
                   EntropyProviderTypes entropyType = EntropyProviderTypes.Random, BitString seed = null, BitString rootI = null)
        {
            _entropyType     = entropyType;
            _entropyProvider = _entropyFactory.GetEntropyProvider(entropyType);
            _entropyProvider.AddEntropy(seed);
            SEED = _entropyProvider.GetEntropy(256);    // for now will only be 256 bits (m = 256)
            _entropyProvider.AddEntropy(rootI);
            RootI   = _entropyProvider.GetEntropy(128);
            _sha256 = new NativeFastSha2_256();

            _lms        = new Lms[layers];
            _lmsTypes   = lmsTypes;
            _lmotsTypes = lmotsTypes;
            _lms[0]     = new Lms(lmsTypes[0], lmotsTypes[0], entropyType, SEED, rootI);
            var parentSeed = SEED;
            var parentI    = RootI;

            for (int i = 1; i < layers; i++)
            {
                var childSeed = _sha256.HashMessage(parentI
                                                    .ConcatenateBits(new BitString(0, 32))
                                                    .ConcatenateBits(new BitString(65534, 16))
                                                    .ConcatenateBits(new BitString("ff", 8))
                                                    .ConcatenateBits(parentSeed)).Digest;
                var I = _sha256.HashMessage(parentI
                                            .ConcatenateBits(new BitString(0, 32))
                                            .ConcatenateBits(new BitString(65535, 16))
                                            .ConcatenateBits(new BitString("ff", 8))
                                            .ConcatenateBits(parentSeed)).Digest.MSBSubstring(0, 128);
                _lms[i]    = new Lms(lmsTypes[i], lmotsTypes[i], entropyType, childSeed, I);
                parentSeed = childSeed;
                parentI    = I;
            }
        }
コード例 #2
0
ファイル: Hss.cs プロジェクト: usnistgov/ACVP-Server
        /// <summary>
        /// Updates the key pair one step. Should be called my MCT in order to safely advance key.
        /// </summary>
        /// <param name="keyPair"></param>
        /// <returns></returns>
        public async Task <HssKeyPair> UpdateKeyPairOneStepAsync(HssKeyPair keyPair)
        {
            var keyPairCopy = keyPair.GetDeepCopy();

            int d = _lms.Length;

            while (keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q == (keyPairCopy.PrivateKey.PrivateKeys[d - 1].OTS_PRIV.Length
                                                                   / (_lms[d - 1].GetLmotsN() * _lms[d - 1].GetLmotsP() + 24)) - 1)
            {
                d--;
                if (d == 0)
                {
                    keyPairCopy.Expired = true;
                    return(keyPairCopy);
                }
            }
            var lowD = d;

            if (d < _lms.Length)
            {
                while (d < _lms.Length)
                {
                    var newSeed = _sha256.HashMessage(_lms[d - 1].GetI()
                                                      .ConcatenateBits(new BitString(keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q + 1, 32))
                                                      .ConcatenateBits(new BitString(65534, 16))
                                                      .ConcatenateBits(new BitString("ff", 8))
                                                      .ConcatenateBits(_lms[d - 1].GetSeed())).Digest;
                    var newI = _sha256.HashMessage(_lms[d - 1].GetI()
                                                   .ConcatenateBits(new BitString(keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q + 1, 32))
                                                   .ConcatenateBits(new BitString(65535, 16))
                                                   .ConcatenateBits(new BitString("ff", 8))
                                                   .ConcatenateBits(_lms[d - 1].GetSeed())).Digest;
                    newI    = newI.MSBSubstring(0, 128);
                    _lms[d] = new Lms(_lmsTypes[d], _lmotsTypes[d], _entropyType, newSeed, newI);
                    var newkeyPairCopy = await _lms[d].GenerateLmsKeyPairAsync();
                    keyPairCopy.PrivateKey.PrivateKeys[d]       = newkeyPairCopy.PrivateKey;
                    keyPairCopy.PrivateKey.PublicKeys[d]        = newkeyPairCopy.PublicKey;
                    keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q = (keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q + 1) % (1 << _lms[d - 1].GetH());
                    keyPairCopy.PrivateKey.Signatures[d - 1]    = _lms[d - 1].GenerateLmsSignature(
                        keyPairCopy.PrivateKey.PublicKeys[d], keyPairCopy.PrivateKey.PrivateKeys[d - 1]);

                    if (keyPairCopy.PrivateKey.Signatures[d - 1] == null)
                    {
                        keyPairCopy.Expired = true;
                        return(keyPairCopy);
                    }

                    d++;
                }
            }
            else
            {
                // Update Q value
                keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q = (keyPairCopy.PrivateKey.PrivateKeys[d - 1].Q + 1) % (1 << _lms[d - 1].GetH());
            }

            return(keyPairCopy);
        }
コード例 #3
0
ファイル: Hss.cs プロジェクト: usnistgov/ACVP-Server
        /// <summary>
        /// Used in signature generation to sign after advancing the key some number of times.
        /// This function is unsafe to use if the keyPair has been advanced before.
        /// </summary>
        /// <param name="keyPair"></param>
        /// <param name="times"></param>
        /// <returns></returns>
        private async Task <HssKeyPair> UpdateKeyPairAsync(HssKeyPair keyPair, int times = 1)
        {
            if (times == 0)
            {
                return(keyPair);
            }
            keyPair = keyPair.GetDeepCopy();

            var divisor = 1;

            for (int i = 1; i < _lms.Length; i++)
            {
                divisor *= (1 << _lms[i].GetH());
            }

            // If update would cause the key to expire, then expire key
            if (((1 << _lms[0].GetH()) - keyPair.PrivateKey.PrivateKeys[0].Q) * divisor <= times)
            {
                keyPair.Expired = true;
                return(keyPair);
            }

            for (int d = 0; d < _lms.Length; d++)
            {
                // Update divisor for next step
                if (d != 0)
                {
                    divisor /= (1 << _lms[d].GetH());
                }

                var qStep = times / divisor;

                // If tree update is needed
                if (qStep + keyPair.PrivateKey.PrivateKeys[d].Q >= (1 << _lms[d].GetH()))
                {
                    // If update would cause the key to expire, then expire key
                    if (d == 0)
                    {
                        keyPair.Expired = true;
                        return(keyPair);
                    }
                    var newSeed = _sha256.HashMessage(_lms[d - 1].GetI()
                                                      .ConcatenateBits(new BitString(keyPair.PrivateKey.PrivateKeys[d - 1].Q, 32))
                                                      .ConcatenateBits(new BitString(65534, 16))
                                                      .ConcatenateBits(new BitString("ff", 8))
                                                      .ConcatenateBits(_lms[d - 1].GetSeed())).Digest;
                    var newI = _sha256.HashMessage(_lms[d - 1].GetI()
                                                   .ConcatenateBits(new BitString(keyPair.PrivateKey.PrivateKeys[d - 1].Q, 32))
                                                   .ConcatenateBits(new BitString(65535, 16))
                                                   .ConcatenateBits(new BitString("ff", 8))
                                                   .ConcatenateBits(_lms[d - 1].GetSeed())).Digest;
                    newI    = newI.MSBSubstring(0, 128);
                    _lms[d] = new Lms(_lmsTypes[d], _lmotsTypes[d], _entropyType, newSeed, newI);
                    var newKeyPair = await _lms[d].GenerateLmsKeyPairAsync();
                    keyPair.PrivateKey.PrivateKeys[d]    = newKeyPair.PrivateKey;
                    keyPair.PrivateKey.PublicKeys[d]     = newKeyPair.PublicKey;
                    keyPair.PrivateKey.Signatures[d - 1] = _lms[d - 1].GenerateLmsSignature(
                        keyPair.PrivateKey.PublicKeys[d], keyPair.PrivateKey.PrivateKeys[d - 1]);
                }

                // Update Q value
                keyPair.PrivateKey.PrivateKeys[d].Q = (keyPair.PrivateKey.PrivateKeys[d].Q + qStep) % (1 << _lms[d].GetH());
            }

            return(keyPair);
        }