Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Cryptography

The crypto module is a hybrid integrated-encryption scheme (ephemeral key → ECDH → HKDF-SHA256 → AEAD), built directly on @noble/curves, @noble/ciphers, and @noble/hashes. It is the basis for sealing every encrypted prism slot. The central type is DataPrismKey.

DataPrismKey

The cryptographic identity of a prism. The private key is never stored: it is derived from a wallet signature and reconstructed on demand.

Constructors (static)

MethodDescription
DataPrismKey.fromSignature(signature, config)derives the secret from a wallet signature, keccak256(signature), reduced to a valid scalar. Deterministic.
DataPrismKey.fromSecret(secret, config)from a raw 32-byte secret (reduced to a valid scalar)
DataPrismKey.fromPublicKey(publicKey, config)a public-only key: can encrypt, cannot open
import { DataPrismKey } from "@dataprism/sdk";
 
const sig = await walletClient.signMessage({ message: `dataprism:key:${cloudId}` });
const key = DataPrismKey.fromSignature(sig, { curve: "secp256k1", algorithm: "aes-256-gcm" });

Because the derivation is deterministic, signing the same message always produces the same key. Derive the message from the cloudId (default), it is public and reproducible from the prism's id, so nothing per-prism is stored. For extra security, mix in a password (`dataprism:key:${cloudId}:${password}`): without it, anyone who steals the wallet's private key could reproduce the signature and decrypt; with it, decryption also requires the password, which is never stored.

Properties

PropertyTypeNote
configEncryptionConfigcurve + algorithm
curveCurve
canOpenbooleanfalse for a public-only key
publicKeyHexHex
secretHexHexthrows if public-only

Methods

MethodReturnsNote
seal(data, aad?)Uint8Arrayencrypt for this prism
open(blob, aad?)Uint8Arraydecrypt (requires the secret)
sealJson(value, aad?)HexJSON → sealed hex
openJson<T>(blob, aad?)Tsealed hex → JSON
toKeySlot(includePrivate = false)KeySlot{ public, private }; private empty unless explicit public mode
const sealed = key.sealJson({ secret: "value" });   // Hex, safe to put on-chain
const data   = key.openJson<{ secret: string }>(sealed);

toKeySlot(true) is the explicit, opt-in "public mode": it writes the private key into the slot so anyone can decrypt the prism's data. The default (false) keeps private empty.

Low-level functions

seal(config: EncryptionConfig, recipientPublicKey: Uint8Array, data: Uint8Array, aad?): Uint8Array
open(config: EncryptionConfig, recipientSecret: Uint8Array, blob: Uint8Array, aad?): Uint8Array

The blob layout is ephemeralKey ‖ nonce ‖ tag ‖ ciphertext. Because it is AEAD, any tampering with a sealed payload is detected, open fails rather than returning corrupt data.

Configuration

type Curve     = "secp256k1" | "x25519" | "ed25519";
type Algorithm = "aes-256-gcm" | "xchacha20";
 
interface EncryptionConfig { curve: Curve; algorithm: Algorithm }
 
const DEFAULT_ENCRYPTION = { curve: "secp256k1", algorithm: "aes-256-gcm" };
 
assertEncryptionConfig(config): void   // validates, or throws

All six curve × algorithm combinations are supported and round-trip tested. The chosen config is stored (in clear) in the prism's dataprism.encryption slot so any reader knows how to decrypt the rest.

Access control

A public-only key (fromPublicKey) can seal / write but cannot open, attempting to decrypt a sealed slot throws. This is the access boundary used by the CloudReader: give a collaborator the public key and they can write data for the prism, but only the secret holder can read the sealed slots.

Copyright © 2026 DataPrism.