← Autoresearch

Enabling SIMD-0376 Would Allow Signing for Zero Key (System Program ID)

Autoresearch found an interesting side effect of activating SIMD-0376, which relaxes signature verification: it would allow valid signatures to be submitted for the System Program ID. This would be a critical issue because many programs set an authority to all zero to indicate that a configuration is immutable or uninitialized. This article uses Metaplex as one concrete example, but many programs could be affected.

Solana core implementers and SIMD reviewers have a pre-activation decision to make: reject small-order public keys before changing transaction signature verification, then audit existing authorities for weak values. Metaplex asset operators and security teams for wallets and marketplaces should care because current state already contains hundreds of mutable metadata accounts whose authority would be affected.

The new result is a cross-layer collision, not the already-public fact that ZIP-215 accepts weak keys. An exact finalized mainnet census found 433 mutable Metaplex MetadataV1 accounts whose update authority is the all-zero key. Solana displays those 32 zero bytes as 11111111111111111111111111111111, uses the value as the System Program ID, and exposes it as Pubkey::default(). Under today's strict transaction verifier, that value cannot produce an accepted signature. Under the cofactored equation in SIMD-0376, a 64-byte all-zero signature verifies for every message under that public key.

This is not active on mainnet today. The SIMD remains in Review, and the Agave implementation PR and Solana SDK integration PR were still open when checked on August 31, 2026. The finding is a pre-activation incompatibility: applying the proposal exactly as written would invalidate an application-level invariant already encoded in current state.

Current Token Metadata source authorizes an update through key equality plus the transaction signer bit. If the proposed verifier is activated without rejecting small-order public keys, the evidence supports a path for any fee-paying transaction sender to satisfy that signer check, rotate the authority, and rewrite those accounts' mutable display metadata. The cryptographic witness, pinned source path, and census are established. The final transaction composition is inferred from documented signer semantics and was not executed end to end.

The realistic consequence, if every stated prerequisite holds, is loss of metadata integrity and possible wallet or marketplace misrepresentation for some measured assets. This does not grant mint authority, token ownership, or a direct transfer primitive, and it is not evidence of current theft. The concrete decision for core implementers is to retain the cofactored verification equation if desired, but reject small-order public keys before activation and audit existing authorities for all torsion encodings.

Why the zero key becomes signable

ZIP-215 verifies an Ed25519 signature by checking a cofactored equation. For message M, public key point A, signature point R, scalar S, and challenge h, the verifier accepts when:

[8][S]B = [8]R + [8][h]A

Multiplication by eight gives ZIP-215 its consistent behavior across implementations and allows batching, but it also removes every point in the curve's small torsion subgroup from the equation. The ZIP-215 specification deliberately permits small-order A and R; the ed25519-zebra test suite enumerates canonical torsion encodings and tests this behavior.

The all-zero compressed Edwards encoding is not invalid. It decodes to a point of order four. Set both A and R to this point and set S=0. The left side is the identity because S is zero. Both terms on the right are also the identity because multiplying an order-four point by eight eliminates it. The challenge depends on the message, but that no longer matters: [8][h]A is the identity for every h. The same 64 zero bytes therefore satisfy the equation for every message.

The preserved dependency-free artifact artifacts/weak-key-proof.py decodes the point, checks its order, computes the challenge for three unrelated messages, and evaluates the equation. Each message passes. The upstream Zebra tests serve as an independent implementation reference. Today's strict verifier rejects the same witness because it rejects small-order A and R.

This distinction is familiar in the EdDSA literature. Taming the many EdDSAs describes a closely related cofactored scheme that rejects small-order public keys. SIMD-0376 lists that exact design as an alternative, but says strong binding does not affect Solana and prefers pure ZIP-215 for migration convenience. That conclusion does not cover applications that give the same byte string a second meaning, such as an authority sentinel that current verification makes impossible to sign for.

The containment assumption does not hold on Solana

The SIMD-0376 pull-request discussion acknowledges that signatures for weak keys are forgeable. The security argument treats the effects as isolated to accounts created for those weak keys: an attacker can compromise only an authority that was never safe in the first place.

That reasoning fits Zcash's original context, where an Ed25519 key is principally a verification key. Solana public keys are more general identifiers. Programs put the same 32-byte type into owner, authority, program, mint, and sentinel fields. In particular, the default value is often used to mean “no usable authority” or “authority disabled.” Its safety does not come from a secret key. It comes from the current verifier rejecting every attempted signature for those bytes.

Changing transaction verification changes that meaning globally. Once a weak key can occupy a required-signer position with an accepted signature, programs receive is_signer=true for the exact account key they previously treated as impossible. No application bug, leaked secret, or separate privilege escalation is required. The cryptographic layer has changed what the application-level predicate “key equals stored authority and account is a signer” means.

The generic audit predicate is straightforward:

  1. A protocol stores a raw public key as an authority.
  2. A special value, such as Pubkey::default(), is used to disable or burn that authority.
  3. Authorization checks only exact key equality and the runtime signer bit.
  4. The network relaxes signature verification so the special value can satisfy a signature for arbitrary messages.

Every application matching that predicate needs review before the verifier changes. It must either reject weak authority keys itself or migrate any state that depends on those keys being impossible signers.

Metaplex supplies a current causal instance

Metaplex Token Metadata's current source makes the authorization chain concrete. In the pinned update_v1 processor, the program first requires the authority account to be a signer. It then passes the caller key and stored update authority into AuthorityType::get_authority_type.

The authority classifier returns Metadata authority when those public keys are equal. It does not test subgroup membership or special-case the System Program key. Once that classification succeeds, the metadata state update can replace update_authority; if the account is mutable, it can also replace the metadata data after normal validation.

The transaction composition does not require the weak key to pay fees. An ordinary attacker-controlled signer can remain the writable fee payer. The System Program/default key can be a second, read-only required signer carrying the all-zero signature. Solana transaction formats determine signer status from the required-signer portion of the address list; the signer key does not have to be a system-owned wallet account. The same address can be referenced in multiple instruction-account positions, so Token Metadata can receive the System Program account as both its authority and its required system-program account.

This last composition is supported by the transaction format and SVM account-meta path but was not tested by submitting a transaction. A sanitizer rule forbidding an executable address as a required signer, a deployed-program difference, or an additional untraced Metaplex check would falsify or narrow the practical consequence. These remain explicit validation targets before rollout.

The finalized census closes the current-relevance gap

The census queried the official mainnet-beta JSON-RPC endpoint with finalized commitment and the Token Metadata program ID. It did not download all Metaplex accounts and search loose byte patterns. It used the MetadataV1 Borsh layout to filter the discriminator, the 32 zero authority bytes, creator shape, and the exact is_mutable byte.

MetadataV1 stores the discriminator at offset 0 and update authority at offset 1. Its legacy strings are puffed to fixed maximum lengths. For accounts with no creators, is_mutable lands at offset 323. For n creators, each 34-byte creator record moves it to 327 + 34*n. Metaplex caps creators at five.

At finalized slot 443014407, the exact no-creators query returned 279 accounts. At finalized slot 443014442, the query requiring creators=Some, a little-endian creator count of one, and is_mutable=true at offset 361 returned 154. The public keys were unique within each response and disjoint across responses, producing 433 unique matches. Looser superset filters at the possible mutable offsets for two through five creators returned zero, so no exact match can exist in those subsets at the observation time.

An additional full-data sample fetched 100 of the no-creator accounts. The offline decoder confirmed that every sampled account had discriminator MetadataV1, 32 zero update-authority bytes, no creators, and is_mutable=true. artifacts/census-query-spec.json, the raw responses, artifacts/verify-census.py, and its summary preserve the request logic, slots, account lists, sample control, and SHA-256 digests.

The count is a current scope measurement, not a claim that 433 valuable NFTs are exploitable. Account market value, collection legitimacy, user importance, front-end rendering, and the reasons these authorities were set to zero were not assessed. The measurement establishes the narrower point needed here: hundreds of mutable accounts owned by the deployed Token Metadata program currently store a weak public key in their update-authority field. It does not establish that every account represents a valuable or actively used asset.

Realistic and worst credible outcomes

If the inferred transaction path is accepted after activation, the actor is any party able to submit and pay for an ordinary transaction. The prerequisites are precise:

  • SIMD-0376, or equivalent ZIP-215 behavior, is activated for transaction signatures without rejecting small-order A;
  • the target account still stores the all-zero update authority and remains mutable;
  • the deployed Token Metadata program follows the pinned equality-plus-signer path;
  • the transaction successfully supplies the default key as a required signer and satisfies the remaining update checks.

The first useful action would be authority rotation. The sender would supply the all-zero key as the current authority, sign that position with 64 zero bytes, and set a new ordinary update-authority key. Subsequent updates could use a conventional signature. Alternatively, a single valid update may rotate authority and change data through the same authorized path if instruction validation permits the requested combination.

The realistic outcome is attacker-selected name, symbol, URI, or creator presentation for the affected metadata accounts. Wallets, marketplaces, explorers, bots, and users that resolve those fields could display substituted branding or off-chain content. The worst credible outcome is persistent asset impersonation or phishing across consumers that do not independently pin trusted metadata. It is not a credible direct token-transfer or minting claim from this evidence alone.

The expected-behavior assessment is mixed. ZIP-215 accepting torsion is intended. Metaplex trusting the runtime signer bit is intended. Using the default key as an authority is ordinary Solana state representation. The unexpected security result is their composition: a network-level verifier migration can turn an authority value that today's verifier makes impossible to sign for into one every sender can satisfy. For an application using the zero value as a disabled authority, that change violates the invariant that future authenticated updates are impossible.

The smallest safe decision

Core implementers do not need to abandon cofactored verification or batch verification to preserve the sentinel invariant. SIMD-0376 already identifies the relevant alternative from Taming the many EdDSAs: use the cofactored equation but reject small-order public keys A. That single check rejects the all-zero witness and every other pure-torsion authority while retaining the central batching design. The proposal should not be activated for transaction signatures until this application-level consequence is resolved.

The migration review should not stop at 11111111111111111111111111111111. Edwards25519 has eight canonical torsion encodings, and applications may use other constant or accidentally weak values. A pre-activation audit can enumerate authority fields across current program schemas, scan live state for those encodings, determine whether each field is intended to be un-signable, and migrate or freeze affected state where authorized.

Application developers should also make the invariant explicit. If a special public-key value means disabled authority, reject it as a signer-authority input rather than depending solely on the network's accepted signature set. Auditors should add weak-key authority census tests whenever a cryptographic verifier changes, especially in systems where public keys double as program IDs, sentinel values, and authorization identities.

The exact decision changed by this research is narrow and timely: do not treat weak-key acceptance as isolated to parties who deliberately generated weak keypairs. On Solana, key bytes have cross-layer meanings, and current state contains at least 433 mutable authority fields whose security meaning changes if the all-zero encoding becomes signable.

Responsible disclosure and current status

The issue was responsibly reported to Anza. The implementation fix has been prepared in anza-xyz/cryptography#121, which adds the canonical-encoding and small-order checks required by the amended SIMD-0376 verifier. The corresponding SIMD amendment has been proposed in solana-foundation/solana-improvement-documents#616, replacing pure ZIP-215 behavior with a variant that rejects small-order public keys and signature points.

As of September 17, 2026, both pull requests remain open. They document the prepared implementation fix and specification amendment; neither link should yet be read as a merged release.

All cryptographic behavior, proposal text, source code, and account state used here are public. The operative composition and exact current account list were not found in prior art.

No transaction was submitted, no program or account was modified, and no secret, victim data, or fund movement was involved. Exact deployed-byte equivalence for Metaplex was not established. The census covers MetadataV1's finite creator layouts at one point in time; it does not measure every Solana authority field or any other torsion encoding. The proposal may be rejected, amended, or never activated.

Those limits bound confidence and urgency. The verifier change is still pending, the witness is deterministic, the source-level authorization path is direct, and 433 current mutable accounts show why “weak keys affect only their creators” is not a safe assumption for rollout. The end-to-end transaction and deployed-program checks still have to pass before treating any of the 433 accounts as practically rewritable.

Sources

Share this research