public static Keystore Generate(Configuration cfg, RawKeyPair rawKeyPair, string walletPassword, string walletName) { // create derived key with Argon2 byte[] salt = Utils.Crypto.GenerateSalt(cfg.DefaultSaltLength); Argon2 arg = Utils.Crypto.GetArgon2FromType(cfg.Argon2Mode, walletPassword); arg.DegreeOfParallelism = cfg.Parallelism; arg.Iterations = cfg.OpsLimit; arg.MemorySize = cfg.MemLimitKIB; arg.Salt = salt; byte[] rawHash = arg.GetBytes(32); // chain public and private key byte arrays byte[] privateAndPublicKey = rawKeyPair.ConcatenatedPrivateKey; // encrypt the key arrays with nonce and derived key byte[] nonce = SecretBox.GenerateNonce(); byte[] ciphertext = SecretBox.Create(privateAndPublicKey, nonce, rawHash); // generate walletName if not given if (walletName == null || walletName.Trim().Length == 0) { walletName = "generated wallet file - " + DateTime.Now; } // generate the domain object for keystore Keystore wallet = new Keystore { PublicKey = rawKeyPair.GetPublicKey(), Id = Guid.NewGuid().ToString().Replace("-", ""), Name = walletName, Version = cfg.Version, Crypto = new Crypto { SecretType = cfg.SecretType, SymmetricAlgorithm = cfg.SymmetricAlgorithm, CipherText = Hex.ToHexString(ciphertext), Kdf = cfg.Argon2Mode, CipherParams = new CipherParams { Nonce = Hex.ToHexString(nonce) }, KdfParams = new KdfParams { MemLimitKib = cfg.MemLimitKIB, OpsLimit = cfg.OpsLimit, Salt = Hex.ToHexString(salt), Parallelism = cfg.Parallelism } } }; return(wallet); }