public byte[] SignCompact(uint256 hash) { var sig = _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, 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; 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 override bool Equals(object obj) { PubKey item = obj as PubKey; if (item == null) { return(false); } return(ToHex().Equals(item.ToHex())); }
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 }