Notes on NEAR's MPC

 

tl;dr: The good: Audit went well. Lúcás Meier’s Cait-Sith threshold ECDSA protocol seems like a reasonable, conservative choice. The bad: Near’s MPC currently works in a 5 out of 8 setting, without any proactive refresh.

Notes

Good

  • MPC’s configuration is transparent, on-chain $\Rightarrow$ can monitor for suspicious membership changes
  • “uses the Cait-Sith protocol in a secure manner”1
  • “we did not identify any issues related to Beaver triple or nonce reuse that could compromise the security of a shared key”1
  • NEAR currently only uses Cait-Sith on mainnet (May 1st, 2026)
    • (The MPC committee can change this over time, of course.)

Unclear

Somewhat concerning

  • Claude Code identified four unaddressed items from the Trails of Bits audit; they are not high-severity though:
    • #4 Ciphertext swapping (DB AAD missing) – Informational, Cryptography
    • #5 Hash function used as KDF (derive_tweak) – Informational, Cryptography
    • #6 P2P identity misbinding (duplicate p2p public keys) – Medium, Data Validation
    • #10 AES-GCM nonce reuse (96-bit random, no rotation) – Medium, Cryptography
  • NEAR modified the Cait-Sith scheme1
    • multiplicative rerandomization of pre-signatures

Concerning

  • TEE-backed MPC nodes are off on mainnet (as of May 1st, 2026)
  • No robustness and no identifiable abort (AFACCT)
    • a malicious participant who deviates can make signing fail (abort the protocol) and do so without being identifiable by honest parties $\Rightarrow$ 1 participant can DoS
  • NEAR had a lot of GitHub CI security issues in the Trail of Bits report (#12, #13, #141)
    • #14 could’ve allowed an attacker to release a completely malicious binary (was rated “difficult” though)

Deeply concerning

  • 5 out of 8 secret-sharing on mainnet (see here)
  • No proactive refresh, even though re-sharing (for nodes leaving and joining) is implemented and would be trivial to call periodically
    • Without proactive refresh, an attacker can slowly take its time and compromise all 5 keys
    • The last re-sharing (and thus refresh) was on March 3rd, 2026
      • $\Rightarrow$ any progress an attacker made in the last 2 months (as of May 1st, 2026) is still good progress
    • Why not? Because proactive refresh must invalidate the ECDSA pre-signatures, which lowers performance.
  • The Cait-Sith threshold ECDSA library was not part of the audit; only its use by NEAR’s MPC node implementation was audited1
    • This library may not have been production-ready.

Resources

MPC node operators

Operators:

  • lacksandtech.near,
  • mpc-lgns.near,
  • multichain-mainnet-aurora.near,
  • near-mpc-staking4all-01.near,
  • nodemonster.near,
  • n1-multichain.near,
  • everstake-mpc-1.near,
  • stakin-mpc.near

NEAR-affiliated names visible:

  • n1-multichain.near (NEAR One)
  • multichain-mainnet-aurora.near (Aurora)

The rest are independent operators (Everstake, Stakin, etc.).

Why no proactive refresh?

First, Beaver triple secret sharing do not need to be refreshed: theft of such sharings do not lead to signature forgeries. Furthermore, $t$-out-of-$n$ secret-shared beaver triples continue to be usable after refresh.

Second, recall that a pre-signature for $k \cdot G$ is a secret sharing:

\[([k]_i, [k\cdot \sk]_i)_{i\in[n]},\]

where $[k]_i$ is player $i$’s ($t$-out-of-$n$) share of the nonce $k$ (and, similarly, $[k\cdot \sk]_i$ is $k\cdot \sk$’s share).

While pre-signatures are indifferent to the secret-sharing of $\sk$ changing, theft of $t$ pre-signature shares would lead to recovery of the $\sk$: the adversary can reconstruct $k$ and $k\cdot \sk$ and then obtain $\sk$.

Hence, for refresh to be meaningful, pre-signatures have to be securely erased/discarded and new ones need to be generated.

Why presignature rerandomization exists

tl;dr: Rerandomization adapts a master-key presignature to sign under $\mathsf{sk} + e$ in 1 online round, with a guardrail against accidental presignature reuse.

NEAR’s MPC supports additive HD key derivation: derived keys are:

\[\mathsf{sk}_{\mathsf{app}} = \mathsf{sk} + e\]

where $e = H(\mathsf{account_id}, \mathsf{path})$ is public.

But cached presignatures $(R, [k]_i, [\sigma]_i)$ are generated with respect to the master $\mathsf{sk}$ (i.e. $\sigma = k \cdot \mathsf{sk}$).

To sign for $\mathsf{sk}_{\mathsf{app}}$ instead of $\mathsf{sk}$, each party must locally adjust their $\sigma$-share to:

\[[\sigma_{\mathsf{app}}]_i = [\sigma]_i + [k]_i \cdot e\]

This $\sigma$-adjustment is why rerandomization exists.

NEAR additionally multiplies through by a public scalar $\delta = \mathsf{HKDF}(\mathsf{pk}, \mathsf{tweak}, \mathsf{msg_hash}, R, \mathsf{participants}, \mathsf{entropy})$, yielding:

\[\bigl(\delta R, \delta [k]_i,\ \delta ([\sigma]_i + [k]_i \cdot e)\bigr)\]

This multiplicative step is not needed for nonce freshness: each signing request already consumes a fresh presignature (crates/node/src/providers/ecdsa/sign.rs:73, take_owned()), so the underlying $k$ is already per-request.

What $\delta$ buys is defense-in-depth: if a bug or retry path ever served the same presignature twice across different $(\mathsf{msg}, \mathsf{tweak})$ pairs, which would normally leak $\mathsf{sk}$, the request-bound $\delta$ ensures the effective nonces still differ. ToB’s audit1 also notes NEAR picked the multiplicative form (vs. Groth–Shoup’s additive6) because the security proof was easier to write that way.

Was not able to find the proof in their repo.

Script: Fetch all MPC participants

curl -s -X POST https://rpc.mainnet.near.org -H "Content-Type: application/json" -d '{
    "jsonrpc":"2.0","id":"1","method":"query",
    "params":{"request_type":"call_function","finality":"final",
              "account_id":"v1.signer","method_name":"state","args_base64":"e30="}
  }' | jq -r '.result.result | implode' | jq .

Script: MPC membership over time

Based on visible on-chain history, no pure refresh (same set) has happened on mainnet. Every reshare was triggered by a membership change.

Here’s what each epoch’s vote_new_parameters proposal actually contained (winning proposals only, ordered by epoch):

Epoch Finalized n / threshold Membership delta from previous
3 2025-08-25 8 / 5 (earliest vote_new_parameters call against this contract — see note)
4 2025-09-17 10 / 7 + everstake-mpc-1.near, + stakin-mpc.near
5 2025-11-21 9 / 6 − lifted-mainnet.near
6 2026-03-03 8 / 5 − chain-signatures-hot.near ← current

Run this vibe-coded script to reproduce these results.

References

For cited works, see below 👇👇

  1. NEAR One MPC Chain Signatures, by Fredrik Dahlgren, Marc Ilunga, and Jim Miller, 2025, [URL]  2 3 4 5 6

  2. Towards Modular Foundations for Protocol Security, by Lúcás Críostóir Meier, in Cryptology ePrint Archive, Paper 2023/187, 2023, [URL] 

  3. Cait-Sith: Overview, Lucas Meier, April 16th, 2023 

  4. Fast Threshold {ECDSA} with Honest Majority, by Ivan Damgård and Thomas Pelle Jakobsen and Jesper Buus Nielsen and Jakob Illeborg Pagter and Michael Bæksvang Østergård, in Cryptology {ePrint} Archive, Paper 2020/501, 2020, [URL]  2

  5. Cait-Sith threshold ECDSA signatures, by Lúcás Meier, GitHub repo 

  6. On the security of ECDSA with additive key derivation and presignatures, by Jens Groth and Victor Shoup, in Cryptology ePrint Archive, Report 2021/1330, 2021, [URL]