/// <inheritdoc/> public bool Verify(Signature sig, PublicKey pubKey, ReadOnlySpan<byte> sigBa) { byte[] spendScr, dataToSign; if (IsSegWit) { spendScr = scriptSer.ConvertWitness(ExecutingScript); dataToSign = Tx.SerializeForSigningSegWit(spendScr, TxInIndex, AmountBeingSpent, sig.SigHash); } else { spendScr = scriptSer.Convert(ExecutingScript, sigBa); dataToSign = Tx.SerializeForSigning(spendScr, TxInIndex, sig.SigHash); } return calc.Verify(dataToSign, sig, pubKey, ForceLowS); }
/// <inheritdoc/> public bool Verify(byte[][] sigs, byte[][] pubKeys, int m, out string error) { byte[] spendScr; if (IsSegWit) { spendScr = scriptSer.ConvertWitness(ExecutingScript); } else { spendScr = scriptSer.ConvertMulti(ExecutingScript, sigs); } int sigIndex = sigs.Length - 1; int pubIndex = pubKeys.Length - 1; while (m > 0 && sigIndex >= 0 && pubIndex >= 0 && m <= pubIndex + 1) { // Empty byte signature doesn't fail as being "invalid" signature with or without strict rules // but it _IS_ invalid and signature verification fails so there is no need to perform verification // and then fail, instead just skip it here. if (sigs[sigIndex].Length == 0) { sigIndex--; pubIndex--; continue; } Signature sig; if (IsStrictDerSig) { if (!Signature.TryReadStrict(sigs[sigIndex], out sig, out error)) { return false; } } else { if (!Signature.TryReadLoose(sigs[sigIndex], out sig, out _)) { sigIndex--; pubIndex--; continue; } } if (!PublicKey.TryRead(pubKeys[pubIndex--], out PublicKey pubK)) { continue; } byte[] dataToSign; if (IsSegWit) { dataToSign = Tx.SerializeForSigningSegWit(spendScr, TxInIndex, AmountBeingSpent, sig.SigHash); } else { dataToSign = Tx.SerializeForSigning(spendScr, TxInIndex, sig.SigHash); } if (calc.Verify(dataToSign, sig, pubK, ForceLowS)) { sigIndex--; m--; } } error = null; return m == 0; }