Implementation Architectures
A) Hybrid: Off-chain Secrets + On-chain Commitments
Current implementation on Stacks blockhain
Storage:
Off-chain: encrypted payload (or encrypted “envelope”) stored on a controlled service (DB/object storage).
On-chain: commitment =
H(payload_bytes)(orH(ciphertext)), plus optional metadata (algo/version/mime/size).
Access / Reveal
Client signs a request (wallet signature).
Gateway verifies current NFT ownership on-chain, rate-limits, then returns the encrypted bytes (or a short-lived URL).
Client verifies:
H(received_payload) == on-chain commitment.
Answer verification (example: Seed Phrase Hunt)
Canonical answer stored encrypted (or as
H(answer||salt)).User submits answer → server checks correctness without publicly revealing plaintext (e.g., compare hashes/HMACs; or compare deterministic transforms).
Pros
Fast UX, low cost, chain-agnostic.
Strong integrity guarantee: server can’t “swap the secret” after mint without being caught.
Trade-offs
Availability and access control depend on the service (not fully trustless).
Privacy is off-chain (keys + delivery must be protected).
B) On-chain Commitments + On-chain “Claim” + Off-chain Key Release
Idea: keep payload encrypted off-chain (or even on-chain), but move the “right to reveal” and the audit trail on-chain. The secret is only unlocked when an on-chain condition is met (ownership + event + optional payment/proof).
Storage
Option 1: ciphertext stored off-chain; commitment on-chain.
Option 2: ciphertext stored on-chain (if small enough); commitment still on-chain.
Unlock flow
Owner calls an on-chain function:
claim-reveal(token-id)(orstart-reveal), emitting an event.Backend watches chain events and releases the decryption key (or envelope) to the owner only after seeing the on-chain claim.
Client decrypts locally and verifies commitment.
Pros
More “protocol-like”: reveal attempts are publicly auditable.
Stronger fairness for games: unlocks can be conditioned on on-chain actions (fees, deadlines, proofs-of-participation).
Still much simpler than ZK reencryption proofs.
Trade-offs
Still relies on a key release service (or MPC network) for confidentiality.
Requires indexer/event listener reliability.
C) Fully On-Chain (ciphertext + proofs on-chain)
Storage:
Ciphertext stored directly in contract storage
Master encryption key encrypted under owner's pubkey
All data verifiable on-chain
Transfer flow:
Seller re-encrypts master key under buyer's pubkey
Seller generates ElGamal re-encryption consistency proof (ZK proof)
Seller submits new ciphertext + proof on-chain
Contract verifies proof: "new ciphertext contains same master key"
If proof valid → transfer proceeds, payment released
Buyer decrypts master key with private key → decrypts secret
Proof verification:
verify_reencryption_proof( old_ciphertext, new_ciphertext, old_pubkey, new_pubkey, zk_proof ) -> bool
Pros:
Trustless (cryptographic guarantees, no escrow needed)
Maximum auditability (everything on-chain)
Prevents seller cheating (can't provide fake secret)
Cons:
Higher gas (proof verification + storage)
Requires chains with EC operations + ZK precompiles
More complex implementation
Last updated