<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Andrei Kochergin</title>
    <description>The latest articles on DEV Community by Andrei Kochergin (@yoozzeek).</description>
    <link>https://dev.to/yoozzeek</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3337199%2Ff68cbe9d-85bf-4492-8ca1-66f55b0a7145.jpg</url>
      <title>DEV Community: Andrei Kochergin</title>
      <link>https://dev.to/yoozzeek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yoozzeek"/>
    <language>en</language>
    <item>
      <title>I built a Lisp VM in Rust that proves its own execution trace (STARKs + Winterfell)</title>
      <dc:creator>Andrei Kochergin</dc:creator>
      <pubDate>Mon, 24 Nov 2025 11:00:00 +0000</pubDate>
      <link>https://dev.to/yoozzeek/i-built-a-lisp-vm-in-rust-that-proves-its-own-execution-trace-starks-winterfell-4fi</link>
      <guid>https://dev.to/yoozzeek/i-built-a-lisp-vm-in-rust-that-proves-its-own-execution-trace-starks-winterfell-4fi</guid>
      <description>&lt;p&gt;Over the last few weeks I've been building an 8-register VM in Rust for a small Lisp-like DSL, plus a proof pipeline that turns programs into STARK proofs of execution.&lt;/p&gt;

&lt;p&gt;The DSL is compiled by the &lt;code&gt;zk-lisp-compiler&lt;/code&gt; crate into a compact Op sequence, and proofs are generated through a dedicated backend built on top of the &lt;strong&gt;winterfell&lt;/strong&gt; crate.&lt;/p&gt;

&lt;p&gt;A few details that might be interesting from a Rust/efficiency point of view:&lt;/p&gt;

&lt;h2&gt;
  
  
  Trace Layout &amp;amp; Generation
&lt;/h2&gt;

&lt;p&gt;I defined a unified execution trace (VM registers, RAM tables, Merkle gadget, Poseidon2 lanes, ROM accumulator) in a single &lt;code&gt;Columns&lt;/code&gt; layout. The &lt;code&gt;VmTraceBuilder&lt;/code&gt; simulates the Op sequence, seeds registers, and fills a Winterfell &lt;code&gt;TraceTable&lt;/code&gt; while keeping allocations predictable (pre-zeroed trace, cached Poseidon2 params, partition selection).&lt;/p&gt;

&lt;h2&gt;
  
  
  Multi-segment Execution
&lt;/h2&gt;

&lt;p&gt;The backend implements a &lt;code&gt;SegmentPlanner&lt;/code&gt; that cuts the padded trace into level-aligned segments under a &lt;code&gt;max_segment_rows&lt;/code&gt; budget. The interesting part was remapping the unified &lt;code&gt;Columns&lt;/code&gt; into per-segment traces and computing state hashes at boundaries for chaining without fighting the borrow checker too much.&lt;/p&gt;

&lt;h2&gt;
  
  
  STARK-in-STARK Recursion
&lt;/h2&gt;

&lt;p&gt;Recursion is expressed via generic traits (&lt;code&gt;RecursionBackend&lt;/code&gt;, &lt;code&gt;RecursionStepProver&lt;/code&gt;). The pipeline proves each execution segment, then runs an aggregation STARK over the resulting step proofs. This required some heavy generic bounds and type plumbing to keep the frontend (&lt;code&gt;zk-lisp-proof::frontend&lt;/code&gt;) fully backend-agnostic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;To prove the VM actually handles state transitions, here is a batch processor I wrote in zk-lisp. It calculates the new state root and total fees for a batch of transactions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight common_lisp"&gt;&lt;code&gt;&lt;span class="c1"&gt;;; Simple rollup-style benchmark for zk-lisp:&lt;/span&gt;
&lt;span class="c1"&gt;;; - N_ACCOUNTS balances in RAM&lt;/span&gt;
&lt;span class="c1"&gt;;; - N_TXS transfers (from, to, amt, fee)&lt;/span&gt;
&lt;span class="c1"&gt;;; - compute new balances and hash the state&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;N_ACCOUNTS&lt;/span&gt;       &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;N_TXS&lt;/span&gt;            &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="nv"&gt;HASH_BALANCES_IV&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;;; RAM layout:&lt;/span&gt;
&lt;span class="c1"&gt;;; [0 .. N_ACCOUNTS-1] = balances&lt;/span&gt;
&lt;span class="c1"&gt;;; [N_ACCOUNTS .. N_ACCOUNTS+4*N_TXS-1] =&lt;/span&gt;
&lt;span class="c1"&gt;;;     tx data (from, to, amt, fee) per tx&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;init_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;;; Initialize account balances [0 .. N_ACCOUNTS-1].&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt; &lt;span class="ss"&gt;:max&lt;/span&gt; &lt;span class="nv"&gt;N_ACCOUNTS&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;begin&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;recur&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

  &lt;span class="c1"&gt;;; Initialize tx table [tx_base .. tx_base + 4*N_TXS-1].&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt; &lt;span class="ss"&gt;:max&lt;/span&gt; &lt;span class="nv"&gt;N_TXS&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;base&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;begin&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="nv"&gt;base&lt;/span&gt;       &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;;; from&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;base&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;;; to&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;base&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;;; amount&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;base&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;;; fee&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;recur&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;N_ACCOUNTS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_from&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_to&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_amount&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_fee&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Safe arithmetic helpers (wrapping into field but&lt;/span&gt;
&lt;span class="c1"&gt;;; using safe-add/safe-sub to enforce non-negative balances).&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;apply_tx&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;from&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_from&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_to&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;begin&lt;/span&gt;
      &lt;span class="c1"&gt;;; Debit sender: from_bal - (amt + fee)&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;safe-sub&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;safe-add&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_amount&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_fee&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
      &lt;span class="c1"&gt;;; Credit receiver: to_bal + amt&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;store&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;safe-add&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_amount&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="c1"&gt;;; Return fee&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;tx_fee&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Loop over all N_TXS, accumulate total fee&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;apply_batch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt; &lt;span class="ss"&gt;:max&lt;/span&gt; &lt;span class="nv"&gt;N_TXS&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;fee_sum&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;fee_sum&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;recur&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;safe-add&lt;/span&gt; &lt;span class="nv"&gt;fee_sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;apply_tx&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="c1"&gt;;; Simple Poseidon2-based hash chain over balances&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;hash_balances&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;loop&lt;/span&gt; &lt;span class="ss"&gt;:max&lt;/span&gt; &lt;span class="nv"&gt;N_ACCOUNTS&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;h&lt;/span&gt; &lt;span class="nv"&gt;HASH_BALANCES_IV&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;h&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;recur&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;hash2&lt;/span&gt; &lt;span class="nv"&gt;h&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;load&lt;/span&gt; &lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;typed-fn&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;bytes32&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="nv"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;bytes32&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;def&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="nv"&gt;expected_fee_sum&lt;/span&gt; &lt;span class="nv"&gt;expected_root&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;begin&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;init_state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nv"&gt;fee_sum&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;apply_batch&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;root&lt;/span&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;hash_balances&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;begin&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;fee_sum&lt;/span&gt; &lt;span class="nv"&gt;expected_fee_sum&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;assert&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;root&lt;/span&gt; &lt;span class="nv"&gt;expected_root&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="p"&gt;))))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This program compiles down to the VM opcodes, and Winterfell generates a proof attesting that "I know a list of valid transactions that result in this state root" without revealing the transactions themselves.&lt;/p&gt;

&lt;p&gt;It's still a prototype (AGPL-3.0), but I'd really appreciate feedback on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the trait structure around &lt;code&gt;ZkBackend&lt;/code&gt; / recursion&lt;/li&gt;
&lt;li&gt;whether the trace planner + VM trace builder design makes sense from a performance perspective&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Repo: &lt;a href="https://github.com/yoozzeek/zk-lisp" rel="noopener noreferrer"&gt;https://github.com/yoozzeek/zk-lisp&lt;/a&gt;&lt;/p&gt;

</description>
      <category>computerscience</category>
      <category>performance</category>
      <category>web3</category>
      <category>rust</category>
    </item>
    <item>
      <title>Smart engineers are no longer needed</title>
      <dc:creator>Andrei Kochergin</dc:creator>
      <pubDate>Wed, 13 Aug 2025 03:46:12 +0000</pubDate>
      <link>https://dev.to/yoozzeek/smart-engineers-are-no-longer-needed-3a08</link>
      <guid>https://dev.to/yoozzeek/smart-engineers-are-no-longer-needed-3a08</guid>
      <description>&lt;p&gt;In the ’70s and earlier, when conditions were harsh, the pioneers of computing knew exactly where every bit went. That hardware limitations made compute far more costly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrrx319wl75m0dya8gyp.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrrx319wl75m0dya8gyp.JPG" alt="Meme developers then and now" width="800" height="725"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Just look at this:&lt;/p&gt;

&lt;p&gt;🚀 Apollo Guidance Computer (Lunar Module, Moon landing):&lt;br&gt;
~72KB of fixed “core‑rope” memory for program code&lt;br&gt;
~4KB of erasable RAM for variables/scratch space&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu5mgypta835q450s132.WEBP" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcu5mgypta835q450s132.WEBP" alt="Photo of the Apollo Guidance Computer" width="600" height="478"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🛰️ Voyager probes (launched in 1977). Both are still operational and sending telemetry. One of them is now 25 billion kilometers from Earth and it’s still talking to us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Command System (CCS): 2KB RAM + ~4KB ROM&lt;/li&gt;
&lt;li&gt;Flight Data Subsystem (FDS): 8KB RAM + ~8KB ROM (science &amp;amp; engineering data)&lt;/li&gt;
&lt;li&gt;Attitude &amp;amp; Articulation Control System (AACS): 2KB RAM + ~8KB ROM (controls orientation)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqe4283wwgzxc0dgo1ac9.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqe4283wwgzxc0dgo1ac9.JPG" alt="Voyager spacecraft during its assembly or preparation, with technicians working on it, likely involving the installation of the Voyager Golden Record" width="252" height="200"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;That’s it. No bloat. No margin for sloppiness. Precision was survival.&lt;/p&gt;

&lt;p&gt;Now? Every React component or Node.js package weighs 10KB+. LLMs spit out infinite SELECT loops, store raw or SHA256’d passwords, and somehow… your app still works. Some top investors, like Paul Graham in his recent X post cheer on vibecoders pumping out 10,000 lines a day like that’s the gold standard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://x.com/paulg/status/1953289830982664236" rel="noopener noreferrer"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbc00rq1n2ud2lp7a7i6n.jpg" alt="Screenshot of Paul Graham’s public X (Twitter) post about vibecoder that writes 10,000 lines of code a day now thanks to AI" width="800" height="1229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How can you not relax and forget the basics?&lt;/p&gt;

&lt;p&gt;I understand why nowadays many of my colleagues are frustrated by “vibe code” and next gen devs skipping the fundamentals. They think the basics are irrelevant now that LLMs can spit out code.&lt;/p&gt;

&lt;p&gt;But this cycle isn’t new:&lt;/p&gt;

&lt;p&gt;👴 In my (millennial) era “older” devs wrote PHP/Perl/Python engines from scratch, while I was so dummy that could only learning Joomla with its extensions, phpBB and HTML with CSS. “You don’t even know what’s under the hood!” I’d hear.&lt;/p&gt;

&lt;p&gt;👴 In the ‘80s, C programmers manually managed memory, scoffing at C++ and OOP as “toys” with “unnecessary abstraction.”&lt;/p&gt;

&lt;p&gt;👴 In the ‘60s, assembler veterans mocked FORTRAN and COBOL. “A compiler can’t optimize better than me!”&lt;/p&gt;

&lt;p&gt;The cycle repeats.&lt;/p&gt;

&lt;p&gt;But here’s what doesn’t change: the foundation. It’s the bedrock. It doesn’t shift with every new framework, hype wave, or trend.&lt;/p&gt;

&lt;p&gt;Learn it. Dig deep. Know what you’re building on. That’s how you stop being a consumer and become a creator.&lt;/p&gt;

&lt;p&gt;Because if you rely on LLMs without understanding the essence, you’re setting yourself up for failure.&lt;/p&gt;

&lt;p&gt;The people pushing “AI will replace you” are selling hype. CEOs, corporations, and investors who preach that you no longer need to learn? They’ll throw your future, your job, even the planet under the bus for a return and control.&lt;/p&gt;

&lt;p&gt;They have no ethical brakes.&lt;/p&gt;

&lt;p&gt;Think LLMs are like drugs: they give the illusion of power. They make you feel like you’re building something. But in the end, you’ll be left with vibes while they collect your time, your money, your talent.&lt;/p&gt;

&lt;p&gt;P.S. Of course, I also use LLM 💊, but only where it actually helps and doesn't hallucinate, overcomplicate (or "simplify" by suggesting rm -rf your-project): small scripts, simple examples, testing and documentation, study help, routine reviews, or fixing spelling in posts like this one. Not for real programming whether it’s a fresh project or some legacy beast.&lt;/p&gt;

&lt;p&gt;By the way, hi everyone! This is my first article on Dev.to. More technical posts coming soon, especially on Rust and security. Stay tuned.&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
