Skip to content

Bare Miniscript multi(...) accepts more than 20 pubkeys and compiles anyway #14

Description

@Nuhiat-Arefin

Summary

bitcoinerlab/miniscript accepts a bare Miniscript multi(k, ...) expression with more than 20 pubkeys and compiles it successfully instead of rejecting it.

Current reference implementations reject this family because CHECKMULTISIG supports at most 20 pubkeys. However, the exposed bare-Miniscript surface here currently treats the same input as both valid and sane.

Minimal repro

const { analyzeMiniscript, compileMiniscript } = require("@bitcoinerlab/miniscript");

const source =
  "multi(2,0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798,02c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5,02f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9,02e493dbf1c10d80f3581e4904930b1404cc6c13900ee0758474fa94abe8c4cd13,022f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,025cbdf0646e5db4eaa398f365f2ea7a0e3d419b7e0330e39ce92bddedcac4f9bc,022f01e5e15cca351daff3843fb70f3c2f0a1bdd05e5af888a67784ef3e10a2a01,03acd484e2f0c7f65309ad178a9f559abde09796974c57e714c35f110dfc27ccbe,03a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7,03774ae7f858a9411e5ef4246b70c65aac5649980be5c17891bbec17895da008cb,03d01115d548e7561b15c38f004d734633687cf4419620095bc5b0f47070afe85a,03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8,03499fdf9e895e719cfd64e67f07d38e3226aa7b63678949e6e49b241a60e823e4,02d7924d4f7d43ea965a465ae3095ff41131e5946f3c85f79e44adbcf8e27e080e,03e60fce93b59e9ec53011aabc21c23e97b2a31369b87a5ae9c44ee89e2a6dec0a,03defdea4cdb677750a420fee807eacf21eb9898ae79b9768766e4faa04a2d4a34,025601570cb47f238d2b0286db4a990fa0f3ba28d1a319f5e7cf55c2a2444da7cc,022b4ea0a797a443d293ef5cff444f4979f06acfebd7e86d277475656138385b6c,024ce119c96e2fa357200b559b2f7dd5a5f02d5290aff74b03f3e471b273211c97,02352bbf4a4cdd12564f93fa332ce333301d9ad40271f8107181340aef25be59d5)";

console.log(analyzeMiniscript(source, { tapscript: false }));
console.log(compileMiniscript(source, { tapscript: false }).asm);

Observed locally

The payload contains 21 unique pubkeys.

Observed behavior:

  • analyzeMiniscript(source, { tapscript: false }) reports:

    • valid: true
    • issane: true
  • compileMiniscript(source, { tapscript: false }) succeeds

  • the compiler emits script for the same invalid policy

Expected behavior

The input should be rejected because bare multi(k, ...) maps to CHECKMULTISIG, which supports at most 20 pubkeys.

For this payload, the expected behavior is a parse / validation / compilation failure for:

multi(2, <21 pubkeys>)

Cross-check against maintained peers

The same payload is rejected by maintained implementations:

  • rust-miniscript: invalid threshold 2-of-21; maximum size is 20
  • bitcoin/bitcoin: parse failed
  • elements-miniscript: CHECKMULTISIG ('multi()' descriptor) only supports up to 20 pubkeys

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