0xMiden / 0xMiden/protocol

bug(multisig): adding a signer to a 1-of-1 account fails STARK verification

Đang mở
#3,113 14 bình luận 0 reaction 0 người được giao Xem trên GitHub
Ngôn ngữ chính
Rust
Star
132
Fork
167
Merge trung bình
1 ngày 23 giờ
Pull request đã merge (30 ngày)
110

Mô tả

### Packages versions

miden-protocol = "0.15.3"
miden-standards = "=0.15.3"
miden-tx = "0.15.3"
miden-node-proto ="0.15.0"
miden-testing = "0.15.3"
miden-client = "0.15.0"
miden-client-sqlite-store = "0.15.0"

### Bug description

## Summary

`update_signers_and_threshold` produces a STARK-invalid proof when adding a
signer to a single-signer multisig (a 1-of-1 account). The transaction
executes fine, but proving/verifying it fails with:

constraint mismatch: quotient * vanishing != folded constraints

This affects both the standard (`auth::multisig`) and smart
(`auth::multisig_smart`) multisig auth components.

## Root cause

After `update_signers_and_threshold` rotates the signer set, it
unconditionally calls `cleanup_pubkey_and_scheme_id_mapping` to clear any
approver slots that are no longer used. When the approver map holds exactly
one entry (e.g. adding a signer to a 1-of-1 multisig), the proc's internal
loop guard already short-circuits and the body never runs - nothing is
cleared. However, *entering* the proc at all perturbs the prover trace enough
to fail node-side STARK verification.

The cleanup only ever has work to do when the signer set shrinks
(`init_num_of_approvers > new_num_of_approvers`). Add-signer and
threshold-only updates should skip it entirely.


## Proposed fix

Gate the cleanup call on the signer set actually shrinking
(`init_num_of_approvers > new_num_of_approvers`) in both:

- `crates/miden-standards/asm/standards/auth/multisig.masm`
- `crates/miden-standards/asm/standards/auth/multisig_smart/mod.masm`

Add-signer and threshold-only updates skip the call; remove-signer behavior is
unchanged.

Add regression tests that grow a 1-of-1 multisig to 2 signers and verify a
real STARK proof, for both the standard and smart variants.

### How can this be reproduced?

1. Create a 1-of-1 multisig account.
2. Execute `update_signers_and_threshold` to grow the signer set to 2
(threshold 2), signed by the single existing approver.
3. Generate and verify a real STARK proof for the transaction (e.g.
`prove_and_verify_transaction`).

The proof fails verification with `constraint mismatch: quotient * vanishing
!= folded constraints`. Note that a dummy block proof
(`MockChain::add_pending_executed_transaction` + `prove_next_block`) uses
`prove_dummy` and does **not** exercise this path, so the bug is invisible
there - it only surfaces under real transaction proving.

### Relevant log output

```shell
Invalid proof for transaction 0x7c212267a3f17a17dbfd431272a7516e5eb11663f0064217509c6e58e2fd2341: failed to verify transaction\ncaused by: failed to verify STARK proof for program with hash0xcdd0a81d45597a6099f138fc997d0a3f886e9553d819063559afe0cdfbe2a5d2\ncaused by: constraint mismatch: quotient * vanishing != folded constraints"
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.