Nada Numpy Dot Product Tutorial
In this tutorial, we’ll explore the capabilities of Nada Numpy together. Before we start, make sure you have the Nillion SDK installed.
To get started, we can initialize our project structure with the following command:
nada init nada-dot-product
This sets up everything we need. Now, let’s dive into the code! We’ll create a program that computes the dot product of two arrays. Here’s the complete code to put in src/main.py
:
from nada_dsl import *
# Step 0: Nada Numpy is imported with this line
import nada_numpy as na
def nada_main():
# Step 1: We use Nada Numpy wrapper to create "Party0", "Party1" and "Party2"
parties = na.parties(3)
# Step 2: Party0 creates an array of dimension (3, ) with name "A"
a = na.array([3], parties[0], "A", SecretInteger)
# Step 3: Party1 creates an array of dimension (3, ) with name "B"
b = na.array([3], parties[1], "B", SecretInteger)
# Step 4: The result is of computing the dot product between the two
result = a.dot(b)
# Step 5: We can use result.output() to produce the output for Party2 and variable name "my_output"
return na.output(result, parties[1], "my_output")
Let’s break this down step-by-step.
1. Import Section
Start by importing the necessary modules. We need Nada DSL and Nada Numpy, so we import them like this:
from nada_dsl import Output, SecretInteger
import nada_numpy as na
Next, define the main function for our program:
def nada_main():
2. Party Declaration Section
In this section, we’ll declare the parties involved in our computation. Parties represent the different participants in our Nada program. Nada Numpy makes it easy to create multiple parties with the na.parties
function:
parties = na.parties(3)
This line creates a list of three parties named: Party0
, Party1
, and Party2
.
3. Input Declaration Section
Now, let’s define our inputs. We’ll create two NadaArrays
, each with three elements. The na.array
function allows us to define an array with arbitrary dimensions and types.
a = na.array([3], parties[0], "A", SecretInteger)
This line creates an array a
with 3 elements, owned by Party0
, named “A”
, and of type SecretInteger
.
Similarly, we define the second array b
:
b = na.array([3], parties[1], "B", SecretInteger)
This array is also 3 elements long, owned by Party1
, named “B”
, and of type SecretInteger
.
Under the hood, NadaArray creates variables for each element of the array. For example, a
will have variables "A_0"
, "A_1"
, and "A_2"
, while b
will have "B_0"
, "B_1"
, and "B_2"
.
4. Computation Section
With our inputs ready, we can perform computations. Calculating the dot product of the two arrays is straightforward. In the Numpy fashion, we use the dot
method:
result = a.dot(b)
This line computes the dot product of arrays a
and b
. If our input arrays were a = [1, 2, 3]
and b = [4, 5, 6]
, the dot product would be computed as 1*4 + 2*5 + 3*6 = 32
.