# 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
