[ 21-DOT-DEV/swift-secp256k1 ] test: add corruption-seam infrastructure for verify-after-sign self-checks (#1238)
Adds the package-internal test seam signing methods will consult between producing signature bytes and self-verifying them (spec 004, Group E). The seam is a @TaskLocal (@Sendable (UnsafeMutableRawBufferPointer) -> Void)? bound only from @testable test code via P256K.$signatureCorruptor.withValue(...) — task-local state needs no lock, cannot leak into parallel tests, and restores itself at scope exit, the same install/run/restore discipline upstream libsecp256k1's counting-callback test macros apply to their global hooks (a hook left installed once masked real test failures, bitcoin-core/secp256k1#1167). The corruptor mutates the produced object through a raw mutable view so one shape covers serialized arrays (withUnsafeMutableBytes) and opaque libsecp256k1 structs (withUnsafeMutableBytes(of:)) without copying or inventing serialization formats — in-place byte mutation is also the faithful fault model for the glitch attacks verify-after-sign exists to catch.
The seam lands inert — no signing method consults it until T009–T012 — but the machinery ships proven: direct tests cover the unbound no-op, bound mutation, nested shadow/restore, and detached-task isolation, and a runCorruptionCase(_:) dispatcher invoked by literal enum argument from each capture-free #expect(processExitsWith:) body (the TestHelperProcess env-var discriminator translated to the only channel exit-test bodies allow) proves the bind → consult → mutate → invariantFailure → stderr-marker pipeline end to end via the .canned case each future path arm reuses.
Co-authored-by: csjones [email protected]
https://github.com/21-DOT-DEV/swift-secp256k1/commit/40c6b46db4bbe7e3834379c12c0d747865423575