🔓Decryption

Decryption is the process of converting an encrypted CipherBlock object or an encrypted score back into its original, human-readable plaintext form. The Cipher class provides different methods and configurations depending on your specific needs.


1. Standard Decryption (decrypt)

This is the most common decryption operation. It is used to decrypt a CipherBlock that contains a full data vector. You'll need the secret key that corresponds to the encryption key used to create the data.

The cipher.decrypt() method takes the encrypted object and the path to the secret key.

Example

from pyenvector import Cipher

# Assume 'encrypted_item' is a CipherBlock object you have retrieved
# encrypted_item = db.get_item(...)

# Initialize the Cipher class
cipher = Cipher(dim=512)

encrypted_item = cipher.encrypt([0.0] * 512, "item", "keys/example/EncKey.json")
# Decrypt the object by providing the secret key path
decrypted_vector = cipher.decrypt(
    encrypted_item, 
    sec_key_path="keys/example/SecKey.json"
)

print("Decrypted vector:", decrypted_vector)
# Output: Decrypted vector: [0.0, 0.0, 0.0, ...]

2. Decryption with a Sealed Secret Key

For enhanced security, you can use a "sealed" secret key. A sealed key is a secret key that has been encrypted with another key, known as a Key Encryption Key (KEK). This prevents the secret key from ever being exposed in plaintext on your system.

To use this feature, you must initialize the Cipher class with the seal_mode and seal_key_path. The actual decryption call remains the same, but the setup is more secure.

Example

from pyenvector import Cipher

# 1. Initialize Cipher with the sealing configuration
# This tells the class how to "unseal" your secret key
cipher = Cipher(
    dim=512,
)
encrypted_item = cipher.encrypt([0.0] * 512, "item", "keys/example-sealed/EncKey.json")
# 2. Decrypt as usual, but provide the path to the SEALED secret key
# The Cipher class will handle unsealing it in memory before use
decrypted_vector = cipher.decrypt(
    encrypted_item,
    sec_key_path="keys/example-sealed/SecKey.json",
    seal_mode="aes",
    seal_kek_path="aes.kek",
)

print("Decrypted vector (from sealed key):", decrypted_vector)

3. Decrypting Scores (decrypt_score)

When you call index.scoring(), the result is not a single value but an encrypted vector of similarity scores (e.g., inner products with all stored entries in the index). Since each score remains encrypted, you need to use the Cipher.decrypt_score() method to reveal the plaintext values.

Basic Usage

from pyenvector import Cipher

# Assume 'encrypted_scores' is the result from index scoring
# encrypted_scores = index.scoring(encrypted_query)

# Initialize the Cipher class
cipher = Cipher(dim=512)

# Decrypt the score vector to get the plaintext similarity scores
plaintext_scores = cipher.decrypt_score(
    encrypted_scores,
    sec_key_path="keys/example/SecKey.json"
)

print(f"The plaintext similarity scores are: {plaintext_scores} ✅")
# Output: The plaintext similarity scores are: [0.8765, 0.6543, 0.4321, ...] ✅

Using a Sealed Secret Key

If you are working with a sealed secret key (SecKey.json), you must also provide the seal_kek_path option.

from pyenvector import Cipher

# Assume 'encrypted_scores' is the result from index scoring
# encrypted_scores = index.scoring(encrypted_query)

# Initialize the Cipher class
cipher = Cipher(dim=512)

# Decrypt the score vector with the sealed secret key
plaintext_scores = cipher.decrypt_score(
    encrypted_scores,
    sec_key_path="keys/example-sealed/SecKey.bin",
    seal_mode="aes",
    seal_kek_path="aes.kek",
)

print(f"The plaintext similarity scores are: {plaintext_scores} ✅")
# Output: The plaintext similarity scores are: [0.8765, 0.6543, 0.4321, ...] ✅

Last updated