Skip to content

apollo_starknet_os_program,starknet_os,blockifier: emit the proof-fact fold in the OS output - #15064

Open
einat-starkware wants to merge 1 commit into
claude/privacy-proof-os-verify-gsxf2h-4-cairo-tree-foldfrom
claude/privacy-proof-os-verify-gsxf2h-3-os-output
Open

einat-starkware wants to merge 1 commit into
claude/privacy-proof-os-verify-gsxf2h-4-cairo-tree-foldfrom
claude/privacy-proof-os-verify-gsxf2h-3-os-output

Conversation

@einat-starkware

@einat-starkware einat-starkware commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Part 5 of the privacy proof-fact fold stack, on top of #15093 (the stack bottom was split into #15090#15091#15092#15093 per review feedback). Implements the decision that the block-root fold continues in the Starknet aggregator.

OS side (per block):

  • Each invoke transaction's proof facts — the same pointers check_proof_facts already validated, so the §4.5 binding-by-construction holds — are recorded during execution via a new proof_facts_references implicit, threaded only through the execute_transactions chain (not the syscall layer, and without touching OsCarriedOutputs/the revert-dummy hint). Reverted transactions are included: their facts are part of the block and their proofs were verified regardless of the revert.
  • At block end the OS folds the recorded references into the block's root entry and emits (proof_facts_root_output_low/high, n_proof_facts_transactions) in OsOutputHeader — the root output digest packed as Uint256 low/high halves (the same composition encode_felt252_data_and_calc_blake2s uses). A block with no contributing transactions emits zeros and is skipped by higher folds; the virtual OS always emits zeros (it rejects proof facts; asserted).

Combine side (multiblock OS + aggregator, one implementation):

  • combine_blocks collects the contributing blocks' root entries (unpacking with range checks; all entries are multiverifier nodes since a block always folds to one entry), folds them pairwise with the carry rule — a lone block root is carried, not self-folded — and emits the combined values. This defines the hierarchical block→multiblock tree shape the proving side must mirror; a linear fold was rejected since it would serialize upstream proving.

Rust: output parsing + CommonOsOutput fields, the aggregator header writer, mirrors of the combine fold and digest packing, and flow-test assertions comparing the OS's emitted fold against the Rust mirror end to end (multi-block, multiple contributing transactions).

Protocol-visible changes: OsOutputHeader.SIZE 9 → 12; OS/virtual-OS/aggregator program hashes and bytecode pins regenerated; os_resources +14 steps per invoke (the recording cost); the new virtual-OS hash replaces the older allowed_virtual_os_program_hashes entry, keeping the current one so the committed proof fixtures stay valid without re-proving.

Verified: all three Cairo programs compile; starknet_os 275/275; apollo_starknet_os_program 6/6; flow tests 115/115; clippy clean.

Flagged for review: the aggregator program now reaches blake_with_opcode on its execution path (when blocks contribute proof facts) — its proving layout must support the blake opcode (e.g. stwo's all_cairo_stwo); if the aggregator is proven under a layout without it, the fold should switch to the builtin-based blake2s (digests unchanged, bitwise builtin needed).

🤖 Generated with Claude Code

https://claude.ai/code/session_01XmPJM3Wph4QLmFmhcxVsh4

@cursor

cursor Bot commented Aug 27, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Changes core OS/aggregator output layout and Cairo folding logic on the privacy attestation path; downstream parsers, provers, and L1 consumers must handle the new header fields and regenerated program hashes.

Overview
Adds proof-fact fold results to the Starknet OS public output so privacy invoke transactions’ verified proof facts are committed in a digest the prover can match.

Per block: invoke execution records non-empty proof facts (including on reverts) via a new proof_facts_references implicit; after txs, fold_recorded_proof_facts builds the block root and OsOutputHeader gains proof_facts_root_output_low/high, n_proof_facts_transactions, plus three serialized words. Virtual OS always emits zeros.

Multi-block / aggregator: combine_blocks skips blocks with no contributors, unpacks packed block roots with range checks, folds with the carry rule (single block root not self-folded), and writes the combined fold into the final header after the linear merge.

Rust & protocol: output parsing, aggregator header wiring, pack_output_digest / fold_block_root_entries mirrors, and flow tests assert against expected folds. OsOutputHeader.SIZE 9→12, OS/virtual-OS/aggregator program hashes and bytecode pins updated, allowed virtual OS hash list rotated (+14 invoke OS steps in versioned constants).

Reviewed by Cursor Bugbot for commit 93f03f6. Bugbot is set up for automated code reviews on this repo. Configure here.

@reviewable-StarkWare

Copy link
Copy Markdown

This change is Reviewable

@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from 93dfeeb to 811a6c1 Compare September 2, 2026 11:43
@einat-starkware
einat-starkware changed the base branch from claude/privacy-proof-os-verify-gsxf2h-2-cairo-fold to claude/privacy-proof-os-verify-gsxf2h-4-cairo-tree-fold September 2, 2026 11:43
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch 2 times, most recently from cb06bb9 to d1023d1 Compare September 2, 2026 12:29
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from d1023d1 to 7cc17ba Compare September 2, 2026 12:45
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from 7cc17ba to cb470b4 Compare September 2, 2026 13:11
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from cb470b4 to 96dd329 Compare September 2, 2026 13:41
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from 96dd329 to 5f9bd84 Compare September 17, 2026 13:36
…t fold in the OS output

Wires the privacy proof-fact fold into the OS and its output, per the decision
that the block-root fold continues in the Starknet aggregator:

- During execution, each invoke transaction's validated proof facts are
  recorded (reverted transactions included - their facts are part of the block)
  via a new proof_facts_references implicit, threaded only through the
  execute_transactions chain.
- At block end the OS folds the recorded references into the block's root
  entry and emits (proof_facts_root_output_low/high, n_proof_facts_transactions)
  in OsOutputHeader - the digest packed as the Uint256 low/high halves. Blocks
  with no contributing transactions emit zeros; the virtual OS always does (it
  rejects proof facts).
- combine_blocks - shared by the multi-block OS and the aggregator - folds the
  contributing blocks' root entries pairwise (a lone block root is carried, not
  self-folded) and emits the combined values, defining the multiblock tree
  shape the proving side must mirror.
- Rust: output parsing, the aggregator header writer, mirrors of the combine
  fold and digest packing, and flow-test assertions comparing the OS's emitted
  fold against the Rust mirror end to end.

Program hashes, bytecode-length pins, and the os_resources measurements are
regenerated (+14 steps per invoke); the new virtual OS hash replaces the older
allowed_virtual_os_program_hashes entry, keeping the current one so committed
proof fixtures stay valid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XmPJM3Wph4QLmFmhcxVsh4
@einat-starkware
einat-starkware force-pushed the claude/privacy-proof-os-verify-gsxf2h-3-os-output branch from 5f9bd84 to 93f03f6 Compare September 22, 2026 09:22

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants