diff --git a/nohup.out b/nohup.out new file mode 100644 index 00000000..7dffe386 --- /dev/null +++ b/nohup.out @@ -0,0 +1,28 @@ +ℹ️ cluster id is 9e68173f-9c23-4acc-ba81-4f079b639964 +ℹ️ using 256 bit prime +ℹ️ storing state in /tmp/.tmp1xYehT (79.99Gbs available) +🏃 starting nilchain node in: /tmp/.tmp1xYehT/nillion-chain +⛓ nilchain JSON RPC available at http://127.0.0.1:48102 +⛓ nilchain REST API available at http://localhost:26650 +⛓ nilchain gRPC available at localhost:26649 +🏃 starting node 12D3KooWMvw1hEqm7EWSDEyqTb6pNetUVkepahKY6hixuAuMZfJS +⏳ waiting until bootnode is up... +🏃 starting node 12D3KooWAiwGZUwSUaT2bYVxGS8jmfMrfsanZYkHwH3uL7WJPsFq +🏃 starting node 12D3KooWM3hsAswc7ZT6VpwQ1TCZU4GCYY55nLhcsxCcfjuixW57 +👛 funding nilchain keys +📝 nillion CLI configuration written to /root/.config/nillion/nillion-cli.yaml +🌄 environment file written to /root/.config/nillion/nillion-devnet.env +ℹ️ cluster id is 9e68173f-9c23-4acc-ba81-4f079b639964 +ℹ️ using 256 bit prime +ℹ️ storing state in /tmp/.tmpgsHTsP (79.99Gbs available) +🏃 starting nilchain node in: /tmp/.tmpgsHTsP/nillion-chain +⛓ nilchain JSON RPC available at http://127.0.0.1:48102 +⛓ nilchain REST API available at http://localhost:26650 +⛓ nilchain gRPC available at localhost:26649 +🏃 starting node 12D3KooWMvw1hEqm7EWSDEyqTb6pNetUVkepahKY6hixuAuMZfJS +⏳ waiting until bootnode is up... +🏃 starting node 12D3KooWAiwGZUwSUaT2bYVxGS8jmfMrfsanZYkHwH3uL7WJPsFq +🏃 starting node 12D3KooWM3hsAswc7ZT6VpwQ1TCZU4GCYY55nLhcsxCcfjuixW57 +👛 funding nilchain keys +📝 nillion CLI configuration written to /root/.config/nillion/nillion-cli.yaml +🌄 environment file written to /root/.config/nillion/nillion-devnet.env diff --git a/quickstart/client_code/=0.9.2 b/quickstart/client_code/=0.9.2 new file mode 100644 index 00000000..972a8252 --- /dev/null +++ b/quickstart/client_code/=0.9.2 @@ -0,0 +1,19 @@ +Requirement already satisfied: cosmpy in /usr/local/lib/python3.10/dist-packages (0.9.2) +Requirement already satisfied: bech32 in /usr/local/lib/python3.10/dist-packages (from cosmpy) (1.2.0) +Requirement already satisfied: ecdsa in /usr/local/lib/python3.10/dist-packages (from cosmpy) (0.19.0) +Requirement already satisfied: googleapis-common-protos in /usr/local/lib/python3.10/dist-packages (from cosmpy) (1.63.2) +Requirement already satisfied: grpcio in /usr/local/lib/python3.10/dist-packages (from cosmpy) (1.64.1) +Requirement already satisfied: jsonschema<5,>=3.2.0 in /usr/local/lib/python3.10/dist-packages (from cosmpy) (4.19.2) +Requirement already satisfied: protobuf<5.0dev,>=4.21.6 in /usr/local/lib/python3.10/dist-packages (from cosmpy) (4.25.3) +Requirement already satisfied: pycryptodome<4.0.0,>=3.18.0 in /usr/local/lib/python3.10/dist-packages (from cosmpy) (3.20.0) +Requirement already satisfied: python-dateutil in /usr/local/lib/python3.10/dist-packages (from cosmpy) (2.8.2) +Requirement already satisfied: requests in /usr/local/lib/python3.10/dist-packages (from cosmpy) (2.31.0) +Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5,>=3.2.0->cosmpy) (23.2.0) +Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5,>=3.2.0->cosmpy) (2023.12.1) +Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5,>=3.2.0->cosmpy) (0.35.1) +Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.10/dist-packages (from jsonschema<5,>=3.2.0->cosmpy) (0.18.1) +Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.10/dist-packages (from ecdsa->cosmpy) (1.16.0) +Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests->cosmpy) (3.3.2) +Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests->cosmpy) (3.7) +Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests->cosmpy) (2.0.7) +Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests->cosmpy) (2024.6.2) diff --git a/quickstart/client_code/nillion-python-starter b/quickstart/client_code/nillion-python-starter new file mode 160000 index 00000000..15e9fe0b --- /dev/null +++ b/quickstart/client_code/nillion-python-starter @@ -0,0 +1 @@ +Subproject commit 15e9fe0b43b980670bf1a97f703a8d2f25ca1afc diff --git a/quickstart/client_code/run_my_first_program.py b/quickstart/client_code/run_my_first_program.py index e69de29b..71f2bd9c 100644 --- a/quickstart/client_code/run_my_first_program.py +++ b/quickstart/client_code/run_my_first_program.py @@ -0,0 +1,113 @@ +from nada_dsl import * + +def initialize_managers(nr_managers): + """ + Initialize managers with unique identifiers. + + Parameters: + - nr_managers (int): Number of managers. + + Returns: + - managers (list): List of Party objects representing managers. + """ + managers = [] + for i in range(nr_managers): + managers.append(Party(name="Manager" + str(i))) + + return managers + +def inputs_initialization(nr_managers, nr_employees, managers): + """ + Initialize inputs for performance scores per employee. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + + Returns: + - scores_per_employee (list): List of lists representing scores per employee. + """ + scores_per_employee = [] + for e in range(nr_employees): + scores_per_employee.append([]) + for m in range(nr_managers): + scores_per_employee[e].append( + SecretUnsignedInteger( + Input(name="m" + str(m) + "_e" + str(e), party=managers[m]) + ) + ) + + return scores_per_employee + +def compute_average_scores(nr_managers, nr_employees, scores_per_employee, outparty): + """ + Compute the average scores for each employee. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + - scores_per_employee (list): List of lists representing scores per employee. + + Returns: + - avg_scores (list): List of Output objects representing average scores for each employee. + """ + avg_scores = [] + for e in range(nr_employees): + total_score = scores_per_employee[e][0] + for m in range(1, nr_managers): + total_score += scores_per_employee[e][m] + average_score = total_score / UnsignedInteger(nr_managers) + avg_scores.append(Output(average_score, "avg_score_e" + str(e), outparty)) + + return avg_scores + +def verify_scores(nr_managers, nr_employees, scores_per_employee, max_score, outparty): + """ + Check if any score exceeds the allowed maximum score. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + - scores_per_employee (list): List of lists representing scores per employee. + + Returns: + - score_checks (list): List of Output objects representing score checks for each employee. + - if_cheat_open (list): List of Output objects representing revealed scores of cheating managers. + """ + score_checks = [] + if_cheat_open = [] + for e in range(nr_employees): + for m in range(nr_managers): + score = scores_per_employee[e][m] + check = score <= UnsignedInteger(max_score) + score_checks.append(Output(check, "check_score_m" + str(m) + "_e" + str(e), outparty)) + reveal_cheat = check.if_else(UnsignedInteger(0), score) + if_cheat_open.append(Output(reveal_cheat, "if_cheat_open_m" + str(m) + "_e" + str(e), outparty)) + + return score_checks, if_cheat_open + +def nada_main(): + # Compiled-time constants + nr_managers = 3 + nr_employees = 2 + max_score = 10 # Example maximum score allowed + + # Parties initialization + managers = initialize_managers(nr_managers) + outparty = Party(name="OutParty") + + # Inputs initialization + scores_per_employee = inputs_initialization(nr_managers, nr_employees, managers) + + # Computation + # Compute average scores + avg_scores = compute_average_scores(nr_managers, nr_employees, scores_per_employee, outparty) + # Check score validity + score_checks, if_cheat_open = verify_scores(nr_managers, nr_employees, scores_per_employee, max_score, outparty) + + # Output + results = avg_scores + score_checks + if_cheat_open + return results + +# Run the main function +nada_main() diff --git a/quickstart/nada_quickstart_programs/nada-project.toml b/quickstart/nada_quickstart_programs/nada-project.toml new file mode 100644 index 00000000..da166dde --- /dev/null +++ b/quickstart/nada_quickstart_programs/nada-project.toml @@ -0,0 +1,7 @@ +name = "nada_quickstart_programs" +version = "0.1.0" +authors = [""] + +[[programs]] +path = "src/main.py" +prime_size = 128 diff --git a/quickstart/nada_quickstart_programs/src/main.py b/quickstart/nada_quickstart_programs/src/main.py new file mode 100644 index 00000000..d9773a92 --- /dev/null +++ b/quickstart/nada_quickstart_programs/src/main.py @@ -0,0 +1,113 @@ +from nada_dsl import * + +def initialize_managers(nr_managers): + """ + Initialize managers with unique identifiers. + + Parameters: + - nr_managers (int): Number of managers. + + Returns: + - managers (list): List of Party objects representing managers. + """ + managers = [] + for i in range(nr_managers): + managers.append(Party(name="Manager" + str(i))) + + return managers + +def inputs_initialization(nr_managers, nr_employees, managers): + """ + Initialize inputs for performance scores per employee. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + + Returns: + - scores_per_employee (list): List of lists representing scores per employee. + """ + scores_per_employee = [] + for e in range(nr_employees): + scores_per_employee.append([]) + for m in range(nr_managers): + scores_per_employee[e].append( + SecretUnsignedInteger( + Input(name="m" + str(m) + "_e" + str(e), party=managers[m]) + ) + ) + + return scores_per_employee + +def compute_average_scores(nr_managers, nr_employees, scores_per_employee, outparty): + """ + Compute the average scores for each employee. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + - scores_per_employee (list): List of lists representing scores per employee. + + Returns: + - avg_scores (list): List of Output objects representing average scores for each employee. + """ + avg_scores = [] + for e in range(nr_employees): + total_score = scores_per_employee[e][0] + for m in range(1, nr_managers): + total_score += scores_per_employee[e][m] + average_score = total_score / UnsignedInteger(nr_managers) + avg_scores.append(Output(average_score, "avg_score_e" + str(e), outparty)) + + return avg_scores + +def verify_scores(nr_managers, nr_employees, scores_per_employee, max_score, outparty): + """ + Check if any score exceeds the allowed maximum score. + + Parameters: + - nr_managers (int): Number of managers. + - nr_employees (int): Number of employees. + - scores_per_employee (list): List of lists representing scores per employee. + + Returns: + - score_checks (list): List of Output objects representing score checks for each employee. + - if_cheat_open (list): List of Output objects representing revealed scores of cheating managers. + """ + score_checks = [] + if_cheat_open = [] + for e in range(nr_employees): + for m in range(nr_managers): + score = scores_per_employee[e][m] + check = score <= UnsignedInteger(max_score) + score_checks.append(Output(check, "check_score_m" + str(m) + "_e" + str(e), outparty)) + reveal_cheat = check.if_else(UnsignedInteger(0), score) + if_cheat_open.append(Output(reveal_cheat, "if_cheat_open_m" + str(m) + "_e" + str(e), outparty)) + + return score_checks, if_cheat_open + +def nada_main(): + # Compiled-time constants + nr_managers = 3 + nr_employees = 2 + max_score = 10 # Example maximum score allowed + + # Parties initialization + managers = initialize_managers(nr_managers) + outparty = Party(name="OutParty") + + # Inputs initialization + scores_per_employee = inputs_initialization(nr_managers, nr_employees, managers) + + # Computation + # Compute average scores + avg_scores = compute_average_scores(nr_managers, nr_employees, scores_per_employee, outparty) + # Check score validity + score_checks, if_cheat_open = verify_scores(nr_managers, nr_employees, scores_per_employee, max_score, outparty) + + # Output + results = avg_scores + score_checks + if_cheat_open + return results + +# Run the main function +nada_main() diff --git a/quickstart/nada_quickstart_programs/target/main.nada.bin b/quickstart/nada_quickstart_programs/target/main.nada.bin new file mode 100644 index 00000000..f48474c7 Binary files /dev/null and b/quickstart/nada_quickstart_programs/target/main.nada.bin differ diff --git a/quickstart_complete/nada_quickstart_programs/src/main.py b/quickstart_complete/nada_quickstart_programs/src/main.py new file mode 100644 index 00000000..67161479 --- /dev/null +++ b/quickstart_complete/nada_quickstart_programs/src/main.py @@ -0,0 +1,30 @@ +from nada_dsl import * +from math import gcd + +def nada_main(): + party1 = Party(name="Party1") + + my_int1 = SecretInteger(Input(name="my_int1", party=party1)) + my_int2 = SecretInteger(Input(name="my_int2", party=party1)) + + sum_int = my_int1 + my_int2 + + difference_int = my_int1 - my_int2 + + product_int = my_int1 * my_int2 + + quotient_int = my_int1 // my_int2 + + gcd_int = gcd(my_int1, my_int2) + + is_multiple = (my_int1 % my_int2) == 0 + multiple_message = is_multiple.if_else("Yes", "No") + + return [ + Output(sum_int, "sum_output", party=party1), + Output(difference_int, "difference_output", party=party1), + Output(product_int, "product_output", party=party1), + Output(quotient_int, "quotient_output", party=party1), + Output(gcd_int, "gcd_output", party=party1), + Output(multiple_message, "multiple_output", party=party1) + ] diff --git a/quickstart_complete/nada_quickstart_programs/src/secret_addition_complete.py b/quickstart_complete/nada_quickstart_programs/src/secret_addition_complete.py index be9daa13..1f335a6b 100644 --- a/quickstart_complete/nada_quickstart_programs/src/secret_addition_complete.py +++ b/quickstart_complete/nada_quickstart_programs/src/secret_addition_complete.py @@ -1,12 +1,11 @@ from nada_dsl import * -def nada_main(): - party1 = Party(name="Party1") +def nada_main(): + party1 = Party(name="Party1") my_int1 = SecretInteger(Input(name="my_int1", party=party1)) + my_int3 = PublicInteger(Input(name="my_int3", party=party1)) - my_int2 = SecretInteger(Input(name="my_int2", party=party1)) - - new_int = my_int1 + my_int2 + new_int = my_int1 / my_int3 return [Output(new_int, "my_output", party1)] \ No newline at end of file diff --git a/quickstart_complete/nada_quickstart_programs/target/secret_addition_complete.nada.bin b/quickstart_complete/nada_quickstart_programs/target/secret_addition_complete.nada.bin index 4351b211..75e0b6c3 100644 Binary files a/quickstart_complete/nada_quickstart_programs/target/secret_addition_complete.nada.bin and b/quickstart_complete/nada_quickstart_programs/target/secret_addition_complete.nada.bin differ