diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 3299c95440f30ff9e94d7f0efa38904a2734dab9..15af260b6b731d128f00abb1811edcf04e9da76c 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -31,13 +31,8 @@ jobs:
           sudo apt update --yes
           sudo apt upgrade --yes
           sudo apt install protobuf-compiler --yes
-      - name: Install Nushell
-        run: |
-          # looks like the following PATH export does not work and `NU` still needs to be set for some reason to invoke `make`...
-          echo "PATH=\"$(make print-NU_DEST):$PATH\"" >> $GITHUB_ENV
-          make install-nu
       - name: Show configuration
-        run: make NU="$(make print-NU_DEST)/nu" show
+        run: make show
       - name: Run tests
         run: |
-          make NU="$(make print-NU_DEST)/nu" check clippy test example
+          make check clippy test
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index daa0125bc0891e723f0a60958d68002af8641c86..a1720e8ab1ef72320bdbbe20c7629b1af6456b03 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -28,9 +28,7 @@ test:
     - apt update --yes
     - apt upgrade --yes
     - apt install protobuf-compiler --yes
-    - export PATH="$(make print-NU_DEST):$PATH"
-    - make install-nu
     - make show
 
   script:
-    - make check clippy test example
+    - make check clippy test
diff --git a/Cargo.toml b/Cargo.toml
index b2797fda681e9ce44274aa1b1eaa0c9c5f00bbb5..5d4cd0d9a7a30fba5b5f0f817fb66c15d6b01752 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,7 +31,6 @@ dragoonfri = { version = "0.1.0", optional = true}
 members = [
     "benchmarks",
     "bins/rank",
-    "bins/saclin",
 ]
 
 [dev-dependencies]
@@ -66,4 +65,4 @@ required-features = ["fri"]
 
 [[example]]
 name = "fec"
-required-features = ["fri"]
\ No newline at end of file
+required-features = ["fri"]
diff --git a/Makefile b/Makefile
index bdc911171d3e5f7c70f357fda95fb8ad75d632d7..c9913f0524fcb969ec26ab2240e693c5a232715d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,4 @@
-NU="nu"
-NU_FLAGS="--no-config-file"
-
-NU_ARCH="x86_64-unknown-linux-musl"
-NU_VERSION="0.101.0"
-NU_BUILD="nu-${NU_VERSION}-${NU_ARCH}"
-NU_DEST="/tmp/"
-
-DEFAULT_GOAL: fmt-check check clippy test-rs
+DEFAULT_GOAL: fmt-check check clippy test
 
 .PHONY: fmt-check
 fmt-check:
@@ -16,16 +8,8 @@ fmt-check:
 fmt:
 	cargo fmt --all
 
-.PHONY: install-nu
-install-nu:
-	mkdir -p "${NU_DEST}"
-	curl -fLo "${NU_DEST}/nu.tar.gz" "https://github.com/nushell/nushell/releases/download/${NU_VERSION}/${NU_BUILD}.tar.gz"
-	tar xvf "${NU_DEST}/nu.tar.gz" --directory "${NU_DEST}"
-	cp "${NU_DEST}/${NU_BUILD}/nu" "${NU_DEST}/nu"
-
 .PHONY: check
 check:
-	${NU} ${NU_FLAGS} scripts/check-nushell-files.nu
 	cargo check --workspace --all-targets
 	cargo check --workspace --all-targets --features kzg
 	cargo check --workspace --all-targets --features aplonk
@@ -35,23 +19,11 @@ check:
 clippy:
 	cargo clippy --workspace --all-targets --all-features -- -D warnings
 
-.PHONY: test-rs
-test-rs:
+.PHONY: test
+test:
 	cargo test --workspace --verbose --all-features
 	cargo test --examples --verbose
 
-.PHONY: test-nu
-test-nu:
-	${NU} ${NU_FLAGS} bins/saclin/tests/cli.nu
-	${NU} ${NU_FLAGS} bins/saclin/tests/binary.nu
-
-.PHONY: test
-test: test-rs test-nu
-
-.PHONY: example
-example:
-	${NU} ${NU_FLAGS} bins/saclin/examples/cli.nu
-
 .PHONY: show
 show:
 	@rustup --version 2> /dev/null
@@ -59,7 +31,6 @@ show:
 	@rustc --version
 	@cargo --version
 	@cargo clippy --version
-	@${NU} ${NU_FLAGS} --commands "version"
 
 .PHONY: doc
 doc:
diff --git a/README.md b/README.md
index d29178c066e4871de0f7c31691636fdb43df3092..f309ec76b27e1cbb3155b454681deda482dfbc26 100644
--- a/README.md
+++ b/README.md
@@ -15,23 +15,7 @@ make
 ```
 or
 ```shell
-make check clippy test-rs
-```
-
-### some extra tests
-this project defines some tests written in [Nushell](https://www.nushell.sh/) to test an
-[implementation of Komodo in a CLI application](bins/saclin/).
-
-If you have [Nushell installed](https://www.nushell.sh/book/installation.html), you can run these
-with the following command:
-```shell
-make test-nu
-```
-
-## examples
-A [CLI example](bins/saclin/examples/cli.nu) is also provided and can be run with
-```shell
-make example
+make check clippy test
 ```
 
 Other examples that showcase the Komodo API are available in [`examples/`](examples/).
diff --git a/bins/saclin/Cargo.toml b/bins/saclin/Cargo.toml
deleted file mode 100644
index bd89b21402b51c7643099af5be0f6bbd24d18c32..0000000000000000000000000000000000000000
--- a/bins/saclin/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-name = "saclin"
-version = "1.0.1"
-edition = "2021"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-anyhow = "1.0.81"
-ark-bls12-381 = "0.4.0"
-ark-ec = "0.4.2"
-ark-ff = "0.4.2"
-ark-poly = "0.4.2"
-ark-serialize = "0.4.2"
-ark-std = "0.4.0"
-komodo = { path = "../../", features = ["fs"] }
-rand = "0.8.5"
-tracing = "0.1.40"
-tracing-subscriber = "0.3.17"
diff --git a/bins/saclin/README.md b/bins/saclin/README.md
deleted file mode 100644
index 53cd160d0986cccac8133a5c39d18008659df5ce..0000000000000000000000000000000000000000
--- a/bins/saclin/README.md
+++ /dev/null
@@ -1 +0,0 @@
-## CLI app using Semi-AVID
diff --git a/bins/saclin/binary.nu b/bins/saclin/binary.nu
deleted file mode 100644
index 2f30ec71138b5209f0a6ee93369d052daeaf10e4..0000000000000000000000000000000000000000
--- a/bins/saclin/binary.nu
+++ /dev/null
@@ -1,10 +0,0 @@
-export def "bytes from_int" []: [int -> binary, list<int> -> binary] {
-    each { into binary --compact } | bytes collect
-}
-
-export def "bytes to_int" []: binary -> list<int> {
-    let bytes = $in
-    seq 1 ($bytes | bytes length) | each {|i|
-        $bytes | bytes at ($i - 1)..($i) | get 0
-    }
-}
diff --git a/bins/saclin/examples/cli.nu b/bins/saclin/examples/cli.nu
deleted file mode 100755
index bdc31972a656753bde19c349107168a6db8570e7..0000000000000000000000000000000000000000
--- a/bins/saclin/examples/cli.nu
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env nu
-use .. [
-    "saclin build",
-    "saclin setup",
-    "saclin prove",
-    "saclin verify",
-    "saclin reconstruct",
-    "saclin ls",
-]
-use ../binary.nu [ "bytes from_int" ]
-
-use std assert
-
-const BYTES = "assets/dragoon_32x32.png"
-const FEC_PARAMS = { k: 3, n: 5 }
-
-const BLOCKS_TO_VERIFY = [0, 1]
-const BLOCKS_TO_RECONSTRUCT = [0, 2, 3]
-
-def main [] {
-    saclin build
-
-    saclin setup (open $BYTES | into binary | bytes length)
-    saclin prove $BYTES --fec-params $FEC_PARAMS
-
-    let blocks = saclin ls
-
-    saclin verify ...($BLOCKS_TO_VERIFY | each {|i| $blocks | get $i })
-
-    let actual = saclin reconstruct ...($BLOCKS_TO_RECONSTRUCT | each {|i| $blocks | get $i })
-    let expected = open $BYTES | bytes from_int
-    assert equal $actual $expected
-
-    print "reconstruction was successful"
-}
diff --git a/bins/saclin/mod.nu b/bins/saclin/mod.nu
deleted file mode 100644
index 2080cb25c8787ceb3321f3f9e4baba6d3345816a..0000000000000000000000000000000000000000
--- a/bins/saclin/mod.nu
+++ /dev/null
@@ -1,381 +0,0 @@
-# Welcome to SACLIN (**S**emi-**A**VID **CLI** in **N**ushell), a tool to encode and prove data.
-#
-# please run `saclin --help` or `saclin <tab>` to have a look at more information
-
-module binary.nu
-
-use binary ["bytes from_int"]
-
-const BIN = "./target/release/saclin"
-const DEFAULT_LOG_LEVEL = "INFO"
-
-def home-dir []: nothing -> path {
-    $env.SACLIN_HOME? | default (
-        $env.XDG_DATA_HOME? | default "~/.local/share" | path join "saclin"
-    ) | path expand
-}
-
-def block-dir []: nothing -> path {
-    home-dir | path join "blocks"
-}
-
-def "nu-complete log-levels" []: nothing -> list<string> {
-    [
-        "TRACE"
-        "DEBUG",
-        "INFO",
-        "WARN",
-        "ERROR",
-    ]
-}
-
-def "nu-complete encoding-methods" []: nothing -> list<string> {
-    [
-        "vandermonde"
-        "random",
-    ]
-}
-
-def run-saclin [
-    --input: path = "",
-    --nb-bytes: int = 0,
-    -k: int = 0,
-    -n: int = 0,
-    --generate-powers,
-    --reconstruct,
-    --verify,
-    --combine,
-    --inspect,
-    --encoding-method: string = "",
-    --log-level: string,
-    ...block_hashes: string,
-]: nothing -> any {
-    let home_dir = home-dir
-    if not ($home_dir | is-empty) {
-        mkdir $home_dir
-    }
-    let block_dir = block-dir
-    if not ($block_dir | is-empty) {
-        mkdir $block_dir
-    }
-
-    with-env {RUST_LOG: $log_level} {
-        let res = do {
-            ^$BIN ...([
-                $input
-                $k
-                $n
-                ($generate_powers | into string)
-                $home_dir
-                ($reconstruct | into string)
-                ($verify | into string)
-                ($combine | into string)
-                ($inspect | into string)
-                $nb_bytes
-                $encoding_method
-            ] | append $block_hashes)
-        } | complete
-
-        print --no-newline $res.stdout
-        if $res.exit_code != 0 {
-            error make --unspanned { msg: $"($res.stderr) \(($res.exit_code)\)" }
-        }
-        $res.stderr | from json
-    }
-}
-
-def list-blocks []: nothing -> list<string> {
-    try {
-        ls (block-dir) | get name | path parse | get stem
-    } catch {
-        []
-    }
-}
-
-# build SACLIN from source, updating the application
-export def "saclin build" []: nothing -> nothing {
-    ^cargo build --release --manifest-path bins/saclin/Cargo.toml
-}
-
-# create a random trusted setup for a given amount of data
-#
-# # Examples
-# ```nushell
-# # create a trusted setup well suited for a file called `my_target_file.txt`
-# saclin setup (open my_target_file.txt | into binary | bytes length)
-# ```
-# ---
-# ```nushell
-# # create a trusted setup for 50k bytes and make sure the setup has been created
-# saclin setup 50_000
-# use std assert; assert ("~/.local/share/saclin/powers" | path exists)
-export def "saclin setup" [
-    nb_bytes: int, # the size of the biggest expected data during the lifetime of the application
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> nothing {
-    (
-        run-saclin
-            --log-level $log_level
-            --nb-bytes $nb_bytes
-            --generate-powers
-    )
-}
-
-# encode and _prove_ a bunch of input bytes
-#
-# # Examples
-# ```nushell
-# # encode and prove `assets/dragoon_32x32.png` with a _3 x 5_ Vandermonde encoding
-# saclin prove assets/dragoon_32x32.png --fec-params {k: 3, n: 5} --encoding-method vandermonde
-# ```
-# ```
-# ─┬────────────────────────────────────────────────────────────────
-# 0│44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3
-# 1│8be575889246fbc49f4c748ac2dc1cd8a4ef71d16e91c9343660a5f79f086
-# 2│6de9fd5fdfe8c08b3132e0d527b14a2a4e4be9a543af1f13d2c397bd113846e4
-# 3│f1c34065cbfc3267f9d41558a465ba6335fd45229ff2eae5b34a8f30467562
-# 4│7aa698f338605462205c5ff46b5463720d073de92a19f897cc4ae6c286ab87
-# ─┴────────────────────────────────────────────────────────────────
-# ```
-export def "saclin prove" [
-    input: path, # the path to the input file to encode and prove
-    --fec-params: record<k: int, n: int>, # the parameters of the encoding
-    --encoding-method: string@"nu-complete encoding-methods" = "random", # the encoding method, e.g. _random_ or _vandermonde_
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> list<string> {
-    # NOTE: the next two runtime checks on the type of `--fec-params` might be
-    # a bug on the Nushell side
-    if $fec_params == null {
-        error make --unspanned {
-            msg: "`saclin prove` requires `--fec-params` to be given"
-        }
-    }
-
-    let type = $fec_params | describe --detailed | update columns { sort }
-    let expected = { type: record, columns: { k: int, n: int } }
-    if $type != $expected {
-        error make {
-            msg: $"(ansi red_bold)invalid `--fec-params`(ansi reset)",
-            label: {
-                text: $"expected ($expected) got ($type)",
-                span: (metadata $fec_params).span,
-            }
-        }
-    }
-
-    (
-        run-saclin
-            --log-level $log_level
-            --input $input
-            -k $fec_params.k
-            -n $fec_params.n
-            --encoding-method $encoding_method
-    )
-}
-
-# verify the integrity of any number of blocks
-#
-# # Examples
-# ```nushell
-# # verify the integrity of two blocks (note the use of the spread operator introduced in Nushell 0.89.0)
-# # > **Note**
-# # > file: `assets/dragoon_32x32.png`
-# # > parameters: k = 3 and n = 5
-# # > method: vandermonde
-# saclin verify ...[
-#     44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3,
-#     7aa698f338605462205c5ff46b5463720d073de92a19f897cc4ae6c286ab87,
-# ]
-# ```
-# ```
-# #┬─────────────────────────────block─────────────────────────────┬status
-# 0│44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3│true
-# 1│7aa698f338605462205c5ff46b5463720d073de92a19f897cc4ae6c286ab87 │true
-# ─┴───────────────────────────────────────────────────────────────┴──────
-# ```
-export def "saclin verify" [
-    ...blocks: string@"list-blocks", # the list of blocks to verify
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> table<block: string, status: int> {
-    run-saclin --log-level $log_level --verify ...$blocks
-}
-
-# reconstruct the original data from a subset of blocks
-#
-# `saclin reconstruct` might throw an error in some cases
-# - when there are too few blocks
-# - when the blocks are linearly dependant, and thus the decoding cannot be applied
-# - when the blocks belong to different data
-#
-# # Examples
-# ```nushell
-# # applying a valid reconstruction
-# # > **Note**
-# # > file: `assets/dragoon_32x32.png`
-# # > parameters: k = 3 and n = 5
-# # > method: vandermonde
-# let bytes = saclin reconstruct ...[
-#     44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3,
-#     7aa698f338605462205c5ff46b5463720d073de92a19f897cc4ae6c286ab87,
-#     8be575889246fbc49f4c748ac2dc1cd8a4ef71d16e91c9343660a5f79f086,
-# ]
-# $bytes | bytes at 0..10
-# ```
-# ```
-# Length: 10 (0xa) bytes | printable whitespace ascii_other non_ascii
-# 00000000:   89 50 4e 47  0d 0a 1a 0a  00 00                      ×PNG__•_00
-# ```
-# ---
-# ```nushell
-# # giving too few blocks
-# # > **Note**
-# # > file: `assets/dragoon_32x32.png`
-# # > parameters: k = 3 and n = 5
-# # > method: vandermonde
-# saclin reconstruct ...[
-#     44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3,
-#     7aa698f338605462205c5ff46b5463720d073de92a19f897cc4ae6c286ab87,
-# ]
-# ```
-# ```
-# Error:   × could not decode: Expected at least 3, got 2 (1)
-# ```
-# ---
-# ```nushell
-# # after combining _44614d_ and _6de9fd_ (see [`saclin combine`]), try to decode with linear dependencies
-# # > **Note**
-# # > file: `assets/dragoon_32x32.png`
-# # > parameters: k = 3 and n = 5
-# # > method: vandermonde
-# # > recoding: _44614d_ <+> _6de9fd_ => _86cdd1_
-# saclin reconstruct ...[
-#     44614daf1f5ebb86f1c69293b82c7795a5a35b4d12718b551648223441028e3,
-#     6de9fd5fdfe8c08b3132e0d527b14a2a4e4be9a543af1f13d2c397bd113846e4,
-#     86cdd1b7ed79618696ab82d848833cbe448719a513b850207936e4dce6294,
-# ]
-# ```
-# ```
-# Error:   × could not decode: Matrix is not invertible at row 2 (1)
-# ```
-export def "saclin reconstruct" [
-    ...blocks: string@"list-blocks", # the blocks that should be used to reconstruct the original data
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> binary {
-    run-saclin --log-level $log_level --reconstruct ...$blocks | bytes from_int
-}
-
-# combine two blocks by computing a random linear combination
-#
-# # Examples
-# # > **Note**
-# # > file: `assets/dragoon_133x133.png`
-# # > parameters: k = 7 and n = 23
-# # > method: random
-# ```nushell
-# saclin combine ...[
-#     1b112a11cd89dad619aadc18cb2c15c315453e177f1117c79d4ae4e219922,
-#     31c9bfe2845cc430d666413d8b8b51aee0d010aa89275a8c7d9d9ca1c9e05c,
-# ]
-# ```
-# ```
-# b785bf5b93d7811792db7234d1b1ee7347398cee617243612d3225fa245545
-# ```
-# ---
-# ```nushell
-# # not giving exactly 2 blocks
-# # > **Note**
-# # > file: `assets/dragoon_133x133.png`
-# # > parameters: k = 7 and n = 23
-# # > method: random
-# saclin combine ...[
-#     c22fe3c72cbc52fc55b46a3f9783f5c9a1e5fb59875f736332cf1b970b8,
-#     1b112a11cd89dad619aadc18cb2c15c315453e177f1117c79d4ae4e219922,
-#     f3f423df47cd7538accd38abe9ad6670b894243647af98fbfa9776e9cf7ff8e,
-# ]
-# ```
-# ```
-# Error:   × expected exactly 2 blocks, found 3 (1)
-# ```
-export def "saclin combine" [
-    ...blocks: string@"list-blocks", # the blocks to combine, should contain two hashes
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> string {
-    run-saclin --log-level $log_level --combine ...$blocks | get 0
-}
-
-# open one or more blocks and inspect their content
-#
-# # Examples
-# ```nushell
-# # inspect a single block
-# # # > **Note**
-# # # > file: `assets/dragoon_133x133.png`
-# # # > parameters: k = 7 and n = 23
-# # # > method: random
-# # # >
-# # # > `$.commits` and `$shard.bytes` have been truncated for readability
-# saclin inspect 374f23fd1f25ae4050c414bc169550bdd10f49f775e2af71d2aee8a87dc
-# | into record
-# | update commits { parse --regex '\((?<f>\d{7})\d+, (?<s>\d{7})\d+\)' }
-# | update shard.bytes { length }
-# ```
-# ```
-# ───────┬──────────────────────────────────────────────────────────────────────
-#        │─────┬────────────────────────────────────────────────────────────────
-# shard  │k    │7
-#        │     │─┬───────────────────────────────────────
-#        │comb │0│79293070128283035155183921571762200246
-#        │     │1│251822311562506197186167674369775071480
-#        │     │2│271375591445361086306725794586025747695
-#        │     │3│170387538935153872006296956270886059735
-#        │     │4│67758248758369211569040944574905941217
-#        │     │5│245908698054074962369032280439731463970
-#        │     │6│323120636634748190275497410128071523309
-#        │     │─┴───────────────────────────────────────
-#        │bytes│89
-#        │hash │d116d9e2bdb0e03fb2bdd6e716a929198f1012ae62a83e773eb2c21917f4b12c
-#        │size │19102
-#        │─────┴────────────────────────────────────────────────────────────────
-#        │#┬───f───┬───s───
-# commits│0│3258872│1117914
-#        │1│1336159│2841207
-#        │2│3908964│4603563
-#        │3│3956175│1154567
-#        │4│2056568│3904956
-#        │5│2957425│2772456
-#        │6│2395336│2282274
-#        │─┴───────┴───────
-# m      │89
-# ───────┴──────────────────────────────────────────────────────────────────────
-# ```
-export def "saclin inspect" [
-    ...blocks: string@"list-blocks", # the blocks to inspect
-    --log-level: string@"nu-complete log-levels" = $DEFAULT_LOG_LEVEL # change the log level
-]: nothing -> table<shard: record<k: int, comb: list<any>, bytes: list<string>, hash: string, size: int>, commits: list<string>, m: int> {
-    run-saclin --log-level $log_level --inspect ...$blocks
-}
-
-# list all the blocks that are currently in the store
-export def "saclin ls" []: nothing -> list<string> {
-    list-blocks
-}
-
-# clean the SACLIN home from all blocks and trusted setup
-export def "saclin clean" []: nothing -> nothing {
-    rm --force --recursive (home-dir)
-}
-
-def pretty-code []: string -> string {
-    $"`(ansi default_dimmed)($in)(ansi reset)`"
-}
-
-# the main entry point of SACLIN, will only print some help
-export def main []: nothing -> nothing {
-    let help = [
-        $"the location of the files generated by SACLIN can be configured via ("$env.SACLIN_HOME" | pretty-code) which will default to",
-        $"- ("$env.XDG_DATA_HOME/saclin" | pretty-code) if ("$env.XDG_DATA_HOME" | pretty-code) is set",
-        $"- ("~/.local/share/saclin/" | pretty-code) otherwise"
-    ]
-
-    print ($help | str join "\n")
-}
diff --git a/bins/saclin/src/main.rs b/bins/saclin/src/main.rs
deleted file mode 100644
index 2f6b1ff2872a49719c9d2a8aa98518893840595c..0000000000000000000000000000000000000000
--- a/bins/saclin/src/main.rs
+++ /dev/null
@@ -1,341 +0,0 @@
-use std::path::{Path, PathBuf};
-use std::process::exit;
-
-use ark_bls12_381::{Fr, G1Projective};
-use ark_ec::CurveGroup;
-use ark_ff::PrimeField;
-use ark_poly::{univariate::DensePolynomial, DenseUVPolynomial};
-use ark_serialize::{CanonicalDeserialize, Compress, Validate};
-use ark_std::ops::Div;
-
-use anyhow::Result;
-use ark_std::rand::RngCore;
-use tracing::{info, warn};
-
-use komodo::{
-    algebra::linalg::Matrix,
-    error::KomodoError,
-    fec::{self, decode, Shard},
-    fs,
-    semi_avid::{build, prove, recode, verify, Block},
-    zk::{self, Powers},
-};
-
-const COMPRESS: Compress = Compress::Yes;
-const VALIDATE: Validate = Validate::Yes;
-
-#[allow(clippy::type_complexity)]
-fn parse_args() -> (
-    Vec<u8>,
-    usize,
-    usize,
-    bool,
-    String,
-    bool,
-    bool,
-    bool,
-    bool,
-    usize,
-    String,
-    Vec<String>,
-) {
-    let bytes_path = std::env::args()
-        .nth(1)
-        .expect("expected path to bytes as first positional argument");
-    let bytes = if bytes_path.is_empty() {
-        vec![]
-    } else {
-        std::fs::read(bytes_path).unwrap()
-    };
-    let k: usize = std::env::args()
-        .nth(2)
-        .expect("expected k as second positional argument")
-        .parse()
-        .expect("could not parse k as an int");
-    let n: usize = std::env::args()
-        .nth(3)
-        .expect("expected n as third positional argument")
-        .parse()
-        .expect("could not parse n as an int");
-    let do_generate_powers: bool = std::env::args()
-        .nth(4)
-        .expect("expected do_generate_powers as fourth positional argument")
-        .parse()
-        .expect("could not parse do_generate_powers as a bool");
-    let home_dir = std::env::args()
-        .nth(5)
-        .expect("expected home_dir as fifth positional argument");
-    let do_reconstruct_data: bool = std::env::args()
-        .nth(6)
-        .expect("expected do_reconstruct_data as sixth positional argument")
-        .parse()
-        .expect("could not parse do_reconstruct_data as a bool");
-    let do_verify_blocks: bool = std::env::args()
-        .nth(7)
-        .expect("expected do_verify_blocks as seventh positional argument")
-        .parse()
-        .expect("could not parse do_verify_blocks as a bool");
-    let do_combine_blocks: bool = std::env::args()
-        .nth(8)
-        .expect("expected do_combine_blocks as eigth positional argument")
-        .parse()
-        .expect("could not parse do_combine_blocks as a bool");
-    let do_inspect_blocks: bool = std::env::args()
-        .nth(9)
-        .expect("expected do_inspect_blocks as ninth positional argument")
-        .parse()
-        .expect("could not parse do_inspect_blocks as a bool");
-    let nb_bytes: usize = std::env::args()
-        .nth(10)
-        .expect("expected nb_bytes as 10th positional argument")
-        .parse()
-        .expect("could not parse nb_bytes as a usize");
-    let encoding_method = std::env::args()
-        .nth(11)
-        .expect("expected encoding_method as 11th positional argument");
-    let block_hashes = std::env::args().skip(12).collect::<Vec<_>>();
-
-    (
-        bytes,
-        k,
-        n,
-        do_generate_powers,
-        home_dir,
-        do_reconstruct_data,
-        do_verify_blocks,
-        do_combine_blocks,
-        do_inspect_blocks,
-        nb_bytes,
-        encoding_method,
-        block_hashes,
-    )
-}
-
-fn throw_error(code: i32, message: &str) {
-    eprint!("{}", message);
-    exit(code);
-}
-
-fn generate_random_powers<F, G, P>(
-    n: usize,
-    powers_dir: &Path,
-    powers_filename: Option<&str>,
-    rng: &mut impl RngCore,
-) -> Result<()>
-where
-    F: PrimeField,
-    G: CurveGroup<ScalarField = F>,
-    P: DenseUVPolynomial<F>,
-    for<'a, 'b> &'a P: Div<&'b P, Output = P>,
-{
-    info!("generating new powers");
-    let powers = zk::setup::<F, G>(zk::nb_elements_in_setup::<F>(n), rng)?;
-
-    fs::dump(&powers, powers_dir, powers_filename, COMPRESS)?;
-
-    Ok(())
-}
-
-fn verify_blocks<F, G, P>(
-    blocks: &[(String, Block<F, G>)],
-    powers: Powers<F, G>,
-) -> Result<(), KomodoError>
-where
-    F: PrimeField,
-    G: CurveGroup<ScalarField = F>,
-    P: DenseUVPolynomial<F>,
-    for<'a, 'b> &'a P: Div<&'b P, Output = P>,
-{
-    let res = blocks
-        .iter()
-        .map(|(f, b)| Ok((f, verify::<F, G, P>(b, &powers)?)))
-        .collect::<Result<Vec<(&String, bool)>, KomodoError>>()?;
-
-    eprint!("[");
-    for (f, v) in res {
-        eprint!("{{block: {:?}, status: {}}}", f, v);
-    }
-    eprint!("]");
-    Ok(())
-}
-
-fn main() {
-    tracing_subscriber::fmt::try_init().expect("cannot init logger");
-
-    let mut rng = rand::thread_rng();
-
-    let (
-        bytes,
-        k,
-        n,
-        do_generate_powers,
-        home_dir,
-        do_reconstruct_data,
-        do_verify_blocks,
-        do_combine_blocks,
-        do_inspect_blocks,
-        nb_bytes,
-        encoding_method,
-        block_hashes,
-    ) = parse_args();
-
-    let home_dir = PathBuf::from(&home_dir);
-    let block_dir = home_dir.join("blocks/");
-    let powers_dir = home_dir;
-    let powers_filename = "powers";
-    let powers_file = powers_dir.join(powers_filename);
-
-    if do_generate_powers {
-        generate_random_powers::<Fr, G1Projective, DensePolynomial<Fr>>(
-            nb_bytes,
-            &powers_dir,
-            Some(powers_filename),
-            &mut rng,
-        )
-        .unwrap_or_else(|e| throw_error(1, &format!("could not generate powers: {}", e)));
-
-        exit(0);
-    }
-
-    if do_reconstruct_data {
-        let blocks: Vec<Shard<Fr>> =
-            fs::read_blocks::<Fr, G1Projective>(&block_hashes, &block_dir, COMPRESS, VALIDATE)
-                .unwrap_or_else(|e| {
-                    throw_error(1, &format!("could not read blocks: {}", e));
-                    unreachable!()
-                })
-                .iter()
-                .cloned()
-                .map(|b| b.1.shard)
-                .collect();
-        eprintln!(
-            "{:?}",
-            decode::<Fr>(blocks).unwrap_or_else(|e| {
-                throw_error(1, &format!("could not decode: {}", e));
-                unreachable!()
-            })
-        );
-
-        exit(0);
-    }
-
-    if do_combine_blocks {
-        let blocks =
-            fs::read_blocks::<Fr, G1Projective>(&block_hashes, &block_dir, COMPRESS, VALIDATE)
-                .unwrap_or_else(|e| {
-                    throw_error(1, &format!("could not read blocks: {}", e));
-                    unreachable!()
-                });
-
-        let formatted_output = fs::dump_blocks(
-            &[recode(
-                &blocks.iter().map(|(_, b)| b).cloned().collect::<Vec<_>>(),
-                &mut rng,
-            )
-            .unwrap_or_else(|e| {
-                throw_error(1, &format!("could not encode block: {}", e));
-                unreachable!()
-            })
-            .unwrap_or_else(|| {
-                throw_error(1, "could not recode block (list of blocks is likely empty)");
-                unreachable!()
-            })],
-            &block_dir,
-            COMPRESS,
-        )
-        .unwrap_or_else(|e| {
-            throw_error(1, &format!("could not dump block: {}", e));
-            unreachable!()
-        });
-
-        eprint!("{}", formatted_output);
-
-        exit(0);
-    }
-
-    if do_inspect_blocks {
-        let blocks =
-            fs::read_blocks::<Fr, G1Projective>(&block_hashes, &block_dir, COMPRESS, VALIDATE)
-                .unwrap_or_else(|e| {
-                    throw_error(1, &format!("could not read blocks: {}", e));
-                    unreachable!()
-                });
-        eprint!("[");
-        for (_, block) in &blocks {
-            eprint!("{},", block);
-        }
-        eprintln!("]");
-
-        exit(0);
-    }
-
-    info!("reading powers from file `{:?}`", powers_file);
-    let powers = if let Ok(serialized) = std::fs::read(&powers_file) {
-        info!("deserializing the powers from `{:?}`", powers_file);
-        Powers::<Fr, G1Projective>::deserialize_with_mode(&serialized[..], COMPRESS, VALIDATE)
-            .unwrap_or_else(|e| {
-                throw_error(
-                    1,
-                    &format!("could not deserialize powers from {:?}: {}", powers_file, e),
-                );
-                unreachable!()
-            })
-    } else {
-        warn!("could not read powers from `{:?}`", powers_file);
-        info!("regenerating temporary powers");
-        zk::setup::<Fr, G1Projective>(zk::nb_elements_in_setup::<Fr>(nb_bytes), &mut rng)
-            .unwrap_or_else(|e| {
-                throw_error(1, &format!("could not generate powers: {}", e));
-                unreachable!()
-            })
-    };
-
-    if do_verify_blocks {
-        verify_blocks::<Fr, G1Projective, DensePolynomial<Fr>>(
-            &fs::read_blocks::<Fr, G1Projective>(&block_hashes, &block_dir, COMPRESS, VALIDATE)
-                .unwrap_or_else(|e| {
-                    throw_error(1, &format!("could not read blocks: {}", e));
-                    unreachable!()
-                }),
-            powers,
-        )
-        .unwrap_or_else(|e| {
-            throw_error(1, &format!("Failed to verify blocks: {}", e));
-            unreachable!()
-        });
-
-        exit(0);
-    }
-
-    let encoding_mat = match encoding_method.as_str() {
-        "vandermonde" => {
-            let points: Vec<Fr> = (0..n)
-                .map(|i| Fr::from_le_bytes_mod_order(&i.to_le_bytes()))
-                .collect();
-            Matrix::vandermonde_unchecked(&points, k)
-        }
-        "random" => Matrix::random(k, n, &mut rng),
-        m => {
-            throw_error(1, &format!("invalid encoding method: {}", m));
-            unreachable!()
-        }
-    };
-
-    let shards = fec::encode::<Fr>(&bytes, &encoding_mat).unwrap_or_else(|e| {
-        throw_error(1, &format!("could not encode: {}", e));
-        unreachable!()
-    });
-    let proof =
-        prove::<Fr, G1Projective, DensePolynomial<Fr>>(&bytes, &powers, k).unwrap_or_else(|e| {
-            throw_error(1, &format!("could not prove: {}", e));
-            unreachable!()
-        });
-    let blocks = build::<Fr, G1Projective, DensePolynomial<Fr>>(&shards, &proof);
-
-    let formatted_output = fs::dump_blocks(&blocks, &block_dir, COMPRESS).unwrap_or_else(|e| {
-        throw_error(1, &format!("could not dump blocks: {}", e));
-        unreachable!()
-    });
-
-    eprint!("{}", formatted_output);
-}
diff --git a/bins/saclin/tests/binary.nu b/bins/saclin/tests/binary.nu
deleted file mode 100644
index 0bd2669bfa9b33df7e6f95fc4b77d3d07c2e22cc..0000000000000000000000000000000000000000
--- a/bins/saclin/tests/binary.nu
+++ /dev/null
@@ -1,19 +0,0 @@
-use ../binary.nu [ "bytes from_int", "bytes to_int" ]
-
-use std assert
-
-def random-bytes [n: int]: nothing -> list<int> {
-    0..$n | each { random int 0..255 }
-}
-
-def main [] {
-    const hello_world_int = [
-        104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100, 33
-    ]
-
-    const expected = 0x[68 65 6C 6C 6F 20 77 6F 72 6C 64 21]
-    assert equal ($hello_world_int | bytes from_int) $expected
-
-    let bytes = random-bytes 1_000
-    assert equal ($bytes | bytes from_int | bytes to_int) $bytes
-}
diff --git a/bins/saclin/tests/cli.nu b/bins/saclin/tests/cli.nu
deleted file mode 100644
index ac765c6f638dbaaa3499b9e48b2e72b60ba19463..0000000000000000000000000000000000000000
--- a/bins/saclin/tests/cli.nu
+++ /dev/null
@@ -1,171 +0,0 @@
-use .. [
-    "saclin build",
-    "saclin setup",
-    "saclin prove",
-    "saclin verify",
-    "saclin reconstruct",
-    "saclin ls",
-    "saclin clean",
-]
-use ../binary.nu [ "bytes from_int" ]
-
-use std assert
-
-# a simple module to extend the `math` command
-module math {
-    # `choose k n` is the list of all the possible $k$ indices chosen among $n$ indices
-    #
-    # see [_test_choose] below for some examples
-    export def choose [k: int, n: int]: nothing -> list<list<int>> {
-        if $k == 0 {
-            return []
-        } else if $k == 1 {
-            return (seq 0 ($n - 1) | each {[ $in ]})
-        }
-
-        choose ($k - 1) $n
-            | each { |x|
-                let l = $x | last
-                if $l != ($n - 1) {
-                    seq ($l + 1) ($n - 1) | each {|it| $x | append $it}
-                }
-            }
-            | flatten
-    }
-
-    def _test_choose [] {
-        use std assert
-
-        assert equal (choose 0 5) []
-        assert equal (choose 1 5) [[0], [1], [2], [3], [4]]
-        assert equal (choose 2 5) [
-            [0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]
-        ]
-        assert equal (choose 3 5) [
-            [0, 1, 2],
-            [0, 1, 3],
-            [0, 1, 4],
-            [0, 2, 3],
-            [0, 2, 4],
-            [0, 3, 4],
-            [1, 2, 3],
-            [1, 2, 4],
-            [1, 3, 4],
-            [2, 3, 4],
-        ]
-        assert equal (choose 4 5) [
-            [0, 1, 2, 3],
-            [0, 1, 2, 4],
-            [0, 1, 3, 4],
-            [0, 2, 3, 4],
-            [1, 2, 3, 4],
-        ]
-        assert equal (choose 5 5) [[0, 1, 2, 3, 4]]
-    }
-
-    # `perm n` is the list of all the possible permutations on $n$ elements
-    #
-    # see [_test_perm] below for some examples
-    export def perm [n: int]: nothing -> list<list<int>> {
-        if $n == 0 {
-            return []
-        } else if $n == 1 {
-            return [[0]]
-        }
-
-        perm ($n - 1)
-            | each {|x|
-                seq 0 ($x | length) | each {|i| $x | insert $i ($n - 1)}
-            }
-            | flatten
-    }
-
-    def _test_perm [] {
-        use std assert
-
-        assert equal (perm 0 | sort) []
-        assert equal (perm 1 | sort) [[0]]
-        assert equal (perm 2 | sort) [[0, 1], [1, 0]]
-        assert equal (perm 3 | sort) [
-            [0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]
-        ]
-        assert equal (perm 4 | sort) [
-            [0, 1, 2, 3],
-            [0, 1, 3, 2],
-            [0, 2, 1, 3],
-            [0, 2, 3, 1],
-            [0, 3, 1, 2],
-            [0, 3, 2, 1],
-            [1, 0, 2, 3],
-            [1, 0, 3, 2],
-            [1, 2, 0, 3],
-            [1, 2, 3, 0],
-            [1, 3, 0, 2],
-            [1, 3, 2, 0],
-            [2, 0, 1, 3],
-            [2, 0, 3, 1],
-            [2, 1, 0, 3],
-            [2, 1, 3, 0],
-            [2, 3, 0, 1],
-            [2, 3, 1, 0],
-            [3, 0, 1, 2],
-            [3, 0, 2, 1],
-            [3, 1, 0, 2],
-            [3, 1, 2, 0],
-            [3, 2, 0, 1],
-            [3, 2, 1, 0],
-        ]
-    }
-}
-
-use math
-
-const FILE = "assets/dragoon_32x32.png"
-const FEC_PARAMS = {k: 3, n: 5}
-
-def test [blocks: list<int>, --fail] {
-    let actual = try {
-        saclin reconstruct ...(saclin ls)
-    } catch {
-        if not $fail {
-            error make --unspanned { msg: "woopsie" }
-        } else {
-            return
-        }
-    }
-
-    let expected = open $FILE | bytes from_int
-    assert equal $actual $expected
-}
-
-def main [] {
-    saclin build
-
-    saclin clean
-
-    saclin setup (open $FILE | into binary | bytes length)
-    saclin prove $FILE --fec-params $FEC_PARAMS
-
-    saclin verify ...(saclin ls)
-
-    let all_k_choose_n_permutations = seq 1 $FEC_PARAMS.n
-        | each {|ki|
-            let p = math perm $ki
-            math choose $ki $FEC_PARAMS.n
-                | each {|it|
-                    {
-                        blocks: ($p | each { each {|i| $it | get $i} }),
-                        fail: ($ki < $FEC_PARAMS.k),
-                    }
-                }
-                | flatten
-        }
-        | flatten
-    let total = $all_k_choose_n_permutations | length
-    $all_k_choose_n_permutations | enumerate | each {|it|
-        print $"[($it.index / $total * 100 | into int)%]: ($it.item.blocks | str join ', ') | ($it.item.fail)"
-        test $it.item.blocks --fail=$it.item.fail
-    }
-
-    print "reconstruction was successful"
-}