Skip to main content

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 from requestDecryption()
  • bitWidth: 8 | 16 | 32 | 64 - The bit width of the encrypted value
  • signed: 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 from requestDecryption()
  • bitWidth: 8 | 16 | 32 | 64 - The bit width of the encrypted value
  • signed: boolean - Whether the value is signed (default: false)
  • signal: AbortSignal - Optional cancellation signal (use AbortSignal.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;
}