{"id":15673962,"url":"https://github.com/sshine/triton-vm-slides","last_synced_at":"2026-03-18T17:38:37.212Z","repository":{"id":152860709,"uuid":"618664294","full_name":"sshine/triton-vm-slides","owner":"sshine","description":"Slides for Rust meetup talk: Programming on Triton VM","archived":false,"fork":false,"pushed_at":"2023-04-10T19:45:43.000Z","size":8825,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-30T05:44:24.931Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sshine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-03-25T01:41:07.000Z","updated_at":"2023-04-10T20:34:12.000Z","dependencies_parsed_at":"2023-07-06T18:32:55.624Z","dependency_job_id":null,"html_url":"https://github.com/sshine/triton-vm-slides","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sshine/triton-vm-slides","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Ftriton-vm-slides","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Ftriton-vm-slides/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Ftriton-vm-slides/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Ftriton-vm-slides/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sshine","download_url":"https://codeload.github.com/sshine/triton-vm-slides/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sshine%2Ftriton-vm-slides/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29677881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T06:23:40.028Z","status":"ssl_error","status_checked_at":"2026-02-21T06:23:39.222Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T15:43:15.556Z","updated_at":"2026-02-21T09:01:19.597Z","avatar_url":"https://github.com/sshine.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"\n![triton-logo.png](./images/triton-logo.png)\n\n### Practical zk\n### applications of\n# Triton VM\n\nSimon Shine\nMarch 30, 2023\n\n---\n\nSlides available on:\nhttps://github.com/sshine/triton-vm-slides\n\nFeel free to interrupt with questions.\n\n---\n\n### About me\n\n- 2021: Penneo\n- 2022: [neptune.cash](https://neptune.cash): zk-STARKs\n- 2023: [nerve smart systems.com](https://nervesmartsystems.com):\n\tHigh-power battery EV chargers\n\n![nerve-logo.png](./images/nerve-logo.png) ![neptune-logo.png](./images/neptune-logo.png)\n\nI've been 🦀'ing out for 16 months now\n\n---\n\n### Summary of talk\n\n1. Zero-knowledge protocols (examples, uses)\n2. Turning problems into polynomials (briefly)\n3. Turning a set of VM instructions into equations\n4. Zero-knowledge protocols (assembly edition)\n5. Abusing the `syn` package: \"Rust\" on Triton VM\n\n---\n\n### Part 1:\n#### Zero-knowledge protocols\n\n---\n\nWhere's Wally?\n![wheres-wally.png](./images/wheres-wally.png)\n\n---\n\nzudoku.xyz by Ferdinand Sauer (CC-BY 4.0)\n![zudoku-1.png](./images/zudoku-1.png)\n\n---\n\nzudoku.xyz by Ferdinand Sauer (CC-BY 4.0)\n![zudoku-2.png](./images/zudoku-2.png)\n\n---\n\nzudoku.xyz by Ferdinand Sauer (CC-BY 4.0)\n![zudoku-3.png](./images/zudoku-3.png)\n\n---\n\nQuestions so far?\n\n---\n\nWhen are zk protocols valuable for society?\n\nThey let us prove quantified\nrisk with privacy enabled.\n\n---\n\nLoan / insurance scoring without leaking...\n- how much you earn\n- when and what you buy\n- when, where and how fast you go\n- your heart rate, cholesterol, blood sugar\n\n---\n\nHow do you translate this into computer problems?\n\nUsing polynomials.\n\n---\n\n### Part 2:\n#### Turning problems into polynomials\n\n---\n\nProve you know the millionth Fibonacci number\n(without revealing the calculation or the number)\n\n$\\Updownarrow$\n\nProve you know a polynomial $P(x)$ that represents\nthe output of $Fib(x)$ at step $x$ of its execution\n(without revealing $P(x)$ for $x$ from 1 to 1 million)\n\n$$P(x) = \\text{the } x \\text{'th Fibonacci number}$$\n\n...in fewer than 1 million steps!\n\n---\n\nA constraint checking polynomial $C(x)$:\n\n$C(y) = 0$ when $P(x) = Fib(x)$\n\n$\\Downarrow$\n\nProve you know a polynomial $C(y)$ where\n$C(P(x)) = 0$ for all $x$ from 1 to 1 million\n\n---\n\nHow to express the constraint for $Fib(x)$?\n\n$$\nFib(x) =\n\\begin{cases}\nFib(x-1) + Fib(x-2) \u0026 \\text{if } x\\geq 2 \\\\\n1              \u0026 \\text{if } x\\geq 1 \\\\\n0              \u0026 \\text{if } x\\geq 0 \\\\\n\\end{cases}\n$$\n\n---\n\n$P(x+2) = P(x+1) + P(x)$\n\n$\\Updownarrow$\n\n$P(x+2) - P(x+1) - P(x) = 0$\n\n$\\Updownarrow$\n\n$C(P(x), P(x+1), P(x+2))$\n\n$\\Updownarrow$\n\n$C_1(y_1,y_2,y_3) = y_3 - y_2 - y_1$\n\n---\n\nLet's invent some more polynomials:\n\n$Z(x) = (x-1)·(x-2)·(x-3)·🧐·(x-1\\text{ million})$\n\nClearly, $Z(x) = 0$ for all $x$ from 1 to 1 million.\n\n$\\Downarrow$\n\nProve you know polynomials $P(x)$ and $D(x)$ so\n\n$C(P(x)) = Z(x)·D(x)$\n\n(dividing a polynomial can happen with *long polynomial division*, or FFTs)\n\n---\n\n### Status\n\n- $C(P(x)) = Z(x)·D(x)$\n- Alice claims to have $C(P(1\\text{ million}))$\n- Bob knows $Z(x)$, their conviction needs $D(x)$.\n- Bob gives Alice sample $x$'es.\n- Alice gives Bob $D(x)$'es.\n- Bob believes Alice with some probability.\n- Repeat this process until the probability is astronomically likely.\n\n---\n\n![completely-different.png](./images/completely-different.png)\n\n...since we're 10% into the\nmath behind zk-STARKs.\n\n---\n\n### Part 3:\n#### Turning a set of VM instructions into equations\n\n---\n\n- `nop`\n\t- $ci_t = opcodes[nop]$\n\t- $clk_t + 1 = clk_{t+1}$\n\t- $pc_t + 1 = pc_{t+1}$\n- `add`\n\t- $stack[0]_{t+1} = stack[0]_t + stack[1]_t$\n\t- \"is a binary operation\"\n\t- \"does not modify memory\"\n- `push` $n$\n\t- $stack[0]_{t+1} = n$\n\t- $stack[1]_{t+1} = stack[0]_t$\n\n---\n\n![constraint-polynomial-examples.png](./images/constraint-polynomial-examples.png)\n\nhttps://triton-vm.org/spec/arithmetization.html\n\n---\n\n### Part 4:\n#### zk protocols (assembly edition)\n\n---\n\n### Prove $Fib(i)$\n\n```\n// Initialize stack: _ 0 1 i\nmain:\n  push 0\n  push 1\n  divine\n\n  call fib-loop\n  write_io // After loop, this is 0\n  write_io // After loop, this is Fib(i)\n  halt\n\nfib-loop:\n  dup0 skiz call fib-step\n  dup0 skiz recurse\n  return\n\n// Before: _ a b i\n// After: _ b (a+b) (i-1)\nfib-step:\n  push -1\n  add\n  swap2\n  dup1\n  add\n  swap1\n  swap2\n  return\n```\n\n---\n\n### Prove valid sudoku\n\nMade by Alexander Lemmens, Simon Shine\n\n```\nmain:\n  call initialize_primes\n  call read_sudoku\n  call initialize_flag\n  call write_sudoku_and_check_rows\n  call check_columns\n  call check_squares\n  push 0\n  read_mem\n  assert\n  halt\n\n// For mapping legal Sudoku digits to distinct primes. \n// Helps with checking consistency of rows, columns, and boxes. \n\ninitialize_primes:\n  push 1 push 2 write_mem pop\n  push 2 push 3 write_mem pop\n  push 3 push 5 write_mem pop\n  push 4 push 7 write_mem pop\n  push 5 push 11 write_mem pop\n  push 6 push 13 write_mem pop\n  push 7 push 17 write_mem pop\n  push 8 push 19 write_mem pop\n  push 9 push 23 write_mem pop\n  return\n\nread_sudoku:\n  call read9\n  call read9\n  call read9\n  call read9\n  call read9\n  call read9\n  call read9\n  call read9\n  call read9\n  return\n\nread9:\n  call read1\n  call read1\n  call read1\n  call read1\n  call read1\n  call read1\n  call read1\n  call read1\n  call read1\n  return\n\n// Applies the mapping from legal Sudoku digits to distinct primes.\n\nread1: // _\n  read_io // _ d\n  read_mem // _ d p\n  swap 1 // _ p d\n  pop // _ p\n  return\n\ninitialize_flag:\n  push 0\n  push 1\n  write_mem\n  pop\n  return\n\n// row0 row1 row2 row3 row4 row5 row6 row7 row8\nwrite_sudoku_and_check_rows:\n  push 9 // row0 row1 row2 row3 row4 row5 row6 row7 row8 9\n  call write_and_check_one_row // row0 row1 row2 row3 row4 row5 row6 row7 \n\t\t\t\t\t\t\t   // 18\n  call write_and_check_one_row // row0 row1 row2 row3 row4 row5 row6 27\n  call write_and_check_one_row // row0 row1 row2 row3 row4 row5 36\n  call write_and_check_one_row // row0 row1 row2 row3 row4 45\n  call write_and_check_one_row // row0 row1 row2 row3 54\n  call write_and_check_one_row // row0 row1 row2 63\n  call write_and_check_one_row // row0 row1 72\n  call write_and_check_one_row // row0 81\n  call write_and_check_one_row // 90\n  pop // ⊥\nreturn\n\nwrite_and_check_one_row: // s0 s1 s2 s3 s4 s5 s6 s7 s8 mem_addr\n  push 1 // s0 s1 s2 s3 s4 s5 s6 s7 s8 mem_addr 1\n  call multiply_and_write // s0 s1 s2 s3 s4 s5 s6 s7 (mem_addr+1) s8\n  call multiply_and_write // s0 s1 s2 s3 s4 s5 s6 (mem_addr+2) (s8·s7)\n  call multiply_and_write // s0 s1 s2 s3 s4 s5 (mem_addr+3) (s8·s7·s6)\n  call multiply_and_write // s0 s1 s2 s3 s4 (mem_addr+4) (s8·s7·s6·s5)\n  call multiply_and_write // s0 s1 s2 s3 (mem_addr+5) (s8·s7·s6·s5·s4)\n  call multiply_and_write // s0 s1 s2 (mem_addr+6) (s8·s7·s6·s5·s4·s3)\n  call multiply_and_write // s0 s1 (mem_addr+7) (s8·s7·s6·s5·s4·s3·s2)\n  call multiply_and_write // s0 (mem_addr+8) (s8·s7·s6·s5·s4·s3·s2·s1)\n  call multiply_and_write // (mem_addr+9) (s8·s7·s6·s5·s4·s3·s2·s1·s0)\n  push 223092870 // (mem_addr+9) (s8·s7·s6·s5·s4·s3·s2·s1·s0) 223092870\n  eq             // (mem_addr+9) (s8·s7·s6·s5·s4·s3·s2·s1·s0==223092870)\n  skiz           // (mem_addr+9)\n    return\n\n  push 0    // (mem_addr+9) 0\n  push 0    // (mem_addr+9) 0 0\n  write_mem // (mem_addr+9) 0\n  pop       // (mem_addr+9)\n  return\n\n  \n\nmultiply_and_write: // s mem_addr acc\n  dup 2     // s mem_addr acc s\n  mul       // s mem_addr (acc·s)\n  swap 1    // s (acc·s) mem_addr\n  push 1    // s (acc·s) mem_addr 1\n  add       // s (acc·s) (mem_addr+1)\n  swap 1    // s (mem_addr+1) (acc·s)\n  swap 2    // (acc·s) (mem_addr+1) s\n  write_mem // (acc·s) (mem_addr+1)\n  swap 1    // (mem_addr+1) (acc·s)\n  return\n\ncheck_columns:\n  push 1\n  call check_one_column\n  push 2\n  call check_one_column\n  push 3\n  call check_one_column\n  push 4\n  call check_one_column\n  push 5\n  call check_one_column\n  push 6\n  call check_one_column\n  push 7\n  call check_one_column\n  push 8\n  call check_one_column\n  push 9\n  call check_one_column\n  return\n\n  \n\ncheck_one_column:\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  call get_column_element\n  pop\n  call check_9_numbers\n  return\n\n  \n\nget_column_element:\n  push 9\n  add\n  read_mem\n  swap 1\n  return\n\ncheck_squares:\n  push 10\n  call check_one_square\n  push 13\n  call check_one_square\n  push 16\n  call check_one_square\n  push 37\n  call check_one_square\n  push 40\n  call check_one_square\n  push 43\n  call check_one_square\n  push 64\n  call check_one_square\n  push 67\n  call check_one_square\n  push 70\n  call check_one_square\n  return\n\ncheck_one_square:\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  push 7\n  add\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  push 7\n  add\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  push 1\n  add\n  read_mem\n  swap 1\n  pop\n  call check_9_numbers\n  return\n\ncheck_9_numbers:\n  mul\n  mul\n  mul\n  mul\n  mul\n  mul\n  mul\n  mul // 223092870 = 2·3·5·7·11·13·17·19·23\n  push 223092870\n  eq\n  skiz\n    return\n  push 0\n  push 0\n  write_mem\n  pop\n  return\n```\n\n---\n\n### Learn more\n\nVitalik Buterin's tutorial part 1:\n- https://vitalik.ca/general/2017/11/09/starks_part_1.html\n\nAlan Szepieniec's tutorials:\n- https://aszepieniec.github.io/stark-anatomy/\n- https://aszepieniec.github.io/stark-brainfuck/\n\nFerdinand Sauer's talk: How to build a zk-VM\n- https://www.youtube.com/watch?v=Nz4OYntBVMg\n\nAndrew Milson's miniSTARK:\n- https://github.com/andrewmilson/ministark\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshine%2Ftriton-vm-slides","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsshine%2Ftriton-vm-slides","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsshine%2Ftriton-vm-slides/lists"}