1 | import { leftpad, toJose } from '../util.js'
|
2 | import { Signer } from '../JWT.js'
|
3 | import { sha256 } from '../Digest.js'
|
4 | import { p256 } from '@noble/curves/p256'
|
5 |
|
6 | /**
|
7 | * Creates a configured signer function for signing data using the ES256 (secp256r1 + sha256) algorithm.
|
8 | *
|
9 | * The signing function itself takes the data as a `Uint8Array` or `string` and returns a `base64Url`-encoded signature
|
10 | *
|
11 | * @example
|
12 | * ```typescript
|
13 | * const sign: Signer = ES256Signer(process.env.PRIVATE_KEY)
|
14 | * const signature: string = await sign(data)
|
15 | * ```
|
16 | *
|
17 | * @param {String} privateKey a private key as `Uint8Array`
|
18 | * @return {Function} a configured signer function `(data: string | Uint8Array): Promise<string>`
|
19 | */
|
20 | export function ES256Signer(privateKey: Uint8Array): Signer {
|
21 | if (privateKey.length !== 32) {
|
22 | throw new Error(`bad_key: Invalid private key format. Expecting 32 bytes, but got ${privateKey.length}`)
|
23 | }
|
24 | return async (data: string | Uint8Array): Promise<string> => {
|
25 | const signature = p256.sign(sha256(data), privateKey)
|
26 | return toJose({
|
27 | r: leftpad(signature.r.toString(16)),
|
28 | s: leftpad(signature.s.toString(16)),
|
29 | })
|
30 | }
|
31 | }
|