public string SignData(byte[] data) { byte[] hash; using (SHA256 sha = SHA256.Create()) { hash = sha.ComputeHash(data, 0, data.Length); } Signature signature = SignHash(hash); byte[] checksum; string prefix; data = signature.GetBytes(); switch (KeyType) { case KeyTypes.K1: checksum = RIPEMD160.ComputeHash(data.Concat(K1Salt)).TakePart(0, 4); prefix = Signature.K1Prefix; break; case KeyTypes.R1: checksum = RIPEMD160.ComputeHash(data.Concat(R1Salt)).TakePart(0, 4); prefix = Signature.R1Prefix; break; default: throw new InvalidKeyException(Resources.WrongKeyType); } string result = prefix + data.Concat(checksum).ToBase58(); return(result); }
public static byte[] ComputeK1Checksum(byte[] buffer, int offset, int length) { byte[] hash = RIPEMD160.ComputeHash(buffer, offset, length); byte[] result = new byte[ChecksumLength]; Array.Copy(hash, 0, result, 0, ChecksumLength); return(result); }
public static byte[] ComputeR1Checksum(byte[] buffer, int offset, int length) { byte[] buf = new byte[length + R1Salt.Length]; Array.Copy(buffer, offset, buf, 0, length); Array.Copy(R1Salt, 0, buf, buf.Length - R1Salt.Length, R1Salt.Length); byte[] hash = RIPEMD160.ComputeHash(buf); byte[] result = new byte[ChecksumLength]; Array.Copy(hash, result, ChecksumLength); return(result); }
public bool VerifySignature(byte[] data, string signature) { if (!signature.StartsWith(Signature.K1Prefix) && !signature.StartsWith(Signature.R1Prefix)) { return(false); } byte[] buf = Base58.Decode(signature.Substring(Signature.PrefixLength)); if (buf.Length != Signature.Length + ChecksumLength) { return(false); } byte[] signatureBuf = new byte[buf.Length - ChecksumLength]; Array.Copy(buf, 0, signatureBuf, 0, Signature.Length); byte[] checksum; if (signature.StartsWith(Signature.R1Prefix)) { checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(R1Salt)).TakePart(0, 4); } else { checksum = RIPEMD160.ComputeHash(signatureBuf.Concat(K1Salt)).TakePart(0, 4); } if (!CheckChecksum(buf, checksum)) { return(false); } byte[] hash; using (SHA256 sha = SHA256.Create()) { hash = sha.ComputeHash(data, 0, data.Length); } byte recoveryId = (byte)(signatureBuf[0] - 31); BigInteger r = signatureBuf.ToInt256(1); BigInteger s = signatureBuf.ToInt256(33); var q = RecoverPublicKey(hash, r, s, recoveryId, Curve); if (q.X.Value != Q.X.Value && q.Y.Value != Q.Y.Value) { return(false); } if (r.Sign < 1 || s.Sign < 1 || r.CompareTo(Curve.N) >= 0 || s.CompareTo(Curve.N) >= 0) { return(false); } BigInteger e = hash.ToInt256(); BigInteger c = s.ModInverse(Curve.N); BigInteger u1 = (e * c).Mod(Curve.N); BigInteger u2 = (r * c).Mod(Curve.N); Point R = Curve.G.MultiplyTwo(u1, q, u2); BigInteger v = R.X.Value.Mod(Curve.N); return(v.Equals(r)); }