mirror of
https://github.com/nbd-wtf/nostr-tools.git
synced 2025-12-08 16:28:49 +00:00
Add support for nip44
This commit is contained in:
1
index.ts
1
index.ts
@@ -19,6 +19,7 @@ export * as nip27 from './nip27.ts'
|
|||||||
export * as nip28 from './nip28.ts'
|
export * as nip28 from './nip28.ts'
|
||||||
export * as nip39 from './nip39.ts'
|
export * as nip39 from './nip39.ts'
|
||||||
export * as nip42 from './nip42.ts'
|
export * as nip42 from './nip42.ts'
|
||||||
|
export * as nip44 from './nip44.ts'
|
||||||
export * as nip57 from './nip57.ts'
|
export * as nip57 from './nip57.ts'
|
||||||
export * as nip98 from './nip98.ts'
|
export * as nip98 from './nip98.ts'
|
||||||
|
|
||||||
|
|||||||
19
nip44.test.ts
Normal file
19
nip44.test.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import crypto from 'node:crypto'
|
||||||
|
|
||||||
|
import {encrypt, decrypt} 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)
|
||||||
|
|
||||||
|
expect(await decrypt(sk2, pk1, await encrypt(sk1, pk2, 'hello'))).toEqual(
|
||||||
|
'hello'
|
||||||
|
)
|
||||||
|
})
|
||||||
57
nip44.ts
Normal file
57
nip44.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import {base64} from '@scure/base'
|
||||||
|
import {randomBytes} from '@noble/hashes/utils'
|
||||||
|
import {secp256k1} from '@noble/curves/secp256k1'
|
||||||
|
import {sha256} from '@noble/hashes/sha256'
|
||||||
|
import {xchacha20} from '@noble/ciphers/chacha'
|
||||||
|
|
||||||
|
import {utf8Decoder, utf8Encoder} from './utils.ts'
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
if (typeof crypto !== 'undefined' && !crypto.subtle && crypto.webcrypto) {
|
||||||
|
// @ts-ignore
|
||||||
|
crypto.subtle = crypto.webcrypto.subtle
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getSharedSecret = (privkey: string, pubkey: string): Uint8Array =>
|
||||||
|
sha256(secp256k1.getSharedSecret(privkey, '02' + pubkey).subarray(1, 33))
|
||||||
|
|
||||||
|
export function encrypt(privkey: string, pubkey: string, text: string, v = 1) {
|
||||||
|
if (v !== 1) {
|
||||||
|
throw new Error('NIP44: unknown encryption version')
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = getSharedSecret(privkey, pubkey)
|
||||||
|
const nonce = randomBytes(24)
|
||||||
|
const plaintext = utf8Encoder.encode(text)
|
||||||
|
const ciphertext = xchacha20(key, nonce, plaintext)
|
||||||
|
|
||||||
|
return JSON.stringify({
|
||||||
|
ciphertext: base64.encode(ciphertext),
|
||||||
|
nonce: base64.encode(nonce),
|
||||||
|
v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function decrypt(privkey: string, pubkey: string, payload: string) {
|
||||||
|
let data
|
||||||
|
try {
|
||||||
|
data = JSON.parse(payload) as {
|
||||||
|
ciphertext: string
|
||||||
|
nonce: string
|
||||||
|
v: number
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
throw new Error('NIP44: failed to parse payload')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.v !== 1) {
|
||||||
|
throw new Error('NIP44: unknown encryption version')
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = getSharedSecret(privkey, pubkey)
|
||||||
|
const nonce = base64.decode(data.nonce)
|
||||||
|
const ciphertext = base64.decode(data.ciphertext)
|
||||||
|
const plaintext = xchacha20(key, nonce, ciphertext)
|
||||||
|
|
||||||
|
return utf8Decoder.decode(plaintext)
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/curves": "1.1.0",
|
"@noble/curves": "1.1.0",
|
||||||
"@noble/hashes": "1.3.1",
|
"@noble/hashes": "1.3.1",
|
||||||
|
"@noble/ciphers": "^0.2.0",
|
||||||
"@scure/base": "1.1.1",
|
"@scure/base": "1.1.1",
|
||||||
"@scure/bip32": "1.3.1",
|
"@scure/bip32": "1.3.1",
|
||||||
"@scure/bip39": "1.2.1"
|
"@scure/bip39": "1.2.1"
|
||||||
|
|||||||
44
yarn.lock
44
yarn.lock
@@ -705,14 +705,24 @@
|
|||||||
"@jridgewell/resolve-uri" "3.1.0"
|
"@jridgewell/resolve-uri" "3.1.0"
|
||||||
"@jridgewell/sourcemap-codec" "1.4.14"
|
"@jridgewell/sourcemap-codec" "1.4.14"
|
||||||
|
|
||||||
"@noble/curves@1.0.0", "@noble/curves@~1.0.0":
|
"@noble/ciphers@^0.2.0":
|
||||||
version "1.0.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.0.0.tgz#e40be8c7daf088aaf291887cbc73f43464a92932"
|
resolved "https://registry.yarnpkg.com/@noble/ciphers/-/ciphers-0.2.0.tgz#a12cda60f3cf1ab5d7c77068c3711d2366649ed7"
|
||||||
integrity sha512-2upgEu0iLiDVDZkNLeFV2+ht0BAVgQnEmCk6JsOch9Rp8xfkMCbvbAZlA2pBHQc73dbl+vFOXfqkf4uemdn0bw==
|
integrity sha512-6YBxJDAapHSdd3bLDv6x2wRPwq4QFMUaB3HvljNBUTThDd12eSm7/3F+2lnfzx2jvM+S6Nsy0jEt9QbPqSwqRw==
|
||||||
dependencies:
|
|
||||||
"@noble/hashes" "1.3.0"
|
|
||||||
|
|
||||||
"@noble/hashes@1.3.0", "@noble/hashes@~1.3.0":
|
"@noble/curves@1.1.0", "@noble/curves@~1.1.0":
|
||||||
|
version "1.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d"
|
||||||
|
integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==
|
||||||
|
dependencies:
|
||||||
|
"@noble/hashes" "1.3.1"
|
||||||
|
|
||||||
|
"@noble/hashes@1.3.1", "@noble/hashes@~1.3.1":
|
||||||
|
version "1.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9"
|
||||||
|
integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
|
||||||
|
|
||||||
|
"@noble/hashes@~1.3.0":
|
||||||
version "1.3.0"
|
version "1.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
|
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1"
|
||||||
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
|
integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg==
|
||||||
@@ -743,19 +753,19 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938"
|
||||||
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA==
|
||||||
|
|
||||||
"@scure/bip32@1.3.0":
|
"@scure/bip32@1.3.1":
|
||||||
version "1.3.0"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.0.tgz#6c8d980ef3f290987736acd0ee2e0f0d50068d87"
|
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10"
|
||||||
integrity sha512-bcKpo1oj54hGholplGLpqPHRbIsnbixFtc06nwuNM5/dwSXOq/AAYoIBRsBmnZJSdfeNW5rnff7NTAz3ZCqR9Q==
|
integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/curves" "~1.0.0"
|
"@noble/curves" "~1.1.0"
|
||||||
"@noble/hashes" "~1.3.0"
|
"@noble/hashes" "~1.3.1"
|
||||||
"@scure/base" "~1.1.0"
|
"@scure/base" "~1.1.0"
|
||||||
|
|
||||||
"@scure/bip39@1.2.0":
|
"@scure/bip39@1.2.1":
|
||||||
version "1.2.0"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.0.tgz#a207e2ef96de354de7d0002292ba1503538fc77b"
|
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a"
|
||||||
integrity sha512-SX/uKq52cuxm4YFXWFaVByaSHJh2w3BnokVSeUJVCv6K7WulT9u2BuNRBhuFl8vAuYnzx9bEu9WgpcNYTrYieg==
|
integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@noble/hashes" "~1.3.0"
|
"@noble/hashes" "~1.3.0"
|
||||||
"@scure/base" "~1.1.0"
|
"@scure/base" "~1.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user