private void TestSign(GMSSParameters CipherParam) { GMSSKeyGenerator mkgen = new GMSSKeyGenerator(CipherParam); IAsymmetricKeyPair akp = mkgen.GenerateKeyPair(); byte[] data = new byte[200]; new VTDev.Libraries.CEXEngine.Crypto.Prng.CSPPrng().GetBytes(data); using (GMSSSign sgn = new GMSSSign(CipherParam)) { // sign the array sgn.Initialize(akp.PrivateKey); byte[] code = sgn.Sign(data, 0, data.Length); // verify the signature sgn.Initialize(akp.PublicKey); if (!sgn.Verify(data, 0, data.Length, code)) { throw new Exception("RLWESignTest: Sign operation failed!"); } // get the next available key (private sub-key is used only once) GMSSPrivateKey nk = ((GMSSPrivateKey)akp.PrivateKey).NextKey(); sgn.Initialize(nk); code = sgn.Sign(new MemoryStream(data)); // verify the signature sgn.Initialize(akp.PublicKey); if (!sgn.Verify(new MemoryStream(data), code)) { throw new Exception("RLWESignTest: Verify test failed!"); } } }
/// <summary> /// Initializes the signature algorithm for signing a message /// </summary> private void InitSign() { _msgDigestTrees.Reset(); // set private key and take from it ots key, auth, tree and key counter, rootSign GMSSPrivateKey gmssPrivateKey = (GMSSPrivateKey)m_asmKey; if (gmssPrivateKey.IsUsed) { throw new Exception("Private key already used"); } // check if last signature has been generated if (gmssPrivateKey.GetCurrentIndex(0) >= gmssPrivateKey.GetNumLeafs(0)) { throw new Exception("No more signatures can be generated"); } // get numLayer _numLayer = _gmssPS.NumLayers; // get OTS Instance of lowest layer byte[] seed = gmssPrivateKey.CurrentSeeds[_numLayer - 1]; byte[] OTSSeed = new byte[_mdLength]; byte[] dummy = new byte[_mdLength]; Array.Copy(seed, 0, dummy, 0, _mdLength); OTSSeed = _gmssRandom.NextSeed(dummy); _Ots = new WinternitzOTSignature(OTSSeed, GetDigest(_gmssPS.DigestEngine), _gmssPS.WinternitzParameter[_numLayer - 1]); byte[][][] helpCurrentAuthPaths = gmssPrivateKey.CurrentAuthPaths; _currentAuthPaths = new byte[_numLayer][][]; // copy the main tree authentication path for (int j = 0; j < _numLayer; j++) { _currentAuthPaths[j] = ArrayUtils.CreateJagged <byte[][]>(helpCurrentAuthPaths[j].Length, _mdLength); for (int i = 0; i < helpCurrentAuthPaths[j].Length; i++) { Array.Copy(helpCurrentAuthPaths[j][i], 0, _currentAuthPaths[j][i], 0, _mdLength); } } // copy index _index = new int[_numLayer]; Array.Copy(gmssPrivateKey.Index, 0, _index, 0, _numLayer); // copy subtreeRootSig byte[] helpSubtreeRootSig; _subtreeRootSig = new byte[_numLayer - 1][]; for (int i = 0; i < _numLayer - 1; i++) { helpSubtreeRootSig = gmssPrivateKey.SubtreeRootSig(i); _subtreeRootSig[i] = new byte[helpSubtreeRootSig.Length]; Array.Copy(helpSubtreeRootSig, 0, _subtreeRootSig[i], 0, helpSubtreeRootSig.Length); } if (gmssPrivateKey.GetCurrentIndex(0) >= gmssPrivateKey.GetNumLeafs(0)) { gmssPrivateKey.IsUsed = true; } }
/// <summary> /// Generate an encryption Key pair /// </summary> /// /// <returns>A GMSSKeyPair containing public and private keys</returns> public IAsymmetricKeyPair GenerateKeyPair() { // initialize authenticationPaths and treehash instances byte[][][] currentAuthPaths = new byte[_numLayer][][]; byte[][][] nextAuthPaths = new byte[_numLayer - 1][][]; Treehash[][] currentTreehash = new Treehash[_numLayer][]; Treehash[][] nextTreehash = new Treehash[_numLayer - 1][]; List <byte[]>[] currentStack = new List <byte[]> [_numLayer]; List <byte[]>[] nextStack = new List <byte[]> [_numLayer - 1]; List <byte[]>[][] currentRetain = new List <byte[]> [_numLayer][]; List <byte[]>[][] nextRetain = new List <byte[]> [_numLayer - 1][]; for (int i = 0; i < _numLayer; i++) { currentAuthPaths[i] = ArrayUtils.CreateJagged <byte[][]>(_heightOfTrees[i], _mdLength);//new byte[heightOfTrees[i]][mdLength]; currentTreehash[i] = new Treehash[_heightOfTrees[i] - m_K[i]]; if (i > 0) { nextAuthPaths[i - 1] = ArrayUtils.CreateJagged <byte[][]>(_heightOfTrees[i], _mdLength);//new byte[heightOfTrees[i]][mdLength]; nextTreehash[i - 1] = new Treehash[_heightOfTrees[i] - m_K[i]]; } currentStack[i] = new List <byte[]>(); if (i > 0) { nextStack[i - 1] = new List <byte[]>(); } } // initialize roots byte[][] currentRoots = ArrayUtils.CreateJagged <byte[][]>(_numLayer, _mdLength); byte[][] nextRoots = ArrayUtils.CreateJagged <byte[][]>(_numLayer - 1, _mdLength); // initialize seeds byte[][] seeds = ArrayUtils.CreateJagged <byte[][]>(_numLayer, _mdLength); // initialize seeds[] by copying starting-seeds of first trees of each layer for (int i = 0; i < _numLayer; i++) { Array.Copy(_currentSeeds[i], 0, seeds[i], 0, _mdLength); } // initialize rootSigs _currentRootSigs = ArrayUtils.CreateJagged <byte[][]>(_numLayer - 1, _mdLength);//new byte[numLayer - 1][mdLength]; // calculation of current authpaths and current rootsigs (AUTHPATHS, SIG) from bottom up to the root for (int h = _numLayer - 1; h >= 0; h--) { GMSSRootCalc tree = new GMSSRootCalc(_heightOfTrees[h], m_K[h], GetDigest(_msgDigestType)); try { // on lowest layer no lower root is available, so just call the method with null as first parameter if (h == _numLayer - 1) { tree = GenerateCurrentAuthpathAndRoot(null, currentStack[h], seeds[h], h); } else { // otherwise call the method with the former computed root value tree = GenerateCurrentAuthpathAndRoot(currentRoots[h + 1], currentStack[h], seeds[h], h); } } catch { } // set initial values needed for the private key construction for (int i = 0; i < _heightOfTrees[h]; i++) { Array.Copy(tree.GetAuthPath()[i], 0, currentAuthPaths[h][i], 0, _mdLength); } currentRetain[h] = tree.GetRetain(); currentTreehash[h] = tree.GetTreehash(); Array.Copy(tree.GetRoot(), 0, currentRoots[h], 0, _mdLength); } // calculation of next authpaths and next roots (AUTHPATHS+, ROOTS+) for (int h = _numLayer - 2; h >= 0; h--) { GMSSRootCalc tree = GenerateNextAuthpathAndRoot(nextStack[h], seeds[h + 1], h + 1); // set initial values needed for the private key construction for (int i = 0; i < _heightOfTrees[h + 1]; i++) { Array.Copy(tree.GetAuthPath()[i], 0, nextAuthPaths[h][i], 0, _mdLength); } nextRetain[h] = tree.GetRetain(); nextTreehash[h] = tree.GetTreehash(); Array.Copy(tree.GetRoot(), 0, nextRoots[h], 0, _mdLength); // create seed for the Merkle tree after next (nextNextSeeds) SEEDs++ Array.Copy(seeds[h + 1], 0, _nextNextSeeds[h], 0, _mdLength); } // generate JDKGMSSPublicKey int[] len = new int[] { currentRoots[0].Length }; byte[] btlen = new byte[4]; Buffer.BlockCopy(len, 0, btlen, 0, btlen.Length); GMSSPublicKey pubKey = new GMSSPublicKey(ArrayUtils.Concat(btlen, currentRoots[0])); // generate the JDKGMSSPrivateKey GMSSPrivateKey privKey = new GMSSPrivateKey(_currentSeeds, _nextNextSeeds, currentAuthPaths, nextAuthPaths, currentTreehash, nextTreehash, currentStack, nextStack, currentRetain, nextRetain, nextRoots, _currentRootSigs, _gmssParams, _msgDigestType); // return the KeyPair return(new GMSSKeyPair(pubKey, privKey)); }
private static void TestSign(GMSSParameters CipherParam) { GMSSKeyGenerator mkgen = new GMSSKeyGenerator(CipherParam); IAsymmetricKeyPair akp = mkgen.GenerateKeyPair(); byte[] data = new byte[200]; new VTDev.Libraries.CEXEngine.Crypto.Prng.CSPPrng().GetBytes(data); // public key serialization test: var pubKeySerialized = akp.PublicKey.ToBytes(); var pubKeyExported = $"-----BEGIN GMSS PUBLIC KEY-----{Environment.NewLine}{Convert.ToBase64String(pubKeySerialized, Base64FormattingOptions.InsertLineBreaks)}{Environment.NewLine}-----END GMSS PUBLIC KEY-----{Environment.NewLine}"; File.WriteAllText("TestPublicKey.txt", pubKeyExported); var pubKeyImported = File.ReadAllText("TestPublicKey.txt").Replace($"-----BEGIN GMSS PUBLIC KEY-----{Environment.NewLine}", "").Replace($"-----END GMSS PUBLIC KEY-----{Environment.NewLine}", ""); var pubKey = GMSSPublicKey.From(Convert.FromBase64String(pubKeyImported)); var currentPrivKey = ((GMSSPrivateKey)akp.PrivateKey); //.NextKey(); for (int i = 0; i < 10; i++) //2000; i++) { try { //var test = JsonConvert.SerializeObject(akp); using (GMSSSign sgn = new GMSSSign(CipherParam)) { //////// sign the array //////sgn.Initialize(akp.PrivateKey); //////byte[] code = sgn.Sign(data, 0, data.Length); //////// verify the signature //////sgn.Initialize(akp.PublicKey); //////if (!sgn.Verify(data, 0, data.Length, code)) ////// throw new Exception("RLWESignTest: Sign operation failed!"); //if (i == 15) try { //var test1 = JsonConvert.SerializeObject(currentPrivKey); //var keyBytes = currentPrivKey.ToBytes(); //var currentPrivKeyCopy = currentPrivKey.DeepCopy(); // private key serialization test //if (i == 19) // currentPrivKey.DebugGetTreehashes("before"); var privKeySerialized = currentPrivKey.ToBytes(); var privKeyExported = $"-----BEGIN GMSS.{GMSSVersion} PRIVATE KEY-----{Environment.NewLine}{Convert.ToBase64String(privKeySerialized, Base64FormattingOptions.InsertLineBreaks)}{Environment.NewLine}-----END GMSS PRIVATE KEY-----{Environment.NewLine}"; File.WriteAllText("TestPrivateKey.txt", privKeyExported); var privKeyImported = File.ReadAllText("TestPrivateKey.txt").Replace($"-----BEGIN GMSS.{GMSSVersion} PRIVATE KEY-----{Environment.NewLine}", "").Replace($"-----END GMSS PRIVATE KEY-----{Environment.NewLine}", ""); var currentPrivKeyRegen = GMSSPrivateKey.From(Convert.FromBase64String(privKeyImported)); //if (i == 19) { using (SHA512Managed sha = new SHA512Managed()) { var test1 = Convert.ToBase64String(sha.ComputeHash(currentPrivKey.ToBytes())); var test2 = Convert.ToBase64String(sha.ComputeHash(currentPrivKeyRegen.ToBytes())); var iAmI = i; if (test1 != test2) { //////GMSSPrivateKey.DEBUG_HIT_NOW = true; var test1b = ByteArrayToString(currentPrivKey.ToBytes()); var test2b = ByteArrayToString(currentPrivKeyRegen.ToBytes()); } else { } } } // currentPrivKey.DebugGetTreehashes("after"); //var xxx = 1; currentPrivKey = currentPrivKeyRegen; //var testXXX = currentPrivKey.NextKey(); //var test2 = JsonConvert.SerializeObject(currentPrivKeyCopy); //var test3 = JsonConvert.SerializeObject(currentPrivKey); //if(test1 != test2 || test2 != test3) //{ //} //currentPrivKey = new GMSSPrivateKey() //var test1 = currentPrivKey.IsUsed; //using (SHA256Managed sha = new SHA256Managed()) //{ // var currentPrivKeyHash = Convert.ToBase64String(sha.ComputeHash(keyBytes)); //} } catch (Exception ex) { throw ex; } //////var test1 = currentPrivKey.ToBytes(); sgn.Initialize(currentPrivKey); var code = sgn.Sign(new MemoryStream(data)); File.WriteAllText("TestSignature.txt", Convert.ToBase64String(code)); // verify the signature sgn.Initialize(pubKey); if (!sgn.Verify(new MemoryStream(data), code)) { throw new Exception("RLWESignTest: Verify test failed!"); } try { // get the next available key (private sub-key is used only once) //////GMSSPrivateKey nk = ((GMSSPrivateKey)akp.PrivateKey).NextKey(); currentPrivKey = currentPrivKey.NextKey(); // ((GMSSPrivateKey)akp.PrivateKey).NextKey(); // currentPrivKey.NextKey(); } catch (Exception ex) { throw ex; } } } catch (Exception ex) { throw ex; } } }
public static string GetPemStringFromGMSSPrivateKey(GMSSPrivateKey key) { return($"-----BEGIN GMSS.{GMSSVersion} PRIVATE KEY-----{Environment.NewLine}{Convert.ToBase64String(key.ToBytes(), Base64FormattingOptions.InsertLineBreaks)}{Environment.NewLine}-----END GMSS PRIVATE KEY-----{Environment.NewLine}"); }
public static GMSSPrivateKey GetGMSSPrivateKeyFromPemString(string keyPem) { return(GMSSPrivateKey.From(Convert.FromBase64String(keyPem.Replace($"-----BEGIN GMSS.{GMSSVersion} PRIVATE KEY-----{Environment.NewLine}", "").Replace($"-----END GMSS PRIVATE KEY-----{Environment.NewLine}", "")))); }
private void TestEncode() { GMSSParameters mpar = GMSSParamSets.FromName(GMSSParamSets.GMSSParamNames.N2P10); GMSSKeyGenerator mkgen = new GMSSKeyGenerator(mpar); IAsymmetricKeyPair akp = mkgen.GenerateKeyPair(); GMSSPublicKey pub = (GMSSPublicKey)akp.PublicKey; byte[] enc = pub.ToBytes(); using (GMSSPublicKey pub2 = GMSSPublicKey.From(enc)) { if (!pub.Equals(pub2)) { throw new Exception("EncryptionKey: public key comparison test failed!"); } if (pub.GetHashCode() != pub2.GetHashCode()) { throw new Exception("EncryptionKey: public key hash test failed!"); } } OnProgress(new TestEventArgs("Passed public key serialization")); MemoryStream pubstr = pub.ToStream(); using (GMSSPublicKey pub2 = GMSSPublicKey.From(pubstr)) { if (!pub.Equals(pub2)) { throw new Exception("EncryptionKey: public key comparison test failed!"); } if (pub.GetHashCode() != pub2.GetHashCode()) { throw new Exception("EncryptionKey: public key hash test failed!"); } } pubstr.Dispose(); OnProgress(new TestEventArgs("Passed public key stream test")); GMSSPrivateKey pri = (GMSSPrivateKey)akp.PrivateKey; enc = pri.ToBytes(); using (GMSSPrivateKey pri2 = GMSSPrivateKey.From(enc)) { if (!pri.Equals(pri2)) { throw new Exception("EncryptionKey: private key comparison test failed!"); } if (pri.GetHashCode() != pri2.GetHashCode()) { throw new Exception("EncryptionKey: private key hash test failed!"); } } OnProgress(new TestEventArgs("Passed private key serialization")); MemoryStream pristr = pri.ToStream(); using (GMSSPrivateKey pri2 = GMSSPrivateKey.From(pristr)) { if (!pri.Equals(pri2)) { throw new Exception("EncryptionKey: private key comparison test failed!"); } if (pri.GetHashCode() != pri2.GetHashCode()) { throw new Exception("EncryptionKey: private key hash test failed!"); } } pristr.Dispose(); OnProgress(new TestEventArgs("Passed private key stream test")); pri.Dispose(); pub.Dispose(); }