diff --git a/.env.sample b/.env.sample
deleted file mode 100644
index f843ceec..00000000
--- a/.env.sample
+++ /dev/null
@@ -1,18 +0,0 @@
-# Leave these blank - the env variables will be populated when you run ./bootstrap-local-environment.sh
-NILLION_BOOTNODE_MULTIADDRESS=
-NILLION_CLUSTER_ID=
-NILLION_USERKEY_PATH_PARTY_1=
-NILLION_USERKEY_PATH_PARTY_2=
-NILLION_USERKEY_PATH_PARTY_3=
-NILLION_USERKEY_PATH_PARTY_4=
-NILLION_USERKEY_PATH_PARTY_5=
-NILLION_NODEKEY_PATH_PARTY_1=
-NILLION_NODEKEY_PATH_PARTY_2=
-NILLION_NODEKEY_PATH_PARTY_3=
-NILLION_NODEKEY_PATH_PARTY_4=
-NILLION_NODEKEY_PATH_PARTY_5=
-NILLION_BLOCKCHAIN_RPC_ENDPOINT=
-NILLION_CHAIN_ID=
-NILLION_PAYMENTS_SC_ADDRESS=
-NILLION_BLINDING_FACTORS_MANAGER_SC_ADDRESS=
-NILLION_WALLET_PRIVATE_KEY=
diff --git a/.gitignore b/.gitignore
index 23729864..57248ff4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,12 @@
**/*.pyc
**/__pycache__
-programs-compiled/
nillion-venv/
permissions/.nillion-config.json
+examples_and_tutorials/nada_programs/target
+quickstart_complete/nada_quickstart_programs/target
.env
+.idea
.DS_Store
*.key
+
.venv
\ No newline at end of file
diff --git a/.nil-sdk.toml b/.nil-sdk.toml
new file mode 100644
index 00000000..f3183813
--- /dev/null
+++ b/.nil-sdk.toml
@@ -0,0 +1 @@
+version = "v0.9.0"
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
deleted file mode 100644
index ed99c932..00000000
--- a/CONTRIBUTING.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# Contributing Guide
-
-Thank you for investing your time in contributing.
-
-This guide aims to provide an overview of the contribution workflow to help us make the contribution process effective for everyone involved.
-
-Read the [README](README.md) to get an overview of the project.
-
-### Project Status
-
-The project is under active development.
-
-You can view the open Issues, follow the development process and contribute to the project.
-
-## Getting started
-
-You can contribute to this repo in many ways:
-
-- Solve open issues
-- Report bugs or feature requests
-- Improve the documentation
-
-Contributions are made via Issues and Pull Requests (PRs). A few general guidelines for contributions:
-
-- Search for existing Issues and PRs before creating your own.
-- Contributions should only fix/add the functionality in the issue OR address style issues, not both.
-- If you're running into an error, please give context. Explain what you're trying to do and how to reproduce the error.
-- Please use the same formatting in the code repository. You can configure your IDE to do it by using the prettier / linting config files included in each package.
-- If applicable, please edit the README.md file to reflect the changes.
-
-### Issues
-
-Issues should be used to report problems, request a new feature, or discuss potential changes before a PR is created.
-
-#### Solve an issue
-
-Scan through our [existing issues](https://github.com/NillionNetwork/nillion-python-starter/issues) to find one that interests you.
-
-If a contributor is working on the issue, they will be assigned to the individual. If you find an issue to work on, you are welcome to assign it to yourself and open a PR with a fix for it.
-
-#### Create a new issue
-
-If a related issue doesn't exist, you can open a new issue.
-
-Some tips to follow when you are creating an issue:
-
-- Provide as much context as possible. Over-communicate to give the most details to the reader.
-- Include the steps to reproduce the issue or the reason for adding the feature.
-- Screenshots, videos etc., are highly appreciated.
-
-### Pull Requests
-
-#### Pull Request Process
-
-We follow the ["fork-and-pull" Git workflow](https://github.com/susam/gitpr)
-
-1. Fork the repo
-2. Clone the project
-3. Create a new branch with a descriptive name
-4. Commit your changes to the new branch
-5. Push changes to your fork
-6. Open a PR in our repository by [creating a pull request from your fork](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork). Use the "main" branch as the base branch, the branch in the repository that you want to merge your changes into.
-7. Tag one of the maintainers to review your PR
-
-Here are some tips for a high-quality pull request:
-
-- Create a title for the PR that accurately defines the work done.
-- Structure the description neatly to make it easy to consume by the readers. For example, you can include bullet points and screenshots instead of having one large paragraph.
-- Add the link to the issue if applicable.
-- Have a good commit message that summarises the work done.
-
-Once you submit your PR:
-
-- We may ask questions, request additional information or ask for changes to be made before a PR can be merged. Please note that these are to make the PR clear for everyone involved and aims to create a frictionless interaction process.
-- As you update your PR and apply changes, mark each conversation resolved.
-
-Once the PR is approved, we'll "squash-and-merge" to keep the git commit history clean.
diff --git a/README.md b/README.md
index ab1eda19..996460f0 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,14 @@
# Nillion Python Starter
-This is a python starter repo for building on the Nillion Network. Complete environment setup, then run the examples:
-
-- To run multi party examples, go to the [multi party compute](examples_and_tutorials/core_concept_multi_party_compute) folder.
-
-- To run single party examples, go to the [single party compute](examples_and_tutorials/core_concept_single_party_compute) folder.
-
-- To run permissions examples (storing and retrieving permissioned secrets, revoking permissions, etc.), go to the [permissions](examples_and_tutorials/core_concept_permissions) folder.
-
-### Prerequisites: Install the CLI Dependencies
-
-The `nillion-devnet` tool spins up `anvil` under the hood, so you need to have `foundry` installed. The [`bootstrap-local-environment.sh`](./bootstrap-local-environment.sh) file uses `pidof` and `grep`.
-
-- [Install `foundry`](https://book.getfoundry.sh/getting-started/installation)
-- [Install `pidof`](https://command-not-found.com/pidof)
-- [Install `grep`](https://command-not-found.com/grep)
-
-## Environment Setup
-
-1. Create a `.env` file by copying the sample:
-
- ```shell
- cp .env.sample .env
- ```
-
-2. Create the virtual environment (`.venv`), install dependencies, and activate the virtual environment
-
- ```shell
- bash ./create_venv.sh && source .venv/bin/activate
- ```
-
- Run the [`bootstrap-local-environment.sh`](./bootstrap-local-environment.sh) script to spin up `nillion-devnet`, generate keys, and get bootnodes, cluster, and payment info:
-
- ```shell
- ./bootstrap-local-environment.sh
- ```
-
-3. Check `.env` file - keys, bootnodes, cluster, and payment info should now be present. If you want to run against a local cluster, use this configuration. Otherwise, replace values with testnet bootnodes, cluster, and payment info.
-
-4. Look through the [programs](./programs/) folder to see examples of Nada programs.
-
-## Compiling Programs
-
-Nada programs need to be compiled ahead of being stored. Compile all programs in the [programs](./programs/) folder with the script [`compile_programs.sh`](./compile_programs.sh):
-
-```shell
-bash compile_programs.sh
-```
-
-This generates a `programs-compiled` folder containing the compiled programs.
-
-## Store a Compiled Program
-
-Store a compiled program in the network with this script:
-
-```shell
-bash store_program.sh {RELATIVE_COMPILED_PROGRAM_PATH}
-```
-
-To store the compiled [`addition_simple`](./programs/addition_simple.py) program you can run:
-
-```shell
-bash store_program.sh programs-compiled/addition_simple.nada.bin
-```
-
-Storing a program results in the stored `program_id`, the network's reference to the program. The `program_id` is the `{user_id}/{program_name}`.
-
-## Testing
-
-Most examples and tutorials within this repository can be tested. Docker is required to run the tests.
-
-```shell
-cd testing
-bash run_tests.sh
-```
+Welcome to the start of your Nillion developer journey.
+
+This repo corresponds to the Nillion Python quickstart. To get started with Nillion head over to the [Python QuickStart docs](https://docs.nillion.com/python-quickstart) and follow the quickstart guide.
+
+For more python examples, check out https://github.com/NillionNetwork/python-examples which contains the following:
+- core_concept_multi_party_compute
+- core_concept_permissions
+- core_concept_single_party_compute
+- core_concept_store_and_retrieve_secrets
+- millionaires_problem_example
+- nada_programs
+- voting_tutorial
diff --git a/bootstrap-local-environment.sh b/bootstrap-local-environment.sh
deleted file mode 100755
index 2ad6f7f1..00000000
--- a/bootstrap-local-environment.sh
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/usr/bin/env bash
-
-# set number of node and user keys to be created
-num_node_keys=5
-num_user_keys=5
-
-# set env file to update
-ENV_TO_UPDATE=".env"
-
-NILLION_DEVNET="nillion-devnet"
-NILLION_CLI="nillion"
-NILLION_CLI_COMMAND_USER_KEYGEN="user-key-gen"
-NILLION_CLI_COMMAND_NODE_KEYGEN="node-key-gen"
-
-# kill any other nillion-devnet processes
-pkill -9 -f $NILLION_DEVNET
-
-for var in NILLION_DEVNET NILLION_CLI; do
- printf "ℹ️ found bin %-18s -> [${!var:?Failed to discover $var}]\n" "$var"
-done
-
-OUTFILE=$(mktemp);
-PIDFILE=$(mktemp);
-
-"$NILLION_DEVNET" >"$OUTFILE" & echo $! >"$PIDFILE";
-echo "--------------------"
-echo "Updating your ${ENV_TO_UPDATE} files with nillion-devnet environment info... This may take a minute."
-echo "--------------------"
-time_limit=160
-while true; do
- # Use 'wait' to check if the log file contains the string
- if grep "cluster is running, bootnode is at" "$OUTFILE"; then
- break
- fi
-
- # If the time limit has been reached, print an error message and exit
- if [[ $SECONDS -ge $time_limit ]]; then
- echo "Timeout reached while waiting for cluster to be ready in '$OUTFILE'" >&2
- exit 1
- fi
- sleep 5
-done
-
-echo "ℹ️ Cluster has been STARTED (see $OUTFILE)"
-cat "$OUTFILE"
-
-# grep cluster info from nillion-devnet
-CLUSTER_ID=$(grep "cluster id is" "$OUTFILE" | awk '{print $4}');
-WEBSOCKET=$(grep "websocket:" "$OUTFILE" | awk '{print $2}');
-BOOT_MULTIADDR=$(grep "cluster is running, bootnode is at" "$OUTFILE" | awk '{print $7}');
-PAYMENTS_CONFIG_FILE=$(grep "payments configuration written to" "$OUTFILE" | awk '{print $5}');
-WALLET_KEYS_FILE=$(grep "wallet keys written to" "$OUTFILE" | awk '{print $5}');
-PAYMENTS_RPC=$(grep "blockchain_rpc_endpoint:" "$PAYMENTS_CONFIG_FILE" | awk '{print $2}');
-PAYMENTS_CHAIN=$(grep "chain_id:" "$PAYMENTS_CONFIG_FILE" | awk '{print $2}');
-PAYMENTS_SC_ADDR=$(grep "payments_sc_address:" "$PAYMENTS_CONFIG_FILE" | awk '{print $2}');
-PAYMENTS_BF_ADDR=$(grep "blinding_factors_manager_sc_address:" "$PAYMENTS_CONFIG_FILE" | awk '{print $2}');
-WALLET_PRIVATE_KEY=$(tail -n1 "$WALLET_KEYS_FILE")
-
-# update or add an environment variable to one or more files
-update_env() {
- local key=$1
- local value=$2
- # Skip the first two arguments to get the file paths
- local files=("${@:3}")
-
- for file in "${files[@]}"; do
- if [ -f "$file" ]; then # Check if file exists
- # Check if the key exists in the file and remove it
- if grep -q "^$key=" "$file"; then
- # Key exists, remove it
- grep -v "^$key=" "$file" > temp.txt && mv temp.txt "$file"
- fi
-
- # Append the new key-value pair to the file
- echo "$key=$value" >> "$file"
- else
- echo "File $file not found. Creating $file"
- touch $file
- echo "$key=$value" >> "$file"
- fi
- done
-}
-
-# log file contents of key files to add to .env
-log_file_contents() {
- local file_path=$1 # Direct path to the target file
-
- # Check if the file exists at the path
- if [[ ! -f "$file_path" ]]; then
- echo "File $file_path does not exist."
- return 1 # Exit the function with an error status if the file does not exist
- fi
-
- # If the file exists, cat its contents
- cat "$file_path"
-}
-
-# Generate node keys and add to .env - ex: NILLION_NODEKEY_PATH_PARTY_1
-for ((i=1; i<=$num_node_keys; i++)); do
- nodekey_file=$(mktemp)
- "$NILLION_CLI" "$NILLION_CLI_COMMAND_NODE_KEYGEN" "$nodekey_file"
- NODEKEY_FILES+=("$nodekey_file")
- update_env "NILLION_NODEKEY_PATH_PARTY_$i" "$nodekey_file" $ENV_TO_UPDATE
- update_env "NILLION_NODEKEY_TEXT_PARTY_$i" "$(log_file_contents $nodekey_file)" $ENV_TO_UPDATE
-done
-
-# Generate user keys and add to .env - ex: NILLION_USERKEY_PATH_PARTY_1
-for ((i=1; i<=$num_user_keys; i++)); do
- userkey_file=$(mktemp)
- "$NILLION_CLI" "$NILLION_CLI_COMMAND_USER_KEYGEN" "$userkey_file"
- USERKEY_FILES+=("$userkey_file")
- update_env "NILLION_USERKEY_PATH_PARTY_$i" "$userkey_file" $ENV_TO_UPDATE
- update_env "NILLION_USERKEY_TEXT_PARTY_$i" "$(log_file_contents $userkey_file)" $ENV_TO_UPDATE
-done
-
-echo "🔑 Node key and user keys have been generated and added to .env"
-
-# Add environment variables to .env
-update_env "NILLION_WEBSOCKETS" "$WEBSOCKET" $ENV_TO_UPDATE
-update_env "NILLION_CLUSTER_ID" "$CLUSTER_ID" $ENV_TO_UPDATE
-update_env "NILLION_BLOCKCHAIN_RPC_ENDPOINT" "$PAYMENTS_RPC" $ENV_TO_UPDATE
-update_env "NILLION_BLINDING_FACTORS_MANAGER_SC_ADDRESS" "$PAYMENTS_BF_ADDR" $ENV_TO_UPDATE
-update_env "NILLION_PAYMENTS_SC_ADDRESS" "$PAYMENTS_SC_ADDR" $ENV_TO_UPDATE
-update_env "NILLION_CHAIN_ID" "$PAYMENTS_CHAIN" $ENV_TO_UPDATE
-update_env "NILLION_WALLET_PRIVATE_KEY" "$WALLET_PRIVATE_KEY" $ENV_TO_UPDATE
-update_env "NILLION_BOOTNODE_MULTIADDRESS" "$BOOT_MULTIADDR" $ENV_TO_UPDATE
-
-echo "Running at process pid: $(pgrep -f $NILLION_DEVNET)"
-
-echo "-------------------------------------------------------"
-echo " 7MM 7MM "
-echo " MM MM "
-echo " db MM MM db "
-echo " MM MM "
-echo ".7MMpMMMb. 7MM MM MM 7MM ,pW-Wq. 7MMpMMMb. "
-echo " MM MM MM MM MM MM 6W' Wb MM MM "
-echo " MM MM MM MM MM MM 8M M8 MM MM "
-echo " MM MM MM MM MM MM YA. ,A9 MM MM "
-echo ".JMML JMML..JMML..JMML..JMML..JMML. Ybmd9 .JMML JMML."
-echo "-------------------------------------------------------"
-echo "-------------------------------------------------------"
-echo "-----------🦆 CONNECTED TO NILLION-DEVNET 🦆-----------"
-echo "-------------------------------------------------------"
-
-echo "ℹ️ Your $ENV_TO_UPDATE file configurations were updated with nillion-devnet connection variables: websocket, cluster id, keys, blockchain info"
-echo "💻 The Nillion devnet is still running behind the scenes; to spin down the Nillion devnet at any time, run 'killall nillion-devnet'"
-
-echo "--------------------"
-echo "💻 Your Nillion local cluster is still running - process pid: $(pgrep -f $NILLION_DEVNET)"
-echo "ℹ️ Updated your .env file configuration variables: bootnode, cluster id, keys, blockchain info"
-
-exit 0
\ No newline at end of file
diff --git a/compile_programs.sh b/compile_programs.sh
deleted file mode 100755
index 5c7d647e..00000000
--- a/compile_programs.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env bash
-
-# This script compiles all $PROGRAMS_FOLDER programs to mir
-PROGRAMS_FOLDER="programs"
-COMPILED_PROGRAMS_FOLDER="programs-compiled"
-
-SCRIPT_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}" 2>/dev/null)" && pwd -P)"
-TARGET_PATH="${SCRIPT_PATH}/${COMPILED_PROGRAMS_FOLDER}"
-PROGRAMS_PATH="${SCRIPT_PATH}/${PROGRAMS_FOLDER}"
-
-PYNADAC="pynadac"
-
-cd "${PROGRAMS_PATH}" || exit 1
-
-for file in *.py ; do
- echo "Compiling ${file}"
- "$PYNADAC" --target-dir "${TARGET_PATH}" \
- --generate-mir-json \
- "${file}"
-done
-
-echo "------------------------"
-echo "Compiled programs: all files in the programs directory were compiled to mir: [$TARGET_PATH]"
-
-echo "Now try running an example:"
-
-echo "----------single party compute --------------"
-
-echo "Code for single party compute lives in the examples_and_tutorials/core_concept_client_single_party_compute folder"
-echo "📋 to run single party compute - addition_simple program: 'cd examples_and_tutorials/core_concept_client_single_party_compute && python3 addition_simple.py'"
-
-echo "----------multi party compute --------------"
-
-echo "Code for multi party compute lives in the examples_and_tutorials/core_concept_multi_party_compute folder"
-echo "📋 to run multi party compute in 3 steps - addition_simple_multi_party_3: 'cd examples_and_tutorials/core_concept_multi_party_compute && python3 01_store_secret_party1.py'"
\ No newline at end of file
diff --git a/create_venv.sh b/create_venv.sh
deleted file mode 100755
index 8e5bb12e..00000000
--- a/create_venv.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env bash
-
-function create_venv () {
- if [[ ! -z "${VIRTUAL_ENV:-}" ]]; then
- echo "Virtualenv is already active! Run 'deactivate' to deactivate the virtualenv."
- return 0
- fi
-
- echo "Creating virtualenv"
- python3 -m pip install --user virtualenv==20.24.6
-
- NILLION_VENV=".venv"
- mkdir -p "$NILLION_VENV"
- python3 -m virtualenv -p python3 "$NILLION_VENV"
- source "$NILLION_VENV/bin/activate"
- python3 -m pip install -r requirements.txt
-
- echo "Virtualenv: $NILLION_VENV"
- echo "Check the $NILLION_VENV/lib/python3.1X/site-packages folder to make sure you have py_nillion_client and nada_dsl packages"
- echo "📋 Copy and run the following command to activate your environment:"
- echo "source $NILLION_VENV/bin/activate"
-}
-
-create_venv
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index a5fa73dc..00000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-version: '3.8'
-services:
- demo:
- container_name: nillion
- build:
- context: .
- dockerfile_inline: |
- FROM python:3.10-slim
- ARG DEBIAN_FRONTEND="noninteractive"
- SHELL ["/bin/bash", "-o", "pipefail", "-xe", "-c"]
- RUN apt update; \
- apt install -y --no-install-recommends \
- jq; \
- apt clean; \
- rm -rf /var/lib/apt/lists/*; \
- pip install --upgrade pip; \
- groupadd -r nillion; \
- useradd -rm -g nillion nillion;
- USER nillion
- network_mode: 'bridge'
- environment:
- - PUID=1000
- - PGID=1000
- - TZ=Europe/London
- - NILLION_SDK_ROOT=/sdk
- volumes:
- - '$PWD/..:/host'
- - $NILLION_SDK_ROOT:/sdk
- working_dir: /host
- command:
- - /bin/bash
- - '-c'
- - |
- source ./utils.sh
- check_for_sdk_root
- install_nada_dsl
- pushd permissions
- ./bootstrap-local-environment.sh
diff --git a/examples_and_tutorials/core_concept_multi_party_compute/01_store_secret_party1.py b/examples_and_tutorials/core_concept_multi_party_compute/01_store_secret_party1.py
deleted file mode 100644
index a1025c66..00000000
--- a/examples_and_tutorials/core_concept_multi_party_compute/01_store_secret_party1.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-from config import (
- CONFIG_PROGRAM_NAME,
- CONFIG_PARTY_1
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# The 1st Party stores a secret
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- client_1 = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]), getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_file"])
- )
- party_id_1 = client_1.party_id
- user_id_1 = client_1.user_id
-
-
- program_mir_path=f"../../programs-compiled/{CONFIG_PROGRAM_NAME}.nada.bin"
-
- # 1st Party stores program
- action_id = await client_1.store_program(
- cluster_id, CONFIG_PROGRAM_NAME, program_mir_path
- )
-
- program_id=f"{user_id_1}/{CONFIG_PROGRAM_NAME}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
-
- # 1st Party creates a secret
- stored_secret_1 = nillion.Secrets({
- key: nillion.SecretInteger(value)
- for key, value in CONFIG_PARTY_1["secrets"].items()
- })
-
- # 1st Party creates input bindings for the program
- secret_bindings_1 = nillion.ProgramBindings(program_id)
- secret_bindings_1.add_input_party(CONFIG_PARTY_1["party_name"], party_id_1)
-
- # 1st Party stores a secret
- store_id_1 = await client_1.store_secrets(
- cluster_id, secret_bindings_1, stored_secret_1, None
- )
- secrets_string = ", ".join(f"{key}: {value}" for key, value in CONFIG_PARTY_1["secrets"].items())
- print(f"\n🎉1️⃣ Party {CONFIG_PARTY_1['party_name']} stored {secrets_string} at store id: {store_id_1}")
- print("\n📋⬇️ Copy and run the following command to store N other party secrets")
- print(f"\npython3 02_store_secret_party_n.py --user_id_1 {user_id_1} --store_id_1 {store_id_1}")
- return [user_id_1, store_id_1]
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_multi_party_compute/02_store_secret_party_n.py b/examples_and_tutorials/core_concept_multi_party_compute/02_store_secret_party_n.py
deleted file mode 100644
index 45dd79c7..00000000
--- a/examples_and_tutorials/core_concept_multi_party_compute/02_store_secret_party_n.py
+++ /dev/null
@@ -1,98 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-from config import (
- CONFIG_PROGRAM_NAME,
- CONFIG_N_PARTIES
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# N other parties store a secret
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
- )
- parser.add_argument(
- "--user_id_1",
- required=True,
- type=str,
- help="User ID of the user who will compute with the secret being stored",
- )
- parser.add_argument(
- "--store_id_1",
- required=True,
- type=str,
- help="Store ID of the 1st secret",
- )
-
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- program_id=f"{args.user_id_1}/{CONFIG_PROGRAM_NAME}"
-
- # start a list of store ids to keep track of stored secrets
- store_ids = []
- party_ids = []
-
- for party_info in CONFIG_N_PARTIES:
- client_n = create_nillion_client(
- getUserKeyFromFile(party_info["userkey_file"]),
- getNodeKeyFromFile(party_info["nodekey_file"])
- )
- party_id_n = client_n.party_id
- user_id_n = client_n.user_id
- party_name = party_info["party_name"]
- secret_name = party_info["secret_name"]
- secret_value = party_info["secret_value"]
-
- # Create a secret for the current party
- stored_secret = nillion.Secrets({
- secret_name: nillion.SecretInteger(secret_value)
- })
-
- # Create input bindings for the program
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id_n)
-
- # Create permissions object
- permissions = nillion.Permissions.default_for_user(user_id_n)
-
- # Give compute permissions to the first party
- compute_permissions = {
- args.user_id_1: {program_id},
- }
- permissions.add_compute_permissions(compute_permissions)
-
- # Store the permissioned secret
- store_id = await client_n.store_secrets(
- cluster_id, secret_bindings, stored_secret, permissions
- )
-
- store_ids.append(store_id)
- party_ids.append(party_id_n)
-
- print(f"\n🎉N Party {party_name} stored {secret_name}: {secret_value} at store id: {store_id}")
- print(f"\n🎉Compute permission on the secret granted to user_id: {args.user_id_1}")
-
- party_ids_to_store_ids = ' '.join([f'{party_id}:{store_id}' for party_id, store_id in zip(party_ids, store_ids)])
-
- print("\n📋⬇️ Copy and run the following command to run multi party computation using the secrets")
- print(f"\npython3 03_multi_party_compute.py --store_id_1 {args.store_id_1} --party_ids_to_store_ids {party_ids_to_store_ids}")
- return [args.store_id_1, party_ids_to_store_ids]
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_multi_party_compute/03_multi_party_compute.py b/examples_and_tutorials/core_concept_multi_party_compute/03_multi_party_compute.py
deleted file mode 100644
index 04591710..00000000
--- a/examples_and_tutorials/core_concept_multi_party_compute/03_multi_party_compute.py
+++ /dev/null
@@ -1,108 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-import importlib
-
-from dotenv import load_dotenv
-
-from config import (
- CONFIG_PROGRAM_NAME,
- CONFIG_PARTY_1,
- CONFIG_N_PARTIES
-)
-
-store_secret_party_1 = importlib.import_module("01_store_secret_party1")
-store_secret_party_n = importlib.import_module("02_store_secret_party_n")
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
- )
-
- parser.add_argument(
- "--store_id_1",
- required=True,
- type=str,
- help="Store ID of the 1st secret",
- )
-
- parser.add_argument(
- "--party_ids_to_store_ids",
- required=True,
- nargs='+',
- type=str,
- help="List of partyid:storeid pairs of the secrets, with each pair separated by a space",
- )
-
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- # 1st party computes on secrets
- client_1 = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]),
- getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_alternate_file"]),
- )
- user_id_1 = client_1.user_id
- party_id_1 = client_1.party_id
-
- program_id=f"{user_id_1}/{CONFIG_PROGRAM_NAME}"
-
-
- # Bind the parties in the computation to the client to set inputs and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(CONFIG_PARTY_1["party_name"], party_id_1)
- compute_bindings.add_output_party(CONFIG_PARTY_1["party_name"], party_id_1)
- store_id_1 = args.store_id_1
-
- print(f"Computing using program {program_id}")
- print(f"Party 1 secret store_id: {store_id_1}")
-
- party_ids_to_store_ids = {}
- i=0
- for pair in args.party_ids_to_store_ids:
- party_id, store_id = pair.split(':')
- party_name = CONFIG_N_PARTIES[i]['party_name']
- compute_bindings.add_input_party(party_name, party_id)
- party_ids_to_store_ids[party_id] = store_id
- i=i+1
-
- # Compute on the secret with all store ids. Note that there are no compute time secrets or public variables
- compute_id = await client_1.compute(
- cluster_id,
- compute_bindings,
- [store_id_1] + list(party_ids_to_store_ids.values()),
- nillion.Secrets({}),
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client_1.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await store_secret_party_1.main()
- args = ['--user_id_1', result[0], '--store_id_1', result[1]]
- result = await store_secret_party_n.main(args)
- store_ids = result[1].split(' ', 1)
- args = ['--store_id_1', result[0], '--party_ids_to_store_ids', store_ids[0], store_ids[1]]
- result = await main(args)
- assert result == {'my_output': 8}
diff --git a/examples_and_tutorials/core_concept_multi_party_compute/README.md b/examples_and_tutorials/core_concept_multi_party_compute/README.md
deleted file mode 100644
index 856a997c..00000000
--- a/examples_and_tutorials/core_concept_multi_party_compute/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Multi Party Example
-
-This is an example using the Nillion Python Client to store a program, and run multi party compute, computation involving secret inputs from multiple parties.
-
-## Assumptions
-
-The 3-part Multi Party example assumes there is a stored program that meets the following criteria:
-
-- there are N+1 parties
-- each party contributes secret inputs of type SecretInteger, and each party stores at least one secret an input
-- the 1st party stores a secret
-- N other parties store secrets and give the 1st party permission to compute on their secrets
-- the 1st party runs compute
-- the 1st party reads the output
-
-## Run the example
-
-1. Set up requirements following the repo README to populate the .env file with environment variables.
-
-2. Follow README instructions to compile a program that meets the above assumptions. Take note of the program name. Here are some programs that meet the multi party example program assumptions:
-
-- addition_simple_multi_party.nada.bin
-- circuit_simple_multi_party.nada.bin
-- complex_operation_mix
-- greater_or_equal_than
-- greater_than
-- import_file
-- less_or_equal_than
-- less_than
-- multiplication_simple_multi_party.nada.bin
-- single_addition_multi_party.nada.bin
-- subtraction_simple_multi_party.nada.bin
-- subtraction_simple_neg_multi_party.nada.bin
-- reuse_simple_1_multi_party.nada.bin
-- reuse_simple_sub_multi_party.nada.bin
-
-For example before running addition_simple_multi_party.py, compile all programs and check that addition_simple_multi_party.nada.bin exists in the compiled-programs folder.
-
-```bash
-cd ../..
-./compile_programs.sh
-```
-
-3. Update values in config.py to set the stored program name, party names, secret names, and secret values.
-
-4. Start the 3 part example by running
-
-```bash
-python3 01_store_secret_party1.py
-```
-
-5. Follow the cli directions to run part 2 and 3 of the example.
diff --git a/examples_and_tutorials/core_concept_multi_party_compute/config.py b/examples_and_tutorials/core_concept_multi_party_compute/config.py
deleted file mode 100644
index 2c4ef4af..00000000
--- a/examples_and_tutorials/core_concept_multi_party_compute/config.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import os
-from dotenv import load_dotenv
-load_dotenv()
-
-# replace this with your program_id
-CONFIG_PROGRAM_NAME="addition_simple_multi_party_3"
-
-# 1st party
-CONFIG_PARTY_1={
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_1"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_1"),
- "nodekey_alternate_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_4"),
- "party_name": "Party1",
- "secrets": {
- "my_int1": 1,
- }
-}
-
-# N other parties
-CONFIG_N_PARTIES=[
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_2"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_2"),
- "party_name": "Party2",
- "secret_name": "my_int2",
- "secret_value": 5,
- },
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_3"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_3"),
- "party_name": "Party3",
- "secret_name": "my_int3",
- "secret_value": 2,
- },
-]
\ No newline at end of file
diff --git a/examples_and_tutorials/core_concept_permissions/01_fetch_reader_userid.py b/examples_and_tutorials/core_concept_permissions/01_fetch_reader_userid.py
deleted file mode 100644
index f41f4636..00000000
--- a/examples_and_tutorials/core_concept_permissions/01_fetch_reader_userid.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import asyncio
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
-
- # Reader Nillion client
- reader = create_nillion_client(userkey, nodekey)
- # Get the reader's user id
- reader_user_id = reader.user_id
-
- print("ℹ️ Fetched the reader's USER ID:", reader_user_id)
- print("\n\nRun the following command to store a secret and give read/retrieve permissions to the READER USER ID")
- print(f"\n📋 python3 02_store_permissioned_secret.py --retriever_user_id {reader_user_id}")
- return reader_user_id
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_permissions/02_store_permissioned_secret.py b/examples_and_tutorials/core_concept_permissions/02_store_permissioned_secret.py
deleted file mode 100644
index 82c344a0..00000000
--- a/examples_and_tutorials/core_concept_permissions/02_store_permissioned_secret.py
+++ /dev/null
@@ -1,76 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
- )
- parser.add_argument(
- "--retriever_user_id",
- required=True,
- type=str,
- help="User ID of the reader python client (derived from user key)",
- )
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_2"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_2"))
-
- # Writer Nillion client
- writer = create_nillion_client(userkey, nodekey)
- writer_user_id = writer.user_id
- print(writer_user_id, args.retriever_user_id)
-
- # Writer gives themself default core_concept_permissions
- permissions = nillion.Permissions.default_for_user(writer_user_id)
- # Writer gives the reader permission to read/retrieve secret
- permissions.add_retrieve_permissions(set([args.retriever_user_id, writer_user_id]))
-
- result = (
- "allowed"
- if permissions.is_retrieve_allowed(args.retriever_user_id)
- else "not allowed"
- )
- if result == "not allowed":
- raise Exception("failed to set core_concept_permissions")
-
- print(f"ℹ️ Permissions set: Reader {args.retriever_user_id} is {result} to retrieve the secret")
-
- secret_name_1 = "my_int1"
- secret_1 = nillion.SecretInteger(10)
-
- secret_name_2 = "my_int2"
- secret_2 = nillion.SecretInteger(32)
- secrets_object = nillion.Secrets({secret_name_1: secret_1, secret_name_2: secret_2})
-
- # Writer stores the permissioned secret, resulting in the secret's store id
- print(f"ℹ️ Storing permissioned secret: {secrets_object}")
- store_id = await writer.store_secrets(
- cluster_id, None, secrets_object, permissions
- )
-
- print("ℹ️ STORE ID:", store_id)
- print("\n\nRun the following command to retrieve the secret by store id as the reader")
- print(f"\n📋 python3 03_retrieve_secret.py --store_id {store_id}")
- return store_id
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_permissions/03_retrieve_secret.py b/examples_and_tutorials/core_concept_permissions/03_retrieve_secret.py
deleted file mode 100644
index 5076a968..00000000
--- a/examples_and_tutorials/core_concept_permissions/03_retrieve_secret.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import argparse
-import asyncio
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Use read permissions to retrieve a secret owned by another user on the Nillion network"
- )
- parser.add_argument(
- "--store_id",
- required=True,
- type=str,
- help="Store ID from the writer client store operation",
- )
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_3"))
-
- # Reader Nillion client
- reader = create_nillion_client(userkey, nodekey)
- reader_user_id = reader.user_id
-
- secret_name = "my_int1"
-
- # Reader retrieves the named secret by store id
- print(f"Retrieving secret as reader: {reader_user_id}")
- result = await reader.retrieve_secret(cluster_id, args.store_id, secret_name)
-
- print(f"🦄 Retrieved {secret_name} secret, value = {result[1].value}", file=sys.stderr)
- print("\n\nRun the following command to revoke the reader's retrieve permissions to the secret")
- print(f"\n📋 python3 04_revoke_read_permissions.py --store_id {args.store_id} --revoked_user_id {reader_user_id}")
- return [args.store_id, reader_user_id]
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_permissions/04_revoke_read_permissions.py b/examples_and_tutorials/core_concept_permissions/04_revoke_read_permissions.py
deleted file mode 100644
index 3a6d73ca..00000000
--- a/examples_and_tutorials/core_concept_permissions/04_revoke_read_permissions.py
+++ /dev/null
@@ -1,65 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Revoke user read/retrieve permissions from a secret on the Nillion network"
- )
- parser.add_argument(
- "--store_id",
- required=True,
- type=str,
- help="Store ID from the writer client store operation",
- )
- parser.add_argument(
- "--revoked_user_id",
- required=True,
- type=str,
- help="User ID of the reader python client (derived from user key)",
- )
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_2"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_4"))
-
- # Writer Nillion client
- writer = create_nillion_client(userkey, nodekey)
-
- # Create new permissions object to rewrite permissions (reader no longer has retrieve permission)
- new_permissions = nillion.Permissions.default_for_user(writer.user_id)
- result = (
- "allowed"
- if new_permissions.is_retrieve_allowed(args.revoked_user_id)
- else "not allowed"
- )
- if result != "not allowed":
- raise Exception("failed to create valid permissions object")
-
- # Update the permission
- print(f"ℹ️ Updating permissions for secret: {args.store_id}.")
- print(f"ℹ️ Reset permissions so that user id {args.revoked_user_id} is {result} to retrieve object.", file=sys.stderr)
- await writer.update_permissions( cluster_id, args.store_id , new_permissions)
-
- print("\n\nRun the following command to test that permissions have been properly revoked")
- print(f"\n📋 python3 05_test_revoked_permissions.py --store_id {args.store_id}")
- return args.store_id
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_permissions/05_test_revoked_permissions.py b/examples_and_tutorials/core_concept_permissions/05_test_revoked_permissions.py
deleted file mode 100644
index 21c257c1..00000000
--- a/examples_and_tutorials/core_concept_permissions/05_test_revoked_permissions.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import argparse
-import asyncio
-import os
-import sys
-import pytest
-import importlib
-
-from dotenv import load_dotenv
-
-fetch_reader_userid = importlib.import_module("01_fetch_reader_userid")
-store_permissioned_secret = importlib.import_module("02_store_permissioned_secret")
-retrieve_secret = importlib.import_module("03_retrieve_secret")
-revoke_read_permissions = importlib.import_module("04_revoke_read_permissions")
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Check that retrieval permissions on a Secret have been revoked"
- )
- parser.add_argument(
- "--store_id",
- required=True,
- type=str,
- help="Store ID from the writer client store operation",
- )
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_5"))
-
- # Reader Nillion client
- reader = create_nillion_client(userkey, nodekey)
- reader_user_id = reader.user_id
-
- try:
- secret_name = "my_int1"
- await reader.retrieve_secret(cluster_id, args.store_id, secret_name)
- print(f"⛔ FAIL: {reader_user_id} user id with revoked permissions was allowed to access secret", file=sys.stderr)
- except Exception as e:
- if str(e) == "retrieving secret: the user is not authorized to access the secret":
- print(f"🦄 Success: After user permissions were revoked, {reader_user_id} was not allowed to access secret", file=sys.stderr)
- else:
- raise(e)
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await fetch_reader_userid.main()
- args = ['--retriever_user_id', result]
- result = await store_permissioned_secret.main(args)
- args = ['--store_id', result]
- result = await retrieve_secret.main(args)
- args = ['--store_id', result[0], '--revoked_user_id', result[1]]
- result = await revoke_read_permissions.main(args)
- args = ['--store_id', result]
- await main(args)
diff --git a/examples_and_tutorials/core_concept_permissions/README.md b/examples_and_tutorials/core_concept_permissions/README.md
deleted file mode 100644
index 1be1b83b..00000000
--- a/examples_and_tutorials/core_concept_permissions/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-### Run permissions examples (storing and retrieving permissioned secrets, revoking permissions)
-
-Before running through examples, `./bootstrap-local-environment.sh` creates user keys for the secret writer and for the reader who the writer will allow to read the secret. Permissions examples are labeled 1-5:
-
-1. The reader fetches their user id
-2. The writer stores a secret and gives the reader retrieve permissions on the secret based on the reader's user id, resulting in a store id for the secret
-3. The reader retrieves the secret with the store id
-4. The writer revokes secret permissions by rewriting them
-5. The reader tries to retrieve the secret, but no longer has access to it
-
-To run through the example flow, simply run the python scripts in order. The output of a script will show you what to run next. Below gives the structure of the commands needed.
-
-```shell
-python3 01_fetch_reader_userid.py
-python3 02_store_permissioned_secret.py --retriever_user_id {READER_USER_ID}
-python3 03_retrieve_secret.py --store_id {STORE_ID}
-python3 04_revoke_read_permissions.py --store_id {STORE_ID} --revoked_user_id {READER_USER_ID}
-python3 05_test_revoked_permissions.py --store_id {STORE_ID}
-```
diff --git a/examples_and_tutorials/core_concept_single_party_compute/README.md b/examples_and_tutorials/core_concept_single_party_compute/README.md
deleted file mode 100644
index a719c9e1..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/README.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Single Party Compute Examples
-
-These compute examples only involve one party.
-
-## Run an example
-
-1. Set up requirements following the repo README to populate the .env file with environment variables.
-
-2. Follow README instructions to compile and store the program of the same name as the file
-
-For example before running addition_simple.py, compile all programs and check that addition_simple.nada.bin exists in the compiled-programs folder.
-
-```bash
-cd ../..
-./compile_programs.sh
-```
-
-3. Run the python example
-
-```bash
-python3 addition_simple.py
-```
diff --git a/examples_and_tutorials/core_concept_single_party_compute/addition_simple.py b/examples_and_tutorials/core_concept_single_party_compute/addition_simple.py
deleted file mode 100644
index 400cc1c3..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/addition_simple.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running simple addition on 1 stored secret and 1 compute time secret
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="addition_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(500),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({"my_int2": nillion.SecretInteger(10)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 510}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/circuit_simple.py b/examples_and_tutorials/core_concept_single_party_compute/circuit_simple.py
deleted file mode 100644
index 86194bcd..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/circuit_simple.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running a simple circuit on 2 stored secrets and 2 compute time secrets
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="circuit_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(3),
- "my_int2": nillion.SecretInteger(4),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "my_int3": nillion.SecretInteger(2),
- "my_int4": nillion.SecretInteger(5)
- })
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 22}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/circuit_simple_2.py b/examples_and_tutorials/core_concept_single_party_compute/circuit_simple_2.py
deleted file mode 100644
index 0fe9db9d..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/circuit_simple_2.py
+++ /dev/null
@@ -1,91 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running a simple circuit on 6 stored secrets and 3 compute time secrets
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="circuit_simple_2"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
- "C": nillion.SecretInteger(5),
- "D": nillion.SecretInteger(6),
- "E": nillion.SecretInteger(2),
- "F": nillion.SecretInteger(1),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "G": nillion.SecretInteger(9),
- "H": nillion.SecretInteger(10),
- "I": nillion.SecretInteger(7),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 319}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/complex.py b/examples_and_tutorials/core_concept_single_party_compute/complex.py
deleted file mode 100644
index 5cb0d2e7..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/complex.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running complex program on 5 stored secrets and 1 runtime secret
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="complex"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(10),
- "B": nillion.SecretInteger(2),
- "C": nillion.SecretInteger(1),
- "D": nillion.SecretInteger(5),
- "E": nillion.SecretInteger(4),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "F": nillion.SecretInteger(3),
- })
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'FINAL': 52}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/correlation_coefficient.py b/examples_and_tutorials/core_concept_single_party_compute/correlation_coefficient.py
deleted file mode 100644
index d4f3d964..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/correlation_coefficient.py
+++ /dev/null
@@ -1,132 +0,0 @@
-from pdb import set_trace as bp
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-from dotenv import load_dotenv
-import random
-from math import sqrt
-import pytest
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running simple addition on 1 stored secret and 1 compute time secret
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_0_name="Party0"
- party_1_name="Party1"
- out_party_name="OutParty"
- program_name="correlation_coefficient"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Config elements
- linear = lambda x: 30*x + 21
- p0_points = 10
- p1_points = 10
- precision = 5
-
- random.seed(42)
-
- # Create inputs for both parties
- party_0_dict = {}
- for i in range(p0_points):
- party_0_dict[f"x{i}"] = nillion.SecretInteger(i+1)
- party_0_dict[f"y{i}"] = nillion.SecretInteger(linear(i+1) + random.randint(0, 10))
-
- party_1_dict = {}
- for i in range(p0_points, p0_points + p1_points):
- party_1_dict[f"x{i}"] = nillion.SecretInteger(i+1)
- party_1_dict[f"y{i}"] = nillion.SecretInteger(linear(i+1) + random.randint(0, 10))
-
-
- # Parties store the secrets
- party_0_secrets = nillion.Secrets(party_0_dict)
- party_1_secrets = nillion.Secrets(party_1_dict)
-
- # Bind to the corresponding pary in the program
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_0_name, party_id)
- secret_bindings.add_input_party(party_1_name, party_id)
-
- # Give core_concept_permissions to owner to compute with my vote
- secret_permissions = nillion.Permissions.default_for_user(user_id)
- secret_permissions.add_compute_permissions({
- user_id: {program_id},
- })
-
- store_ids = []
- # Store in the network
- print(f"Storing party 0: {party_0_secrets}")
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, party_0_secrets, secret_permissions
- )
- store_ids.append(store_id)
- print(f"Stored party 0 with store_id ={store_id}")
-
-
- print(f"Storing party 1: {party_1_secrets}")
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, party_1_secrets, secret_permissions
- )
- store_ids.append(store_id)
- print(f"Stored party 1 with store_id ={store_id}")
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_0_name, party_id)
- compute_bindings.add_input_party(party_1_name, party_id)
- compute_bindings.add_output_party(out_party_name, party_id)
- computation_time_secrets = nillion.Secrets({})
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- store_ids,
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- corr_coeff_squared = compute_event.result.value["correlation_coefficient_squared"] / 10**precision
- sign = 1 if compute_event.result.value["sign"] else -1
- corr_coeff = round(sign * sqrt(corr_coeff_squared), precision)
- print(f"📈 Correlation coefficient = {corr_coeff} with precision {precision}.")
- return compute_event.result.value
-
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'correlation_coefficient_squared': 99958, 'sign': 1}
\ No newline at end of file
diff --git a/examples_and_tutorials/core_concept_single_party_compute/division_simple.py b/examples_and_tutorials/core_concept_single_party_compute/division_simple.py
deleted file mode 100644
index 10749918..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/division_simple.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running simple division on 2 stored secrets
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="division_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(10),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({"my_int3": nillion.PublicVariableInteger(2),}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 5}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/input_integer.py b/examples_and_tutorials/core_concept_single_party_compute/input_integer.py
deleted file mode 100644
index ab468c81..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/input_integer.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party, returns the secret input
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="input_integer"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "a": nillion.SecretInteger(16),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- nillion.Secrets({}),
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 16}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/input_single.py b/examples_and_tutorials/core_concept_single_party_compute/input_single.py
deleted file mode 100644
index da14b96f..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/input_single.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party, returns the secret input
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="input_single"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(91),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- nillion.Secrets({}),
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 91}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/modulo_simple.py b/examples_and_tutorials/core_concept_single_party_compute/modulo_simple.py
deleted file mode 100644
index 6dc55160..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/modulo_simple.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running modulo on 1 stored secrets and a public variable
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="modulo_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(37),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
- public_variables = nillion.PublicVariables({
- "public_my_int2": nillion.PublicVariableInteger(12)
- })
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- public_variables,
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 1}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/multiplication_simple.py b/examples_and_tutorials/core_concept_single_party_compute/multiplication_simple.py
deleted file mode 100644
index 2f682ddf..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/multiplication_simple.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running simple multiplication on 1 stored secret and 1 compute time secret
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- user_id = client.user_id
- party_name="Party1"
- program_name="multiplication_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(500),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({"my_int2": nillion.SecretInteger(10)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 5000}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/nada_fn_composition.py b/examples_and_tutorials/core_concept_single_party_compute/nada_fn_composition.py
deleted file mode 100644
index a4987ff0..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/nada_fn_composition.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="nada_fn_composition"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(500),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({"my_int2": nillion.SecretInteger(10)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 255000}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/nada_fn_simple.py b/examples_and_tutorials/core_concept_single_party_compute/nada_fn_simple.py
deleted file mode 100644
index f45734c9..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/nada_fn_simple.py
+++ /dev/null
@@ -1,81 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="nada_fn_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(500),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({"my_int2": nillion.SecretInteger(10)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 510}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reduce_simple.py b/examples_and_tutorials/core_concept_single_party_compute/reduce_simple.py
deleted file mode 100644
index 52766d9d..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reduce_simple.py
+++ /dev/null
@@ -1,88 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reduce_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret array
- secret_name = "my_array_1"
-
- secret_array= nillion.SecretArray([
- nillion.SecretInteger(1),
- nillion.SecretInteger(2),
- nillion.SecretInteger(3),
- nillion.SecretInteger(4),
- ])
-
- stored_secret_array = nillion.Secrets({secret_name: secret_array})
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret array
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret_array, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({"my_int1": nillion.SecretInteger(5)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'reduce.addition': 15}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse.py b/examples_and_tutorials/core_concept_single_party_compute/reuse.py
deleted file mode 100644
index 55d61343..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(4),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "C": nillion.SecretInteger(5),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'R': 27}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped1.py b/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped1.py
deleted file mode 100644
index 57e74be8..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped1.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse_flipped1"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
-
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "C": nillion.SecretInteger(5),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'R': 57}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped2.py b/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped2.py
deleted file mode 100644
index 006d8f89..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse_flipped2.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse_flipped2"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
-
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "C": nillion.SecretInteger(5),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'R': 112}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_1.py b/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_1.py
deleted file mode 100644
index 44716cee..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_1.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse_simple_1"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 84}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_2.py b/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_2.py
deleted file mode 100644
index a10f2617..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_2.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse_simple_2"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(4),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 49}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_sub.py b/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_sub.py
deleted file mode 100644
index 3becc296..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/reuse_simple_sub.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="reuse_simple_sub"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(50),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "B": nillion.SecretInteger(20),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 2100}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/simple.py b/examples_and_tutorials/core_concept_single_party_compute/simple.py
deleted file mode 100644
index ef2b1fef..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/simple.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
- "C": nillion.SecretInteger(5),
- "D": nillion.SecretInteger(6),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'O': 72}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/simple_literals.py b/examples_and_tutorials/core_concept_single_party_compute/simple_literals.py
deleted file mode 100644
index 7dba12cf..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/simple_literals.py
+++ /dev/null
@@ -1,82 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="simple_literals"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "C": nillion.SecretInteger(5),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'O': 1015}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables.py b/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables.py
deleted file mode 100644
index 95354635..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running compute with only public variables
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="simple_public_variables"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "C": nillion.SecretInteger(5),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- public_variables = nillion.PublicVariables({
- "B": nillion.PublicVariableInteger(10),
- "D": nillion.PublicVariableInteger(6),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- nillion.Secrets({}),
- public_variables,
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'O': 119}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables_only.py b/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables_only.py
deleted file mode 100644
index ba97ffba..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/simple_public_variables_only.py
+++ /dev/null
@@ -1,72 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running compute with only public variables
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="simple_public_variables_only"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
-
- public_variables = nillion.PublicVariables({
- "A": nillion.PublicVariableInteger(10),
- "B": nillion.PublicVariableInteger(6),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [],
- nillion.Secrets({}),
- public_variables,
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'O': 60}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/simple_sub.py b/examples_and_tutorials/core_concept_single_party_compute/simple_sub.py
deleted file mode 100644
index 261a66df..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/simple_sub.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="simple_sub"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- "B": nillion.SecretInteger(14),
- "C": nillion.SecretInteger(5),
- "D": nillion.SecretInteger(6),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({})
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'O': 12}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/single_addition.py b/examples_and_tutorials/core_concept_single_party_compute/single_addition.py
deleted file mode 100644
index ff36d500..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/single_addition.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running a simple circuit on 6 stored secrets and 3 compute time secrets
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="single_addition"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "A": nillion.SecretInteger(3),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "B": nillion.SecretInteger(14),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'R': 17}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple.py b/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple.py
deleted file mode 100644
index e25df271..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple.py
+++ /dev/null
@@ -1,84 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# 1 Party running a simple circuit on 6 stored secrets and 3 compute time secrets
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="subtraction_simple"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(30),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "my_int2": nillion.SecretInteger(90),
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 60}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple_neg.py b/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple_neg.py
deleted file mode 100644
index 8bdb441a..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/subtraction_simple_neg.py
+++ /dev/null
@@ -1,83 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
- party_id = client.party_id
- user_id = client.user_id
- party_name="Party1"
- program_name="subtraction_simple_neg"
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
-
- # store program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
-
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
- # Create a secret
- stored_secret = nillion.Secrets({
- "my_int4": nillion.SecretInteger(3),
- })
- secret_bindings = nillion.ProgramBindings(program_id)
- secret_bindings.add_input_party(party_name, party_id)
-
- # Store a secret
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, stored_secret, None
- )
-
- # Bind the parties in the computation to the client to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- computation_time_secrets = nillion.Secrets({
- "my_int2": nillion.SecretInteger(9)
- })
-
- # Compute on the secrets
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 6}
diff --git a/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py b/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
deleted file mode 100644
index 2ad87f97..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
+++ /dev/null
@@ -1,62 +0,0 @@
-import asyncio
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Complete the 🎯 TODOs to store the tiny_secret_addition program in the network, store secrets, and compute
-async def main():
- # 0. The bootstrap-local-environment.sh script put nillion-devnet config variables into the .env file
- # Get cluster_id, user_key, and node_key from the .env file
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
-
- # 🎯 TODO 1. Initialize NillionClient against nillion-devnet
- # Create Nillion Client for user
- client = create_nillion_client(userkey, nodekey)
-
- # 🎯 TODO 2. Get the user id and party id from NillionClient
-
-
- # 🎯 TODO 3. Store a compiled Nada program in the network
- # Set the program name
- program_name="tiny_secret_addition"
- # Set the path to the compiled program
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
- # Store the program
- # Create a variable for the program_id, which is the {user_id}/{program_name}
-
-
- # 🎯 TODO 4. Create the 1st secret with bindings to the program
- # Create a secret named "my_int1" with any value, ex: 500
- # Create secret bindings object to bind the secret to the program and set the input party
- # Set the input party for the secret
- # The party name needs to match the party name that is storing "my_int1" in the program
-
-
- # 🎯 TODO 5. Store the secret in the network and print the returned store_id
-
-
- # 🎯 TODO 6. Create compute bindings to set input and output parties
-
-
- # 🎯 TODO 7. Compute on the program with 1st secret from the network, and the 2nd secret, provided at compute time
- # Add my_int2, the 2nd secret at computation time
- # Compute on the secret
-
- # 🎯 TODO 8. Print the computation result
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition_complete.py b/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition_complete.py
deleted file mode 100644
index 84213fe7..00000000
--- a/examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition_complete.py
+++ /dev/null
@@ -1,101 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# This python script stores the tiny_secret_addition_complete program in the network, store secrets, and compute
-async def main():
- # 0. The bootstrap-local-environment.sh script put nillion-devnet config variables into the .env file
- # Get cluster_id, user_key, and node_key from the .env file
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
-
- # ✅ 1. Initialize NillionClient against nillion-devnet
- # Create Nillion Client for user
- client = create_nillion_client(userkey, nodekey)
-
- # ✅ 2. Get the user id and party id from NillionClient
- party_id = client.party_id
- user_id = client.user_id
-
- # ✅ 3. Store a compiled Nada program in the network
- # Set the program name
- program_name="tiny_secret_addition_complete"
- # Set the path to the compiled program
- program_mir_path=f"../../programs-compiled/{program_name}.nada.bin"
- # Store the program
- action_id = await client.store_program(
- cluster_id, program_name, program_mir_path
- )
- # Create a variable for the program_id, which is the {user_id}/{program_name}
- program_id=f"{user_id}/{program_name}"
- print('Stored program. action_id:', action_id)
- print('Stored program_id:', program_id)
-
-
- # ✅ 4. Create the 1st secret with bindings to the program
- # Create a secret named "my_int1" with any value, ex: 500
- new_secret = nillion.Secrets({
- "my_int1": nillion.SecretInteger(500),
- })
-
- # Create secret bindings object to bind the secret to the program and set the input party
- secret_bindings = nillion.ProgramBindings(program_id)
-
- # Set the input party for the secret
- # The party name needs to match the party name that is storing "my_int1" in the program
- party_name="Party1"
- secret_bindings.add_input_party(party_name, party_id)
-
- # ✅ 5. Store the secret in the network and print the returned store_id
- store_id = await client.store_secrets(
- cluster_id, secret_bindings, new_secret, None
- )
- print(f"Computing using program {program_id}")
- print(f"Use secret store_id: {store_id}")
-
- # ✅ 6. Create compute bindings to set input and output parties
- compute_bindings = nillion.ProgramBindings(program_id)
- compute_bindings.add_input_party(party_name, party_id)
- compute_bindings.add_output_party(party_name, party_id)
-
- # ✅ 7. Compute on the program with 1st secret from the network, and the 2nd secret, provided at compute time
-
- # Add my_int2, the 2nd secret at computation time
- computation_time_secrets = nillion.Secrets({"my_int2": nillion.SecretInteger(10)})
-
- # Compute on the secret
- compute_id = await client.compute(
- cluster_id,
- compute_bindings,
- [store_id],
- computation_time_secrets,
- nillion.PublicVariables({}),
- )
-
- # ✅ 8. Print the computation result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The result is {compute_event.result.value}")
- return compute_event.result.value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == {'my_output': 510}
diff --git a/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_blob.py b/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_blob.py
deleted file mode 100644
index 90ca81fb..00000000
--- a/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_blob.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Store and retrieve a SecretBlob using the Python Client
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
-
- # Create a SecretBlob
- secret_name = "my_blob"
-
- # create a bytearray from the string using UTF-8 encoding
- secret_value = bytearray("gm, builder!", "utf-8")
- secret_integer = nillion.Secrets({
- secret_name: nillion.SecretBlob(secret_value),
- })
-
- # Store a SecretBlob
- # Notice that both bindings and permissions are set to None
- # Secrets of type SecretBlob don't need bindings because they aren't used in programs
- # Permissions need to be set to allow users other than the secret creator to use the secret
- store_id = await client.store_secrets(
- cluster_id, None, secret_integer, None
- )
-
- print(f"The secret is stored at store_id: {store_id}")
-
- result_tuple = await client.retrieve_secret(cluster_id, store_id, secret_name)
- print(f"The secret name as a uuid is {result_tuple[0]}")
-
- decoded_secret_value = result_tuple[1].value.decode('utf-8')
- print(f"The secret value is '{decoded_secret_value}'")
- return decoded_secret_value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == 'gm, builder!'
diff --git a/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_integer.py b/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_integer.py
deleted file mode 100644
index 781dcabb..00000000
--- a/examples_and_tutorials/core_concept_store_and_retrieve_secrets/store_and_retrieve_integer.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Store and retrieve a SecretInteger using the Python Client
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- client = create_nillion_client(userkey, nodekey)
-
- # Create a SecretInteger
- secret_name = "my_int1"
- secret_value = 100
- secret_integer = nillion.Secrets({
- secret_name: nillion.SecretInteger(secret_value),
- })
-
- # Store a SecretInteger
- # Notice that both bindings and permissions are set to None
- # Bindings need to be set to use secrets in programs
- # Permissions need to be set to allow users other than the secret creator to use the secret
- store_id = await client.store_secrets(
- cluster_id, None, secret_integer, None
- )
-
- print(f"The secret is stored at store_id: {store_id}")
-
- result_tuple = await client.retrieve_secret(cluster_id, store_id, secret_name)
- print(f"The secret name as a uuid is {result_tuple[0]}")
- print(f"The secret value is {result_tuple[1].value}")
- return result_tuple[1].value
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await main()
- assert result == 100
diff --git a/examples_and_tutorials/millionaires_problem_example/01_store_secret_party1.py b/examples_and_tutorials/millionaires_problem_example/01_store_secret_party1.py
deleted file mode 100644
index f97083ba..00000000
--- a/examples_and_tutorials/millionaires_problem_example/01_store_secret_party1.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import asyncio
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-from config import (
- CONFIG_PARTY_1
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Alice stores the millionaires program in the network
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
- client_alice = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]), getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_file"])
- )
-
- millionaires_program_name = "millionaires"
-
- # Note: check out the code for the full millionaires program in the programs folder
- program_mir_path = "millionaires.nada.bin"
-
- # Store millionaires program in the network
- print(f"Storing program in the network: {millionaires_program_name}")
- await client_alice.store_program(
- cluster_id, millionaires_program_name, program_mir_path
- )
-
- user_id_alice = client_alice.user_id
- program_id = f"{user_id_alice}/{millionaires_program_name}"
-
- print(f"Alice stores millionaires program at program_id: {program_id}")
- print(f"Alice tells Bob and Charlie her user_id and the millionaires program_id")
-
- print("\n📋⬇️ Copy and run the following command to store Bob and Charlie's salaries in the network")
- print(f"\npython3 02_store_secret_party_n.py --user_id_1 {user_id_alice} --program_id {program_id}")
- return [user_id_alice, program_id]
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/millionaires_problem_example/02_store_secret_party_n.py b/examples_and_tutorials/millionaires_problem_example/02_store_secret_party_n.py
deleted file mode 100644
index 63f5e910..00000000
--- a/examples_and_tutorials/millionaires_problem_example/02_store_secret_party_n.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-
-from dotenv import load_dotenv
-from config import (
- CONFIG_N_PARTIES
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Bob and Charlie store their salaries in the network
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
- )
- parser.add_argument(
- "--user_id_1",
- required=True,
- type=str,
- help="User ID of the user who will compute with the secret being stored",
- )
- parser.add_argument(
- "--program_id",
- required=True,
- type=str,
- help="Program ID of the millionaires program",
- )
-
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- # start a list of store ids to keep track of stored secrets
- store_ids = []
- party_ids = []
-
- for party_info in CONFIG_N_PARTIES:
- client_n = create_nillion_client(
- getUserKeyFromFile(party_info["userkey_file"]),
- getNodeKeyFromFile(party_info["nodekey_file"])
- )
- party_id_n = client_n.party_id
- user_id_n = client_n.user_id
- party_name = party_info["party_name"]
- secret_name = party_info["secret_name"]
- secret_value = party_info["secret_value"]
-
- # Create a secret for the current party
- stored_secret = nillion.Secrets({
- secret_name: nillion.SecretInteger(secret_value)
- })
-
- # Create input bindings for the specific millionaires program by program id
- secret_bindings = nillion.ProgramBindings(args.program_id)
-
- # Add the respective input party to say who will provide the input to the program
- secret_bindings.add_input_party(party_name, party_id_n)
- print(f"\n🔗 {party_name} sets bindings so that the secret can be input to a specific program (program_id: {args.program_id}) by a specific party (party_id: {party_id_n})")
-
- # Create permissions object with default permissions for the current user
- permissions = nillion.Permissions.default_for_user(user_id_n)
-
- # Give compute permissions to Alice so she can use the secret in the specific millionionaires program by program id
- compute_permissions = {
- args.user_id_1: {args.program_id},
- }
- permissions.add_compute_permissions(compute_permissions)
- print(f"\n👍 {party_name} gives compute permissions on their secret to Alice's user_id: {args.user_id_1}")
-
- # Store the permissioned secret
- store_id = await client_n.store_secrets(
- cluster_id, secret_bindings, stored_secret, permissions
- )
-
- store_ids.append(store_id)
- party_ids.append(party_id_n)
-
- print(f"\n🎉 {party_name} stored {secret_name}: {secret_value} at store id: {store_id}")
-
-
- party_ids_to_store_ids = ' '.join([f'{party_id}:{store_id}' for party_id, store_id in zip(party_ids, store_ids)])
-
- print("\n📋⬇️ Copy and run the following command to run multi party computation using the secrets")
- print(f"\npython3 03_multi_party_compute.py --program_id {args.program_id} --party_ids_to_store_ids {party_ids_to_store_ids}")
- return [args.program_id, party_ids_to_store_ids]
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- pass
diff --git a/examples_and_tutorials/millionaires_problem_example/03_multi_party_compute.py b/examples_and_tutorials/millionaires_problem_example/03_multi_party_compute.py
deleted file mode 100644
index d8ac2776..00000000
--- a/examples_and_tutorials/millionaires_problem_example/03_multi_party_compute.py
+++ /dev/null
@@ -1,127 +0,0 @@
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-import pytest
-import importlib
-
-from dotenv import load_dotenv
-
-from config import (
- CONFIG_PARTY_1,
- CONFIG_N_PARTIES
-)
-
-store_secret_party_1 = importlib.import_module("01_store_secret_party1")
-store_secret_party_n = importlib.import_module("02_store_secret_party_n")
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-async def main(args = None):
- parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
- )
-
- parser.add_argument(
- "--program_id",
- required=True,
- type=str,
- help="Program ID of the millionaires program",
- )
-
- parser.add_argument(
- "--party_ids_to_store_ids",
- required=True,
- nargs='+',
- type=str,
- help="List of partyid:storeid pairs of the secrets, with each pair separated by a space",
- )
-
-
- args = parser.parse_args(args)
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- # Alice initializes a client
- client_alice = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]),
- getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_alternate_file"])
- )
- party_id_alice = client_alice.party_id
-
- # Create computation bindings for millionaires program
- compute_bindings = nillion.ProgramBindings(args.program_id)
-
- # Add Alice as an input party
- compute_bindings.add_input_party(CONFIG_PARTY_1["party_name"], party_id_alice)
-
- # Add an output party (Alice).
- # The output party reads the result of the blind computation
- compute_bindings.add_output_party(CONFIG_PARTY_1["party_name"], party_id_alice)
-
- print(f"Computing using program {args.program_id}")
-
- # Also add Bob and Charlie as input parties
- party_ids_to_store_ids = {}
- i=0
- for pair in args.party_ids_to_store_ids:
- party_id, store_id = pair.split(':')
- party_name = CONFIG_N_PARTIES[i]['party_name']
- compute_bindings.add_input_party(party_name, party_id)
- party_ids_to_store_ids[party_id] = store_id
- i=i+1
-
- # Add any computation time secrets
- # Alice provides her salary at compute time
- party_name_alice = CONFIG_PARTY_1["party_name"]
- secret_name_alice = CONFIG_PARTY_1["secret_name"]
- secret_value_alice = CONFIG_PARTY_1["secret_value"]
- compute_time_secrets = nillion.Secrets({
- secret_name_alice: nillion.SecretInteger(secret_value_alice)
- })
-
- print(f"\n🎉 {party_name_alice} provided {secret_name_alice}: {secret_value_alice} as a compute time secret")
-
- # Compute on the secret with all store ids. Note that there are no compute time secrets or public variables
- compute_id = await client_alice.compute(
- cluster_id,
- compute_bindings,
- list(party_ids_to_store_ids.values()), # Bob and Charlie's stored secrets
- compute_time_secrets, # Alice's computation time secret
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- while True:
- compute_event = await client_alice.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- print(f"🖥️ The output result is {compute_event.result.value}")
-
- # The compute result is an index
- # Map it to the corresponding party name who should pay for lunch
- # ['Alice', 'Bob', 'Charlie']
- my_parties = CONFIG_N_PARTIES
- my_parties.insert(0, CONFIG_PARTY_1)
- richest_party = my_parties[compute_event.result.value["largest_position"]]["party_name"]
- print(f"The richest friend is {richest_party}")
- return richest_party
-
-if __name__ == "__main__":
- asyncio.run(main())
-
-@pytest.mark.asyncio
-async def test_main():
- result = await store_secret_party_1.main()
- args = ['--user_id_1', result[0], '--program_id', result[1]]
- result = await store_secret_party_n.main(args)
- store_ids = result[1].split(' ', 1)
- args = ['--program_id', result[0], '--party_ids_to_store_ids', store_ids[0], store_ids[1]]
- result = await main(args)
- assert result == 'Charlie'
diff --git a/examples_and_tutorials/millionaires_problem_example/README.md b/examples_and_tutorials/millionaires_problem_example/README.md
deleted file mode 100644
index 181ec1a1..00000000
--- a/examples_and_tutorials/millionaires_problem_example/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# MPC Millionaires Problem Example
-
-In our version of the [Millionaires Problem](https://docs.nillion.com/multi-party-computation#classic-scenario-the-millionaires-problem), three friends, Alice, Bob & Charlie finish lunch and decide that the richest friend should pay the bill.
-
-They want to figure out who has the highest salary without telling each other how much they earn.
-
-Alice suggests that this is the perfect opportunity for the friends to use Nillion for blind computation on high value data to determine who should pay for lunch. She offers to create a millionaires problem program, compile it, and store it in Nillion so that the friends can run multi party blind computation to figure out who should pay for lunch.
-
-- Alice's millionaires program in NADA: [../../programs/millionaires.py](https://github.com/NillionNetwork/nillion-python-starter/blob/main/programs/millionaires.py)
-- Compiled program: [./millionaires.nada.bin](https://github.com/NillionNetwork/nillion-python-starter/blob/main/millionaires_problem_example/millionaires.nada.bin)
-
-## Setup
-
-Before running the example, [follow the repo README](https://github.com/NillionNetwork/nillion-python-starter/blob/main/README.md) to install cli dependencies, complete environment setup, and activate your .venv environment.
-
-## Run the example
-
-### Step 1
-
-- Alice creates and stores program in the network
-- Alice shares her user id and the resulting program id with Bob and Charlie
-
-Run the command to perform step 1.
-
-```bash
-python3 01_store_secret_party1.py
-```
-
-### Step 2
-
-- Bob and Charlie store their salaries in the network as secrets. Each secret is stored with
- - **bindings** to the millionaires program id
- - **permissions** so Alice can compute using the secret
-- Bob and Charlie each share their party_id and secret store_id with Alice.
-
-The script will provide the command to perform step 2.
-
-```bash
-python3 02_store_secret_party_n.py --user_id_1 {user_id} --program_id {program_id}
-```
-
-### Step 3
-
-- Alice runs millionaires program computation using Bob and Charlie's secret salaries. She provides her own salary as a secret at computation time.
-- Alice receives the output result of the program, and the friends know that Charlie should pay for lunch.
-
-The script will provide the command to perform step 3.
-
-```bash
-python3 03_multi_party_compute.py --program_id {program_id} --party_ids_to_store_ids {party_ids_to_store_ids}
-```
diff --git a/examples_and_tutorials/millionaires_problem_example/config.py b/examples_and_tutorials/millionaires_problem_example/config.py
deleted file mode 100644
index 24fb49d8..00000000
--- a/examples_and_tutorials/millionaires_problem_example/config.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import os
-import py_nillion_client as nillion
-from dotenv import load_dotenv
-load_dotenv()
-
-# Alice
-CONFIG_PARTY_1={
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_1"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_1"),
- "nodekey_alternate_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_4"),
- "party_name": "Alice",
- "secret_name": "alice_salary",
- "secret_value": 10000,
-}
-
-# Bob and Charlie
-CONFIG_N_PARTIES=[
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_2"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_2"),
- "party_name": "Bob",
- "secret_name": "bob_salary",
- "secret_value": 8000,
- },
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_3"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_3"),
- "party_name": "Charlie",
- "secret_name": "charlie_salary",
- "secret_value": 12000,
- },
-]
\ No newline at end of file
diff --git a/examples_and_tutorials/millionaires_problem_example/millionaires.nada.bin b/examples_and_tutorials/millionaires_problem_example/millionaires.nada.bin
deleted file mode 100644
index b2ac6e1f..00000000
Binary files a/examples_and_tutorials/millionaires_problem_example/millionaires.nada.bin and /dev/null differ
diff --git a/examples_and_tutorials/voting_tutorial/01_store_program_party1.py b/examples_and_tutorials/voting_tutorial/01_store_program_party1.py
deleted file mode 100644
index afbe2cbb..00000000
--- a/examples_and_tutorials/voting_tutorial/01_store_program_party1.py
+++ /dev/null
@@ -1,115 +0,0 @@
-##########################################################################################
-
-# VOTING -- PART 1
-
-##########################################################################################
-
-
-import asyncio
-import os
-import sys
-from dotenv import load_dotenv
-from config import (
- CONFIG_PARTY_1
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-# Alice stores the voting program in the network
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- while True:
-
- # Below, you can choose which voting program to use. In case you choose a voting program
- # different from the robust version ('voting_dishonest_robust_6'), you can complete
- # either 'digest_plurality_vote_honest_result()' or 'digest_plurality_vote_dishonest_with_abort_result()'
- # functions to digest the result.
- #
- # Existing voting programs:
- #
- # program_name = "voting_honest_1"
- # program_name = "voting_honest_2"
- # program_name = "voting_dishonest_abort_5"
- # program_name = "voting_dishonest_robust_6"
-
- print("Choose a program to test:")
- print("1. voting_honest_1")
- print("2. voting_honest_2")
- print("3. voting_dishonest_abort_5")
- print("4. voting_dishonest_robust_6")
-
- choice = input("Enter the number corresponding to your choice: ")
-
- programs = {
- "1": "voting_honest_1",
- "2": "voting_honest_2",
- "3": "voting_dishonest_abort_5",
- "4": "voting_dishonest_robust_6"
- }
-
- if choice in programs:
- program_name = programs[choice]
- print("You have chosen:", program_name)
- print(" _ _ _ _ _ _ _ ")
- print("| | ___| |_( )___ __ _____ | |_ ___ __ _(_) |_| |__ ")
- print("| | / _ \\ __|// __| \\ \\ / / _ \\| __/ _ \\ \\ \\ /\\ / / | __| '_ \\ ")
- print("| |__| __/ |_ \\__ \\ \\ V / (_) | || __/ \\ V V /| | |_| | | |")
- print("|_____\\___|\\__| |___/ \\_/_\\___/ \\__\\___| \\_/\\_/ |_|\\__|_| |_|")
- print(" _____(_) | (_) ___ _____| | ")
- print(" | _ | | | | |/ _ \\| _ | | ")
- print(" | | | | | | | | (_) | | | |_| ")
- print(" |_| |_|_|_|_|_|\\___/|_| |_(_) ")
- print(" ")
- break # Exit the loop if a valid choice is made
- else:
- print("Invalid choice. Please enter a number between 1 and 4.")
-
- #####################################
- # 1. Parties initialization #
- #####################################
-
- #############################
- # 1.1 Owner initialization #
- #############################
-
- client_alice = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]), getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_file"])
- )
-
- #####################################
- # 2. Storing program #
- #####################################
-
- program_mir_path = f"../../programs-compiled/{program_name}.nada.bin"
- if os.path.exists(program_mir_path):
- None
- else:
- raise FileNotFoundError(f"The file '{program_mir_path}' does not exist.\nMake sure you compiled the PyNada programs with './compile_programs.sh'.\nCheck README.md for more details.")
-
- # Store program in the Network
- print(f"Storing program in the network: {program_name}")
- action_id = await client_alice.store_program(
- cluster_id, program_name, program_mir_path
- )
- print("action_id is: ", action_id)
- user_id_alice = client_alice.user_id
- program_id = f"{user_id_alice}/{program_name}"
- print("program_id is: ", program_id)
-
- #####################################
- # 3. Send program ID #
- #####################################
-
- # This requires its own mechanism in a real environment.
- print(f"Alice stored {program_name} program at program_id: {program_id}")
- print(f"Alice tells Bob and Charlie her user_id and the voting program_id")
-
- print("\n📋⬇️ Copy and run the following command to store Bob and Charlie's votes in the network")
- print(f"\npython3 02_store_secret_party_n.py --user_id_1 {user_id_alice} --program_id {program_id}")
-
-asyncio.run(main())
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/02_store_secret_party_n.py b/examples_and_tutorials/voting_tutorial/02_store_secret_party_n.py
deleted file mode 100644
index 8a5ce0a5..00000000
--- a/examples_and_tutorials/voting_tutorial/02_store_secret_party_n.py
+++ /dev/null
@@ -1,118 +0,0 @@
-##########################################################################################
-
-# VOTING -- PART 2
-
-##########################################################################################
-
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-from dotenv import load_dotenv
-from config import (
- CONFIG_N_PARTIES
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-
-load_dotenv()
-
-parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
-)
-parser.add_argument(
- "--user_id_1",
- required=True,
- type=str,
- help="User ID of the user who will compute with the secret being stored",
-)
-parser.add_argument(
- "--program_id",
- required=True,
- type=str,
- help="Program ID of the voting program",
-)
-
-args = parser.parse_args()
-
-# Bob and Charlie store their votes in the network
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- # start a list of store ids to keep track of stored secrets
- store_ids = []
- party_ids = []
-
- for party_info in CONFIG_N_PARTIES:
-
- #####################################
- # 1. Parties initialization #
- #####################################
-
- #############################
- # 1.2 Voters initialization #
- #############################
- client_n = create_nillion_client(
- getUserKeyFromFile(party_info["userkey_file"]),
- getNodeKeyFromFile(party_info["nodekey_file"])
- )
- party_id_n = client_n.party_id
- user_id_n = client_n.user_id
- party_name = party_info["party_name"]
- party_role = party_info["party_role"]
- secret_votes = party_info["secret_votes"]
-
- #####################################
- # 4. Storing votes #
- #####################################
- # Create a secret for the current party
- secret_votes = {key: nillion.SecretUnsignedInteger(value) for key, value in secret_votes.items()}
- stored_secret = nillion.Secrets(secret_votes)
-
- ###########################################
- # 4.1 Bind voter to party in the program #
- ###########################################
- # Create input bindings for the specific voting program by program id
- secret_bindings = nillion.ProgramBindings(args.program_id)
-
- # Add the respective input party to say who will provide the input to the program
- secret_bindings.add_input_party(party_role, party_id_n)
- print(f"\n🔗 {party_name} sets bindings so that the secret can be input to a specific program (program_id: {args.program_id}) by a specific party (party_id: {party_id_n})")
-
- ###########################################
- # 4.2 Set compute permissions to owner #
- ###########################################
- # Create permissions object with default permissions for the current user
- permissions = nillion.Permissions.default_for_user(user_id_n)
-
- # Give compute permissions to Alice so she can use the secret in the specific voting program by program id
- compute_permissions = {
- args.user_id_1: {args.program_id},
- }
- permissions.add_compute_permissions(compute_permissions)
- print(f"\n👍 {party_name} gives compute permissions on their secret to Alice's user_id: {args.user_id_1}")
-
- # Store the permissioned secret
- store_id = await client_n.store_secrets(
- cluster_id, secret_bindings, stored_secret, permissions
- )
-
- store_ids.append(store_id)
- party_ids.append(party_id_n)
-
- print(f"\n🎉 {party_name} stored its vote at store id: {store_id}")
-
- #####################################
- # 5. Send party IDs and store IDs #
- #####################################
-
- # This requires its own mechanism in a real environment.
- party_ids_to_store_ids = ' '.join([f'{party_id}:{store_id}' for party_id, store_id in zip(party_ids, store_ids)])
-
- print("\n📋⬇️ Copy and run the following command to run multi party computation using the secrets")
- print(f"\npython3 03_multi_party_compute.py --program_id {args.program_id} --party_ids_to_store_ids {party_ids_to_store_ids}")
-
-asyncio.run(main())
diff --git a/examples_and_tutorials/voting_tutorial/03_multi_party_compute.py b/examples_and_tutorials/voting_tutorial/03_multi_party_compute.py
deleted file mode 100644
index f357de86..00000000
--- a/examples_and_tutorials/voting_tutorial/03_multi_party_compute.py
+++ /dev/null
@@ -1,153 +0,0 @@
-##########################################################################################
-
-# VOTING -- PART 3
-
-##########################################################################################
-
-import argparse
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-from dotenv import load_dotenv
-from config import (
- CONFIG,
- CONFIG_CANDIDATES,
- CONFIG_PARTY_1,
- CONFIG_N_PARTIES
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-from digest_result import digest_plurality_vote_honest_result, digest_plurality_vote_dishonest_with_abort_result, digest_plurality_vote_robust_result
-
-
-load_dotenv()
-
-parser = argparse.ArgumentParser(
- description="Create a secret on the Nillion network with set read/retrieve permissions"
-)
-
-parser.add_argument(
- "--program_id",
- required=True,
- type=str,
- help="Program ID of the voting program",
-)
-
-parser.add_argument(
- "--party_ids_to_store_ids",
- required=True,
- nargs='+',
- type=str,
- help="List of partyid:storeid pairs of the secrets, with each pair separated by a space",
-)
-
-args = parser.parse_args()
-
-async def main():
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- #####################################
- # 1. Parties initialization #
- #####################################
-
- #############################
- # 1.1 Owner initialization #
- #############################
- # Alice initializes a client
- client_alice = create_nillion_client(
- getUserKeyFromFile(CONFIG_PARTY_1["userkey_file"]),
- getNodeKeyFromFile(CONFIG_PARTY_1["nodekey_file"])
- )
- party_id_alice = client_alice.party_id
-
- #####################################
- # 4. Storing votes #
- #####################################
- # Add any computation time secrets
- # Alice provides her vote at compute time
-
- party_name_alice = CONFIG_PARTY_1["party_name"]
- secret_votes = CONFIG_PARTY_1["secret_votes"]
- secret_votes = {key: nillion.SecretUnsignedInteger(value) for key, value in secret_votes.items()}
- compute_time_secrets = nillion.Secrets(secret_votes)
-
- print(f"\n🎉 {party_name_alice} provided her vote as a compute time secret.")
-
- #####################################
- # 6. Owner execute computation #
- #####################################
- # Create computation bindings for voting program
- compute_bindings = nillion.ProgramBindings(args.program_id)
-
- #################################################
- # 6.1 Bind voter to input party in the program #
- #################################################
- # Add Alice as an input party
- compute_bindings.add_input_party(CONFIG_PARTY_1["party_role"], party_id_alice)
-
- # Also add Bob and Charlie as input parties
- party_ids_to_store_ids = {}
- i=0
- for pair in args.party_ids_to_store_ids:
- party_id, store_id = pair.split(':')
- party_role = CONFIG_N_PARTIES[i]['party_role']
- compute_bindings.add_input_party(party_role, party_id)
- party_ids_to_store_ids[party_id] = store_id
- i=i+1
-
- ##################################################
- # 6.2 Bind owner to output party in the program #
- ##################################################
- # Add an output party (Alice).
- # The output party reads the result of the blind computation
- compute_bindings.add_output_party("OutParty", party_id_alice)
-
- print(f"Computing using program {args.program_id}")
-
- # Compute on the secret with all store ids. Note that there are no compute time secrets or public variables
- compute_id = await client_alice.compute(
- cluster_id,
- compute_bindings,
- list(party_ids_to_store_ids.values()), # Bob and Charlie's stored secrets
- compute_time_secrets, # Alice's computation time secret
- nillion.PublicVariables({}),
- )
-
- # Print compute result
- print(f"The computation was sent to the network. compute_id: {compute_id}")
- print("Waiting computation response...")
- while True:
- compute_event = await client_alice.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- dict_result = compute_event.result.value
- print(f"🖥️ The output result is {dict_result}\n")
-
- # Digest the result
- program_name = os.path.basename(args.program_id)
- nr_candidates = CONFIG["nr_candidates"]
- nr_voters = CONFIG["nr_voters"]
- voters = CONFIG_N_PARTIES
- voters.insert(0, CONFIG_PARTY_1)
- candidates = CONFIG_CANDIDATES
- if program_name == "voting_dishonest_robust_6":
- print("Let use digest the result given by the network:")
- winner, total_votes, cheaters = digest_plurality_vote_robust_result(dict_result, nr_candidates, nr_voters)
- winner_name = candidates[winner]
- cheaters_names = [voters[voter]["party_name"] for voter in cheaters]
- print(f"🏆 Winner is {winner_name}")
- print(f"🔢 Total number of votes per candidate:")
- print(f" Dave: {total_votes[0]}")
- print(f" Emma: {total_votes[1]}")
- print(f"🕵️♂️ List of cheaters: {cheaters_names}")
- elif program_name in ["voting_honest_1", "voting_honest_2"]:
- digest_plurality_vote_honest_result(dict_result, nr_candidates, nr_voters)
- elif program_name == "voting_dishonest_abort_5":
- digest_plurality_vote_dishonest_with_abort_result(dict_result, nr_candidates, nr_voters)
-
- break
-
-asyncio.run(main())
diff --git a/examples_and_tutorials/voting_tutorial/README.md b/examples_and_tutorials/voting_tutorial/README.md
deleted file mode 100644
index f4ea3380..00000000
--- a/examples_and_tutorials/voting_tutorial/README.md
+++ /dev/null
@@ -1,87 +0,0 @@
-# Voting tutorial
-
-This tutorial aims to introduce you to the features of PyNada embedded DSL through the use of voting systems. We'll start simple and gradually increase the complexity of the programs to show you some interesting techniques.
-
-Additionally, we've provided two sets of Python scripts for you to explore the flow of a voting system running in `devnet-nillion`:
-
-1. Single File: One script emulates the behavior of all parties.
-2. Multiple Files: Each party runs in its own separate script.
-
-In a real-world scenario, the roles should be distributed across multiple machines.
-
-## Tutorial
-
-Please go to the [tutorial page](tutorial.md) to dive deeper into PyNada.
-
-## Setup
-
-Before running the example, [follow the repo README](../../README.md) to install cli dependencies, complete environment setup, and activate your .venv environment.
-
-## Single file example
-
-In the single file version, the different roles are played by a single entity (`general_client`). The script has the following flow:
-
- 1. Parties initialization.
- 2. Owner stores a program.
- 3. (Real environment:) Owner sends the program ID to all voters.
- 4. Voters store votes:
- 4.1 Bind voter to party in the program
- 4.2 Set compute permission to owner
- 5. (Real environment:) Voters send their their party IDs and store IDs to the owner.
- 6. Owner compute voting system using votes from voters.
-
-Also, we present a function [`digest_plurality_vote_robust_result()`](digest_result.py) that digests the result output by the [voting_dishonest_robust_6.py](../../programs/voting_dishonest_robust_6.py).
-
-### Run
-
-Run the command to start the example and follow the steps described:
-```bash
-python3 client_voting.py
-```
-
-## Multiple files example
-
-In this voting example, we maintain the same structure as in previous multiparty computation examples:
-
-- Alice assumes the role of the owner and acts as voter 0.
-- Bob serves as voter 1.
-- Charlie takes on the role of voter 2.
-
-Furthermore, the voters will cast their votes for two candidates: Dave and Emma.
-
-### Step 1
-
-- Alice creates and stores program in the network
-- Alice shares her user id and the resulting program id with Bob and Charlie
-
-Run the command to perform step 1.
-
-```bash
-python3 01_store_secret_party1.py
-```
-
-### Step 2
-
-- Bob and Charlie store their VOTES in the network as secrets. Each secret is stored with
- - **bindings** to the voting program id.
- - **permissions** so Alice (the owner) can compute using the secret.
-- Bob and Charlie each share their `party_id` and secret `store_id` with Alice.
-
-The script will provide the command to perform step 2.
-
-```bash
-python3 02_store_secret_party_n.py --user_id_1 {user_id} --program_id {program_id}
-```
-
-### Step 3
-
-- Alice runs voting program computation using Bob and Charlie's secret votes. She provides her own vote as a secret at computation time.
-- Alice receives the output result of the program.
-
-The script will provide the command to perform step 3.
-
-```bash
-python3 03_multi_party_compute.py --program_id {program_id} --party_ids_to_store_ids {party_ids_to_store_ids}
-```
-
-Also, we present a function [`digest_plurality_vote_robust_result()`](digest_result.py) that digests the result output by the [voting_dishonest_robust_6.py](../../programs/voting_dishonest_robust_6.py).
diff --git a/examples_and_tutorials/voting_tutorial/client_voting.py b/examples_and_tutorials/voting_tutorial/client_voting.py
deleted file mode 100644
index 8ac02a7d..00000000
--- a/examples_and_tutorials/voting_tutorial/client_voting.py
+++ /dev/null
@@ -1,294 +0,0 @@
-##########################################################################################
-
-# SINGLE FILE VOTING
-
-##########################################################################################
-
-
-import asyncio
-import py_nillion_client as nillion
-import os
-import sys
-from dotenv import load_dotenv
-from config import (
- CONFIG
-)
-
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
-from helpers.nillion_client_helper import create_nillion_client
-from helpers.nillion_keypath_helper import getUserKeyFromFile, getNodeKeyFromFile
-from digest_result import digest_plurality_vote_honest_result, digest_plurality_vote_dishonest_with_abort_result, digest_plurality_vote_robust_result
-
-load_dotenv()
-
-async def main():
-
- cluster_id = os.getenv("NILLION_CLUSTER_ID")
-
- while True:
-
- # Below, you can choose which voting program to use. In case you choose a voting program
- # different from the robust version ('voting_dishonest_robust_6'), you can complete
- # either 'digest_plurality_vote_honest_result()' or 'digest_plurality_vote_dishonest_with_abort_result()'
- # functions above to digest the result.
- #
- # Existing voting programs:
- #
- # program_name = "voting_honest_1"
- # program_name = "voting_honest_2"
- # program_name = "voting_dishonest_abort_5"
- # program_name = "voting_dishonest_robust_6"
-
- print("Choose a program to test:")
- print("1. voting_honest_1")
- print("2. voting_honest_2")
- print("3. voting_dishonest_abort_5")
- print("4. voting_dishonest_robust_6")
-
- choice = input("Enter the number corresponding to your choice: ")
-
- programs = {
- "1": "voting_honest_1",
- "2": "voting_honest_2",
- "3": "voting_dishonest_abort_5",
- "4": "voting_dishonest_robust_6"
- }
-
- if choice in programs:
- program_name = programs[choice]
- print("You have chosen:", program_name)
- print(" _ _ _ _ _ _ _ ")
- print("| | ___| |_( )___ __ _____ | |_ ___ __ _(_) |_| |__ ")
- print("| | / _ \\ __|// __| \\ \\ / / _ \\| __/ _ \\ \\ \\ /\\ / / | __| '_ \\ ")
- print("| |__| __/ |_ \\__ \\ \\ V / (_) | || __/ \\ V V /| | |_| | | |")
- print("|_____\\___|\\__| |___/ \\_/_\\___/ \\__\\___| \\_/\\_/ |_|\\__|_| |_|")
- print(" _____(_) | (_) ___ _____| | ")
- print(" | _ | | | | |/ _ \\| _ | | ")
- print(" | | | | | | | | (_) | | | |_| ")
- print(" |_| |_|_|_|_|_|\\___/|_| |_(_) ")
- print(" ")
- break # Exit the loop if a valid choice is made
- else:
- print("Invalid choice. Please enter a number between 1 and 4.")
-
- # We initialize one party 'general_client' that represents all different parties.
- #
- # In a real environment, the clients must run in different machines with
- # different node and user keys.
- #
- # The script has the following flow:
- # 1. Parties initialization
- # 2. Owner stores a program.
- # 3. (Real environment:) Owner sends the program ID to all voters.
- # 4. Voters store votes:
- # 4.1 Bind voter to party in the program
- # 4.2 Set compute permission to owner
- # 5. (Real environment:) Voters send their their party IDs and store IDs to the owner.
- # 6. Owner compute voting system using votes from voters.
-
- nr_candidates = CONFIG["nr_candidates"]
- nr_voters = CONFIG["nr_voters"]
-
- #####################################
- # 1. Parties initialization #
- #####################################
-
- ######################################
- # 1.0 General client initialization #
- ######################################
- userkey = getUserKeyFromFile(os.getenv("NILLION_USERKEY_PATH_PARTY_1"))
- nodekey = getNodeKeyFromFile(os.getenv("NILLION_NODEKEY_PATH_PARTY_1"))
- general_client = create_nillion_client(userkey, nodekey)
-
- # #############################
- # # 1.1 Owner initialization #
- # #############################
- # # Path to the user and node key generated in previous step
- # owner_nodekey_path = "/path/to/owner_node.key"
- # owner_nodekey = nillion.NodeKey.from_file(owner_nodekey_path)
- # owner_userkey_path = "/path/to/owner_user.key"
- # owner_userkey = nillion.UserKey.from_file(owner_userkey_path)
- # owner = nillion.NillionClient(
- # owner_nodekey,
- # bootnodes,
- # nillion.ConnectionMode.relay(),
- # owner_userkey,
- # payments_config=payments_config
- # )
-
- # #############################
- # # 1.2 Voters initialization #
- # #############################
- # # Initialize voters
- # voters = []
- # for v in range(nr_voters):
- # # Path to the user and node key generated in previous step
- # voter_nodekey_path = "/path/to/voter"+str(v)+"_node.key"
- # voter_nodekey = nillion.NodeKey.from_file(voter_nodekey_path)
- # voter_userkey_path = "/path/to/voter"+str(v)+"_user.key"
- # voter_userkey = nillion.UserKey.from_file(voter_userkey_path)
- # voter = nillion.NillionClient(
- # voter_nodekey,
- # bootnodes,
- # nillion.ConnectionMode.relay(),
- # voter_userkey,
- # payments_config=payments_config
- # )
- # voters.append(voter)
-
-
- #####################################
- # 2. Storing program #
- #####################################
-
- # Note: do not forget to compile the programs and store the corresponding .nada.bin file.
- program_mir_path = f"../../programs-compiled/{program_name}.nada.bin"
- if os.path.exists(program_mir_path):
- None
- else:
- raise FileNotFoundError(f"The file '{program_mir_path}' does not exist.\nMake sure you compiled the PyNada programs with './compile_programs.sh'.\nCheck README.md for more details.")
-
- # Store program in the Network
- print(f"Storing program in the network: {program_name}")
- # action_id = await owner.store_program(
- action_id = await general_client.store_program(
- cluster_id, program_name, program_mir_path
- )
- print("action_id is: ", action_id)
- # program_id = owner.user_id + "/" + program_name
- program_id = general_client.user_id + "/" + program_name
- print("program_id is: ", program_id)
-
- #####################################
- # 3. Send program ID #
- #####################################
-
- # This requires its own mechanism in a real environment.
- # In this demo, we just reuse the variable 'program_id'.
-
- #####################################
- # 4. Storing votes #
- #####################################
-
- # Each voter stores its vote. In this demo, we assume each voter has a file
- # containing their votes for each candidate. E.g. voter 0 has a file 'inputs/v0_input.txt'
- # with the following format:
- # ==============
- # 1
- # 2
- # ==============
- # This means, voter 0 assigns 1 to candidate 0 and 2 to candidate 1.
-
- # Voters store the secrets
- store_ids = []
- for v in range(nr_voters):
- voter_v = general_client
- # voter_v = voters[v]
- print("voter_v: ", voter_v)
- # structure v's votes
- v_vote_dic = {}
- v_input_file = "inputs/v"+str(v)+"_input.txt"
- with open(v_input_file, 'r') as file:
- c = 0
- for line in file:
- # Remove leading and trailing whitespaces, then convert to integer
- v_c_vote_value = int(line.strip())
- v_c_vote = nillion.SecretUnsignedInteger(v_c_vote_value)
- v_vote_dic["v"+str(v)+"_c"+str(c)] = v_c_vote
- c += 1
- v_to_be_store_secrets = nillion.Secrets(v_vote_dic)
-
- ###########################################
- # 4.1 Bind voter to party in the program #
- ###########################################
- v_bindings = nillion.ProgramBindings(program_id)
- v_bindings.add_input_party("Voter"+str(v), voter_v.party_id)
-
- ###########################################
- # 4.2 Set compute permissions to owner #
- ###########################################
- # Give permissions to owner to compute with my vote
- v_permissions = nillion.Permissions.default_for_user(voter_v.user_id)
- v_permissions.add_compute_permissions({
- # owner.user_id: {program_id},
- general_client.user_id: {program_id},
- })
-
- # Store in the network
- print("Storing vote by voter "+str(v)+f": {v_to_be_store_secrets}")
- store_id = await voter_v.store_secrets(
- cluster_id, v_bindings, v_to_be_store_secrets, v_permissions
- )
- store_ids.append(store_id)
- print(f"Stored vote by voter "+str(v)+f" with store_id ={store_id}")
-
- #####################################
- # 5. Send party IDs and store IDs #
- #####################################
-
- # This requires its own mechanism in a real environment.
- # In this demo, we just reuse the variable 'store_ids' and
- # the voters' clients to extra their party IDs.
-
- #####################################
- # 6. Owner execute computation #
- #####################################
-
- #################################################
- # 6.1 Bind voter to input party in the program #
- #################################################
- owner_bindings = nillion.ProgramBindings(program_id)
- for v in range(nr_voters):
- # owner_bindings_0.add_input_party("Voter"+str(v), voters[v].party_id)
- owner_bindings.add_input_party("Voter"+str(v), general_client.party_id)
-
- ##################################################
- # 6.2 Bind owner to output party in the program #
- ##################################################
- # Bind the "OutParty" party in the computation to the owner's client
- # owner_bindings.add_output_party("OutParty", owner.party_id)
- owner_bindings.add_output_party("OutParty", general_client.party_id)
-
- # No secret is directly passed to 'compute'. It only uses
- # stored secrets.
- to_be_used_in_computation = nillion.Secrets({})
-
- print(f"Computing using program {program_id}")
- print(f"Stored secrets: {store_ids}")
- print(f"Provided secret: {to_be_used_in_computation}")
-
- # Owner can execute the computation
- # compute_id = await owner.compute(
- compute_id = await general_client.compute(
- cluster_id,
- owner_bindings,
- store_ids,
- to_be_used_in_computation,
- nillion.PublicVariables({}),
- )
-
- print(f"Computation sent to the network, compute_id = {compute_id}")
- print("Waiting computation response...")
- while True:
- compute_event = await general_client.next_compute_event()
- if isinstance(compute_event, nillion.ComputeFinishedEvent):
- print(f"✅ Compute complete for compute_id {compute_event.uuid}")
- dict_result = compute_event.result.value
- print(f"🖥️ The result is: {dict_result}\n")
-
- if program_name == "voting_dishonest_robust_6":
- print("Let use digest the result given by the network:")
- winner, total_votes, cheaters = digest_plurality_vote_robust_result(dict_result, nr_candidates, nr_voters)
- print(f"🏆 Winner is candidate with ID={winner}")
- print(f"🔢 Total number of votes per candidate: {total_votes}")
- print(f"🕵️♂️ List of cheaters' IDs: {cheaters}")
- elif program_name in ["voting_honest_1", "voting_honest_2"]:
- digest_plurality_vote_honest_result(dict_result, nr_candidates, nr_voters)
- elif program_name == "voting_dishonest_abort_5":
- digest_plurality_vote_dishonest_with_abort_result(dict_result, nr_candidates, nr_voters)
-
- break
-
-
-
-asyncio.run(main())
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/config.py b/examples_and_tutorials/voting_tutorial/config.py
deleted file mode 100644
index e6cb7386..00000000
--- a/examples_and_tutorials/voting_tutorial/config.py
+++ /dev/null
@@ -1,50 +0,0 @@
-import os
-from dotenv import load_dotenv
-load_dotenv()
-
-CONFIG = {
- "nr_candidates": 2,
- "nr_voters": 3,
-}
-
-CONFIG_CANDIDATES=[
- "Dave",
- "Emma"
-]
-
-
-# Alice
-CONFIG_PARTY_1={
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_1"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_1"),
- "party_name": "Alice",
- "party_role": "Voter0",
- "secret_votes": {
- "v0_c0": 1,
- "v0_c1": 2,
- },
-}
-
-# Bob and Charlie
-CONFIG_N_PARTIES=[
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_2"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_2"),
- "party_name": "Bob",
- "party_role": "Voter1",
- "secret_votes": {
- "v1_c0": 1,
- "v1_c1": 2,
- },
- },
- {
- "userkey_file": os.getenv("NILLION_USERKEY_PATH_PARTY_3"),
- "nodekey_file": os.getenv("NILLION_NODEKEY_PATH_PARTY_3"),
- "party_name": "Charlie",
- "party_role": "Voter2",
- "secret_votes": {
- "v2_c0": 2,
- "v2_c1": 1,
- },
- },
-]
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/digest_result.py b/examples_and_tutorials/voting_tutorial/digest_result.py
deleted file mode 100644
index 8f85cadb..00000000
--- a/examples_and_tutorials/voting_tutorial/digest_result.py
+++ /dev/null
@@ -1,70 +0,0 @@
-def digest_plurality_vote_honest_result(dict_result, nr_candidates, nr_voters):
-
- # TODO: complete there the code to digest the output of the honest version
-
- print("Update 'digest_plurality_vote_honest_result()' functions to digest the result.")
-
- return None
-
-
-def digest_plurality_vote_dishonest_with_abort_result(dict_result, nr_candidates, nr_voters):
-
- # TODO: complete there the code to digest the output of the dishonest with abort version
-
- print("Update 'digest_plurality_vote_dishonest_with_abort_result()' functions to digest the result.")
-
- return None
-
-
-def digest_plurality_vote_robust_result(dict_result, nr_candidates, nr_voters):
- """
- Digests the robust result of a plurality voting process, identifying the winner,
- the votes per candidate, and any potential cheaters.
-
- Parameters:
- - dict_result (dict): A dictionary containing the robust result of the plurality
- voting process. It should contain keys for final vote counts
- for each candidate, checks for sum and product rules per voter,
- and actions if cheating is detected.
- - nr_candidates (int): The total number of candidates in the voting process.
- - nr_voters (int): The total number of voters in the voting process.
-
- Returns:
- - winner (int): The index of the winning candidate.
- - votes_per_candidate (list): A list containing the number of votes received by
- each candidate.
- - cheaters (list): A list containing the IDs of any potential cheaters.
- """
-
- # check cheaters
- set_of_cheaters = set()
- for v in range(nr_voters):
- if dict_result["check_sum_v"+str(v)] != nr_candidates + 1:
- # add the voter id to set_of_cheaters
- set_of_cheaters.add(v)
- for c in range(nr_candidates):
- if dict_result["check_prod_v"+str(v)+"_c"+str(c)] != 0:
- # add the voter id to set_of_cheaters
- set_of_cheaters.add(v)
-
- # collect final votes
- votes_per_candidate = []
- for c in range(nr_candidates):
- # read nr of votes for candidate 'c'
- votes_per_candidate.append(dict_result["final_vote_count_c"+str(c)])
- # revert action of cheaters for all candidates
- for cheater in set_of_cheaters:
- # if sum rule was broken
- if dict_result["check_sum_v"+str(cheater)] != nr_candidates + 1:
- for c in range(nr_candidates):
- votes_per_candidate[c] -= dict_result["if_sum_cheat_open_v"+str(cheater)+"_c"+str(c)]
- # if product rule was broken
- else:
- for c in range(nr_candidates):
- votes_per_candidate[c] -= dict_result["if_prod_cheat_open_v"+str(cheater)+"_c"+str(c)]
-
- # define winner
- winner = max(range(len(votes_per_candidate)), key=lambda i: votes_per_candidate[i])
-
- return winner, votes_per_candidate, list(set_of_cheaters)
-
diff --git a/examples_and_tutorials/voting_tutorial/image/architecture.png b/examples_and_tutorials/voting_tutorial/image/architecture.png
deleted file mode 100644
index 033dd5c6..00000000
Binary files a/examples_and_tutorials/voting_tutorial/image/architecture.png and /dev/null differ
diff --git a/examples_and_tutorials/voting_tutorial/inputs/v0_input.txt b/examples_and_tutorials/voting_tutorial/inputs/v0_input.txt
deleted file mode 100644
index 7a754f41..00000000
--- a/examples_and_tutorials/voting_tutorial/inputs/v0_input.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-2
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/inputs/v1_input.txt b/examples_and_tutorials/voting_tutorial/inputs/v1_input.txt
deleted file mode 100644
index 7a754f41..00000000
--- a/examples_and_tutorials/voting_tutorial/inputs/v1_input.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-1
-2
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/inputs/v2_input.txt b/examples_and_tutorials/voting_tutorial/inputs/v2_input.txt
deleted file mode 100644
index 6bf8d174..00000000
--- a/examples_and_tutorials/voting_tutorial/inputs/v2_input.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-2
-1
\ No newline at end of file
diff --git a/examples_and_tutorials/voting_tutorial/tutorial.md b/examples_and_tutorials/voting_tutorial/tutorial.md
deleted file mode 100644
index 0fd3674b..00000000
--- a/examples_and_tutorials/voting_tutorial/tutorial.md
+++ /dev/null
@@ -1,909 +0,0 @@
-# Voting tutorial
-
-## Introduction
-
-This tutorial provides a generic template for creating several voting systems in `PyNada`. We will explore five types of voting systems: Plurality, Range, Veto, Approval and Borda. For a more detailed exposition on the voting systems, we can refer to [[DTY21]](https://www.sciencedirect.com/science/article/abs/pii/S0957417420310964). The tutorial is specifically focused on PyNada programs for these voting systems. If you want to run the voting programs in `nillion-devnet`, check the [README](README.md) file.
-
-Let us consider the following voting scenario: three voters and two potential candidates. Voters transmit their votes to the Nillion Network in a secret-shared form, which processes the votes for each candidate without having access to their underlying values. The result of the computation is then transmitted to the owner of the voting system, who is able to reconstruct the result and read the winner.
-
-
- Architecture example.
-