{
 "slug": "multi-party-computation-mpc-vs-seen-signed-receipts",
 "topic_id": "TOPIC-080",
 "cluster": "Digital Asset Custody",
 "tier": "Tier B",
 "title": "Splitting the key does not decide whether to sign",
 "summary": "Multi-party computation removes the single point of key compromise. It says nothing about whether the transaction being signed is the one anyone intended.",
 "lede": "MPC solves an important problem well: no single party ever holds a complete key. The question of what the assembled parties are signing is a different problem, and MPC answers it by assumption.",
 "date": "2024-07-31",
 "category": "Comparison",
 "author_id": "whit-calloway",
 "tags": [
  "MPC",
  "threshold signatures",
  "key management",
  "custody",
  "authorization",
  "comparison"
 ],
 "image_title": "Splitting Key Not Deciding",
 "schema": "Article",
 "key_takeaways": [
  "MPC addresses key custody: no complete key exists in one place, and compromise of one share is insufficient.",
  "The transaction to be signed is supplied by an initiating system, and MPC signs what it is given.",
  "The two are layered, not alternative: MPC below for key security, authorisation above for what gets signed."
 ],
 "body": [
  {
   "type": "h2",
   "text": "What MPC provides"
  },
  {
   "type": "diagram",
   "kind": "chain",
   "alt": "Two different questions",
   "caption": "MPC answers the first. Nothing in the stack answers the second.",
   "nodes": [
    {
     "label": "Who can produce a signature?",
     "sub": "MPC answers this",
     "note": "key custody",
     "good": true
    },
    {
     "label": "Should this be signed?",
     "sub": "policy engine guesses",
     "note": "from a payload",
     "bad": true
    },
    {
     "label": "Did a human see it?",
     "sub": "unanswered",
     "note": "the gap",
     "bad": true
    }
   ]
  },
  {
   "type": "p",
   "html": "A threshold signature scheme distributes key material so that a complete private key never exists in one location. Signing requires a threshold of parties to participate in a protocol, and no participant learns the others' shares."
  },
  {
   "type": "table",
   "head": [
    "Threat",
    "MPC"
   ],
   "rows": [
    [
     "Theft of a complete private key",
     "No such key exists"
    ],
    [
     "Compromise of one share holder",
     "Insufficient below threshold"
    ],
    [
     "Insider with access to one share",
     "Insufficient"
    ],
    [
     "Loss of one share",
     "Recoverable with the remaining threshold"
    ],
    [
     "<strong style=\"font-weight:600\">Signing an incorrect transaction</strong>",
     "<strong style=\"font-weight:600\">Not addressed</strong>"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The first four rows are real and substantial. The fifth is the subject of this piece."
  },
  {
   "type": "h2",
   "text": "Where the transaction comes from"
  },
  {
   "type": "p",
   "html": "An MPC signing ceremony begins with a message to be signed. That message is constructed and supplied by an initiating system — a treasury application, an orchestration service, a policy engine."
  },
  {
   "type": "code",
   "text": "# The initiating system decides what gets signed\n\ntx = build_withdrawal(destination, amount, asset)\n\n# MPC parties participate in signing THIS message.\n# Each party's role is protocol participation, not review.\n\nsignature = mpc_sign(tx, threshold=3, parties=5)\n\n# If build_withdrawal was influenced by an attacker,\n# five honest parties produce a valid signature over\n# a transaction nobody wanted."
  },
  {
   "type": "p",
   "html": "This is not a defect in the scheme. MPC is a signing protocol and signing protocols sign what they are given. The assumption is that something upstream decided correctly."
  },
  {
   "type": "h2",
   "text": "The human-participation variant"
  },
  {
   "type": "p",
   "html": "Some deployments have human operators approve before their node participates. This is better and it inherits the display problem exactly as multisignature schemes do."
  },
  {
   "type": "ul",
   "items": [
    "What the operator sees comes from an interface, not necessarily from the bytes being signed",
    "Operators approving routinely develop the same reflexive behaviour as any repeated approval",
    "The approval is typically recorded as application state, so there is no evidence of what was shown"
   ]
  },
  {
   "type": "p",
   "html": "So a human-in-the-loop MPC deployment has the same gap as a hardware multisignature setup: the signers were present and what they saw was not necessarily what executed."
  },
  {
   "type": "h2",
   "text": "Layering the two"
  },
  {
   "type": "table",
   "head": [
    "Layer",
    "Question answered",
    "Mechanism"
   ],
   "rows": [
    [
     "Authorisation",
     "Did a named human intend this specific transfer?",
     "Signature over the rendered statement, from a personal credential"
    ],
    [
     "Policy",
     "Is this within the configured rules?",
     "Custody policy engine"
    ],
    [
     "Key custody",
     "Can any single compromise produce a signature?",
     "MPC threshold scheme"
    ]
   ]
  },
  {
   "type": "p",
   "html": "Read top to bottom: the human decides, the policy constrains, the key scheme signs. Each layer addresses a threat the others do not, and removing any one leaves a gap."
  },
  {
   "type": "h2",
   "text": "The practical integration"
  },
  {
   "type": "code",
   "text": "# Before the MPC ceremony begins\n\nstatement = render_from_bytes(tx)          # decoded, complete\nreceipt   = await_human_signature(statement)\nverify(receipt, issuer_jwks) or abort()\nrequire(receipt.digest == sha256(JCS(render_from_bytes(tx))))\n\n# Only now does the ceremony start\nsignature = mpc_sign(tx, threshold=3, parties=5)\n\n# The receipt is retained with the transaction record."
  },
  {
   "type": "p",
   "html": "The recomputation on the fourth line is what makes it robust. The statement is derived from the transaction bytes both at approval and immediately before signing, and a difference halts the ceremony."
  },
  {
   "type": "h2",
   "text": "What to ask an MPC vendor"
  },
  {
   "type": "ol",
   "items": [
    "Where does the message to be signed come from, and what would happen if that system were compromised?",
    "Do your operators review the transaction, and if so is what they see derived from the bytes being signed?",
    "Is there a record of what each operator was shown, or only that they approved?",
    "Can the ceremony be gated on an external approval your platform cannot itself produce?"
   ]
  },
  {
   "type": "p",
   "html": "The third question tends to produce the most informative answer. Most platforms record approval as a status; very few record the rendered content."
  },
  {
   "type": "p",
   "html": "None of this diminishes MPC. It is the right answer to key custody and the largest custody incidents of recent years did not involve key compromise — which is precisely the argument for attending to the layer above it."
  },
  {
   "type": "h2",
   "text": "A worked example: a compromised orchestrator"
  },
  {
   "type": "table",
   "caption": "What each layer does when the payload is wrong",
   "head": [
    "Layer",
    "Behaviour"
   ],
   "rows": [
    [
     "MPC signing service",
     "Produces a valid signature — that is its job"
    ],
    [
     "Threshold policy",
     "Satisfied, if the amount is under the limit"
    ],
    [
     "Approver dashboard",
     "Displays whatever the orchestrator sent it"
    ],
    [
     "<strong style=\"font-weight:600\">Signature over the rendered effect</strong>",
     "<strong style=\"font-weight:600\">Fails — the human signed different bytes</strong>"
    ]
   ]
  },
  {
   "type": "p",
   "html": "The layers compose rather than compete: MPC removes the single point of key compromise, and a human signature over the rendered effect removes the question of whether anyone meant it."
  },
  {
   "type": "h2",
   "text": "Objections and honest limits"
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“Our MPC has a human-participation mode.”</strong> Worth checking what the human is shown. If it is a dashboard fed by the same orchestrator, a compromised orchestrator controls both the transaction and the rendering."
  },
  {
   "type": "p",
   "html": "<strong style=\"font-weight:600\">“This adds latency to every transaction.”</strong> Only to the ones you gate. Small, frequent transfers run under a bounded grant; the gate belongs on the irreversible, high-value tail."
  }
 ],
 "faq": [
  {
   "q": "Is MPC inadequate?",
   "a": "It is the right answer to key custody and does that job well. It signs the message it is given, so what gets signed is decided upstream."
  },
  {
   "q": "Does human approval in an MPC flow solve it?",
   "a": "It helps and inherits the display problem. What the operator sees may not be derived from the bytes being signed, and the approval is usually recorded as a status."
  },
  {
   "q": "Do MPC and seen-and-signed compete?",
   "a": "No. They are layers: the human decides, the policy constrains, the threshold scheme signs. Removing any layer leaves a distinct gap."
  },
  {
   "q": "What should be asked of a vendor?",
   "a": "Whether there is a record of what each operator was shown, not merely that they approved. Very few platforms record rendered content."
  },
  {
   "q": "Does MPC replace human approval?",
   "a": "No. It removes a custody risk. Whether the transaction is the intended one is a separate question."
  },
  {
   "q": "Can the two be layered?",
   "a": "Yes, and they should be: a human signature over the rendered effect becomes a required input to the MPC signing policy."
  },
  {
   "q": "Does this slow every transaction?",
   "a": "Only the gated ones. Routine transfers run under a bounded grant."
  }
 ],
 "sources": [
  {
   "t": "Published literature on threshold signature schemes and multi-party computation."
  },
  {
   "t": "FTC — business guidance on marketplaces and consumer protection",
   "u": "https://www.ftc.gov/business-guidance"
  },
  {
   "t": "Post-incident analyses of custody compromises involving display mismatch."
  },
  {
   "t": "NIST Multi-Party Threshold Cryptography project",
   "u": "https://csrc.nist.gov/projects/threshold-cryptography"
  }
 ],
 "related": [
  {
   "slug": "bybit-wazirx-multisig-hack-payload-mismatch-postmortem",
   "title": "The payload flip",
   "category": "Crypto"
  },
  {
   "slug": "fireblocks-bitgo-api-perimeter-gating-automated-custodial",
   "title": "The custody API is the perimeter",
   "category": "Crypto"
  },
  {
   "slug": "hardware-wallet-blind-signing-ledger-trezor-screens-cant",
   "title": "Why hardware wallet screens cannot protect you",
   "category": "Crypto"
  }
 ],
 "image": "https://cdn.twc.sh/images/igcache/Splitting%20Key%20Not%20Deciding/1500_900/blog.jpg",
 "wordcount": 954,
 "url": "/blog/multi-party-computation-mpc-vs-seen-signed-receipts.html",
 "reading_time": "4 min read",
 "hub": {
  "slug": "topics/digital-asset-custody",
  "title": "Digital asset custody"
 },
 "answer": "No. It decides how a signature is produced without any single party holding the key. What the transaction is, and whether anyone intended it, comes from somewhere else entirely — usually a policy engine reading a payload the wallet never rendered to a human.",
 "answer_q": "Does MPC decide whether a transaction should be signed?",
 "glossary": [
  {
   "term": "Multi-party computation",
   "def": "Producing a signature from key shares held by several parties, so no single party holds the key."
  },
  {
   "term": "Rendered effect",
   "def": "What the transaction will actually do, shown to a person in terms they can judge."
  },
  {
   "term": "Blind approval",
   "def": "Approving a payload whose effect was never rendered independently."
  }
 ],
 "checklist": {
  "title": "Questions for an MPC vendor",
  "id": "mpcqs",
  "desc": "Five steps.",
  "steps": [
   {
    "name": "Where does the transaction payload originate?",
    "text": "That system is your real trust boundary."
   },
   {
    "name": "What is the human shown, and who renders it?",
    "text": "If the same system, it is not independent."
   },
   {
    "name": "Is the approval signed or clicked?",
    "text": "A click is a session event."
   },
   {
    "name": "Can I verify approvals offline later?",
    "text": "Without calling you."
   },
   {
    "name": "What happens if your service is unavailable?",
    "text": "Fail-open is the usual undocumented answer."
   }
  ]
 },
 "cta": {
  "title": "Where this fits in Manav",
  "html": "Manav sits in front of the signing policy: a human signature over the rendered effect, required before the MPC service will assemble shares.",
  "href": "../docs.html",
  "label": "See transaction gating"
 }
}