From 5dd9068b73c99d9ff860d5faec21f020cd5be9ef Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 12:50:19 -0300
Subject: [PATCH 01/37] First draft

---
 Cargo.lock                     | 236 +++++++++++++++++++++++++++++++++
 cairo-vm-cli/src/main.rs       |  18 +++
 vm/Cargo.toml                  |   1 +
 vm/src/vm/runners/cairo_pie.rs |  37 ++++++
 4 files changed, 292 insertions(+)

diff --git a/Cargo.lock b/Cargo.lock
index 7b162d25f9..4c72f36e19 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,23 @@
 # It is not intended for manual editing.
 version = 3
 
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "aes"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
+dependencies = [
+ "cfg-if",
+ "cipher",
+ "cpufeatures",
+]
+
 [[package]]
 name = "ahash"
 version = "0.7.7"
@@ -200,6 +217,12 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
 
+[[package]]
+name = "base64ct"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
+
 [[package]]
 name = "bincode"
 version = "2.0.0-rc.3"
@@ -269,6 +292,33 @@ version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
 
+[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
+name = "bzip2"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
+dependencies = [
+ "bzip2-sys",
+ "libc",
+]
+
+[[package]]
+name = "bzip2-sys"
+version = "0.1.11+1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
+dependencies = [
+ "cc",
+ "libc",
+ "pkg-config",
+]
+
 [[package]]
 name = "cairo-felt"
 version = "0.8.7"
@@ -722,6 +772,7 @@ dependencies = [
  "starknet-types-core",
  "thiserror-no-std",
  "wasm-bindgen-test",
+ "zip",
 ]
 
 [[package]]
@@ -772,6 +823,7 @@ version = "1.0.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
 dependencies = [
+ "jobserver",
  "libc",
 ]
 
@@ -808,6 +860,16 @@ dependencies = [
  "half",
 ]
 
+[[package]]
+name = "cipher"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
+dependencies = [
+ "crypto-common",
+ "inout",
+]
+
 [[package]]
 name = "clap"
 version = "4.4.8"
@@ -901,6 +963,12 @@ dependencies = [
  "unicode-xid",
 ]
 
+[[package]]
+name = "constant_time_eq"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
+
 [[package]]
 name = "convert_case"
 version = "0.6.0"
@@ -919,6 +987,15 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
 [[package]]
 name = "criterion"
 version = "0.5.1"
@@ -1015,6 +1092,15 @@ dependencies = [
  "typenum",
 ]
 
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
 [[package]]
 name = "derivative"
 version = "2.2.0"
@@ -1124,6 +1210,16 @@ version = "0.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
 
+[[package]]
+name = "flate2"
+version = "1.0.28"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
 [[package]]
 name = "fnv"
 version = "1.0.7"
@@ -1414,6 +1510,15 @@ version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
 
+[[package]]
+name = "inout"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
+dependencies = [
+ "generic-array",
+]
+
 [[package]]
 name = "instant"
 version = "0.1.12"
@@ -1458,6 +1563,15 @@ version = "1.0.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
 
+[[package]]
+name = "jobserver"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
+dependencies = [
+ "libc",
+]
+
 [[package]]
 name = "js-sys"
 version = "0.3.65"
@@ -1639,6 +1753,15 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
 
+[[package]]
+name = "miniz_oxide"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
+dependencies = [
+ "adler",
+]
+
 [[package]]
 name = "ndarray"
 version = "0.13.1"
@@ -1832,6 +1955,17 @@ dependencies = [
  "windows-targets",
 ]
 
+[[package]]
+name = "password-hash"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
+dependencies = [
+ "base64ct",
+ "rand_core",
+ "subtle",
+]
+
 [[package]]
 name = "paste"
 version = "1.0.14"
@@ -1844,6 +1978,18 @@ version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "17359afc20d7ab31fdb42bb844c8b3bb1dabd7dcf7e68428492da7f16966fcef"
 
+[[package]]
+name = "pbkdf2"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
+dependencies = [
+ "digest",
+ "hmac",
+ "password-hash",
+ "sha2",
+]
+
 [[package]]
 name = "petgraph"
 version = "0.6.4"
@@ -1881,6 +2027,12 @@ version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
 
+[[package]]
+name = "pkg-config"
+version = "0.3.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
+
 [[package]]
 name = "plotters"
 version = "0.3.5"
@@ -1909,6 +2061,12 @@ dependencies = [
  "plotters-backend",
 ]
 
+[[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
 [[package]]
 name = "ppv-lite86"
 version = "0.2.17"
@@ -2336,6 +2494,17 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "sha1"
+version = "0.10.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "digest",
+]
+
 [[package]]
 name = "sha2"
 version = "0.10.8"
@@ -2589,6 +2758,24 @@ dependencies = [
  "thiserror-impl-no-std",
 ]
 
+[[package]]
+name = "time"
+version = "0.3.31"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e"
+dependencies = [
+ "deranged",
+ "powerfmt",
+ "serde",
+ "time-core",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
+
 [[package]]
 name = "tiny-keccak"
 version = "2.0.2"
@@ -3010,3 +3197,52 @@ dependencies = [
  "quote",
  "syn 2.0.39",
 ]
+
+[[package]]
+name = "zip"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
+dependencies = [
+ "aes",
+ "byteorder",
+ "bzip2",
+ "constant_time_eq",
+ "crc32fast",
+ "crossbeam-utils",
+ "flate2",
+ "hmac",
+ "pbkdf2",
+ "sha1",
+ "time",
+ "zstd",
+]
+
+[[package]]
+name = "zstd"
+version = "0.11.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
+dependencies = [
+ "zstd-safe",
+]
+
+[[package]]
+name = "zstd-safe"
+version = "5.0.2+zstd.1.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
+dependencies = [
+ "libc",
+ "zstd-sys",
+]
+
+[[package]]
+name = "zstd-sys"
+version = "2.0.9+zstd.1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656"
+dependencies = [
+ "cc",
+ "pkg-config",
+]
diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index a24ef7bb92..a7d8497169 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -42,6 +42,8 @@ struct Args {
     air_public_input: Option<String>,
     #[clap(long = "air_private_input")]
     air_private_input: Option<String>,
+    #[clap(long = "cairo_pie_output")]
+    cairo_pie_output: Option<String>,
 }
 
 fn validate_layout(value: &str) -> Result<String, String> {
@@ -145,6 +147,14 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         return Err(Error::Cli(error));
     }
 
+    if args.cairo_pie_output.is_some() && args.proof_mode {
+        let error = Args::command().error(
+            clap::error::ErrorKind::ArgumentConflict,
+            "--proof_mode and --cairo_pie_output cannot be both specified.",
+        );
+        return Err(Error::Cli(error));
+    }
+
     let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some();
     let mut hint_executor = BuiltinHintProcessor::new_empty();
     let cairo_run_config = cairo_run::CairoRunConfig {
@@ -227,6 +237,14 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         std::fs::write(file_path, json)?;
     }
 
+    if let Some(file_name) = args.cairo_pie_output {
+        cairo_runner
+            .get_cairo_pie(&vm)
+            .map_err(CairoRunError::Runner)?
+            .write_zip_file(&file_name)
+            .unwrap()
+    }
+
     Ok(())
 }
 
diff --git a/vm/Cargo.toml b/vm/Cargo.toml
index e7f9fe029a..a7af63173d 100644
--- a/vm/Cargo.toml
+++ b/vm/Cargo.toml
@@ -42,6 +42,7 @@ extensive_hints = []
 print = ["std"]
 
 [dependencies]
+zip = "0.6.6"
 mimalloc = { workspace = true, optional = true }
 num-bigint = { workspace = true }
 rand = { workspace = true }
diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index d464065899..7e9128ac76 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -1,3 +1,5 @@
+use std::{fs::File, io::Write, path::Path};
+
 use super::cairo_runner::ExecutionResources;
 use crate::{
     serde::deserialize_program::BuiltinName,
@@ -6,6 +8,7 @@ use crate::{
     Felt252,
 };
 use serde::{Deserialize, Serialize};
+use zip::ZipWriter;
 
 const CAIRO_PIE_VERSION: &str = "1.1";
 
@@ -96,6 +99,40 @@ pub struct CairoPieVersion {
     pub cairo_pie: (),
 }
 
+impl CairoPie {
+    pub fn serialize_json(&self) -> Result<String, serde_json::Error> {
+        serde_json::to_string_pretty(&self)
+    }
+
+    pub fn write_zip_file(&self, file_name: &String) -> Result<(), std::io::Error> {
+        let path = Path::new(file_name);
+        let file = File::create(path).unwrap();
+        let mut zip_writer = ZipWriter::new(file);
+        let options =
+            zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
+        zip_writer.start_file("version.json", options)?;
+        zip_writer.write(serde_json::to_string(&self.version).unwrap().as_bytes())?;
+        zip_writer.start_file("metadata.json", options)?;
+        zip_writer.write(serde_json::to_string(&self.metadata).unwrap().as_bytes())?;
+        zip_writer.start_file("memory.bin", options)?;
+        zip_writer.write(serde_json::to_string(&self.memory).unwrap().as_bytes())?;
+        zip_writer.start_file("additional_data.json", options)?;
+        zip_writer.write(
+            serde_json::to_string(&self.additional_data)
+                .unwrap()
+                .as_bytes(),
+        )?;
+        zip_writer.start_file("execution_resources.json", options)?;
+        zip_writer.write(
+            serde_json::to_string(&self.execution_resources)
+                .unwrap()
+                .as_bytes(),
+        )?;
+        zip_writer.finish().unwrap();
+        Ok(())
+    }
+}
+
 mod serde_impl {
     use super::CAIRO_PIE_VERSION;
     use crate::{types::relocatable::MaybeRelocatable, utils::CAIRO_PRIME, Felt252};

From 7a9924e0cf295defcd07c0afd616b0a17e852be9 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 13:37:28 -0300
Subject: [PATCH 02/37] Add special serialization for ecdsa builtin additional
 data

---
 vm/src/vm/runners/cairo_pie.rs | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index 7e9128ac76..ef94620157 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -55,6 +55,7 @@ pub enum BuiltinAdditionalData {
     Hash(Vec<Relocatable>),
     Output(OutputBuiltinAdditionalData),
     // Signatures are composed of (r, s) tuples
+    #[serde(serialize_with = "serde_impl::serialize_signature_additional_data")]
     Signature(HashMap<Relocatable, (Felt252, Felt252)>),
     None,
 }
@@ -134,11 +135,20 @@ impl CairoPie {
 }
 
 mod serde_impl {
+    use std::collections::HashMap;
+
     use super::CAIRO_PIE_VERSION;
-    use crate::{types::relocatable::MaybeRelocatable, utils::CAIRO_PRIME, Felt252};
+    use crate::{
+        types::relocatable::{MaybeRelocatable, Relocatable},
+        utils::CAIRO_PRIME,
+        Felt252,
+    };
     use num_bigint::BigUint;
     use num_traits::Num;
-    use serde::{ser::SerializeSeq, Serialize, Serializer};
+    use serde::{
+        ser::{SerializeMap, SerializeSeq},
+        Serialize, Serializer,
+    };
 
     pub const ADDR_BYTE_LEN: usize = 8;
     pub const FIELD_BYTE_LEN: usize = 32;
@@ -253,6 +263,21 @@ mod serde_impl {
     {
         serializer.serialize_str(CAIRO_PIE_VERSION)
     }
+
+    pub fn serialize_signature_additional_data<S>(
+        values: &HashMap<Relocatable, (Felt252, Felt252)>,
+        serializer: S,
+    ) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut map_serializer = serializer.serialize_map(Some(values.len()))?;
+
+        for (key, (x, y)) in values {
+            map_serializer.serialize_entry(&key.to_string(), &format!("[{}, {}]", x, y))?;
+        }
+        map_serializer.end()
+    }
 }
 
 #[cfg(test)]

From 653e8b04a772567ee5d60ca7d36c99258b1537f1 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 13:38:57 -0300
Subject: [PATCH 03/37] Start comparison script

---
 Makefile                             | 14 ++++++++++----
 vm/src/tests/cairo_pie_comparator.py | 20 ++++++++++++++++++++
 vm/src/tests/compare_vm_state.sh     | 14 ++++++++++++++
 3 files changed, 44 insertions(+), 4 deletions(-)
 create mode 100644 vm/src/tests/cairo_pie_comparator.py

diff --git a/Makefile b/Makefile
index e39d995130..4ebc32d0ce 100644
--- a/Makefile
+++ b/Makefile
@@ -69,8 +69,10 @@ TEST_FILES:=$(wildcard $(TEST_DIR)/*.cairo)
 COMPILED_TESTS:=$(patsubst $(TEST_DIR)/%.cairo, $(TEST_DIR)/%.json, $(TEST_FILES))
 CAIRO_MEM:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.memory, $(COMPILED_TESTS))
 CAIRO_TRACE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.trace, $(COMPILED_TESTS))
+CAIRO_PIE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.pie.zip, $(COMPILED_TESTS))
 CAIRO_RS_MEM:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.memory, $(COMPILED_TESTS))
 CAIRO_RS_TRACE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.trace, $(COMPILED_TESTS))
+CAIRO_RS_PIE:=$(patsubst $(TEST_DIR)/%.json, $(TEST_DIR)/%.rs.pie.zip, $(COMPILED_TESTS))
 
 BENCH_DIR=cairo_programs/benchmarks
 BENCH_FILES:=$(wildcard $(BENCH_DIR)/*.cairo)
@@ -94,11 +96,11 @@ $(BENCH_DIR)/%.json: $(BENCH_DIR)/%.cairo
 $(TEST_DIR)/%.json: $(TEST_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR)" $< --output $@
 
-$(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory: $(TEST_DIR)/%.json $(RELBIN)
-	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory
+$(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory $(TEST_DIR)/%.rs.pie.zip: $(TEST_DIR)/%.json $(RELBIN)
+	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
 
-$(TEST_DIR)/%.trace $(TEST_DIR)/%.memory: $(TEST_DIR)/%.json
-	cairo-run --layout starknet_with_keccak --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory
+$(TEST_DIR)/%.trace $(TEST_DIR)/%.memory $(TEST_DIR)/%.pie.zip: $(TEST_DIR)/%.json
+	cairo-run --layout starknet_with_keccak --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip
 
 $(NORETROCOMPAT_DIR)/%.json: $(NORETROCOMPAT_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR):$(NORETROCOMPAT_DIR)" $< --output $@
@@ -306,6 +308,9 @@ compare_air_public_input: $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PUBLIC_INPUT)
 compare_air_private_input: $(CAIRO_RS_AIR_PRIVATE_INPUT) $(CAIRO_AIR_PRIVATE_INPUT)
 	cd vm/src/tests; ./compare_vm_state.sh memory proof_mode air_private_input
 
+compare_pie: $(CAIRO_RS_PIE) $(CAIRO_PIE)
+	cd vm/src/tests; ./compare_vm_state.sh pie
+
 # Run with nightly enable the `doc_cfg` feature wich let us provide clear explaination about which parts of the code are behind a feature flag
 docs:
 	RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --verbose --release --locked --no-deps --all-features --open
@@ -314,6 +319,7 @@ clean:
 	rm -f $(TEST_DIR)/*.json
 	rm -f $(TEST_DIR)/*.memory
 	rm -f $(TEST_DIR)/*.trace
+	rm -f $(TEST_DIR)/*.pie.zip
 	rm -f $(BENCH_DIR)/*.json
 	rm -f $(BAD_TEST_DIR)/*.json
 	rm -f $(PRINT_TEST_DIR)/*.json
diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
new file mode 100644
index 0000000000..8156a173cb
--- /dev/null
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import sys
+import json
+from zipfile import ZipFile
+
+
+filename1 = sys.argv[1]
+filename2 = sys.argv[2]
+
+with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip:
+    with cairo_lang_pie_zip.open('version.json') as cl_verison_file, cairo_vm_pie_zip.open('version.json') as cv_verison_file:
+        cl_version = json.load(cl_verison_file)
+        cv_version = json.load(cv_verison_file)
+        if cl_version == cv_verison_file:
+            print(f"Comparison succesful for {filename1}/version.json vs {filename2}/version.json")
+        else:
+            print(f"Comparison unsuccesful for {filename1}/version.json  vs {filename2}/version.json")
+            exit(1)
+
diff --git a/vm/src/tests/compare_vm_state.sh b/vm/src/tests/compare_vm_state.sh
index 24388d20bf..34c7486663 100755
--- a/vm/src/tests/compare_vm_state.sh
+++ b/vm/src/tests/compare_vm_state.sh
@@ -10,6 +10,7 @@ trace=false
 memory=false
 air_public_input=false
 air_private_input=false
+pie=false
 passed_tests=0
 failed_tests=0
 
@@ -30,6 +31,9 @@ for i in $@; do
         "air_private_input") air_private_input=true
         echo "Requested air_private_input comparison"
         ;;
+        "pie") pie=true
+        echo "Requested pie comparison"
+        ;;
         *)
         ;;
     esac
@@ -90,6 +94,16 @@ for file in $(ls $tests_path | grep .cairo$ | sed -E 's/\.cairo$//'); do
             passed_tests=$((passed_tests + 1))
         fi
     fi
+
+    if $pie; then
+        if ! ./cairo_pie_comparator.py $path_file.pie.zip $path_file.rs.pie.zip; then
+            echo "Cairo PIE differs for $file"
+            exit_code=1
+            failed_tests=$((failed_tests + 1))
+        else
+            passed_tests=$((passed_tests + 1))
+        fi
+    fi
 done
 
 if test $failed_tests != 0; then

From 666f6e80c7dad25a1691724a160400ee2d7cb11d Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 13:53:38 -0300
Subject: [PATCH 04/37] Add compare_all_no_proof target

---
 Makefile | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 4ebc32d0ce..887955c5f5 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@ endif
 .PHONY: build-cairo-1-compiler build-cairo-1-compiler-macos build-cairo-2-compiler build-cairo-2-compiler-macos \
 	deps deps-macos cargo-deps build run check test clippy coverage benchmark \
 	compare_benchmarks_deps compare_benchmarks docs clean \
-	compare_vm_output compare_trace_memory compare_trace compare_memory \
+	compare_trace_memory compare_trace compare_memory compare_pie compare_all_no_proof \
 	compare_trace_memory_proof  compare_all_proof compare_trace_proof compare_memory_proof compare_air_public_input  compare_air_private_input\
 	cairo_bench_programs cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts \
 	cairo_trace cairo-vm_trace cairo_proof_trace cairo-vm_proof_trace \
@@ -284,6 +284,9 @@ compare_benchmarks: cairo_bench_programs
 compare_trace_memory: $(CAIRO_RS_TRACE) $(CAIRO_TRACE) $(CAIRO_RS_MEM) $(CAIRO_MEM)
 	cd vm/src/tests; ./compare_vm_state.sh trace memory
 
+compare_all_no_proof: $(CAIRO_RS_TRACE) $(CAIRO_TRACE) $(CAIRO_RS_MEM) $(CAIRO_MEM) $(CAIRO_RS_PIE) $(CAIRO_PIE)
+	cd vm/src/tests; ./compare_vm_state.sh trace memory
+
 compare_trace: $(CAIRO_RS_TRACE) $(CAIRO_TRACE)
 	cd vm/src/tests; ./compare_vm_state.sh trace
 

From 5a724985ecc895134b452a84dd1ebf8c628addce Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 13:54:05 -0300
Subject: [PATCH 05/37] Update file permissions

---
 vm/src/tests/cairo_pie_comparator.py | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 mode change 100644 => 100755 vm/src/tests/cairo_pie_comparator.py

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
old mode 100644
new mode 100755

From 89a7af054586ea43e6811e4875fd555864acf076 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 14:13:32 -0300
Subject: [PATCH 06/37] Fix makefile

---
 Makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index 887955c5f5..3c60039b59 100644
--- a/Makefile
+++ b/Makefile
@@ -97,10 +97,10 @@ $(TEST_DIR)/%.json: $(TEST_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR)" $< --output $@
 
 $(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory $(TEST_DIR)/%.rs.pie.zip: $(TEST_DIR)/%.json $(RELBIN)
-	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $@ --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
+	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $(@D)/$(*F) --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
 
 $(TEST_DIR)/%.trace $(TEST_DIR)/%.memory $(TEST_DIR)/%.pie.zip: $(TEST_DIR)/%.json
-	cairo-run --layout starknet_with_keccak --program $< --trace_file $@ --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip
+	cairo-run --layout starknet_with_keccak --program $< --trace_file $(@D)/$(*F) --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip
 
 $(NORETROCOMPAT_DIR)/%.json: $(NORETROCOMPAT_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR):$(NORETROCOMPAT_DIR)" $< --output $@

From 5bcf06a8faf21263b4ab107eca2c4b18a155eed7 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 16:13:01 -0300
Subject: [PATCH 07/37] Add special serialization for pedersen builtin
 additional data

---
 vm/src/vm/runners/cairo_pie.rs | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index ef94620157..d780341ef7 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -52,6 +52,7 @@ pub struct OutputBuiltinAdditionalData {
 #[serde(untagged)]
 pub enum BuiltinAdditionalData {
     // Contains verified addresses as contiguous index, value pairs
+    #[serde(serialize_with = "serde_impl::serialize_hash_additional_data")]
     Hash(Vec<Relocatable>),
     Output(OutputBuiltinAdditionalData),
     // Signatures are composed of (r, s) tuples
@@ -278,6 +279,23 @@ mod serde_impl {
         }
         map_serializer.end()
     }
+
+    pub fn serialize_hash_additional_data<S>(
+        values: &[Relocatable],
+        serializer: S,
+    ) -> Result<S::Ok, S::Error>
+    where
+        S: Serializer,
+    {
+        let mut seq_serializer = serializer.serialize_seq(Some(values.len()))?;
+
+        for value in values {
+            seq_serializer
+                .serialize_element(&format!("[{}, {}]", value.segment_index, value.offset))?;
+        }
+
+        seq_serializer.end()
+    }
 }
 
 #[cfg(test)]

From b429d33354c8a7e8e991388f312c3c5f4da70ade Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 16:22:19 -0300
Subject: [PATCH 08/37] Fix prev commit

---
 vm/src/vm/runners/cairo_pie.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index d780341ef7..bcb1cbe643 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -291,7 +291,7 @@ mod serde_impl {
 
         for value in values {
             seq_serializer
-                .serialize_element(&format!("[{}, {}]", value.segment_index, value.offset))?;
+                .serialize_element(&[value.segment_index, value.offset as isize])?;
         }
 
         seq_serializer.end()

From 9a6fcbe44903dcef1dbc6048a10103685dc73a8f Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 16:35:06 -0300
Subject: [PATCH 09/37] Serialize ecdsa additional data as sequence

---
 vm/src/vm/runners/cairo_pie.rs | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index bcb1cbe643..b8270504bb 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -146,10 +146,7 @@ mod serde_impl {
     };
     use num_bigint::BigUint;
     use num_traits::Num;
-    use serde::{
-        ser::{SerializeMap, SerializeSeq},
-        Serialize, Serializer,
-    };
+    use serde::{ser::SerializeSeq, Serialize, Serializer};
 
     pub const ADDR_BYTE_LEN: usize = 8;
     pub const FIELD_BYTE_LEN: usize = 32;
@@ -272,12 +269,18 @@ mod serde_impl {
     where
         S: Serializer,
     {
-        let mut map_serializer = serializer.serialize_map(Some(values.len()))?;
+        let mut seq_serializer = serializer.serialize_seq(Some(values.len()))?;
 
         for (key, (x, y)) in values {
-            map_serializer.serialize_entry(&key.to_string(), &format!("[{}, {}]", x, y))?;
+            seq_serializer.serialize_element(&[
+                [
+                    Felt252Wrapper(&Felt252::from(key.segment_index)),
+                    Felt252Wrapper(&Felt252::from(key.offset)),
+                ],
+                [Felt252Wrapper(x), Felt252Wrapper(y)],
+            ])?;
         }
-        map_serializer.end()
+        seq_serializer.end()
     }
 
     pub fn serialize_hash_additional_data<S>(
@@ -290,8 +293,7 @@ mod serde_impl {
         let mut seq_serializer = serializer.serialize_seq(Some(values.len()))?;
 
         for value in values {
-            seq_serializer
-                .serialize_element(&[value.segment_index, value.offset as isize])?;
+            seq_serializer.serialize_element(&[value.segment_index, value.offset as isize])?;
         }
 
         seq_serializer.end()

From 3d17276871a5b004e8dba788065f89b97d71a50a Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 16:43:23 -0300
Subject: [PATCH 10/37] Expand comparison script

---
 vm/src/tests/cairo_pie_comparator.py | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 8156a173cb..ae402623cc 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -8,13 +8,16 @@
 filename1 = sys.argv[1]
 filename2 = sys.argv[2]
 
-with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip:
-    with cairo_lang_pie_zip.open('version.json') as cl_verison_file, cairo_vm_pie_zip.open('version.json') as cv_verison_file:
-        cl_version = json.load(cl_verison_file)
-        cv_version = json.load(cv_verison_file)
-        if cl_version == cv_verison_file:
-            print(f"Comparison succesful for {filename1}/version.json vs {filename2}/version.json")
-        else:
-            print(f"Comparison unsuccesful for {filename1}/version.json  vs {filename2}/version.json")
-            exit(1)
+strict_comparison_files = ["version.json", "metadata.json", "execution_resources.json", "additional_data.json"]
 
+with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip:
+    # Compare json files
+    for file in strict_comparison_files:
+        with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file:
+            cl_content = json.load(cairo_lang_file)
+            cv_content = json.load(cairo_vm_file)
+            if cl_content == cv_content:
+                print(f"Comparison succesful for {filename1}/{file} vs {filename2}/{file}")
+            else:
+                print(f"Comparison unsuccesful for {filename1}/{file}  vs {filename2}/{file}")
+                exit(1)

From f9a449ef9c476572266497673c69fe7de4932179 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 16:56:20 -0300
Subject: [PATCH 11/37] Skip bugged case + Reduce amount of prints in
 comparison script

---
 vm/src/tests/cairo_pie_comparator.py | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index ae402623cc..98c89b606f 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -13,11 +13,15 @@
 with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip:
     # Compare json files
     for file in strict_comparison_files:
+        # Skipping this check due to a bug in the memory holes count
+        # TODO: Remove it once the bug is fixed
+        if filename1 == "../../../cairo_programs/keccak_alternative_hint.pie.zip" and file == "execution_resources.json":
+            continue
         with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file:
             cl_content = json.load(cairo_lang_file)
             cv_content = json.load(cairo_vm_file)
-            if cl_content == cv_content:
-                print(f"Comparison succesful for {filename1}/{file} vs {filename2}/{file}")
-            else:
+            if cl_content != cv_content:
                 print(f"Comparison unsuccesful for {filename1}/{file}  vs {filename2}/{file}")
                 exit(1)
+
+    print(f"Comparison succesful for {filename1} vs {filename2}")

From 171862deb87ef66e47234bf8cdf37a78d758db22 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 17:07:02 -0300
Subject: [PATCH 12/37] Improve skip

---
 vm/src/tests/cairo_pie_comparator.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 98c89b606f..4c6a34fd05 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -15,7 +15,8 @@
     for file in strict_comparison_files:
         # Skipping this check due to a bug in the memory holes count
         # TODO: Remove it once the bug is fixed
-        if filename1 == "../../../cairo_programs/keccak_alternative_hint.pie.zip" and file == "execution_resources.json":
+        if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip") and file == "execution_resources.json":
+            print(f"Comparison skipped for {filename1}/{file}  vs {filename2}/{file}")
             continue
         with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file:
             cl_content = json.load(cairo_lang_file)

From 89fc207ad96060c8007e588d815199d890118786 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 17:24:49 -0300
Subject: [PATCH 13/37] Add comparison to CI

---
 .github/workflows/rust.yml           | 11 ++++++++---
 vm/src/tests/cairo_pie_comparator.py |  2 +-
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index 20c9ec31fc..54ed96ea0a 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -322,6 +322,7 @@ jobs:
           cairo_programs/**/*.trace
           cairo_programs/**/*.air_public_input
           cairo_programs/**/*.air_private_input
+          cairo_programs/**/*.pie.zip
         key: ${{ matrix.program-target }}-reference-trace-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo') }}
         restore-keys: ${{ matrix.program-target }}-reference-trace-cache-
 
@@ -364,7 +365,7 @@ jobs:
           extra-args: '--proof_mode --air_public_input {program}.rs.air_public_input --air_private_input {program}.rs.air_private_input '
         - program-target: cairo_test_programs
           programs-dir: cairo_programs
-          extra-args: ''
+          extra-args: '--cairo_pie_output {program}.rs.pie.zip'
     name: Compute memory and execution traces with cairo-vm
     needs: [ build-programs, build-release ]
     runs-on: ubuntu-22.04
@@ -401,6 +402,7 @@ jobs:
           cairo_programs/**/*.trace
           cairo_programs/**/*.air_public_input
           cairo_programs/**/*.air_private_input
+          cairo_programs/**/*.pie.zip
         key: ${{ matrix.program-target }}-release-trace-cache-${{ github.sha }}
 
 
@@ -501,6 +503,7 @@ jobs:
           cairo_programs/**/*.trace
           cairo_programs/**/*.air_public_input
           cairo_programs/**/*.air_private_input
+          cairo_programs/**/*.pie.zip
         key: ${{ matrix.program-target }}-reference-trace-cache-${{ hashFiles('cairo_programs/**/*.cairo', 'examples/wasm-demo/src/array_sum.cairo') }}
         fail-on-cache-miss: true
 
@@ -512,6 +515,7 @@ jobs:
           cairo_programs/**/*.trace
           cairo_programs/**/*.air_public_input
           cairo_programs/**/*.air_private_input
+          cairo_programs/**/*.pie.zip
         key: ${{ matrix.program-target }}-release-trace-cache-${{ github.sha }}
         fail-on-cache-miss: true
 
@@ -521,9 +525,10 @@ jobs:
           PROOF=proof_mode 
           AIR_PUBLIC_INPUT=air_public_input
           AIR_PRIVATE_INPUT=air_private_input
+        else
+          PIE=pie
         fi
-        ./vm/src/tests/compare_vm_state.sh trace memory $PROOF $AIR_PUBLIC_INPUT $AIR_PRIVATE_INPUT
-        ./vm/src/tests/compare_vm_state.sh trace memory $PROOF
+        ./vm/src/tests/compare_vm_state.sh trace memory $PROOF $AIR_PUBLIC_INPUT $AIR_PRIVATE_INPUT $PIE
 
   wasm-demo:
     name: Build the wasm demo
diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 4c6a34fd05..8cf2934ef9 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -15,7 +15,7 @@
     for file in strict_comparison_files:
         # Skipping this check due to a bug in the memory holes count
         # TODO: Remove it once the bug is fixed
-        if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip") and file == "execution_resources.json":
+        if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip" or filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip") and file == "execution_resources.json":
             print(f"Comparison skipped for {filename1}/{file}  vs {filename2}/{file}")
             continue
         with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file:

From a0c74c91d8bc1e0c514d93ab984870923970907c Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 17:30:46 -0300
Subject: [PATCH 14/37] Fix

---
 vm/src/tests/cairo_pie_comparator.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 8cf2934ef9..ea678a2bc4 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -4,7 +4,6 @@
 import json
 from zipfile import ZipFile
 
-
 filename1 = sys.argv[1]
 filename2 = sys.argv[2]
 
@@ -15,7 +14,7 @@
     for file in strict_comparison_files:
         # Skipping this check due to a bug in the memory holes count
         # TODO: Remove it once the bug is fixed
-        if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip" or filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip") and file == "execution_resources.json":
+        if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip" or filename1 == "../../../cairo_programs/keccak_alternative_hint.pie.zip") and file == "execution_resources.json":
             print(f"Comparison skipped for {filename1}/{file}  vs {filename2}/{file}")
             continue
         with cairo_lang_pie_zip.open(file) as cairo_lang_file, cairo_vm_pie_zip.open(file) as cairo_vm_file:

From 70513f0c10d3f9612dc63abb59a409e6c4e57da7 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 18:44:04 -0300
Subject: [PATCH 15/37] Fix pie memory serialization

---
 vm/src/vm/runners/cairo_pie.rs | 31 +++++++++++--------------------
 vm/src/vm/vm_memory/memory.rs  |  2 +-
 2 files changed, 12 insertions(+), 21 deletions(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index b8270504bb..d3f4c9ddfa 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -30,7 +30,11 @@ impl From<(isize, usize)> for SegmentInfo {
 // A simplified version of Memory, without any additional data besides its elements
 // Contains all addr-value pairs, ordered by index and offset
 // Allows practical serialization + conversion between CairoPieMemory & Memory
-pub type CairoPieMemory = Vec<((usize, usize), MaybeRelocatable)>;
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
+pub struct CairoPieMemory(
+    #[serde(serialize_with = "serde_impl::serialize_memory")]
+    pub  Vec<((usize, usize), MaybeRelocatable)>,
+);
 
 #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
 pub struct PublicMemoryPage {
@@ -64,7 +68,6 @@ pub enum BuiltinAdditionalData {
 #[derive(Serialize, Clone, Debug, PartialEq, Eq)]
 pub struct CairoPie {
     pub metadata: CairoPieMetadata,
-    #[serde(serialize_with = "serde_impl::serialize_memory")]
     pub memory: CairoPieMemory,
     pub execution_resources: ExecutionResources,
     pub additional_data: HashMap<String, BuiltinAdditionalData>,
@@ -144,8 +147,6 @@ mod serde_impl {
         utils::CAIRO_PRIME,
         Felt252,
     };
-    use num_bigint::BigUint;
-    use num_traits::Num;
     use serde::{ser::SerializeSeq, Serialize, Serializer};
 
     pub const ADDR_BYTE_LEN: usize = 8;
@@ -216,12 +217,12 @@ mod serde_impl {
                 MaybeRelocatable::RelocatableValue(rel_val) => {
                     let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
 
-                    let reloc_base = BigUint::from_str_radix(RELOCATE_BASE, 16)
+                    let reloc_base = Felt252::from_hex(RELOCATE_BASE)
                         .map_err(|_| serde::ser::Error::custom("invalid relocation base str"))?;
                     let reloc_value = reloc_base
-                        + BigUint::from(rel_val.segment_index as usize)
-                            * BigUint::from(OFFSET_BASE)
-                        + BigUint::from(rel_val.offset);
+                        + Felt252::from(rel_val.segment_index as usize)
+                            * Felt252::from(OFFSET_BASE)
+                        + Felt252::from(rel_val.offset);
                     res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
                     res.extend_from_slice(reloc_value.to_bytes_le().as_ref());
                 }
@@ -236,12 +237,7 @@ mod serde_impl {
             };
         }
 
-        serializer.serialize_str(
-            res.iter()
-                .map(|b| format!("{:02x}", b))
-                .collect::<String>()
-                .as_str(),
-        )
+        serializer.serialize_bytes(&res)
     }
 
     pub fn serialize_prime<S>(_value: &(), serializer: S) -> Result<S::Ok, S::Error>
@@ -306,11 +302,6 @@ mod test {
 
     #[test]
     fn serialize_cairo_pie_memory() {
-        #[derive(Serialize)]
-        struct MemoryWrapper(
-            #[serde(serialize_with = "serde_impl::serialize_memory")] CairoPieMemory,
-        );
-
         let addrs = [
             ((1, 0), "0000000000800080"),
             ((1, 1), "0100000000800080"),
@@ -320,7 +311,7 @@ mod test {
             ((5, 8), "0800000000800280"),
         ];
 
-        let memory = MemoryWrapper(vec![
+        let memory = CairoPieMemory(vec![
             (addrs[0].0, MaybeRelocatable::Int(1234.into())),
             (addrs[1].0, MaybeRelocatable::Int(11.into())),
             (addrs[2].0, MaybeRelocatable::Int(12.into())),
diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs
index 56d6fe0f41..c05c52dffd 100644
--- a/vm/src/vm/vm_memory/memory.rs
+++ b/vm/src/vm/vm_memory/memory.rs
@@ -524,7 +524,7 @@ impl From<&Memory> for CairoPieMemory {
                 }
             }
         }
-        pie_memory
+        CairoPieMemory(pie_memory)
     }
 }
 

From 08e037eca1c0e4376f748a7bdca10462f19f586f Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 19:46:20 -0300
Subject: [PATCH 16/37] Fix constant value

---
 vm/src/vm/runners/cairo_pie.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index d3f4c9ddfa..c70958d839 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -154,7 +154,7 @@ mod serde_impl {
     pub const ADDR_BASE: u64 = 0x8000000000000000; // 2 ** (8 * ADDR_BYTE_LEN - 1)
     pub const OFFSET_BASE: u64 = 0x800000000000; // 2 ** OFFSET_BIT_LEN
     pub const RELOCATE_BASE: &str =
-        "8000000000000000000000000000000000000000000000000000000000000000"; // 2 ** (8 * FIELD_BYTE_LEN - 1)
+        "57896044618658097711785492504343953926634992332820282019728792003956564819968"; // 2 ** (8 * FIELD_BYTE_LEN - 1)
 
     struct Felt252Wrapper<'a>(&'a Felt252);
 

From 39a05bc6da7227ce0f1fcdffb10ae558e2347fc6 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 19:50:43 -0300
Subject: [PATCH 17/37] Save temp changes

---
 vm/src/tests/cairo_pie_comparator.py | 51 ++++++++++++++++++++++++++++
 vm/src/tests/memory_comparator.py    | 37 ++++++++++++++++++++
 2 files changed, 88 insertions(+)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index ea678a2bc4..826e57e2ae 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -25,3 +25,54 @@
                 exit(1)
 
     print(f"Comparison succesful for {filename1} vs {filename2}")
+
+    # Compare binary files
+    #Copy paste starts here
+
+    cairo_mem = {}
+    cairo_rs_mem = {}
+
+    with cairo_lang_pie_zip.open("memory.bin", 'r') as f:
+        cairo_raw = f.read()
+        assert len(cairo_raw) % 40 == 0, f'{filename1}: malformed memory file from Cairo VM'
+        chunks = len(cairo_raw) // 40
+        for i in range(0, chunks):
+            chunk = cairo_raw[i*40:(i+1)*40]
+            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
+            assert k not in cairo_mem, f'{filename1}: address {k} has two values'
+            cairo_mem[k] = v
+        assert len(cairo_mem) * 40 == len(cairo_raw), f'{filename1}: {len(cairo_mem) * 40} != {len(cairo_raw)}'
+
+    with cairo_vm_pie_zip.open("memory.bin", 'r') as f:
+        cairo_rs_raw = f.read()
+        print(len(cairo_rs_raw))
+        assert len(cairo_rs_raw) % 40 == 0, f'{filename2}: malformed memory file from cairo-vm'
+        chunks = len(cairo_rs_raw) // 40
+        for i in range(0, chunks):
+            chunk = cairo_rs_raw[i*40:(i+1)*40]
+            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
+            assert k not in cairo_rs_mem, f'{filename2}: address {k} has two values'
+            cairo_rs_mem[k] = v
+        assert len(cairo_rs_mem) * 40 == len(cairo_rs_raw), f'{filename2}: {len(cairo_rs_mem) * 40} != {len(cairo_rs_raw)}'
+
+    assert len(cairo_mem) == len(cairo_rs_mem), f'{filename2}: len(cairo_mem)={len(cairo_mem)} len(cairo_mem)={len(cairo_rs_mem)}'
+    if cairo_mem != cairo_rs_mem:
+        print(f'Mismatch between {filename1} (Cairo) and {filename2} (cairo_rs)')
+        print('keys in Cairo but not cairo-vm:')
+        for k in cairo_mem:
+            if k in cairo_rs_mem:
+                continue
+            print(f'{k}:{v}')
+        print('keys in cairo_rs but not Cairo:')
+        for k in cairo_rs_mem:
+            if k in cairo_mem:
+                continue
+            print(f'{k}:{v}')
+        print('mismatched values (Cairo <-> cairo_rs)):')
+        for k in cairo_rs_mem:
+            if k not in cairo_mem:
+                continue
+            if cairo_rs_mem[k] == cairo_mem[k]:
+                continue
+            print(f'{k}:({cairo_mem[k]} <-> {cairo_rs_mem[k]})')
+        exit(1)
diff --git a/vm/src/tests/memory_comparator.py b/vm/src/tests/memory_comparator.py
index c46d4910f3..7f8e95e5cd 100755
--- a/vm/src/tests/memory_comparator.py
+++ b/vm/src/tests/memory_comparator.py
@@ -52,6 +52,43 @@ def main():
             print(f'{k}:({cairo_mem[k]} <-> {cairo_rs_mem[k]})')
         exit(1)
 
+def compare_memory_file_contents(cairo_raw_mem, cairo_rs_raw_mem):
+    cairo_mem = read_memory_file_contents(cairo_raw_mem)
+    cairo_rs_mem = read_memory_file_contents(cairo_rs_raw_mem)
+
+    assert len(cairo_mem) == len(cairo_rs_mem), f'len(cairo_mem)={len(cairo_mem)} len(cairo_mem)={len(cairo_rs_mem)}'
+    if cairo_mem != cairo_rs_mem:
+        print(f'Mismatch between cairo_lang and cairo-vm')
+        print('keys in cairo_lang but not cairo-vm:')
+        for k in cairo_mem:
+            if k in cairo_rs_mem:
+                continue
+        print(f'{k}:{cairo_mem[k]}')
+        print('keys in cairo-vm but not cairo_lang:')
+        for k in cairo_rs_mem:
+            if k in cairo_mem:
+                continue
+            print(f'{k}:{cairo_rs_mem[k]}')
+        print('mismatched values (cairo_lang <-> cairo-vm)):')
+        for k in cairo_rs_mem:
+            if k not in cairo_mem:
+                continue
+            if cairo_rs_mem[k] == cairo_mem[k]:
+                continue
+            print(f'{k}:({cairo_mem[k]} <-> {cairo_rs_mem[k]})')
+        exit(1)
+
+def read_memory_file_contents(raw_mem_content) -> {}:
+        mem = {}
+        assert len(raw_mem_content) % 40 == 0, f'Malformed memory file'
+        chunks = len(raw_mem_content) // 40
+        for i in range(0, chunks):
+            chunk = raw_mem_content[i*40:(i+1)*40]
+            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
+            assert k not in mem, f'Address {k} has two values'
+            mem[k] = v
+        assert len(mem) * 40 == len(raw_mem_content), f'Malformed memory file'
+        return mem
 
 if __name__ == '__main__':
     main()

From f8699b792c8397484901f03b30f6c971eb28242d Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 19:50:53 -0300
Subject: [PATCH 18/37] Revert "Fix constant value"

This reverts commit 08e037eca1c0e4376f748a7bdca10462f19f586f.
---
 vm/src/vm/runners/cairo_pie.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index c70958d839..d3f4c9ddfa 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -154,7 +154,7 @@ mod serde_impl {
     pub const ADDR_BASE: u64 = 0x8000000000000000; // 2 ** (8 * ADDR_BYTE_LEN - 1)
     pub const OFFSET_BASE: u64 = 0x800000000000; // 2 ** OFFSET_BIT_LEN
     pub const RELOCATE_BASE: &str =
-        "57896044618658097711785492504343953926634992332820282019728792003956564819968"; // 2 ** (8 * FIELD_BYTE_LEN - 1)
+        "8000000000000000000000000000000000000000000000000000000000000000"; // 2 ** (8 * FIELD_BYTE_LEN - 1)
 
     struct Felt252Wrapper<'a>(&'a Felt252);
 

From 8ae33e169737171a304ca4ee8ab6490d06d5ea65 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Wed, 17 Jan 2024 20:18:25 -0300
Subject: [PATCH 19/37] Use to_bytes instead of serialize impl + simplify
 scripts

---
 vm/src/tests/cairo_pie_comparator.py | 48 ++------------------
 vm/src/tests/memory_comparator.py    | 47 +------------------
 vm/src/vm/runners/cairo_pie.rs       | 68 +++++++++++++++++++++++-----
 3 files changed, 61 insertions(+), 102 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 826e57e2ae..a74c35d1ef 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -3,6 +3,7 @@
 import sys
 import json
 from zipfile import ZipFile
+import memory_comparator
 
 filename1 = sys.argv[1]
 filename2 = sys.argv[2]
@@ -27,52 +28,9 @@
     print(f"Comparison succesful for {filename1} vs {filename2}")
 
     # Compare binary files
-    #Copy paste starts here
 
     cairo_mem = {}
     cairo_rs_mem = {}
 
-    with cairo_lang_pie_zip.open("memory.bin", 'r') as f:
-        cairo_raw = f.read()
-        assert len(cairo_raw) % 40 == 0, f'{filename1}: malformed memory file from Cairo VM'
-        chunks = len(cairo_raw) // 40
-        for i in range(0, chunks):
-            chunk = cairo_raw[i*40:(i+1)*40]
-            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
-            assert k not in cairo_mem, f'{filename1}: address {k} has two values'
-            cairo_mem[k] = v
-        assert len(cairo_mem) * 40 == len(cairo_raw), f'{filename1}: {len(cairo_mem) * 40} != {len(cairo_raw)}'
-
-    with cairo_vm_pie_zip.open("memory.bin", 'r') as f:
-        cairo_rs_raw = f.read()
-        print(len(cairo_rs_raw))
-        assert len(cairo_rs_raw) % 40 == 0, f'{filename2}: malformed memory file from cairo-vm'
-        chunks = len(cairo_rs_raw) // 40
-        for i in range(0, chunks):
-            chunk = cairo_rs_raw[i*40:(i+1)*40]
-            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
-            assert k not in cairo_rs_mem, f'{filename2}: address {k} has two values'
-            cairo_rs_mem[k] = v
-        assert len(cairo_rs_mem) * 40 == len(cairo_rs_raw), f'{filename2}: {len(cairo_rs_mem) * 40} != {len(cairo_rs_raw)}'
-
-    assert len(cairo_mem) == len(cairo_rs_mem), f'{filename2}: len(cairo_mem)={len(cairo_mem)} len(cairo_mem)={len(cairo_rs_mem)}'
-    if cairo_mem != cairo_rs_mem:
-        print(f'Mismatch between {filename1} (Cairo) and {filename2} (cairo_rs)')
-        print('keys in Cairo but not cairo-vm:')
-        for k in cairo_mem:
-            if k in cairo_rs_mem:
-                continue
-            print(f'{k}:{v}')
-        print('keys in cairo_rs but not Cairo:')
-        for k in cairo_rs_mem:
-            if k in cairo_mem:
-                continue
-            print(f'{k}:{v}')
-        print('mismatched values (Cairo <-> cairo_rs)):')
-        for k in cairo_rs_mem:
-            if k not in cairo_mem:
-                continue
-            if cairo_rs_mem[k] == cairo_mem[k]:
-                continue
-            print(f'{k}:({cairo_mem[k]} <-> {cairo_rs_mem[k]})')
-        exit(1)
+    with cairo_lang_pie_zip.open("memory.bin", 'r') as f1,  cairo_vm_pie_zip.open("memory.bin", 'r') as f2:
+        memory_comparator.compare_memory_file_contents(f1.read(), f2.read())
diff --git a/vm/src/tests/memory_comparator.py b/vm/src/tests/memory_comparator.py
index 7f8e95e5cd..686368a4d5 100755
--- a/vm/src/tests/memory_comparator.py
+++ b/vm/src/tests/memory_comparator.py
@@ -5,52 +5,9 @@
 def main():
     filename1 = sys.argv[1]
     filename2 = sys.argv[2]
-    cairo_mem = {}
-    cairo_rs_mem = {}
 
-    with open(filename1, 'rb') as f:
-        cairo_raw = f.read()
-        assert len(cairo_raw) % 40 == 0, f'{filename1}: malformed memory file from Cairo VM'
-        chunks = len(cairo_raw) // 40
-        for i in range(0, chunks):
-            chunk = cairo_raw[i*40:(i+1)*40]
-            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
-            assert k not in cairo_mem, f'{filename1}: address {k} has two values'
-            cairo_mem[k] = v
-        assert len(cairo_mem) * 40 == len(cairo_raw), f'{filename1}: {len(cairo_mem) * 40} != {len(cairo_raw)}'
-
-    with open(filename2, 'rb') as f:
-        cairo_rs_raw = f.read()
-        assert len(cairo_rs_raw) % 40 == 0, f'{filename2}: malformed memory file from cairo-vm'
-        chunks = len(cairo_rs_raw) // 40
-        for i in range(0, chunks):
-            chunk = cairo_rs_raw[i*40:(i+1)*40]
-            k, v = int.from_bytes(chunk[:8], 'little'), int.from_bytes(chunk[8:], 'little')
-            assert k not in cairo_rs_mem, f'{filename2}: address {k} has two values'
-            cairo_rs_mem[k] = v
-        assert len(cairo_rs_mem) * 40 == len(cairo_rs_raw), f'{filename2}: {len(cairo_rs_mem) * 40} != {len(cairo_rs_raw)}'
-
-    assert len(cairo_mem) == len(cairo_rs_mem), f'{filename2}: len(cairo_mem)={len(cairo_mem)} len(cairo_mem)={len(cairo_rs_mem)}'
-    if cairo_mem != cairo_rs_mem:
-        print(f'Mismatch between {filename1} (Cairo) and {filename2} (cairo_rs)')
-        print('keys in Cairo but not cairo-vm:')
-        for k in cairo_mem:
-            if k in cairo_rs_mem:
-                continue
-            print(f'{k}:{v}')
-        print('keys in cairo_rs but not Cairo:')
-        for k in cairo_rs_mem:
-            if k in cairo_mem:
-                continue
-            print(f'{k}:{v}')
-        print('mismatched values (Cairo <-> cairo_rs)):')
-        for k in cairo_rs_mem:
-            if k not in cairo_mem:
-                continue
-            if cairo_rs_mem[k] == cairo_mem[k]:
-                continue
-            print(f'{k}:({cairo_mem[k]} <-> {cairo_rs_mem[k]})')
-        exit(1)
+    with open(filename1, 'rb') as f1, open(filename2, 'rb') as f2:
+        compare_memory_file_contents(f1.read(), f2.read())
 
 def compare_memory_file_contents(cairo_raw_mem, cairo_rs_raw_mem):
     cairo_mem = read_memory_file_contents(cairo_raw_mem)
diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index d3f4c9ddfa..c763297189 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -120,7 +120,7 @@ impl CairoPie {
         zip_writer.start_file("metadata.json", options)?;
         zip_writer.write(serde_json::to_string(&self.metadata).unwrap().as_bytes())?;
         zip_writer.start_file("memory.bin", options)?;
-        zip_writer.write(serde_json::to_string(&self.memory).unwrap().as_bytes())?;
+        zip_writer.write(&self.memory.to_bytes())?;
         zip_writer.start_file("additional_data.json", options)?;
         zip_writer.write(
             serde_json::to_string(&self.additional_data)
@@ -139,14 +139,16 @@ impl CairoPie {
 }
 
 mod serde_impl {
+    use num_traits::Num;
     use std::collections::HashMap;
 
-    use super::CAIRO_PIE_VERSION;
+    use super::{CAIRO_PIE_VERSION, CairoPieMemory};
     use crate::{
         types::relocatable::{MaybeRelocatable, Relocatable},
         utils::CAIRO_PRIME,
         Felt252,
     };
+    use num_bigint::BigUint;
     use serde::{ser::SerializeSeq, Serialize, Serializer};
 
     pub const ADDR_BYTE_LEN: usize = 8;
@@ -210,36 +212,78 @@ mod serde_impl {
         let mut res = Vec::with_capacity(mem_cap);
 
         for ((segment, offset), value) in values.iter() {
+            let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
+            res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
             match value {
                 // Serializes RelocatableValue(little endian):
                 // 1bit |   SEGMENT_BITS |   OFFSET_BITS
                 // 1    |     segment    |   offset
                 MaybeRelocatable::RelocatableValue(rel_val) => {
-                    let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
-
-                    let reloc_base = Felt252::from_hex(RELOCATE_BASE)
+                    let reloc_base = BigUint::from_str_radix(RELOCATE_BASE, 16)
                         .map_err(|_| serde::ser::Error::custom("invalid relocation base str"))?;
                     let reloc_value = reloc_base
-                        + Felt252::from(rel_val.segment_index as usize)
-                            * Felt252::from(OFFSET_BASE)
-                        + Felt252::from(rel_val.offset);
-                    res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
+                        + BigUint::from(rel_val.segment_index as usize)
+                            * BigUint::from(OFFSET_BASE)
+                        + BigUint::from(rel_val.offset);
                     res.extend_from_slice(reloc_value.to_bytes_le().as_ref());
                 }
                 // Serializes Int(little endian):
                 // 1bit | Num
                 // 0    | num
                 MaybeRelocatable::Int(data_val) => {
-                    let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
-                    res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
                     res.extend_from_slice(data_val.to_bytes_le().as_ref());
                 }
             };
         }
 
-        serializer.serialize_bytes(&res)
+        serializer.serialize_str(
+            res.iter()
+                .map(|b| format!("{:02x}", b))
+                .collect::<String>()
+                .as_str(),
+        )
     }
 
+    impl CairoPieMemory {
+    pub fn to_bytes(&self) -> Vec<u8> {
+        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
+        use alloc::string::String;
+        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
+        use alloc::vec::Vec;
+
+        // Missing segment and memory holes can be ignored
+        // as they can be inferred by the address on the prover side
+        let values = &self.0;
+        let mem_cap = values.len() * ADDR_BYTE_LEN + values.len() * FIELD_BYTE_LEN;
+        let mut res = Vec::with_capacity(mem_cap);
+
+        for ((segment, offset), value) in values.iter() {
+            let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
+            res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
+            match value {
+                // Serializes RelocatableValue(little endian):
+                // 1bit |   SEGMENT_BITS |   OFFSET_BITS
+                // 1    |     segment    |   offset
+                MaybeRelocatable::RelocatableValue(rel_val) => {
+                    let reloc_base = BigUint::from_str_radix(RELOCATE_BASE, 16).unwrap();
+                    let reloc_value = reloc_base
+                        + BigUint::from(rel_val.segment_index as usize)
+                            * BigUint::from(OFFSET_BASE)
+                        + BigUint::from(rel_val.offset);
+                    res.extend_from_slice(reloc_value.to_bytes_le().as_ref());
+                }
+                // Serializes Int(little endian):
+                // 1bit | Num
+                // 0    | num
+                MaybeRelocatable::Int(data_val) => {
+                    res.extend_from_slice(data_val.to_bytes_le().as_ref());
+                }
+            };
+        }
+        res
+    }
+}
+
     pub fn serialize_prime<S>(_value: &(), serializer: S) -> Result<S::Ok, S::Error>
     where
         S: Serializer,

From 0ac1e33bc4b1a24e2aced9bcd0b99252caf62877 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 10:25:18 -0300
Subject: [PATCH 20/37] Cleanup

---
 vm/src/tests/cairo_pie_comparator.py | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index a74c35d1ef..61dc5d8ed5 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -25,12 +25,8 @@
                 print(f"Comparison unsuccesful for {filename1}/{file}  vs {filename2}/{file}")
                 exit(1)
 
-    print(f"Comparison succesful for {filename1} vs {filename2}")
-
     # Compare binary files
-
-    cairo_mem = {}
-    cairo_rs_mem = {}
-
     with cairo_lang_pie_zip.open("memory.bin", 'r') as f1,  cairo_vm_pie_zip.open("memory.bin", 'r') as f2:
         memory_comparator.compare_memory_file_contents(f1.read(), f2.read())
+
+    print(f"Comparison succesful for {filename1} vs {filename2}")

From 642efa7ab7295f193c9ac41d1c8eec9a344aff6e Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 10:30:39 -0300
Subject: [PATCH 21/37] Fix test

---
 vm/src/vm/vm_memory/memory.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs
index c05c52dffd..d6d17a2a47 100644
--- a/vm/src/vm/vm_memory/memory.rs
+++ b/vm/src/vm/vm_memory/memory.rs
@@ -1630,11 +1630,11 @@ mod memory_tests {
 
         assert_eq!(
             CairoPieMemory::from(&memory),
-            vec![
+            CairoPieMemory(vec![
                 ((1, 2), MaybeRelocatable::from(5)),
                 ((7, 6), MaybeRelocatable::from((1, 2))),
                 ((8, 9), MaybeRelocatable::from(3))
             ]
-        )
+        ))
     }
 }

From 405e8ff09f5e9e7b4725694d787d4c4b2586b942 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 10:45:48 -0300
Subject: [PATCH 22/37] Clean interface + remove unwraps

---
 cairo-vm-cli/src/main.rs       |   5 +-
 vm/src/vm/runners/cairo_pie.rs | 104 +++++++++++++++------------------
 vm/src/vm/vm_memory/memory.rs  |   4 +-
 3 files changed, 51 insertions(+), 62 deletions(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index a7d8497169..75fad7c893 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -9,7 +9,7 @@ use cairo_vm::vm::errors::trace_errors::TraceError;
 use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
 use clap::{CommandFactory, Parser, ValueHint};
 use std::io::{self, Write};
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use thiserror::Error;
 
 #[cfg(feature = "with_mimalloc")]
@@ -238,10 +238,11 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
     }
 
     if let Some(file_name) = args.cairo_pie_output {
+        let file_path = Path::new(&file_name);
         cairo_runner
             .get_cairo_pie(&vm)
             .map_err(CairoRunError::Runner)?
-            .write_zip_file(&file_name)
+            .write_zip_file(&file_path)
             .unwrap()
     }
 
diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index c763297189..4c4a17348d 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -105,35 +105,23 @@ pub struct CairoPieVersion {
 }
 
 impl CairoPie {
-    pub fn serialize_json(&self) -> Result<String, serde_json::Error> {
-        serde_json::to_string_pretty(&self)
-    }
-
-    pub fn write_zip_file(&self, file_name: &String) -> Result<(), std::io::Error> {
-        let path = Path::new(file_name);
-        let file = File::create(path).unwrap();
+    #[cfg(feature = "std")]
+    pub fn write_zip_file(&self, file_path: &Path) -> Result<(), std::io::Error> {
+        let file = File::create(file_path)?;
         let mut zip_writer = ZipWriter::new(file);
         let options =
             zip::write::FileOptions::default().compression_method(zip::CompressionMethod::Stored);
         zip_writer.start_file("version.json", options)?;
-        zip_writer.write(serde_json::to_string(&self.version).unwrap().as_bytes())?;
+        zip_writer.write_all(serde_json::to_string(&self.version)?.as_bytes())?;
         zip_writer.start_file("metadata.json", options)?;
-        zip_writer.write(serde_json::to_string(&self.metadata).unwrap().as_bytes())?;
+        zip_writer.write_all(serde_json::to_string(&self.metadata)?.as_bytes())?;
         zip_writer.start_file("memory.bin", options)?;
-        zip_writer.write(&self.memory.to_bytes())?;
+        zip_writer.write_all(&self.memory.to_bytes())?;
         zip_writer.start_file("additional_data.json", options)?;
-        zip_writer.write(
-            serde_json::to_string(&self.additional_data)
-                .unwrap()
-                .as_bytes(),
-        )?;
+        zip_writer.write_all(serde_json::to_string(&self.additional_data)?.as_bytes())?;
         zip_writer.start_file("execution_resources.json", options)?;
-        zip_writer.write(
-            serde_json::to_string(&self.execution_resources)
-                .unwrap()
-                .as_bytes(),
-        )?;
-        zip_writer.finish().unwrap();
+        zip_writer.write_all(serde_json::to_string(&self.execution_resources)?.as_bytes())?;
+        zip_writer.finish()?;
         Ok(())
     }
 }
@@ -142,7 +130,7 @@ mod serde_impl {
     use num_traits::Num;
     use std::collections::HashMap;
 
-    use super::{CAIRO_PIE_VERSION, CairoPieMemory};
+    use super::{CairoPieMemory, CAIRO_PIE_VERSION};
     use crate::{
         types::relocatable::{MaybeRelocatable, Relocatable},
         utils::CAIRO_PRIME,
@@ -245,44 +233,44 @@ mod serde_impl {
     }
 
     impl CairoPieMemory {
-    pub fn to_bytes(&self) -> Vec<u8> {
-        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-        use alloc::string::String;
-        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-        use alloc::vec::Vec;
-
-        // Missing segment and memory holes can be ignored
-        // as they can be inferred by the address on the prover side
-        let values = &self.0;
-        let mem_cap = values.len() * ADDR_BYTE_LEN + values.len() * FIELD_BYTE_LEN;
-        let mut res = Vec::with_capacity(mem_cap);
-
-        for ((segment, offset), value) in values.iter() {
-            let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
-            res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
-            match value {
-                // Serializes RelocatableValue(little endian):
-                // 1bit |   SEGMENT_BITS |   OFFSET_BITS
-                // 1    |     segment    |   offset
-                MaybeRelocatable::RelocatableValue(rel_val) => {
-                    let reloc_base = BigUint::from_str_radix(RELOCATE_BASE, 16).unwrap();
-                    let reloc_value = reloc_base
-                        + BigUint::from(rel_val.segment_index as usize)
-                            * BigUint::from(OFFSET_BASE)
-                        + BigUint::from(rel_val.offset);
-                    res.extend_from_slice(reloc_value.to_bytes_le().as_ref());
-                }
-                // Serializes Int(little endian):
-                // 1bit | Num
-                // 0    | num
-                MaybeRelocatable::Int(data_val) => {
-                    res.extend_from_slice(data_val.to_bytes_le().as_ref());
-                }
-            };
+        pub fn to_bytes(&self) -> Vec<u8> {
+            #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
+            use alloc::string::String;
+            #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
+            use alloc::vec::Vec;
+
+            // Missing segment and memory holes can be ignored
+            // as they can be inferred by the address on the prover side
+            let values = &self.0;
+            let mem_cap = values.len() * ADDR_BYTE_LEN + values.len() * FIELD_BYTE_LEN;
+            let mut res = Vec::with_capacity(mem_cap);
+
+            for ((segment, offset), value) in values.iter() {
+                let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64;
+                res.extend_from_slice(mem_addr.to_le_bytes().as_ref());
+                match value {
+                    // Serializes RelocatableValue(little endian):
+                    // 1bit |   SEGMENT_BITS |   OFFSET_BITS
+                    // 1    |     segment    |   offset
+                    MaybeRelocatable::RelocatableValue(rel_val) => {
+                        let reloc_base = BigUint::from_str_radix(RELOCATE_BASE, 16).unwrap();
+                        let reloc_value = reloc_base
+                            + BigUint::from(rel_val.segment_index as usize)
+                                * BigUint::from(OFFSET_BASE)
+                            + BigUint::from(rel_val.offset);
+                        res.extend_from_slice(reloc_value.to_bytes_le().as_ref());
+                    }
+                    // Serializes Int(little endian):
+                    // 1bit | Num
+                    // 0    | num
+                    MaybeRelocatable::Int(data_val) => {
+                        res.extend_from_slice(data_val.to_bytes_le().as_ref());
+                    }
+                };
+            }
+            res
         }
-        res
     }
-}
 
     pub fn serialize_prime<S>(_value: &(), serializer: S) -> Result<S::Ok, S::Error>
     where
diff --git a/vm/src/vm/vm_memory/memory.rs b/vm/src/vm/vm_memory/memory.rs
index d6d17a2a47..29b36900b0 100644
--- a/vm/src/vm/vm_memory/memory.rs
+++ b/vm/src/vm/vm_memory/memory.rs
@@ -1634,7 +1634,7 @@ mod memory_tests {
                 ((1, 2), MaybeRelocatable::from(5)),
                 ((7, 6), MaybeRelocatable::from((1, 2))),
                 ((8, 9), MaybeRelocatable::from(3))
-            ]
-        ))
+            ])
+        )
     }
 }

From 5f84875d9850f5e5bb01e784d7c1ff65648518d6 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 10:55:02 -0300
Subject: [PATCH 23/37] Fixes

---
 Makefile                 | 2 +-
 cairo-vm-cli/src/main.rs | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 3c60039b59..6afa9e5805 100644
--- a/Makefile
+++ b/Makefile
@@ -285,7 +285,7 @@ compare_trace_memory: $(CAIRO_RS_TRACE) $(CAIRO_TRACE) $(CAIRO_RS_MEM) $(CAIRO_M
 	cd vm/src/tests; ./compare_vm_state.sh trace memory
 
 compare_all_no_proof: $(CAIRO_RS_TRACE) $(CAIRO_TRACE) $(CAIRO_RS_MEM) $(CAIRO_MEM) $(CAIRO_RS_PIE) $(CAIRO_PIE)
-	cd vm/src/tests; ./compare_vm_state.sh trace memory
+	cd vm/src/tests; ./compare_vm_state.sh trace memory pie
 
 compare_trace: $(CAIRO_RS_TRACE) $(CAIRO_TRACE)
 	cd vm/src/tests; ./compare_vm_state.sh trace
diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index 75fad7c893..78911aaa64 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -237,8 +237,8 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         std::fs::write(file_path, json)?;
     }
 
-    if let Some(file_name) = args.cairo_pie_output {
-        let file_path = Path::new(&file_name);
+    if let Some(ref file_name) = args.cairo_pie_output {
+        let file_path = Path::new(file_name);
         cairo_runner
             .get_cairo_pie(&vm)
             .map_err(CairoRunError::Runner)?

From cd3dbaf247a3a71c225b21cd4c457959dd0c197a Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 10:55:43 -0300
Subject: [PATCH 24/37] clippy

---
 cairo-vm-cli/src/main.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index 78911aaa64..dd6381376a 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -242,7 +242,7 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         cairo_runner
             .get_cairo_pie(&vm)
             .map_err(CairoRunError::Runner)?
-            .write_zip_file(&file_path)
+            .write_zip_file(file_path)
             .unwrap()
     }
 

From 9b0a7ae1e81cd48f810bf0a7b8efb1207ee7c4a3 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:03:24 -0300
Subject: [PATCH 25/37] Move arg validation to a separate func

---
 cairo-vm-cli/src/main.rs | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index dd6381376a..351121b7df 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -112,9 +112,7 @@ impl FileWriter {
     }
 }
 
-fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
-    let args = Args::try_parse_from(args)?;
-
+fn validate_args(args: &Args) -> Result<(), Error> {
     if args.air_public_input.is_some() && !args.proof_mode {
         let error = Args::command().error(
             clap::error::ErrorKind::ArgumentConflict,
@@ -155,6 +153,14 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         return Err(Error::Cli(error));
     }
 
+    Ok(())
+}
+
+fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
+    let args = Args::try_parse_from(args)?;
+
+    validate_args(&args)?;
+
     let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some();
     let mut hint_executor = BuiltinHintProcessor::new_empty();
     let cairo_run_config = cairo_run::CairoRunConfig {

From 1c2760b9c14bd48315f4aa3ef7bc2de380e58d12 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:25:07 -0300
Subject: [PATCH 26/37] Move mutually exclusive argument validation to clap

---
 cairo-vm-cli/src/main.rs | 59 ++++++----------------------------------
 1 file changed, 9 insertions(+), 50 deletions(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index 351121b7df..e4ad4f10a5 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -7,7 +7,7 @@ use cairo_vm::hint_processor::builtin_hint_processor::builtin_hint_processor_def
 use cairo_vm::vm::errors::cairo_run_errors::CairoRunError;
 use cairo_vm::vm::errors::trace_errors::TraceError;
 use cairo_vm::vm::errors::vm_errors::VirtualMachineError;
-use clap::{CommandFactory, Parser, ValueHint};
+use clap::{Parser, ValueHint};
 use std::io::{self, Write};
 use std::path::{Path, PathBuf};
 use thiserror::Error;
@@ -38,11 +38,16 @@ struct Args {
     proof_mode: bool,
     #[structopt(long = "secure_run")]
     secure_run: Option<bool>,
-    #[clap(long = "air_public_input")]
+    #[clap(long = "air_public_input", requires = "proof_mode")]
     air_public_input: Option<String>,
-    #[clap(long = "air_private_input")]
+    #[clap(
+        long = "air_private_input",
+        requires = "proof_mode",
+        requires = "trace_file",
+        requires = "memory_file"
+    )]
     air_private_input: Option<String>,
-    #[clap(long = "cairo_pie_output")]
+    #[clap(long = "cairo_pie_output", conflicts_with = "proof_mode")]
     cairo_pie_output: Option<String>,
 }
 
@@ -112,55 +117,9 @@ impl FileWriter {
     }
 }
 
-fn validate_args(args: &Args) -> Result<(), Error> {
-    if args.air_public_input.is_some() && !args.proof_mode {
-        let error = Args::command().error(
-            clap::error::ErrorKind::ArgumentConflict,
-            "--air_public_input can only be used in proof_mode.",
-        );
-        return Err(Error::Cli(error));
-    }
-
-    if args.air_private_input.is_some() && !args.proof_mode {
-        let error = Args::command().error(
-            clap::error::ErrorKind::ArgumentConflict,
-            "--air_private_input can only be used in proof_mode.",
-        );
-        return Err(Error::Cli(error));
-    }
-
-    if args.air_private_input.is_some() && args.trace_file.is_none() {
-        let error = Args::command().error(
-            clap::error::ErrorKind::ArgumentConflict,
-            "--trace_file must be set when --air_private_input is set.",
-        );
-        return Err(Error::Cli(error));
-    }
-
-    if args.air_private_input.is_some() && args.memory_file.is_none() {
-        let error = Args::command().error(
-            clap::error::ErrorKind::ArgumentConflict,
-            "--memory_file must be set when --air_private_input is set.",
-        );
-        return Err(Error::Cli(error));
-    }
-
-    if args.cairo_pie_output.is_some() && args.proof_mode {
-        let error = Args::command().error(
-            clap::error::ErrorKind::ArgumentConflict,
-            "--proof_mode and --cairo_pie_output cannot be both specified.",
-        );
-        return Err(Error::Cli(error));
-    }
-
-    Ok(())
-}
-
 fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
     let args = Args::try_parse_from(args)?;
 
-    validate_args(&args)?;
-
     let trace_enabled = args.trace_file.is_some() || args.air_public_input.is_some();
     let mut hint_executor = BuiltinHintProcessor::new_empty();
     let cairo_run_config = cairo_run::CairoRunConfig {

From d0a634f3cb4a15d7eb01788224015cbbb8f7b1c7 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:29:40 -0300
Subject: [PATCH 27/37] rename var

---
 vm/src/tests/cairo_pie_comparator.py | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/vm/src/tests/cairo_pie_comparator.py b/vm/src/tests/cairo_pie_comparator.py
index 61dc5d8ed5..b4d6629401 100755
--- a/vm/src/tests/cairo_pie_comparator.py
+++ b/vm/src/tests/cairo_pie_comparator.py
@@ -8,11 +8,11 @@
 filename1 = sys.argv[1]
 filename2 = sys.argv[2]
 
-strict_comparison_files = ["version.json", "metadata.json", "execution_resources.json", "additional_data.json"]
+json_files = ["version.json", "metadata.json", "execution_resources.json", "additional_data.json"]
 
 with ZipFile(filename1) as cairo_lang_pie_zip, ZipFile(filename2) as cairo_vm_pie_zip:
     # Compare json files
-    for file in strict_comparison_files:
+    for file in json_files:
         # Skipping this check due to a bug in the memory holes count
         # TODO: Remove it once the bug is fixed
         if (filename1 == "../../../cairo_programs/_keccak_alternative_hint.pie.zip" or filename1 == "../../../cairo_programs/relocate_temporary_segment_append.pie.zip" or filename1 == "../../../cairo_programs/keccak_alternative_hint.pie.zip") and file == "execution_resources.json":

From 230bf07cd82d693909438afbdca9186d353228c1 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:36:39 -0300
Subject: [PATCH 28/37] Add Chaneglog entry

---
 CHANGELOG.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64620c5850..1cd3d5ef81 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,11 @@
 
 #### Upcoming Changes
 
+* feat: Add `cairo_pie_output` flag to `cairo_vm_cli` [#1578] (https://github.com/lambdaclass/cairo-vm/pull/1578)
+  * Fix serialization of CairoPie to be fully compatible with the python version
+  * Add `CairoPie::write_zip_file`
+  * Move handling of required and exclusive arguments in `cairo-vm-cli` to struct definition using clap derives
+
 * feat: Add `air_private_input` flag to `cairo1-run` [#1559] (https://github.com/lambdaclass/cairo-vm/pull/1559)
 
 * feat: Add `args` flag to `cairo1-run` [#15551] (https://github.com/lambdaclass/cairo-vm/pull/15551)

From f4c7a96daf23577685fb357d3b381ddc9d304984 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:38:28 -0300
Subject: [PATCH 29/37] Make zip dep optional

---
 vm/Cargo.toml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/vm/Cargo.toml b/vm/Cargo.toml
index a7af63173d..6c33144a20 100644
--- a/vm/Cargo.toml
+++ b/vm/Cargo.toml
@@ -19,6 +19,7 @@ std = [
     "starknet-crypto/std",
     "dep:num-prime",
     "thiserror-no-std/std",
+    "dep:zip",
 ]
 cairo-1-hints = [
     "dep:cairo-lang-starknet",
@@ -42,7 +43,7 @@ extensive_hints = []
 print = ["std"]
 
 [dependencies]
-zip = "0.6.6"
+zip = {version = "0.6.6", optional = true }
 mimalloc = { workspace = true, optional = true }
 num-bigint = { workspace = true }
 rand = { workspace = true }

From 333e6f8f0df949c82ccaea98d71ce9fa1da2bde5 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 11:59:31 -0300
Subject: [PATCH 30/37] Fix wasm imports

---
 vm/src/vm/runners/cairo_pie.rs | 22 ++++++++--------------
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs
index 4c4a17348d..a768893d02 100644
--- a/vm/src/vm/runners/cairo_pie.rs
+++ b/vm/src/vm/runners/cairo_pie.rs
@@ -1,6 +1,5 @@
-use std::{fs::File, io::Write, path::Path};
-
 use super::cairo_runner::ExecutionResources;
+use crate::stdlib::prelude::{String, Vec};
 use crate::{
     serde::deserialize_program::BuiltinName,
     stdlib::{collections::HashMap, prelude::*},
@@ -8,7 +7,11 @@ use crate::{
     Felt252,
 };
 use serde::{Deserialize, Serialize};
-use zip::ZipWriter;
+#[cfg(feature = "std")]
+use {
+    std::{fs::File, io::Write, path::Path},
+    zip::ZipWriter,
+};
 
 const CAIRO_PIE_VERSION: &str = "1.1";
 
@@ -127,10 +130,11 @@ impl CairoPie {
 }
 
 mod serde_impl {
+    use crate::stdlib::collections::HashMap;
     use num_traits::Num;
-    use std::collections::HashMap;
 
     use super::{CairoPieMemory, CAIRO_PIE_VERSION};
+    use crate::stdlib::prelude::{String, Vec};
     use crate::{
         types::relocatable::{MaybeRelocatable, Relocatable},
         utils::CAIRO_PRIME,
@@ -189,11 +193,6 @@ mod serde_impl {
     where
         S: Serializer,
     {
-        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-        use alloc::string::String;
-        #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-        use alloc::vec::Vec;
-
         // Missing segment and memory holes can be ignored
         // as they can be inferred by the address on the prover side
         let mem_cap = values.len() * ADDR_BYTE_LEN + values.len() * FIELD_BYTE_LEN;
@@ -234,11 +233,6 @@ mod serde_impl {
 
     impl CairoPieMemory {
         pub fn to_bytes(&self) -> Vec<u8> {
-            #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-            use alloc::string::String;
-            #[cfg(any(target_arch = "wasm32", no_std, not(feature = "std")))]
-            use alloc::vec::Vec;
-
             // Missing segment and memory holes can be ignored
             // as they can be inferred by the address on the prover side
             let values = &self.0;

From 8ad3c66cc025a637084e0413461255fd8ffea968 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 12:11:30 -0300
Subject: [PATCH 31/37] Add file extension

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 6afa9e5805..239508e029 100644
--- a/Makefile
+++ b/Makefile
@@ -100,7 +100,7 @@ $(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory $(TEST_DIR)/%.rs.pie.zip: $(TEST_
 	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $(@D)/$(*F) --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
 
 $(TEST_DIR)/%.trace $(TEST_DIR)/%.memory $(TEST_DIR)/%.pie.zip: $(TEST_DIR)/%.json
-	cairo-run --layout starknet_with_keccak --program $< --trace_file $(@D)/$(*F) --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip
+	cairo-run --layout starknet_with_keccak --program $< --trace_file $(@D)/$(*F).trace --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip
 
 $(NORETROCOMPAT_DIR)/%.json: $(NORETROCOMPAT_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR):$(NORETROCOMPAT_DIR)" $< --output $@

From 03426ba346697fa9d98db662055ef39094f6023e Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 12:43:48 -0300
Subject: [PATCH 32/37] Add file extension

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 239508e029..1da8c57d2d 100644
--- a/Makefile
+++ b/Makefile
@@ -97,7 +97,7 @@ $(TEST_DIR)/%.json: $(TEST_DIR)/%.cairo
 	cairo-compile --cairo_path="$(TEST_DIR):$(BENCH_DIR)" $< --output $@
 
 $(TEST_DIR)/%.rs.trace $(TEST_DIR)/%.rs.memory $(TEST_DIR)/%.rs.pie.zip: $(TEST_DIR)/%.json $(RELBIN)
-	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $(@D)/$(*F) --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
+	cargo llvm-cov run -p cairo-vm-cli --release --no-report -- --layout all_cairo $< --trace_file $(@D)/$(*F).rs.trace --memory_file $(@D)/$(*F).rs.memory --cairo_pie_output $(@D)/$(*F).rs.pie.zip
 
 $(TEST_DIR)/%.trace $(TEST_DIR)/%.memory $(TEST_DIR)/%.pie.zip: $(TEST_DIR)/%.json
 	cairo-run --layout starknet_with_keccak --program $< --trace_file $(@D)/$(*F).trace --memory_file $(@D)/$(*F).memory --cairo_pie_output $(@D)/$(*F).pie.zip

From 0a130f730aacb9f75caa699eb8d55bef7c2f15ee Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 14:04:39 -0300
Subject: [PATCH 33/37] Remove unwrap + improve coverage

---
 cairo-vm-cli/src/main.rs | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index e4ad4f10a5..328be606aa 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -207,8 +207,7 @@ fn run(args: impl Iterator<Item = String>) -> Result<(), Error> {
         cairo_runner
             .get_cairo_pie(&vm)
             .map_err(CairoRunError::Runner)?
-            .write_zip_file(file_path)
-            .unwrap()
+            .write_zip_file(file_path)?
     }
 
     Ok(())
@@ -291,6 +290,7 @@ mod tests {
         #[values(false, true)] entrypoint: bool,
         #[values(false, true)] air_public_input: bool,
         #[values(false, true)] air_private_input: bool,
+        #[values(false, true)] cairo_pie_output: bool,
     ) {
         let mut args = vec!["cairo-vm-cli".to_string()];
         if let Some(layout) = layout {
@@ -302,6 +302,9 @@ mod tests {
         if air_private_input {
             args.extend_from_slice(&["--air_private_input".to_string(), "/dev/null".to_string()]);
         }
+        if cairo_pie_output {
+            args.extend_from_slice(&["--cairo_pie_output".to_string(), "/dev/null".to_string()]);
+        }
         if proof_mode {
             trace_file = true;
             args.extend_from_slice(&["--proof_mode".to_string()]);
@@ -325,6 +328,7 @@ mod tests {
         args.push("../cairo_programs/proof_programs/fibonacci.json".to_string());
         if air_public_input && !proof_mode
             || (air_private_input && (!proof_mode || !trace_file || !memory_file))
+            || cairo_pie_output && proof_mode
         {
             assert_matches!(run(args.into_iter()), Err(_));
         } else {

From 4ca5964429fdf0198e434a963f7e6d049d37c5f9 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 15:35:57 -0300
Subject: [PATCH 34/37] quick fix

---
 cairo-vm-cli/src/main.rs | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index 328be606aa..4deab7b8be 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -47,7 +47,13 @@ struct Args {
         requires = "memory_file"
     )]
     air_private_input: Option<String>,
-    #[clap(long = "cairo_pie_output", conflicts_with = "proof_mode")]
+    #[clap(
+        long = "cairo_pie_output",
+        conflicts_with = "proof_mode",
+        // We need to add these two or else passing cairo_pie_output + either of these without proof_mode will fail
+        conflicts_with = "air_private_input",
+        conflicts_with = "air_public_input",
+    )]
     cairo_pie_output: Option<String>,
 }
 

From 2cce1a678a070374dfef9376ff9014b8c804b1b7 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 15:42:22 -0300
Subject: [PATCH 35/37] Clean solution

---
 cairo-vm-cli/src/main.rs | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/cairo-vm-cli/src/main.rs b/cairo-vm-cli/src/main.rs
index 4deab7b8be..a3c349d79a 100644
--- a/cairo-vm-cli/src/main.rs
+++ b/cairo-vm-cli/src/main.rs
@@ -42,17 +42,14 @@ struct Args {
     air_public_input: Option<String>,
     #[clap(
         long = "air_private_input",
-        requires = "proof_mode",
-        requires = "trace_file",
-        requires = "memory_file"
+        requires_all = ["proof_mode", "trace_file", "memory_file"] 
     )]
     air_private_input: Option<String>,
     #[clap(
         long = "cairo_pie_output",
-        conflicts_with = "proof_mode",
-        // We need to add these two or else passing cairo_pie_output + either of these without proof_mode will fail
-        conflicts_with = "air_private_input",
-        conflicts_with = "air_public_input",
+        // We need to add these air_private_input & air_public_input or else
+        // passing cairo_pie_output + either of these without proof_mode will not fail
+        conflicts_with_all = ["proof_mode", "air_private_input", "air_public_input"]
     )]
     cairo_pie_output: Option<String>,
 }

From 3ab3d3089dc2f56d406c25284781463ca4442158 Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Thu, 18 Jan 2024 15:46:56 -0300
Subject: [PATCH 36/37] Update README

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index 1e45ad3f50..1d7d274d46 100644
--- a/README.md
+++ b/README.md
@@ -175,6 +175,8 @@ The cairo-vm-cli supports the following optional arguments:
 
 - `--air_private_input <AIR_PRIVATE_INPUT>`: Receives the name of a file and outputs the AIR private inputs into it. Can only be used if proof_mode, trace_file & memory_file are also enabled.
 
+- `--cairo_pie_output <CAIRO_PIE_OUTPUT>`: Receives the name of a file and outputs the Cairo PIE into it. Can only be used if proof_mode, is not enabled.
+
 For example, to obtain the air public inputs from a fibonacci program run, we can run :
 
 ```bash

From e539c1397a5913713ab44fdf2a60be251a2296eb Mon Sep 17 00:00:00 2001
From: Federica <fedemoletta@hotmail.com>
Date: Fri, 19 Jan 2024 15:07:09 -0300
Subject: [PATCH 37/37] Update makefile targets

---
 Makefile | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/Makefile b/Makefile
index bef40b55dc..c1f433574a 100644
--- a/Makefile
+++ b/Makefile
@@ -234,11 +234,11 @@ cairo_bench_programs: $(COMPILED_BENCHES)
 cairo_1_test_contracts: $(CAIRO_1_COMPILED_CASM_CONTRACTS)
 cairo_2_test_contracts: $(CAIRO_2_COMPILED_CASM_CONTRACTS)
 
-cairo_proof_trace: $(CAIRO_TRACE_PROOF) $(CAIRO_MEM_PROOF) $(CAIRO_AIR_PUBLIC_INPUT)
-cairo-vm_proof_trace: $(CAIRO_RS_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_RS_AIR_PUBLIC_INPUT)
+cairo_proof_trace: $(CAIRO_TRACE_PROOF) $(CAIRO_MEM_PROOF) $(CAIRO_AIR_PUBLIC_INPUT) $(CAIRO_AIR_PRIVATE_INPUT)
+cairo-vm_proof_trace: $(CAIRO_RS_TRACE_PROOF) $(CAIRO_RS_MEM_PROOF) $(CAIRO_RS_AIR_PUBLIC_INPUT) $(CAIRO_RS_AIR_PRIVATE_INPUT)
 
-cairo_trace: $(CAIRO_TRACE) $(CAIRO_MEM)
-cairo-vm_trace: $(CAIRO_RS_TRACE) $(CAIRO_RS_MEM)
+cairo_trace: $(CAIRO_TRACE) $(CAIRO_MEM) $(CAIRO_PIE)
+cairo-vm_trace: $(CAIRO_RS_TRACE) $(CAIRO_RS_MEM) $(CAIRO_RS_PIE)
 
 test: cairo_proof_programs cairo_test_programs cairo_1_test_contracts cairo_2_test_contracts
 	cargo llvm-cov nextest --no-report --workspace --features "test_utils, cairo-1-hints"