-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
The sell() function in packages/skill/src/skill.ts has critical issues with encryption key handling that make the escrow workflow non-functional.
Problems
1. Encryption key not stored after generation
At line 149, a random encryption key is generated:
const encryptionKey = ethers.randomBytes(32);But at lines 197-198, there's a TODO:
// TODO: Store encryption key securely for later release
// In production, use escrow keystore (encrypted, crash-recovery safe)Impact: After sell() returns, the encryption key is lost. The seller cannot reveal it to the buyer after escrow is funded.
2. Swarm-native encryption key embedded in reference
The uploadToSwarm() method (lines 366-392) uses Swarm-native encryption when encrypt: true:
if (encrypt) {
headers['Swarm-Encrypt'] = 'true';
}With Swarm-native encryption, the returned reference format is:
reference = content_hash + encryption_key (64 bytes + 32 bytes)
Impact: Anyone with the full swarmRef can decrypt the data immediately. There's no way to withhold the key for the escrow reveal phase.
3. Key mismatch in sell() workflow
sell() generates TWO different keys:
encryptionKeyat line 149 (never used for actual encryption)- Swarm-native key embedded in reference at line 153
The keyCommitment at line 169 is computed from the first key:
const keyCommitment = ethers.keccak256(encryptionKey);But this key has nothing to do with the Swarm-encrypted data!
Impact: Even if the seller reveals the committed key, it cannot decrypt the Swarm-encrypted data.
Expected Behavior
The escrow workflow should be:
- Seller encrypts data with key K (application-level encryption, NOT Swarm-native)
- Seller uploads encrypted blob to Swarm (without
Swarm-Encryptheader) - Seller creates escrow with
keyCommitment = hash(K) - Buyer funds escrow
- Seller reveals K on-chain
- Buyer downloads blob and decrypts with K
Suggested Fix
Option A: Don't use Swarm-native encryption for escrow
- Encrypt data with
encryptionKeybefore upload - Upload without
Swarm-Encrypt: true - Store
encryptionKeysecurely for later reveal
Option B: Split Swarm reference
- Upload with
Swarm-Encrypt: true - Split reference into
content_hash(share) andkey(reveal later) - Use the embedded key as the escrow key
Files Affected
packages/skill/src/skill.ts-sell()anduploadToSwarm()methods
Related
- The CLI (
sx escrows create) has a similar issue - it generates a random key unrelated to actual data encryption