Skip to main content

This is an test package for Python Fhe Http

Project description

FHE-HTTP-Python

Introduce

  • Fully Homomorphic Encryption (FHE) is a technology that enables processing encrypted data without decrypting it. This allows clients to delegate computations, such as machine learning (ML) tasks to resource-equipped servers without revealing their own data. It can also be used for applications like Private Information Retrieval (PIR). For more details about FHE, please refer to the tfhe-rs documentation.
  • This project offers a Python interface for using tfhe-rs. Additionally, a zk-experimental version is supported, enabling the server to verify encrypted values before computation begins, and assembly code execution allows clients to define the computation process/
  • Currently, gpu acceleration of tfhe-rs is not yet available in this project.

Environment Required

  • rust^1.77.1 stable installation
  • python^3.10
  • Apple silicon chip (pkg installation on PyPI)

How to use

About Package

// download from from PyPI
$ pip install fhe-http

// Build fhe-http package from source
// This will create a package in site-packages of pip
$ cd fhe-http/fhe_http_python
$ maturin develop

Run Tests

// After package downloaded or built
# cd fhe-http/fhe_http_python
# python tests/*

Details of usage

#Basic Fhe Computation

Description

This basic version of FHE computation enables clients to delegate computation tasks to servers. Clients use a client key which is generated by themselves to encrypt the values. After encryption, clients send the encrypted values and a server key to the servers. Once the server key is received and set by the servers, the servers can execute the FHE computation on the ciphertexts. The computation result remains encrypted and is supposed to be sent back to the clients, who can then decrypt it to obtain the result in plaintext.

Supported

  • operations:
    • add, sub, mul, div, rem, and, or, xor, shr, shl, not, and, neg
  • FheType:
    • Int64
    • Uint64

Example usage

import fhe_http as py_fhe

# initialize keys
key_gen = py_fhe.KeyGenerator()
key_gen.init_keys()
client_key = key_gen.get_client_key()
server_key = key_gen.get_server_key()

# Server Side:
# set server key for ciphertext computation
sk_setter = py_fhe.ServerKeySetter()
decompressed_server_key = sk_setter.decompress_server_key(server_key)
sk_setter.set_server_key(decompressed_server_key)

# Client Side:
# use Fhe module to encrypt
fhe = py_fhe.Fhe(client_key)

# Client Side:
# encryt value
serailizer = py_fhe.Serializer()
data_type = py_fhe.create_fhe_value_type("Int64")
encrypted_a = fhe.encrypt(serailizer.from_i64(123), data_type)
encrypted_b = fhe.encrypt(serailizer.from_i64(456), data_type)

# Server Side:
# using FheOps module to have ciphertext computation
fhe_ops = py_fhe.FheOps()
encrypted_c = fhe_ops.add(encrypted_a, encrypted_b, data_type)

# Client side:
# decrypt computation result
decrypted_c = fhe.decrypt(encrypted_c, data_type)
c = serailizer.to_i64(decrypted_c)
assert c == 123 + 456

#ZK-experimental Fhe Computation

Description

This zk-experimental feature allows servers to verify encrypted values sent by clients before starting the FHE execution, preventing the processing of invalid or malicious values. Clients must use a public key, generated with zk public parameters, to encrypt the values. Servers verify these encrypted values by leveraging the zk public parameters (the same one used to generate public key). After completing the FHE computation, clients will receive the same result as they would using the non-zk feature.

Supported

  • operations:
    • add, sub, mul, div, rem, and, or, xor, shr, shl, not, and, neg
  • ProvenFheType:
    • ProvenInt64
    • ProvenUint64

Example usage

import fhe_http as py_fhe

# initialize keys
key_gen = py_fhe.KeyGenerator()
key_gen.init_keys()
client_key = key_gen.get_client_key()
server_key = key_gen.get_server_key()
public_key = key_gen.get_public_key()

# initialize zk params
public_zk_params = py_fhe.get_public_zk_params(msg=2, carry=2)

# Server Side:
# set server key for ciphertext computation
sk_setter = py_fhe.ServerKeySetter()
decompressed_server_key = sk_setter.decompress_server_key(server_key)
sk_setter.set_server_key(decompressed_server_key)

# Client Side:
# use Fhe module to encrypt
fhe = py_fhe.Fhe(client_key, public_key)

# Client Side:
# encryt value with public_zk_params
serailizer = py_fhe.Serializer()
proven_fhe_type = py_fhe.create_proven_fhe_value_type("ProvenInt64")
encrypted_a = fhe.proven_encrypt(serailizer.from_i64(123), proven_fhe_type, public_zk_params)
encrypted_b = fhe.proven_encrypt(serailizer.from_i64(456), proven_fhe_type, public_zk_params)

# Server Side:
# using ProvenFheOps module to have ciphertext computation
proven_ops = py_fhe.ProvenFheOps()
encrypted_c = proven_ops.add(encrypted_a, encrypted_b, proven_fhe_type, public_zk_params, public_key)

# Client Side:
decrypted_c = fhe.decrypt(encrypted_c, proven_fhe_type)
c = serailizer.to_u64(decrypted_c)
assert c == 123 + 456

#Assembly Code Fhe execution

Description

This assembly feature allows clients to define a function that includes multiple operations. The assembler.code_wrapper is a decorator that parses Python code into self-defined assembly code (see the example code below). Clients can define the function's parameters and send the encrypted actual values corresponding to those parameters to a server. Upon receiving the encrypted parameters, the server executes the assembly code and responds with the fhe computation results to the client.

Supported

  • operations:
    • add, sub, mul, div, rem, and, or, xor, shr, shl, not, and
    • neg is temporarily not supported in assembly code execution.
  • Type:
    • Int64
    • Uint64

Example usage

import fhe_http as py_fhe
from fhe_http.assembler.assembler import Assembler

def generate_keys():
    key_gen = py_fhe.KeyGenerator()
    key_gen.init_keys()
    client_key = key_gen.get_client_key()
    server_key = key_gen.get_server_key()
    return client_key, server_key

def set_server_key(server_key):
    sk_setter = py_fhe.ServerKeySetter()
    decompressed_server_key = sk_setter.decompress_server_key(server_key)
    sk_setter.set_server_key(decompressed_server_key)

def encrypt(num: int, client_key, data_type: str = "Uint64"):
    serailizer = py_fhe.Serializer()
    fhe_value = py_fhe.create_fhe_value_type(data_type)
    fhe = py_fhe.Fhe(client_key)
    return fhe.encrypt(serailizer.from_i64(num), fhe_value)

def decrypt(encrypted_num, client_key, data_type: str = "Uint64"):
    serailizer = py_fhe.Serializer()
    fhe_value = py_fhe.create_fhe_value_type(data_type)
    fhe = py_fhe.Fhe(client_key)
    return serailizer.to_i64(fhe.decrypt(encrypted_num, fhe_value))

def get_asm_code():
    assembler = Assembler()

    @assembler.code_wrapper
    def operation(i, j, two, three):
        a = i + j
        b = a >> two
        c = two << three
        d = c - b
        return d

    return "\n".join(operation.assembly)

if __name__ == "__main__":
    assembly = get_asm_code()
    client_key, server_key = generate_keys()
    set_server_key(server_key)

    encrypted = py_fhe.execute_assembly(
        assembly,
        {
            "i": encrypt(25, client_key),
            "j": encrypt(21, client_key),
            "two": encrypt(2, client_key),
            "three": encrypt(3, client_key),
        },
        py_fhe.create_fhe_value_type("Uint64"),
    )
    decrypted = decrypt(encrypted, client_key)
    print(decrypted)

Interaction via Http

Decription

This python package also provide some function for http request. For example: setting the header to comfirm the fhe protocol, and some json related operation for both body and header (see below exmaple)

Example usage

Execution

$ pip install fastapi uvicorn requests fhe-http

// machine 1
$ python3 server_test.py

// machine 2
$ python3 client_test.py

Client Side

# file name: client_test.py
import json
import fastapi
import uvicorn
from fastapi import Body
from pydantic import BaseModel
import fhe_http as py_fhe


app = fastapi.FastAPI()


class Addition(BaseModel):
    a: str
    b: str
    server_key: str


def encrypt(num: int, client_key, data_type: str = "Int64"):
    serailizer = py_fhe.Serializer()
    fhe_value = py_fhe.create_fhe_value_type(data_type)
    fhe = py_fhe.Fhe(client_key)
    return fhe.encrypt(serailizer.from_i64(num), fhe_value)


def set_server_key(server_key):
    sk_setter = py_fhe.ServerKeySetter()
    decompressed_server_key = sk_setter.decompress_server_key(server_key)
    sk_setter.set_server_key(decompressed_server_key)


@app.post("/")
async def post_request(data: Addition = Body(...)):
    print("Received request")
    data_type = py_fhe.create_fhe_value_type("Int64")
    data_json = json.loads(data.model_dump_json())
    encrypted_a = py_fhe.decode_fhe_value(data_json["a"])
    encrypted_b = py_fhe.decode_fhe_value(data_json["b"])
    server_key = py_fhe.decode_fhe_value(data_json["server_key"])
    set_server_key(server_key)
    fhe_ops = py_fhe.FheOps()
    encrypted_c = fhe_ops.add(encrypted_a, encrypted_b, data_type)
    encoded_c = py_fhe.encode_fhe_value(encrypted_c)
    return {"result": encoded_c, "status": "success"}


if __name__ == "__main__":
    uvicorn.run("server_test:app", host="localhost", port=8000, reload=True)

Server Side

# file name: server_test.py
# client.py
import json
import requests
import fhe_http as py_fhe


def generate_keys():
    key_gen = py_fhe.KeyGenerator()
    key_gen.init_keys()
    client_key = key_gen.get_client_key()
    server_key = key_gen.get_server_key()
    return client_key, server_key


def decrypt(encrypted_num, client_key, data_type: str = "Int64"):
    serailizer = py_fhe.Serializer()
    fhe_value = py_fhe.create_fhe_value_type(data_type)
    fhe = py_fhe.Fhe(client_key)
    return serailizer.to_i64(fhe.decrypt(encrypted_num, fhe_value))


def send_post_request(url):
    header = json.loads(py_fhe.create_fhe_header("123"))
    client_key, server_key = generate_keys()
    data = {"a": 123123123, "b": 123}
    data_type = py_fhe.create_fhe_value_type("Int64")
    encrypt_json = py_fhe.encrypt_fhe_body(
        [("a", data_type), ("b", data_type)], data, client_key
    )
    encrypt_json = json.loads(encrypt_json)
    payload_str = py_fhe.set_server_key_to_json(server_key, encrypt_json)
    payload = json.loads(payload_str)
    response = requests.post(url, json=payload, headers=header)
    response = response.json()
    encrypted_c = py_fhe.decode_fhe_value(response["result"])
    c = decrypt(encrypted_c, client_key)
    assert c == 123123246


if __name__ == "__main__":
    server_url = "http://localhost:8000"
    send_post_request(server_url)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

fhe_http-0.2.44-cp310-cp310-macosx_14_0_universal2.whl (1.4 MB view details)

Uploaded CPython 3.10 macOS 14.0+ universal2 (ARM64, x86-64)

fhe_http-0.2.44-cp310-cp310-macosx_12_0_x86_64.whl (1.6 MB view details)

Uploaded CPython 3.10 macOS 12.0+ x86-64

File details

Details for the file fhe_http-0.2.44-cp310-cp310-macosx_14_0_universal2.whl.

File metadata

File hashes

Hashes for fhe_http-0.2.44-cp310-cp310-macosx_14_0_universal2.whl
Algorithm Hash digest
SHA256 dc7ec7837bc73c89dbd8c7c9ad7115071634420872ca6a10f517497bf4e36c48
MD5 873f6b941ebc3dc4817e30cddc422458
BLAKE2b-256 4d5dbbe1a6be92839f1c770d36c8aa848bc3d6b6481c498fa40641da9d50de7d

See more details on using hashes here.

File details

Details for the file fhe_http-0.2.44-cp310-cp310-macosx_12_0_x86_64.whl.

File metadata

File hashes

Hashes for fhe_http-0.2.44-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 84f19d6119285a5f95afa9184b7c71735c497e75be497b4724add3f41a172b3e
MD5 17d3092e88bd0a43b347f5c11187bf2f
BLAKE2b-256 05eb44894ed4e7f745536bebad5c015aaa8787d6219d8b93a1e827570aa39834

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page