Skip to content

sp1-lib exports Weierstrass decompress wrappers that unconditionally panic #2926

Description

@4waan

Component

sp1-zkvm

Have you ensured that all of these are up to date?

  • SP1 SDK
  • cargo prove CLI/sp1up

What version of SP1 SDK are you on?

No response

What version of the cargo prove CLI are you on?

No response

Operating System

macOS (Apple Silicon)

Describe the bug

Summary

In the SECP256K1_DECOMPRESS, SECP256R1_DECOMPRESS and BLS12381_DECOMPRESS precompiles theres no executor implementation and no AIR. Their guest side wrappers are still public API in sp1-lib and sp1-zkvm, so any guest that calls one traps in the executor.. on every input:

  • sp1_lib::bls12381::decompress_pubkey (crates/zkvm/lib/src/bls12381.rs:94-116)
  • syscall_bls12381_decompress, syscall_secp256k1_decompress, syscall_secp256r1_decompress
    (declared crates/zkvm/lib/src/lib.rs:106,115,180; defined in
    crates/zkvm/entrypoint/src/syscalls/{secp256k1,secp256r1,bls12381}.rs)

ED_DECOMPRESS is unaffected... still maps to RiscvAirId::EdDecompress (crates/core/executor/src/syscall_code.rs:327) and works. This is specific to the three Weierstrass curves.

Line references are against ed5eff636.

How to reproduce

Any input triggers it; the failure does not depend on the point being malformed

// guest program
use sp1_lib::bls12381::decompress_pubkey;

let _ = decompress_pubkey(&[0u64; 6]);

Substituting syscall_secp256k1_decompress or syscall_secp256r1_decompress should behave the
same way, as should any other caller of these four wrappers.

Expected result, depending on which executor runs:

  • minimal executor — This method should be deprecated.
  • native VM executor — BLS12381_DECOMPRESS is not supported by the native executor.

In the interest of accuracy: I have not executed this. The report is derived from reading the syscall dispatch thats the unreachable!, the panic!, and the absent RiscvAirId mapping cited in the table below which establishes that the call has no implementation on any path, but is not the same as an observed failure. The exact message and which executor fires will depend on configuration. happy to build a guest and paste real output if that would help triage.

Evidence

Three independent dead ends downstream of the ecall:

Layer Status
Native VM executor crates/core/executor/src/vm/syscall.rs:413-418 unreachable!("...is not supported by the native executor")
Minimal executor crates/core/executor/src/minimal/ecall.rs:99,108,117 -> crates/core/executor/src/minimal/precompiles/weierstrass/decompress.rs:12panic!("This method should be deprecated.")
AIR All three return None from both RiscvAirId mappings (crates/core/executor/src/syscall_code.rs:363-364 and :421-422) — no chip, no constraints

Supporting signals that this was intentional rather than drift: the machine-side AIR tests are commented out (weierstrass_decompress.rs:718-776), and the host-side helper sp1_curves::weierstrass::bls12_381::bls12381_decompress is referenced only by its own unit test. The bls12381-decompress, secp256k1-decompress and secp256r1-decompress ELFs are still declared in crates/test-artifacts/src/lib.rs but nothing runs them.

(Nothing in-tree calls these syscalls except those test programs. In particular the ecdsa module computes square roots in Rust (crates/zkvm/lib/src/ecdsa/affine.rs, DecompressPoint::decompress), so the k256/p256 patched crates do not depend on them.)

Why this is worth fixing

well.. sp1-lib is published. A downstream user reaching for the obvious-looking decompress_pubkey gets an executor panic with no compile-time signal and no doc warning that the precompile behind it no longer exists. The failure is unconditional, so it surfaces immediately in development rather than silently but the diagnostic ("This method should be deprecated.") does not point at the caller's problem.

Suggested resolution

Whichever matches the intent behind the removal:

  1. Delete the four wrappers and the stale test-artifact ELF declarations. This also retires the
    dormant defects tracked in bls12-381: decompress_pubkey discards the point-at-infinity flag and performs no subgroup check (dormant) #2927 , which can be closed alongside.
  2. #[deprecated] them with a note pointing at the replacement, if one is expected.
  3. Reinstate the precompiles — in which case bls12-381: decompress_pubkey discards the point-at-infinity flag and performs no subgroup check (dormant) #2927 must be worked before shipping, since
    reinstatement is what makes those defects reachable.

Related

decompress_pubkey also has pre-existing correctness defects

the point-at-infinity flag is discarded, there is no subgroup check, and the Result can never be Err. Those are invisible today only because the function cannot run, and are tracked separately in #2927 .

They are deliberately not part of this issue: deleting these wrappers resolves this report and
retires those defects at the same time, so they only need action if the resolution is
reinstatement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions