From c78bd4cef11d76fd5aa1add31e42cbdc5da1c6ea Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 15 Aug 2023 11:40:54 -0300 Subject: [PATCH] encoding implementation doesn't require complicate TLV parsing. --- 44.md | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/44.md b/44.md index 1ff5a8a1..da840593 100644 --- a/44.md +++ b/44.md @@ -30,7 +30,7 @@ Example: Encrypting the message `hello` from Alice to Bob results in the base-64 encoded tlv payload: ``` -AAEBARgeI8gcP/4mnw3mKgtMvD8aGYUnGBlhopoCBd94Ev9i +AZKyMIHbfVYFlAAK7Ci5wuM5GFOLaeI7LQKDzWJY ``` # Other Notes @@ -47,7 +47,7 @@ This encryption scheme replaces the one described in NIP-04, which is not secure import {xchacha20} from "@noble/ciphers/chacha" import {secp256k1} from "@noble/curves/secp256k1" import {sha256} from "@noble/hashes/sha256" -import {randomBytes, concatBytes} from "@noble/hashes/utils" +import {randomBytes} from "@noble/hashes/utils" import {base64} from "@scure/base" export const utf8Decoder = new TextDecoder() @@ -100,44 +100,24 @@ export function encrypt(privkey: string, pubkey: string, text: string, v = 1) { const nonce = randomBytes(24) const plaintext = utf8Encoder.encode(text) const ciphertext = xchacha20(key, nonce, plaintext) - const tlv = encodeTLV({ - 0: [new Uint8Array([1])], - 1: [nonce], - 2: [ciphertext] - }) - return base64.encode(tlv) + const payload = new Uint8Array(1 + 24 + ciphertext.length) + payload.set([version], 0) + payload.set(nonce, 1) + payload.set(ciphertext, 1 + 24) + + return base64.encode(payload) } export function decrypt(privkey: string, pubkey: string, payload: string) { - let byteArray - try { - byteArray = base64.decode(payload) - } catch (e) { - throw new Error(`NIP44: failed to base64 decode payload: ${e}`) + const payload = base64.decode(blob) + if (payload[0] !== 1) { + throw new Error('NIP44: unknown encryption version') } - let tlv - try { - tlv = parseTLV(byteArray) - } catch (e) { - throw new Error(`NIP44: failed to decode tlv: ${e}`) - } + const nonce = payload.subarray(1, 25) + const ciphertext = payload.subarray(25) - if (tlv[0]?.[0]?.[0] !== 1) { - throw new Error(`NIP44: invalid version: ${tlv[0]?.[0]?.[0]}`) - } - - if (tlv[1]?.[0]?.length !== 24) { - throw new Error(`NIP44: invalid nonce: ${tlv[1]?.[0]}`) - } - - if (!tlv[2]?.[0]) { - throw new Error(`NIP44: missing ciphertext`) - } - - const nonce = tlv[1][0] - const ciphertext = tlv[2][0] const key = getSharedSecret(privkey, pubkey) const plaintext = xchacha20(key, nonce, ciphertext)