public static string ExportToKeystore(KdfType kdfType, Wallet wallet, byte[] address, JsonSerializerSettings jsonSettings) { Contract.Assert(!string.IsNullOrWhiteSpace(wallet.PasswordHash)); var passwordHashBytes = Encoding.UTF8.GetBytes(wallet.PasswordHash); var salt = CryptoUtil.RandomBytes(32); var kdfparams = new { dklen = 32, salt = salt.ToHex() }; byte[] derivedKey; switch (kdfType) { case KdfType.Scrypt: { derivedKey = PasswordHash.ScryptHashBinary(passwordHashBytes, salt, PasswordHash.Strength.Sensitive, kdfparams.dklen); break; } case KdfType.Argon: { derivedKey = PasswordHash.ArgonHashBinary(passwordHashBytes, salt, PasswordHash.StrengthArgon.Sensitive, kdfparams.dklen); break; } default: throw new NotSupportedException("Unsupported kdf"); } var iv = CryptoUtil.RandomBytes(32); var pKey = wallet.GetPrivateKeyByAddress(address); var nonce = derivedKey.Take(24).ToArray(); var box = SecretBox.CreateDetached(pKey, nonce, iv); var keystore = new Keystore { Version = KeystoreVersion, Id = wallet.Id, Address = address.ToHex(), Crypto = new KeystoreCrypto { CipherText = box.CipherText.ToHex(), CipherParameters = new KeystoreCryptoParameters { Iv = iv.ToHex() }, Cipher = "crypto_secretbox_detached", Kdf = kdfType.ToString().ToLowerInvariant(), KdfParameters = new KeystoreKdfParameters { Salt = kdfparams.salt, DerivedKeyLength = kdfparams.dklen, }, Mac = box.Mac.ToHex() } }; return(JsonConvert.SerializeObject(keystore, Formatting.None, jsonSettings)); }