public static BigInteger[] GenerateSignature(BigInteger privateKey, byte[] hash) { BigInteger?k = null; for (int i = 0; i < 100; i++) { byte[] kBytes = new byte[33]; rngCsp.GetBytes(kBytes); kBytes[32] = 0; k = new BigInteger(kBytes); var z = Bytes32.ConvetToBigInteger(hash); if (k.Value.IsZero || k >= Secp256k1.q) { continue; } var r = Calculate.getPublicByPrivate(k.Value)[0] % Secp256k1.q; if (r.IsZero) { continue; } var ss = (z + r * privateKey); var s = (ss * (k.Value.ModInverse(Secp256k1.q))) % Secp256k1.q; if (s.IsZero) { continue; } return(new BigInteger[] { r, s }); } throw new Exception("Unable to generate signature"); }
public static string GetAddressOfUncompressed(BigInteger[] publicKey) { var publicKeyArray1 = HexToByteArray.BigIntegerTo32ByteArray(publicKey[0]); HexToByteArray.ChangeDirection(ref publicKeyArray1); var publicKeyArray2 = HexToByteArray.BigIntegerTo32ByteArray(publicKey[1]); HexToByteArray.ChangeDirection(ref publicKeyArray2); // var array = HexToByteArray.BigIntegerTo32ByteArray(privateKey); var resultAdd = Calculate.BiteSplitJoint(new byte[] { 0x04 }, publicKeyArray1); resultAdd = Calculate.BiteSplitJoint(resultAdd, publicKeyArray2); Console.WriteLine($"非压缩公钥为{ Hex.BytesToHex(resultAdd)}"); var step3 = ripemd160.ComputeHash(sha256.ComputeHash(resultAdd)); var step4 = Calculate.BiteSplitJoint(new byte[] { 0x00 }, step3); var step5 = sha256.ComputeHash(sha256.ComputeHash(step4)); var step6 = Calculate.BiteSplitJoint(step4, new byte[] { step5[0], step5[1], step5[2], step5[3] }); return(Calculate.Encode(step6)); //SHA256 sha256 = new SHA256Managed(); //byte[] hash1 = sha256.ComputeHash(resultAdd); //var pubKeyHash = Hash160.Hash(publicKey.EncodePoint(hash1)); //byte[] hash2 = sha256.ComputeHash(hash1); //var result = new byte[CheckSumSizeInBytes]; //Buffer.BlockCopy(hash2, 0, result, 0, result.Length); //byte[] chechHash = Calculate.GetCheckSum(resultAdd); }
public static bool Check(string inputSting, out System.Numerics.BigInteger privateBigInteger) { var privateByte = Base58.Decode(inputSting); // var privateByte = Hex.HexToBytes32(inputSting); // var privateKey1 = Calculate.Encode(privateByte); if (privateByte.Length == 38) { if (privateByte[0] == 0x80 && privateByte[33] == 0x01) { var m = new List <byte>(); for (var i = 0; i < 34; i++) { m.Add(privateByte[i]); } byte[] chechHash = Calculate.GetCheckSum(m.ToArray()); if ( chechHash[0] == privateByte[34] && chechHash[1] == privateByte[35] && chechHash[2] == privateByte[36] && chechHash[3] == privateByte[37]) { privateBigInteger = 0; for (var i = 1; i < 33; i++) { privateBigInteger = privateBigInteger * 256; privateBigInteger = privateBigInteger + Convert.ToInt32(privateByte[i]); } privateBigInteger = privateBigInteger % Secp256k1.q; return(true); } else { privateBigInteger = -1; return(false); } } else { privateBigInteger = -1; return(false); } } else if (privateByte.Length == 37) { if (privateByte[0] == 0x80) { var m = new List <byte>(); for (var i = 0; i < 33; i++) { m.Add(privateByte[i]); } byte[] chechHash = Calculate.GetCheckSum(m.ToArray()); if ( chechHash[0] == privateByte[33] && chechHash[1] == privateByte[34] && chechHash[2] == privateByte[35] && chechHash[3] == privateByte[36]) { privateBigInteger = 0; for (var i = 1; i < 33; i++) { privateBigInteger = privateBigInteger * 256; privateBigInteger = privateBigInteger + Convert.ToInt32(privateByte[i]); } privateBigInteger = privateBigInteger % Secp256k1.q; return(true); } else { privateBigInteger = -1; return(false); } } else { privateBigInteger = -1; return(false); } } else { privateBigInteger = -1; return(false); } }
public static string SignMessage() { Console.WriteLine("请输入要签名的信息(utf-8)"); var msg = Console.ReadLine(); Console.WriteLine("请输入要私钥"); // output($"拖入您的Base58编码的37位或38位的私钥的路径,用此私钥进行验证.即校验.txt"); var privateKey = Console.ReadLine(); System.Numerics.BigInteger privateBigInteger; if (PrivateKeyF.Check(privateKey, out privateBigInteger)) { } else { Console.WriteLine($"请输入正确的私钥!!!"); return(""); } bool compressed; string address; if (privateKey.Length == 51) { compressed = false; address = PublicKeyF.GetAddressOfUncompressed(Calculate.getPublicByPrivate(privateBigInteger)); } else if (privateKey.Length == 52) { compressed = true; address = PublicKeyF.GetAddressOfcompressed(Calculate.getPublicByPrivate(privateBigInteger)); } else { throw new Exception(""); } var msgHash = msg_digest(msg); var signal = PrivateKeyF.Sign(privateBigInteger, msgHash); var r = signal[0]; var rByte = HexToByteArray.BigIntegerTo32ByteArray(r); HexToByteArray.ChangeDirection(ref rByte); var s = signal[1]; var sByte = HexToByteArray.BigIntegerTo32ByteArray(s); HexToByteArray.ChangeDirection(ref sByte); // Console.WriteLine($"{Convert.ToBase64String(rByte)}{Convert.ToBase64String(sByte)}"); var sequence = new byte[] { 0 }; //[0]; sequence = sequence.Concat(rByte).ToArray(); sequence = sequence.Concat(sByte).ToArray(); for (var i = 0; i < 4; i++) { int nV = 27 + i; if (compressed) { nV += 4; } sequence[0] = Convert.ToByte(nV); var sig = Convert.ToBase64String(sequence); Console.WriteLine(sig); var calAddredd = verify_message(sig, msg, compressed ? 1 : 0); // return sig; if (calAddredd == address) { return(sig); } //if (verify_message(sig, msg, compressed ? 1 : 0) == address) // return sig; } return(""); }
public static string verify_message(string signature, string message, int addrtype) { byte[] sig; //try { sig = Convert.FromBase64String(signature); } //catch (err) //{ // return false; //} if (sig.Length != 65) { return("Error e"); } // extract r,s from signature var r = Bytes32.ConvetToBigInteger(sig.Skip(1).Take(32).ToArray()); var s = Bytes32.ConvetToBigInteger(sig.Skip(33).Take(32).ToArray()); // var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 33 + 32)); // get recid // var compressed = false; var nV = Convert.ToInt32(sig[0]); if (nV < 27 || nV >= 35) { return("Error e"); } if (nV >= 31) { // compressed = true; nV -= 4; } var recid = new BigInteger(nV - 27); { //var z = Bytes32.ConvetToBigInteger(hash); ; //var w = s.ModInverse(Secp256k1.q); //var u1 = (z * w) % Secp256k1.q; //var u2 = (r * w) % Secp256k1.q; //bool isZero; //var pt = Calculate.pointPlus(Calculate.getPublicByPrivate(u1), Calculate.getMulValue(u2, publicKey), out isZero);// (publicKey.Multiply(u2)); //if (pt == null) //{ // return false; //} //else //{ // var pmod = pt[0] % Secp256k1.q; // return pmod == r; //} } //var ecparams = getSECCurveByName("secp256k1"); //var curve = ecparams.getCurve(); //var a = curve.getA().toBigInteger(); //var b = curve.getB().toBigInteger(); //var p = curve.getQ(); //var G = ecparams.getG(); //var order = ecparams.getN(); //var x = r.add(order.multiply(recid.divide(BigInteger.valueOf(2)))); var x = recid / 2 * Secp256k1.q + r; //Calculate.getMulValue(,recid / 2); // var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p); var alpha = (x * x * x + Secp256k1.a * x + Secp256k1.b) % Secp256k1.p; //var beta = alpha.modPow(p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)), p); var beta = BigInteger.ModPow(alpha, (Secp256k1.p + 1) / 4, Secp256k1.p);//Calculate.Pow((Secp256k1.p + 1) / 4, alpha); var y = (beta - recid).IsEven ? beta : (Secp256k1.p - beta); //var y = beta.subtract(recid).isEven() ? beta : p.subtract(beta); // var R = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); // var e = BigInteger.fromByteArrayUnsigned(msg_digest(message)); var e = Bytes32.ConvetToBigInteger(msg_digest(message)); // var minus_e = BigInteger.Negate(e)+ % Secp256k1.q; var minus_e = ((Secp256k1.q - e) % Secp256k1.q + Secp256k1.q) % Secp256k1.q; var inv_r = Inverse.ex_gcd(r, Secp256k1.q);////BigInteger.mo r.modInverse(order); //var Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r); bool isZero; var Q__ = Calculate.pointPlus(Calculate.getMulValue(s, new BigInteger[] { x, y }), Calculate.getPublicByPrivate(minus_e), out isZero); if (isZero) { return("Error e"); } else { var Q = Calculate.getMulValue(inv_r, Q__); var public_key = PublicKeyF.GetAddressOfcompressed(Q); if (addrtype == 0) { return(PublicKeyF.GetAddressOfUncompressed(Q)); } else if (addrtype == 1) { return(PublicKeyF.GetAddressOfcompressed(Q)); } else { return("Error e"); } } }
public static bool checkSign(string signature, string message, string address) { byte[] sig; { sig = Convert.FromBase64String(signature); } if (sig.Length != 65) { return(false); } // extract r,s from signature var r = Bytes32.ConvetToBigInteger(sig.Skip(1).Take(32).ToArray()); var s = Bytes32.ConvetToBigInteger(sig.Skip(33).Take(32).ToArray()); // var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 33 + 32)); // get recid var compressed = false; var nV = Convert.ToInt32(sig[0]); if (nV < 27 || nV >= 35) { return(false); } if (nV >= 31) { compressed = true; nV -= 4; } var recid = new BigInteger(nV - 27); //var ecparams = getSECCurveByName("secp256k1"); //var curve = ecparams.getCurve(); //var a = curve.getA().toBigInteger(); //var b = curve.getB().toBigInteger(); //var p = curve.getQ(); //var G = ecparams.getG(); //var order = ecparams.getN(); //var x = r.add(order.multiply(recid.divide(BigInteger.valueOf(2)))); var x = recid / 2 * Secp256k1.q + r; //Calculate.getMulValue(,recid / 2); // var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p); var alpha = (x * x * x + Secp256k1.a * x + Secp256k1.b) % Secp256k1.p; //var beta = alpha.modPow(p.add(BigInteger.ONE).divide(BigInteger.valueOf(4)), p); var beta = BigInteger.ModPow(alpha, (Secp256k1.p + 1) / 4, Secp256k1.p);//Calculate.Pow((Secp256k1.p + 1) / 4, alpha); var y = (beta - recid).IsEven ? beta : (Secp256k1.p - beta); //var y = beta.subtract(recid).isEven() ? beta : p.subtract(beta); // var R = new ECPointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y)); // var e = BigInteger.fromByteArrayUnsigned(msg_digest(message)); var e = Bytes32.ConvetToBigInteger(msg_digest(message)); // var minus_e = BigInteger.Negate(e)+ % Secp256k1.q; var minus_e = ((Secp256k1.q - e) % Secp256k1.q + Secp256k1.q) % Secp256k1.q; var inv_r = Inverse.ex_gcd(r, Secp256k1.q);////BigInteger.mo r.modInverse(order); //var Q = (R.multiply(s).add(G.multiply(minus_e))).multiply(inv_r); bool isZero; var Q__ = Calculate.pointPlus(Calculate.getMulValue(s, new BigInteger[] { x, y }), Calculate.getPublicByPrivate(minus_e), out isZero); if (isZero) { return(false); } else { var Q = Calculate.getMulValue(inv_r, Q__); // var public_key = PublicKeyF.GetAddressOfcompressed(Q); if (compressed) { var compressedAdress = PublicKeyF.GetAddressOfcompressed(Q); Console.WriteLine($"compressed Adress:{compressedAdress}"); return(compressedAdress == address); } else { var unCompressedAdress = PublicKeyF.GetAddressOfUncompressed(Q); Console.WriteLine($"uncompressed adress:{unCompressedAdress}"); return(unCompressedAdress == address); } } }