public static string signMsgWithPem(string msg, string pem) { if (msg == null || msg.Length == 0) { throw new ArgumentException("Message cannot be empty."); } string[] keyInfo = keysFromPem(pem); string privKey = keyInfo [2]; // Console.WriteLine ("Uncomp PubKey: " + keyInfo[0]); BigInteger privKeyNum = new BigInteger(privKey, 16); BitCoinSharp.EcKey keys = new BitCoinSharp.EcKey(privKeyNum); byte[] msgBytes = Encoding.UTF8.GetBytes(msg); SHA256Managed hashstring = new SHA256Managed(); byte[] msgHash = hashstring.ComputeHash(msgBytes); byte[] signedMsgBytes = keys.Sign(msgHash); string signedMsg = Utils.BytesToHexString(signedMsgBytes); return(signedMsg); }
/// <summary> /// Once a transaction has some inputs and outputs added, the signatures in the inputs can be calculated. The /// signature is over the transaction itself, to prove the redeemer actually created that transaction, /// so we have to do this step last. /// </summary> /// <remarks> /// This method is similar to SignatureHash in script.cpp /// </remarks> /// <param name="hashType">This should always be set to SigHash.ALL currently. Other types are unused. </param> /// <param name="wallet">A wallet is required to fetch the keys needed for signing.</param> /// <exception cref="ScriptException"/> public void SignInputs(SigHash hashType, Wallet wallet) { Debug.Assert(_inputs.Count > 0); Debug.Assert(_outputs.Count > 0); // I don't currently have an easy way to test other modes work, as the official client does not use them. Debug.Assert(hashType == SigHash.All); // The transaction is signed with the input scripts empty except for the input we are signing. In the case // where addInput has been used to set up a new transaction, they are already all empty. The input being signed // has to have the connected OUTPUT program in it when the hash is calculated! // // Note that each input may be claiming an output sent to a different key. So we have to look at the outputs // to figure out which key to sign with. var signatures = new byte[_inputs.Count][]; var signingKeys = new EcKey[_inputs.Count]; for (var i = 0; i < _inputs.Count; i++) { var input = _inputs[i]; Debug.Assert(input.ScriptBytes.Length == 0, "Attempting to sign a non-fresh transaction"); // Set the input to the script of its output. input.ScriptBytes = input.Outpoint.ConnectedPubKeyScript; // Find the signing key we'll need to use. var connectedPubKeyHash = input.Outpoint.ConnectedPubKeyHash; var key = wallet.FindKeyFromPubHash(connectedPubKeyHash); // This assert should never fire. If it does, it means the wallet is inconsistent. Debug.Assert(key != null, "Transaction exists in wallet that we cannot redeem: " + Utils.BytesToHexString(connectedPubKeyHash)); // Keep the key around for the script creation step below. signingKeys[i] = key; // The anyoneCanPay feature isn't used at the moment. const bool anyoneCanPay = false; var hash = HashTransactionForSignature(hashType, anyoneCanPay); // Set the script to empty again for the next input. input.ScriptBytes = TransactionInput.EmptyArray; // Now sign for the output so we can redeem it. We use the keypair to sign the hash, // and then put the resulting signature in the script along with the public key (below). using (var bos = new MemoryStream()) { bos.Write(key.Sign(hash)); bos.Write((byte)(((int)hashType + 1) | (anyoneCanPay ? 0x80 : 0))); signatures[i] = bos.ToArray(); } } // Now we have calculated each signature, go through and create the scripts. Reminder: the script consists of // a signature (over a hash of the transaction) and the complete public key needed to sign for the connected // output. for (var i = 0; i < _inputs.Count; i++) { var input = _inputs[i]; Debug.Assert(input.ScriptBytes.Length == 0); var key = signingKeys[i]; input.ScriptBytes = Script.CreateInputScript(signatures[i], key.PubKey); } // Every input is now complete. }
public static String generatePem() { // Create a new key BitCoinSharp.EcKey keys = new BitCoinSharp.EcKey(); StringWriter stringWriter = new StringWriter(); PemWriter pemWriter = new PemWriter(stringWriter); const string DER1 = "30740201010420"; string privKey = (privKeyFromKeyPair(keys)); // Make sure private key is in correct format privKey = checkHas64(privKey); const string DER2 = "a0070605"; const string DER3 = "2b8104000a"; const string DER4 = "a144034200"; string pubKey = uncompressedPubKeyFromKeyPair(keys); string fullDER = DER1 + privKey + DER2 + DER3 + DER4 + pubKey; PemObject pemObj = new PemObject("EC PRIVATE KEY", hexToBytes(fullDER)); pemWriter.WriteObject(pemObj); string pem = stringWriter.ToString(); return(pem); }
public static String generatePem() { // Create a new key BitCoinSharp.EcKey keys = new BitCoinSharp.EcKey(); StringWriter stringWriter = new StringWriter (); PemWriter pemWriter = new PemWriter (stringWriter); const string DER1 = "30740201010420"; string privKey = (privKeyFromKeyPair (keys)); // Make sure private key is in correct format privKey = checkHas64 (privKey); const string DER2 = "a0070605"; const string DER3 = "2b8104000a"; const string DER4 = "a144034200"; string pubKey = uncompressedPubKeyFromKeyPair (keys); string fullDER = DER1 + privKey + DER2 + DER3 + DER4 + pubKey; PemObject pemObj = new PemObject("EC PRIVATE KEY", hexToBytes(fullDER)); pemWriter.WriteObject(pemObj); string pem = stringWriter.ToString (); return pem; }
public static String deriveSIN(EcKey ecKey) { // Get sha256 hash and then the RIPEMD-160 hash of the public key (this call gets the result in one step). byte[] pubKeyHash = ecKey.PubKeyHash; // Convert binary pubKeyHash, SINtype and version to Hex String version = "0F"; String SINtype = "02"; String pubKeyHashHex = bytesToHex(pubKeyHash); // Concatenate all three elements String preSIN = version + SINtype + pubKeyHashHex; // Convert the hex string back to binary and double sha256 hash it leaving in binary both times byte[] preSINbyte = hexToBytes(preSIN); byte[] hash2Bytes = Utils.DoubleDigest(preSINbyte); // Convert back to hex and take first four bytes String hashString = bytesToHex(hash2Bytes); String first4Bytes = hashString.Substring(0, 8); // Append first four bytes to fully appended SIN string String unencoded = preSIN + first4Bytes; byte[] unencodedBytes = new BigInteger(unencoded, 16).ToByteArray(); String encoded = Base58.Encode(unencodedBytes); return encoded; }
public static void saveEcKey(EcKey ecKey) { byte[] bytes = ecKey.ToAsn1(); FileStream fs = new FileStream(PRIV_KEY_FILENAME, FileMode.Create, FileAccess.Write); fs.Write(bytes, 0, bytes.Length); fs.Close(); }
private static string privKeyFromKeyPair(BitCoinSharp.EcKey keys) { string keyString = keys.ToString(); int indexPrivKeyStart = keyString.IndexOf("priv:") + 5; // to account for the actual chars "priv:" string privKeyString = keyString.Substring(indexPrivKeyStart); privKeyString = checkHas64(privKeyString); return(privKeyString); }
/// <summary> /// Constructor for use if the keys and SIN were derived external to this library. /// </summary> /// <param name="ecKey">An elliptical curve key.</param> /// <param name="clientName">The label for this client.</param> /// <param name="envUrl">The target server URL.</param> public BitPay(EcKey ecKey, String clientName = BITPAY_PLUGIN_INFO, String envUrl = BITPAY_URL) { // IgnoreBadCertificates(); _ecKey = ecKey; this.deriveIdentity(); _baseUrl = envUrl; _httpClient = new HttpClient(); _httpClient.BaseAddress = new Uri(_baseUrl); this.tryGetAccessTokens(); }
// ************************************* // * Private Methods * // ************************************* private static string uncompressedPubKeyFromKeyPair(BitCoinSharp.EcKey keys) { string keyString = keys.ToString(); int indexPubKeyStart = keyString.IndexOf("pub:") + 4; // to account for the actual chars "pub:" int indexPubKeyEnd = keyString.LastIndexOf("priv:") - 1; // to account for the space char before "priv:" string pubKeyString = keyString.Substring(indexPubKeyStart, indexPubKeyEnd - indexPubKeyStart); pubKeyString = checkHas64(pubKeyString); return(pubKeyString); }
/// <summary> /// Once a transaction has some inputs and outputs added, the signatures in the inputs can be calculated. The /// signature is over the transaction itself, to prove the redeemer actually created that transaction, /// so we have to do this step last. /// </summary> /// <remarks> /// This method is similar to SignatureHash in script.cpp /// </remarks> /// <param name="hashType">This should always be set to SigHash.ALL currently. Other types are unused. </param> /// <param name="wallet">A wallet is required to fetch the keys needed for signing.</param> /// <exception cref="ScriptException"/> public void SignInputs(SigHash hashType, Wallet wallet) { Debug.Assert(_inputs.Count > 0); Debug.Assert(_outputs.Count > 0); // I don't currently have an easy way to test other modes work, as the official client does not use them. Debug.Assert(hashType == SigHash.All); // The transaction is signed with the input scripts empty except for the input we are signing. In the case // where addInput has been used to set up a new transaction, they are already all empty. The input being signed // has to have the connected OUTPUT program in it when the hash is calculated! // // Note that each input may be claiming an output sent to a different key. So we have to look at the outputs // to figure out which key to sign with. var signatures = new byte[_inputs.Count][]; var signingKeys = new EcKey[_inputs.Count]; for (var i = 0; i < _inputs.Count; i++) { var input = _inputs[i]; Debug.Assert(input.ScriptBytes.Length == 0, "Attempting to sign a non-fresh transaction"); // Set the input to the script of its output. input.ScriptBytes = input.Outpoint.ConnectedPubKeyScript; // Find the signing key we'll need to use. var connectedPubKeyHash = input.Outpoint.ConnectedPubKeyHash; var key = wallet.FindKeyFromPubHash(connectedPubKeyHash); // This assert should never fire. If it does, it means the wallet is inconsistent. Debug.Assert(key != null, "Transaction exists in wallet that we cannot redeem: " + Utils.BytesToHexString(connectedPubKeyHash)); // Keep the key around for the script creation step below. signingKeys[i] = key; // The anyoneCanPay feature isn't used at the moment. const bool anyoneCanPay = false; var hash = HashTransactionForSignature(hashType, anyoneCanPay); // Set the script to empty again for the next input. input.ScriptBytes = TransactionInput.EmptyArray; // Now sign for the output so we can redeem it. We use the keypair to sign the hash, // and then put the resulting signature in the script along with the public key (below). using (var bos = new MemoryStream()) { bos.Write(key.Sign(hash)); bos.Write((byte) (((int) hashType + 1) | (anyoneCanPay ? 0x80 : 0))); signatures[i] = bos.ToArray(); } } // Now we have calculated each signature, go through and create the scripts. Reminder: the script consists of // a signature (over a hash of the transaction) and the complete public key needed to sign for the connected // output. for (var i = 0; i < _inputs.Count; i++) { var input = _inputs[i]; Debug.Assert(input.ScriptBytes.Length == 0); var key = signingKeys[i]; input.ScriptBytes = Script.CreateInputScript(signatures[i], key.PubKey); } // Every input is now complete. }
private void initKeys() { if (KeyUtils.privateKeyExists()) { _ecKey = KeyUtils.loadEcKey(); // Alternatively, load your private key from a location you specify. // _ecKey = KeyUtils.createEcKeyFromHexStringFile("C:\\Users\\key.priv"); } else { _ecKey = KeyUtils.createEcKey(); KeyUtils.saveEcKey(_ecKey); } }
/// <summary> /// Adds the given ECKey to the wallet. There is currently no way to delete keys (that would result in coin loss). /// </summary> public void AddKey(EcKey key) { lock (this) { Debug.Assert(!Keychain.Contains(key)); Keychain.Add(key); } }
public static string signMsgWithPem(string msg, string pem) { if (msg == null || msg.Length == 0) throw new ArgumentException("Message cannot be empty."); string[] keyInfo = keysFromPem (pem); string privKey = keyInfo [2]; // Console.WriteLine ("Uncomp PubKey: " + keyInfo[0]); BigInteger privKeyNum = new BigInteger(privKey, 16); BitCoinSharp.EcKey keys = new BitCoinSharp.EcKey (privKeyNum); byte[] msgBytes = Encoding.UTF8.GetBytes (msg); SHA256Managed hashstring = new SHA256Managed(); byte[] msgHash = hashstring.ComputeHash(msgBytes); byte[] signedMsgBytes = keys.Sign (msgHash); string signedMsg = Utils.BytesToHexString (signedMsgBytes); return signedMsg; }
public static EcKey createEcKeyFromHexString(String privateKey) { BigInteger pkey = new BigInteger(privateKey, 16); EcKey key = new EcKey(pkey, true); return key; }
public static String sign(EcKey ecKey, String input) { String hash = sha256Hash(input); return bytesToHex(ecKey.Sign(hexToBytes(hash))); }