1
1
import { sha256 } from "@noble/hashes/sha256" ;
2
- import * as secp from "./secp256k1" ;
2
+ import { mod } from "@noble/curves/abstract/modular" ;
3
+ import { secp256k1 } from "./secp256k1" ;
3
4
import { assertBool , assertBytes , hexToBytes , toHex } from "./utils" ;
4
5
5
6
// Use `secp256k1` module directly.
6
7
// This is a legacy compatibility layer for the npm package `secp256k1` via noble-secp256k1
7
8
9
+ const Point = secp256k1 . ProjectivePoint ;
10
+
8
11
function hexToNumber ( hex : string ) : bigint {
9
12
if ( typeof hex !== "string" ) {
10
13
throw new TypeError ( "hexToNumber: expected string, got " + typeof hex ) ;
@@ -17,9 +20,8 @@ const bytesToNumber = (bytes: Uint8Array) => hexToNumber(toHex(bytes));
17
20
const numberToHex = ( num : number | bigint ) =>
18
21
num . toString ( 16 ) . padStart ( 64 , "0" ) ;
19
22
const numberToBytes = ( num : number | bigint ) => hexToBytes ( numberToHex ( num ) ) ;
20
- const { mod } = secp . utils ;
21
23
22
- const ORDER = secp . CURVE . n ;
24
+ const ORDER = secp256k1 . CURVE . n ;
23
25
24
26
type Output = Uint8Array | ( ( len : number ) => Uint8Array ) ;
25
27
interface Signature {
@@ -44,11 +46,11 @@ function output(
44
46
45
47
function getSignature ( signature : Uint8Array ) {
46
48
assertBytes ( signature , 64 ) ;
47
- return secp . Signature . fromCompact ( signature ) ;
49
+ return secp256k1 . Signature . fromCompact ( signature ) ;
48
50
}
49
51
50
52
export function createPrivateKeySync ( ) : Uint8Array {
51
- return secp . utils . randomPrivateKey ( ) ;
53
+ return secp256k1 . utils . randomPrivateKey ( ) ;
52
54
}
53
55
54
56
export async function createPrivateKey ( ) : Promise < Uint8Array > {
@@ -57,7 +59,7 @@ export async function createPrivateKey(): Promise<Uint8Array> {
57
59
58
60
export function privateKeyVerify ( privateKey : Uint8Array ) : boolean {
59
61
assertBytes ( privateKey , 32 ) ;
60
- return secp . utils . isValidPrivateKey ( privateKey ) ;
62
+ return secp256k1 . utils . isValidPrivateKey ( privateKey ) ;
61
63
}
62
64
63
65
export function publicKeyCreate (
@@ -67,14 +69,14 @@ export function publicKeyCreate(
67
69
) : Uint8Array {
68
70
assertBytes ( privateKey , 32 ) ;
69
71
assertBool ( compressed ) ;
70
- const res = secp . getPublicKey ( privateKey , compressed ) ;
72
+ const res = secp256k1 . getPublicKey ( privateKey , compressed ) ;
71
73
return output ( out , compressed ? 33 : 65 , res ) ;
72
74
}
73
75
74
76
export function publicKeyVerify ( publicKey : Uint8Array ) : boolean {
75
77
assertBytes ( publicKey , 33 , 65 ) ;
76
78
try {
77
- secp . Point . fromHex ( publicKey ) ;
79
+ Point . fromHex ( publicKey ) ;
78
80
return true ;
79
81
} catch ( e ) {
80
82
return false ;
@@ -88,7 +90,7 @@ export function publicKeyConvert(
88
90
) : Uint8Array {
89
91
assertBytes ( publicKey , 33 , 65 ) ;
90
92
assertBool ( compressed ) ;
91
- const res = secp . Point . fromHex ( publicKey ) . toRawBytes ( compressed ) ;
93
+ const res = Point . fromHex ( publicKey ) . toRawBytes ( compressed ) ;
92
94
return output ( out , compressed ? 33 : 65 , res ) ;
93
95
}
94
96
@@ -110,11 +112,9 @@ export function ecdsaSign(
110
112
) {
111
113
throw new Error ( "Secp256k1: noncefn && data is unsupported" ) ;
112
114
}
113
- const [ signature , recid ] = secp . signSync ( msgHash , privateKey , {
114
- recovered : true ,
115
- der : false ,
116
- } ) ;
117
- return { signature : output ( out , 64 , signature ) , recid } ;
115
+ const sig = secp256k1 . sign ( msgHash , privateKey ) ;
116
+ const recid = sig . recovery ! ;
117
+ return { signature : output ( out , 64 , sig . toCompactRawBytes ( ) ) , recid } ;
118
118
}
119
119
120
120
export function ecdsaRecover (
@@ -126,8 +126,8 @@ export function ecdsaRecover(
126
126
) {
127
127
assertBytes ( msgHash , 32 ) ;
128
128
assertBool ( compressed ) ;
129
- const sign = getSignature ( signature ) . toHex ( ) ;
130
- const point = secp . Point . fromSignature ( msgHash , sign , recid ) ;
129
+ const sign = getSignature ( signature ) ;
130
+ const point = sign . addRecoveryBit ( recid ) . recoverPublicKey ( msgHash ) ;
131
131
return output ( out , compressed ? 33 : 65 , point . toRawBytes ( compressed ) ) ;
132
132
}
133
133
@@ -145,14 +145,15 @@ export function ecdsaVerify(
145
145
if ( r >= ORDER || s >= ORDER ) {
146
146
throw new Error ( "Cannot parse signature" ) ;
147
147
}
148
- const pub = secp . Point . fromHex ( publicKey ) ; // should not throw error
148
+ const pub = Point . fromHex ( publicKey ) ; // can throw error
149
+ pub ; // typescript
149
150
let sig ;
150
151
try {
151
152
sig = getSignature ( signature ) ;
152
153
} catch ( error ) {
153
154
return false ;
154
155
}
155
- return secp . verify ( sig , msgHash , pub ) ;
156
+ return secp256k1 . verify ( sig , msgHash , publicKey ) ;
156
157
}
157
158
158
159
export function privateKeyTweakAdd (
@@ -195,7 +196,7 @@ export function publicKeyNegate(
195
196
) {
196
197
assertBytes ( publicKey , 33 , 65 ) ;
197
198
assertBool ( compressed ) ;
198
- const point = secp . Point . fromHex ( publicKey ) . negate ( ) ;
199
+ const point = Point . fromHex ( publicKey ) . negate ( ) ;
199
200
return output ( out , compressed ? 33 : 65 , point . toRawBytes ( compressed ) ) ;
200
201
}
201
202
@@ -214,10 +215,10 @@ export function publicKeyCombine(
214
215
}
215
216
assertBool ( compressed ) ;
216
217
const combined = publicKeys
217
- . map ( ( pub ) => secp . Point . fromHex ( pub ) )
218
- . reduce ( ( res , curr ) => res . add ( curr ) , secp . Point . ZERO ) ;
218
+ . map ( ( pub ) => Point . fromHex ( pub ) )
219
+ . reduce ( ( res , curr ) => res . add ( curr ) , Point . ZERO ) ;
219
220
// Prohibit returning ZERO point
220
- if ( combined . equals ( secp . Point . ZERO ) ) {
221
+ if ( combined . equals ( Point . ZERO ) ) {
221
222
throw new Error ( "Combined result must not be zero" ) ;
222
223
}
223
224
return output ( out , compressed ? 33 : 65 , combined . toRawBytes ( compressed ) ) ;
@@ -232,10 +233,10 @@ export function publicKeyTweakAdd(
232
233
assertBytes ( publicKey , 33 , 65 ) ;
233
234
assertBytes ( tweak , 32 ) ;
234
235
assertBool ( compressed ) ;
235
- const p1 = secp . Point . fromHex ( publicKey ) ;
236
- const p2 = secp . Point . fromPrivateKey ( tweak ) ;
236
+ const p1 = Point . fromHex ( publicKey ) ;
237
+ const p2 = Point . fromPrivateKey ( tweak ) ;
237
238
const point = p1 . add ( p2 ) ;
238
- if ( p2 . equals ( secp . Point . ZERO ) || point . equals ( secp . Point . ZERO ) ) {
239
+ if ( p2 . equals ( Point . ZERO ) || point . equals ( Point . ZERO ) ) {
239
240
throw new Error ( "Tweak must not be zero" ) ;
240
241
}
241
242
return output ( out , compressed ? 33 : 65 , point . toRawBytes ( compressed ) ) ;
@@ -257,7 +258,7 @@ export function publicKeyTweakMul(
257
258
if ( bn <= 1 || bn >= ORDER ) {
258
259
throw new Error ( "Tweak is zero or bigger than curve order" ) ;
259
260
}
260
- const point = secp . Point . fromHex ( publicKey ) . multiply ( bn ) ;
261
+ const point = Point . fromHex ( publicKey ) . multiply ( bn ) ;
261
262
return output ( out , compressed ? 33 : 65 , point . toRawBytes ( compressed ) ) ;
262
263
}
263
264
@@ -285,8 +286,8 @@ export function signatureExport(
285
286
signature : Uint8Array ,
286
287
out ?: Output
287
288
) : Uint8Array {
288
- const res = getSignature ( signature ) . toRawBytes ( ) ;
289
- return output ( out , 72 , getSignature ( signature ) . toRawBytes ( ) ) . slice (
289
+ const res = getSignature ( signature ) . toDERRawBytes ( ) ;
290
+ return output ( out , 72 , res . slice ( ) ) . slice (
290
291
0 ,
291
292
res . length
292
293
) ;
@@ -297,7 +298,7 @@ export function signatureImport(
297
298
out ?: Output
298
299
) : Uint8Array {
299
300
assertBytes ( signature ) ;
300
- const sig = secp . Signature . fromDER ( signature ) ;
301
+ const sig = secp256k1 . Signature . fromDER ( signature ) ;
301
302
return output ( out , 64 , hexToBytes ( sig . toCompactHex ( ) ) ) ;
302
303
}
303
304
@@ -328,7 +329,7 @@ export function ecdh(
328
329
if ( options . data !== undefined ) {
329
330
assertBytes ( options . data ) ;
330
331
}
331
- const point = secp . Point . fromHex ( secp . getSharedSecret ( privateKey , publicKey ) ) ;
332
+ const point = Point . fromHex ( secp256k1 . getSharedSecret ( privateKey , publicKey ) ) ;
332
333
if ( options . hashfn === undefined ) {
333
334
return output ( out , 32 , sha256 ( point . toRawBytes ( true ) ) ) ;
334
335
}
@@ -342,10 +343,11 @@ export function ecdh(
342
343
assertBytes ( options . ybuf , 32 ) ;
343
344
}
344
345
assertBytes ( out as Uint8Array , 32 ) ;
346
+ const { x, y } = point . toAffine ( ) ;
345
347
const xbuf = options . xbuf || new Uint8Array ( 32 ) ;
346
- xbuf . set ( numberToBytes ( point . x ) ) ;
348
+ xbuf . set ( numberToBytes ( x ) ) ;
347
349
const ybuf = options . ybuf || new Uint8Array ( 32 ) ;
348
- ybuf . set ( numberToBytes ( point . y ) ) ;
350
+ ybuf . set ( numberToBytes ( y ) ) ;
349
351
const hash = options . hashfn ( xbuf , ybuf , options . data ! ) ;
350
352
if ( ! ( hash instanceof Uint8Array ) || hash . length !== 32 ) {
351
353
throw new Error ( "secp256k1.ecdh: invalid options.hashfn output" ) ;
0 commit comments