/// <summary> /// Generates a Hss Key Pair asynchronously. Safe to call from an Orleans grain. /// </summary> /// <returns>Valid HssKeyPair</returns> public async Task <HssKeyPair> GenerateHssKeyPairAsync() { LmsPrivateKey[] priv = new LmsPrivateKey[_lms.Length]; BitString[] pub = new BitString[_lms.Length]; BitString[] sig = new BitString[_lms.Length - 1]; // Generate Key Pairs await GenerateHssKeyPairHelperAsync(priv, pub); // Generate sig list for (int i = 1; i < _lms.Length; i++) { sig[i - 1] = _lms[i - 1].GenerateLmsSignature(pub[i], priv[i - 1]); } // Return u32str(L) || pub[0] as the public key and the priv[], pub[], and sig[] arrays as the private key var publicKey = new BitString(_lms.Length, 32).ConcatenateBits(pub[0]); var privateKey = new HssPrivateKey(priv, pub, sig); return(new HssKeyPair(privateKey, publicKey)); }
public BitString GenerateLmsSignature(BitString msg, LmsPrivateKey privateKey) { // 0. Use pub to generate tree if it is not null if (privateKey.Pub != null) { var tree = LmsDllLoader.BuildTreeWithPub(_h, _m, _I.ToBytes(), privateKey.Pub, _lmots.GetP(), _lmots.GetN(), _lmots.GetW()); _tree = new LmsTree(_h, _m, tree); } // 1. Generate ots with next available leaf (in private key) var q = privateKey.Q; if (q * ((_lmots.GetN() * _lmots.GetP()) + 24) >= privateKey.OTS_PRIV.Length) { return(null); } var lmots_signature = _lmots.GenerateLmotsSignature(msg, new BitString(privateKey.GetLmotsPrivateKeyQ(q)), SEED); // 2. Increment q in private key to ensure no reusablility of key // privateKey.UpdateQ(); // currently done in hss // 3. Determine path[] var path = new BitString(""); int currentIndex = (1 << _h) + q; for (int i = 0; i < _h; i++) { path = path.ConcatenateBits(_tree.GetSibling(currentIndex)); currentIndex /= 2; } // 4. u32str(q) || lmots_signature || u32str(type) || path[0] || path[1] || path[2] || ... || path[h - 1] return(new BitString(q, 32) .ConcatenateBits(lmots_signature) .ConcatenateBits(_typecode) .ConcatenateBits(path)); }