Sealing & Unsealing
Overview
In Fhenix's FHE system, data returned from smart contracts is "sealed" (internally re-encrypted since it already exists in an encrypted state) to maintain confidentiality during transmission. The unsealing process converts this encrypted data back into readable values using your permit's sealing key pair.
Note: To learn more about sealed box encryption, take a look at the libsodium sealedbox docs.
Basic Usage
Simple Unsealing
The most straightforward way to unseal data is using cofhejs.unseal()
:
Note: Unsealing requires
Cofhejs
to be initialized and for a permit to be created.
// Get sealed data from a contract
const sealedBalance = await myContract.getBalance()
// Unseal with the correct type
const result = await cofhejs.unseal(sealedBalance, FheTypes.Uint64)
if (!result.success) {
console.error('Failed to unseal:', result.error)
return
}
console.log('Balance:', result.data) // Unsealed value as BigInt
Supported Types
The unsealing process supports all FHE data types:
// Integer types
const uint8 = await cofhejs.unseal(sealed, FheTypes.Uint8)
const uint16 = await cofhejs.unseal(sealed, FheTypes.Uint16)
const uint32 = await cofhejs.unseal(sealed, FheTypes.Uint32)
const uint64 = await cofhejs.unseal(sealed, FheTypes.Uint64)
const uint128 = await cofhejs.unseal(sealed, FheTypes.Uint128)
const uint256 = await cofhejs.unseal(sealed, FheTypes.Uint256)
// Boolean
const bool = await cofhejs.unseal(sealed, FheTypes.Bool)
// Address
const address = await cofhejs.unseal(sealed, FheTypes.Address)
Advanced Usage
Direct Permit Unsealing
For lower-level control, you can use the Permit class directly to unseal data:
const permit = await Permit.create({
type: 'self',
issuer: userAddress,
})
// Seal some data (for demonstration)
const value = 937387n
const sealed = SealingKey.seal(value, permit.sealingPair.publicKey)
// Unseal directly with permit
const unsealed = permit.unseal(sealed)
console.log(unsealed === value) // true
Type Conversions
Internally, data types require specific handling when unsealed:
// Boolean values
const boolValue = true
const sealedBool = SealingKey.seal(boolValue ? 1 : 0, permit.sealingPair.publicKey)
const unsealedBool = permit.unseal(sealedBool)
const resultBool = unsealedBool === 1n // Convert BigInt to boolean
// Address values
const addressValue = '0x1234...'
const sealedAddress = SealingKey.seal(BigInt(addressValue), permit.sealingPair.publicKey)
const unsealedAddress = permit.unseal(sealedAddress)
const resultAddress = getAddress(`0x${unsealedAddress.toString(16).slice(-40)}`)
However this is handled for you with cofhejs.unseal
. Unsealing an encrypted boolean will return a bool
, an encrypted address will return a 0x
prefixed string, and an encrypted number will return a js bigint
.