<?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: Maksim Ryndin</title>
    <description>The latest articles on DEV Community by Maksim Ryndin (@maksim_ryndin_a8a74309698).</description>
    <link>https://dev.to/maksim_ryndin_a8a74309698</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%2F1801536%2Fe1380cce-7ba4-45ba-b44d-a7d70f5ccd78.jpg</url>
      <title>DEV Community: Maksim Ryndin</title>
      <link>https://dev.to/maksim_ryndin_a8a74309698</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maksim_ryndin_a8a74309698"/>
    <language>en</language>
    <item>
      <title>Cairo for Rust devs I (verifiable computation)</title>
      <dc:creator>Maksim Ryndin</dc:creator>
      <pubDate>Tue, 30 Jul 2024 11:29:07 +0000</pubDate>
      <link>https://dev.to/maksim_ryndin_a8a74309698/cairo-for-rust-devs-i-verifiable-computation-2op2</link>
      <guid>https://dev.to/maksim_ryndin_a8a74309698/cairo-for-rust-devs-i-verifiable-computation-2op2</guid>
      <description>&lt;p&gt;This is a series of articles about &lt;a href="https://www.cairo-lang.org/" rel="noopener noreferrer"&gt;Cairo&lt;/a&gt; usually mentioned in the context of web3 and &lt;a href="https://www.starknet.io/" rel="noopener noreferrer"&gt;Starknet&lt;/a&gt; smart contracts but here we would like to expose it as a language for creating provable and verifiable programs which allows you to outsource the computation in a trustless manner&lt;sup id="fnref1"&gt;1&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;It is a work-in-progress. Updates are expected. Experienced Caironautes are welcome to point out where I am wrong.&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Why Cairo when Rust is already so awesome&lt;/li&gt;
&lt;li&gt;
Cairo

&lt;ul&gt;
&lt;li&gt;Mind Map&lt;/li&gt;
&lt;li&gt;Setup&lt;/li&gt;
&lt;li&gt;Input and output&lt;/li&gt;
&lt;li&gt;Provers&lt;/li&gt;
&lt;li&gt;Proof&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;li&gt;References&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Cairo when Rust is already so awesome
&lt;/h2&gt;

&lt;p&gt;Let's say, you have a task of finding arbitrage opportunities between different currency markets&lt;sup id="fnref2"&gt;2&lt;/sup&gt;. You can model this problem via finding the negative cycle in the graph where vertices are currencies and edges are pair markets. The graph is directed and weighted where weights are logarithms of exchange rates. Bellman-Ford shortest path algorithm is usually applied in this case (we will focus on verifiable computation here and on the implementation in the next article so don't worry about the algorithm now).&lt;/p&gt;

&lt;p&gt;The time complexity of the algorithm is &lt;code&gt;O(|V||E|)&lt;/code&gt; (where &lt;code&gt;V&lt;/code&gt; is a set of vertices and &lt;code&gt;E&lt;/code&gt; is a set of edges) so you're going to outsource this computation for large graphs to a cloud provider but due to the money-related nature of the problem you want to make it reliably - you do want to verify the result without re-running the algorithm (i.e. be sure that the provider actually ran the binary with the algorithm). In other words, you want to ensure a &lt;em&gt;computational integrity&lt;/em&gt; via a &lt;em&gt;succinct&lt;/em&gt; verification of the output&lt;sup id="fnref3"&gt;3&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Hm... How would we make it?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1pxgvm3g831a2eq2yc5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1pxgvm3g831a2eq2yc5.jpg" alt="Surprised monkey" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The conventional thinking would suggest us to use hashing of binaries (actually hashes are the right direction) but wouldn't guarantee the unchanged runtime (memory can be changed), inputs can be changed. So traditional approaches focus on how to protect the binary and input from being tampered in any way. But there is always some room for cheating.&lt;/p&gt;

&lt;p&gt;To our relief brainy cryptographers have come up with various &lt;a href="https://en.wikipedia.org/wiki/Zero-knowledge_proof#Zero-Knowledge_Proof_protocols" rel="noopener noreferrer"&gt;proof schemes&lt;/a&gt;. In our example, the cloud provider is &lt;em&gt;a prover&lt;/em&gt; who runs the expensive computation and delivers the output and &lt;em&gt;the proof&lt;/em&gt;&lt;sup id="fnref4"&gt;4&lt;/sup&gt; to &lt;em&gt;the verifier&lt;/em&gt; (us). One of the latest state-of-the-art proof schemes is &lt;a href="https://eprint.iacr.org/2018/046" rel="noopener noreferrer"&gt;STARK&lt;/a&gt; which in layman's (my) terms basically records the computation execution trace which is then randomly sampled by verifier and checked against predefined constraints&lt;sup id="fnref5"&gt;5&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;It is possible to integrate this execution tracing into an existing Rust program using some of general STARK libraries (e.g. &lt;a href="https://github.com/facebook/winterfell" rel="noopener noreferrer"&gt;Winterfell&lt;/a&gt;) but it would require knowing the low-level things very well (see &lt;a href="https://github.com/facebook/winterfell?tab=readme-ov-file#usage" rel="noopener noreferrer"&gt;the example&lt;/a&gt; for very simple computation) and be sure that &lt;em&gt;all&lt;/em&gt; computations are traced (and all &lt;a href="https://reilabs.io/blog/zero-knowledge-systems-you-can-trust/" rel="noopener noreferrer"&gt;constraints&lt;/a&gt; are enforced).&lt;br&gt;
Would it be nice to abstract away the low-level complexities and work with a familiar Rust syntax? Welcome to Cairo!&lt;/p&gt;
&lt;h2&gt;
  
  
  Cairo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.cairo-lang.org/" rel="noopener noreferrer"&gt;Cairo&lt;/a&gt; is a language for creating programs which are allow to verify computations without re-running the program. Cairo is heavily inspired by Rust&lt;sup id="fnref6"&gt;6&lt;/sup&gt; (move semantics and ownership, traits, core types, tooling) but due to the nature of verifiable computation the underlying machinery (memory model and a non-deterministic execution) is completely different. Our knowledge of Rust should help to quickly get used to the syntax and control flow but we should be careful when thinking over the computation.&lt;/p&gt;
&lt;h3&gt;
  
  
  Mind map
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rust&lt;/th&gt;
&lt;th&gt;Cairo&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rustc&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/starkware-libs/cairo" rel="noopener noreferrer"&gt;cairo&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;compiler&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;cargo&lt;/td&gt;
&lt;td&gt;&lt;a href="https://docs.swmansion.com/scarb/" rel="noopener noreferrer"&gt;scarb&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;multitool (dependencies, build, test)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cargo.toml&lt;/td&gt;
&lt;td&gt;Scarb.toml&lt;/td&gt;
&lt;td&gt;project configuration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rustup&lt;/td&gt;
&lt;td&gt;&lt;a href="https://asdf-vm.com/guide/getting-started.html" rel="noopener noreferrer"&gt;asdf&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;toolchain management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;crates.io&lt;/td&gt;
&lt;td&gt;&lt;a href="https://scarbs.xyz/" rel="noopener noreferrer"&gt;scarbs.xyz&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;package registry&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rust Playground&lt;/td&gt;
&lt;td&gt;&lt;a href="https://cairovm.codes/" rel="noopener noreferrer"&gt;cairovm.codes&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;online compilation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;I expect that you have Rust already installed. Let's also install &lt;a href="https://docs.swmansion.com/scarb/" rel="noopener noreferrer"&gt;scarb&lt;/a&gt; (&lt;code&gt;asdf&lt;/code&gt; is a recommended way) and make a project&lt;sup id="fnref7"&gt;7&lt;/sup&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb new bellman_ford_cairo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we open the generated repository (there is the official &lt;a href="https://marketplace.visualstudio.com/items?itemName=starkware.cairo1" rel="noopener noreferrer"&gt;VS code extension&lt;/a&gt;&lt;sup id="fnref8"&gt;8&lt;/sup&gt; to highlight the syntax), we will see the familiar structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Input and output
&lt;/h3&gt;

&lt;p&gt;Let think on the input of data. In the context of a pricing data and different currency pairs we can expect a sparse graph. So a lean representation would be to use a vector of tuples &lt;code&gt;Vec&amp;lt;(String, String, f32)&amp;gt;&lt;/code&gt; where strings denote currency names (like USD or EUR) and &lt;code&gt;f32&lt;/code&gt; is an exchange rate. All sounds good except... except some minor things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;There are no utf8 String's in Cairo - &lt;a href="https://book.cairo-lang.org/ch02-02-data-types.html#string-types" rel="noopener noreferrer"&gt;alternatives&lt;/a&gt; are short strings (up to 31 ascii bytes) and long strings (byte arrays of ascii bytes).&lt;/li&gt;
&lt;li&gt;There is no builtin dynamically growing modifiable array like &lt;code&gt;Vec&lt;/code&gt; in Rust (but with &lt;a href="https://community.starknet.io/t/cairo-v2-7-0-is-coming/114362" rel="noopener noreferrer"&gt;Cairo 2.7.0&lt;/a&gt; it is expected). There is an appendable-only (and poppable from the front) &lt;a href="https://github.com/starkware-libs/cairo/blob/main/corelib/src/array.cairo" rel="noopener noreferrer"&gt;&lt;code&gt;Array&lt;/code&gt;&lt;/a&gt; which can serve as a &lt;a href="https://github.com/keep-starknet-strange/alexandria/blob/main/packages/data_structures/src/queue.cairo" rel="noopener noreferrer"&gt;FIFO-queue&lt;/a&gt; and &lt;a href="https://github.com/starkware-libs/cairo/blob/main/corelib/src/dict.cairo" rel="noopener noreferrer"&gt;&lt;code&gt;Felt252Dict&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt; which can serve as a basis to implement library-defined &lt;a href="https://github.com/keep-starknet-strange/alexandria/blob/main/packages/data_structures/src/vec.cairo" rel="noopener noreferrer"&gt;&lt;code&gt;Vec&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;There are no floats in Cairo. So either we can revert to library-defined &lt;a href="https://github.com/influenceth/cubit/tree/main" rel="noopener noreferrer"&gt;fixed-point numbers&lt;/a&gt; or &lt;a href="https://github.com/keep-starknet-strange/alexandria/blob/main/packages/math/src/trigonometry.cairo" rel="noopener noreferrer"&gt;multiply input floats&lt;/a&gt; in advance by some integer constant and drop the fractional part.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And we also may stuck how to provide the input as there is no such thing as std wrappers to libc to read stdin or a file. It is like Rust in &lt;code&gt;#[no_std]&lt;/code&gt;. Let's investigate which options we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb cairo-run &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a section &lt;code&gt;Arguments&lt;/code&gt; which says that a program argument is "a JSON array of numbers, decimal bigints or recursive arrays of those" and the main function should have a corresponding signature (there is an example &lt;code&gt;[1, 2, [3, 4, 5]]` to `fn main(t: (u64, u64), v: Array&amp;lt;u64&amp;gt;)&lt;/code&gt;). So let's remove an example code from &lt;code&gt;lib.cairo&lt;/code&gt; and try the following &lt;code&gt;main&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of edges: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we encode currency names with &lt;code&gt;u16&lt;/code&gt; (they represent graph edges as a pair of vertices) and &lt;code&gt;felt252&lt;/code&gt; represents an exchange rate (a weight of the edge). Here we should talk a little bit more about the &lt;a href="https://eprint.iacr.org/2021/1063" rel="noopener noreferrer"&gt;CPU architecture&lt;/a&gt; which is expected by Cairo program. The machine word is 252 bits wide and is represented by &lt;code&gt;felt252&lt;/code&gt; type (&lt;strong&gt;F&lt;/strong&gt;ield &lt;strong&gt;El&lt;/strong&gt;emen*&lt;em&gt;t&lt;/em&gt;*, because of the underlying math). So every type is &lt;a href="https://docs.starknet.io/architecture-and-concepts/smart-contracts/serialization-of-cairo-types/" rel="noopener noreferrer"&gt;Serialization of Cairo types&lt;/a&gt; eventually represented via &lt;code&gt;felt252&lt;/code&gt;.  So basically the maximum number we can get is 252 bits and if we are going to encode floats by multiplying them with some integer constant, &lt;code&gt;felt252&lt;/code&gt; seems to be a right choice.&lt;/p&gt;

&lt;p&gt;Let's compile and run the program (think &lt;code&gt;cargo run&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb cairo-run &lt;span class="s2"&gt;"[[1, 2, 300]]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;number of edges: 1
Run completed successfully, returning &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works! Ok, what about an output? &lt;code&gt;returning []&lt;/code&gt; hints that we can try the same way as an input. We expect that the algorithm returns a path corresponding to the arbitrage opportunity. Let's try:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of edges: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;array!&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// path 1 -&amp;gt; 2 -&amp;gt; 3 -&amp;gt; 4&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;number of edges: 1
Run completed successfully, returning &lt;span class="o"&gt;[&lt;/span&gt;2837, 2841]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What??? &lt;em&gt;By the way, you may get another numbers as I did in other runs as the execution is non-deterministic.&lt;/em&gt; Let's first inspect &lt;a href="https://github.com/starkware-libs/cairo/blob/main/crates/cairo-lang-semantic/src/inline_macros/array.rs" rel="noopener noreferrer"&gt;&lt;code&gt;array!&lt;/code&gt; macro&lt;/a&gt;. We see that it is a code-generation plugin to the compiler which basically instantiate an array &lt;code&gt;ArrayTrait::new()&lt;/code&gt; and appends every element to it. Why &lt;code&gt;ArrayTrait&lt;/code&gt; and not just &lt;code&gt;Array&lt;/code&gt;? Digging further leads us to &lt;a href="https://github.com/starkware-libs/cairo/blob/main/corelib/src/array.cairo" rel="noopener noreferrer"&gt;&lt;code&gt;Array&lt;/code&gt;&lt;/a&gt; implementation. &lt;/p&gt;

&lt;p&gt;We cannot find a familiar &lt;code&gt;trait ArrayTrait&amp;lt;T&amp;gt;&lt;/code&gt; but there is again a macro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="nd"&gt;#[generate_trait]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;ArrayImpl&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;ArrayTrait&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Searching over the codebase of Cairo - and &lt;a href="https://github.com/starkware-libs/cairo/blob/main/crates/cairo-lang-plugins/src/plugins/generate_trait.rs" rel="noopener noreferrer"&gt;here&lt;/a&gt; it is. What does it generate? In Cairo defining methods for a type requires a trait as methods are &lt;a href="https://book.cairo-lang.org/ch05-03-method-syntax.html#defining-methods" rel="noopener noreferrer"&gt;defined only for a trait&lt;/a&gt;. So &lt;code&gt;#[generate_trait]&lt;/code&gt; reduces a boilerplate generating a corresponding trait definition out of the implementation for a type. You can always define a corresponding trait manually (e.g. check the library-implemented &lt;a href="https://github.com/keep-starknet-strange/alexandria/blob/main/packages/data_structures/src/queue.cairo" rel="noopener noreferrer"&gt;Queue&lt;/a&gt;). Thus the associated (i.e. doesn't require an instance) method &lt;code&gt;new&lt;/code&gt; is called on &lt;code&gt;ArrayTrait&lt;/code&gt;.&lt;br&gt;
Let's come back to the output. We do specify the output as &lt;code&gt;Array&amp;lt;u16&amp;gt;&lt;/code&gt;. And the output of 2 numbers instead of 4 suggests that we deal with some compact serialization scheme.&lt;br&gt;
Let's test this hypothesis with a bigger int and larger array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u128&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of edges: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="c1"&gt;// u128::MAX but there is not MAX const &lt;/span&gt;
    &lt;span class="c1"&gt;// for unsigned integers&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;340282366920938463463374607431768211455&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="nd"&gt;array!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;elem&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It again returns two numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;number of edges: 1
Run completed successfully, returning &lt;span class="o"&gt;[&lt;/span&gt;2845, 2851]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Damn! Notice that &lt;code&gt;2851 - 2845 = 6&lt;/code&gt; while earlier it was &lt;code&gt;2841 - 2837 = 4&lt;/code&gt; so it looks like slice bounds as it corresponds to the number of integers we hope to output. Let's find &lt;a href="https://github.com/starkware-libs/cairo/blob/main/crates/bin/cairo-run/src/main.rs" rel="noopener noreferrer"&gt;&lt;code&gt;Run completed successfully, returning&lt;/code&gt;&lt;/a&gt; in the compiler source code. It seems that &lt;code&gt;scarb&lt;/code&gt; runs this binary. And the output is &lt;a href="https://github.com/starkware-libs/cairo/blob/main/crates/cairo-lang-runner/src/lib.rs" rel="noopener noreferrer"&gt;&lt;code&gt;Vec&amp;lt;Felt252&amp;gt;&lt;/code&gt;&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="cd"&gt;/// The ran function return value.&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Debug,&lt;/span&gt; &lt;span class="nd"&gt;Eq,&lt;/span&gt; &lt;span class="nd"&gt;PartialEq,&lt;/span&gt; &lt;span class="nd"&gt;Clone)]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;RunResultValue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/// Run ended successfully, returning the memory of the non-implicit returns.&lt;/span&gt;
    &lt;span class="nf"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Felt252&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="cd"&gt;/// Run panicked, returning the carried error data.&lt;/span&gt;
    &lt;span class="nf"&gt;Panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Felt252&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"returning the memory of the non-implicit returns"... Here the hint - it's a memory. Cairo's &lt;a href="https://book.cairo-lang.org/ch11-02-smart-pointers.html?highlight=segmen#smart-pointers" rel="noopener noreferrer"&gt;memory model&lt;/a&gt; is a contiguous immutable array. Perhaps, these two &lt;code&gt;felt252&lt;/code&gt; numbers denote the start and end indices in the memory? &lt;code&gt;scarb cairo-run --help&lt;/code&gt; suggests an argument &lt;code&gt;--print-full-memory&lt;/code&gt;. Let's try that for the original program:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u16&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of edges: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;array!&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb cairo-run &lt;span class="s2"&gt;"[[1, 2, 300]]"&lt;/span&gt; &lt;span class="nt"&gt;--print-full-memory&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;number of edges: 1
Run completed successfully, returning &lt;span class="o"&gt;[&lt;/span&gt;2837, 2841]
Full memory: &lt;span class="o"&gt;[&lt;/span&gt;_, 290341444919459839, 1, 
... 
6744073709483335, 4130, 594, 4166, 500, 1, 2, 300, 49, 1997209042069643135709344952807065910992472029923670688473712229447419591075, 
0, 2463311330861459210825190905860592116187541770, 19, 
1, 2, 3, 4, &lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hm... Let's try to use &lt;code&gt;2837&lt;/code&gt; as an index to this "contiguous" array of memory. Just replace "_" with 0 (it is just to feed it into python) and let's feed the memory array into a python interpreter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&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="mi"&gt;290341444919459839&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="p"&gt;...&lt;/span&gt; 
&lt;span class="mi"&gt;6744073709483335&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;594&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4166&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;500&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;49&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1997209042069643135709344952807065910992472029923670688473712229447419591075&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="mi"&gt;2463311330861459210825190905860592116187541770&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2837&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2838&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2839&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2840&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="mi"&gt;4&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;memory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2841&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nc"&gt;Traceback &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;lt;stdin&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;IndexError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice. At least now we understand what these two numbers in the output mean - they denote output start and end indices in a memory array. Ok, but let's remember our initial goal - we need to outsource the computation and then be able to verify it. Perhaps, for that thing there is a more convenient way to get the output?&lt;sup id="fnref9"&gt;9&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Provers
&lt;/h3&gt;

&lt;p&gt;There are several provers for STARKs and some convenient wrappers for Cairo programs. I'm going to use &lt;a href="https://github.com/starkware-libs/stone-prover" rel="noopener noreferrer"&gt;Stone&lt;/a&gt; as it is the one &lt;a href="https://starkware.co/blog/unleashing-the-power-of-the-stone-prover/" rel="noopener noreferrer"&gt;used&lt;/a&gt; by Starknet. Let's try to prove and verify our program. The &lt;a href="https://github.com/starkware-libs/stone-prover?tab=readme-ov-file#creating-and-verifying-a-proof-of-a-cairo-program" rel="noopener noreferrer"&gt;readme&lt;/a&gt; provides an example.&lt;/p&gt;

&lt;p&gt;The prover requires a memory dump, a trace file and an AIR&lt;sup id="fnref10"&gt;10&lt;/sup&gt; input after the execution but &lt;code&gt;cairo-run&lt;/code&gt; cli doesn't expose these arguments.&lt;/p&gt;

&lt;p&gt;We haven't yet checked how our compiled "binary" looks like. Let's inspect &lt;code&gt;target&lt;/code&gt; directory. It contains &lt;code&gt;bellman_ford_cairo.sierra.json&lt;/code&gt;. It is our program as a Sierra intermediate representation, think as of LLVM IR. I wouldn't go into any details, just recommend &lt;a href="https://medium.com/nethermind-eth/under-the-hood-of-cairo-1-0-exploring-sierra-7f32808421f5" rel="noopener noreferrer"&gt;the articles&lt;/a&gt; by Mathieu Saugier&lt;/p&gt;

&lt;p&gt;We cannot run a json file. It should be compiled to a target:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;cairo assembly (casm) interpreted by &lt;a href="https://www.cairo-lang.org/resources/#virtual-machines" rel="noopener noreferrer"&gt;a cairo virtual machine&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/cryptonerdcn/wasm-cairo" rel="noopener noreferrer"&gt;wasm&lt;/a&gt; executed by wasm vm&lt;/li&gt;
&lt;li&gt;native host assembly - see &lt;a href="https://github.com/lambdaclass/cairo_native" rel="noopener noreferrer"&gt;cairo native&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we check what &lt;code&gt;cairo-run&lt;/code&gt; &lt;a href="https://github.com/starkware-libs/cairo/blob/main/Cargo.toml" rel="noopener noreferrer"&gt;uses&lt;/a&gt;, it is &lt;a href="https://github.com/lambdaclass/cairo-vm" rel="noopener noreferrer"&gt;a Rust vm&lt;/a&gt;. Let's clone the vm repository and run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cargo &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--bin&lt;/span&gt; cairo1-run &lt;span class="nt"&gt;--path&lt;/span&gt; cairo1-run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then we get a cairo vm interpreter and let's run this interpreter in our repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run src/lib.cairo &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to specify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.cairo-lang.org/how_cairo_works/builtins.html#layouts" rel="noopener noreferrer"&gt;the layout&lt;/a&gt; as we need &lt;a href="https://docs.cairo-lang.org/how_cairo_works/program_input_and_output.html#id2" rel="noopener noreferrer"&gt;an output&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;the public input (our graph) as the provider should prove to verifier that he/she knows an optimal route to the specific graph and not that he/she knows an optimal route to some undisclosed graph. In other words, our input is public.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we run the command above... we get an error:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;thread &lt;span class="s1"&gt;'main'&lt;/span&gt; panicked at cairo1-run/src/main.rs:181:18:
called &lt;span class="sb"&gt;`&lt;/span&gt;Result::unwrap&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt; on an &lt;span class="sb"&gt;`&lt;/span&gt;Err&lt;span class="sb"&gt;`&lt;/span&gt; value: Failed to find development corelib.
note: run with &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nv"&gt;RUST_BACKTRACE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1&lt;span class="sb"&gt;`&lt;/span&gt; environment variable to display a backtrace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So 1) there is some form of linking 2) if there is a development corelib, then there is a release one. There is an &lt;a href="https://github.com/lambdaclass/cairo-vm/tree/main/cairo1-run#running-scarb-projects" rel="noopener noreferrer"&gt;instruction&lt;/a&gt; in README for scarb projects - we can provide a Sierra program to the interpreter and add&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[cairo]&lt;/span&gt;
&lt;span class="py"&gt;enable-gas&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to &lt;code&gt;Scarb.toml&lt;/code&gt;&lt;sup id="fnref11"&gt;11&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;So let's try&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb &lt;span class="nt"&gt;--release&lt;/span&gt; build
&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/release/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we get... &lt;code&gt;Error: Runner(MissingMain)&lt;/code&gt;. &amp;gt;_&amp;lt;. Let's try the dev mode again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb build
&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/dev/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The error &lt;code&gt;Error: IlegalInputValue&lt;/code&gt;. Ah, we should provide an input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/dev/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="s2"&gt;"[[1, 2, 300]]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again in the readme "only allowed &lt;code&gt;Array&amp;lt;felt252&amp;gt;&lt;/code&gt; as return and input value in the proof mode". Ok, let's change the code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Array&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;felt252&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number of edges: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="nf"&gt;.len&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="nd"&gt;array!&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&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;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb build
&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/dev/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--args&lt;/span&gt; &lt;span class="s2"&gt;"[1 2 300]"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it works!!! Hooray!! There two other useful arguments: &lt;code&gt;--print_output&lt;/code&gt; and &lt;code&gt;--args_file&lt;/code&gt; that allow a readable output and a large input graph.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;graph.txt
&lt;span class="o"&gt;[&lt;/span&gt;1 2 300]
&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/dev/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--args_file&lt;/span&gt; graph.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--print_output&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 1997209042069643135709344952807065910992472029923670688473712229447419591075&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG] number of edges: 3
                &lt;span class="o"&gt;(&lt;/span&gt;raw: 2463311330861459210825190905860592116187542282&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 19                             &lt;span class="o"&gt;)&lt;/span&gt;

Program Output : &lt;span class="o"&gt;[&lt;/span&gt;1 2 3 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yeeeeee! Before finishing this section let's fix the release mode. As the dev profile works, it seems that there is a difference in profiles. It seems that &lt;a href="https://docs.swmansion.com/scarb/docs/reference/manifest.html#sierra-replace-ids" rel="noopener noreferrer"&gt;sierra-replace-ids&lt;/a&gt; affects this.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;Scarb.toml&lt;/code&gt; we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[cairo]&lt;/span&gt;
&lt;span class="py"&gt;enable-gas&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="py"&gt;sierra-replace-ids&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scarb &lt;span class="nt"&gt;--release&lt;/span&gt; build
&lt;span class="nv"&gt;$ &lt;/span&gt;cairo1-run target/release/bellman_ford_cairo.sierra.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;small &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_public_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--air_private_input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--trace_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;trace.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--memory_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;memory.bin &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--proof_mode&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--args_file&lt;/span&gt; graph.txt &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--print_output&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 1997209042069643135709344952807065910992472029923670688473712229447419591075&lt;span class="o"&gt;)&lt;/span&gt; 
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG] number of edges: 3
                &lt;span class="o"&gt;(&lt;/span&gt;raw: 2463311330861459210825190905860592116187542282&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;DEBUG]                                 &lt;span class="o"&gt;(&lt;/span&gt;raw: 19                             &lt;span class="o"&gt;)&lt;/span&gt;

Program Output : &lt;span class="o"&gt;[&lt;/span&gt;1 2 3 4]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is the same. Note &lt;code&gt;[DEBUG]&lt;/code&gt; output is related to &lt;code&gt;cairo1-run&lt;/code&gt;. In the repository we should now have files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;memory.bin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;private_input.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public_input.json&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;trace.bin&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It seems that we have all the artifacts to generate a proof.&lt;/p&gt;

&lt;h3&gt;
  
  
  Proof
&lt;/h3&gt;

&lt;p&gt;I've prepared a ready-to-use (and arm64 compatible!) &lt;a href="https://hub.docker.com/r/maksimryndin/starknet-stone" rel="noopener noreferrer"&gt;stone prover&lt;/a&gt; with Docker (thus you outsourced me the prover's compilation and I outsourced Docker image building to Github in a trusted way :)).&lt;/p&gt;

&lt;p&gt;Then in our repository run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/tmp maksimryndin/starknet-stone:latest prover &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-logtostderr&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--out_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/proof.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--private_input_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/private_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--public_input_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/public_input.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--prover_config_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/cpu_air_prover_config.json &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--parameter_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/cpu_air_params.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The files &lt;code&gt;cpu_air_prover_config.json&lt;/code&gt; and &lt;code&gt;cpu_air_params.json&lt;/code&gt; I took from Stone &lt;a href="https://github.com/starkware-libs/stone-prover/tree/main/e2e_test/Cairo" rel="noopener noreferrer"&gt;e2e test&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  what&lt;span class="o"&gt;()&lt;/span&gt;:  src/starkware/stark/stark.cc:187: Fri parameters &lt;span class="k"&gt;do &lt;/span&gt;not match stark degree bound. Expected FRI degree from FriParameters: 8192. STARK: 131072
Stack trace &lt;span class="o"&gt;(&lt;/span&gt;most recent call last&lt;span class="o"&gt;)&lt;/span&gt;:
&amp;lt;...&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you have any idea what it means? Me - no :)). Let's try to explore &lt;a href="https://github.com/starkware-libs/stone-prover/blob/main/src/starkware/stark/stark.cc" rel="noopener noreferrer"&gt;the source code&lt;/a&gt; of the prover. The number &lt;code&gt;131072&lt;/code&gt; denotes the actual degree - &lt;code&gt;trace_length&lt;/code&gt; attribute of &lt;a href="https://github.com/starkware-libs/stone-prover/blob/main/src/starkware/air/air.h" rel="noopener noreferrer"&gt;&lt;code&gt;Air&lt;/code&gt;&lt;/a&gt; class which seems to be instantiated from the statement. &lt;a href="https://github.com/starkware-libs/stone-prover/blob/main/src/starkware/main/cpu/cpu_air_prover_main.cc" rel="noopener noreferrer"&gt;The statement&lt;/a&gt; is a combination of public and private inputs, air parameters file. &lt;code&gt;8192&lt;/code&gt; denotes the expected which is calculated from &lt;code&gt;cpu_air_params.json&lt;/code&gt; with the function &lt;a href="https://github.com/starkware-libs/stone-prover/blob/main/src/starkware/stark/stark.cc" rel="noopener noreferrer"&gt;&lt;code&gt;GetFriExpectedDegreeBound&lt;/code&gt;&lt;/a&gt;. The sample &lt;code&gt;cpu_air_params.json&lt;/code&gt; is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PrimeField0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"fri_step_list"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"last_layer_degree_bound"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"n_queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"proof_of_work_bits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"log_n_cosets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"use_extension_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So &lt;code&gt;GetFriExpectedDegreeBound&lt;/code&gt; calculates it like &lt;code&gt;8192 = last_layer_degree_bound * 2.pow(0) * 2.pow(4) * 2.pow(3)&lt;/code&gt; or in logarithm base 2 terms: &lt;code&gt;log(trace_length) = log(last_layer_degree_bound) + ∑fri_step_list&lt;/code&gt; (this is almost &lt;a href="https://github.com/starkware-libs/stone-prover/tree/main?tab=readme-ov-file#configuration-for-other-input-sizes" rel="noopener noreferrer"&gt;the note&lt;/a&gt;). The error raises on testing an equality between an actual and an expected degrees. To tune the air configuration in a meaningful way we have to learn some theory but for now let's just add an additional FRI step of 4 to hold the equation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PrimeField0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stark"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"fri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"fri_step_list"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"last_layer_degree_bound"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"n_queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"proof_of_work_bits"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"log_n_cosets"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"use_extension_field"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we run the prover again (make sure to update memory and trace paths in &lt;code&gt;private_input.json&lt;/code&gt;), it outputs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;I0730 10:39:04.829474     1 profiling.cc:58] Prover started
I0730 10:39:05.030071     1 memory_cell.inl:121] Filled 12256 vacant slots &lt;span class="k"&gt;in &lt;/span&gt;memory: 171 holes and 12085 spares.
I0730 10:39:19.560891     1 stark.cc:425] Trace cells count:
Log number of rows: 17, first trace n_cols: 23, interaction trace n_cols: 2, Total trace cells: 3276800
I0730 10:40:03.643604     1 prover_main_helper_impl.cc:178] Byte count: 88424
Hash count: 1344
Commitment count: 6
Field element count: 1419
Data count: 1
I0730 10:40:03.658634     1 profiling.cc:85] Prover finished &lt;span class="k"&gt;in &lt;/span&gt;58.8287 sec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that total number of rows (&lt;code&gt;2.pow(17)&lt;/code&gt;) is &lt;code&gt;131072&lt;/code&gt;. And we can verify the computation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/tmp maksimryndin/starknet-stone:latest verifier &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-logtostderr&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--in_file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/tmp/proof.json
I0730 11:14:42.393836     1 cpu_air_verifier_main.cc:39] Proof verified successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article we learnt about verifiable computations with Cairo, compiled a basic program, explored input/output for Cairo programs, and proved/verified the basic program. As a result of our trial-and-error path, the convenient wrapper tools were born which we will use further. All the source code is in &lt;a href="https://github.com/maksimryndin/bellman_ford_cairo" rel="noopener noreferrer"&gt;the repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now it's time to digest it and learn some cool things from the references 8 - 12 (the order is a recommended way).&lt;/p&gt;

&lt;p&gt;In the next article(s) we will implement Bellman-Ford algorithm, try to break/attack the proof scheme, investigate the time complexity of the verification, an overhead over the Rust version.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://book.cairo-lang.org/" rel="noopener noreferrer"&gt;Cairo book&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://reilabs.io/blog/introducing-hints-in-cairo-programming-language/" rel="noopener noreferrer"&gt;Introducing Hints in Cairo programming language&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.cairo-lang.org/how_cairo_works/index.html" rel="noopener noreferrer"&gt;Cairo0 docs&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://starkware.co/blog/stwo-prover-the-next-gen-of-stark-scaling-is-here/" rel="noopener noreferrer"&gt;Stwo Prover: The next-gen of STARK scaling is here&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/nethermind-eth/under-the-hood-of-cairo-1-0-exploring-sierra-7f32808421f5" rel="noopener noreferrer"&gt;Under the hood of Cairo 1.0: Exploring Sierra&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://reilabs.io/blog/zero-knowledge-systems-you-can-trust/" rel="noopener noreferrer"&gt;Zero Knowledge Systems You Can Trust&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://starkware.co/blog/unleashing-the-power-of-the-stone-prover/" rel="noopener noreferrer"&gt;Unleashing the power of the Stone Prover&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/starkware/stark-math-the-journey-begins-51bd2b063c71" rel="noopener noreferrer"&gt;STARK Math: The Journey Begins&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/starkware/arithmetization-i-15c046390862" rel="noopener noreferrer"&gt;Arithmetization I&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/starkware/arithmetization-ii-403c3b3f4355" rel="noopener noreferrer"&gt;Arithmetization II&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://medium.com/starkware/low-degree-testing-f7614f5172db" rel="noopener noreferrer"&gt;Low Degree Testing&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://aszepieniec.github.io/stark-anatomy/" rel="noopener noreferrer"&gt;Anatomy of a STARK&lt;/a&gt; (accessed in July 2024)&lt;/li&gt;
&lt;/ol&gt;




&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;The phrase "reliable outsourcing of computation" credits to &lt;a href="https://lurk-lang.org/" rel="noopener noreferrer"&gt;Lurk language&lt;/a&gt;. Volunteers are invited to create an article "Lurk for List/Clojure devs". It would be interesting to compare both languages for verifiable computation. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn2"&gt;
&lt;p&gt;in these articles we aren't tailored to web3 at all but they are within &lt;a href="https://medium.com/@maksim.ryndin/how-to-create-an-atomic-arbitrage-bot-in-starknet-part-2-the-foggy-desert-d3f28fad69c7" rel="noopener noreferrer"&gt;my ongoing effort&lt;/a&gt; to seize arbitrage opportunities in crypto. For those interested there is &lt;a href="https://t.me/+TiNIOKAdIyQzNDg0" rel="noopener noreferrer"&gt;the Telegram group&lt;/a&gt; uniting MEV (re)searchers. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn3"&gt;
&lt;p&gt;Another prominent use case in the context of web3: we can move some computation from onchain to offchain in a trustless manner (&lt;a href="https://www.starknet.io/" rel="noopener noreferrer"&gt;Starknet&lt;/a&gt; is all around this). ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn4"&gt;
&lt;p&gt;A verifier is actually protected against a  &lt;em&gt;computationally bound&lt;/em&gt; prover so it is not a strict proof, rather &lt;em&gt;an argument of knowledge&lt;/em&gt; but I will stick with the word "proof" to avoid over-complication. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn5"&gt;
&lt;p&gt;Besides a computational integrity, there can be another (optional) requirement of zero-knowledge (ZK) when the prover doesn't reveal some information about the input. The rabbit hole is  deep that there is no single article - follow &lt;a href="https://github.com/keep-starknet-strange/awesome-starknet?tab=readme-ov-file#cryptography-and-maths" rel="noopener noreferrer"&gt;the suggested reading&lt;/a&gt;. By the way, many STARK-provers still (July 2024) do not implement perfect ZK, e.g. &lt;a href="(https://github.com/facebook/winterfell/issues/9)"&gt;Winterfell&lt;/a&gt;, &lt;a href="https://github.com/andrewmilson/ministark/issues/6" rel="noopener noreferrer"&gt;miniSTARK&lt;/a&gt;, &lt;a href="https://github.com/lambdaclass/lambdaworks/issues/850" rel="noopener noreferrer"&gt;Stark Platinum Prover&lt;/a&gt;. Also refer to &lt;a href="https://reilabs.io/blog/introducing-hints-in-cairo-programming-language/" rel="noopener noreferrer"&gt;the article&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn6"&gt;
&lt;p&gt;Actually, there is &lt;a href="https://docs.cairo-lang.org/hello_cairo/index.html" rel="noopener noreferrer"&gt;Cairo0&lt;/a&gt; which was the first version of a language for STARK-verifiable computation. It is basically an assembly language for STARK CPU. You may still encounter it in some &lt;a href="https://github.com/kkrt-labs/kakarot/blob/main/src/kakarot/interpreter.cairo" rel="noopener noreferrer"&gt;projects&lt;/a&gt;. In this article and in general, mentioning Cairo means talking about Cairo1, a Rust-like language. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn7"&gt;
&lt;p&gt;It seems that a separation between binary and library crates in Cairo is via inclusion/exclusion of &lt;code&gt;main&lt;/code&gt; function in &lt;code&gt;lib.cairo&lt;/code&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn8"&gt;
&lt;p&gt;Make sure to choose Cairo 1.0 from Starkware Industries. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn9"&gt;
&lt;p&gt;There are also &lt;a href="https://github.com/reilabs/cairo-hints" rel="noopener noreferrer"&gt;hints&lt;/a&gt; which were first introduced in &lt;a href="https://docs.cairo-lang.org/how_cairo_works/hints.html" rel="noopener noreferrer"&gt;Cairo0&lt;/a&gt; and haven't yet implemented in Cairo1 in the official compiler. And they can possibly allow for more interactions with the outer world. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn10"&gt;
&lt;p&gt;See &lt;a href="https://medium.com/starkware/tagged/stark-math" rel="noopener noreferrer"&gt;Stark math&lt;/a&gt; articles on Arithmetization. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;li id="fn11"&gt;
&lt;p&gt;Gas metering should protect a prover from infinite loops as relations between a prover and a verifier are trustless. But for the moment I have no idea why &lt;a href="https://github.com/lambdaclass/cairo-vm/blob/main/cairo1-run/README.md#running-scarb-projects" rel="noopener noreferrer"&gt;"cairo1-run skips gas checks when running"&lt;/a&gt;. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>rust</category>
      <category>cairo</category>
      <category>starks</category>
    </item>
  </channel>
</rss>
