Decryption
After an FHE program executes on encrypted inputs, the plaintext result can be retrieved through threshold decryption.
Ensure the client is initialized before using these functions.
Requesting threshold decryption
To request threshold decryption of a ciphertext, use the requestDecryption() function:
export async function requestDecryptionExample(
signer: spf.PrivateKeySigner,
ciphertextId: spf.CiphertextId,
): Promise<spf.DecryptHandle> {
// Request decryption
const decryptHandle = await spf.requestDecryption(signer, ciphertextId);
console.log("Decryption requested:", decryptHandle);
return decryptHandle;
}
This submits a decryption request to the SPF threshold committee. The signer must have decrypt access to the ciphertext.
Parameters:
signer:AnySigner- Signer for authentication (must have decrypt access)ciphertextId:CiphertextId- The ciphertext identifier to decrypt
Returns: Promise<DecryptHandle> - The decryption handle (branded hex string with 0x prefix)
Checking decryption status
To check the status of a decryption request, use the checkDecryptionStatus() function:
export async function checkDecryptionStatusExample(
decryptHandle: spf.DecryptHandle,
bitWidth: spf.BitWidth,
): Promise<spf.DecryptionStatus> {
const status = await spf.checkDecryptionStatus(
decryptHandle,
bitWidth,
false,
);
if (status.status === "success") {
console.log("Decryption completed!");
console.log("Polynomial bytes:", status.payload.value);
} else if (status.status === "failed") {
console.error("Decryption failed:", status.payload?.message);
} else {
console.log("Decryption is still", status.status);
}
return status;
}
Parameters:
decryptHandle:DecryptHandle- The decrypt handle fromrequestDecryption()bitWidth:8 | 16 | 32 | 64- The bit width of the encrypted valuesigned:boolean- Whether the value is signed (default: false)
Returns: Promise<DecryptionStatus> - Discriminated union with status field
Waiting for decryption completion
For convenience, use waitForDecryption() to automatically poll until decryption completes and parse the result:
export async function waitForDecryptionExample(
decryptHandle: spf.DecryptHandle,
bitWidth: spf.BitWidth,
signed: boolean,
): Promise<bigint> {
// Wait for decryption and parse the result (16-bit unsigned value)
const plaintext: bigint = await spf.waitForDecryption(
decryptHandle,
bitWidth,
signed,
);
console.log("Decrypted value:", plaintext);
return plaintext;
}
This function polls checkDecryptionStatus() until decryption completes, then automatically parses the polynomial bytes into the plaintext value.
Parameters:
decryptHandle:DecryptHandle- The decrypt handle fromrequestDecryption()bitWidth:8 | 16 | 32 | 64- The bit width of the encrypted valuesigned:boolean- Whether the value is signed (default: false)signal:AbortSignal- Optional cancellation signal (useAbortSignal.timeout(ms)for timeout)
Returns: Promise<bigint> - The decrypted plaintext value
Cancellation support
The waitForDecryption() function supports cancellation via AbortSignal:
export async function decryptionWithAbortExample(
decryptHandle: spf.DecryptHandle,
): Promise<bigint> {
try {
// Wait for decryption with 30 second timeout
const plaintext = await spf.waitForDecryption(
decryptHandle,
16,
false,
AbortSignal.timeout(30000),
);
return plaintext;
} catch (error) {
if (error instanceof Error && error.name === "TimeoutError") {
console.log("Decryption timed out after 30 seconds");
}
throw error;
}
}
Complete decryption workflow
Here is a complete decryption example:
export async function completeDecryptionWorkflow(
signer: spf.PrivateKeySigner,
ciphertextId: spf.CiphertextId,
): Promise<bigint> {
// Request decryption
const decryptHandle = await spf.requestDecryption(signer, ciphertextId);
console.log("Decryption requested:", decryptHandle);
// Wait for completion and parse result
const plaintext = await spf.waitForDecryption(decryptHandle, 16, false);
console.log("Decrypted value:", plaintext);
return plaintext;
}