mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-13 02:18:51 +00:00
Implement NIP-44: secure versioned replacement for NIP4 (#221)
This commit is contained in:
@@ -1,21 +1,75 @@
|
||||
import crypto from 'node:crypto'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { encrypt, decrypt, utils } from './nip44.ts'
|
||||
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
|
||||
import { v2 as vectors } from './nip44.vectors.json'
|
||||
import { getPublicKey } from './keys.ts'
|
||||
|
||||
import { encrypt, decrypt, getSharedSecret } from './nip44.ts'
|
||||
import { getPublicKey, generatePrivateKey } from './keys.ts'
|
||||
|
||||
// @ts-ignore
|
||||
// eslint-disable-next-line no-undef
|
||||
globalThis.crypto = crypto
|
||||
|
||||
test('encrypt and decrypt message', async () => {
|
||||
let sk1 = generatePrivateKey()
|
||||
let sk2 = generatePrivateKey()
|
||||
let pk1 = getPublicKey(sk1)
|
||||
let pk2 = getPublicKey(sk2)
|
||||
let sharedKey1 = getSharedSecret(sk1, pk2)
|
||||
let sharedKey2 = getSharedSecret(sk2, pk1)
|
||||
|
||||
expect(decrypt(hexToBytes(sk1), encrypt(hexToBytes(sk1), 'hello'))).toEqual('hello')
|
||||
expect(decrypt(sharedKey2, encrypt(sharedKey1, 'hello'))).toEqual('hello')
|
||||
test('NIP44: valid_sec', async () => {
|
||||
for (const v of vectors.valid_sec) {
|
||||
const pub2 = getPublicKey(v.sec2)
|
||||
const key = utils.v2.getConversationKey(v.sec1, pub2)
|
||||
expect(bytesToHex(key)).toEqual(v.shared)
|
||||
const ciphertext = encrypt(key, v.plaintext, { salt: hexToBytes(v.salt) })
|
||||
expect(ciphertext).toEqual(v.ciphertext)
|
||||
const decrypted = decrypt(key, ciphertext)
|
||||
expect(decrypted).toEqual(v.plaintext)
|
||||
}
|
||||
})
|
||||
|
||||
test('NIP44: valid_pub', async () => {
|
||||
for (const v of vectors.valid_pub) {
|
||||
const key = utils.v2.getConversationKey(v.sec1, v.pub2)
|
||||
expect(bytesToHex(key)).toEqual(v.shared)
|
||||
const ciphertext = encrypt(key, v.plaintext, { salt: hexToBytes(v.salt) })
|
||||
expect(ciphertext).toEqual(v.ciphertext)
|
||||
const decrypted = decrypt(key, ciphertext)
|
||||
expect(decrypted).toEqual(v.plaintext)
|
||||
}
|
||||
})
|
||||
|
||||
test('NIP44: invalid', async () => {
|
||||
for (const v of vectors.invalid) {
|
||||
expect(() => {
|
||||
const key = utils.v2.getConversationKey(v.sec1, v.pub2)
|
||||
const ciphertext = decrypt(key, v.plaintext)
|
||||
}).toThrowError()
|
||||
}
|
||||
})
|
||||
|
||||
test('NIP44: invalid_conversation_key', async () => {
|
||||
for (const v of vectors.invalid_conversation_key) {
|
||||
expect(() => {
|
||||
const key = utils.v2.getConversationKey(v.sec1, v.pub2)
|
||||
const ciphertext = encrypt(key, v.plaintext)
|
||||
}).toThrowError()
|
||||
}
|
||||
})
|
||||
|
||||
test('NIP44: v1 calcPadding', () => {
|
||||
for (const [len, shouldBePaddedTo] of vectors.padding) {
|
||||
const actual = utils.v2.calcPadding(len)
|
||||
expect(actual).toEqual(shouldBePaddedTo)
|
||||
}
|
||||
})
|
||||
|
||||
// To re-generate vectors and produce new ones:
|
||||
// Create regen.mjs with this content:
|
||||
// import {getPublicKey, nip44} from './lib/esm/nostr.mjs'
|
||||
// import {bytesToHex, hexToBytes} from '@noble/hashes/utils'
|
||||
// import vectors from './nip44.vectors.json' assert { type: "json" };
|
||||
// function genVectors(v) {
|
||||
// const pub2 = v.pub2 ?? getPublicKey(v.sec2);
|
||||
// let sharedKey = nip44.utils.v2.getConversationKey(v.sec1, pub2)
|
||||
// let ciphertext = nip44.encrypt(sharedKey, v.plaintext, { salt: hexToBytes(v.salt) })
|
||||
// console.log({
|
||||
// sec1: v.sec1,
|
||||
// pub2: pub2,
|
||||
// sharedKey: bytesToHex(sharedKey),
|
||||
// salt: v.salt,
|
||||
// plaintext: v.plaintext,
|
||||
// ciphertext
|
||||
// })
|
||||
// }
|
||||
// for (let v of vectors.valid_sec) genVectors(v);
|
||||
// for (let v of vectors.valid_pub) genVectors(v);
|
||||
// const padded = concatBytes(utils.v2.pad(plaintext), new Uint8Array(250))
|
||||
// const mac = randomBytes(32)
|
||||
|
||||
Reference in New Issue
Block a user