Skip to content

Extract arm_core crate: pure types with no risc0-zkvm or k256 deps#213

Merged
XuyangSong merged 12 commits into
developfrom
anthony/arm-crate-split
Apr 1, 2026
Merged

Extract arm_core crate: pure types with no risc0-zkvm or k256 deps#213
XuyangSong merged 12 commits into
developfrom
anthony/arm-crate-split

Conversation

@AHartNtkn

@AHartNtkn AHartNtkn commented Mar 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Introduces a new anoma-rm-core crate containing all types that can be expressed without risc0-zkvm or k256: Digest, ArmError, Resource, NullifierKey/Commitment, MerklePath, ComplianceInstance, ComplianceUnit, Action, Transaction, Delta, LogicInstance/AppData/ExpirableBlob/LogicVerifierInputs, and opaque DeltaProof/DeltaWitness byte wrappers
  • Constants are split: raw *_VK_BYTES arrays in arm_core, lazy_static Digest wrappers and ELF keys stay in arm
  • Extension traits (NullifierKeyExt, MerklePathExt, ActionExt, ComplianceUnitExt, TransactionExt, etc.) in arm add the zkvm/k256 operations on top of arm_core types

Dependency isolation verified

cargo tree -p anoma-rm-core | grep -E "risc0|k256"
# (no output)

Motivation

Follow-up to anthony/arm-dep-minimum (PR #206). The repo owner's feedback was that feature flags make maintenance harder because the same crate is used across circuits, clients, and multiple chains/servers. This PR replaces that approach with a proper crate split.

🤖 Generated with Claude Code

AHartNtkn and others added 3 commits March 2, 2026 13:17
Introduces a new `anoma-rm-core` crate containing all types that can
be expressed without risc0-zkvm or k256: Digest, ArmError, Resource,
NullifierKey/Commitment, MerklePath, ComplianceInstance, ComplianceUnit,
Action, Transaction, Delta, LogicInstance/AppData/ExpirableBlob, and
opaque DeltaProof/DeltaWitness byte wrappers. Constants are split into
raw byte arrays (arm_core) vs lazy_static Digest wrappers and ELF keys
(arm). Extension traits (NullifierKeyExt, MerklePathExt, ActionExt,
ComplianceUnitExt, TransactionExt, etc.) in arm add the zkvm/k256
operations on top of arm_core types.

`cargo tree -p anoma-rm-core | grep -E "risc0|k256"` produces no output.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…gic constants

- Delete `pub mod prelude` (verbatim duplicate of the crate-root trait re-exports)
- `hash_two`: stack array instead of Vec — eliminates one heap alloc per Merkle node
- `to_journal`: use `bytemuck::cast_vec` to reinterpret Vec<u32> in-place as Vec<u8>,
  avoiding a second allocation on every compliance proof verification
- `get_logic_verifiers`: drop intermediate `compliance_intances` clone Vec; iterate
  `compliance_units` directly and replace `vec![a, b]` flat_maps with `[a, b]` arrays
- `padding_leaf()`: delegate to `initial_root()` — removes the duplicate
  `Digest::try_from(EMPTY_HASH_BYTES)` decode
- `COMMITMENT_TREE_DEPTH`: replace magic `10` with a named pub const
- `NullifierKeyExt::random_pair`: use `DIGEST_BYTES` instead of bare `32`
- `LogicVerifierInputs` in `logic_proof`: private use (already re-exported at crate root)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AHartNtkn and others added 6 commits March 2, 2026 14:48
- arm_test_app: import LogicVerifierInputs from crate root, not
  logic_proof module (which was made private during simplify)
- compliance: revert cast_vec back to words_to_bytes().to_vec();
  bytemuck::cast_vec panics at runtime for u32->u8 in version 1.23.2

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bytemuck::from_bytes requires the input &[u8] to be aligned to
align_of::<[u32; 8]>() = 4. Byte slices from constants and Vec<u8>
carry only 1-byte alignment, which panics on aarch64 (CI) but passes
by coincidence on x86_64 (local dev).

Replace with u32::from_ne_bytes in a loop: no alignment requirement,
same byte interpretation as bytemuck::cast_slice. Also deduplicate
FromHex by delegating to TryFrom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DeltaWitness::Serialize uses serialize_bytes which writes a u64 length
prefix in bincode. DeltaWitness::Deserialize was reading [u8; 32] which
expects no prefix, causing silent data corruption on roundtrip.

Change Deserialize to use Vec::deserialize (matching what DeltaProof
already does), with an explicit length check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…merge

The cherry-pick of the bincode roundtrip tests left them with wrong
indentation and a stray closing brace, causing a parse error.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The cherry-pick of f73271b fixed the DeltaWitness Deserialize in
arm/src/delta_proof.rs but missed the identical bug in
arm_core/src/delta_types.rs (the opaque newtype version).

serialize_bytes writes a u64 length prefix; <[u8; 32]>::deserialize
reads raw bytes without it, corrupting the byte stream. Use
Vec::deserialize + try_into, matching what DeltaProof already does.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@AHartNtkn AHartNtkn requested a review from XuyangSong March 3, 2026 21:05
Provides a canonical conversion from structured ComplianceInstance
to the u32 word array representation used by the aggregation circuit.
Eliminates the need for downstream consumers to hand-roll field-by-field
copies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

@XuyangSong XuyangSong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Thank you for the work!
I’ve also left a comment about the constants dependency issue.
Could you help add a README for the arm_core crate too?

Comment thread arm_core/src/constants.rs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@XuyangSong XuyangSong changed the base branch from main to develop April 1, 2026 10:17
Resolved conflicts in arm/src/action.rs and arm/src/transaction.rs:
- action.rs: dropped develop's duplicate verify/delta/get_delta_msg methods
  (already provided by ActionExt trait); changed verify signature to &self
- transaction.rs: kept crate-split architecture (DeltaProof::from_bytes,
  non-Result get_delta_msg); changed verify signature to &self to match
- delta_proof.rs: auto-merged (mod tests reorganization)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@XuyangSong XuyangSong merged commit ceabfa4 into develop Apr 1, 2026
6 checks passed
@github-project-automation github-project-automation Bot moved this from Triage to Released in Anoma SDK - What's Cooking Apr 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Released

Development

Successfully merging this pull request may close these issues.

2 participants