Repository navigation
Conversation
Nodes sign the exact bytes they publish (domain || subject || body) with their identity key and send Mpc-Node-Id and Mpc-Result-Sig headers. The message body is unchanged, so existing clients keep working. - pkg/resultauth: sign/verify, key lookup, t+1 aggregator, signing queue - result_signing.per_node_results (default false) keeps one copy per node - client: ResultVerifyMode off|log|enforce, NodePublicKeys, RequiredNodeSignatures(+ per-wallet override); copies are acked only after their result is delivered - mpcium-cli export-node-keys builds node_public_keys.json from identity files - examples, e2e (enforce, t+1), setup script and deployment guides updated
- Build the signing payload with append instead of a summed capacity (CodeQL) - Write node_public_keys.json with 0600 (gosec) - Split Aggregator.Add into roundFor and record to cut its complexity (Sonar)
|
Collaborator
Author
|
Apex side: fystack/apex#807 |
Collaborator
Author
|
Superseded by #175, which targets master directly and keeps the t+1 quorum for keygen only. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Nodes sign every keygen, signing and reshare result they publish. Clients verify those signatures against node public keys pinned in their own config, and can require t+1 nodes to agree before acting on a result. This replaces the approach in #171: the signature now travels in NATS headers instead of the body, so the message body is unchanged and clients don't have to rebuild the signed bytes from a struct.
How it works
"mpcium-result-v1" || subject || bodywith its identity key and setsMpc-Node-IdandMpc-Result-Sig. Including the subject stops a result being replayed on another topic. Signing happens in one queue wrapper (resultauth.NewSigningQueue), so no publish site changed.result_signing.per_node_results(defaultfalse) adds the node ID to the JetStream idempotency key so every node's copy is kept. Withfalse, JetStream keeps one copy, the same as today.pkg/client): new optionsResultVerifyMode(off|log|enforce, default off),NodePublicKeys,RequiredNodeSignaturesandRequiredNodeSignaturesForWallet. Inenforce, unsigned or forged results are terminated.mpcium-cli export-node-keysbuildsnode_public_keys.jsonfrom identity files. Any node's identity directory works, because every node holds all peers'*_identity.json.setup_identities.shruns it; the examples and the ECS, k8s and systemd guides use it.Compatibility
No config change is needed to upgrade. Nodes add headers that old clients ignore, the body is unchanged, and every new option defaults to the old behaviour. Turn on
per_node_resultson all nodes before any client setsRequiredNodeSignatures> 1. With every node off, a client that requires more than 1 receives a single copy and every result times out.Testing
-race) forpkg/resultauthandpkg/client: tampered body, wrong subject, unknown node, forged first copy, ack after delivery, late copies, retry after error, replay, per-wallet threshold, and shared test vectors.enforce, t+1 = 2 andper_node_results: true.enforce(keygen and Stellar withdrawals through the UI, plus forged and unsigned results) passed.Usage note
With
RequiredNodeSignatures> 1, every copy of a result must reach one aggregator. Within a process, all subscriptions share one. Across processes, either give each process its ownClientIDor consume results from a single process. Apex does the latter by consuming MPC results on its HA leader only.Replay protection
Results are bound to their subject and body, so a result can't be moved to another topic or edited, and late copies of a finished operation are dropped. To also reject an old, validly signed result re-sent for the same operation, a client should use a
TxIDthat is unique per signing attempt and accept results only for the current attempt. Nodes treatTxIDas opaque and sign the body that contains it, so a result can't be relabelled. Apex does this by sending<txID>#<attemptID>.