@unknownncat/curve25519-node 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Sem nome bah
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,210 @@
1
+ # @unknownncat/curve25519-node
2
+
3
+ [![npm](https://img.shields.io/npm/v/%40unknownncat%2Fcurve25519-node)](https://www.npmjs.com/package/@unknownncat/curve25519-node)
4
+ [![downloads](https://img.shields.io/npm/dm/%40unknownncat%2Fcurve25519-node)](https://www.npmjs.com/package/@unknownncat/curve25519-node)
5
+ [![types](https://img.shields.io/badge/types-included-blue)](./dist/index.d.ts)
6
+ [![license](https://img.shields.io/github/license/unknownncat/curve25519-node)](./LICENSE)
7
+ [![node](https://img.shields.io/badge/node-%3E%3D20-339933?logo=node.js&logoColor=white)](https://nodejs.org/)
8
+ ![runtime deps](https://img.shields.io/badge/runtime%20deps-0-brightgreen)
9
+ ![esm+cjs](https://img.shields.io/badge/ESM%20%2B%20CJS-compatible-blue)
10
+
11
+ Modern **zero-dependency** X25519 + Ed25519 for Node.js using OpenSSL via `node:crypto`.
12
+
13
+ - **Node:** `>= 20`
14
+ - **Runtime deps:** `0`
15
+ - **TypeScript:** `strict`, **ESM-first**
16
+ - **Compat:** ESM + CJS (`import` e `require`)
17
+
18
+ ---
19
+
20
+ ## Why
21
+
22
+ O projeto original ([curve25519-js](https://github.com/harveyconnor/curve25519-js)) fazia aritmética de campo manual (loops extensos BigInt/Float64) para Curve25519/Ed25519.
23
+
24
+ Este pacote troca isso por primitivas nativas do OpenSSL (via `node:crypto`), com foco em:
25
+
26
+ - **segurança** por implementação consolidada
27
+ - **performance** melhor em Node moderno
28
+ - **API pequena** e **bem tipada**
29
+
30
+ ---
31
+
32
+ ## Compatibility notes (importante)
33
+
34
+ Este pacote **não replica o esquema `axlsign`** do `curve25519-js`.
35
+
36
+ Aqui a API é **padrão moderna**:
37
+
38
+ - acordo de chave: **X25519**
39
+ - assinatura: **Ed25519**
40
+
41
+ Consequências:
42
+
43
+ - Chaves de X25519 e Ed25519 são **diferentes** (public keys diferentes).
44
+ - `sign`/`verify` usam chaves **Ed25519**.
45
+ - Conversão X25519 public key ↔ Ed25519 public key **não é exposta** por `node:crypto`.
46
+ - `opt_random` (64 bytes) do legado **não é suportado** em Ed25519 com `node:crypto`.
47
+ - O compat layer aceita um 3º argumento apenas por compatibilidade de chamada, mas **sempre lança erro** se ele for fornecido.
48
+
49
+ ---
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ npm i @unknownncat/curve25519-node
55
+ ```
56
+
57
+ ---
58
+
59
+ ## Usage
60
+
61
+ ### ESM (TypeScript / Node moderno)
62
+
63
+ ```ts
64
+ import {
65
+ asBytes32,
66
+ x25519,
67
+ ed25519,
68
+ sign, // compat top-level (Ed25519)
69
+ verify, // compat top-level (Ed25519)
70
+ } from "@unknownncat/curve25519-node";
71
+
72
+ const aliceSeed = asBytes32(crypto.getRandomValues(new Uint8Array(32)));
73
+ const bobSeed = asBytes32(crypto.getRandomValues(new Uint8Array(32)));
74
+
75
+ const aliceX = x25519.generateKeyPair(aliceSeed);
76
+ const bobX = x25519.generateKeyPair(bobSeed);
77
+
78
+ const s1 = x25519.sharedKey(aliceX.private, bobX.public);
79
+ const s2 = x25519.sharedKey(bobX.private, aliceX.public);
80
+ // s1 e s2 devem ser iguais
81
+
82
+ const signerSeed = asBytes32(crypto.getRandomValues(new Uint8Array(32)));
83
+ const ed = ed25519.generateKeyPair(signerSeed);
84
+
85
+ const msg = new TextEncoder().encode("hello");
86
+
87
+ const sig = ed25519.sign(signerSeed, msg);
88
+ const ok = verify(ed.public, msg, sig);
89
+
90
+ const signedMsg = ed25519.signMessage(signerSeed, msg);
91
+ const opened = ed25519.openMessage(ed.public, signedMsg);
92
+ ```
93
+
94
+ ### CommonJS
95
+
96
+ ```js
97
+ const { x25519, ed25519, asBytes32 } = require("@unknownncat/curve25519-node");
98
+
99
+ const seed = asBytes32(new Uint8Array(32));
100
+ const kp = x25519.generateKeyPair(seed);
101
+
102
+ const sig = ed25519.sign(seed, Buffer.from("hello"));
103
+ ```
104
+
105
+ ### Subpath imports (opcional)
106
+
107
+ ```ts
108
+ import { x25519 } from "@unknownncat/curve25519-node/x25519";
109
+ import { ed25519 } from "@unknownncat/curve25519-node/ed25519";
110
+ import { asBytes32, asBytes64 } from "@unknownncat/curve25519-node/types";
111
+ ```
112
+
113
+ ---
114
+
115
+ ## API
116
+
117
+ ### Namespace `x25519`
118
+
119
+ - `publicKey(secretKey32: Bytes32): Bytes32`
120
+ - `sharedKey(secretKey32: Bytes32, publicKey32: Bytes32): Bytes32`
121
+ - `generateKeyPair(seed32: Bytes32): { public: Bytes32; private: Bytes32 }`
122
+
123
+ ### Namespace `ed25519`
124
+
125
+ - `publicKey(secretSeed32: Bytes32): Bytes32`
126
+ - `generateKeyPair(seed32: Bytes32): { public: Bytes32; private: Bytes32 }`
127
+ - `sign(secretSeed32: Bytes32, msg: Uint8Array): Bytes64`
128
+ - `verify(publicKey32: Bytes32, msg: Uint8Array, signature64: Bytes64): boolean`
129
+ - `signMessage(secretSeed32: Bytes32, msg: Uint8Array): Uint8Array`
130
+ - `openMessage(publicKey32: Bytes32, signedMsg: Uint8Array): Uint8Array | null`
131
+
132
+ ### Top-level compat layer
133
+
134
+ - `sharedKey = x25519.sharedKey`
135
+ - `generateKeyPair = x25519.generateKeyPair`
136
+ - `sign`, `verify`, `signMessage`, `openMessage` (**Ed25519**)
137
+ - `generateKeyPairX25519`, `generateKeyPairEd25519`
138
+
139
+ > `sign` e `signMessage` aceitam um terceiro argumento opcional **apenas para compatibilidade de chamada**, mas **sempre lançam erro** se ele for fornecido (`opt_random` legado não suportado).
140
+
141
+ ---
142
+
143
+ ## Branded types
144
+
145
+ - `Bytes32`
146
+ - `Bytes64`
147
+
148
+ Helpers:
149
+
150
+ - `asBytes32(u8)`
151
+ - `asBytes64(u8)`
152
+
153
+ ✅ Os helpers validam tamanho e retornam o **mesmo objeto** (sem cópia).
154
+
155
+ ---
156
+
157
+ ## Technical details (RFC 8410 DER)
158
+
159
+ Prefixos usados para importar/exportar RAW(32) ↔ `KeyObject` via DER prealocado:
160
+
161
+ - X25519 PKCS#8 prefix: `302e020100300506032b656e04220420`
162
+ - X25519 SPKI prefix: `302a300506032b656e032100`
163
+ - Ed25519 PKCS#8 prefix: `302e020100300506032b657004220420`
164
+ - Ed25519 SPKI prefix: `302a300506032b6570032100`
165
+
166
+ As operações usam buffers DER prealocados + `.set`, sem loops byte-a-byte.
167
+
168
+ ---
169
+
170
+ ## Performance notes
171
+
172
+ - Sem `Buffer.concat` no hot path; buffers montados por prealloc + `.set`.
173
+ - `Uint8Array` → `Buffer` usa view zero-copy:
174
+ - `Buffer.from(u8.buffer, u8.byteOffset, u8.byteLength)`
175
+
176
+ - `signMessage` monta `signature || msg` com `Uint8Array` prealocado e `.set`.
177
+ - Para throughput máximo em loops longos, considere cachear `KeyObject` no nível da aplicação (evita parse ASN.1 repetido).
178
+
179
+ ---
180
+
181
+ ## Security
182
+
183
+ - Validação de tipo/tamanho em todas as entradas públicas.
184
+ - Sem logs de segredo.
185
+ - Comparações internas de DER prefix usam `timingSafeEqual`.
186
+
187
+ ---
188
+
189
+ ## Tests
190
+
191
+ ```bash
192
+ npm test
193
+ ```
194
+
195
+ Cobertura inclui vetores RFC:
196
+
197
+ - X25519: RFC 7748
198
+ - Ed25519: RFC 8032
199
+
200
+ ---
201
+
202
+ ## License
203
+
204
+ MIT © unknownncat — veja [LICENSE](./LICENSE)
205
+
206
+ ---
207
+
208
+ ## Thanks
209
+
210
+ ❤️ [curve25519-js](https://github.com/harveyconnor/curve25519-js)
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publicKey = publicKey;
4
+ exports.generateKeyPair = generateKeyPair;
5
+ exports.sign = sign;
6
+ exports.verify = verify;
7
+ exports.signMessage = signMessage;
8
+ exports.openMessage = openMessage;
9
+ const node_crypto_1 = require("node:crypto");
10
+ const assert_js_1 = require("./internal/assert.js");
11
+ const der_js_1 = require("./internal/der.js");
12
+ /**
13
+ * Derives an Ed25519 public key from a raw 32-byte seed.
14
+ */
15
+ function publicKey(secretSeed32) {
16
+ (0, assert_js_1.assertBytes32)(secretSeed32, "secretSeed32");
17
+ return (0, der_js_1.rawPublicFromEd25519Spki)((0, node_crypto_1.createPublicKey)((0, der_js_1.keyFromEd25519Private)(secretSeed32)));
18
+ }
19
+ /**
20
+ * Deterministically creates an Ed25519 key pair from a 32-byte seed.
21
+ * The private key returned is the original 32-byte seed.
22
+ */
23
+ function generateKeyPair(seed32) {
24
+ (0, assert_js_1.assertBytes32)(seed32, "seed32");
25
+ return {
26
+ public: publicKey(seed32),
27
+ private: seed32,
28
+ };
29
+ }
30
+ /**
31
+ * Signs a message with Ed25519 and returns the 64-byte detached signature.
32
+ */
33
+ function sign(secretSeed32, msg) {
34
+ (0, assert_js_1.assertBytes32)(secretSeed32, "secretSeed32");
35
+ (0, assert_js_1.assertUint8Array)(msg, "msg");
36
+ const signature = (0, node_crypto_1.sign)(null, (0, assert_js_1.toBufferView)(msg), (0, der_js_1.keyFromEd25519Private)(secretSeed32));
37
+ if (signature.byteLength !== 64) {
38
+ throw new Error(`Ed25519 signature must be 64 bytes, received ${signature.byteLength}`);
39
+ }
40
+ return (0, assert_js_1.asBytes64)(new Uint8Array(signature.buffer, signature.byteOffset, signature.byteLength), "signature");
41
+ }
42
+ /**
43
+ * Verifies a detached Ed25519 signature.
44
+ */
45
+ function verify(publicKey32, msg, signature64) {
46
+ (0, assert_js_1.assertBytes32)(publicKey32, "publicKey32");
47
+ (0, assert_js_1.assertUint8Array)(msg, "msg");
48
+ (0, assert_js_1.assertBytes64)(signature64, "signature64");
49
+ return (0, node_crypto_1.verify)(null, (0, assert_js_1.toBufferView)(msg), (0, der_js_1.keyFromEd25519Public)(publicKey32), (0, assert_js_1.toBufferView)(signature64));
50
+ }
51
+ /**
52
+ * Returns signature || message.
53
+ */
54
+ function signMessage(secretSeed32, msg) {
55
+ (0, assert_js_1.assertBytes32)(secretSeed32, "secretSeed32");
56
+ (0, assert_js_1.assertUint8Array)(msg, "msg");
57
+ const signature = sign(secretSeed32, msg);
58
+ const signed = new Uint8Array(64 + msg.byteLength);
59
+ signed.set(signature, 0);
60
+ signed.set(msg, 64);
61
+ return signed;
62
+ }
63
+ /**
64
+ * Verifies signature || message and returns a copy of the message if valid, else null.
65
+ */
66
+ function openMessage(publicKey32, signedMsg) {
67
+ (0, assert_js_1.assertBytes32)(publicKey32, "publicKey32");
68
+ (0, assert_js_1.assertUint8Array)(signedMsg, "signedMsg");
69
+ if (signedMsg.byteLength < 64) {
70
+ return null;
71
+ }
72
+ const signature64 = (0, assert_js_1.asBytes64)(signedMsg.subarray(0, 64), "signedMsg signature");
73
+ const msg = signedMsg.subarray(64);
74
+ if (!verify(publicKey32, msg, signature64)) {
75
+ return null;
76
+ }
77
+ // Return a detached message copy to avoid retaining oversized parent buffers.
78
+ return new Uint8Array(msg);
79
+ }
80
+ //# sourceMappingURL=ed25519.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../../src/ed25519.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verify = exports.openMessage = exports.generateKeyPairEd25519 = exports.generateKeyPairX25519 = exports.generateKeyPair = exports.sharedKey = exports.ed25519 = exports.x25519 = exports.assertBytes64 = exports.assertBytes32 = exports.asBytes64 = exports.asBytes32 = void 0;
4
+ exports.sign = sign;
5
+ exports.signMessage = signMessage;
6
+ const assert_js_1 = require("./internal/assert.js");
7
+ const ed25519Api = require("./ed25519.js");
8
+ const x25519Api = require("./x25519.js");
9
+ var assert_js_2 = require("./internal/assert.js");
10
+ Object.defineProperty(exports, "asBytes32", { enumerable: true, get: function () { return assert_js_2.asBytes32; } });
11
+ Object.defineProperty(exports, "asBytes64", { enumerable: true, get: function () { return assert_js_2.asBytes64; } });
12
+ Object.defineProperty(exports, "assertBytes32", { enumerable: true, get: function () { return assert_js_2.assertBytes32; } });
13
+ Object.defineProperty(exports, "assertBytes64", { enumerable: true, get: function () { return assert_js_2.assertBytes64; } });
14
+ /**
15
+ * Standard X25519 namespace.
16
+ */
17
+ exports.x25519 = {
18
+ publicKey: x25519Api.publicKey,
19
+ sharedKey: x25519Api.sharedKey,
20
+ generateKeyPair: x25519Api.generateKeyPair,
21
+ };
22
+ /**
23
+ * Standard Ed25519 namespace.
24
+ */
25
+ exports.ed25519 = {
26
+ publicKey: ed25519Api.publicKey,
27
+ generateKeyPair: ed25519Api.generateKeyPair,
28
+ sign: ed25519Api.sign,
29
+ verify: ed25519Api.verify,
30
+ signMessage: ed25519Api.signMessage,
31
+ openMessage: ed25519Api.openMessage,
32
+ };
33
+ /**
34
+ * Top-level compatibility alias for X25519 shared secret.
35
+ */
36
+ exports.sharedKey = exports.x25519.sharedKey;
37
+ /**
38
+ * Top-level compatibility alias for X25519 deterministic key generation.
39
+ */
40
+ exports.generateKeyPair = exports.x25519.generateKeyPair;
41
+ /**
42
+ * Explicit X25519 key generation helper.
43
+ */
44
+ exports.generateKeyPairX25519 = exports.x25519.generateKeyPair;
45
+ /**
46
+ * Explicit Ed25519 key generation helper.
47
+ */
48
+ exports.generateKeyPairEd25519 = exports.ed25519.generateKeyPair;
49
+ /**
50
+ * Compatibility wrapper for Ed25519 detached signing.
51
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
52
+ */
53
+ function sign(secretSeed32, msg, opt_random) {
54
+ (0, assert_js_1.assertUint8Array)(msg, "msg");
55
+ (0, assert_js_1.assertNoOptRandom)(opt_random, "sign");
56
+ return exports.ed25519.sign(secretSeed32, msg);
57
+ }
58
+ /**
59
+ * Compatibility wrapper for Ed25519 signed-message mode.
60
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
61
+ */
62
+ function signMessage(secretSeed32, msg, opt_random) {
63
+ (0, assert_js_1.assertUint8Array)(msg, "msg");
64
+ (0, assert_js_1.assertNoOptRandom)(opt_random, "signMessage");
65
+ return exports.ed25519.signMessage(secretSeed32, msg);
66
+ }
67
+ /**
68
+ * Top-level compatibility alias for signed-message verification/open.
69
+ */
70
+ exports.openMessage = exports.ed25519.openMessage;
71
+ /**
72
+ * Top-level compatibility alias for detached signature verification.
73
+ */
74
+ exports.verify = exports.ed25519.verify;
75
+ const api = {
76
+ x25519: exports.x25519,
77
+ ed25519: exports.ed25519,
78
+ sharedKey: exports.sharedKey,
79
+ generateKeyPair: exports.generateKeyPair,
80
+ generateKeyPairX25519: exports.generateKeyPairX25519,
81
+ generateKeyPairEd25519: exports.generateKeyPairEd25519,
82
+ sign,
83
+ signMessage,
84
+ openMessage: exports.openMessage,
85
+ verify: exports.verify,
86
+ };
87
+ exports.default = api;
88
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAqDA,oBAIC;AAMD,kCAIC;AAnED,oDAA2E;AAC3E,2CAA2C;AAC3C,yCAAyC;AAGzC,kDAA0F;AAAjF,sGAAA,SAAS,OAAA;AAAE,sGAAA,SAAS,OAAA;AAAE,0GAAA,aAAa,OAAA;AAAE,0GAAA,aAAa,OAAA;AAG3D;;GAEG;AACU,QAAA,MAAM,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC,SAAS;IAC9B,SAAS,EAAE,SAAS,CAAC,SAAS;IAC9B,eAAe,EAAE,SAAS,CAAC,eAAe;CAClC,CAAC;AAEX;;GAEG;AACU,QAAA,OAAO,GAAG;IACrB,SAAS,EAAE,UAAU,CAAC,SAAS;IAC/B,eAAe,EAAE,UAAU,CAAC,eAAe;IAC3C,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,WAAW,EAAE,UAAU,CAAC,WAAW;IACnC,WAAW,EAAE,UAAU,CAAC,WAAW;CAC3B,CAAC;AAEX;;GAEG;AACU,QAAA,SAAS,GAAG,cAAM,CAAC,SAAS,CAAC;AAE1C;;GAEG;AACU,QAAA,eAAe,GAAG,cAAM,CAAC,eAAe,CAAC;AAEtD;;GAEG;AACU,QAAA,qBAAqB,GAAG,cAAM,CAAC,eAAe,CAAC;AAE5D;;GAEG;AACU,QAAA,sBAAsB,GAAG,eAAO,CAAC,eAAe,CAAC;AAE9D;;;GAGG;AACH,SAAgB,IAAI,CAAC,YAAqB,EAAE,GAAe,EAAE,UAAuB;IAClF,IAAA,4BAAgB,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,IAAA,6BAAiB,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,eAAO,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,YAAqB,EAAE,GAAe,EAAE,UAAuB;IACzF,IAAA,4BAAgB,EAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,IAAA,6BAAiB,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAC7C,OAAO,eAAO,CAAC,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACU,QAAA,WAAW,GAAG,eAAO,CAAC,WAAW,CAAC;AAE/C;;GAEG;AACU,QAAA,MAAM,GAAG,eAAO,CAAC,MAAM,CAAC;AAErC,MAAM,GAAG,GAAG;IACV,MAAM,EAAN,cAAM;IACN,OAAO,EAAP,eAAO;IACP,SAAS,EAAT,iBAAS;IACT,eAAe,EAAf,uBAAe;IACf,qBAAqB,EAArB,6BAAqB;IACrB,sBAAsB,EAAtB,8BAAsB;IACtB,IAAI;IACJ,WAAW;IACX,WAAW,EAAX,mBAAW;IACX,MAAM,EAAN,cAAM;CACE,CAAC;AAEX,kBAAe,GAAG,CAAC"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertUint8Array = assertUint8Array;
4
+ exports.assertBytes32 = assertBytes32;
5
+ exports.assertBytes64 = assertBytes64;
6
+ exports.asBytes32 = asBytes32;
7
+ exports.asBytes64 = asBytes64;
8
+ exports.assertNoOptRandom = assertNoOptRandom;
9
+ exports.toBufferView = toBufferView;
10
+ function assertUint8Array(value, name) {
11
+ if (!(value instanceof Uint8Array)) {
12
+ const actual = value === null ? "null" : typeof value;
13
+ throw new TypeError(`${name} must be a Uint8Array, received ${actual}`);
14
+ }
15
+ }
16
+ function assertLength(value, expected, name) {
17
+ if (value.byteLength !== expected) {
18
+ throw new RangeError(`${name} must be ${expected} bytes, received ${value.byteLength}`);
19
+ }
20
+ }
21
+ function assertBytes32(value, name = "value") {
22
+ assertUint8Array(value, name);
23
+ assertLength(value, 32, name);
24
+ }
25
+ function assertBytes64(value, name = "value") {
26
+ assertUint8Array(value, name);
27
+ assertLength(value, 64, name);
28
+ }
29
+ function asBytes32(value, name = "value") {
30
+ assertBytes32(value, name);
31
+ return value;
32
+ }
33
+ function asBytes64(value, name = "value") {
34
+ assertBytes64(value, name);
35
+ return value;
36
+ }
37
+ function assertNoOptRandom(optRandom, fnName) {
38
+ if (optRandom !== undefined) {
39
+ throw new Error(`${fnName} does not support opt_random with node:crypto Ed25519. ` +
40
+ "Remove the third argument and use deterministic Ed25519 signing.");
41
+ }
42
+ }
43
+ function toBufferView(value) {
44
+ return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
45
+ }
46
+ //# sourceMappingURL=assert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.js","sourceRoot":"","sources":["../../../src/internal/assert.ts"],"names":[],"mappings":";;AAEA,4CAKC;AAQD,sCAGC;AAED,sCAGC;AAED,8BAGC;AAED,8BAGC;AAED,8CAOC;AAED,oCAEC;AA5CD,SAAgB,gBAAgB,CAAC,KAAc,EAAE,IAAY;IAC3D,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC;QACtD,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAiB,EAAE,QAAgB,EAAE,IAAY;IACrE,IAAI,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,YAAY,QAAQ,oBAAoB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IAC7D,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,SAAgB,aAAa,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IAC7D,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,SAAgB,SAAS,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IACzD,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,SAAS,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IACzD,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAgB,CAAC;AAC1B,CAAC;AAED,SAAgB,iBAAiB,CAAC,SAAkB,EAAE,MAAc;IAClE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,yDAAyD;YAChE,kEAAkE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,SAAgB,YAAY,CAAC,KAAiB;IAC5C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.derPkcs8 = derPkcs8;
4
+ exports.derSpki = derSpki;
5
+ exports.keyFromX25519Private = keyFromX25519Private;
6
+ exports.keyFromX25519Public = keyFromX25519Public;
7
+ exports.keyFromEd25519Private = keyFromEd25519Private;
8
+ exports.keyFromEd25519Public = keyFromEd25519Public;
9
+ exports.rawPublicFromX25519Spki = rawPublicFromX25519Spki;
10
+ exports.rawPublicFromEd25519Spki = rawPublicFromEd25519Spki;
11
+ const node_crypto_1 = require("node:crypto");
12
+ const assert_js_1 = require("./assert.js");
13
+ const X25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b656e04220420", "hex");
14
+ const X25519_SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
15
+ const ED25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b657004220420", "hex");
16
+ const ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
17
+ function appendRaw32(prefix, raw32, inputName) {
18
+ (0, assert_js_1.assertBytes32)(raw32, inputName);
19
+ const out = Buffer.allocUnsafe(prefix.length + 32);
20
+ out.set(prefix, 0);
21
+ out.set(raw32, prefix.length);
22
+ return out;
23
+ }
24
+ function derPkcs8(prefix, raw32) {
25
+ return appendRaw32(prefix, raw32, "raw private key");
26
+ }
27
+ function derSpki(prefix, raw32) {
28
+ return appendRaw32(prefix, raw32, "raw public key");
29
+ }
30
+ function keyFromX25519Private(raw32) {
31
+ return (0, node_crypto_1.createPrivateKey)({
32
+ key: derPkcs8(X25519_PKCS8_PREFIX, raw32),
33
+ format: "der",
34
+ type: "pkcs8",
35
+ });
36
+ }
37
+ function keyFromX25519Public(raw32) {
38
+ return (0, node_crypto_1.createPublicKey)({
39
+ key: derSpki(X25519_SPKI_PREFIX, raw32),
40
+ format: "der",
41
+ type: "spki",
42
+ });
43
+ }
44
+ function keyFromEd25519Private(seed32) {
45
+ return (0, node_crypto_1.createPrivateKey)({
46
+ key: derPkcs8(ED25519_PKCS8_PREFIX, seed32),
47
+ format: "der",
48
+ type: "pkcs8",
49
+ });
50
+ }
51
+ function keyFromEd25519Public(raw32) {
52
+ return (0, node_crypto_1.createPublicKey)({
53
+ key: derSpki(ED25519_SPKI_PREFIX, raw32),
54
+ format: "der",
55
+ type: "spki",
56
+ });
57
+ }
58
+ function rawPublicFromSpki(keyObject, prefix, label) {
59
+ const der = keyObject.export({ format: "der", type: "spki" });
60
+ if (!Buffer.isBuffer(der)) {
61
+ throw new TypeError(`${label} SPKI export must be a Buffer`);
62
+ }
63
+ if (der.byteLength !== prefix.length + 32) {
64
+ throw new Error(`${label} SPKI DER length mismatch`);
65
+ }
66
+ const exportedPrefix = der.subarray(0, prefix.length);
67
+ if (!(0, node_crypto_1.timingSafeEqual)(exportedPrefix, prefix)) {
68
+ throw new Error(`${label} SPKI DER prefix mismatch`);
69
+ }
70
+ const raw = new Uint8Array(der.buffer, der.byteOffset + prefix.length, 32);
71
+ return (0, assert_js_1.asBytes32)(raw, `${label} public key`);
72
+ }
73
+ function rawPublicFromX25519Spki(keyObject) {
74
+ return rawPublicFromSpki(keyObject, X25519_SPKI_PREFIX, "X25519");
75
+ }
76
+ function rawPublicFromEd25519Spki(keyObject) {
77
+ return rawPublicFromSpki(keyObject, ED25519_SPKI_PREFIX, "Ed25519");
78
+ }
79
+ //# sourceMappingURL=der.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"der.js","sourceRoot":"","sources":["../../../src/internal/der.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.publicKey = publicKey;
4
+ exports.sharedKey = sharedKey;
5
+ exports.generateKeyPair = generateKeyPair;
6
+ const node_crypto_1 = require("node:crypto");
7
+ const assert_js_1 = require("./internal/assert.js");
8
+ const der_js_1 = require("./internal/der.js");
9
+ function clampScalar(seed32) {
10
+ const clamped = new Uint8Array(32);
11
+ clamped.set(seed32);
12
+ clamped[0] = (clamped[0] ?? 0) & 248;
13
+ const last = clamped[31] ?? 0;
14
+ clamped[31] = (last & 127) | 64;
15
+ return (0, assert_js_1.asBytes32)(clamped, "clamped scalar");
16
+ }
17
+ /**
18
+ * Derives an X25519 public key from a raw 32-byte secret scalar.
19
+ */
20
+ function publicKey(secretKey32) {
21
+ (0, assert_js_1.assertBytes32)(secretKey32, "secretKey32");
22
+ const privateKey = (0, der_js_1.keyFromX25519Private)(secretKey32);
23
+ return (0, der_js_1.rawPublicFromX25519Spki)((0, node_crypto_1.createPublicKey)(privateKey));
24
+ }
25
+ /**
26
+ * Computes X25519 ECDH shared secret (raw 32 bytes).
27
+ */
28
+ function sharedKey(secretKey32, publicKey32) {
29
+ (0, assert_js_1.assertBytes32)(secretKey32, "secretKey32");
30
+ (0, assert_js_1.assertBytes32)(publicKey32, "publicKey32");
31
+ const shared = (0, node_crypto_1.diffieHellman)({
32
+ privateKey: (0, der_js_1.keyFromX25519Private)(secretKey32),
33
+ publicKey: (0, der_js_1.keyFromX25519Public)(publicKey32),
34
+ });
35
+ if (shared.byteLength !== 32) {
36
+ throw new Error(`X25519 shared secret must be 32 bytes, received ${shared.byteLength}`);
37
+ }
38
+ return (0, assert_js_1.asBytes32)(new Uint8Array(shared.buffer, shared.byteOffset, shared.byteLength), "sharedKey");
39
+ }
40
+ /**
41
+ * Deterministically creates an X25519 key pair from a 32-byte seed.
42
+ * The returned private key is explicitly clamped for stable output.
43
+ */
44
+ function generateKeyPair(seed32) {
45
+ (0, assert_js_1.assertBytes32)(seed32, "seed32");
46
+ const privateKey = clampScalar(seed32);
47
+ const publicKey32 = publicKey(privateKey);
48
+ return {
49
+ public: publicKey32,
50
+ private: privateKey,
51
+ };
52
+ }
53
+ //# sourceMappingURL=x25519.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x25519.js","sourceRoot":"","sources":["../../src/x25519.ts"],"names":[],"mappings":";;AAqBA,8BAIC;AAKD,8BAaC;AAMD,0CAQC;AAzDD,6CAA6D;AAC7D,oDAAgE;AAChE,8CAI2B;AAG3B,SAAS,WAAW,CAAC,MAAe;IAClC,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAChC,OAAO,IAAA,qBAAS,EAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,WAAoB;IAC5C,IAAA,yBAAa,EAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAA,6BAAoB,EAAC,WAAW,CAAC,CAAC;IACrD,OAAO,IAAA,gCAAuB,EAAC,IAAA,6BAAe,EAAC,UAAU,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,WAAoB,EAAE,WAAoB;IAClE,IAAA,yBAAa,EAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,IAAA,yBAAa,EAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,IAAA,2BAAa,EAAC;QAC3B,UAAU,EAAE,IAAA,6BAAoB,EAAC,WAAW,CAAC;QAC7C,SAAS,EAAE,IAAA,4BAAmB,EAAC,WAAW,CAAC;KAC5C,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mDAAmD,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,IAAA,qBAAS,EAAC,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;AACrG,CAAC;AAED;;;GAGG;AACH,SAAgB,eAAe,CAAC,MAAe;IAC7C,IAAA,yBAAa,EAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,UAAU;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Bytes32, Bytes64, KeyPair32 } from "./types.js";
2
+ /**
3
+ * Derives an Ed25519 public key from a raw 32-byte seed.
4
+ */
5
+ export declare function publicKey(secretSeed32: Bytes32): Bytes32;
6
+ /**
7
+ * Deterministically creates an Ed25519 key pair from a 32-byte seed.
8
+ * The private key returned is the original 32-byte seed.
9
+ */
10
+ export declare function generateKeyPair(seed32: Bytes32): KeyPair32;
11
+ /**
12
+ * Signs a message with Ed25519 and returns the 64-byte detached signature.
13
+ */
14
+ export declare function sign(secretSeed32: Bytes32, msg: Uint8Array): Bytes64;
15
+ /**
16
+ * Verifies a detached Ed25519 signature.
17
+ */
18
+ export declare function verify(publicKey32: Bytes32, msg: Uint8Array, signature64: Bytes64): boolean;
19
+ /**
20
+ * Returns signature || message.
21
+ */
22
+ export declare function signMessage(secretSeed32: Bytes32, msg: Uint8Array): Uint8Array;
23
+ /**
24
+ * Verifies signature || message and returns a copy of the message if valid, else null.
25
+ */
26
+ export declare function openMessage(publicKey32: Bytes32, signedMsg: Uint8Array): Uint8Array | null;
27
+ //# sourceMappingURL=ed25519.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ed25519.d.ts","sourceRoot":"","sources":["../src/ed25519.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,wBAAgB,SAAS,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAGxD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAM1D;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO,CASpE;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAW3F;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,GAAG,UAAU,CAS9E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAgB1F"}
@@ -0,0 +1,72 @@
1
+ import { createPublicKey, sign as cryptoSign, verify as cryptoVerify } from "node:crypto";
2
+ import { asBytes64, assertBytes32, assertBytes64, assertUint8Array, toBufferView } from "./internal/assert.js";
3
+ import { keyFromEd25519Private, keyFromEd25519Public, rawPublicFromEd25519Spki } from "./internal/der.js";
4
+ /**
5
+ * Derives an Ed25519 public key from a raw 32-byte seed.
6
+ */
7
+ export function publicKey(secretSeed32) {
8
+ assertBytes32(secretSeed32, "secretSeed32");
9
+ return rawPublicFromEd25519Spki(createPublicKey(keyFromEd25519Private(secretSeed32)));
10
+ }
11
+ /**
12
+ * Deterministically creates an Ed25519 key pair from a 32-byte seed.
13
+ * The private key returned is the original 32-byte seed.
14
+ */
15
+ export function generateKeyPair(seed32) {
16
+ assertBytes32(seed32, "seed32");
17
+ return {
18
+ public: publicKey(seed32),
19
+ private: seed32,
20
+ };
21
+ }
22
+ /**
23
+ * Signs a message with Ed25519 and returns the 64-byte detached signature.
24
+ */
25
+ export function sign(secretSeed32, msg) {
26
+ assertBytes32(secretSeed32, "secretSeed32");
27
+ assertUint8Array(msg, "msg");
28
+ const signature = cryptoSign(null, toBufferView(msg), keyFromEd25519Private(secretSeed32));
29
+ if (signature.byteLength !== 64) {
30
+ throw new Error(`Ed25519 signature must be 64 bytes, received ${signature.byteLength}`);
31
+ }
32
+ return asBytes64(new Uint8Array(signature.buffer, signature.byteOffset, signature.byteLength), "signature");
33
+ }
34
+ /**
35
+ * Verifies a detached Ed25519 signature.
36
+ */
37
+ export function verify(publicKey32, msg, signature64) {
38
+ assertBytes32(publicKey32, "publicKey32");
39
+ assertUint8Array(msg, "msg");
40
+ assertBytes64(signature64, "signature64");
41
+ return cryptoVerify(null, toBufferView(msg), keyFromEd25519Public(publicKey32), toBufferView(signature64));
42
+ }
43
+ /**
44
+ * Returns signature || message.
45
+ */
46
+ export function signMessage(secretSeed32, msg) {
47
+ assertBytes32(secretSeed32, "secretSeed32");
48
+ assertUint8Array(msg, "msg");
49
+ const signature = sign(secretSeed32, msg);
50
+ const signed = new Uint8Array(64 + msg.byteLength);
51
+ signed.set(signature, 0);
52
+ signed.set(msg, 64);
53
+ return signed;
54
+ }
55
+ /**
56
+ * Verifies signature || message and returns a copy of the message if valid, else null.
57
+ */
58
+ export function openMessage(publicKey32, signedMsg) {
59
+ assertBytes32(publicKey32, "publicKey32");
60
+ assertUint8Array(signedMsg, "signedMsg");
61
+ if (signedMsg.byteLength < 64) {
62
+ return null;
63
+ }
64
+ const signature64 = asBytes64(signedMsg.subarray(0, 64), "signedMsg signature");
65
+ const msg = signedMsg.subarray(64);
66
+ if (!verify(publicKey32, msg, signature64)) {
67
+ return null;
68
+ }
69
+ // Return a detached message copy to avoid retaining oversized parent buffers.
70
+ return new Uint8Array(msg);
71
+ }
72
+ //# sourceMappingURL=ed25519.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../src/ed25519.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,IAAI,IAAI,UAAU,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAC/G,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAG1G;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,YAAqB;IAC7C,aAAa,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC5C,OAAO,wBAAwB,CAAC,eAAe,CAAC,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AACxF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,OAAO;QACL,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;QACzB,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,IAAI,CAAC,YAAqB,EAAE,GAAe;IACzD,aAAa,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC5C,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,qBAAqB,CAAC,YAAY,CAAC,CAAC,CAAC;IAC3F,IAAI,SAAS,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,SAAS,CAAC,UAAU,EAAE,SAAS,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;AAC9G,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,MAAM,CAAC,WAAoB,EAAE,GAAe,EAAE,WAAoB;IAChF,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAE1C,OAAO,YAAY,CACjB,IAAI,EACJ,YAAY,CAAC,GAAG,CAAC,EACjB,oBAAoB,CAAC,WAAW,CAAC,EACjC,YAAY,CAAC,WAAW,CAAC,CAC1B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,YAAqB,EAAE,GAAe;IAChE,aAAa,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IAC5C,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7B,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACzB,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACpB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,WAAoB,EAAE,SAAqB;IACrE,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,gBAAgB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAEzC,IAAI,SAAS,CAAC,UAAU,GAAG,EAAE,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,WAAW,GAAG,SAAS,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,qBAAqB,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,8EAA8E;IAC9E,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,83 @@
1
+ import * as ed25519Api from "./ed25519.js";
2
+ import * as x25519Api from "./x25519.js";
3
+ import type { Bytes32, Bytes64 } from "./types.js";
4
+ export { asBytes32, asBytes64, assertBytes32, assertBytes64 } from "./internal/assert.js";
5
+ export type { Bytes32, Bytes64, KeyPair32 } from "./types.js";
6
+ /**
7
+ * Standard X25519 namespace.
8
+ */
9
+ export declare const x25519: {
10
+ readonly publicKey: typeof x25519Api.publicKey;
11
+ readonly sharedKey: typeof x25519Api.sharedKey;
12
+ readonly generateKeyPair: typeof x25519Api.generateKeyPair;
13
+ };
14
+ /**
15
+ * Standard Ed25519 namespace.
16
+ */
17
+ export declare const ed25519: {
18
+ readonly publicKey: typeof ed25519Api.publicKey;
19
+ readonly generateKeyPair: typeof ed25519Api.generateKeyPair;
20
+ readonly sign: typeof ed25519Api.sign;
21
+ readonly verify: typeof ed25519Api.verify;
22
+ readonly signMessage: typeof ed25519Api.signMessage;
23
+ readonly openMessage: typeof ed25519Api.openMessage;
24
+ };
25
+ /**
26
+ * Top-level compatibility alias for X25519 shared secret.
27
+ */
28
+ export declare const sharedKey: typeof x25519Api.sharedKey;
29
+ /**
30
+ * Top-level compatibility alias for X25519 deterministic key generation.
31
+ */
32
+ export declare const generateKeyPair: typeof x25519Api.generateKeyPair;
33
+ /**
34
+ * Explicit X25519 key generation helper.
35
+ */
36
+ export declare const generateKeyPairX25519: typeof x25519Api.generateKeyPair;
37
+ /**
38
+ * Explicit Ed25519 key generation helper.
39
+ */
40
+ export declare const generateKeyPairEd25519: typeof ed25519Api.generateKeyPair;
41
+ /**
42
+ * Compatibility wrapper for Ed25519 detached signing.
43
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
44
+ */
45
+ export declare function sign(secretSeed32: Bytes32, msg: Uint8Array, opt_random?: Uint8Array): Bytes64;
46
+ /**
47
+ * Compatibility wrapper for Ed25519 signed-message mode.
48
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
49
+ */
50
+ export declare function signMessage(secretSeed32: Bytes32, msg: Uint8Array, opt_random?: Uint8Array): Uint8Array;
51
+ /**
52
+ * Top-level compatibility alias for signed-message verification/open.
53
+ */
54
+ export declare const openMessage: typeof ed25519Api.openMessage;
55
+ /**
56
+ * Top-level compatibility alias for detached signature verification.
57
+ */
58
+ export declare const verify: typeof ed25519Api.verify;
59
+ declare const api: {
60
+ readonly x25519: {
61
+ readonly publicKey: typeof x25519Api.publicKey;
62
+ readonly sharedKey: typeof x25519Api.sharedKey;
63
+ readonly generateKeyPair: typeof x25519Api.generateKeyPair;
64
+ };
65
+ readonly ed25519: {
66
+ readonly publicKey: typeof ed25519Api.publicKey;
67
+ readonly generateKeyPair: typeof ed25519Api.generateKeyPair;
68
+ readonly sign: typeof ed25519Api.sign;
69
+ readonly verify: typeof ed25519Api.verify;
70
+ readonly signMessage: typeof ed25519Api.signMessage;
71
+ readonly openMessage: typeof ed25519Api.openMessage;
72
+ };
73
+ readonly sharedKey: typeof x25519Api.sharedKey;
74
+ readonly generateKeyPair: typeof x25519Api.generateKeyPair;
75
+ readonly generateKeyPairX25519: typeof x25519Api.generateKeyPair;
76
+ readonly generateKeyPairEd25519: typeof ed25519Api.generateKeyPair;
77
+ readonly sign: typeof sign;
78
+ readonly signMessage: typeof signMessage;
79
+ readonly openMessage: typeof ed25519Api.openMessage;
80
+ readonly verify: typeof ed25519Api.verify;
81
+ };
82
+ export default api;
83
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAa,MAAM,YAAY,CAAC;AAE9D,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1F,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,MAAM;;;;CAIT,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,OAAO;;;;;;;CAOV,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,SAAS,4BAAmB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,eAAe,kCAAyB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,qBAAqB,kCAAyB,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,sBAAsB,mCAA0B,CAAC;AAE9D;;;GAGG;AACH,wBAAgB,IAAI,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAI7F;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,UAAU,CAIvG;AAED;;GAEG;AACH,eAAO,MAAM,WAAW,+BAAsB,CAAC;AAE/C;;GAEG;AACH,eAAO,MAAM,MAAM,0BAAiB,CAAC;AAErC,QAAA,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;CAWC,CAAC;AAEX,eAAe,GAAG,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,79 @@
1
+ import { assertNoOptRandom, assertUint8Array } from "./internal/assert.js";
2
+ import * as ed25519Api from "./ed25519.js";
3
+ import * as x25519Api from "./x25519.js";
4
+ export { asBytes32, asBytes64, assertBytes32, assertBytes64 } from "./internal/assert.js";
5
+ /**
6
+ * Standard X25519 namespace.
7
+ */
8
+ export const x25519 = {
9
+ publicKey: x25519Api.publicKey,
10
+ sharedKey: x25519Api.sharedKey,
11
+ generateKeyPair: x25519Api.generateKeyPair,
12
+ };
13
+ /**
14
+ * Standard Ed25519 namespace.
15
+ */
16
+ export const ed25519 = {
17
+ publicKey: ed25519Api.publicKey,
18
+ generateKeyPair: ed25519Api.generateKeyPair,
19
+ sign: ed25519Api.sign,
20
+ verify: ed25519Api.verify,
21
+ signMessage: ed25519Api.signMessage,
22
+ openMessage: ed25519Api.openMessage,
23
+ };
24
+ /**
25
+ * Top-level compatibility alias for X25519 shared secret.
26
+ */
27
+ export const sharedKey = x25519.sharedKey;
28
+ /**
29
+ * Top-level compatibility alias for X25519 deterministic key generation.
30
+ */
31
+ export const generateKeyPair = x25519.generateKeyPair;
32
+ /**
33
+ * Explicit X25519 key generation helper.
34
+ */
35
+ export const generateKeyPairX25519 = x25519.generateKeyPair;
36
+ /**
37
+ * Explicit Ed25519 key generation helper.
38
+ */
39
+ export const generateKeyPairEd25519 = ed25519.generateKeyPair;
40
+ /**
41
+ * Compatibility wrapper for Ed25519 detached signing.
42
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
43
+ */
44
+ export function sign(secretSeed32, msg, opt_random) {
45
+ assertUint8Array(msg, "msg");
46
+ assertNoOptRandom(opt_random, "sign");
47
+ return ed25519.sign(secretSeed32, msg);
48
+ }
49
+ /**
50
+ * Compatibility wrapper for Ed25519 signed-message mode.
51
+ * opt_random from legacy curve25519-js/axlsign is intentionally unsupported.
52
+ */
53
+ export function signMessage(secretSeed32, msg, opt_random) {
54
+ assertUint8Array(msg, "msg");
55
+ assertNoOptRandom(opt_random, "signMessage");
56
+ return ed25519.signMessage(secretSeed32, msg);
57
+ }
58
+ /**
59
+ * Top-level compatibility alias for signed-message verification/open.
60
+ */
61
+ export const openMessage = ed25519.openMessage;
62
+ /**
63
+ * Top-level compatibility alias for detached signature verification.
64
+ */
65
+ export const verify = ed25519.verify;
66
+ const api = {
67
+ x25519,
68
+ ed25519,
69
+ sharedKey,
70
+ generateKeyPair,
71
+ generateKeyPairX25519,
72
+ generateKeyPairEd25519,
73
+ sign,
74
+ signMessage,
75
+ openMessage,
76
+ verify,
77
+ };
78
+ export default api;
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC3E,OAAO,KAAK,UAAU,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,SAAS,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAG1F;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,SAAS,EAAE,SAAS,CAAC,SAAS;IAC9B,SAAS,EAAE,SAAS,CAAC,SAAS;IAC9B,eAAe,EAAE,SAAS,CAAC,eAAe;CAClC,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,SAAS,EAAE,UAAU,CAAC,SAAS;IAC/B,eAAe,EAAE,UAAU,CAAC,eAAe;IAC3C,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,WAAW,EAAE,UAAU,CAAC,WAAW;IACnC,WAAW,EAAE,UAAU,CAAC,WAAW;CAC3B,CAAC;AAEX;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;AAEtD;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC,eAAe,CAAC;AAE5D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,YAAqB,EAAE,GAAe,EAAE,UAAuB;IAClF,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,iBAAiB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,YAAqB,EAAE,GAAe,EAAE,UAAuB;IACzF,gBAAgB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC7B,iBAAiB,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAC7C,OAAO,OAAO,CAAC,WAAW,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;AAE/C;;GAEG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;AAErC,MAAM,GAAG,GAAG;IACV,MAAM;IACN,OAAO;IACP,SAAS;IACT,eAAe;IACf,qBAAqB;IACrB,sBAAsB;IACtB,IAAI;IACJ,WAAW;IACX,WAAW;IACX,MAAM;CACE,CAAC;AAEX,eAAe,GAAG,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Bytes32, Bytes64 } from "../types.js";
2
+ export declare function assertUint8Array(value: unknown, name: string): asserts value is Uint8Array;
3
+ export declare function assertBytes32(value: Uint8Array, name?: string): asserts value is Bytes32;
4
+ export declare function assertBytes64(value: Uint8Array, name?: string): asserts value is Bytes64;
5
+ export declare function asBytes32(value: Uint8Array, name?: string): Bytes32;
6
+ export declare function asBytes64(value: Uint8Array, name?: string): Bytes64;
7
+ export declare function assertNoOptRandom(optRandom: unknown, fnName: string): void;
8
+ export declare function toBufferView(value: Uint8Array): Buffer;
9
+ //# sourceMappingURL=assert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../src/internal/assert.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEpD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,IAAI,UAAU,CAK1F;AAQD,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,SAAU,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAGzF;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,SAAU,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAGzF;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,SAAU,GAAG,OAAO,CAGpE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,SAAU,GAAG,OAAO,CAGpE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAO1E;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAEtD"}
@@ -0,0 +1,37 @@
1
+ export function assertUint8Array(value, name) {
2
+ if (!(value instanceof Uint8Array)) {
3
+ const actual = value === null ? "null" : typeof value;
4
+ throw new TypeError(`${name} must be a Uint8Array, received ${actual}`);
5
+ }
6
+ }
7
+ function assertLength(value, expected, name) {
8
+ if (value.byteLength !== expected) {
9
+ throw new RangeError(`${name} must be ${expected} bytes, received ${value.byteLength}`);
10
+ }
11
+ }
12
+ export function assertBytes32(value, name = "value") {
13
+ assertUint8Array(value, name);
14
+ assertLength(value, 32, name);
15
+ }
16
+ export function assertBytes64(value, name = "value") {
17
+ assertUint8Array(value, name);
18
+ assertLength(value, 64, name);
19
+ }
20
+ export function asBytes32(value, name = "value") {
21
+ assertBytes32(value, name);
22
+ return value;
23
+ }
24
+ export function asBytes64(value, name = "value") {
25
+ assertBytes64(value, name);
26
+ return value;
27
+ }
28
+ export function assertNoOptRandom(optRandom, fnName) {
29
+ if (optRandom !== undefined) {
30
+ throw new Error(`${fnName} does not support opt_random with node:crypto Ed25519. ` +
31
+ "Remove the third argument and use deterministic Ed25519 signing.");
32
+ }
33
+ }
34
+ export function toBufferView(value) {
35
+ return Buffer.from(value.buffer, value.byteOffset, value.byteLength);
36
+ }
37
+ //# sourceMappingURL=assert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert.js","sourceRoot":"","sources":["../../src/internal/assert.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,KAAc,EAAE,IAAY;IAC3D,IAAI,CAAC,CAAC,KAAK,YAAY,UAAU,CAAC,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC;QACtD,MAAM,IAAI,SAAS,CAAC,GAAG,IAAI,mCAAmC,MAAM,EAAE,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAiB,EAAE,QAAgB,EAAE,IAAY;IACrE,IAAI,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,YAAY,QAAQ,oBAAoB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IAC7D,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IAC7D,gBAAgB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,YAAY,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IACzD,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAiB,EAAE,IAAI,GAAG,OAAO;IACzD,aAAa,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC3B,OAAO,KAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,SAAkB,EAAE,MAAc;IAClE,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,yDAAyD;YAChE,kEAAkE,CACrE,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAiB;IAC5C,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { type KeyObject } from "node:crypto";
2
+ import type { Bytes32 } from "../types.js";
3
+ export declare function derPkcs8(prefix: Buffer, raw32: Uint8Array): Buffer;
4
+ export declare function derSpki(prefix: Buffer, raw32: Uint8Array): Buffer;
5
+ export declare function keyFromX25519Private(raw32: Bytes32): KeyObject;
6
+ export declare function keyFromX25519Public(raw32: Bytes32): KeyObject;
7
+ export declare function keyFromEd25519Private(seed32: Bytes32): KeyObject;
8
+ export declare function keyFromEd25519Public(raw32: Bytes32): KeyObject;
9
+ export declare function rawPublicFromX25519Spki(keyObject: KeyObject): Bytes32;
10
+ export declare function rawPublicFromEd25519Spki(keyObject: KeyObject): Bytes32;
11
+ //# sourceMappingURL=der.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"der.d.ts","sourceRoot":"","sources":["../../src/internal/der.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsD,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAiB3C,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAElE;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM,CAEjE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAM9D;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAM7D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAMhE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAM9D;AAoBD,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAErE;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAEtE"}
@@ -0,0 +1,69 @@
1
+ import { createPrivateKey, createPublicKey, timingSafeEqual } from "node:crypto";
2
+ import { asBytes32, assertBytes32 } from "./assert.js";
3
+ const X25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b656e04220420", "hex");
4
+ const X25519_SPKI_PREFIX = Buffer.from("302a300506032b656e032100", "hex");
5
+ const ED25519_PKCS8_PREFIX = Buffer.from("302e020100300506032b657004220420", "hex");
6
+ const ED25519_SPKI_PREFIX = Buffer.from("302a300506032b6570032100", "hex");
7
+ function appendRaw32(prefix, raw32, inputName) {
8
+ assertBytes32(raw32, inputName);
9
+ const out = Buffer.allocUnsafe(prefix.length + 32);
10
+ out.set(prefix, 0);
11
+ out.set(raw32, prefix.length);
12
+ return out;
13
+ }
14
+ export function derPkcs8(prefix, raw32) {
15
+ return appendRaw32(prefix, raw32, "raw private key");
16
+ }
17
+ export function derSpki(prefix, raw32) {
18
+ return appendRaw32(prefix, raw32, "raw public key");
19
+ }
20
+ export function keyFromX25519Private(raw32) {
21
+ return createPrivateKey({
22
+ key: derPkcs8(X25519_PKCS8_PREFIX, raw32),
23
+ format: "der",
24
+ type: "pkcs8",
25
+ });
26
+ }
27
+ export function keyFromX25519Public(raw32) {
28
+ return createPublicKey({
29
+ key: derSpki(X25519_SPKI_PREFIX, raw32),
30
+ format: "der",
31
+ type: "spki",
32
+ });
33
+ }
34
+ export function keyFromEd25519Private(seed32) {
35
+ return createPrivateKey({
36
+ key: derPkcs8(ED25519_PKCS8_PREFIX, seed32),
37
+ format: "der",
38
+ type: "pkcs8",
39
+ });
40
+ }
41
+ export function keyFromEd25519Public(raw32) {
42
+ return createPublicKey({
43
+ key: derSpki(ED25519_SPKI_PREFIX, raw32),
44
+ format: "der",
45
+ type: "spki",
46
+ });
47
+ }
48
+ function rawPublicFromSpki(keyObject, prefix, label) {
49
+ const der = keyObject.export({ format: "der", type: "spki" });
50
+ if (!Buffer.isBuffer(der)) {
51
+ throw new TypeError(`${label} SPKI export must be a Buffer`);
52
+ }
53
+ if (der.byteLength !== prefix.length + 32) {
54
+ throw new Error(`${label} SPKI DER length mismatch`);
55
+ }
56
+ const exportedPrefix = der.subarray(0, prefix.length);
57
+ if (!timingSafeEqual(exportedPrefix, prefix)) {
58
+ throw new Error(`${label} SPKI DER prefix mismatch`);
59
+ }
60
+ const raw = new Uint8Array(der.buffer, der.byteOffset + prefix.length, 32);
61
+ return asBytes32(raw, `${label} public key`);
62
+ }
63
+ export function rawPublicFromX25519Spki(keyObject) {
64
+ return rawPublicFromSpki(keyObject, X25519_SPKI_PREFIX, "X25519");
65
+ }
66
+ export function rawPublicFromEd25519Spki(keyObject) {
67
+ return rawPublicFromSpki(keyObject, ED25519_SPKI_PREFIX, "Ed25519");
68
+ }
69
+ //# sourceMappingURL=der.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"der.js","sourceRoot":"","sources":["../../src/internal/der.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ declare const bytes32Brand: unique symbol;
2
+ declare const bytes64Brand: unique symbol;
3
+ export type Bytes32 = Uint8Array & {
4
+ readonly __brand: typeof bytes32Brand;
5
+ };
6
+ export type Bytes64 = Uint8Array & {
7
+ readonly __brand: typeof bytes64Brand;
8
+ };
9
+ export interface KeyPair32 {
10
+ public: Bytes32;
11
+ private: Bytes32;
12
+ }
13
+ export {};
14
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,YAAY,EAAE,OAAO,MAAM,CAAC;AAC1C,OAAO,CAAC,MAAM,YAAY,EAAE,OAAO,MAAM,CAAC;AAE1C,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,YAAY,CAAA;CAAE,CAAC;AAC7E,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,OAAO,YAAY,CAAA;CAAE,CAAC;AAE7E,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import type { Bytes32, KeyPair32 } from "./types.js";
2
+ /**
3
+ * Derives an X25519 public key from a raw 32-byte secret scalar.
4
+ */
5
+ export declare function publicKey(secretKey32: Bytes32): Bytes32;
6
+ /**
7
+ * Computes X25519 ECDH shared secret (raw 32 bytes).
8
+ */
9
+ export declare function sharedKey(secretKey32: Bytes32, publicKey32: Bytes32): Bytes32;
10
+ /**
11
+ * Deterministically creates an X25519 key pair from a 32-byte seed.
12
+ * The returned private key is explicitly clamped for stable output.
13
+ */
14
+ export declare function generateKeyPair(seed32: Bytes32): KeyPair32;
15
+ //# sourceMappingURL=x25519.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x25519.d.ts","sourceRoot":"","sources":["../src/x25519.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAWrD;;GAEG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,OAAO,GAAG,OAAO,CAIvD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAa7E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAQ1D"}
package/dist/x25519.js ADDED
@@ -0,0 +1,48 @@
1
+ import { createPublicKey, diffieHellman } from "node:crypto";
2
+ import { asBytes32, assertBytes32 } from "./internal/assert.js";
3
+ import { keyFromX25519Private, keyFromX25519Public, rawPublicFromX25519Spki, } from "./internal/der.js";
4
+ function clampScalar(seed32) {
5
+ const clamped = new Uint8Array(32);
6
+ clamped.set(seed32);
7
+ clamped[0] = (clamped[0] ?? 0) & 248;
8
+ const last = clamped[31] ?? 0;
9
+ clamped[31] = (last & 127) | 64;
10
+ return asBytes32(clamped, "clamped scalar");
11
+ }
12
+ /**
13
+ * Derives an X25519 public key from a raw 32-byte secret scalar.
14
+ */
15
+ export function publicKey(secretKey32) {
16
+ assertBytes32(secretKey32, "secretKey32");
17
+ const privateKey = keyFromX25519Private(secretKey32);
18
+ return rawPublicFromX25519Spki(createPublicKey(privateKey));
19
+ }
20
+ /**
21
+ * Computes X25519 ECDH shared secret (raw 32 bytes).
22
+ */
23
+ export function sharedKey(secretKey32, publicKey32) {
24
+ assertBytes32(secretKey32, "secretKey32");
25
+ assertBytes32(publicKey32, "publicKey32");
26
+ const shared = diffieHellman({
27
+ privateKey: keyFromX25519Private(secretKey32),
28
+ publicKey: keyFromX25519Public(publicKey32),
29
+ });
30
+ if (shared.byteLength !== 32) {
31
+ throw new Error(`X25519 shared secret must be 32 bytes, received ${shared.byteLength}`);
32
+ }
33
+ return asBytes32(new Uint8Array(shared.buffer, shared.byteOffset, shared.byteLength), "sharedKey");
34
+ }
35
+ /**
36
+ * Deterministically creates an X25519 key pair from a 32-byte seed.
37
+ * The returned private key is explicitly clamped for stable output.
38
+ */
39
+ export function generateKeyPair(seed32) {
40
+ assertBytes32(seed32, "seed32");
41
+ const privateKey = clampScalar(seed32);
42
+ const publicKey32 = publicKey(privateKey);
43
+ return {
44
+ public: publicKey32,
45
+ private: privateKey,
46
+ };
47
+ }
48
+ //# sourceMappingURL=x25519.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"x25519.js","sourceRoot":"","sources":["../src/x25519.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAG3B,SAAS,WAAW,CAAC,MAAe;IAClC,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,CAAC;IACrC,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAChC,OAAO,SAAS,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,WAAoB;IAC5C,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,MAAM,UAAU,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC;IACrD,OAAO,uBAAuB,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,WAAoB,EAAE,WAAoB;IAClE,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAC1C,aAAa,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;IAE1C,MAAM,MAAM,GAAG,aAAa,CAAC;QAC3B,UAAU,EAAE,oBAAoB,CAAC,WAAW,CAAC;QAC7C,SAAS,EAAE,mBAAmB,CAAC,WAAW,CAAC;KAC5C,CAAC,CAAC;IAEH,IAAI,MAAM,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,mDAAmD,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,SAAS,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,WAAW,CAAC,CAAC;AACrG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC7C,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAChC,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,WAAW,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO;QACL,MAAM,EAAE,WAAW;QACnB,OAAO,EAAE,UAAU;KACpB,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,77 @@
1
+ {
2
+ "name": "@unknownncat/curve25519-node",
3
+ "version": "1.0.0",
4
+ "description": "Modern zero-dependency X25519 + Ed25519 for Node.js using OpenSSL via node:crypto",
5
+ "keywords": [
6
+ "curve25519",
7
+ "x25519",
8
+ "ed25519",
9
+ "crypto",
10
+ "cryptography",
11
+ "openssl",
12
+ "node"
13
+ ],
14
+ "homepage": "https://github.com/unknownncat/curve25519-node#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/unknownncat/curve25519-node/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/unknownncat/curve25519-node.git"
21
+ },
22
+ "license": "MIT",
23
+ "author": "unknownncat",
24
+ "type": "module",
25
+ "sideEffects": false,
26
+ "main": "./dist/cjs/index.js",
27
+ "module": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "exports": {
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js",
33
+ "require": "./dist/cjs/index.js",
34
+ "default": "./dist/index.js"
35
+ },
36
+ "./x25519": {
37
+ "types": "./dist/x25519.d.ts",
38
+ "import": "./dist/x25519.js",
39
+ "require": "./dist/cjs/x25519.js",
40
+ "default": "./dist/x25519.js"
41
+ },
42
+ "./ed25519": {
43
+ "types": "./dist/ed25519.d.ts",
44
+ "import": "./dist/ed25519.js",
45
+ "require": "./dist/cjs/ed25519.js",
46
+ "default": "./dist/ed25519.js"
47
+ },
48
+ "./types": {
49
+ "types": "./dist/types.d.ts",
50
+ "import": "./dist/types.js",
51
+ "require": "./dist/cjs/types.js",
52
+ "default": "./dist/types.js"
53
+ },
54
+ "./package.json": "./package.json"
55
+ },
56
+ "files": [
57
+ "dist/**/*",
58
+ "README.md",
59
+ "LICENSE"
60
+ ],
61
+ "engines": {
62
+ "node": ">=20"
63
+ },
64
+ "scripts": {
65
+ "clean": "node scripts/clean.mjs",
66
+ "build:esm": "tsc -p tsconfig.json",
67
+ "build:cjs": "tsc -p tsconfig.cjs.json && node scripts/write-cjs-package-json.mjs",
68
+ "build": "npm run clean && npm run build:esm && npm run build:cjs",
69
+ "test": "npm run build && node --test \"test/*.test.mjs\"",
70
+ "prepack": "npm run test",
71
+ "prepublishOnly": "npm run test"
72
+ },
73
+ "devDependencies": {
74
+ "@types/node": "^22.18.6",
75
+ "typescript": "^5.9.2"
76
+ }
77
+ }