public PubKey Compress() { if (IsCompressed) { return(this); } return(ECKey.GetPubKey(true)); }
public PubKey Compress() { if (IsCompressed) { return(this); } #if HAS_SPAN return(new PubKey(this._ECKey, true)); #else return(ECKey.GetPubKey(true)); #endif }
public static PubKey RecoverCompact(uint256 hash, CompactSignature compactSignature) { if (compactSignature is null) { throw new ArgumentNullException(nameof(compactSignature)); } if (hash is null) { throw new ArgumentNullException(nameof(hash)); } #if HAS_SPAN Span <byte> msg = stackalloc byte[32]; hash.ToBytes(msg); if (Secp256k1.SecpRecoverableECDSASignature.TryCreateFromCompact(compactSignature.Signature, compactSignature.RecoveryId, out var sig) && Secp256k1.ECPubKey.TryRecover(NBitcoinContext.Instance, sig, msg, out var pubkey)) { return(new PubKey(pubkey, true)); } throw new InvalidOperationException("Impossible to recover the public key"); #else BigInteger r = new BigInteger(1, compactSignature.Signature.SafeSubarray(0, 32)); BigInteger s = new BigInteger(1, compactSignature.Signature.SafeSubarray(32, 32)); #pragma warning disable 618 var sig = new ECDSASignature(r, s); #pragma warning restore 618 ECKey key = ECKey.RecoverFromSignature(compactSignature.RecoveryId, sig, hash); return(key.GetPubKey(true)); #endif }
public byte[] SignCompact(uint256 hash) { ECDSASignature sig = this._ECKey.Sign(hash); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash, this.IsCompressed); if (k != null && k.GetPubKey(this.IsCompressed).ToHex() == this.PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } int headerByte = recId + 27 + (this.IsCompressed ? 4 : 0); var sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S sigData[0] = (byte)headerByte; Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32); return(sigData); }
public static byte[] RecoverPublickey(byte[] msgHash, byte[] signature) { if (signature.Length != 65) { throw new ArgumentException("signature invalid"); } byte[] r = new byte[32]; byte[] s = new byte[32]; byte[] v = new byte[1]; try { Array.Copy(signature, 0, r, 0, 32); Array.Copy(signature, 32, s, 0, 32); Array.Copy(signature, 64, v, 0, 1); int V = Convert.ToInt32(v[0]); if (V != 0 && V != 1) { throw new ArgumentException("invalid signature recovery"); } ECDSASignature sign = new ECDSASignature(new DerInteger(r).PositiveValue, new DerInteger(s).PositiveValue); ECKey ecKey = ECKey.RecoverFromSignature(V, sign, msgHash, false); return(ecKey.GetPubKey(false)); } catch { throw new ArgumentException("signature invalid"); } }
public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded) { if (signatureEncoded.Length < 65) { throw new ArgumentException("Signature truncated, expected 65 bytes and got " + signatureEncoded.Length); } int header = signatureEncoded[0]; // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y if (header < 27 || header > 34) { throw new ArgumentException("Header byte out of range: " + header); } ECDSASignature sig = DecodeSig(signatureEncoded); bool compressed = false; if (header >= 31) { compressed = true; header -= 4; } int recId = header - 27; ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed); return(key.GetPubKey(compressed)); }
public PubKey Decompress() { if (!IsCompressed) { return(this); } return(ECKey.GetPubKey(false)); }
public static byte[] GetPubKeyNoPrefix(this ECKey key) { var pubKey = key.GetPubKey(false); var arr = new byte[pubKey.Length - 1]; //remove the prefix Array.Copy(pubKey, 1, arr, 0, arr.Length); return(arr); }
public byte[] GeneratePublicKey( byte[] privateKey) { var ecKey = new ECKey(privateKey, true); return(ecKey .GetPubKey(false) .Skip(1) // Skipping prefix .ToArray()); }
public static byte[] DerivePublicKey(byte[] privatekey) { if (IsValidPrivateKey(privatekey)) { ECKey key = new ECKey(privatekey, true); return(key.GetPubKey(false)); } throw new ArgumentException("invalid private key"); }
//Note: Y coordinates can only be forced, so it is assumed 0 and 1 will be the recId (even if implementation allows for 2 and 3) internal int CalculateRecId(ECDSASignature signature, byte[] hash) { var recId = -1; var thisKey = _ecKey.GetPubKey(false); // compressed for (var i = 0; i \ { var rec = ECKey.RecoverFromSignature(i, signature, hash, false); if (rec != null) { var k = rec.GetPubKey(false); if (k != null && k.SequenceEqual(thisKey)) { recId = i; break; } } } if (recId == -1) throw new Exception("Could not construct a recoverable key. This should never happen."); return recId; }
public void TestPublicKey() { var privateKey = "F43EBCC94E6C257EDBE559183D1A8778B2D5A08040902C0F0A77A3343A1D0EA5"; var prvKey = privateKey.HexToByteArray(); var ecKey = new ECKey(prvKey, true); var publicKey0 = ecKey.GetPubKey(); var publicKey1 = private2PublicDemo(prvKey); Assert.Equal(publicKey0, publicKey1); }
public static PubKey RecoverCompact(uint256 hash, byte[] signatureEncoded) { #if HAS_SPAN if (signatureEncoded.Length != 65) { throw new ArgumentException(paramName: nameof(signatureEncoded), message: "Signature truncated, expected 65"); } Span <byte> msg = stackalloc byte[32]; hash.ToBytes(msg); var s = signatureEncoded.AsSpan(); int recid = (s[0] - 27) & 3; bool fComp = ((s[0] - 27) & 4) != 0; Secp256k1.ECPubKey pubkey; Secp256k1.SecpRecoverableECDSASignature sig; if (Secp256k1.SecpRecoverableECDSASignature.TryCreateFromCompact(s.Slice(1), recid, out sig) && sig is Secp256k1.SecpRecoverableECDSASignature && Secp256k1.ECPubKey.TryRecover(NBitcoinContext.Instance, sig, msg, out pubkey) && pubkey is Secp256k1.ECPubKey) { return(new PubKey(pubkey, fComp)); } throw new InvalidOperationException("Impossible to recover the public key"); #else if (signatureEncoded.Length < 65) { throw new ArgumentException("Signature truncated, expected 65 bytes and got " + signatureEncoded.Length); } int header = signatureEncoded[0]; // The header byte: 0x1B = first key with even y, 0x1C = first key with odd y, // 0x1D = second key with even y, 0x1E = second key with odd y if (header < 27 || header > 34) { throw new ArgumentException("Header byte out of range: " + header); } var sig = DecodeSig(signatureEncoded); bool compressed = false; if (header >= 31) { compressed = true; header -= 4; } int recId = header - 27; ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed); return(key.GetPubKey(compressed)); #endif }
//Note: Y coordinates can only be forced, so it is assumed 0 and 1 will be the recId (even if implementation allows for 2 and 3) internal int CalculateRecId(ECDSASignature signature, byte[] hash) { //var recId = -1; var thisKey = _ecKey.GetPubKey(false); // compressed return(CalculateRecId(signature, hash, thisKey)); //for (var i = 0; i < 4; i++) //{ // var rec = ECKey.RecoverFromSignature(i, signature, hash, false); // if (rec != null) // { // var k = rec.GetPubKey(false); // if (k != null && k.SequenceEqual(thisKey)) // { // recId = i; // break; // } // } //} //if (recId == -1) // throw new Exception("Could not construct a recoverable key. This should never happen."); //return recId; }
public byte[] SignCompact(uint256 hash, bool forceLowR) { if (hash is null) { throw new ArgumentNullException(nameof(hash)); } AssertNotDisposed(); #if HAS_SPAN Span <byte> vchSig = stackalloc byte[65]; int rec = -1; var sig = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out rec), rec); sig.WriteToSpanCompact(vchSig.Slice(1), out int recid); vchSig[0] = (byte)(27 + rec + (IsCompressed ? 4 : 0)); return(vchSig.ToArray()); #else var sig = _ECKey.Sign(hash, forceLowR); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash, IsCompressed); if (k != null && k.GetPubKey(IsCompressed).ToHex() == PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } int headerByte = recId + 27 + (IsCompressed ? 4 : 0); byte[] sigData = new byte[65]; // 1 header + 32 bytes for R + 32 bytes for S sigData[0] = (byte)headerByte; #pragma warning disable 618 Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 1, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 33, 32); #pragma warning restore 618 return(sigData); #endif }
public CompactSignature SignCompact(uint256 hash, bool forceLowR) { if (hash is null) { throw new ArgumentNullException(nameof(hash)); } if (!IsCompressed) { throw new InvalidOperationException("This operation is only supported on compressed pubkey"); } AssertNotDisposed(); #if HAS_SPAN byte[] sigBytes = new byte[64]; var sig = new Secp256k1.SecpRecoverableECDSASignature(_ECKey.Sign(hash, forceLowR, out var rec), rec); sig.WriteToSpanCompact(sigBytes, out _); return(new CompactSignature(rec, sigBytes)); #else var sig = _ECKey.Sign(hash, forceLowR); // Now we have to work backwards to figure out the recId needed to recover the signature. int recId = -1; for (int i = 0; i < 4; i++) { ECKey k = ECKey.RecoverFromSignature(i, sig, hash); if (k != null && k.GetPubKey(true).ToHex() == PubKey.ToHex()) { recId = i; break; } } if (recId == -1) { throw new InvalidOperationException("Could not construct a recoverable key. This should never happen."); } #pragma warning disable 618 byte[] sigData = new byte[64]; // 1 header + 32 bytes for R + 32 bytes for S Array.Copy(Utils.BigIntegerToBytes(sig.R, 32), 0, sigData, 0, 32); Array.Copy(Utils.BigIntegerToBytes(sig.S, 32), 0, sigData, 32, 32); #pragma warning restore 618 return(new CompactSignature(recId, sigData)); #endif }
public static int CalculateRecId(this ECKey key, ECDSASignature signature, byte[] hash) { var recId = -1; var thisKey = key.GetPubKey(false); // compressed for (var i = 0; i < 4; i++) { var k = ECKey.RecoverFromSignature(i, signature, hash, false).GetPubKey(false); if (k != null && Enumerable.SequenceEqual(k, thisKey)) { recId = i; break; } } if (recId == -1) { throw new Exception("Could not construct a recoverable key. This should never happen."); } return(recId); }
public byte[] GetPubKey() { return(_ecKey.GetPubKey()); }
//Note: Y coordinates can only be forced, so it is assumed 0 and 1 will be the recId (even if implementation allows for 2 and 3) internal int CalculateRecId(ECDSASignature signature, byte[] hash) { var thisKey = _ecKey.GetPubKey(false); // compressed return(CalculateRecId(signature, hash, thisKey)); }
public static PubKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 hash, bool compressed) { ECKey key = ECKey.RecoverFromSignature(recId, sig, hash, compressed); return(key?.GetPubKey(compressed)); }
private static int CalculateRecId(ECKey eckey, ECDSASignature signature, byte[] hash) { var thisKey = eckey.GetPubKey(false); return(CalculateRecId(signature, hash, thisKey)); }