Skip to content

refactor(sigall): recompute signing digests from package contents - #947

Merged
robwoodgate merged 2 commits into
mainfrom
refactor/sigall-signing-package
Aug 11, 2026
Merged

refactor(sigall): recompute signing digests from package contents#947
robwoodgate merged 2 commits into
mainfrom
refactor/sigall-signing-package

Conversation

@robwoodgate

@robwoodgate robwoodgate commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Description

The SigAll signing package carried precomputed digests that signPackage signed directly. Recomputing them from the package's own inputs, outputs and quote is simpler and more robust: a signer always signs exactly what the package describes, and the transport no longer duplicates data it already contains. With that, the digests field and the validateDigest option are redundant and removed.

The sigallA prefix is kept: a package from an older build still parses, with its digests field ignored and stripped, and the fields that matter (inputs, outputs, quote, witness) are unchanged.

Changes

  • signPackage recomputes digests from package contents and emits one signature per supported format.
  • SigAllSigningPackage drops digests; deserializePackage drops the validateDigest option and rebuilds the package from validated fields only. New guards: melt packages require a non-empty quote (it is part of the signed transcript), and witness.signatures must be a string array.
  • Digest names are version-anchored: SigAllDigests is now { v0 }, leaving room for the length-framed v1 format proposed in NUT-11: length-frame the SIG_ALL message aggregation nuts#404.
  • The deprecated pre-v0 message builder is removed; the wallet SIG_ALL path and computeDigests now produce the v0 format only. Pre-v0 was only ever accepted by Nutshell <= 0.20.2 and CDK < 0.14.0.
  • buildP2PKSigAllMessage renamed buildP2PKSigAllMessageV0 (internal, not in the public rollup).

Reviewer Notes

  • Breaking for the experimental SigAll surface only: SigAllDigests shape, deserializePackage signature, no digests in emitted packages. Wallets on old mints that only accept the pre-v0 SIG_ALL format will no longer be able to spend SIG_ALL-locked proofs there.
  • Net deletion overall; SigAll.ts coverage 98.9% statements / 95.2% branches from its own suite.

@robwoodgate robwoodgate added the backport v4-dev Backport this PR to v4-dev label Aug 10, 2026
@github-project-automation github-project-automation Bot moved this to Backlog in cashu-ts Aug 10, 2026
@robwoodgate robwoodgate changed the title refactor(sigall)!: recompute signing digests from package contents refactor(sigall): recompute signing digests from package contents Aug 10, 2026
@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.75%. Comparing base (e9ba7b6) to head (40fa371).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #947      +/-   ##
==========================================
+ Coverage   95.70%   95.75%   +0.05%     
==========================================
  Files          55       55              
  Lines        5797     5778      -19     
  Branches     1467     1463       -4     
==========================================
- Hits         5548     5533      -15     
+ Misses        105      103       -2     
+ Partials      144      142       -2     
Flag Coverage Δ
integration 37.83% <5.88%> (-0.17%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

signPackage now derives its digests from the package's own inputs,
outputs and quote, so the digests field is redundant and has been
removed from the transport format; packages from older builds still
parse, with the field ignored. Digest names are version-anchored
(v0 = unframed concatenation); the deprecated pre-v0 message builder
is removed and signers emit one signature per supported format. Melt
packages must carry a quote and witness signatures are shape-checked
on deserialize.
KvngMikey added a commit to KvngMikey/nuts that referenced this pull request Aug 11, 2026
The digests object is computable from the rest of the package, so
carrying it added nothing a signer could not derive itself. Worse, a
signer that trusts a supplied digest signs a message it has never
checked against the transaction it is approving.

The legacy entry hashed the pre-amount-binding format (secret||C||B_),
which NUT-11 no longer specifies. Without amount binding a signature
commits to which blinded outputs exist but not to their values, letting
amounts be reordered across outputs while the signature and the mint's
balance check both still pass. Carrying that digest gave a superseded
format renewed standing.

The current entry hashed today's aggregation format, a label that goes
stale the moment the message format changes (see cashubtc#404). Dropping both
leaves the package independent of any aggregation scheme.

Adds a normative requirement that signers derive the message to sign
from the package contents themselves, and regenerates the sigallA
vector without digests.

Addresses review feedback from @robwoodgate. Serialized vector matches
the one pinned in cashubtc/cashu-ts#947.
@robwoodgate
robwoodgate merged commit 20a29e2 into main Aug 11, 2026
18 checks passed
@robwoodgate
robwoodgate deleted the refactor/sigall-signing-package branch August 11, 2026 20:49
@github-project-automation github-project-automation Bot moved this from Backlog to Done in cashu-ts Aug 11, 2026
@robwoodgate

Copy link
Copy Markdown
Collaborator Author

Successfully created backport PR for v4-dev:

@KvngMikey KvngMikey left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK !

KvngMikey added a commit to KvngMikey/nuts that referenced this pull request Aug 12, 2026
The digests object is computable from the rest of the package, so
carrying it added nothing a signer could not derive itself. Worse, a
signer that trusts a supplied digest signs a message it has never
checked against the transaction it is approving.

The legacy entry hashed the pre-amount-binding format (secret||C||B_),
which NUT-11 no longer specifies. Without amount binding a signature
commits to which blinded outputs exist but not to their values, letting
amounts be reordered across outputs while the signature and the mint's
balance check both still pass. Carrying that digest gave a superseded
format renewed standing.

The current entry hashed today's aggregation format, a label that goes
stale the moment the message format changes (see cashubtc#404). Dropping both
leaves the package independent of any aggregation scheme.

Adds a normative requirement that signers derive the message to sign
from the package contents themselves, and regenerates the sigallA
vector without digests.

Also clarifies the witness encoding. NUT-11 defines Proof.witness as a
serialized JSON string, but the package schema showed witness as a JSON
object without saying which representation applied. An implementer
could serialize it before putting it in the package, or pass the
package's object straight into Proof.witness; both parse as valid JSON
and fail only later. The object form is correct and is what the vector
already encodes, so this documents the field rather than changing it.
The accompanying note also states that inputs[].secret keeps the
representation it has in Proof.secret, since documenting only witness
invites the opposite mistake.

Addresses review feedback from @robwoodgate and Copilot. Serialized
vector matches the one pinned in cashubtc/cashu-ts#947.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport v4-dev Backport this PR to v4-dev

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants