diff --git a/.gitignore b/.gitignore index 169a028..3a34c0e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,7 @@ nada_dsl/version.py *.log *.out + +# IntelliJ IDEA +*.iml +.idea \ No newline at end of file diff --git a/docs/_source/nada_dsl.nada_types.rst b/docs/_source/nada_dsl.nada_types.rst index c05154d..be628b7 100644 --- a/docs/_source/nada_dsl.nada_types.rst +++ b/docs/_source/nada_dsl.nada_types.rst @@ -15,7 +15,7 @@ nada\_dsl.nada\_types :show-inheritance: -.. automodule:: nada_dsl.nada_types.types +.. automodule:: nada_dsl.nada_types.scalar_types :members: :undoc-members: :show-inheritance: diff --git a/nada_dsl/__init__.py b/nada_dsl/__init__.py index 3a3205c..5932ba3 100644 --- a/nada_dsl/__init__.py +++ b/nada_dsl/__init__.py @@ -4,7 +4,7 @@ from nada_dsl.audit import * from nada_dsl.source_ref import * -from nada_dsl.nada_types.types import * +from nada_dsl.nada_types.scalar_types import * from nada_dsl.nada_types.generics import * from nada_dsl.nada_types.function import * from nada_dsl.nada_types.collections import * diff --git a/nada_dsl/compiler_frontend_test.py b/nada_dsl/compiler_frontend_test.py index 5863f03..40e238d 100644 --- a/nada_dsl/compiler_frontend_test.py +++ b/nada_dsl/compiler_frontend_test.py @@ -18,7 +18,7 @@ ) # pylint: disable=wildcard-import,unused-wildcard-import -from nada_dsl.nada_types.types import * +from nada_dsl.nada_types.scalar_types import * from nada_dsl.circuit_io import Input, Output from nada_dsl.compiler_frontend import ( nada_dsl_to_nada_mir, diff --git a/nada_dsl/nada_types/__init__.py b/nada_dsl/nada_types/__init__.py index 1f816b5..be0bca9 100644 --- a/nada_dsl/nada_types/__init__.py +++ b/nada_dsl/nada_types/__init__.py @@ -1,4 +1,5 @@ from dataclasses import dataclass +from enum import Enum from typing import Dict, TypeAlias, Union, Type from nada_dsl.source_ref import SourceRef @@ -81,6 +82,18 @@ def __init__(self, name): """ +class Mode(Enum): + CONSTANT = 1 + PUBLIC = 2 + SECRET = 3 + + +class BaseType(Enum): + BOOLEAN = 1 + INTEGER = 2 + UNSIGNED_INTEGER = 3 + + @dataclass class NadaType: """Nada type class. @@ -125,9 +138,10 @@ def class_to_type(cls): name = cls.__name__ # Rename public variables so they are considered as the same as literals. if name.startswith("Public"): - name = name[len("Public") :].lstrip() + name = name[len("Public"):].lstrip() return name return name def __bool__(self): raise NotImplementedError + diff --git a/nada_dsl/nada_types/collections.py b/nada_dsl/nada_types/collections.py index 6590399..92caed1 100644 --- a/nada_dsl/nada_types/collections.py +++ b/nada_dsl/nada_types/collections.py @@ -16,7 +16,7 @@ from nada_dsl.nada_types import NadaType # Wildcard import due to non-zero types -from nada_dsl.nada_types.types import * # pylint: disable=W0614:wildcard-import +from nada_dsl.nada_types.scalar_types import * # pylint: disable=W0614:wildcard-import from nada_dsl.source_ref import SourceRef from nada_dsl.errors import NadaNotAllowedException from nada_dsl.nada_types.function import NadaFunction, nada_fn diff --git a/nada_dsl/nada_types/scalar_types.py b/nada_dsl/nada_types/scalar_types.py new file mode 100644 index 0000000..9ea7f14 --- /dev/null +++ b/nada_dsl/nada_types/scalar_types.py @@ -0,0 +1,390 @@ +from . import NadaType, Mode, BaseType, OperationType +from nada_dsl.circuit_io import Literal +from typing import Union +from nada_dsl.operations import * +from .. import SourceRef + +SCALAR_TYPES = {} + + +def register_scalar_type(mode: Mode, base_type: BaseType): + def decorator(scalar_type): + SCALAR_TYPES[(mode, base_type)] = scalar_type + return scalar_type + return decorator + + +def new_scalar_type(mode: Mode, base_type: BaseType): + return SCALAR_TYPES.get((mode, base_type)) + + +class ScalarType(NadaType): + base_type: BaseType + mode: Mode + """This abstraction represents all scalar types: + - Boolean, PublicBoolean, SecretBoolean + - Integer, PublicInteger, SecretInteger + - UnsignedInteger, PublicUnsignedInteger, SecretUnsignedInteger + It provides common operation implementations for all the scalar types, defined above. + """ + + def __init__(self, inner: OperationType, base_type: BaseType, mode: Mode): + super().__init__(inner=inner) + self.base_type = base_type + self.mode = mode + + def __eq__(self, other): + return equals_operation("Equals", "==", self, other, lambda lhs, rhs: lhs == rhs) + + def __ne__(self, other): + return equals_operation("NotEquals", "!=", self, other, lambda lhs, rhs: lhs != rhs) + + +def equals_operation(operation, operator, left: ScalarType, right: ScalarType, f) -> ScalarType: + """This function is an abstraction for the equality operations""" + base_type = left.base_type + if base_type != right.base_type: + raise TypeError(f"Invalid operation: {left} {operator} {right}") + mode = Mode(max([left.mode.value, right.mode.value])) + if mode == Mode.CONSTANT: + return Boolean(value=bool(f(left.value, right.value))) + elif mode == Mode.PUBLIC: + operation = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return PublicBoolean(inner=operation) + else: + operation = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return SecretBoolean(inner=operation) + + +class NumericType(ScalarType): + """This abstraction represents all numeric types: + - Integer, PublicInteger, SecretInteger + - UnsignedInteger, PublicUnsignedInteger, SecretUnsignedInteger + It provides common operation implementations for all the numeric types, defined above. + """ + + def __add__(self, other): + return binary_arithmetic_operation("Addition", "+", self, other, lambda lhs, rhs: lhs + rhs) + + def __sub__(self, other): + return binary_arithmetic_operation("Subtraction", "-", self, other, lambda lhs, rhs: lhs - rhs) + + def __mul__(self, other): + return binary_arithmetic_operation("Multiplication", "*", self, other, lambda lhs, rhs: lhs * rhs) + + def __truediv__(self, other): + return binary_arithmetic_operation("Division", "/", self, other, lambda lhs, rhs: lhs / rhs) + + def __mod__(self, other): + return binary_arithmetic_operation("Modulo", "%", self, other, lambda lhs, rhs: lhs % rhs) + + def __pow__(self, other): + base_type = self.base_type + if (base_type != other.base_type or + not (base_type == BaseType.INTEGER or base_type == BaseType.UNSIGNED_INTEGER)): + raise TypeError(f"Invalid operation: {self} ** {other}") + mode = Mode(max([self.mode.value, other.mode.value])) + if mode == Mode.CONSTANT: + return new_scalar_type(mode, base_type)(self.value ** other.value) + elif mode == Mode.PUBLIC: + inner = Power(left=self, right=other, source_ref=SourceRef.back_frame()) + return new_scalar_type(mode, base_type)(inner) + else: + raise TypeError(f"Invalid operation: {self} ** {other}") + + def __lshift__(self, other): + return shift_operation("LeftShift", "<<", self, other, lambda lhs, rhs: lhs << rhs) + + def __rshift__(self, other): + return shift_operation("RightShift", ">>", self, other, lambda lhs, rhs: lhs >> rhs) + + def __lt__(self, other): + return binary_relational_operation("LessThan", "<", self, other, lambda lhs, rhs: lhs < rhs) + + def __gt__(self, other): + return binary_relational_operation("GreaterThan", ">", self, other, lambda lhs, rhs: lhs > rhs) + + def __le__(self, other): + return binary_relational_operation("LessOrEqualThan", "<=", self, other, lambda lhs, rhs: lhs <= rhs) + + def __ge__(self, other): + return binary_relational_operation("GreaterOrEqualThan", ">=", self, other, lambda lhs, rhs: lhs >= rhs) + + +def binary_arithmetic_operation(operation, operator, left: ScalarType, right: ScalarType, f) -> ScalarType: + """This function is an abstraction for the binary arithmetic operations""" + base_type = left.base_type + if (base_type != right.base_type or + not (base_type == BaseType.INTEGER or base_type == BaseType.UNSIGNED_INTEGER)): + raise TypeError(f"Invalid operation: {left} {operator} {right}") + mode = Mode(max([left.mode.value, right.mode.value])) + if mode == Mode.CONSTANT: + return new_scalar_type(mode, base_type)(f(left.value, right.value)) + else: + inner = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return new_scalar_type(mode, base_type)(inner) + + +def shift_operation(operation, operator, left: ScalarType, right: ScalarType, f) -> ScalarType: + """This function is an abstraction for the shift operations""" + base_type = left.base_type + right_base_type = right.base_type + if (not (base_type == BaseType.INTEGER or base_type == BaseType.UNSIGNED_INTEGER) + or not right_base_type == BaseType.UNSIGNED_INTEGER): + raise TypeError(f"Invalid operation: {left} {operator} {right}") + right_mode = right.mode + if not (right_mode == Mode.CONSTANT or right_mode == Mode.PUBLIC): + raise TypeError(f"Invalid operation: {left} {operator} {right}") + mode = Mode(max([left.mode.value, right_mode.value])) + if mode == Mode.CONSTANT: + return new_scalar_type(mode, base_type)(f(left.value, right.value)) + else: + inner = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return new_scalar_type(mode, base_type)(inner) + + +def binary_relational_operation(operation, operator, left: ScalarType, right: ScalarType, f) -> ScalarType: + """This function is an abstraction for the binary relational operations""" + base_type = left.base_type + if (base_type != right.base_type or + not (base_type == BaseType.INTEGER or base_type == BaseType.UNSIGNED_INTEGER)): + raise TypeError(f"Invalid operation: {left} {operator} {right}") + mode = Mode(max([left.mode.value, right.mode.value])) + if mode == Mode.CONSTANT: + return new_scalar_type(mode, BaseType.BOOLEAN)(f(left.value, right.value)) + else: + inner = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return new_scalar_type(mode, BaseType.BOOLEAN)(inner) + + +# Public equals can not be called by a literal, for this reason, it's not implemented by NumericType +def public_equals_operation(left: ScalarType, right: ScalarType) -> ScalarType: + """This function is an abstraction for the public_equals.""" + base_type = left.base_type + if (base_type != right.base_type or + not (base_type == BaseType.INTEGER or base_type == BaseType.UNSIGNED_INTEGER)): + raise TypeError(f"Invalid operation: {left}.public_equals({right})") + if left.mode == Mode.CONSTANT or right.mode == Mode.CONSTANT: + raise TypeError(f"Invalid operation: {left}.public_equals({right})") + else: + return PublicBoolean(inner=PublicOutputEquality(left=left, right=right, source_ref=SourceRef.back_frame())) + + +class BooleanType(ScalarType): + """This abstraction represents all boolean types: + - Boolean, PublicBoolean, SecretBoolean + It provides common operation implementations for all the boolean types, defined above. + """ + + def __and__(self, other): + return binary_logical_operation("BooleanAnd", "&", self, other, lambda lhs, rhs: lhs & rhs) + + def __or__(self, other): + return binary_logical_operation("BooleanOr", "|", self, other, lambda lhs, rhs: lhs | rhs) + + def __xor__(self, other): + return binary_logical_operation("BooleanXor", "^", self, other, lambda lhs, rhs: lhs ^ rhs) + + def if_else(self, arg_0: ScalarType, arg_1: ScalarType) -> ScalarType: + """This function implements the function 'if_else' for every class that extends 'BooleanType'.""" + base_type = arg_0.base_type + if base_type != arg_1.base_type or base_type == BaseType.BOOLEAN or self.mode == Mode.CONSTANT: + raise TypeError(f"Invalid operation: {self}.IfElse({arg_0}, {arg_1})") + mode = Mode(max([self.mode.value, arg_0.mode.value, arg_1.mode.value])) + inner = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) + if mode == Mode.CONSTANT: + mode = Mode.PUBLIC + return new_scalar_type(mode, base_type)(inner) + + +def binary_logical_operation(operation, operator, left: ScalarType, right: ScalarType, f) -> ScalarType: + """This function is an abstraction for the logical operations.""" + base_type = left.base_type + if base_type != right.base_type or not base_type == BaseType.BOOLEAN: + raise TypeError(f"Invalid operation: {left} {operator} {right}") + mode = Mode(max([left.mode.value, right.mode.value])) + if mode == Mode.CONSTANT: + return Boolean(value=bool(f(left.value, right.value))) + elif mode == Mode.PUBLIC: + operation = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return PublicBoolean(inner=operation) + else: + operation = globals()[operation](left=left, right=right, source_ref=SourceRef.back_frame()) + return SecretBoolean(inner=operation) + + +@dataclass +@register_scalar_type(Mode.CONSTANT, BaseType.INTEGER) +class Integer(NumericType): + value: int + + def __init__(self, value): + value = int(value) + super().__init__(Literal(value=value, source_ref=SourceRef.back_frame()), BaseType.INTEGER, Mode.CONSTANT) + self.value = value + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + +@dataclass +@register_scalar_type(Mode.CONSTANT, BaseType.UNSIGNED_INTEGER) +class UnsignedInteger(NumericType): + value: int + + def __init__(self, value): + value = int(value) + super().__init__( + Literal(value=value, source_ref=SourceRef.back_frame()), + BaseType.UNSIGNED_INTEGER, + Mode.CONSTANT + ) + self.value = value + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + +@dataclass +@register_scalar_type(Mode.CONSTANT, BaseType.BOOLEAN) +class Boolean(BooleanType): + value: bool + + def __init__(self, value): + value = bool(value) + super().__init__(Literal(value=value, source_ref=SourceRef.back_frame()), BaseType.BOOLEAN, Mode.CONSTANT) + self.value = value + + def __bool__(self) -> bool: + return self.value + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def __invert__(self: "Boolean") -> "Boolean": + return Boolean(value=bool(not self.value)) + + +@dataclass +@register_scalar_type(Mode.PUBLIC, BaseType.INTEGER) +class PublicInteger(NumericType): + + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.INTEGER, Mode.PUBLIC) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def public_equals(self, other: Union["PublicInteger", "SecretInteger"]) -> "PublicBoolean": + return public_equals_operation(self, other) + + +@dataclass +@register_scalar_type(Mode.PUBLIC, BaseType.UNSIGNED_INTEGER) +class PublicUnsignedInteger(NumericType): + + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.UNSIGNED_INTEGER, Mode.PUBLIC) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def public_equals(self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger"]) -> "PublicBoolean": + return public_equals_operation(self, other) + + +@dataclass +@register_scalar_type(Mode.PUBLIC, BaseType.BOOLEAN) +class PublicBoolean(BooleanType): + + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.BOOLEAN, Mode.PUBLIC) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def __invert__(self: "PublicBoolean") -> "PublicBoolean": + operation = Not(this=self, source_ref=SourceRef.back_frame()) + return PublicBoolean(inner=operation) + + +@dataclass +@register_scalar_type(Mode.SECRET, BaseType.INTEGER) +class SecretInteger(NumericType): + + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.INTEGER, Mode.SECRET) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def public_equals(self, other: Union["PublicInteger", "SecretInteger"]) -> "PublicBoolean": + return public_equals_operation(self, other) + + def trunc_pr(self, other: Union["PublicUnsignedInteger", "UnsignedInteger"]) -> "SecretInteger": + if isinstance(other, UnsignedInteger): + operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) + return SecretInteger(inner=operation) + elif isinstance(other, PublicUnsignedInteger): + operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) + return SecretInteger(inner=operation) + else: + raise TypeError(f"Invalid operation: {self}.trunc_pr({other})") + + @classmethod + def random(cls) -> "SecretInteger": + return SecretInteger(inner=Random(source_ref=SourceRef.back_frame())) + + def to_public(self: "SecretInteger") -> "PublicInteger": + operation = Reveal(this=self, source_ref=SourceRef.back_frame()) + return PublicInteger(inner=operation) + + +@dataclass +@register_scalar_type(Mode.SECRET, BaseType.UNSIGNED_INTEGER) +class SecretUnsignedInteger(NumericType): + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.UNSIGNED_INTEGER, Mode.SECRET) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def public_equals(self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger"]) -> "PublicBoolean": + return public_equals_operation(self, other) + + def trunc_pr(self, other: Union["PublicUnsignedInteger", "UnsignedInteger"]) -> "SecretUnsignedInteger": + if isinstance(other, UnsignedInteger): + operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) + return SecretUnsignedInteger(inner=operation) + elif isinstance(other, PublicUnsignedInteger): + operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) + return SecretUnsignedInteger(inner=operation) + else: + raise TypeError(f"Invalid operation: {self}.trunc_pr({other})") + + @classmethod + def random(cls) -> "SecretUnsignedInteger": + return SecretUnsignedInteger(inner=Random(source_ref=SourceRef.back_frame())) + + def to_public(self: "SecretUnsignedInteger",) -> "PublicUnsignedInteger": + operation = Reveal(this=self, source_ref=SourceRef.back_frame()) + return PublicUnsignedInteger(inner=operation) + + +@dataclass +@register_scalar_type(Mode.SECRET, BaseType.BOOLEAN) +class SecretBoolean(BooleanType): + def __init__(self, inner: NadaType): + super().__init__(inner, BaseType.BOOLEAN, Mode.SECRET) + + def __eq__(self, other): + return ScalarType.__eq__(self, other) + + def __invert__(self: "SecretBoolean") -> "SecretBoolean": + operation = Not(this=self, source_ref=SourceRef.back_frame()) + return SecretBoolean(inner=operation) + + def to_public(self: "SecretBoolean") -> "PublicBoolean": + operation = Reveal(this=self, source_ref=SourceRef.back_frame()) + return PublicBoolean(inner=operation) + diff --git a/nada_dsl/nada_types/types.py b/nada_dsl/nada_types/types.py deleted file mode 100644 index c84c0b9..0000000 --- a/nada_dsl/nada_types/types.py +++ /dev/null @@ -1,1720 +0,0 @@ -# This file is automatically generated. Do not edit! - -from . import NadaType -from dataclasses import dataclass -from nada_dsl.circuit_io import Literal -from nada_dsl.operations import Addition, BooleanAnd, BooleanOr, BooleanXor, Division, Equals, GreaterOrEqualThan, GreaterThan, IfElse, LeftShift, LessOrEqualThan, LessThan, Modulo, Multiplication, Not, NotEquals, Power, PublicOutputEquality, Random, Reveal, RightShift, Subtraction, TruncPr -from nada_dsl.source_ref import SourceRef -from typing import Union - -@dataclass -class Integer(NadaType): - value: int - - def __init__(self, value: int): - super().__init__(inner=Literal(value=value, source_ref=SourceRef.back_frame())) - if isinstance(value, int): - self.value = value - else: - raise ValueError(f"Expected int, got {type(value).__name__}") - - def __add__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Integer", "PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value + other.value)) - elif isinstance(other, PublicInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Integer", "PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value - other.value)) - elif isinstance(other, PublicInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Integer", "PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value * other.value)) - elif isinstance(other, PublicInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Integer", "PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value / other.value)) - elif isinstance(other, PublicInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Integer", "PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value % other.value)) - elif isinstance(other, PublicInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __pow__( - self, other: Union["Integer", "PublicInteger"] - ) -> Union["Integer", "PublicInteger"]: - if isinstance(other, Integer): - return Integer(value=int(self.value ** other.value)) - elif isinstance(other, PublicInteger): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ** {other}") - - def __lshift__( - self, other: "UnsignedInteger" - ) -> "Integer": - if isinstance(other, UnsignedInteger): - return Integer(value=int(self.value << other.value)) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: "UnsignedInteger" - ) -> "Integer": - if isinstance(other, UnsignedInteger): - return Integer(value=int(self.value >> other.value)) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value < other.value)) - elif isinstance(other, PublicInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value > other.value)) - elif isinstance(other, PublicInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value <= other.value)) - elif isinstance(other, PublicInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value >= other.value)) - elif isinstance(other, PublicInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value == other.value)) - elif isinstance(other, PublicInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - return Boolean(value=bool(self.value != other.value)) - elif isinstance(other, PublicInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - -@dataclass -class UnsignedInteger(NadaType): - value: int - - def __init__(self, value: int): - super().__init__(inner=Literal(value=value, source_ref=SourceRef.back_frame())) - if isinstance(value, int): - self.value = value - else: - raise ValueError(f"Expected int, got {type(value).__name__}") - - def __add__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value + other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value - other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value * other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value / other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value % other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __pow__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value ** other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ** {other}") - - def __lshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value << other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "UnsignedInteger"]: - if isinstance(other, UnsignedInteger): - return UnsignedInteger(value=int(self.value >> other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value < other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value > other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value <= other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value >= other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value == other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - return Boolean(value=bool(self.value != other.value)) - elif isinstance(other, PublicUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - -@dataclass -class Boolean(NadaType): - value: bool - - def __init__(self, value: bool): - super().__init__(inner=Literal(value=value, source_ref=SourceRef.back_frame())) - if isinstance(value, bool): - self.value = value - else: - raise ValueError(f"Expected bool, got {type(value).__name__}") - - def __bool__(self) -> bool: - return self.value - - def __eq__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - return Boolean(value=bool(self.value == other.value)) - elif isinstance(other, PublicBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - return Boolean(value=bool(self.value != other.value)) - elif isinstance(other, PublicBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def __and__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - return Boolean(value=bool(self.value & other.value)) - elif isinstance(other, PublicBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} & {other}") - - def __or__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - return Boolean(value=bool(self.value | other.value)) - elif isinstance(other, PublicBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} | {other}") - - def __xor__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["Boolean", "PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - return Boolean(value=bool(self.value ^ other.value)) - elif isinstance(other, PublicBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ^ {other}") - - def __invert__( - self: "Boolean" - ) -> "Boolean": - return Boolean(value=bool(not self.value)) - -@dataclass -class PublicInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __add__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicInteger", "SecretInteger"]: - if isinstance(other, Integer): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __pow__( - self, other: Union["Integer", "PublicInteger"] - ) -> "PublicInteger": - if isinstance(other, Integer): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ** {other}") - - def __lshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "PublicInteger": - if isinstance(other, UnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "PublicInteger": - if isinstance(other, UnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Integer): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def public_equals( - self, other: Union["PublicInteger", "SecretInteger"] - ) -> "PublicBoolean": - if isinstance(other, PublicInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.public_equals({other})") - -@dataclass -class PublicUnsignedInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __add__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger"]: - if isinstance(other, UnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger"]: - if isinstance(other, UnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger"]: - if isinstance(other, UnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger"]: - if isinstance(other, UnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicUnsignedInteger", "SecretUnsignedInteger"]: - if isinstance(other, UnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __pow__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "PublicUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Power(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ** {other}") - - def __lshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "PublicUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "PublicUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, UnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def public_equals( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger"] - ) -> "PublicBoolean": - if isinstance(other, PublicUnsignedInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.public_equals({other})") - -@dataclass -class PublicBoolean(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __eq__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def __and__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} & {other}") - - def __or__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} | {other}") - - def __xor__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> Union["PublicBoolean", "SecretBoolean"]: - if isinstance(other, Boolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ^ {other}") - - def __invert__( - self: "PublicBoolean" - ) -> "PublicBoolean": - operation = Not(this=self, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - - def if_else( - self: "PublicBoolean", - arg_0, arg_1: Union["Integer", "PublicInteger", "PublicUnsignedInteger", "SecretInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["PublicInteger", "PublicUnsignedInteger", "SecretInteger", "SecretUnsignedInteger"]: - if isinstance(arg_0, SecretInteger) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, SecretInteger) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretInteger) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, Integer) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(arg_0, Integer) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(arg_0, Integer) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.IfElse({arg_0}, {arg_1})") - -@dataclass -class SecretInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __add__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretInteger": - if isinstance(other, Integer): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretInteger": - if isinstance(other, Integer): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretInteger": - if isinstance(other, Integer): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretInteger": - if isinstance(other, Integer): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretInteger": - if isinstance(other, Integer): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, SecretInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __lshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretInteger": - if isinstance(other, UnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretInteger": - if isinstance(other, UnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Integer", "PublicInteger", "SecretInteger"] - ) -> "SecretBoolean": - if isinstance(other, Integer): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def public_equals( - self, other: Union["PublicInteger", "SecretInteger"] - ) -> "PublicBoolean": - if isinstance(other, PublicInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.public_equals({other})") - - def trunc_pr( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretInteger": - if isinstance(other, UnsignedInteger): - operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.trunc_pr({other})") - - @classmethod - def random(cls) -> "SecretInteger": - return SecretInteger(inner=Random(source_ref=SourceRef.back_frame())) - - def to_public( - self: "SecretInteger", - ) -> "PublicInteger": - operation = Reveal(this=self, source_ref=SourceRef.back_frame()) - return PublicInteger(inner=operation) - -@dataclass -class SecretUnsignedInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __add__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Addition(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} + {other}") - - def __sub__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Subtraction(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} - {other}") - - def __mul__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Multiplication(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} * {other}") - - def __truediv__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Division(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} / {other}") - - def __mod__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Modulo(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} % {other}") - - def __lshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LeftShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} << {other}") - - def __rshift__( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = RightShift(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >> {other}") - - def __lt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} < {other}") - - def __gt__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} > {other}") - - def __le__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = LessOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} <= {other}") - - def __ge__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = GreaterOrEqualThan(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} >= {other}") - - def __eq__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> "SecretBoolean": - if isinstance(other, UnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def public_equals( - self, other: Union["PublicUnsignedInteger", "SecretUnsignedInteger"] - ) -> "PublicBoolean": - if isinstance(other, PublicUnsignedInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - elif isinstance(other, SecretUnsignedInteger): - operation = PublicOutputEquality(left=self, right=other, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.public_equals({other})") - - def trunc_pr( - self, other: Union["PublicUnsignedInteger", "UnsignedInteger"] - ) -> "SecretUnsignedInteger": - if isinstance(other, UnsignedInteger): - operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(other, PublicUnsignedInteger): - operation = TruncPr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.trunc_pr({other})") - - @classmethod - def random(cls) -> "SecretUnsignedInteger": - return SecretUnsignedInteger(inner=Random(source_ref=SourceRef.back_frame())) - - def to_public( - self: "SecretUnsignedInteger", - ) -> "PublicUnsignedInteger": - operation = Reveal(this=self, source_ref=SourceRef.back_frame()) - return PublicUnsignedInteger(inner=operation) - -@dataclass -class SecretBoolean(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __eq__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> "SecretBoolean": - if isinstance(other, Boolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = Equals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} == {other}") - - def __ne__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> "SecretBoolean": - if isinstance(other, Boolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = NotEquals(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} != {other}") - - def __and__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> "SecretBoolean": - if isinstance(other, Boolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanAnd(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} & {other}") - - def __or__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> "SecretBoolean": - if isinstance(other, Boolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanOr(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} | {other}") - - def __xor__( - self, other: Union["Boolean", "PublicBoolean", "SecretBoolean"] - ) -> "SecretBoolean": - if isinstance(other, Boolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, PublicBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - elif isinstance(other, SecretBoolean): - operation = BooleanXor(left=self, right=other, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - else: - raise TypeError(f"Invalid operation: {self} ^ {other}") - - def __invert__( - self: "SecretBoolean" - ) -> "SecretBoolean": - operation = Not(this=self, source_ref=SourceRef.back_frame()) - return SecretBoolean(inner=operation) - - def to_public( - self: "SecretBoolean", - ) -> "PublicBoolean": - operation = Reveal(this=self, source_ref=SourceRef.back_frame()) - return PublicBoolean(inner=operation) - - def if_else( - self: "SecretBoolean", - arg_0, arg_1: Union["Integer", "PublicInteger", "PublicUnsignedInteger", "SecretInteger", "SecretUnsignedInteger", "UnsignedInteger"] - ) -> Union["SecretInteger", "SecretUnsignedInteger"]: - if isinstance(arg_0, Integer) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, Integer) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, Integer) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, PublicInteger) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretInteger) and isinstance(arg_1, Integer): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretInteger) and isinstance(arg_1, PublicInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, SecretInteger) and isinstance(arg_1, SecretInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, UnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, PublicUnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, UnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, PublicUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - elif isinstance(arg_0, SecretUnsignedInteger) and isinstance(arg_1, SecretUnsignedInteger): - operation = IfElse(this=self, arg_0=arg_0, arg_1=arg_1, source_ref=SourceRef.back_frame()) - return SecretUnsignedInteger(inner=operation) - else: - raise TypeError(f"Invalid operation: {self}.IfElse({arg_0}, {arg_1})") - -@dataclass -class SecretBlob(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class ShamirShareInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class ShamirShareUnsignedInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class ShamirShareBoolean(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - def __invert__( - self: "ShamirShareBoolean" - ) -> "ShamirShareBoolean": - operation = Not(this=self, source_ref=SourceRef.back_frame()) - return ShamirShareBoolean(inner=operation) - - pass -@dataclass -class ShamirParticleInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class ShamirParticleUnsignedInteger(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class Array(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass -@dataclass -class Tuple(NadaType): - def __init__(self, inner: NadaType): - super().__init__(inner) - pass diff --git a/nada_dsl/scalar_type_test.py b/nada_dsl/scalar_type_test.py new file mode 100644 index 0000000..e7c1869 --- /dev/null +++ b/nada_dsl/scalar_type_test.py @@ -0,0 +1,479 @@ +import itertools +from collections.abc import Iterable +from typing import Union + +import pytest + +from nada_dsl import Input, Party +from nada_dsl.nada_types import BaseType, Mode +from nada_dsl.nada_types.scalar_types import Integer, PublicInteger, SecretInteger, Boolean, PublicBoolean, \ + SecretBoolean, UnsignedInteger, PublicUnsignedInteger, SecretUnsignedInteger, ScalarType, BooleanType + + +def combine_lists(list1, list2): + """This returns all combinations for the items of two lists""" + result = [] + for item1 in list1: + if isinstance(item1, Iterable): + item1 = list(item1) + else: + item1 = [item1] + for item2 in list2: + if isinstance(item2, Iterable): + item2 = list(item2) + else: + item2 = [item2] + result.append(item1 + item2) + return result + + +# All boolean values +booleans = [ + Boolean(value=True), + PublicBoolean(Input(name="public", party=Party("party"))), + SecretBoolean(Input(name="secret", party=Party("party"))) +] + +# All public boolean values +public_booleans = [ + Boolean(value=True), + PublicBoolean(Input(name="public", party=Party("party"))), +] + +# All secret boolean values +secret_booleans = [SecretBoolean(Input(name="secret", party="party"))] + +# All integer values +integers = [ + Integer(value=1), + PublicInteger(Input(name="public", party=Party("party"))), + SecretInteger(Input(name="secret", party=Party("party"))) +] + +# All public integer values +public_integers = [ + Integer(value=1), + PublicInteger(Input(name="public", party=Party("party"))), +] + +# All secret integer values +secret_integers = [SecretInteger(Input(name="secret", party="party"))] + +# All integer inputs (non literal elements) +variable_integers = [ + PublicInteger(Input(name="public", party=Party("party"))), + SecretInteger(Input(name="public", party=Party("party"))) +] + +# All unsigned integer values +unsigned_integers = [ + UnsignedInteger(value=1), + PublicUnsignedInteger(Input(name="public", party=Party("party"))), + SecretUnsignedInteger(Input(name="secret", party=Party("party"))) +] + +# All public unsigned integer values +public_unsigned_integers = [ + UnsignedInteger(value=1), + PublicUnsignedInteger(Input(name="public", party=Party("party"))), +] + +# All secret unsigned integer values +secret_unsigned_integers = [SecretUnsignedInteger(Input(name="secret", party="party"))] + +# All unsigned integer inputs (non-literal elements) +variable_unsigned_integers = [ + PublicUnsignedInteger(Input(name="public", party=Party("party"))), + SecretUnsignedInteger(Input(name="public", party=Party("party"))) +] + +# Binary arithmetic operations. They are provided as functions to the tests to avoid duplicate code +binary_arithmetic_functions = [ + lambda lhs, rhs: lhs + rhs, + lambda lhs, rhs: lhs - rhs, + lambda lhs, rhs: lhs * rhs, + lambda lhs, rhs: lhs / rhs, + lambda lhs, rhs: lhs % rhs, +] + +# Data set for the binary arithmetic operation tests. It combines all allowed operands with the operations. +binary_arithmetic_operations = ( + # Integers + combine_lists(itertools.product(integers, repeat=2), binary_arithmetic_functions) + # UnsignedIntegers + + combine_lists(itertools.product(unsigned_integers, repeat=2), binary_arithmetic_functions) +) + + +@pytest.mark.parametrize("left, right, operation", binary_arithmetic_operations) +def test_binary_arithmetic_operations(left: ScalarType, right: ScalarType, operation): + result = operation(left, right) + assert result.base_type, left.base_type + assert result.base_type, right.base_type + assert result.mode.value, max([left.mode.value, right.mode.value]) + + +# Allowed operands for the power operation +allowed_pow_operands = ( + # Integers: Only combinations of public integers + combine_lists(public_integers, public_integers) + # UnsignedIntegers: Only combinations of public unsigned integers + + combine_lists(public_unsigned_integers, public_unsigned_integers) +) + + +@pytest.mark.parametrize("left, right", allowed_pow_operands) +def test_pow(left: ScalarType, right: ScalarType): + result = left ** right + assert result.base_type, left.base_type + assert result.base_type, right.base_type + assert result.mode.value, max([left.mode.value, right.mode.value]) + + +# All shift operations. +shift_functions = [ + lambda lhs, rhs: lhs << rhs, + lambda lhs, rhs: lhs >> rhs, +] + +# The shift operations accept public unsigned integers on the right operand only. +allowed_shift_operands = ( + # Integers on the left operand + combine_lists(combine_lists(integers, public_unsigned_integers), shift_functions) + # UnsignedIntegers on the left operand + + combine_lists(combine_lists(unsigned_integers, public_unsigned_integers), shift_functions) +) + + +@pytest.mark.parametrize("left, right, operation", allowed_shift_operands) +def test_shift(left: ScalarType, right: ScalarType, operation): + result = operation(left, right) + assert result.base_type, left.base_type + assert result.mode, left.mode + + +# Binary relational operations. +# Equals and NotEquals are not included, because they accept by the Boolean types as well +binary_relational_functions = [ + lambda lhs, rhs: lhs < rhs, + lambda lhs, rhs: lhs > rhs, + lambda lhs, rhs: lhs <= rhs, + lambda lhs, rhs: lhs >= rhs +] + +# Allowed operands that are accepted by the numeric relational operations. They are combined with the operations. +binary_relational_operations = ( + # Integers + combine_lists(itertools.product(integers, repeat=2), binary_relational_functions) + # UnsignedIntegers + + combine_lists(itertools.product(unsigned_integers, repeat=2), binary_relational_functions) +) + + +@pytest.mark.parametrize("left, right, operation", binary_relational_operations) +def test_binary_relational_operations(left: ScalarType, right: ScalarType, operation): + result = operation(left, right) + assert result.base_type, BaseType.BOOLEAN + assert result.mode.value, max([left.mode.value, right.mode.value]) + + +# Equality operations +equals_functions = [ + lambda lhs, rhs: lhs == rhs, + lambda lhs, rhs: lhs != rhs +] + +# Allowed operands that are accepted by the equality operations. They are combined with the operations. +equals_operations = ( + combine_lists(itertools.product(integers, repeat=2), equals_functions) + + combine_lists(itertools.product(unsigned_integers, repeat=2), equals_functions) + + combine_lists(itertools.product(booleans, repeat=2), equals_functions) +) + + +@pytest.mark.parametrize("left, right, operation", equals_operations) +def test_equals_operations(left: ScalarType, right: ScalarType, operation): + result = operation(left, right) + assert result.base_type, BaseType.BOOLEAN + assert result.mode.value, max([left.mode.value, right.mode.value]) + + +# Allowed operands that are accepted by the public_equals function. Literals are not accepted. +public_equals_operands = ( + # Integers + combine_lists(variable_integers, variable_integers) + # UnsignedIntegers + + combine_lists(variable_unsigned_integers, variable_unsigned_integers) +) + + +@pytest.mark.parametrize("left, right", public_equals_operands) +def test_public_equals( + left: Union["PublicInteger", "SecretInteger", "PublicUnsignedInteger", "SecretUnsignedInteger"] + , right: Union["PublicInteger", "SecretInteger", "PublicUnsignedInteger", "SecretUnsignedInteger"] +): + assert isinstance(left.public_equals(right), PublicBoolean) + + +# All supported logic functions +logic_functions = [ + lambda lhs, rhs: lhs & rhs, + lambda lhs, rhs: lhs | rhs, + lambda lhs, rhs: lhs ^ rhs +] + +# Allowed operands that are accepted by the logic operations. They are combined with the operations. +binary_logic_operations = combine_lists(combine_lists(booleans, booleans), logic_functions) + + +@pytest.mark.parametrize("left, right, operation", binary_logic_operations) +def test_logic_operations(left: BooleanType, right: BooleanType, operation): + result = operation(left, right) + assert result.base_type, BaseType.BOOLEAN + assert result.mode.value, max([left.mode.value, right.mode.value]) + + +@pytest.mark.parametrize("operand", booleans) +def test_invert_operations(operand): + result = ~operand + assert result.base_type, BaseType.BOOLEAN + assert result.mode, operand.mode + + +# Allowed operands that are accepted by the probabilistic truncation. +trunc_pr_operands = ( + combine_lists(secret_integers, public_unsigned_integers) + + combine_lists(secret_unsigned_integers, public_unsigned_integers) +) + + +@pytest.mark.parametrize("left, right", trunc_pr_operands) +def test_trunc_pr(left, right): + result = left.trunc_pr(right) + assert result.base_type, left.base_type + assert result.mode, Mode.SECRET + + +# Allowed types that can generate a random value. +random_operands = secret_integers + secret_unsigned_integers + + +@pytest.mark.parametrize("operand", random_operands) +def test_random(operand): + result = operand.random() + assert result.base_type, operand.base_type + assert result.mode, Mode.SECRET + + +# Allowed types that can invoke the to_public() function. +to_public_operands = secret_integers + secret_unsigned_integers + secret_booleans + + +@pytest.mark.parametrize("operand", to_public_operands) +def test_to_public(operand): + result = operand.to_public() + assert result.base_type, operand.base_type + assert result.mode, Mode.PUBLIC + + +public_boolean = PublicBoolean(Input(name="public", party="party")) + +# Allow combination of operands that are accepted by if_else function +if_else_operands = ( + combine_lists(secret_booleans, combine_lists(integers, integers)) + + combine_lists([public_boolean], combine_lists(integers, integers)) + + combine_lists(secret_booleans, combine_lists(unsigned_integers, unsigned_integers)) + + combine_lists([public_boolean], combine_lists(unsigned_integers, unsigned_integers)) +) + + +@pytest.mark.parametrize("condition, left, right", if_else_operands) +def test_if_else(condition: BooleanType, left: ScalarType, right: ScalarType): + result = condition.if_else(left, right) + assert left.base_type == right.base_type + assert result.base_type == left.base_type + expected_mode = Mode(max([condition.mode.value, left.mode.value, right.mode.value])) + assert result.mode, expected_mode + + +# List of not allowed operations +not_allowed_binary_operations = \ + ( # Arithmetic operations + combine_lists(combine_lists(booleans, booleans), binary_arithmetic_functions) + + combine_lists(combine_lists(booleans, integers), binary_arithmetic_functions) + + combine_lists(combine_lists(booleans, unsigned_integers), binary_arithmetic_functions) + + combine_lists(combine_lists(integers, booleans), binary_arithmetic_functions) + + combine_lists(combine_lists(integers, unsigned_integers), binary_arithmetic_functions) + + combine_lists(combine_lists(unsigned_integers, booleans), binary_arithmetic_functions) + + combine_lists(combine_lists(unsigned_integers, integers), binary_arithmetic_functions) + # Relational operations + + combine_lists(combine_lists(booleans, booleans), binary_relational_functions) + + combine_lists(combine_lists(booleans, integers), binary_relational_functions) + + combine_lists(combine_lists(booleans, unsigned_integers), binary_relational_functions) + + combine_lists(combine_lists(integers, booleans), binary_relational_functions) + + combine_lists(combine_lists(integers, unsigned_integers), binary_relational_functions) + + combine_lists(combine_lists(unsigned_integers, booleans), binary_relational_functions) + + combine_lists(combine_lists(unsigned_integers, integers), binary_relational_functions) + # Equals operations + + combine_lists(combine_lists(booleans, integers), equals_functions) + + combine_lists(combine_lists(booleans, unsigned_integers), equals_functions) + + combine_lists(combine_lists(integers, booleans), equals_functions) + + combine_lists(combine_lists(integers, unsigned_integers), equals_functions) + + combine_lists(combine_lists(unsigned_integers, booleans), equals_functions) + + combine_lists(combine_lists(unsigned_integers, integers), equals_functions) + # Logic operations + + combine_lists(combine_lists(booleans, integers), logic_functions) + + combine_lists(combine_lists(booleans, unsigned_integers), logic_functions) + + combine_lists(combine_lists(integers, booleans), logic_functions) + + combine_lists(combine_lists(integers, integers), logic_functions) + + combine_lists(combine_lists(integers, unsigned_integers), logic_functions) + + combine_lists(combine_lists(unsigned_integers, booleans), logic_functions) + + combine_lists(combine_lists(unsigned_integers, integers), logic_functions) + + combine_lists(combine_lists(unsigned_integers, unsigned_integers), logic_functions) + ) + + +@pytest.mark.parametrize("left, right, operation", not_allowed_binary_operations) +def test_not_allowed_binary_operations(left, right, operation): + with pytest.raises(Exception) as invalid_operation: + operation(left, right) + assert invalid_operation.type == TypeError + + +# List of operands that the operation power does not accept. +not_allowed_pow = ( + combine_lists(booleans, booleans) + + combine_lists(integers, booleans) + + combine_lists(unsigned_integers, booleans) + + combine_lists(booleans, integers) + + combine_lists(secret_integers, integers) + + combine_lists(public_integers, secret_integers) + + combine_lists(integers, unsigned_integers) + + combine_lists(booleans, unsigned_integers) + + combine_lists(unsigned_integers, integers) + + combine_lists(secret_unsigned_integers, unsigned_integers) + + combine_lists(public_unsigned_integers, secret_unsigned_integers) +) + + +@pytest.mark.parametrize("left, right", not_allowed_pow) +def test_not_allowed_pow(left, right): + with pytest.raises(Exception) as invalid_operation: + left ** right + assert invalid_operation.type == TypeError + + +# List of operands that the shift operation do not accept. +not_allowed_shift = ( + combine_lists(combine_lists(booleans, booleans), shift_functions) + + combine_lists(combine_lists(integers, booleans), shift_functions) + + combine_lists(combine_lists(unsigned_integers, booleans), shift_functions) + + combine_lists(combine_lists(booleans, integers), shift_functions) + + combine_lists(combine_lists(integers, integers), shift_functions) + + combine_lists(combine_lists(unsigned_integers, integers), shift_functions) + + combine_lists(combine_lists(booleans, unsigned_integers), shift_functions) + + combine_lists(combine_lists(integers, secret_unsigned_integers), shift_functions) + + combine_lists(combine_lists(unsigned_integers, secret_unsigned_integers), shift_functions) +) + + +@pytest.mark.parametrize("left, right, operation", not_allowed_shift) +def test_not_allowed_shift(left, right, operation): + with pytest.raises(Exception) as invalid_operation: + operation(left, right) + assert invalid_operation.type == TypeError + + +# List of operands that the public_equals function does not accept. +not_allowed_public_equals_operands = (combine_lists(variable_integers, variable_unsigned_integers) + + combine_lists(variable_unsigned_integers, variable_integers)) + + +@pytest.mark.parametrize("left, right", not_allowed_public_equals_operands) +def test_not_allowed_public_equals( + left: Union["PublicInteger", "SecretInteger", "PublicUnsignedInteger", "SecretUnsignedInteger"] + , right: Union["PublicInteger", "SecretInteger", "PublicUnsignedInteger", "SecretUnsignedInteger"] +): + with pytest.raises(Exception) as invalid_operation: + left.public_equals(right) + assert invalid_operation.type == TypeError + + +# List of types that does not support the function invert. +not_allowed_invert_operands = integers + unsigned_integers + + +@pytest.mark.parametrize("operand", not_allowed_invert_operands) +def test_not_allowed_invert_operations(operand): + with pytest.raises(Exception) as invalid_operation: + operand.__invert__() + assert invalid_operation.type == AttributeError + + +# List of operands that the probabilistic truncation does not accept. +not_allowed_trunc_pr_operands = ( + combine_lists(booleans, booleans) + + combine_lists(integers, booleans) + + combine_lists(unsigned_integers, booleans) + + combine_lists(booleans, integers) + + combine_lists(integers, integers) + + combine_lists(unsigned_integers, integers) + + combine_lists(booleans, unsigned_integers) + + combine_lists(integers, secret_unsigned_integers) + + combine_lists(public_integers, public_unsigned_integers) + + combine_lists(unsigned_integers, secret_unsigned_integers) + + combine_lists(public_unsigned_integers, public_unsigned_integers) +) + + +@pytest.mark.parametrize("left, right", not_allowed_trunc_pr_operands) +def test_not_allowed_trunc_pr(left, right): + with pytest.raises(Exception) as invalid_operation: + left.trunc_pr(right) + assert invalid_operation.type == TypeError or invalid_operation.type == AttributeError + + +# List of types that can not generate a random value +random_operands = booleans + public_integers + public_unsigned_integers + + +@pytest.mark.parametrize("operand", random_operands) +def test_not_allowed_random(operand): + with pytest.raises(Exception) as invalid_operation: + operand.random() + assert invalid_operation.type == AttributeError + + +# List of types that can not invoke the function to_public() +to_public_operands = public_booleans + public_integers + public_unsigned_integers + + +@pytest.mark.parametrize("operand", to_public_operands) +def test_not_to_public(operand): + with pytest.raises(Exception) as invalid_operation: + operand.to_public() + assert invalid_operation.type == AttributeError + + +# List of operands that the function if_else does not accept +not_allowed_if_else_operands = ( + # Boolean branches + combine_lists(booleans, combine_lists(booleans, booleans)) + # Branches with different types + + combine_lists(booleans, combine_lists(integers, booleans)) + + combine_lists(booleans, combine_lists(unsigned_integers, booleans)) + + combine_lists(booleans, combine_lists(booleans, integers)) + + combine_lists(booleans, combine_lists(unsigned_integers, integers)) + + combine_lists(booleans, combine_lists(booleans, unsigned_integers)) + + combine_lists(booleans, combine_lists(integers, unsigned_integers)) + # The condition is a literal + + combine_lists([Boolean(value=True)], combine_lists(integers, integers)) + + combine_lists([Boolean(value=True)], combine_lists(unsigned_integers, unsigned_integers)) +) + + +@pytest.mark.parametrize("condition, left, right", not_allowed_if_else_operands) +def test_if_else(condition: BooleanType, left: ScalarType, right: ScalarType): + with pytest.raises(Exception) as invalid_operation: + condition.if_else(left, right) + assert invalid_operation.type == TypeError diff --git a/pyproject.toml b/pyproject.toml index 907afb1..7b8c01c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "nada_dsl" -version = "0.6.2" +version = "0.6.3" description = "Nillion Nada DSL to create Nillion MPC programs." requires-python = ">=3.10" readme = "README.pyproject.md"