/// <summary> /// Verify a /// </summary> /// <param name="pubKey"></param> /// <param name="hash"></param> /// <param name="signature"></param> /// <returns></returns> public static bool VerifyHashSignatureSecp256k1(string pubKey, string hash, string signature) { var secp256k1 = ECCurve.CreateFromValue("1.3.132.0.10"); // signature is DER encoded -> convert to 64 byte array var sigBytes = HexStringToByteArray(signature); var p1len = sigBytes[3]; var sigp1 = sigBytes.Skip(4).SkipWhile(b => b == 0).Take(32).ToArray(); // Remove any 0 padded bytes var p2len = sigBytes.Skip(4 + p1len + 1).Take(1).ToArray()[0]; var sigp2 = sigBytes.Skip(4 + p1len + 2).SkipWhile(b => b == 0).Take(32).ToArray(); // Remove any 0 padded bytes var sig = sigp1.Concat(sigp2).ToArray(); PubKey pk = new PubKey(HexStringToByteArray(pubKey)); var pkBytes = pk.Decompress().ToBytes(); using (var dsa = ECDsa.Create(new ECParameters { Curve = secp256k1, Q = new ECPoint { // gets the {x,y} from the uncompressed public key X = pkBytes.Skip(1).Take(32).ToArray(), Y = pkBytes.Skip(33).ToArray(), } })) { var isValid = dsa.VerifyHash(HexStringToByteArray(hash), sig); return(isValid); } }
string IAddressGenerator.GenerateAddress(byte[] pubKeyBytes) { var pubKey = new PubKey(pubKeyBytes); var decompPubKeyBytes = pubKey.Decompress().ToBytes(); return(Address.WithNetwork(Network.Mainnet).NewSecp256k1Address(decompPubKeyBytes).ToString()); }
public bool Check(string passphrase, BitcoinAddress expectedAddress) { //Derive passfactor using scrypt with ownerentropy and the user's passphrase and use it to recompute passpoint var passfactor = BitcoinEncryptedSecretEC.CalculatePassFactor(passphrase, this.LotSequence, this.OwnerEntropy); //Derive decryption key for pointb using scrypt with passpoint, addresshash, and ownerentropy var passpoint = BitcoinEncryptedSecretEC.CalculatePassPoint(passfactor); var derived = BitcoinEncryptedSecretEC.CalculateDecryptionKey(passpoint, this.AddressHash, this.OwnerEntropy); //Decrypt encryptedpointb to yield pointb var pointbprefix = this.EncryptedPointB[0]; pointbprefix = (byte)(pointbprefix ^ (byte)(derived[63] & 0x01)); //Optional since ArithmeticException will catch it, but it saves some times if (pointbprefix != 0x02 && pointbprefix != 0x03) { return(false); } var pointb = BitcoinEncryptedSecret.DecryptKey(this.EncryptedPointB.Skip(1).ToArray(), derived); pointb = new[] { pointbprefix }.Concat(pointb).ToArray(); //4.ECMultiply pointb by passfactor. Use the resulting EC point as a public key var curve = ECKey.Secp256k1; ECPoint pointbec; try { pointbec = curve.Curve.DecodePoint(pointb); } catch (ArgumentException) { return(false); } catch (ArithmeticException) { return(false); } var pubkey = new PubKey(pointbec.Multiply(new BigInteger(1, passfactor)).GetEncoded()); //and hash it into address using either compressed or uncompressed public key methodology as specifid in flagbyte. pubkey = this.IsCompressed ? pubkey.Compress() : pubkey.Decompress(); var actualhash = BitcoinEncryptedSecretEC.HashAddress(pubkey.GetAddress(this.Network)); var expectedhash = BitcoinEncryptedSecretEC.HashAddress(expectedAddress); return(Utils.ArrayEqual(actualhash, expectedhash)); }
public static string generateAddress() { // Currently we get PrivateKey and PubKey and Wif from the NBitcoin library. Haven't written my own code yet. // https://github.com/MetacoSA/NBitcoin (available from the Nu-Get package manager) Key privateKey = new Key(); // generate a random private key BitcoinSecret wif = privateKey.GetWif(Network.Main); PubKey pubKey = privateKey.PubKey; string publicKey = pubKey.ToString(); //"03c18bc24ea4b6e1fc08c356f436d9ffaca4f583c0adc0c83a36b3a1b3abeef762"; //Console.WriteLine("Publickey: " + publicKey); //var hash = getHashSha256(publicKeyHex); var hash = getHash("sha256", publicKey); //Console.WriteLine("hash:" + hash); //Console.ReadLine(); //RIPEMD160 r = RIPEMD160Managed.Create("SHA256"); string hashed = getHash("ripemd160", hash); //Console.WriteLine("hashed:" + hashed); hashed = "3c" + hashed; //Console.WriteLine("<hashed:" + hashed); //Console.ReadLine(); string newhash1 = getHash("sha256", hashed); string newhash2 = getHash("sha256", newhash1); string checksum = newhash2.Substring(0, 8); // 4 hex-bytes = 8 characters //Console.WriteLine("first hash256: " + newhash1); //Console.WriteLine("2nd hash256: " + newhash2); //Console.WriteLine("Checksum: " + checksum); //Console.ReadLine(); string withChecksum = hashed + checksum; string address = ConvertToBase58(withChecksum); //Console.WriteLine(address); //var r = ripemd160(Crypto.SHA256(Crypto.util.hexToBytes(h), { asBytes: true})); //r.unshift(byte || coinjs.pub); //var hash = Crypto.SHA256(Crypto.SHA256(r, { asBytes: true}), { asBytes: true}); //var checksum = hash.slice(0, 4); //return coinjs.base58encode(r.concat(checksum)) return(wif + "," + privateKey.ToHex() + "," + pubKey.Decompress().ToString() + "," + address + "\n"); }
//Referenced By: https://github.com/MetacoSA/NBitcoin/issues/565 public string GenerateAddress(byte[] pubKeyBytes) { var ETH_publickKey = new PubKey(pubKeyBytes); byte[] byte_ETH_publicKey = ETH_publickKey.Decompress().ToBytes(); var PubKeyNoPrefix = new byte[byte_ETH_publicKey.Length - 1]; Array.Copy(byte_ETH_publicKey, 1, PubKeyNoPrefix, 0, PubKeyNoPrefix.Length); var initaddr = new Nethereum.Util.Sha3Keccack().CalculateHash(PubKeyNoPrefix); var addr = new byte[initaddr.Length - 12]; Array.Copy(initaddr, 12, addr, 0, initaddr.Length - 12); var hex_addr = BitConverter.ToString(addr).Replace("-", ""); string public_address = new Nethereum.Util.AddressUtil().ConvertToChecksumAddress(hex_addr); return(public_address); }
public void ShouldGeneratePublicKeyFromPrivateKey() { var priv = "181ff77d7286b81334b7166f290c0a509b5106c21505aba3f004bbc3bd78027b"; Wallet wallet = new FileCoinWallet(priv); var pubKeyDecomp = wallet.PublicKey.Decompress(); Assert.AreEqual( expected: "04e2c906303ddcc8a52c6e9e42c5c83c1e43fc4ca3e15357ae85478adbc029cacdddf97830cf46720d41e04ab4592b7db219fda58f289e1df170d34fd174672cc3", actual: pubKeyDecomp.ToHex() ); var pubKey = new PubKey(wallet.PublicKey.ToBytes()); Assert.AreEqual( expected: "04e2c906303ddcc8a52c6e9e42c5c83c1e43fc4ca3e15357ae85478adbc029cacdddf97830cf46720d41e04ab4592b7db219fda58f289e1df170d34fd174672cc3", actual: pubKey.Decompress().ToHex() ); }
public string GenerateAddress(byte[] pubKeyBytes, Network network, Protocol protocol) { var pubKey = new PubKey(pubKeyBytes); var decompPubKeyBytes = pubKey.Decompress().ToBytes(); var address = Address.WithNetwork(network); switch (protocol) { case Protocol.SECP256K1: address = address.NewSecp256k1Address(decompPubKeyBytes); break; default: throw new NotSupportedException(); } return(address.ToString()); }
string GenerateAddress(PubKey pubKey, NetworkVersion networkVersion) { var minLength = -1; var publicKey = pubKey.Decompress(); var pubKeyBytes = publicKey.ToBytes(); var version = (int)networkVersion; var versionHex = Convert.ToString(version, 16); var pubKeyHash160BytesSha256 = NBitcoin.Crypto.Hashes.SHA256(pubKeyBytes); var pubKeyHash160Bytes = NBitcoin.Crypto.Hashes.RIPEMD160(pubKeyHash160BytesSha256, pubKeyHash160BytesSha256.Length); var pubKeyHash160Hex = pubKeyHash160Bytes.ToHexString(); var hash160Regex = new Regex(@"/^[0-9a-fA-F]{40}$/"); if (hash160Regex.Match(pubKeyHash160Hex).Length > 0) { throw new ArgumentException("Invalid argument: not a hash160 hex string"); } var checksumInputHex = $"{versionHex}{pubKeyHash160Hex}"; var checksumInputBytes = checksumInputHex.FromHexToByteArray(); if (version < 0 || version >= 32) { throw new ArgumentOutOfRangeException("Invalid version (must be between 0 and 31)"); } if (versionHex.Length == 1) { versionHex = $"0{versionHex}"; } var checksumRegex = new Regex(@"/^[0-9a-fA-F]*$/"); if (checksumRegex.Match(checksumInputHex).Length > 0) { throw new ArgumentException("Invalid data (not a hex string)"); } var doubleHashedChecksumInputBytes = NBitcoin.Crypto.Hashes.SHA256(NBitcoin.Crypto.Hashes.SHA256(checksumInputBytes)); var checksumHex = doubleHashedChecksumInputBytes[..4].ToHexString();
string GenerateAddress(PubKey pubKey) { var publicKey = pubKey.Decompress(); var pubKeyBytes = publicKey.ToBytes(); pubKeyBytes = pubKeyBytes.Skip(1).ToArray(); var pubKeyHash = new Sha3Keccack().CalculateHash(pubKeyBytes); var sha3HashBytes = new byte[20]; Array.Copy(pubKeyHash, pubKeyHash.Length - 20, sha3HashBytes, 0, 20); byte[] PKHWithVersionBytes = Helper.Concat(new byte[] { 65 }, sha3HashBytes); var hexAddress = PKHWithVersionBytes.ToHexString(); var address = Encoders.Base58Check.EncodeData(PKHWithVersionBytes); return(address); }
public static String GetETHLedgerAddress(ExtPubKey pubkey, int index) { var pkd = pubkey; PubKey ETH_publickKey = pkd.PubKey; byte[] byte_ETH_publicKey = ETH_publickKey.Decompress().ToBytes(); var PubKeyNoPrefix = new byte[byte_ETH_publicKey.Length - 1]; Array.Copy(byte_ETH_publicKey, 1, PubKeyNoPrefix, 0, PubKeyNoPrefix.Length); var initaddr = new Nethereum.Util.Sha3Keccack().CalculateHash(PubKeyNoPrefix); var addr = new byte[initaddr.Length - 12]; Array.Copy(initaddr, 12, addr, 0, initaddr.Length - 12); var hex_addr = BitConverter.ToString(addr).Replace("-", ""); string public_address = new Nethereum.Util.AddressUtil().ConvertToChecksumAddress(hex_addr); return(public_address); }
static void Main(string[] args) { // Number of BTC and ETH keys to generate int n = 100; Console.WriteLine(""); // Generate Bitcoin addresses and private keys Console.WriteLine("Generating " + n + " BTC addresses & private keys..."); Console.WriteLine(""); string BTCfileName = "C:\\GENKEYS\\BitcoinKeys.csv"; if (!File.Exists(BTCfileName)) { string header = "ID, BTC address, BTC privateKey, Assigned" + Environment.NewLine; File.WriteAllText(BTCfileName, header); } for (int i = 1; i <= n; i++) { try { Guid guid = Guid.NewGuid(); Key privateKey = new Key(); // generate a random private key PubKey publicKey = privateKey.PubKey; // derive public key var privateKeySecret = privateKey.GetBitcoinSecret(Network.Main); var address = publicKey.Decompress().GetAddress(Network.Main); string keys = guid + "," + address + "," + privateKeySecret + ", 0" + Environment.NewLine; File.AppendAllText(BTCfileName, keys); Console.WriteLine("BTC address: " + address); } catch (Exception x) { Console.WriteLine("Error:" + x.Message); Console.WriteLine(""); } } // -------------------------------------------- Console.WriteLine(""); Console.WriteLine(""); Console.WriteLine(""); // -------------------------------------------- // Generate Ethereum addresses and private keys Console.WriteLine("Generating " + n + " ETH addresses & private keys..."); Console.WriteLine(""); string ETHfileName = "C:\\GENKEYS\\EthereumKeys.csv"; if (!File.Exists(ETHfileName)) { string header = "ID, ETH address, ETH privateKey, Assigned" + Environment.NewLine; File.WriteAllText(ETHfileName, header); } for (int i = 1; i <= n; i++) { try { Guid guid = Guid.NewGuid(); var ecKey = EthECKey.GenerateKey(); // generate a random private key var privateKeyAsBytes = ecKey.GetPrivateKeyAsBytes().ToHex(); // derive public key var address = ecKey.GetPublicAddress(); string keys = guid + "," + address + "," + privateKeyAsBytes + ", 0" + Environment.NewLine; File.AppendAllText(ETHfileName, keys); Console.WriteLine("ETH address: " + address); } catch (Exception x) { Console.WriteLine("Error:" + x.Message); Console.WriteLine(""); } } }
public EncryptedKeyResult GenerateEncryptedSecret(bool isCompressed = true, byte[] seedb = null) { //Set flagbyte. byte flagByte = 0; //Turn on bit 0x20 if the Bitcoin address will be formed by hashing the compressed public key flagByte |= isCompressed ? (byte)0x20 : (byte)0x00; flagByte |= LotSequence != null ? (byte)0x04 : (byte)0x00; //Generate 24 random bytes, call this seedb. Take SHA256(SHA256(seedb)) to yield 32 bytes, call this factorb. seedb = seedb ?? RandomUtils.GetBytes(24); var factorb = Hashes.Hash256(seedb).ToBytes(); //ECMultiply passpoint by factorb. var curve = ECKey.Secp256k1; var passpoint = curve.Curve.DecodePoint(Passpoint); var pubPoint = passpoint.Multiply(new BigInteger(1, factorb)); //Use the resulting EC point as a public key var pubKey = new PubKey(pubPoint.GetEncoded()); //and hash it into a Bitcoin address using either compressed or uncompressed public key //This is the generated Bitcoin address, call it generatedaddress. pubKey = isCompressed ? pubKey.Compress() : pubKey.Decompress(); //call it generatedaddress. var generatedaddress = pubKey.GetAddress(Network); //Take the first four bytes of SHA256(SHA256(generatedaddress)) and call it addresshash. var addresshash = BitcoinEncryptedSecretEC.HashAddress(generatedaddress); //Derive a second key from passpoint using scrypt //salt is addresshash + ownerentropy var derived = BitcoinEncryptedSecretEC.CalculateDecryptionKey(Passpoint, addresshash, OwnerEntropy); //Now we will encrypt seedb. var encrypted = BitcoinEncryptedSecret.EncryptSeed (seedb, derived); //0x01 0x43 + flagbyte + addresshash + ownerentropy + encryptedpart1[0...7] + encryptedpart2 which totals 39 bytes var bytes = new[] { flagByte } .Concat(addresshash) .Concat(this.OwnerEntropy) .Concat(encrypted.Take(8).ToArray()) .Concat(encrypted.Skip(16).ToArray()) .ToArray(); var encryptedSecret = new BitcoinEncryptedSecretEC(bytes, Network); return(new EncryptedKeyResult(encryptedSecret, generatedaddress, seedb, () => { //ECMultiply factorb by G, call the result pointb. The result is 33 bytes. var pointb = new Key(factorb).PubKey.ToBytes(); //The first byte is 0x02 or 0x03. XOR it by (derivedhalf2[31] & 0x01), call the resulting byte pointbprefix. var pointbprefix = (byte)(pointb[0] ^ (byte)(derived[63] & 0x01)); var pointbx = BitcoinEncryptedSecret.EncryptKey(pointb.Skip(1).ToArray(), derived); var encryptedpointb = new byte[] { pointbprefix }.Concat(pointbx).ToArray(); var confirmBytes = Network.GetVersionBytes(Base58Type.CONFIRMATION_CODE) .Concat(new[] { flagByte }) .Concat(addresshash) .Concat(OwnerEntropy) .Concat(encryptedpointb) .ToArray(); return new BitcoinConfirmationCode(Encoders.Base58Check.EncodeData(confirmBytes), Network); })); }
public void TestAddressCreation() { Key privateKey; // = new Key(); privateKey = Key.Parse("L5e7GTVzDEFTS2YwRJcRse5LkgpAetKApCafc6avoKLovPcnFE74", Network.Main); // For getting the same outputs PubKey publicKey = privateKey.PubKey; BitcoinAddress addressLegacy = publicKey.GetAddress(ScriptPubKeyType.Legacy, Network.Main); BitcoinAddress addressSegwit = publicKey.GetAddress(ScriptPubKeyType.Segwit, Network.Main); BitcoinAddress addressSegwitP2SH = publicKey.GetAddress(ScriptPubKeyType.SegwitP2SH, Network.Main); KeyId publicKeyHash = publicKey.Hash; // Wif -> // Priv. key -> Wif (Check README.md - Wif) BitcoinSecret wif = privateKey.GetWif(Network.Main); BitcoinSecret wif2 = new BitcoinSecret("L5e7GTVzDEFTS2YwRJcRse5LkgpAetKApCafc6avoKLovPcnFE74", Network.Main); Assert.AreEqual(wif, wif2); // Private key -> // Wif -> Priv. key Key privateKey1 = Key.Parse("L5e7GTVzDEFTS2YwRJcRse5LkgpAetKApCafc6avoKLovPcnFE74", Network.Main); Assert.AreEqual(privateKey, privateKey1); // Base58 encoded priv key var privKeyVersionBytes = Network.Main.GetVersionBytes(Base58Type.SECRET_KEY, true); byte[] privKeyWithVersionBytes = Helper.Concat(privKeyVersionBytes, privateKey.ToBytes()); var privKeyBase58 = Encoders.Base58Check.EncodeData(privKeyWithVersionBytes); // Encrypted priv key (BIP38) BitcoinEncryptedSecret encryptedPrivKey = wif.Encrypt("password"); // Decrypted priv key BitcoinEncryptedSecret encryptedPrivKeyFromStr = BitcoinEncryptedSecret.Create("6PYWRpL1zPnz5kVxn74H9WdGJZVQ3ah6Pnq54GNinkfrXdd9fWNVS6dn95", Network.Main); BitcoinSecret decryptedPrivKey = encryptedPrivKeyFromStr.GetSecret("password"); Assert.AreEqual(wif, decryptedPrivKey); // Public key hash -> // Check README (Hash160(Public Key)) var hash1 = NBitcoin.Crypto.Hashes.SHA256(publicKey.ToBytes()); var pkh = NBitcoin.Crypto.Hashes.RIPEMD160(hash1, hash1.Length); // SHA256(RIPEMD160(PUB_KUY)) var generatedPubKeyHash = new KeyId(pkh); Assert.AreEqual(publicKeyHash, generatedPubKeyHash); // Bitcoin Address > var versionBytes = Network.Main.GetVersionBytes(Base58Type.PUBKEY_ADDRESS, true); // 0x00 byte[] PKHWithVersionBytes = Helper.Concat(versionBytes, pkh); // 0x00 + PKH var address1 = Encoders.Base58Check.EncodeData(PKHWithVersionBytes); Assert.AreEqual(addressLegacy.ToString(), address1); // 1Co3ZZ3U5ELVmZrV3oXk2qbv58AjuwRrnB Console.WriteLine(); Console.WriteLine($"Pri : {privateKey.ToHex()} (Hex)"); // fb401b5261327d8543382c065af27e28a9775c278b7c3dba8cd0d88f0ad042b1 Console.WriteLine($"Pri : {privKeyBase58} (Base58)"); // 5KiwSFcZuAM3N5Ruf8cfiNzdCFupxFoFuqPafmK7JHqtsEms7HB Console.WriteLine($"Pri : {encryptedPrivKey} (Encrypted)"); // 6PYWRpL1zPnz5kVxn74H9WdGJZVQ3ah6Pnq54GNinkfrXdd9fWNVS6dn95 Console.WriteLine($"Pri : {wif} (Wif)"); // L5e7GTVzDEFTS2YwRJcRse5LkgpAetKApCafc6avoKLovPcnFE74 Console.WriteLine($"Pub : {publicKey}"); // 03c092d451383dedd6052de6778f9b7c393252ecbd4cd05e842638a84a2c6e2528 Console.WriteLine($"Pub : {publicKey.Decompress()} (Decomp.)"); // 04c092d451383dedd6052de6778f9b7c393252ecbd4cd05e842638a84a2c6e2528fe41f265a1d8884eb304a33b6f8a6a245fab83f7bf503d7dfc532ffc6593df15 Console.WriteLine($"PKH : {publicKey.Hash}"); // 815ea7e8372ae215c40dc3d07a024adc7ddaf858 Console.WriteLine($"Add : {addressLegacy} (Legacy)"); // 1Co3ZZ3U5ELVmZrV3oXk2qbv58AjuwRrnB Console.WriteLine($"Add : {addressSegwitP2SH} (SegwitP2SH)"); // 3JCvRhjrEyw9pvZiE3TxsdSHNPJQh1vHTe Console.WriteLine($"Add : {addressSegwit} (Segwit)"); // bc1qs90206ph9t3pt3qdc0g85qj2m37a47zclpwws7 }
public void TestVerify() { // Sample challenge-response // Send to wallet: // req: lnurl1dp68gup69uhnzwfj9ccnvwpwxqhrzdej8gerwdf5xvhkcmnpw46xstmnd9nku6tw8a6xzeead3hkw6twye4nz0f4xqenqvps89zrxd6xxaryx3fc8yc5y3fcxycyxwzyx3qnydz9xveyyd6pg56r2wpjxscnxd2p8qcrzdzpx9prxd29xapnjdjxx4ryys3t74l // url:http://192.168.0.172:27543/lnauth/signin?tag=login&k1=5030009D37F7FCE891BE810C8D4A24E32B7AE45824135A8014A1B35E7C96F5FB // Response from wallet: // key: 038b02325d76b1e096071a6fdaf6c695800ad79b7245f7e6b0d5ccd505a2d4c10c // k1:5030009D37F7FCE891BE810C8D4A24E32B7AE45824135A8014A1B35E7C96F5FB // sig:3044022006a071c4997c313e3c0bcb13daed2dddf1ebe5d899405125e674423c12480150022006664645062a1f2b5bca4d35c76ef72b0cdd46e1ba0cab89bd085c18a2922f6d // Works //var publicKey = CryptoService.HexStringToByteArray("038b02325d76b1e096071a6fdaf6c695800ad79b7245f7e6b0d5ccd505a2d4c10c"); //var hash = CryptoService.HexStringToByteArray("5030009D37F7FCE891BE810C8D4A24E32B7AE45824135A8014A1B35E7C96F5FB"); //var signature = CryptoService.HexStringToByteArray("3044022006a071c4997c313e3c0bcb13daed2dddf1ebe5d899405125e674423c12480150022006664645062a1f2b5bca4d35c76ef72b0cdd46e1ba0cab89bd085c18a2922f6d"); // Fails - should work var publicKey = CryptoService.HexStringToByteArray("038b02325d76b1e096071a6fdaf6c695800ad79b7245f7e6b0d5ccd505a2d4c10c"); var hash = CryptoService.HexStringToByteArray("6A6EAB458D4DE401A78F109911274A1A21A9A512BA861933D6937E0EA95B016A"); var signature = CryptoService.HexStringToByteArray("3045022100da228f52aaeef71ba92b0241832e5e19f23f74bc663057017c35ce81c51efe5702206a0c1c1f56af604ada61557f827ca0778546c25d6729edbd43a8853f9a96435f"); var secp256k1 = ECCurve.CreateFromValue("1.3.132.0.10"); // signature is DER encoded -> convert to 64 byte array var p1len = signature[3]; var sigp1 = signature.Skip(4).SkipWhile(b => b == 0).Take(32).ToArray(); // Remove any 0 padded bytes var p2len = signature.Skip(4 + p1len + 1).Take(1).ToArray()[0]; var sigp2 = signature.Skip(4 + p1len + 2).SkipWhile(b => b == 0).Take(32).ToArray(); // Remove any 0 padded bytes var sig = sigp1.Concat(sigp2).ToArray(); // decompress the public key //var i = publicKey[0]; //var x = new BigInteger(publicKey.Skip(1).ToArray()); //var p = new BigInteger(CryptoService.HexStringToByteArray("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F")); //var a = new BigInteger(0); //var b = new BigInteger(7); //var y_sq = (x * x * x + a * x + b) % p; //var y = BigInteger.ModPow(y_sq, (p + 1) / 4, p); //if ((i == 02 && y % 2 != 0) || (i == 03 && y % 2 == 0)) //{ // y = (p - y % p); //} //var pkX1 = x.ToByteArray(); //var pkY1 = y.ToByteArray(); PubKey pk = new PubKey(publicKey); var pkBytes = pk.Decompress().ToBytes(); var pkX = pkBytes.Skip(1).Take(32).ToArray(); var pkY = pkBytes.Skip(33).ToArray(); var dsa = ECDsa.Create(new ECParameters { Curve = secp256k1, //D optional: (private key bytes) we don't have Q = new ECPoint { // gets the {x,y} from the uncompressed public key X = pkX, Y = pkY, } }); var isValid = dsa.VerifyHash(hash, sig); Assert.IsTrue(isValid); //CngKey.Import(publicKey, CngKeyBlobFormat.EccPublicBlob) //ECDsaCng ecsdKey = new ECDsaCng() }