示例#1
0
 public static bool TryCreateFromCompact(ReadOnlySpan <byte> in64, int recid, [MaybeNullWhen(false)] out SecpRecoverableECDSASignature sig)
 {
     sig = null;
     if (SecpECDSASignature.TryCreateFromCompact(in64, out var compact) && compact is SecpECDSASignature)
     {
         sig = new SecpRecoverableECDSASignature(compact, recid);
         return(true);
     }
     return(false);
 }
 public bool TrySignRecoverable(ReadOnlySpan <byte> msg32, INonceFunction?nonceFunction, out SecpRecoverableECDSASignature?recoverableSignature)
 {
     if (msg32.Length != 32)
     {
         throw new ArgumentException(paramName: nameof(msg32), message: "msg32 should be 32 bytes");
     }
     if (this.TrySignECDSA(msg32, nonceFunction, out int recid, out SecpECDSASignature? sig) && sig is SecpECDSASignature)
     {
         recoverableSignature = new SecpRecoverableECDSASignature(sig, recid);
         return(true);
     }
     recoverableSignature = null;
     return(false);
 }
示例#3
0
        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
        }