Skip to content

Commit f3c98b1

Browse files
authored
fix: fixing testing infrastructure fail (#74)
* fix: fixing testing infrastructure fail including tests * feat: working matrix inverse example (not integrated)
1 parent e0a8dce commit f3c98b1

27 files changed

+228
-190
lines changed

examples/linear_regression/nada-project.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ name = "linear-regression"
22
version = "0.1.0"
33
authors = [""]
44

5+
[test_framework.nada-test]
6+
command = "nada-test ./tests"
7+
58
[[programs]]
69
path = "src/linear_regression.py"
710
prime_size = 64

examples/linear_regression/src/determinant.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def nada_main():
3838
parties = na.parties(3)
3939

4040
X = na.array([3, 3], parties[0], "A", SecretInteger)
41-
X = X.reveal()
41+
X = X.to_public()
4242
detX = determinant(X)
4343

4444
return na.output(detX, parties[2], "my_output")

examples/linear_regression/src/gauss_jordan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ def nada_main():
5151

5252
A = na.array([3, 3], parties[0], "A", nada_type=SecretInteger)
5353

54-
A = A.reveal()
54+
A = A.to_public()
5555
A_inv = gauss_jordan_zn(A, PRIME)
5656
outputs = na.output(A_inv, parties[2], "my_output")
5757

examples/linear_regression/src/linear_regression.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def linsol(A: NadaArray, b: NadaArray, modulo: int):
9191
) # (n, n) random matrix R with inverse determinant detR_inv
9292

9393
# Revealing matrix RA
94-
RA = (R @ A).reveal() # (n, n) revealed matrix
94+
RA = (R @ A).to_public() # (n, n) revealed matrix
9595

9696
# Computing Rb as a secret matrix multiplication of R and b
9797
Rb = R @ b # (n, n) @ (n,) = (n,)

examples/linear_regression/src/linear_regression_256.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def private_modular_inverse(secret: SecretInteger, modulo: int) -> SecretInteger
5656
r = SecretInteger.random()
5757

5858
ra = r * secret # Masking our secret
59-
ra_revealed = ra.reveal() # Revealing the masked secret
59+
ra_revealed = ra.to_public() # Revealing the masked secret
6060

6161
ra_inv = public_modular_inverse(
6262
ra_revealed, modulo
@@ -144,7 +144,7 @@ def matrix_inverse(matrix: np.ndarray, modulo: int):
144144
n = matrix.shape[0]
145145
R, detR = random_lu_matrix(n) # n by n random matrix R with determinant detR
146146
# Revealing matrix RA
147-
RA = (R @ matrix).reveal()
147+
RA = (R @ matrix).to_public()
148148
# # Concatenating RA and R
149149
RAR = RA.hstack(R)
150150
# Performing Gauss-Jordan elimination
@@ -241,7 +241,7 @@ def linsol(A: NadaArray, b: NadaArray, modulo: int):
241241
) # (n, n) random matrix R with inverse determinant detR_inv
242242

243243
# Revealing matrix RA
244-
RA = (R @ A).reveal() # (n, n) revealed matrix
244+
RA = (R @ A).to_public() # (n, n) revealed matrix
245245

246246
# Computing Rb as a secret matrix multiplication of R and b
247247
Rb = R @ b # (n, n) @ (n,) = (n,)

examples/linear_regression/src/matrix_inverse.py

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ def public_modular_inverse(
4040
power = value ** Integer(
4141
mod - 1
4242
) # value ** modulo = value ** (modulo // 2) * modulo ** (modulo // 2)
43-
power = power * power * value if rem else Integer(1) # value ** mo
43+
power = power * power * (value if rem else Integer(1)) # value ** mo
4444
return power
4545

4646

@@ -133,14 +133,7 @@ def gauss_jordan_zn(mat: na.NadaArray, modulo: int):
133133

134134
# Forward elimination
135135
for i in range(rows):
136-
# # Find pivot row
137-
# pivot_row = i
138-
# while pivot_row < rows and (mat[pivot_row][i] == Integer(0)) is Boolean(True):
139-
# pivot_row += 1
140-
141-
# # Swap pivot row with current row
142-
# mat[[i, pivot_row]] = mat[[pivot_row, i]]
143-
136+
144137
# Scale pivot row to have leading 1
145138
diagonal_element = mat[i][i]
146139
pivot_inv = public_modular_inverse(diagonal_element, modulo)
@@ -168,7 +161,7 @@ def matrix_inverse(matrix: np.ndarray, modulo: int):
168161
R, detR = random_lu_matrix(n) # n by n random matrix R with determinant detR
169162

170163
# Revealing matrix RA
171-
RA = (R @ matrix).reveal()
164+
RA = (R @ matrix).to_public()
172165
# # Concatenating RA and R
173166
RAR = RA.hstack(R)
174167
# Performing Gauss-Jordan elimination
@@ -186,7 +179,7 @@ def matrix_inverse(matrix: np.ndarray, modulo: int):
186179
def nada_main():
187180
parties = na.parties(3)
188181

189-
A = na.array([4, 4], parties[0], "A", nada_type=SecretInteger)
182+
A = na.array([10, 10], parties[0], "A", nada_type=SecretInteger)
190183
A_inv = matrix_inverse(A, PRIME)
191184

192185
result = A @ A_inv

examples/linear_regression/src/modular_inverse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def private_modular_inverse(secret: SecretInteger, modulo: int) -> SecretInteger
5555
r = SecretInteger.random()
5656

5757
ra = r * secret # Masking our secret
58-
ra_revealed = ra.reveal() # Revealing the masked secret
58+
ra_revealed = ra.to_public() # Revealing the masked secret
5959

6060
ra_inv = public_modular_inverse(
6161
ra_revealed, modulo
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from nada_test import nada_test, NadaTest
2+
import sys
3+
import nada_numpy.client as na
4+
import numpy as np
5+
6+
# Functional style test
7+
@nada_test(program="matrix_inverse")
8+
def my_test():
9+
n = 10
10+
m = np.random.rand(n, n)
11+
mx = np.sum(np.abs(m), axis=1)
12+
np.fill_diagonal(m, mx)
13+
A = na.array(m * (1 << 16), "A", nada_type=int)
14+
print("INPUTS:", A, file=sys.stderr)
15+
outputs = yield A
16+
print(outputs, file=sys.stderr)
17+
for output, value in outputs.items():
18+
output = output.split("_")
19+
if output[-1] == output[-2]:
20+
assert value == 1, f"Expected 1 {output}, got {value}"
21+
else:
22+
assert value == 0, f"Expected 0 {output}, got {value}"
23+
24+
#assert outputs["my_output"] == a + b

examples/linear_regression/tests/matrix_inverse.yaml

Lines changed: 0 additions & 62 deletions
This file was deleted.

nada_numpy/array.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -550,14 +550,14 @@ def vstack(self, other: "NadaArray") -> "NadaArray":
550550
"""
551551
return NadaArray(np.vstack((self.inner, other.inner)))
552552

553-
def reveal(self) -> "NadaArray":
553+
def to_public(self) -> "NadaArray":
554554
"""
555-
Reveal the elements of the array.
555+
Reveal the elements of the array and make them public
556556
557557
Returns:
558558
NadaArray: A new NadaArray with revealed values.
559559
"""
560-
return self.apply(lambda x: x.reveal())
560+
return self.apply(lambda x: x.to_public())
561561

562562
def apply(self, func: Callable[[Any], Any]) -> "NadaArray":
563563
"""
@@ -1516,7 +1516,7 @@ def log(x):
15161516
f"Log is not compatible with {dtype}, only with Rational and SecretRational types."
15171517
)
15181518

1519-
def reciprocal( # pylint: disable=too-many-arguments
1519+
def reciprocal( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
15201520
self,
15211521
all_pos: bool = False,
15221522
initial: Optional["Rational"] = None,

nada_numpy/client.py

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -61,36 +61,13 @@ def array(
6161
Dict: A dictionary mapping generated names to Nillion input objects.
6262
"""
6363
# TODO: Use this version when check for zero values is removed
64-
# if len(arr.shape) == 1:
65-
# if nada_type == Rational:
66-
# nada_type = public_rational # type: ignore
67-
# elif nada_type == SecretRational:
68-
# nada_type = secret_rational # type: ignore
69-
# return {
70-
# f"{prefix}_{i}": (nada_type(int(arr[i]))) for i in range(arr.shape[0]) # type: ignore
71-
# }
72-
73-
# TODO: remove check for zero values when pushing zero secrets is supported
74-
7564
if len(arr.shape) == 1:
7665
if nada_type == Rational:
77-
return {
78-
f"{prefix}_{i}": (public_rational(arr[i])) for i in range(arr.shape[0])
79-
}
80-
if nada_type == SecretRational:
81-
return {
82-
f"{prefix}_{i}": (
83-
secret_rational(arr[i]) if arr[i] != 0 else SecretInteger(1)
84-
)
85-
for i in range(arr.shape[0])
86-
}
66+
nada_type = public_rational # type: ignore
67+
elif nada_type == SecretRational:
68+
nada_type = secret_rational # type: ignore
8769
return {
88-
f"{prefix}_{i}": (
89-
nada_type(int(arr[i])) # type: ignore
90-
if (nada_type in (Integer, UnsignedInteger) or int(arr[i]) != 0)
91-
else nada_type(1) # type: ignore
92-
)
93-
for i in range(arr.shape[0])
70+
f"{prefix}_{i}": (nada_type(int(arr[i]))) for i in range(arr.shape[0]) # type: ignore
9471
}
9572
return {
9673
k: v

nada_numpy/funcs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ def log(
730730
)
731731

732732

733-
def reciprocal( # pylint: disable=too-many-arguments
733+
def reciprocal( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
734734
arr: NadaArray,
735735
all_pos: bool = False,
736736
initial: Optional["Rational"] = None,

nada_numpy/types.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
]
2525

2626

27-
class SecretBoolean(dsl.SecretBoolean):
27+
class SecretBoolean(dsl.SecretBoolean): # pylint:disable=too-many-ancestors
2828
"""SecretBoolean rational wrapper"""
2929

3030
def __init__(self, value: dsl.SecretBoolean) -> None:
@@ -80,7 +80,7 @@ def if_else(
8080
return result
8181

8282

83-
class PublicBoolean(dsl.PublicBoolean):
83+
class PublicBoolean(dsl.PublicBoolean): # pylint:disable=too-many-ancestors
8484
"""PublicBoolean rational wrapper"""
8585

8686
def __init__(self, value: dsl.PublicBoolean) -> None:
@@ -169,6 +169,7 @@ def __init__(
169169
if not isinstance(value, (Integer, PublicInteger)):
170170
raise TypeError(f"Cannot instantiate Rational from type `{type(value)}`.")
171171

172+
self.base_type = "Rational"
172173
if log_scale is None:
173174
log_scale = get_log_scale()
174175
self._log_scale = log_scale
@@ -838,7 +839,7 @@ def log(
838839
raise TypeError("log input should be of type Rational.")
839840
return result
840841

841-
def reciprocal( # pylint: disable=too-many-arguments
842+
def reciprocal( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
842843
self,
843844
all_pos: bool = False,
844845
initial: Optional["Rational"] = None,
@@ -1299,6 +1300,7 @@ def __init__(
12991300
f"Cannot instantiate SecretRational from type `{type(value)}`."
13001301
)
13011302

1303+
self.base_type = "Rational"
13021304
if log_scale is None:
13031305
log_scale = get_log_scale()
13041306
self._log_scale = log_scale
@@ -1346,6 +1348,7 @@ def add(self, other: _NadaRational, ignore_scale: bool = False) -> "SecretRation
13461348
SecretRational: Result of the addition.
13471349
"""
13481350
if not isinstance(other, (Rational, SecretRational)):
1351+
# Lays the groundwork for broadcasting to Nada Array if it implements it
13491352
return NotImplemented
13501353

13511354
if not ignore_scale and self.log_scale != other.log_scale:
@@ -1780,14 +1783,14 @@ def public_equals(self, other: _NadaRational) -> PublicBoolean:
17801783
raise ValueError("Cannot compare values with different scales.")
17811784
return self.value.public_equals(other.value)
17821785

1783-
def reveal(self) -> Rational:
1786+
def to_public(self) -> Rational:
17841787
"""
17851788
Reveal the SecretRational value.
17861789
17871790
Returns:
17881791
Rational: Revealed SecretRational value.
17891792
"""
1790-
return Rational(self.value.reveal(), self.log_scale)
1793+
return Rational(self.value.to_public(), self.log_scale)
17911794

17921795
def trunc_pr(self, arg_0: _NadaRational) -> "SecretRational":
17931796
"""
@@ -1972,7 +1975,7 @@ def log(
19721975
raise TypeError("log input should be of type SecretRational.")
19731976
return result
19741977

1975-
def reciprocal( # pylint: disable=too-many-arguments
1978+
def reciprocal( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
19761979
self,
19771980
all_pos: bool = False,
19781981
initial: Optional["Rational"] = None,
@@ -2670,7 +2673,7 @@ def log(
26702673
return y
26712674

26722675

2673-
def reciprocal( # pylint: disable=too-many-arguments
2676+
def reciprocal( # pylint: disable=too-many-arguments disable=too-many-positional-arguments
26742677
x: _NadaRational,
26752678
all_pos: bool = False,
26762679
initial: Optional[Rational] = None,

0 commit comments

Comments
 (0)