build: gate the experimental modules on SECP256K1_EXPERIMENTAL in CMake

configure.ac refuses --enable-module-frost, --enable-module-chilldkg and
--enable-module-iceberg outright unless --enable-experimental is also
given. The CMake build had no equivalent, so
-DSECP256K1_ENABLE_MODULE_ICEBERG=ON produced a library with no warning
banner and no acknowledgement that anything experimental was requested.

Of the three, iceberg is the one this matters most for: doc/iceberg.md
tells the reader not to put money behind it, and the CMake path let a
build acquire it without the reader ever passing a flag that says so.

Add the three checks to the existing NOT SECP256K1_EXPERIMENTAL block,
next to the ARM32 assembly check and worded the same way. The options are
declared well above it, so the values are set by the time the block runs.
Verified both directions: the configure fails with "Iceberg module is
experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow." without the
flag, and succeeds with it.

This deliberately leaves the other zkp experimental modules alone. They
are ON by default in CMake and gating them would change every existing
CMake build; the three added here are OFF by default, so nobody is
relying on the ungated path.

While here, correct doc/iceberg.md, which claimed the module "builds by
default here". SECP_SET_DEFAULT(enable_module_iceberg, no, yes) makes it
off by default and on in dev mode, which is now what the paragraph says,
along with the experimental requirement it did not previously mention.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kgothatso Ngako
2026-09-01 23:38:05 +02:00
parent 7afee05de8
commit 67e9424552
2 changed files with 18 additions and 9 deletions

View File

@@ -129,6 +129,15 @@ if(NOT SECP256K1_EXPERIMENTAL)
if(SECP256K1_ASM STREQUAL "arm32")
message(FATAL_ERROR "ARM32 assembly is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
if(SECP256K1_ENABLE_MODULE_FROST)
message(FATAL_ERROR "FROST module is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
if(SECP256K1_ENABLE_MODULE_CHILLDKG)
message(FATAL_ERROR "ChillDKG module is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
if(SECP256K1_ENABLE_MODULE_ICEBERG)
message(FATAL_ERROR "Iceberg module is experimental. Use -DSECP256K1_EXPERIMENTAL=ON to allow.")
endif()
endif()
set(SECP256K1_VALGRIND "AUTO" CACHE STRING "Build with extra checks for running inside Valgrind. [default=AUTO]")

View File

@@ -5,15 +5,15 @@ The following sections contain additional notes on the API of the iceberg
module (`include/secp256k1_iceberg.h`). A usage example can be found in
`examples/iceberg.c`, which runs the whole flow and narrates it.
**This module is experimental.** It builds by default here, which is a
development convenience rather than a statement that it is ready. Iceberg has a
security proof, by reduction to NestedMuSig2's unforgeability, but it is in an
anonymous conference submission that is still a working draft, and at the two
nonces BIP-327 fixes that reduction holds in the algebraic group model rather
than the plain random oracle model. The proof also assumes a property no library
can provide (that a session label is used once, group-wide) and the known
ways to lose a key all live in exactly that assumption. Do not put money behind
this module.
**This module is experimental.** It is off by default and on in dev mode, and
both build systems refuse it outright without `--enable-experimental` or
`-DSECP256K1_EXPERIMENTAL=ON`. Iceberg has a security proof, by reduction to
NestedMuSig2's unforgeability, but it is in an anonymous conference submission
that is still a working draft, and at the two nonces BIP-327 fixes that
reduction holds in the algebraic group model rather than the plain random
oracle model. The proof also assumes a property no library can provide (that a
session label is used once, group-wide) and the known ways to lose a key all
live in exactly that assumption. Do not put money behind this module.
Iceberg lets a *t*-of-*n* group act as a single MuSig2 participant. From outside,
the result is an ordinary BIP-340 signature: nothing in it records that a group