0xMiden / 0xMiden/protocol

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

未關閉
#3,113 14 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視
主要語言
Rust
星號
132
分支
167
平均合併
1 天 23 小時
30 天內合併 PR
110

描述

### 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"
```

貢獻指南

開啟貢獻指南

評估

這個 Issue 還沒有評估資料。

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。