Switch from noble-secp256k1 to noble-curves
This commit is contained in:
parent
f17ab41d72
commit
204ae0eff1
11
event.ts
11
event.ts
|
@ -1,5 +1,6 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {schnorr} from '@noble/curves/secp256k1'
|
||||||
import {sha256} from '@noble/hashes/sha256'
|
import {sha256} from '@noble/hashes/sha256'
|
||||||
|
import {bytesToHex} from '@noble/hashes/utils'
|
||||||
|
|
||||||
import {utf8Encoder} from './utils'
|
import {utf8Encoder} from './utils'
|
||||||
import {getPublicKey} from './keys'
|
import {getPublicKey} from './keys'
|
||||||
|
@ -78,7 +79,7 @@ export function serializeEvent(evt: UnsignedEvent): string {
|
||||||
|
|
||||||
export function getEventHash(event: UnsignedEvent): string {
|
export function getEventHash(event: UnsignedEvent): string {
|
||||||
let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)))
|
let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)))
|
||||||
return secp256k1.utils.bytesToHex(eventHash)
|
return bytesToHex(eventHash)
|
||||||
}
|
}
|
||||||
|
|
||||||
const isRecord = (obj: unknown): obj is Record<string, unknown> => obj instanceof Object
|
const isRecord = (obj: unknown): obj is Record<string, unknown> => obj instanceof Object
|
||||||
|
@ -104,7 +105,7 @@ export function validateEvent<T>(event: T): event is T & UnsignedEvent {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function verifySignature(event: Event): boolean {
|
export function verifySignature(event: Event): boolean {
|
||||||
return secp256k1.schnorr.verifySync(
|
return schnorr.verify(
|
||||||
event.sig,
|
event.sig,
|
||||||
getEventHash(event),
|
getEventHash(event),
|
||||||
event.pubkey
|
event.pubkey
|
||||||
|
@ -112,7 +113,7 @@ export function verifySignature(event: Event): boolean {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function signEvent(event: UnsignedEvent, key: string): string {
|
export function signEvent(event: UnsignedEvent, key: string): string {
|
||||||
return secp256k1.utils.bytesToHex(
|
return bytesToHex(
|
||||||
secp256k1.schnorr.signSync(getEventHash(event), key)
|
schnorr.sign(getEventHash(event), key)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
9
index.ts
9
index.ts
|
@ -17,12 +17,3 @@ export * as nip57 from './nip57'
|
||||||
|
|
||||||
export * as fj from './fakejson'
|
export * as fj from './fakejson'
|
||||||
export * as utils from './utils'
|
export * as utils from './utils'
|
||||||
|
|
||||||
// monkey patch secp256k1
|
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
|
||||||
import {hmac} from '@noble/hashes/hmac'
|
|
||||||
import {sha256} from '@noble/hashes/sha256'
|
|
||||||
secp256k1.utils.hmacSha256Sync = (key, ...msgs) =>
|
|
||||||
hmac(sha256, key, secp256k1.utils.concatBytes(...msgs))
|
|
||||||
secp256k1.utils.sha256Sync = (...msgs) =>
|
|
||||||
sha256(secp256k1.utils.concatBytes(...msgs))
|
|
||||||
|
|
7
keys.ts
7
keys.ts
|
@ -1,9 +1,10 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {schnorr} from '@noble/curves/secp256k1'
|
||||||
|
import {bytesToHex} from '@noble/hashes/utils'
|
||||||
|
|
||||||
export function generatePrivateKey(): string {
|
export function generatePrivateKey(): string {
|
||||||
return secp256k1.utils.bytesToHex(secp256k1.utils.randomPrivateKey())
|
return bytesToHex(schnorr.utils.randomPrivateKey())
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPublicKey(privateKey: string): string {
|
export function getPublicKey(privateKey: string): string {
|
||||||
return secp256k1.utils.bytesToHex(secp256k1.schnorr.getPublicKey(privateKey))
|
return bytesToHex(schnorr.getPublicKey(privateKey))
|
||||||
}
|
}
|
||||||
|
|
2
nip04.ts
2
nip04.ts
|
@ -1,5 +1,5 @@
|
||||||
import {randomBytes} from '@noble/hashes/utils'
|
import {randomBytes} from '@noble/hashes/utils'
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {secp256k1} from '@noble/curves/secp256k1'
|
||||||
import {base64} from '@scure/base'
|
import {base64} from '@scure/base'
|
||||||
|
|
||||||
import {utf8Decoder, utf8Encoder} from './utils'
|
import {utf8Decoder, utf8Encoder} from './utils'
|
||||||
|
|
4
nip06.ts
4
nip06.ts
|
@ -1,4 +1,4 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {bytesToHex} from '@noble/hashes/utils'
|
||||||
import {wordlist} from '@scure/bip39/wordlists/english.js'
|
import {wordlist} from '@scure/bip39/wordlists/english.js'
|
||||||
import {
|
import {
|
||||||
generateMnemonic,
|
generateMnemonic,
|
||||||
|
@ -14,7 +14,7 @@ export function privateKeyFromSeedWords(
|
||||||
let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase))
|
let root = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic, passphrase))
|
||||||
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey
|
let privateKey = root.derive(`m/44'/1237'/0'/0/0`).privateKey
|
||||||
if (!privateKey) throw new Error('could not derive private key')
|
if (!privateKey) throw new Error('could not derive private key')
|
||||||
return secp256k1.utils.bytesToHex(privateKey)
|
return bytesToHex(privateKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateSeedWords(): string {
|
export function generateSeedWords(): string {
|
||||||
|
|
4
nip13.ts
4
nip13.ts
|
@ -1,8 +1,8 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {hexToBytes} from '@noble/hashes/utils'
|
||||||
|
|
||||||
/** Get POW difficulty from a Nostr hex ID. */
|
/** Get POW difficulty from a Nostr hex ID. */
|
||||||
export function getPow(id: string): number {
|
export function getPow(id: string): number {
|
||||||
return getLeadingZeroBits(secp256k1.utils.hexToBytes(id))
|
return getLeadingZeroBits(hexToBytes(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
26
nip19.ts
26
nip19.ts
|
@ -1,4 +1,4 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {bytesToHex, concatBytes, hexToBytes} from '@noble/hashes/utils'
|
||||||
import {bech32} from '@scure/base'
|
import {bech32} from '@scure/base'
|
||||||
|
|
||||||
import {utf8Decoder, utf8Encoder} from './utils'
|
import {utf8Decoder, utf8Encoder} from './utils'
|
||||||
|
@ -39,7 +39,7 @@ export function decode(nip19: string): {
|
||||||
return {
|
return {
|
||||||
type: 'nprofile',
|
type: 'nprofile',
|
||||||
data: {
|
data: {
|
||||||
pubkey: secp256k1.utils.bytesToHex(tlv[0][0]),
|
pubkey: bytesToHex(tlv[0][0]),
|
||||||
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : []
|
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,10 @@ export function decode(nip19: string): {
|
||||||
return {
|
return {
|
||||||
type: 'nevent',
|
type: 'nevent',
|
||||||
data: {
|
data: {
|
||||||
id: secp256k1.utils.bytesToHex(tlv[0][0]),
|
id: bytesToHex(tlv[0][0]),
|
||||||
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : [],
|
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : [],
|
||||||
author: tlv[2]?.[0]
|
author: tlv[2]?.[0]
|
||||||
? secp256k1.utils.bytesToHex(tlv[2][0])
|
? bytesToHex(tlv[2][0])
|
||||||
: undefined
|
: undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,8 +75,8 @@ export function decode(nip19: string): {
|
||||||
type: 'naddr',
|
type: 'naddr',
|
||||||
data: {
|
data: {
|
||||||
identifier: utf8Decoder.decode(tlv[0][0]),
|
identifier: utf8Decoder.decode(tlv[0][0]),
|
||||||
pubkey: secp256k1.utils.bytesToHex(tlv[2][0]),
|
pubkey: bytesToHex(tlv[2][0]),
|
||||||
kind: parseInt(secp256k1.utils.bytesToHex(tlv[3][0]), 16),
|
kind: parseInt(bytesToHex(tlv[3][0]), 16),
|
||||||
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : []
|
relays: tlv[1] ? tlv[1].map(d => utf8Decoder.decode(d)) : []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ export function decode(nip19: string): {
|
||||||
case 'nsec':
|
case 'nsec':
|
||||||
case 'npub':
|
case 'npub':
|
||||||
case 'note':
|
case 'note':
|
||||||
return {type: prefix, data: secp256k1.utils.bytesToHex(data)}
|
return {type: prefix, data: bytesToHex(data)}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new Error(`unknown prefix ${prefix}`)
|
throw new Error(`unknown prefix ${prefix}`)
|
||||||
|
@ -132,14 +132,14 @@ export function noteEncode(hex: string): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
function encodeBytes(prefix: string, hex: string): string {
|
function encodeBytes(prefix: string, hex: string): string {
|
||||||
let data = secp256k1.utils.hexToBytes(hex)
|
let data = hexToBytes(hex)
|
||||||
let words = bech32.toWords(data)
|
let words = bech32.toWords(data)
|
||||||
return bech32.encode(prefix, words, Bech32MaxSize)
|
return bech32.encode(prefix, words, Bech32MaxSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function nprofileEncode(profile: ProfilePointer): string {
|
export function nprofileEncode(profile: ProfilePointer): string {
|
||||||
let data = encodeTLV({
|
let data = encodeTLV({
|
||||||
0: [secp256k1.utils.hexToBytes(profile.pubkey)],
|
0: [hexToBytes(profile.pubkey)],
|
||||||
1: (profile.relays || []).map(url => utf8Encoder.encode(url))
|
1: (profile.relays || []).map(url => utf8Encoder.encode(url))
|
||||||
})
|
})
|
||||||
let words = bech32.toWords(data)
|
let words = bech32.toWords(data)
|
||||||
|
@ -148,9 +148,9 @@ export function nprofileEncode(profile: ProfilePointer): string {
|
||||||
|
|
||||||
export function neventEncode(event: EventPointer): string {
|
export function neventEncode(event: EventPointer): string {
|
||||||
let data = encodeTLV({
|
let data = encodeTLV({
|
||||||
0: [secp256k1.utils.hexToBytes(event.id)],
|
0: [hexToBytes(event.id)],
|
||||||
1: (event.relays || []).map(url => utf8Encoder.encode(url)),
|
1: (event.relays || []).map(url => utf8Encoder.encode(url)),
|
||||||
2: event.author ? [secp256k1.utils.hexToBytes(event.author)] : []
|
2: event.author ? [hexToBytes(event.author)] : []
|
||||||
})
|
})
|
||||||
let words = bech32.toWords(data)
|
let words = bech32.toWords(data)
|
||||||
return bech32.encode('nevent', words, Bech32MaxSize)
|
return bech32.encode('nevent', words, Bech32MaxSize)
|
||||||
|
@ -163,7 +163,7 @@ export function naddrEncode(addr: AddressPointer): string {
|
||||||
let data = encodeTLV({
|
let data = encodeTLV({
|
||||||
0: [utf8Encoder.encode(addr.identifier)],
|
0: [utf8Encoder.encode(addr.identifier)],
|
||||||
1: (addr.relays || []).map(url => utf8Encoder.encode(url)),
|
1: (addr.relays || []).map(url => utf8Encoder.encode(url)),
|
||||||
2: [secp256k1.utils.hexToBytes(addr.pubkey)],
|
2: [hexToBytes(addr.pubkey)],
|
||||||
3: [new Uint8Array(kind)]
|
3: [new Uint8Array(kind)]
|
||||||
})
|
})
|
||||||
let words = bech32.toWords(data)
|
let words = bech32.toWords(data)
|
||||||
|
@ -191,5 +191,5 @@ function encodeTLV(tlv: TLV): Uint8Array {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
return secp256k1.utils.concatBytes(...entries)
|
return concatBytes(...entries)
|
||||||
}
|
}
|
||||||
|
|
9
nip26.ts
9
nip26.ts
|
@ -1,4 +1,5 @@
|
||||||
import * as secp256k1 from '@noble/secp256k1'
|
import {schnorr} from '@noble/curves/secp256k1'
|
||||||
|
import {bytesToHex} from '@noble/hashes/utils'
|
||||||
import {sha256} from '@noble/hashes/sha256'
|
import {sha256} from '@noble/hashes/sha256'
|
||||||
|
|
||||||
import {Event} from './event'
|
import {Event} from './event'
|
||||||
|
@ -36,8 +37,8 @@ export function createDelegation(
|
||||||
utf8Encoder.encode(`nostr:delegation:${parameters.pubkey}:${cond}`)
|
utf8Encoder.encode(`nostr:delegation:${parameters.pubkey}:${cond}`)
|
||||||
)
|
)
|
||||||
|
|
||||||
let sig = secp256k1.utils.bytesToHex(
|
let sig = bytesToHex(
|
||||||
secp256k1.schnorr.signSync(sighash, privateKey)
|
schnorr.sign(sighash, privateKey)
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -84,7 +85,7 @@ export function getDelegator(event: Event): string | null {
|
||||||
let sighash = sha256(
|
let sighash = sha256(
|
||||||
utf8Encoder.encode(`nostr:delegation:${event.pubkey}:${cond}`)
|
utf8Encoder.encode(`nostr:delegation:${event.pubkey}:${cond}`)
|
||||||
)
|
)
|
||||||
if (!secp256k1.schnorr.verifySync(sig, sighash, pubkey)) return null
|
if (!schnorr.verify(sig, sighash, pubkey)) return null
|
||||||
|
|
||||||
return pubkey
|
return pubkey
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
},
|
},
|
||||||
"license": "Public domain",
|
"license": "Public domain",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@noble/hashes": "1.2.0",
|
"@noble/curves": "1.0.0",
|
||||||
"@noble/secp256k1": "1.7.0",
|
"@noble/hashes": "1.3.0",
|
||||||
"@scure/base": "1.1.1",
|
"@scure/base": "1.1.1",
|
||||||
"@scure/bip32": "1.1.4",
|
"@scure/bip32": "1.3.0",
|
||||||
"@scure/bip39": "1.1.1"
|
"@scure/bip39": "1.2.0"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"decentralization",
|
"decentralization",
|
||||||
|
|
Loading…
Reference in New Issue