Encrypted, ephemeral, private memos on atproto
at main 27 lines 984 B view raw
1import { XWing } from "@noble/post-quantum/hybrid.js"; 2import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; 3import { randomBytes } from "@noble/hashes/utils.js"; 4import { sha3_512 } from "@noble/hashes/sha3.js"; 5import type { EncryptedPayload } from "./types.ts"; 6 7export function encryptText( 8 publicKey: Uint8Array, 9 text: string, 10): EncryptedPayload { 11 // Create a copy of the public key to prevent mutation by XWing.encapsulate 12 const publicKeyCopy = new Uint8Array(publicKey); 13 const { cipherText, sharedSecret } = XWing.encapsulate(publicKeyCopy); 14 const nonce = randomBytes(24); 15 const contentBytes = new TextEncoder().encode(text); 16 const cipher = xchacha20poly1305(sharedSecret, nonce); 17 const content = cipher.encrypt(contentBytes); 18 const hash = sha3_512(contentBytes); 19 20 return { 21 cipherText: cipherText.toBase64(), 22 content: content.toBase64(), 23 nonce: nonce.toBase64(), 24 hash: hash.toBase64(), 25 length: contentBytes.byteLength, 26 }; 27}