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.

Required

  • rust^1.77.1 stable
  • python^3.10
  • environment:
    • ubuntu-22.04
    • macos arm64
    • macos x86-64

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 Distribution

fhe-http-0.2.47.tar.gz (25.8 kB view details)

Uploaded Source

Built Distributions

fhe_http-0.2.47-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.47-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.47.tar.gz.

File metadata

  • Download URL: fhe-http-0.2.47.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.10.12

File hashes

Hashes for fhe-http-0.2.47.tar.gz
Algorithm Hash digest
SHA256 be7bfbc12ef53212784f3c85aa7ccbfab325d724b212f2562c8c938dbc441201
MD5 716ea8c411ca94b147f4c84422596080
BLAKE2b-256 37ad9c3e3edeefd46d3d9c301ba803d9bd4678bf73b8443044dd2f7120db29c5

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fhe_http-0.2.47-cp310-cp310-macosx_14_0_universal2.whl
Algorithm Hash digest
SHA256 c16d7be87b1995890dbc4d08ff1504b80354455a281ebd53f4798e03b4fb5c84
MD5 bf5eaf3077b7d802d06ec04d546f8a50
BLAKE2b-256 1a2a4a167aebe27b28a3595d19b13a493ebec1770df0af1aec7faf727c4a485e

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for fhe_http-0.2.47-cp310-cp310-macosx_12_0_x86_64.whl
Algorithm Hash digest
SHA256 255e8c3389a942c9f80cf158bf9b76681da3f51abc0b164477b00f7e63088634
MD5 c9670f38338d3bcf52ceae8882b26c39
BLAKE2b-256 f7bda4c53ab205cebbe17867ea105b9ec2526598fd5e6fb9cc8ca967820a673b

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