106 lines
3.5 KiB
Python
106 lines
3.5 KiB
Python
# built-in dependencies
|
|
from typing import Optional, Union
|
|
from abc import ABC, abstractmethod
|
|
|
|
# 3rd party dependencies
|
|
from lightecc.interfaces.elliptic_curve import EllipticCurvePoint
|
|
|
|
# project dependencies
|
|
from lightphe.models.Algorithm import Algorithm
|
|
|
|
|
|
# Signature for supported cryptosystems
|
|
|
|
|
|
class Homomorphic(ABC):
|
|
keys: dict
|
|
plaintext_modulo: int
|
|
ciphertext_modulo: int
|
|
|
|
# Cryptosystems must define REQUIRED_KEYS as a dict with:
|
|
# - "public_key": list of required sub-fields in keys["public_key"]
|
|
# - "private_key": list of required sub-fields in keys["private_key"]
|
|
# - "nested" (optional): dict mapping a public_key sub-field that itself
|
|
# holds a dict to its required sub-fields.
|
|
REQUIRED_KEYS: dict
|
|
|
|
@abstractmethod
|
|
def generate_keys(
|
|
self,
|
|
key_size: int,
|
|
s: Optional[int] = None,
|
|
max_retries: Optional[int] = None,
|
|
plaintext_limit: Optional[int] = None,
|
|
) -> dict:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def generate_random_key(self) -> int:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def encrypt(
|
|
self, plaintext: int, random_key: Union[Optional[int], Optional[list]] = None
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def decrypt(self, ciphertext: Union[int, tuple, list, EllipticCurvePoint]) -> int:
|
|
pass
|
|
|
|
def add(
|
|
self,
|
|
ciphertext1: Union[int, tuple, list, EllipticCurvePoint],
|
|
ciphertext2: Union[int, tuple, list, EllipticCurvePoint],
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(
|
|
f"{self.get_algorithm_name()} is not homomorphic with respect to the addition"
|
|
)
|
|
|
|
def multiply(
|
|
self,
|
|
ciphertext1: Union[int, tuple, list, EllipticCurvePoint],
|
|
ciphertext2: Union[int, tuple, list, EllipticCurvePoint],
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(
|
|
f"{self.get_algorithm_name()} is not homomorphic with respect to the multiplication"
|
|
)
|
|
|
|
def xor(
|
|
self,
|
|
ciphertext1: Union[int, tuple, list, EllipticCurvePoint],
|
|
ciphertext2: Union[int, tuple, list, EllipticCurvePoint],
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(
|
|
f"{self.get_algorithm_name()} is not homomorphic with respect to the exclusive or"
|
|
)
|
|
|
|
def homomorphic_and(
|
|
self,
|
|
ciphertext1: Union[int, tuple, list, EllipticCurvePoint],
|
|
ciphertext2: Union[int, tuple, list, EllipticCurvePoint],
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(
|
|
f"{self.get_algorithm_name()} is not homomorphic with respect to the bitwise and"
|
|
)
|
|
|
|
def multiply_by_constant(
|
|
self, ciphertext: Union[int, tuple, list, EllipticCurvePoint], constant: int
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(
|
|
f"{self.get_algorithm_name()} is not supporting multiplying ciphertext by a known constant"
|
|
)
|
|
|
|
def reencrypt(
|
|
self, ciphertext: Union[int, tuple, list, EllipticCurvePoint]
|
|
) -> Union[int, tuple, list, EllipticCurvePoint]:
|
|
raise ValueError(f"{self.get_algorithm_name()} does not support re-encryption")
|
|
|
|
def get_algorithm_name(self) -> str:
|
|
class_name = self.__class__.__name__
|
|
algorithm_name = getattr(Algorithm, class_name, None)
|
|
assert isinstance(
|
|
algorithm_name, str
|
|
), f"Algorithm name for {class_name} is not defined"
|
|
return algorithm_name
|