/// <summary> /// Builds tree from pub and also the public key as a BitString /// </summary> /// <param name="pub">A bunch of last 32 bytes of public keys</param> /// <returns>LMS public key</returns> private BitString GenerateLmsPublicKey(byte[] pub) { var tree = LmsDllLoader.BuildTreeWithPub(_h, _m, _I.ToBytes(), pub, _lmots.GetP(), _lmots.GetN(), _lmots.GetW()); _tree = new LmsTree(_h, _m, tree); var publicKey = _typecode.ConcatenateBits(_lmotsTypecode) .ConcatenateBits(_I) .ConcatenateBits(_tree.GetRoot()); return(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)); }