Skip to main content

Privacy & Access Model

The v2 Encryption Scheme

When the SDK snapshots a memory bundle, it derives the encryption key directly from the content:

key = keccak256(plaintext JSON)[0:32] // first 32 bytes
contentHash = keccak256(plaintext JSON) // full 32 bytes, stored on-chain

The bundle is encrypted with NaCl secretbox using this key, then uploaded to 0G Storage. The contentHash is stored on-chain in MemoryRegistry.

This means: anyone who can read the contentHash on-chain can derive the decryption key and decrypt the bundle.

The v2: prefix on a storageURI signals that this scheme is in use. The SDK uses the v2 scheme for all new tokens.


There Is No Cryptographic Confidentiality in v1

This is intentional, not an oversight.

The design goal is a verifiable marketplace: before buying or renting a memory token, a potential buyer can decrypt the bundle and inspect its contents. The contentHash on-chain is the proof that the decrypted content is authentic — the keccak256 of the plaintext must match.

What this means in practice:

  • Anyone with an RPC connection to 0G Chain can read contentHash for any token
  • Anyone who can read contentHash can decrypt the corresponding bundle from 0G Storage
  • There is no access control at the encryption layer in v1

Do not store secrets, private keys, or sensitive personal data in a v1 memory bundle.


The v1 Legacy Scheme

Tokens minted before the v2 upgrade use a storageURI without the v2: prefix (e.g., 0g://rootHash). These use a different key derivation:

key = keccak256(walletAddress + contentHash)

Only the original creator's wallet address is known, so only the creator can decrypt v1 tokens. These tokens are not decryptable by buyers before purchase — which made marketplace verification impossible and motivated the v2 redesign.

The SDK detects the prefix and uses the appropriate decryption path automatically.


API-Level Access Control

The REST API adds a separate layer of access control on top of the encryption layer. The GET /api/memory/:tokenId endpoint is guarded by WalletAuthGuard:

  • The requester must sign a timestamp with their wallet (EIP-191 personal_sign)
  • The API verifies that the signing address is the current token owner or an active renter

This does not protect the bundle from anyone who queries the chain directly — it only gates the convenience API. See Authentication → for header format and signing details.


Roadmap: TEE-Based Key Escrow

The v2 roadmap addresses the confidentiality gap with a TEE (Trusted Execution Environment) key escrow model:

  • The encryption key is held inside a TEE, not derived from contentHash
  • The TEE releases the key only after confirming on-chain that payment has been received
  • This enables atomic key release: decryption key delivered if and only if payment is confirmed

Under this model, buyers cannot decrypt before purchase, and the royalty system can be enforced atomically (see Royalty →). The honor-system dependency is removed.

This is not yet implemented in v1.


Next: Quick Start →