@hg-ts/rsa 0.7.24 → 0.7.26
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/README.md +331 -0
- package/dist/X25519/index.d.ts +4 -0
- package/dist/X25519/index.d.ts.map +1 -0
- package/dist/X25519/index.js +4 -0
- package/dist/X25519/index.js.map +1 -0
- package/dist/X25519/key-pair.d.ts +13 -0
- package/dist/X25519/key-pair.d.ts.map +1 -0
- package/dist/X25519/key-pair.js +39 -0
- package/dist/X25519/key-pair.js.map +1 -0
- package/dist/X25519/private-key.d.ts +11 -0
- package/dist/X25519/private-key.d.ts.map +1 -0
- package/dist/X25519/private-key.js +40 -0
- package/dist/X25519/private-key.js.map +1 -0
- package/dist/X25519/public-key.d.ts +13 -0
- package/dist/X25519/public-key.d.ts.map +1 -0
- package/dist/X25519/public-key.js +49 -0
- package/dist/X25519/public-key.js.map +1 -0
- package/dist/X25519/utils.d.ts +2 -0
- package/dist/X25519/utils.d.ts.map +1 -0
- package/dist/X25519/utils.js +12 -0
- package/dist/X25519/utils.js.map +1 -0
- package/dist/X25519/x25519.test.d.ts +18 -0
- package/dist/X25519/x25519.test.d.ts.map +1 -0
- package/dist/X25519/x25519.test.js +183 -0
- package/dist/X25519/x25519.test.js.map +1 -0
- package/dist/base/index.d.ts +5 -0
- package/dist/base/index.d.ts.map +1 -0
- package/dist/base/index.js +5 -0
- package/dist/base/index.js.map +1 -0
- package/dist/base/key-pair.d.ts +27 -0
- package/dist/base/key-pair.d.ts.map +1 -0
- package/dist/base/key-pair.js +29 -0
- package/dist/base/key-pair.js.map +1 -0
- package/dist/base/key.d.ts +7 -0
- package/dist/base/key.d.ts.map +1 -0
- package/dist/base/key.js +10 -0
- package/dist/base/key.js.map +1 -0
- package/dist/base/private-key.d.ts +11 -0
- package/dist/base/private-key.d.ts.map +1 -0
- package/dist/base/private-key.js +4 -0
- package/dist/base/private-key.js.map +1 -0
- package/dist/base/public-key.d.ts +6 -0
- package/dist/base/public-key.d.ts.map +1 -0
- package/dist/base/public-key.js +4 -0
- package/dist/base/public-key.js.map +1 -0
- package/dist/exceptions/index.d.ts +2 -0
- package/dist/exceptions/index.d.ts.map +1 -0
- package/dist/exceptions/index.js +2 -0
- package/dist/exceptions/index.js.map +1 -0
- package/dist/exceptions/invalid-decryption-key.expection.d.ts +5 -0
- package/dist/exceptions/invalid-decryption-key.expection.d.ts.map +1 -0
- package/dist/exceptions/invalid-decryption-key.expection.js +7 -0
- package/dist/exceptions/invalid-decryption-key.expection.js.map +1 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/rsa/index.d.ts +4 -0
- package/dist/rsa/index.d.ts.map +1 -0
- package/dist/rsa/index.js +4 -0
- package/dist/rsa/index.js.map +1 -0
- package/dist/rsa/key-pair.d.ts +12 -0
- package/dist/rsa/key-pair.d.ts.map +1 -0
- package/dist/rsa/key-pair.js +40 -0
- package/dist/rsa/key-pair.js.map +1 -0
- package/dist/rsa/private-key.d.ts +16 -0
- package/dist/rsa/private-key.d.ts.map +1 -0
- package/dist/rsa/private-key.js +65 -0
- package/dist/rsa/private-key.js.map +1 -0
- package/dist/rsa/public-key.d.ts +19 -0
- package/dist/rsa/public-key.d.ts.map +1 -0
- package/dist/rsa/public-key.js +85 -0
- package/dist/rsa/public-key.js.map +1 -0
- package/dist/{rsa.test.d.ts → rsa/rsa.test.d.ts} +6 -0
- package/dist/rsa/rsa.test.d.ts.map +1 -0
- package/dist/{rsa.test.js → rsa/rsa.test.js} +101 -24
- package/dist/rsa/rsa.test.js.map +1 -0
- package/package.json +11 -9
- package/src/X25519/index.ts +3 -0
- package/src/X25519/key-pair.ts +58 -0
- package/src/X25519/private-key.ts +54 -0
- package/src/X25519/public-key.ts +68 -0
- package/src/X25519/utils.ts +22 -0
- package/src/X25519/x25519.test.ts +150 -0
- package/src/base/index.ts +4 -0
- package/src/base/key-pair.ts +75 -0
- package/src/base/key.ts +13 -0
- package/src/base/private-key.ts +17 -0
- package/src/base/public-key.ts +7 -0
- package/src/exceptions/index.ts +1 -0
- package/src/exceptions/invalid-decryption-key.expection.ts +7 -0
- package/src/index.ts +4 -3
- package/src/rsa/index.ts +3 -0
- package/src/rsa/key-pair.ts +55 -0
- package/src/rsa/private-key.ts +82 -0
- package/src/rsa/public-key.ts +110 -0
- package/src/rsa/rsa.test.ts +194 -0
- package/dist/rsa.base-key.d.ts +0 -16
- package/dist/rsa.base-key.d.ts.map +0 -1
- package/dist/rsa.base-key.js +0 -54
- package/dist/rsa.base-key.js.map +0 -1
- package/dist/rsa.key-pair.d.ts +0 -19
- package/dist/rsa.key-pair.d.ts.map +0 -1
- package/dist/rsa.key-pair.js +0 -46
- package/dist/rsa.key-pair.js.map +0 -1
- package/dist/rsa.private-key.d.ts +0 -13
- package/dist/rsa.private-key.d.ts.map +0 -1
- package/dist/rsa.private-key.js +0 -38
- package/dist/rsa.private-key.js.map +0 -1
- package/dist/rsa.public-key.d.ts +0 -13
- package/dist/rsa.public-key.d.ts.map +0 -1
- package/dist/rsa.public-key.js +0 -52
- package/dist/rsa.public-key.js.map +0 -1
- package/dist/rsa.test.d.ts.map +0 -1
- package/dist/rsa.test.js.map +0 -1
- package/src/rsa.base-key.ts +0 -75
- package/src/rsa.key-pair.ts +0 -65
- package/src/rsa.private-key.ts +0 -50
- package/src/rsa.public-key.ts +0 -65
- package/src/rsa.test.ts +0 -134
package/README.md
ADDED
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
# @hg-ts/rsa
|
|
2
|
+
|
|
3
|
+
Пакет-обёртка над `node-forge` для:
|
|
4
|
+
|
|
5
|
+
- генерации RSA key pair;
|
|
6
|
+
- шифрования и расшифровки строк;
|
|
7
|
+
- подписи и проверки подписи;
|
|
8
|
+
- восстановления ключей из PEM.
|
|
9
|
+
|
|
10
|
+
## Экспорт
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import {
|
|
14
|
+
RsaKeyPair,
|
|
15
|
+
RsaPrivateKey,
|
|
16
|
+
RsaPublicKey,
|
|
17
|
+
} from '@hg-ts/rsa';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Пакет экспортирует только основной entrypoint `.` и сейчас не имеет отдельного browser entry в `package.json`.
|
|
21
|
+
|
|
22
|
+
## API
|
|
23
|
+
|
|
24
|
+
### `RsaKeyPair`
|
|
25
|
+
|
|
26
|
+
Создаёт новую пару ключей или восстанавливает её из приватного ключа.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
type RsaKeyPairOptions = {
|
|
30
|
+
seed?: string;
|
|
31
|
+
bits?: number;
|
|
32
|
+
privateKey?: RsaPrivateKey | string;
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Пример:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const rsa = new RsaKeyPair({ bits: 2048 });
|
|
40
|
+
|
|
41
|
+
const encrypted = rsa.encrypt('hello');
|
|
42
|
+
const decrypted = rsa.decrypt(encrypted);
|
|
43
|
+
|
|
44
|
+
const signature = rsa.sign('hello');
|
|
45
|
+
const isValid = rsa.verify(signature, 'hello');
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Методы и свойства:
|
|
49
|
+
|
|
50
|
+
- `encrypt(value: string | Buffer): Buffer`
|
|
51
|
+
- `decrypt(value: string | Buffer): string`
|
|
52
|
+
- `sign(value: string): Buffer`
|
|
53
|
+
- `verify(signature: string | Buffer, value: string): boolean`
|
|
54
|
+
- `publicKey: string`
|
|
55
|
+
- `privateKey: string`
|
|
56
|
+
|
|
57
|
+
Особенности текущего поведения:
|
|
58
|
+
|
|
59
|
+
- если `encrypt` получает строку, `decrypt` возвращает исходную строку;
|
|
60
|
+
- если `encrypt` получает `Buffer`, `decrypt` возвращает hex-строку, из которой вызывающий код должен сам собрать `Buffer`;
|
|
61
|
+
- при `privateKey` в опциях новая пара не генерируется, а публичный ключ вычисляется из переданного приватного ключа;
|
|
62
|
+
- при `seed` используется детерминированная генерация через PRNG `node-forge`.
|
|
63
|
+
|
|
64
|
+
### `RsaPrivateKey`
|
|
65
|
+
|
|
66
|
+
Создание из PEM:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const privateKey = RsaPrivateKey.fromString(pem);
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Методы:
|
|
73
|
+
|
|
74
|
+
- `decrypt(encrypted: string | Buffer): string`
|
|
75
|
+
- `sign(value: string): Buffer`
|
|
76
|
+
- `toPublicKey(): RsaPublicKey`
|
|
77
|
+
- `toString(): string`
|
|
78
|
+
- `static fromString(pemKey: string): RsaPrivateKey`
|
|
79
|
+
|
|
80
|
+
### `RsaPublicKey`
|
|
81
|
+
|
|
82
|
+
Создание из PEM:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const publicKey = RsaPublicKey.fromString(pem);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Методы:
|
|
89
|
+
|
|
90
|
+
- `encrypt(value: string | Buffer): Buffer`
|
|
91
|
+
- `verify(signature: string | Buffer, value: string): boolean`
|
|
92
|
+
- `toString(): string`
|
|
93
|
+
- `static fromString(pemKey: string): RsaPublicKey`
|
|
94
|
+
- `static schema`
|
|
95
|
+
|
|
96
|
+
`RsaPublicKey.schema` валидирует PEM публичного ключа и нормализует его через повторную сериализацию.
|
|
97
|
+
|
|
98
|
+
## Криптографическое поведение
|
|
99
|
+
|
|
100
|
+
По текущей реализации пакет использует:
|
|
101
|
+
|
|
102
|
+
- шифрование `RSAES-PKCS1-V1_5`;
|
|
103
|
+
- подпись `RSA-PSS`;
|
|
104
|
+
- хеш `SHA-256`;
|
|
105
|
+
- `saltLength: 20` для PSS.
|
|
106
|
+
|
|
107
|
+
См. реализацию:
|
|
108
|
+
|
|
109
|
+
- [rsa.public-key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.public-key.ts:32)
|
|
110
|
+
- [rsa.private-key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.private-key.ts:17)
|
|
111
|
+
- [base.key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/base.key.ts:55)
|
|
112
|
+
|
|
113
|
+
## Ограничения реализации
|
|
114
|
+
|
|
115
|
+
### Работа с длинными сообщениями
|
|
116
|
+
|
|
117
|
+
Пакет поддерживает длинные сообщения через ручное разбиение входа на чанки перед RSA-операцией.
|
|
118
|
+
|
|
119
|
+
Размер чанка вычисляется как:
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
keyLength - (digestLength * 2) - 2
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Это поведение зафиксировано в [base.key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/base.key.ts:59).
|
|
126
|
+
|
|
127
|
+
Важно:
|
|
128
|
+
|
|
129
|
+
- разбиение происходит по внутреннему строковому представлению;
|
|
130
|
+
- для строк используется UTF-8;
|
|
131
|
+
- для `Buffer` данные сначала переводятся в hex-строку, а не шифруются как сырые байты.
|
|
132
|
+
|
|
133
|
+
Из-за этого бинарный API фактически работает как transport для hex-представления.
|
|
134
|
+
|
|
135
|
+
### Неоднородный контракт `decrypt`
|
|
136
|
+
|
|
137
|
+
`decrypt` всегда возвращает `string`, но семантика строки зависит от исходного типа входа:
|
|
138
|
+
|
|
139
|
+
- для текстового сообщения это обычный текст;
|
|
140
|
+
- для бинарного сообщения это hex.
|
|
141
|
+
|
|
142
|
+
Этот контракт стоит учитывать в интеграциях и тестах.
|
|
143
|
+
|
|
144
|
+
## Browser-safe отчёт
|
|
145
|
+
|
|
146
|
+
### Итог
|
|
147
|
+
|
|
148
|
+
В текущем состоянии пакет нельзя считать гарантированно browser-safe.
|
|
149
|
+
|
|
150
|
+
### Причины
|
|
151
|
+
|
|
152
|
+
1. Публичный API и внутренняя реализация завязаны на `Buffer`.
|
|
153
|
+
|
|
154
|
+
Подтверждение:
|
|
155
|
+
|
|
156
|
+
- [base.key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/base.key.ts:12)
|
|
157
|
+
- [rsa.public-key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.public-key.ts:32)
|
|
158
|
+
- [rsa.private-key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.private-key.ts:17)
|
|
159
|
+
- [rsa.key-pair.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.key-pair.ts:22)
|
|
160
|
+
|
|
161
|
+
Для браузера это означает зависимость от полифила `Buffer` как минимум на runtime-уровне.
|
|
162
|
+
|
|
163
|
+
2. Пакет не публикует browser entrypoint.
|
|
164
|
+
|
|
165
|
+
Подтверждение:
|
|
166
|
+
|
|
167
|
+
- [package.json](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/package.json:6)
|
|
168
|
+
|
|
169
|
+
Сейчас export только один:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
".": "./dist/index.js"
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
3. `RsaPublicKey` импортирует основной entrypoint `@hg-ts/validation`, который сам тянет node-specific расширения и `Buffer`-зависимые схемы.
|
|
178
|
+
|
|
179
|
+
Подтверждение:
|
|
180
|
+
|
|
181
|
+
- [rsa.public-key.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.public-key.ts:1)
|
|
182
|
+
- [validation/index.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/validation/src/index.ts:1)
|
|
183
|
+
- [validation/node-schemas.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/validation/src/node-schemas.ts:3)
|
|
184
|
+
|
|
185
|
+
### Практический вывод
|
|
186
|
+
|
|
187
|
+
С высокой вероятностью пакет будет работать:
|
|
188
|
+
|
|
189
|
+
- в Node.js;
|
|
190
|
+
- в браузере только при наличии совместимого bundler setup и полифилов.
|
|
191
|
+
|
|
192
|
+
Сейчас пакет не выглядит как "безусловно безопасный для браузера" library package, который можно подключить в frontend без дополнительных условий.
|
|
193
|
+
|
|
194
|
+
### Что проверить отдельно перед использованием в браузере
|
|
195
|
+
|
|
196
|
+
- есть ли в бандлере полифил `Buffer`;
|
|
197
|
+
- как резолвится `node-forge` в browser bundle;
|
|
198
|
+
- не подтягивается ли `@hg-ts/validation` main entry вместо browser entry;
|
|
199
|
+
- нет ли падения при импорте пакета без вызова методов;
|
|
200
|
+
- нет ли рассинхронизации между Node и browser по кодировкам `binary`/`hex`/`utf8`.
|
|
201
|
+
|
|
202
|
+
## Сценарии тестирования, которые стоит покрыть
|
|
203
|
+
|
|
204
|
+
Ниже список сценариев, которые стоит иметь в автоматическом покрытии. Часть из них уже есть, часть сейчас отсутствует.
|
|
205
|
+
|
|
206
|
+
### Уже покрыто
|
|
207
|
+
|
|
208
|
+
- создание key pair;
|
|
209
|
+
- восстановление key pair из приватного ключа и PEM-строки;
|
|
210
|
+
- encrypt/decrypt для ASCII-строки;
|
|
211
|
+
- encrypt/decrypt для UTF-8 строки;
|
|
212
|
+
- encrypt/decrypt для длинного сообщения;
|
|
213
|
+
- sign/verify;
|
|
214
|
+
- детерминированная генерация по `seed`;
|
|
215
|
+
- валидация публичного ключа.
|
|
216
|
+
|
|
217
|
+
См. [rsa.test.ts](/Users/atsapko/Documents/Hyper%20Graph/social%20network/framework/packages/rsa/src/rsa.test.ts:1).
|
|
218
|
+
|
|
219
|
+
### Стоит добавить в покрытие
|
|
220
|
+
|
|
221
|
+
1. Негативные кейсы подписи.
|
|
222
|
+
|
|
223
|
+
Нужно проверить:
|
|
224
|
+
|
|
225
|
+
- `verify` с изменённым payload;
|
|
226
|
+
- `verify` подписи от другого ключа;
|
|
227
|
+
- `verify` для повреждённой подписи;
|
|
228
|
+
- `verify` для пустой подписи.
|
|
229
|
+
|
|
230
|
+
2. Негативные кейсы расшифровки.
|
|
231
|
+
|
|
232
|
+
Нужно проверить:
|
|
233
|
+
|
|
234
|
+
- decrypt чужим приватным ключом;
|
|
235
|
+
- decrypt повреждённого ciphertext;
|
|
236
|
+
- decrypt обрезанного ciphertext;
|
|
237
|
+
- decrypt строки не в hex-формате.
|
|
238
|
+
|
|
239
|
+
3. Граничные размеры сообщения.
|
|
240
|
+
|
|
241
|
+
Нужно покрыть:
|
|
242
|
+
|
|
243
|
+
- сообщение ровно в один chunk;
|
|
244
|
+
- сообщение на один символ меньше лимита;
|
|
245
|
+
- сообщение на один символ больше лимита;
|
|
246
|
+
- несколько chunk-ов подряд.
|
|
247
|
+
|
|
248
|
+
4. Бинарные payload-ы.
|
|
249
|
+
|
|
250
|
+
Нужно проверить:
|
|
251
|
+
|
|
252
|
+
- пустой `Buffer`;
|
|
253
|
+
- бинарные данные с нулевыми байтами;
|
|
254
|
+
- бинарные данные со всеми значениями `0x00..0xFF`;
|
|
255
|
+
- корректность round-trip через `decrypt(...)->hex->Buffer.from(hex, 'hex')`.
|
|
256
|
+
|
|
257
|
+
5. PEM parsing.
|
|
258
|
+
|
|
259
|
+
Нужно проверить:
|
|
260
|
+
|
|
261
|
+
- invalid private key PEM;
|
|
262
|
+
- public key PEM с лишними пробелами и переводами строк;
|
|
263
|
+
- не-RSA PEM;
|
|
264
|
+
- encrypted private key PEM, если такой формат не поддерживается.
|
|
265
|
+
|
|
266
|
+
6. Конфигурационные кейсы генерации.
|
|
267
|
+
|
|
268
|
+
Нужно проверить:
|
|
269
|
+
|
|
270
|
+
- `bits` по умолчанию;
|
|
271
|
+
- очень маленькие значения `bits`;
|
|
272
|
+
- недопустимые значения `bits`;
|
|
273
|
+
- комбинацию `seed + bits`;
|
|
274
|
+
- приоритет `privateKey` над `seed`.
|
|
275
|
+
|
|
276
|
+
7. Browser smoke tests.
|
|
277
|
+
|
|
278
|
+
Минимально стоит иметь:
|
|
279
|
+
|
|
280
|
+
- импорт пакета в browser-like окружении;
|
|
281
|
+
- encrypt/decrypt строки в browser runner;
|
|
282
|
+
- sign/verify строки в browser runner;
|
|
283
|
+
- тест без явного использования `globalThis.Buffer`, если пакет заявляется как browser-safe.
|
|
284
|
+
|
|
285
|
+
## Примеры
|
|
286
|
+
|
|
287
|
+
### Генерация ключей
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import { RsaKeyPair } from '@hg-ts/rsa';
|
|
291
|
+
|
|
292
|
+
const rsa = new RsaKeyPair({ bits: 2048 });
|
|
293
|
+
|
|
294
|
+
console.log(rsa.publicKey);
|
|
295
|
+
console.log(rsa.privateKey);
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
### Восстановление из приватного ключа
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
import { RsaKeyPair } from '@hg-ts/rsa';
|
|
302
|
+
|
|
303
|
+
const restored = new RsaKeyPair({
|
|
304
|
+
privateKey: existingPrivatePem,
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### Подпись и проверка
|
|
309
|
+
|
|
310
|
+
```ts
|
|
311
|
+
const rsa = new RsaKeyPair({ bits: 2048 });
|
|
312
|
+
const payload = JSON.stringify({ id: '123' });
|
|
313
|
+
|
|
314
|
+
const signature = rsa.sign(payload);
|
|
315
|
+
const ok = rsa.verify(signature, payload);
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### Шифрование бинарных данных
|
|
319
|
+
|
|
320
|
+
```ts
|
|
321
|
+
const rsa = new RsaKeyPair({ bits: 2048 });
|
|
322
|
+
const payload = Buffer.from('hello');
|
|
323
|
+
|
|
324
|
+
const encrypted = rsa.encrypt(payload);
|
|
325
|
+
const decryptedHex = rsa.decrypt(encrypted);
|
|
326
|
+
const decrypted = Buffer.from(decryptedHex, 'hex');
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
## Вывод
|
|
330
|
+
|
|
331
|
+
Пакет решает базовые задачи RSA и уже покрыт позитивными сценариями, но его текущий контракт ориентирован в первую очередь на Node.js. Для browser-safe статуса не хватает как минимум отдельного browser-compatible entrypoint, отказа от жёсткой зависимости на `Buffer` и отдельного browser smoke coverage.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/X25519/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/X25519/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { BaseKeyPair, KeyPairOptions, KeyPairResult, NewKeyPairOptions } from '../base/index.js';
|
|
2
|
+
import { X25519PrivateKey } from './private-key.js';
|
|
3
|
+
import { X25519PublicKey } from './public-key.js';
|
|
4
|
+
export declare class X25519KeyPair extends BaseKeyPair<X25519PrivateKey, X25519PublicKey> {
|
|
5
|
+
constructor(options?: KeyPairOptions<X25519PrivateKey>);
|
|
6
|
+
encrypt(value: string | Buffer, recipientPublicKey: X25519PublicKey): Buffer;
|
|
7
|
+
decrypt(value: string | Buffer, senderPublicKey: X25519PublicKey): string;
|
|
8
|
+
sign(value: string): Buffer;
|
|
9
|
+
verify(signature: string | Buffer, value: string): boolean;
|
|
10
|
+
protected generateNewKeys(options: NewKeyPairOptions): KeyPairResult<X25519PrivateKey, X25519PublicKey>;
|
|
11
|
+
private generatePrivateKey;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=key-pair.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-pair.d.ts","sourceRoot":"","sources":["../../src/X25519/key-pair.ts"],"names":[],"mappings":"AACA,OAAO,EACN,WAAW,EACX,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAElD,qBAAa,aAAc,SAAQ,WAAW,CAC7C,gBAAgB,EAChB,eAAe,CACf;gBACmB,OAAO,GAAE,cAAc,CAAC,gBAAgB,CAAM;IAIjD,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,kBAAkB,EAAE,eAAe,GAAG,MAAM;IAI5E,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,eAAe,EAAE,eAAe,GAAG,MAAM;IAIzE,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI3B,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1E,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa,CAAC,gBAAgB,EAAE,eAAe,CAAC;IAUvG,OAAO,CAAC,kBAAkB;CAa1B"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import sodium from 'libsodium-wrappers';
|
|
2
|
+
import { BaseKeyPair, } from '../base/index.js';
|
|
3
|
+
import { X25519PrivateKey } from './private-key.js';
|
|
4
|
+
export class X25519KeyPair extends BaseKeyPair {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
super(options, X25519PrivateKey);
|
|
7
|
+
}
|
|
8
|
+
encrypt(value, recipientPublicKey) {
|
|
9
|
+
return recipientPublicKey.encrypt(value, this.privateKeyInstance);
|
|
10
|
+
}
|
|
11
|
+
decrypt(value, senderPublicKey) {
|
|
12
|
+
return this.privateKeyInstance.decrypt(value, senderPublicKey);
|
|
13
|
+
}
|
|
14
|
+
sign(value) {
|
|
15
|
+
return this.privateKeyInstance.sign(value);
|
|
16
|
+
}
|
|
17
|
+
verify(signature, value) {
|
|
18
|
+
return this.publicKeyInstance.verify(signature, value);
|
|
19
|
+
}
|
|
20
|
+
generateNewKeys(options) {
|
|
21
|
+
const privateKey = this.generatePrivateKey(options.seed);
|
|
22
|
+
const privateKeyInstance = new X25519PrivateKey(privateKey);
|
|
23
|
+
return {
|
|
24
|
+
privateKey: privateKeyInstance,
|
|
25
|
+
publicKey: privateKeyInstance.toPublicKey(),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
generatePrivateKey(seed) {
|
|
29
|
+
if (!seed) {
|
|
30
|
+
return Buffer.from(sodium.randombytes_buf(sodium.crypto_scalarmult_SCALARBYTES));
|
|
31
|
+
}
|
|
32
|
+
const bytes = Buffer.from(seed, 'utf8');
|
|
33
|
+
if (bytes.length === sodium.crypto_scalarmult_SCALARBYTES) {
|
|
34
|
+
return bytes;
|
|
35
|
+
}
|
|
36
|
+
return Buffer.from(sodium.crypto_generichash(sodium.crypto_scalarmult_SCALARBYTES, bytes, null));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=key-pair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-pair.js","sourceRoot":"","sources":["../../src/X25519/key-pair.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EACN,WAAW,GAIX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,OAAO,aAAc,SAAQ,WAGlC;IACA,YAAmB,UAA4C,EAAE;QAChE,KAAK,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;IAClC,CAAC;IAEe,OAAO,CAAC,KAAsB,EAAE,kBAAmC;QAClF,OAAO,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACnE,CAAC;IAEe,OAAO,CAAC,KAAsB,EAAE,eAAgC;QAC/E,OAAO,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;IAChE,CAAC;IAEe,IAAI,CAAC,KAAa;QACjC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5C,CAAC;IAEe,MAAM,CAAC,SAA0B,EAAE,KAAa;QAC/D,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;IAES,eAAe,CAAC,OAA0B;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACzD,MAAM,kBAAkB,GAAG,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC;QAE5D,OAAO;YACN,UAAU,EAAE,kBAAkB;YAC9B,SAAS,EAAE,kBAAkB,CAAC,WAAW,EAAE;SAC3C,CAAC;IACH,CAAC;IAEO,kBAAkB,CAAC,IAAa;QACvC,IAAI,CAAC,IAAI,EAAE,CAAC;YACX,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,6BAA6B,CAAC,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAExC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,6BAA6B,EAAE,CAAC;YAC3D,OAAO,KAAK,CAAC;QACd,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,6BAA6B,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAClG,CAAC;CACD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BasePrivateKey } from '../base/index.js';
|
|
2
|
+
import { X25519PublicKey } from './public-key.js';
|
|
3
|
+
export declare class X25519PrivateKey extends BasePrivateKey<Buffer, X25519PublicKey> {
|
|
4
|
+
decrypt(encrypted: string | Buffer, senderPublicKeyInstance: X25519PublicKey): string;
|
|
5
|
+
sign(_value: string): Buffer;
|
|
6
|
+
toPublicKey(): X25519PublicKey;
|
|
7
|
+
toString(): string;
|
|
8
|
+
get nativeKey(): Buffer;
|
|
9
|
+
static fromString(value: string): X25519PrivateKey;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=private-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"private-key.d.ts","sourceRoot":"","sources":["../../src/X25519/private-key.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,qBAAa,gBAAiB,SAAQ,cAAc,CAAC,MAAM,EAAE,eAAe,CAAC;IAC5D,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,uBAAuB,EAAE,eAAe,GAAG,MAAM;IA0BrF,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI5B,WAAW,IAAI,eAAe;IAI9B,QAAQ,IAAI,MAAM;IAIlC,IAAoB,SAAS,IAAI,MAAM,CAEtC;WAEa,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,gBAAgB;CAGzD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { NotImplementedException } from '@hg-ts/exception';
|
|
2
|
+
import sodium from 'libsodium-wrappers';
|
|
3
|
+
import { BasePrivateKey } from '../base/index.js';
|
|
4
|
+
import { InvalidDecryptionKeyExpection } from '../exceptions/index.js';
|
|
5
|
+
import { X25519PublicKey } from './public-key.js';
|
|
6
|
+
import { deriveEncryptionKey } from './utils.js';
|
|
7
|
+
export class X25519PrivateKey extends BasePrivateKey {
|
|
8
|
+
decrypt(encrypted, senderPublicKeyInstance) {
|
|
9
|
+
const payload = typeof encrypted === 'string' ? Buffer.from(encrypted, 'base64') : encrypted;
|
|
10
|
+
const senderPublicKey = senderPublicKeyInstance.nativeKey;
|
|
11
|
+
const sharedSecret = Buffer.from(sodium.crypto_scalarmult(this.key, senderPublicKey));
|
|
12
|
+
const publicKey = this.toPublicKey().nativeKey;
|
|
13
|
+
const encryptionKey = deriveEncryptionKey(sharedSecret, senderPublicKey, publicKey);
|
|
14
|
+
try {
|
|
15
|
+
const nonce = payload.subarray(0, 24);
|
|
16
|
+
const ciphertext = payload.subarray(24);
|
|
17
|
+
const decrypted = sodium.crypto_aead_xchacha20poly1305_ietf_decrypt(null, ciphertext, null, nonce, encryptionKey);
|
|
18
|
+
return Buffer.from(decrypted).toString('utf-8');
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
throw new InvalidDecryptionKeyExpection();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
sign(_value) {
|
|
25
|
+
throw new NotImplementedException();
|
|
26
|
+
}
|
|
27
|
+
toPublicKey() {
|
|
28
|
+
return new X25519PublicKey(Buffer.from(sodium.crypto_scalarmult_base(this.key)));
|
|
29
|
+
}
|
|
30
|
+
toString() {
|
|
31
|
+
return this.key.toString('base64');
|
|
32
|
+
}
|
|
33
|
+
get nativeKey() {
|
|
34
|
+
return Buffer.from(this.key);
|
|
35
|
+
}
|
|
36
|
+
static fromString(value) {
|
|
37
|
+
return new X25519PrivateKey(Buffer.from(value, 'base64'));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=private-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"private-key.js","sourceRoot":"","sources":["../../src/X25519/private-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,6BAA6B,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,OAAO,gBAAiB,SAAQ,cAAuC;IAC5D,OAAO,CAAC,SAA0B,EAAE,uBAAwC;QAC3F,MAAM,OAAO,GAAG,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAE7F,MAAM,eAAe,GAAG,uBAAuB,CAAC,SAAS,CAAC;QAC1D,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;QAEtF,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC;QAC/C,MAAM,aAAa,GAAG,mBAAmB,CAAC,YAAY,EAAE,eAAe,EAAE,SAAS,CAAC,CAAC;QAEpF,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,MAAM,CAAC,0CAA0C,CAClE,IAAI,EACJ,UAAU,EACV,IAAI,EACJ,KAAK,EACL,aAAa,CACb,CAAC;YAEF,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,IAAI,6BAA6B,EAAE,CAAC;QAC3C,CAAC;IACF,CAAC;IAEe,IAAI,CAAC,MAAc;QAClC,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACrC,CAAC;IAEe,WAAW;QAC1B,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAClF,CAAC;IAEe,QAAQ;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IAAoB,SAAS;QAC5B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,KAAa;QACrC,OAAO,IAAI,gBAAgB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3D,CAAC;CACD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from '@hg-ts/validation';
|
|
2
|
+
import { BasePublicKey } from '../base/index.js';
|
|
3
|
+
import type { X25519PrivateKey } from './private-key.js';
|
|
4
|
+
export declare class X25519PublicKey extends BasePublicKey<Buffer> {
|
|
5
|
+
static schema: z.ZodPipe<z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>, z.ZodString>;
|
|
6
|
+
encrypt(value: string | Buffer, senderPrivateKeyInstance: X25519PrivateKey): Buffer;
|
|
7
|
+
verify(_signature: string | Buffer, _value: string): boolean;
|
|
8
|
+
toString(): string;
|
|
9
|
+
get nativeKey(): Buffer;
|
|
10
|
+
static fromString(value: string): X25519PublicKey;
|
|
11
|
+
private formatInput;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=public-key.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-key.d.ts","sourceRoot":"","sources":["../../src/X25519/public-key.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAEtC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAoBzD,qBAAa,eAAgB,SAAQ,aAAa,CAAC,MAAM,CAAC;IACzD,OAAc,MAAM,iFAAU;IAEd,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,wBAAwB,EAAE,gBAAgB,GAAG,MAAM;IAmBnF,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAI5D,QAAQ,IAAI,MAAM;IAIlC,IAAoB,SAAS,IAAI,MAAM,CAEtC;WAEa,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe;IAIxD,OAAO,CAAC,WAAW;CAKnB"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { NotImplementedException } from '@hg-ts/exception';
|
|
2
|
+
import { z } from '@hg-ts/validation';
|
|
3
|
+
import sodium from 'libsodium-wrappers';
|
|
4
|
+
import { BasePublicKey } from '../base/index.js';
|
|
5
|
+
import { deriveEncryptionKey } from './utils.js';
|
|
6
|
+
const schema = z.string().transform((value, ctx) => {
|
|
7
|
+
const publicKey = Buffer.from(value, 'base64');
|
|
8
|
+
if (publicKey.length !== sodium.crypto_scalarmult_BYTES) {
|
|
9
|
+
ctx.issues.push({
|
|
10
|
+
message: 'Invalid X25519 public key',
|
|
11
|
+
fatal: true,
|
|
12
|
+
code: 'invalid_format',
|
|
13
|
+
input: value,
|
|
14
|
+
format: 'X25519 Public Key',
|
|
15
|
+
});
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
}).pipe(z.string());
|
|
20
|
+
export class X25519PublicKey extends BasePublicKey {
|
|
21
|
+
static schema = schema;
|
|
22
|
+
encrypt(value, senderPrivateKeyInstance) {
|
|
23
|
+
const senderPrivateKey = senderPrivateKeyInstance.nativeKey;
|
|
24
|
+
const sharedSecret = Buffer.from(sodium.crypto_scalarmult(senderPrivateKey, this.key));
|
|
25
|
+
const senderPublicKey = senderPrivateKeyInstance.toPublicKey().nativeKey;
|
|
26
|
+
const encryptionKey = deriveEncryptionKey(sharedSecret, senderPublicKey, this.key);
|
|
27
|
+
const nonce = Buffer.from(sodium.randombytes_buf(sodium.crypto_aead_xchacha20poly1305_ietf_NPUBBYTES));
|
|
28
|
+
const ciphertext = Buffer.from(sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(this.formatInput(value), null, null, nonce, encryptionKey));
|
|
29
|
+
return Buffer.concat([nonce, ciphertext]);
|
|
30
|
+
}
|
|
31
|
+
verify(_signature, _value) {
|
|
32
|
+
throw new NotImplementedException();
|
|
33
|
+
}
|
|
34
|
+
toString() {
|
|
35
|
+
return this.key.toString('base64');
|
|
36
|
+
}
|
|
37
|
+
get nativeKey() {
|
|
38
|
+
return Buffer.from(this.key);
|
|
39
|
+
}
|
|
40
|
+
static fromString(value) {
|
|
41
|
+
return new X25519PublicKey(Buffer.from(value, 'base64'));
|
|
42
|
+
}
|
|
43
|
+
formatInput(value) {
|
|
44
|
+
return typeof value === 'string'
|
|
45
|
+
? Buffer.from(value, 'utf8')
|
|
46
|
+
: value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=public-key.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-key.js","sourceRoot":"","sources":["../../src/X25519/public-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AACtC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE/C,IAAI,SAAS,CAAC,MAAM,KAAK,MAAM,CAAC,uBAAuB,EAAE,CAAC;QACzD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACf,OAAO,EAAE,2BAA2B;YACpC,KAAK,EAAE,IAAI;YACX,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,mBAAmB;SAC3B,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACd,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAEpB,MAAM,OAAO,eAAgB,SAAQ,aAAqB;IAClD,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IAEd,OAAO,CAAC,KAAsB,EAAE,wBAA0C;QACzF,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,SAAS,CAAC;QAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;QAEvF,MAAM,eAAe,GAAG,wBAAwB,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC;QACzE,MAAM,aAAa,GAAG,mBAAmB,CAAC,YAAY,EAAE,eAAe,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;QAEnF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACvG,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,0CAA0C,CAC/E,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EACvB,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,aAAa,CACb,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC;IAC3C,CAAC;IAEe,MAAM,CAAC,UAA2B,EAAE,MAAc;QACjE,MAAM,IAAI,uBAAuB,EAAE,CAAC;IACrC,CAAC;IAEe,QAAQ;QACvB,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IAAoB,SAAS;QAC5B,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC;IAEM,MAAM,CAAC,UAAU,CAAC,KAAa;QACrC,OAAO,IAAI,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC1D,CAAC;IAEO,WAAW,CAAC,KAAsB;QACzC,OAAO,OAAO,KAAK,KAAK,QAAQ;YAC/B,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC;YAC5B,CAAC,CAAC,KAAK,CAAC;IACV,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/X25519/utils.ts"],"names":[],"mappings":"AAMA,wBAAgB,mBAAmB,CAClC,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,GACxB,MAAM,CAWR"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import sodium from 'libsodium-wrappers';
|
|
2
|
+
const ALGORITHM = Buffer.from('X25519-XChaCha20-Poly1305', 'utf8');
|
|
3
|
+
sodium.ready.catch(() => { });
|
|
4
|
+
export function deriveEncryptionKey(sharedSecret, senderPublicKey, recipientPublicKey) {
|
|
5
|
+
return Buffer.from(sodium.crypto_generichash(sodium.crypto_aead_xchacha20poly1305_ietf_KEYBYTES, Buffer.concat([
|
|
6
|
+
ALGORITHM,
|
|
7
|
+
sharedSecret,
|
|
8
|
+
senderPublicKey,
|
|
9
|
+
recipientPublicKey,
|
|
10
|
+
]), null));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/X25519/utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;AAEnE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAE7B,MAAM,UAAU,mBAAmB,CAClC,YAAoB,EACpB,eAAuB,EACvB,kBAA0B;IAE1B,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAC3C,MAAM,CAAC,2CAA2C,EAClD,MAAM,CAAC,MAAM,CAAC;QACb,SAAS;QACT,YAAY;QACZ,eAAe;QACf,kBAAkB;KAClB,CAAC,EACF,IAAI,CACJ,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Suite } from '@hg-ts/tests';
|
|
2
|
+
export declare class X25519Test extends Suite {
|
|
3
|
+
encryption(): Promise<void>;
|
|
4
|
+
duplicateEncryptionDifferences(): Promise<void>;
|
|
5
|
+
encryptionFailsForAnotherRecipient(): Promise<void>;
|
|
6
|
+
encryptionBuffer(): Promise<void>;
|
|
7
|
+
signature(): Promise<void>;
|
|
8
|
+
verify(): Promise<void>;
|
|
9
|
+
keyPairFromPrivateKeyString(): Promise<void>;
|
|
10
|
+
seededWithNonScalarBytesLength(): Promise<void>;
|
|
11
|
+
seededWithScalarBytesLength(): Promise<void>;
|
|
12
|
+
privateKeyFromString(): Promise<void>;
|
|
13
|
+
publicKeyFromString(): Promise<void>;
|
|
14
|
+
publicKeyValidationValid(): Promise<void>;
|
|
15
|
+
publicKeyValidationFails(): Promise<void>;
|
|
16
|
+
setUp(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=x25519.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x25519.test.d.ts","sourceRoot":"","sources":["../../src/X25519/x25519.test.ts"],"names":[],"mappings":"AACA,OAAO,EAIN,KAAK,EAEL,MAAM,cAAc,CAAC;AAStB,qBACa,UAAW,SAAQ,KAAK;IAEvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,8BAA8B,IAAI,OAAO,CAAC,IAAI,CAAC;IAe/C,kCAAkC,IAAI,OAAO,CAAC,IAAI,CAAC;IAYnD,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYjC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAS1B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAQvB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5C,8BAA8B,IAAI,OAAO,CAAC,IAAI,CAAC;IAW/C,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5C,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrC,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQpC,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAQzC,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5C"}
|