private static PrivateKey GetPrivateKey(string msg) { while (true) { ConsoleMessage.Write(ConsoleColor.Yellow, msg); string input = Console.ReadLine(); if (input.Length != 64) { ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, should be 64 characters long! Try again.\n"); continue; } if (!input.IsHex()) { ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, is not a valid hexadecimal string!"); continue; } var p = new PrivateKey(Encoding.HexStringToByteArray(input)); if (!KeyOps.IsValidKey(p)) { ConsoleMessage.WriteLine(ConsoleColor.Red, "Invalid private key, is not a valid ED25519 key!"); } return(p); } }
public void TestAddressesBothWays() { for (int i = 0; i < 10; i++) { WalletKeys w = KeyOps.GenerateWalletKeys(); /* TRTL, Monero, random different lengths */ ulong[] prefixes = new ulong[] { 0x3bbb1d, 0x12, 0x0, 0x11, 0x222, 0x3333, 0x44444, 0x555555, 0x6666666 }; foreach (ulong prefix in prefixes) { string derivedAddress1 = Addresses.AddressFromKeys(w.privateSpendKey, w.privateViewKey, prefix); Addresses.KeysFromAddress(derivedAddress1, prefix).Do( error => Assert.Fail($"Failed to parse keys from address: {error}"), keys => { Assert.AreEqual <PublicKey>(w.publicSpendKey, keys.spendKey); Assert.AreEqual <PublicKey>(w.publicViewKey, keys.viewKey); } ); string derivedAddress2 = Addresses.AddressFromKeys(w.publicSpendKey, w.publicViewKey, prefix); Addresses.KeysFromAddress(derivedAddress2, prefix).Do( error => Assert.Fail($"Failed to parse keys from address: {error}"), keys => { Assert.AreEqual <PublicKey>(w.publicSpendKey, keys.spendKey); Assert.AreEqual <PublicKey>(w.publicViewKey, keys.viewKey); } ); } } }
/// <summary> /// Determines if the WebKey object is valid according to the rules for /// each of the possible WebKeyTypes. For more information, see WebKeyTypes. /// </summary> /// <returns>true if the WebKey is valid</returns> public virtual bool IsValid() { // MUST have kty if (string.IsNullOrEmpty(Kty)) { return(false); } // Validate Key Operations if (KeyOps != null && KeyOps.Count() != 0) { if (!KeyOps.All((op) => { return(JsonWebKeyOperation.AllOperations.Contains(op)); })) { return(false); } } // Per-kty validation switch (Kty) { case JsonWebKeyType.EllipticCurve: break; case JsonWebKeyType.Octet: return(IsValidOctet()); case JsonWebKeyType.Rsa: return(IsValidRsa()); case JsonWebKeyType.RsaHsm: return(IsValidRsaHsm()); } return(false); }
private static PrivateKeys GetPrivateKeysFromSeed() { while (true) { ConsoleMessage.Write(ConsoleColor.Yellow, "Mnemonic seed (25 words): "); string input = Console.ReadLine(); switch (Mnemonics.MnemonicToPrivateKey(input)) { case ILeft <Error> error: { ConsoleMessage.WriteLine(ConsoleColor.Red, error.Value.errorMessage); ConsoleMessage.WriteLine("Try again.\n"); continue; } case IRight <PrivateKey> key: { var privateSpendKey = key.Value; var privateViewKey = KeyOps.GenerateDeterministicKeys(privateSpendKey) .privateKey; return(new PrivateKeys(privateSpendKey, privateViewKey)); } } } }
NewWallet(string filename, string password, PrivateKey privateViewKey, string address) { if (!KeyOps.IsValidKey(privateViewKey)) { return(Either.Left <Error, WalletBackend>( Error.InvalidPrivateKey() )); } if (File.Exists(filename)) { return(Either.Left <Error, WalletBackend>( Error.FileAlreadyExists() )); } /* If we can get the keys from the address, make a new view wallet, * save it, and return it. Else, return the error */ return(Addresses.KeysFromAddress(address).Fmap( publicKeys => { WalletBackend wallet = new WalletBackend( filename, password, privateViewKey, publicKeys ); wallet.Save(); return Either.Right <Error, WalletBackend>(wallet); } )); }
/* Make a new wallet with the given filename and password, returning * either the wallet or an error */ public static IEither <Error, WalletBackend> NewWallet(string filename, string password) { WalletKeys keys = KeyOps.GenerateWalletKeys(); return(NewWallet(filename, password, keys.GetPrivateKeys())); }
NewWallet(string filename, string password, PrivateKeys privateKeys) { if (!KeyOps.IsValidKey(privateKeys.spendKey) || !KeyOps.IsValidKey(privateKeys.viewKey)) { return(Either.Left <Error, WalletBackend>( Error.InvalidPrivateKey() )); } if (File.Exists(filename)) { return(Either.Left <Error, WalletBackend>( Error.FileAlreadyExists() )); } /* Create the wallet instance */ WalletBackend wallet = new WalletBackend( filename, password, privateKeys ); /* Save it */ wallet.Save(); /* Return it */ return(Either.Right <Error, WalletBackend>(wallet)); }
public JObject GetPublicJwt() { var result = new JObject { { "kty", MAPPING_KEYTYPEENUM_TO_STR[Kty] }, { "use", MAPPING_USAGESENUM_TO_STR[Use] }, { "alg", Alg }, { "kid", Kid } }; if (KeyOps.Any()) { result.Add("key_ops", JArray.FromObject(KeyOps.Where(k => PUBLIC_KEY_OPERATIONS.Contains(k)).Select(s => MAPPING_KEYOPERATIONENUM_TO_STR[s]))); } var publicFields = MAPPING_KEYTYPE_TO_PUBLIC_KEYS[Kty]; foreach (var kvp in Content) { if (!publicFields.Contains(kvp.Key)) { continue; } result.Add(kvp.Key, kvp.Value); } return(result); }
public void TestAreKeysDeterministic() { /* A private spend key and private view key derived pair */ PrivateKey a1 = new PrivateKey(Encoding.HexStringToByteArray( "a235851985a974aeafa6db9ed4bd8cd523d3f43048bb69df5dff4dfcc445b107" )); PrivateKey a2 = new PrivateKey(Encoding.HexStringToByteArray( "b7636ec1e84039dbb6d93ddbcf0f8e39e418ce13516fa1d8c40717f81e8d370e" )); /* a2 is derived from a1 */ Assert.IsTrue(KeyOps.AreKeysDeterministic(a1, a2)); /* Derivation is only one way */ Assert.IsFalse(KeyOps.AreKeysDeterministic(a2, a1)); /* Two completely unrelated keys */ PrivateKey b1 = new PrivateKey(Encoding.HexStringToByteArray( "ee87e28220156cde3b901beb74bd089bdb512a3f6cef39fca66f900d4009fb08" )); PrivateKey b2 = new PrivateKey(Encoding.HexStringToByteArray( "677e019be0351443ea8904a6d6786056f7390eb74ba05ec327bccf2d318ca809" )); Assert.IsFalse(KeyOps.AreKeysDeterministic(b1, b2)); Assert.IsFalse(KeyOps.AreKeysDeterministic(b2, b1)); }
/* Makes a new wallet with the given private keys */ private WalletBackend(string filename, string password, PrivateKeys privateKeys) : this( filename, password, privateKeys.spendKey, privateKeys.viewKey, KeyOps.PrivateKeyToPublicKey(privateKeys.spendKey), KeyOps.PrivateKeyToPublicKey(privateKeys.viewKey), false ) { }
public bool CheckSignature(string PrefixHash, string PublicKey, string Signature) { byte[] ph = HexStringToByteArray(PrefixHash); byte[] pbk = HexStringToByteArray(PublicKey); byte[] sig = HexStringToByteArray(Signature); return(KeyOps.CheckSignature(ph, pbk, sig)); }
public string GenerateKeyImage(string PublicKey, string PrivateKey) { byte[] pbk = HexStringToByteArray(PublicKey); byte[] pvk = HexStringToByteArray(PrivateKey); byte[] output = KeyOps.GenerateKeyImage(pbk, pvk); return(ByteArrayToHexString(output)); }
public string ScalarmultKey(string KeyImageA, string KeyImageB) { byte[] kia = HexStringToByteArray(KeyImageA); byte[] kib = HexStringToByteArray(KeyImageB); byte[] output = KeyOps.ScalarmultKey(kia, kib); return(ByteArrayToHexString(output)); }
public string GenerateSignature(string PrefixHash, string PublicKey, string PrivateKey) { byte[] ph = HexStringToByteArray(PrefixHash); byte[] pbk = HexStringToByteArray(PublicKey); byte[] pvk = HexStringToByteArray(PrivateKey); byte[] sig = KeyOps.GenerateSignature(ph, pbk, pvk); return(ByteArrayToHexString(sig)); }
public void TestGenerateKeys() { KeyPair pair = KeyOps.GenerateKeys(); PublicKey pub = KeyOps.PrivateKeyToPublicKey(pair.privateKey); /* The public key should be the same one as we get get from * manual derivation of the private key */ Assert.AreEqual <PublicKey>(pair.publicKey, pub); }
private void ValidateKeyExchangeKey() { if (KeyOps != null && KeyOps.Contains(Constants.KeyOpsImport)) { // "import" is exclusive, it cannot be combined with any other value(s). if (KeyOps.Length > 1) { throw new ArgumentException(Resources.KeyOpsImportIsExclusive); } } }
public string HashToScalar(string Hash) { if (Hash.Length % 2 != 0) { return(null); } byte[] tmp = HexStringToByteArray(Hash); KeyOps.HashToScalar(ref tmp, tmp); return(ByteArrayToHexString(tmp)); }
public object Clone() { return(new JsonWebKey { Alg = Alg, KeyOps = KeyOps.ToArray(), Use = Use, Kid = Kid, Kty = Kty, SerializedKey = SerializedKey, Content = Content == null ? new Dictionary <string, string>() : Content.ToDictionary(s => s.Key, s => s.Value) }); }
public void TestGenerateDeterministicKeys() { PrivateKey p = new PrivateKey("677e019be0351443ea8904a6d6786056f7390eb74ba05ec327bccf2d318ca809"); PublicKey pubViewKey = new PublicKey("09e9c339bd1d751bf88d4d2301daa75576297e2e6b1a133cc0b9f03355421f69"); PrivateKey privViewKey = new PrivateKey("508ba238625600b2ddec49eef1f114002c76c1436d4a144c3588069c3f72ae02"); /* Generate view keys from a private spend key seed */ KeyPair pair = KeyOps.GenerateDeterministicKeys(p); Assert.AreEqual <PublicKey>(pubViewKey, pair.publicKey); Assert.AreEqual <PrivateKey>(privViewKey, pair.privateKey); }
public KeyPair GenerateKeys() { KeyPair k = new KeyPair(); byte[] pbk = new byte[32]; byte[] pvk = new byte[32]; KeyOps.GenerateKeys(ref pbk, ref pvk); k.PublicKey = ByteArrayToHexString(pbk); k.PrivateKey = ByteArrayToHexString(pvk); return(k); }
public void TestAddressesBothWays() { for (int i = 0; i < 10; i++) { WalletKeys w = KeyOps.GenerateWalletKeys(); /* TRTL, Monero, random different lengths */ ulong[] prefixes = new ulong[] { 0x3bbb1d, 0x12, 0x0, 0x11, 0x222, 0x3333, 0x44444, 0x555555, 0x6666666 }; foreach (ulong prefix in prefixes) { string derivedAddress1 = Addresses.AddressFromKeys(w.spendKeys.privateKey, w.viewKeys.privateKey, prefix); switch (Addresses.KeysFromAddress(derivedAddress1, prefix)) { case ILeft <string> error: { Assert.Fail($"Failed to parse keys from address: {error.Value}"); break; } case IRight <PublicKeys> keys: { Assert.AreEqual <PublicKey>(keys.Value.spendKey, w.spendKeys.publicKey); Assert.AreEqual <PublicKey>(keys.Value.viewKey, w.viewKeys.publicKey); break; } } string derivedAddress2 = Addresses.AddressFromKeys(w.spendKeys.publicKey, w.viewKeys.publicKey, prefix); switch (Addresses.KeysFromAddress(derivedAddress2, prefix)) { case ILeft <string> error: { Assert.Fail($"Failed to parse keys from address: {error.Value}"); break; } case IRight <PublicKeys> keys: { Assert.AreEqual <PublicKey>(keys.Value.spendKey, w.spendKeys.publicKey); Assert.AreEqual <PublicKey>(keys.Value.viewKey, w.viewKeys.publicKey); break; } } } } }
// Test key generation static void TestKeyGeneration() { // Generate a set of wallet keys WalletKeys Keys = KeyOps.GenerateWalletKeys(); // Get an address string from the generated wallet keys string Address = Addresses.AddressFromKeys(Keys.publicSpendKey, Keys.publicViewKey); // Output generated keys to console Console.WriteLine($"Private spend key: {Keys.privateSpendKey.ToString()}"); Console.WriteLine($"Private view key: {Keys.privateViewKey.ToString()}"); // Output address to console Console.WriteLine($"Public address: {Address}"); Console.WriteLine(); }
private void ValidateKeyExchangeKey() { if (KeyOps != null && KeyOps.Contains(Constants.KeyOpsImport)) { // "import" is exclusive, it cannot be combined with any other value(s). if (KeyOps.Length > 1) { throw new ArgumentException(Resources.KeyOpsImportIsExclusive); } // When KeyOps is 'import', KeyType MUST be RSA-HSM if (Destination != HsmDestination) { throw new ArgumentException(Resources.KEKMustBeHSM); } } }
public void TestPrivateKeyToPublicKey() { /* A private key and public key pair */ PrivateKey a1 = new PrivateKey("3a8441fa686f3d0c01b60264a79153c41fdd925ae4a31ffab215648f00758101"); PublicKey a2 = new PublicKey("8464c6ff818fb7f502e4533c23f6ddb615b3568dbbfe954d07f8dd8fd23aefb3"); Assert.AreEqual <PublicKey>(a2, KeyOps.PrivateKeyToPublicKey(a1)); /* Two completely unrelated keys */ PrivateKey b1 = new PrivateKey("a8219da64ddb1974292a19b6f2a3d3ef411a592191590d21ac59961c8af0c50e"); PublicKey b2 = new PublicKey("45266e9d6259817e6c38cdd7f774fc38c9596d7400b1728546cf111e342941a5"); Assert.AreNotEqual <PublicKey>(b2, KeyOps.PrivateKeyToPublicKey(b1)); }
NewWallet(string filename, string password, string mnemonicSeed) { /* Derive the mnemonic into a private spend key if possible */ return(Mnemonics.MnemonicToPrivateKey(mnemonicSeed) .Fmap(privateSpendKey => { /* Derive the private view key from the private spend key */ var privateKeys = new PrivateKeys( privateSpendKey, KeyOps.GenerateDeterministicKeys(privateSpendKey).privateKey ); /* Try and create the new wallet from the private keys */ return NewWallet(filename, password, privateKeys); })); }
public bool CheckRingSignatures(string PrefixHash, string KeyImage, string[] PublicKeys, string[] Signatures) { byte[] ph = HexStringToByteArray(PrefixHash); byte[] ki = HexStringToByteArray(KeyImage); byte[][] pks = new byte[PublicKeys.Length][]; for (int i = 0; i < PublicKeys.Length; i++) { pks[i] = HexStringToByteArray(PublicKeys[i]); } byte[][] sigs = new byte[Signatures.Length][]; for (int i = 0; i < Signatures.Length; i++) { sigs[i] = HexStringToByteArray(Signatures[i]); } return(KeyOps.CheckRingSignatures(ph, ki, pks, sigs)); }
public void TestGenerateWalletKeys() { WalletKeys keys = KeyOps.GenerateWalletKeys(); var privateSpendKey = keys.spendKeys.privateKey; var privateViewKey = keys.viewKeys.privateKey; /* All newly generated keys should be a deterministic pair */ Assert.IsTrue(KeyOps.AreKeysDeterministic(privateSpendKey, privateViewKey)); var publicSpendKey = KeyOps.PrivateKeyToPublicKey(privateSpendKey); var publicViewKey = KeyOps.PrivateKeyToPublicKey(privateViewKey); /* We should derive the same public keys from the private keys * as the ones returned from GenerateWalletKeys() */ Assert.AreEqual <PublicKey>(publicSpendKey, keys.spendKeys.publicKey); Assert.AreEqual <PublicKey>(publicViewKey, keys.viewKeys.publicKey); }
public void TestMnemonicBothWays() { for (int i = 0; i < 1000; i++) { /* Generate a random private key */ PrivateKey p = KeyOps.GenerateKeys().privateKey; /* Convert to mnemonic */ string m = Mnemonics.PrivateKeyToMnemonic(p); /* Convert back to a private key */ Mnemonics.MnemonicToPrivateKey(m).Do( err => Assert.Fail($"Failed to parse mnemonic seed: {err}"), /* Should be the same as the original private key */ key => Assert.AreEqual <PrivateKey>(p, key) ); } }
public string HashToEllipticCurve(string Hash) { if (!IsKey(Hash)) { return(null); } byte[] tmp = HexStringToByteArray(Hash); ge_p3 tmp3 = new ge_p3(); KeyOps.HashToEllipticCurve(tmp3, tmp); byte[] output = new byte[32]; ED25519.ge_p3_tobytes(ref output, tmp3); return(ByteArrayToHexString(output)); }
public string[] GenerateRingSignatures(string PrefixHash, string KeyImage, string[] PublicKeys, string TransactionSecretKey, ulong realOutput) { byte[] ph = HexStringToByteArray(PrefixHash); byte[] ki = HexStringToByteArray(KeyImage); byte[][] pks = new byte[PublicKeys.Length][]; for (int i = 0; i < PublicKeys.Length; i++) { pks[i] = HexStringToByteArray(PublicKeys[i]); } byte[] tsk = HexStringToByteArray(TransactionSecretKey); byte[][] sigs = KeyOps.GenerateRingSignatures(ph, ki, pks, tsk, realOutput); string[] output = new string[sigs.Length]; for (int i = 0; i < sigs.Length; i++) { output[i] = ByteArrayToHexString(sigs[i]); } return(output); }