/** * Benchmark: AES-256-GCM (Web Crypto) vs NaCl SecretBox * Tests encryption/decryption performance across payload sizes */ import { aesEncrypt, aesDecrypt, generateSymmetricKey, generateKeyPair, encryptForRecipient, decryptFromSender, shareDocKey, receiveDocKey, } from './mit-crypto.js' function generateTestData(size: number): Uint8Array { const data = new Uint8Array(size) // getRandomValues has 64KB limit, fill in chunks for (let offset = 0; offset < size; offset += 65536) { const chunk = Math.min(65536, size - offset) crypto.getRandomValues(data.subarray(offset, offset + chunk)) } return data } const encoder = new TextEncoder() const decoder = new TextDecoder() async function benchmark(name: string, fn: () => Promise, iterations: number = 1000) { // Warmup for (let i = 0; i < 10; i++) await fn() const start = performance.now() for (let i = 0; i < iterations; i++) await fn() const elapsed = performance.now() - start console.log(`${name}: ${(elapsed / iterations).toFixed(3)}ms avg (${iterations} iterations)`) } async function main() { console.log('=== rStack Crypto Primitives Benchmark ===\n') // ─── Symmetric Encryption ─── console.log('--- Symmetric Encryption (AES-256-GCM) ---') const key = generateSymmetricKey() for (const size of [100, 1_000, 10_000, 100_000]) { const data = generateTestData(size) await benchmark(` Encrypt ${size.toLocaleString()}B`, async () => { await aesEncrypt(key, data) }) const encrypted = await aesEncrypt(key, data) await benchmark(` Decrypt ${size.toLocaleString()}B`, async () => { await aesDecrypt(key, encrypted) }) } // ─── Key Exchange ─── console.log('\n--- Key Exchange (x25519 ECDH) ---') const alice = generateKeyPair() const bob = generateKeyPair() await benchmark(' Generate key pair', async () => { generateKeyPair() }) // ─── ECIES Encryption ─── console.log('\n--- ECIES Encryption (x25519 + AES-256-GCM) ---') const message = encoder.encode('This is a secret document encryption key - 32 bytes!') await benchmark(' Encrypt for recipient', async () => { await encryptForRecipient(message, bob.publicKey, alice.privateKey) }) const { ciphertext, ephemeralPublicKey } = await encryptForRecipient( message, bob.publicKey, alice.privateKey ) await benchmark(' Decrypt from sender', async () => { await decryptFromSender(ciphertext, ephemeralPublicKey, bob.privateKey) }) // ─── Document Key Sharing ─── console.log('\n--- Document Key Sharing ---') const docKey = generateSymmetricKey() await benchmark(' Share doc key', async () => { await shareDocKey(docKey, bob.publicKey, alice.privateKey) }) const shared = await shareDocKey(docKey, bob.publicKey, alice.privateKey) await benchmark(' Receive doc key', async () => { await receiveDocKey(shared.encryptedKey, shared.ephemeralPublicKey, bob.privateKey) }) // ─── End-to-End Roundtrip ─── console.log('\n--- Full Roundtrip: Note Encryption + Key Sharing ---') const noteContent = encoder.encode(JSON.stringify({ title: 'Secret Meeting Notes', content: '

Discussion about token allocation...

'.repeat(100), tags: ['dao', 'treasury', 'private'], })) await benchmark(' Full encrypt + share flow', async () => { // 1. Generate doc key const dk = generateSymmetricKey() // 2. Encrypt content const enc = await aesEncrypt(dk, noteContent) // 3. Share key with collaborator await shareDocKey(dk, bob.publicKey, alice.privateKey) }) await benchmark(' Full receive + decrypt flow', async () => { // Simulated received data const dk = generateSymmetricKey() const enc = await aesEncrypt(dk, noteContent) const sk = await shareDocKey(dk, bob.publicKey, alice.privateKey) // Actual measured flow const receivedKey = await receiveDocKey(sk.encryptedKey, sk.ephemeralPublicKey, bob.privateKey) await aesDecrypt(receivedKey, enc) }) // ─── Correctness Check ─── console.log('\n--- Correctness Verification ---') // Symmetric roundtrip const testData = encoder.encode('Hello, encrypted world!') const testKey = generateSymmetricKey() const testEncrypted = await aesEncrypt(testKey, testData) const testDecrypted = await aesDecrypt(testKey, testEncrypted) const symOk = decoder.decode(testDecrypted) === 'Hello, encrypted world!' console.log(` Symmetric roundtrip: ${symOk ? 'PASS' : 'FAIL'}`) // ECIES roundtrip const kp1 = generateKeyPair() const kp2 = generateKeyPair() const plaintext = encoder.encode('Secret message for key pair 2') const { ciphertext: ct, ephemeralPublicKey: epk } = await encryptForRecipient( plaintext, kp2.publicKey, kp1.privateKey ) const decrypted = await decryptFromSender(ct, epk, kp2.privateKey) const eciesOk = decoder.decode(decrypted) === 'Secret message for key pair 2' console.log(` ECIES roundtrip: ${eciesOk ? 'PASS' : 'FAIL'}`) // Doc key sharing roundtrip const origKey = generateSymmetricKey() const shareResult = await shareDocKey(origKey, kp2.publicKey, kp1.privateKey) const recoveredKey = await receiveDocKey( shareResult.encryptedKey, shareResult.ephemeralPublicKey, kp2.privateKey ) const keyOk = origKey.every((b, i) => b === recoveredKey[i]) console.log(` Doc key sharing roundtrip: ${keyOk ? 'PASS' : 'FAIL'}`) console.log('\nDone.') } main().catch(console.error)