Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions mithril-stm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.9.27 (03-11-2026)

### Changed

- Introduced circuit-local Halo2 types in `circuits/halo2/types.rs` with shared `CircuitBaseField`, `CircuitBase`, and `CircuitCurve`.
- Replaced duplicated local `F`/`C` aliases with shared circuit types across Halo2 circuit, gadgets, and golden helper code.
- Standardized Halo2 conversion paths using `From`/`Into` implementations for circuit/domain field wrappers.
- Added `circuits/halo2/adapters.rs` to convert STM Merkle paths into Halo2 witness paths for circuit consumption.
- Removed `circuits/halo2/utils/mod.rs` and inlined field-limb split logic into `circuits/halo2/gadgets.rs`.
- Unified synthesis error mapping through `to_synthesis_error` in `circuits/halo2/errors.rs`.

## 0.9.26 (03-09-2026)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion mithril-stm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "mithril-stm"
version = "0.9.26"
version = "0.9.27"
edition = { workspace = true }
authors = { workspace = true }
homepage = { workspace = true }
Expand Down
48 changes: 48 additions & 0 deletions mithril-stm/src/circuits/halo2/adapters.rs
Comment thread
hjeljeli32 marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! Adapters for converting STM-side structures to Halo2 circuit witness structures.

use digest::Digest;
use thiserror::Error;

use crate::circuits::halo2::types::{MerklePath as Halo2MerklePath, Position};
use crate::membership_commitment::MerklePath as StmMerklePath;
use crate::signature_scheme::BaseFieldElement;

/// Errors returned when adapting STM Merkle paths to Halo2 witness paths.
#[derive(Debug, Error)]
pub enum MerklePathAdapterError {
#[error("invalid merkle digest length")]
InvalidDigestLength,
#[error("non-canonical merkle digest")]
NonCanonicalDigest,
}

impl<D: Digest> TryFrom<&StmMerklePath<D>> for Halo2MerklePath {
type Error = MerklePathAdapterError;

fn try_from(stm_path: &StmMerklePath<D>) -> Result<Self, Self::Error> {
let mut siblings = Vec::with_capacity(stm_path.values.len());

for (i, value) in stm_path.values.iter().enumerate() {
let bytes: [u8; 32] = value
.as_slice()
.try_into()
.map_err(|_| MerklePathAdapterError::InvalidDigestLength)?;
let node = BaseFieldElement::from_bytes(&bytes)
.ok()
.map(|base| base.into())
.ok_or(MerklePathAdapterError::NonCanonicalDigest)?;
let bit = (stm_path.index >> i) & 1;
// At level `i`, `bit = (index >> i) & 1`: `0` means current is left, `1` means right.
// STM uses `H(current || sibling)` for `bit == 0`, else `H(sibling || current)`.
// Map `0 -> Position::Right` and `1 -> Position::Left` so Halo2 folds identically.
let position = if bit == 0 {
Position::Right
} else {
Position::Left
};
siblings.push((position, node));
}

Ok(Halo2MerklePath::new(siblings))
}
}
Loading
Loading