distributed-lab / distributed-lab/bitcoin-window-mul

`*_to_*_bits_toaltstack` boundary guards: LE under-push for `num_bits <= 1`; BE over-push for `num_bits = 0`

Open
#3 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
14
Forks
3
PR merge metrics
No merged PRs in 30d

Description

### **Summary**

* `limb_to_le_bits_toaltstack` pushes to `altstack` only when `num_bits ≥ 2`. Callers that pop `num_bits` items underflow for `num_bits = 1`.
* `limb_to_be_bits_toaltstack` unconditionally pushes even when `num_bits = 0`, leaving an unexpected extra item on `altstack`.

Both violate the contract “push exactly `num_bits` bits to `altstack`,” breaking stack discipline at the edges.

### **Proposed Fix**

**LE:**

```rust
pub fn limb_to_le_bits_toaltstack(num_bits: usize) -> Script {
if num_bits >= 2 {
script! {
{ limb_to_le_bits_common(num_bits) }
for _ in 0..num_bits { OP_TOALTSTACK }
}
} else if num_bits == 1 {
script! {
OP_TOALTSTACK
}
} else {
script! {}
}
}
```

**BE:**

```rust
pub fn limb_to_be_bits_toaltstack(num_bits: usize) -> Script {
if num_bits >= 2 {
script! {
{ limb_to_be_bits_common(num_bits) }
OP_TOALTSTACK
OP_TOALTSTACK
}
} else if num_bits == 1 {
script! {
OP_TOALTSTACK
}
} else {
script! {}
}
}
```

**Acknowledgements:** This issue was identified using Pomelo ([https://eprint.iacr.org/2024/1768](https://eprint.iacr.org/2024/1768)) by the UCSB/Nubit team. We also acknowledge [BitVM#360](https://github.com/BitVM/BitVM/issues/360) for first flagging potential problems in the `limb_to_le_bits*` family.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.