simple-hpke 0.0.11 → 0.1.1
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 +35 -29
- package/dist/constants.cjs +61 -41
- package/dist/constants.cjs.map +3 -3
- package/dist/constants.js +61 -41
- package/dist/constants.js.map +3 -3
- package/dist/constants.min.cjs +1 -1
- package/dist/constants.min.cjs.map +3 -3
- package/dist/constants.min.js +1 -1
- package/dist/constants.min.js.map +3 -3
- package/dist/index.cjs +62 -41
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +46 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -41
- package/dist/index.js.map +3 -3
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.cjs.map +3 -3
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +3 -3
- package/dist/meta.json +15 -14
- package/dist/util.cjs +61 -41
- package/dist/util.cjs.map +3 -3
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +61 -41
- package/dist/util.js.map +3 -3
- package/dist/util.min.cjs +1 -1
- package/dist/util.min.cjs.map +3 -3
- package/dist/util.min.js +1 -1
- package/dist/util.min.js.map +3 -3
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,57 +1,38 @@
|
|
|
1
1
|
import { type RecipientKey, encryptToString, encryptBytes } from './util';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Create a new AES key for the given public key.
|
|
4
4
|
*
|
|
5
|
-
* @param recipient
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* raw bytes (`Uint8Array`, 16 or 32 bytes). Omit to generate a fresh
|
|
10
|
-
* extractable key of `opts.keysize` bits. A supplied `CryptoKey` MUST be
|
|
11
|
-
* extractable (its raw bytes are sealed).
|
|
12
|
-
* @param opts `keysize` (128/256, default 256; ignored when `aesKey` is
|
|
13
|
-
* supplied) and `info` (bound into the HPKE key schedule; default empty).
|
|
14
|
-
* @returns { wrapped:Uint8Array, key:CryptoKey } The envelope bytes and a
|
|
15
|
-
* usable AES-GCM `CryptoKey`.
|
|
5
|
+
* @param recipient Public key for decryptor
|
|
6
|
+
* @param opts `size` and `info`
|
|
7
|
+
* @returns {{ enc, key }} The wrapped envelope bytes and the generated
|
|
8
|
+
* AES-GCM key.
|
|
16
9
|
*/
|
|
17
|
-
export declare function
|
|
18
|
-
|
|
10
|
+
export declare function create(recipient: RecipientKey, opts?: {
|
|
11
|
+
size?: 128 | 256;
|
|
19
12
|
info?: Uint8Array | string;
|
|
20
13
|
}): Promise<{
|
|
21
|
-
|
|
14
|
+
enc: Uint8Array<ArrayBufferLike>;
|
|
22
15
|
key: CryptoKey;
|
|
23
16
|
}>;
|
|
24
17
|
/**
|
|
25
|
-
*
|
|
26
|
-
* AES-GCM `CryptoKey`, or `open.raw(...)` for the raw key bytes.
|
|
27
|
-
*/
|
|
28
|
-
export declare const open: typeof openBytes & {
|
|
29
|
-
raw: typeof openRawBytes;
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Recover an AES key that was wrapped with `seal`, using your private key.
|
|
18
|
+
* Encrypt the given AES key to the given public key.
|
|
33
19
|
*
|
|
34
|
-
* @
|
|
35
|
-
*
|
|
36
|
-
* @param opts `info` — must match the value passed to `seal`.
|
|
37
|
-
* @returns The recovered AES-GCM `CryptoKey` (extractable).
|
|
20
|
+
* @returns {{ enc, key }} The wrapped envelope bytes and a usable AES-GCM
|
|
21
|
+
* key with the same raw bytes as `aesKey`.
|
|
38
22
|
*/
|
|
39
|
-
declare function
|
|
40
|
-
info
|
|
41
|
-
}): Promise<
|
|
23
|
+
export declare function seal(recipient: RecipientKey, aesKey: CryptoKey | Uint8Array | null, opts?: {
|
|
24
|
+
info?: Uint8Array | string;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
enc: Uint8Array<ArrayBufferLike>;
|
|
27
|
+
key: CryptoKey;
|
|
28
|
+
}>;
|
|
42
29
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* @param keypair The same X25519 `CryptoKeyPair` used to seal.
|
|
47
|
-
* @param wrapped The envelope returned by `seal` (`enc ‖ ciphertext`).
|
|
48
|
-
* @param opts `info` — must match the value passed to `seal`.
|
|
49
|
-
* @returns The recovered key bytes (16 or 32 bytes, matching whatever
|
|
50
|
-
* was sealed).
|
|
30
|
+
* Recover the AES key wrapped by `create` or `seal`. Call `open(...)` for a
|
|
31
|
+
* usable AES-GCM `CryptoKey`, or `open.raw(...)` for the raw key bytes.
|
|
51
32
|
*/
|
|
52
|
-
declare
|
|
53
|
-
|
|
54
|
-
}
|
|
33
|
+
export declare const open: typeof openBytes & {
|
|
34
|
+
raw: typeof openRawBytes;
|
|
35
|
+
};
|
|
55
36
|
/**
|
|
56
37
|
* Seal an AES key to `recipient` and AES-GCM encrypt a message under it.
|
|
57
38
|
* Call `encrypt(...)` for the raw envelope bytes, or `encrypt.asString(...)`
|
|
@@ -117,5 +98,29 @@ declare function decryptFromString(keypair: CryptoKeyPair, message: string, opts
|
|
|
117
98
|
info?: Uint8Array | string;
|
|
118
99
|
buffer: true;
|
|
119
100
|
}): Promise<Uint8Array>;
|
|
101
|
+
/**
|
|
102
|
+
* Like `open`, but returns the recovered key as raw bytes instead of
|
|
103
|
+
* importing it as an AES-GCM `CryptoKey`. Exposed as `open.raw`.
|
|
104
|
+
*
|
|
105
|
+
* @param keypair The same X25519 `CryptoKeyPair` used to create or seal.
|
|
106
|
+
* @param wrapped The `enc` bytes returned by `create` or `seal`.
|
|
107
|
+
* @param opts `info` — must match the value passed to `create` or `seal`.
|
|
108
|
+
* @returns The recovered key bytes (16 or 32 bytes, matching whatever
|
|
109
|
+
* was wrapped).
|
|
110
|
+
*/
|
|
111
|
+
declare function openRawBytes(keypair: CryptoKeyPair, wrapped: Uint8Array, opts?: {
|
|
112
|
+
info: Uint8Array | string;
|
|
113
|
+
}): Promise<Uint8Array>;
|
|
114
|
+
/**
|
|
115
|
+
* Recover an AES key that was wrapped with `create` or `seal`.
|
|
116
|
+
*
|
|
117
|
+
* @param keypair The same X25519 `CryptoKeyPair` used to create or seal.
|
|
118
|
+
* @param wrapped The `enc` bytes returned by `create` or `seal`.
|
|
119
|
+
* @param opts `info` — must match the value passed to `create` or `seal`.
|
|
120
|
+
* @returns The recovered AES-GCM `CryptoKey` (extractable).
|
|
121
|
+
*/
|
|
122
|
+
declare function openBytes(keypair: CryptoKeyPair, wrapped: Uint8Array, opts?: {
|
|
123
|
+
info: Uint8Array | string;
|
|
124
|
+
}): Promise<CryptoKey>;
|
|
120
125
|
export {};
|
|
121
126
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,YAAY,EAGjB,eAAe,EACf,YAAY,EAOf,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,KAAK,YAAY,EAGjB,eAAe,EACf,YAAY,EAOf,MAAM,QAAQ,CAAA;AAoBf;;;;;;;GAOG;AACH,wBAAsB,MAAM,CACxB,SAAS,EAAC,YAAY,EACtB,IAAI,CAAC,EAAC;IAEF,IAAI,CAAC,EAAC,GAAG,GAAC,GAAG,CAAA;IAEb,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAA;CAC1B,GACH,OAAO,CAAC;IAAE,GAAG,EAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAAC,GAAG,EAAC,SAAS,CAAA;CAAE,CAAC,CAG5D;AAED;;;;;GAKG;AACH,wBAAsB,IAAI,CACtB,SAAS,EAAC,YAAY,EACtB,MAAM,EAAC,SAAS,GAAC,UAAU,GAAC,IAAI,EAChC,IAAI,CAAC,EAAC;IAEF,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAA;CAC1B,GACH,OAAO,CAAC;IAAE,GAAG,EAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IAAC,GAAG,EAAC,SAAS,CAAA;CAAE,CAAC,CAG5D;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI;;CAEf,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,OAAO;;CAElB,CAAA;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;CAGlB,CAAA;AAEF;;;;;;;;GAQG;AACH,iBAAe,YAAY,CACvB,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,UAAU,EAClB,IAAI,CAAC,EAAC;IAAE,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAA;CAAE,GACnC,OAAO,CAAC,UAAU,CAAC,CA6BpB;AAED;;;;;;;;GAQG;AACH,iBAAe,eAAe,CAC1B,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,UAAU,EAClB,IAAI,CAAC,EAAC;IAAE,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAA;CAAE,GACnC,OAAO,CAAC,MAAM,CAAC,CAGhB;AAED;;;;;;;;;;;;;GAaG;AACH,iBAAe,iBAAiB,CAC5B,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,MAAM,EACd,IAAI,CAAC,EAAC;IAAE,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAC;IAAC,MAAM,CAAC,EAAC,KAAK,CAAA;CAAE,GAClD,OAAO,CAAC,MAAM,CAAC,CAAA;AAEjB,iBAAe,iBAAiB,CAC5B,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,MAAM,EACd,IAAI,EAAC;IAAE,IAAI,CAAC,EAAC,UAAU,GAAC,MAAM,CAAC;IAAC,MAAM,EAAC,IAAI,CAAA;CAAE,GAC/C,OAAO,CAAC,UAAU,CAAC,CAAA;AA0HrB;;;;;;;;;GASG;AACH,iBAAe,YAAY,CACvB,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,UAAU,EAClB,IAAI,CAAC,EAAC;IAAE,IAAI,EAAC,UAAU,GAAC,MAAM,CAAA;CAAE,GAClC,OAAO,CAAC,UAAU,CAAC,CAYpB;AAED;;;;;;;GAOG;AACH,iBAAe,SAAS,CACpB,OAAO,EAAC,aAAa,EACrB,OAAO,EAAC,UAAU,EAClB,IAAI,CAAC,EAAC;IAAE,IAAI,EAAC,UAAU,GAAC,MAAM,CAAA;CAAE,GAClC,OAAO,CAAC,SAAS,CAAC,CAGnB"}
|
package/dist/index.js
CHANGED
|
@@ -1342,14 +1342,24 @@ async function aeadOpen(key, nonce, ciphertext) {
|
|
|
1342
1342
|
__name(aeadOpen, "aeadOpen");
|
|
1343
1343
|
async function encryptBytes(recipient, message, aesKey, opts) {
|
|
1344
1344
|
const plaintext = typeof message === "string" ? new TextEncoder().encode(message) : message;
|
|
1345
|
-
|
|
1345
|
+
let enc;
|
|
1346
|
+
let key;
|
|
1347
|
+
if (!aesKey) {
|
|
1348
|
+
const keys = await create2(recipient, opts);
|
|
1349
|
+
enc = keys.enc;
|
|
1350
|
+
key = keys.key;
|
|
1351
|
+
} else {
|
|
1352
|
+
const keys = await seal(recipient, aesKey, opts);
|
|
1353
|
+
enc = keys.enc;
|
|
1354
|
+
key = keys.key;
|
|
1355
|
+
}
|
|
1346
1356
|
const iv = globalThis.crypto.getRandomValues(new Uint8Array(NN));
|
|
1347
1357
|
const ct = new Uint8Array(await subtle.encrypt(
|
|
1348
1358
|
{ name: "AES-GCM", iv },
|
|
1349
1359
|
key,
|
|
1350
1360
|
plaintext
|
|
1351
1361
|
));
|
|
1352
|
-
return concat2(i2osp(
|
|
1362
|
+
return concat2(i2osp(enc.length, WRAPPED_LEN_PREFIX), enc, iv, ct);
|
|
1353
1363
|
}
|
|
1354
1364
|
__name(encryptBytes, "encryptBytes");
|
|
1355
1365
|
async function encryptToString(recipient, message, aesKey, opts) {
|
|
@@ -1550,51 +1560,19 @@ __name(concat2, "concat");
|
|
|
1550
1560
|
|
|
1551
1561
|
// src/index.ts
|
|
1552
1562
|
var subtle2 = globalThis.crypto.subtle;
|
|
1563
|
+
async function create2(recipient, opts) {
|
|
1564
|
+
const { wrapped, key } = await encryptKey(recipient, null, opts);
|
|
1565
|
+
return { enc: wrapped, key };
|
|
1566
|
+
}
|
|
1567
|
+
__name(create2, "create");
|
|
1553
1568
|
async function seal(recipient, aesKey, opts) {
|
|
1554
|
-
const
|
|
1555
|
-
|
|
1556
|
-
if (aesKey instanceof Uint8Array) {
|
|
1557
|
-
validateRawKeyBytes(aesKey);
|
|
1558
|
-
keyBytes = aesKey;
|
|
1559
|
-
} else if (aesKey) {
|
|
1560
|
-
keyBytes = await exportAesKeyBytes(aesKey);
|
|
1561
|
-
validateRawKeyBytes(keyBytes);
|
|
1562
|
-
} else {
|
|
1563
|
-
const keysize = opts?.keysize ?? 256;
|
|
1564
|
-
validateKeysize(keysize);
|
|
1565
|
-
keyBytes = globalThis.crypto.getRandomValues(
|
|
1566
|
-
new Uint8Array(keysize / 8)
|
|
1567
|
-
);
|
|
1568
|
-
}
|
|
1569
|
-
const publicKey = await resolveRecipientPublicKey(recipient);
|
|
1570
|
-
const { sharedSecret, enc } = await encap(publicKey);
|
|
1571
|
-
const { key, baseNonce } = await keySchedule(sharedSecret, info);
|
|
1572
|
-
const ciphertext = await aeadSeal(key, baseNonce, keyBytes);
|
|
1573
|
-
const wrapped = concat2(enc, ciphertext);
|
|
1574
|
-
const aesGcmKey = await importAesKey(keyBytes);
|
|
1575
|
-
return { wrapped, key: aesGcmKey };
|
|
1569
|
+
const { wrapped, key } = await encryptKey(recipient, aesKey, opts);
|
|
1570
|
+
return { enc: wrapped, key };
|
|
1576
1571
|
}
|
|
1577
1572
|
__name(seal, "seal");
|
|
1578
1573
|
var open = Object.assign(openBytes, {
|
|
1579
1574
|
raw: openRawBytes
|
|
1580
1575
|
});
|
|
1581
|
-
async function openBytes(keypair, wrapped, opts) {
|
|
1582
|
-
const keyBytes = await openRawBytes(keypair, wrapped, opts);
|
|
1583
|
-
return importAesKey(keyBytes);
|
|
1584
|
-
}
|
|
1585
|
-
__name(openBytes, "openBytes");
|
|
1586
|
-
async function openRawBytes(keypair, wrapped, opts) {
|
|
1587
|
-
if (wrapped.byteLength < ENC_LENGTH + AEAD_TAG_LENGTH) {
|
|
1588
|
-
throw new Error("malformed envelope: too short");
|
|
1589
|
-
}
|
|
1590
|
-
const info = normalizeInfo(opts?.info);
|
|
1591
|
-
const enc = wrapped.slice(0, ENC_LENGTH);
|
|
1592
|
-
const ciphertext = wrapped.slice(ENC_LENGTH);
|
|
1593
|
-
const sharedSecret = await decap(enc, keypair);
|
|
1594
|
-
const { key, baseNonce } = await keySchedule(sharedSecret, info);
|
|
1595
|
-
return aeadOpen(key, baseNonce, ciphertext);
|
|
1596
|
-
}
|
|
1597
|
-
__name(openRawBytes, "openRawBytes");
|
|
1598
1576
|
var encrypt = Object.assign(encryptBytes, {
|
|
1599
1577
|
asString: encryptToString
|
|
1600
1578
|
});
|
|
@@ -1733,7 +1711,50 @@ async function keySchedule(sharedSecret, info) {
|
|
|
1733
1711
|
return { key, baseNonce };
|
|
1734
1712
|
}
|
|
1735
1713
|
__name(keySchedule, "keySchedule");
|
|
1714
|
+
async function openRawBytes(keypair, wrapped, opts) {
|
|
1715
|
+
if (wrapped.byteLength < ENC_LENGTH + AEAD_TAG_LENGTH) {
|
|
1716
|
+
throw new Error("malformed envelope: too short");
|
|
1717
|
+
}
|
|
1718
|
+
const info = normalizeInfo(opts?.info);
|
|
1719
|
+
const enc = wrapped.slice(0, ENC_LENGTH);
|
|
1720
|
+
const ciphertext = wrapped.slice(ENC_LENGTH);
|
|
1721
|
+
const sharedSecret = await decap(enc, keypair);
|
|
1722
|
+
const { key, baseNonce } = await keySchedule(sharedSecret, info);
|
|
1723
|
+
return aeadOpen(key, baseNonce, ciphertext);
|
|
1724
|
+
}
|
|
1725
|
+
__name(openRawBytes, "openRawBytes");
|
|
1726
|
+
async function openBytes(keypair, wrapped, opts) {
|
|
1727
|
+
const keyBytes = await openRawBytes(keypair, wrapped, opts);
|
|
1728
|
+
return importAesKey(keyBytes);
|
|
1729
|
+
}
|
|
1730
|
+
__name(openBytes, "openBytes");
|
|
1731
|
+
async function encryptKey(recipient, aesKey, opts) {
|
|
1732
|
+
const info = normalizeInfo(opts?.info);
|
|
1733
|
+
let keyBytes;
|
|
1734
|
+
if (aesKey instanceof Uint8Array) {
|
|
1735
|
+
validateRawKeyBytes(aesKey);
|
|
1736
|
+
keyBytes = aesKey;
|
|
1737
|
+
} else if (aesKey) {
|
|
1738
|
+
keyBytes = await exportAesKeyBytes(aesKey);
|
|
1739
|
+
validateRawKeyBytes(keyBytes);
|
|
1740
|
+
} else {
|
|
1741
|
+
const keysize = opts?.size ?? 256;
|
|
1742
|
+
validateKeysize(keysize);
|
|
1743
|
+
keyBytes = globalThis.crypto.getRandomValues(
|
|
1744
|
+
new Uint8Array(keysize / 8)
|
|
1745
|
+
);
|
|
1746
|
+
}
|
|
1747
|
+
const publicKey = await resolveRecipientPublicKey(recipient);
|
|
1748
|
+
const { sharedSecret, enc } = await encap(publicKey);
|
|
1749
|
+
const { key, baseNonce } = await keySchedule(sharedSecret, info);
|
|
1750
|
+
const ciphertext = await aeadSeal(key, baseNonce, keyBytes);
|
|
1751
|
+
const wrapped = concat2(enc, ciphertext);
|
|
1752
|
+
const aesGcmKey = await importAesKey(keyBytes);
|
|
1753
|
+
return { wrapped, key: aesGcmKey };
|
|
1754
|
+
}
|
|
1755
|
+
__name(encryptKey, "encryptKey");
|
|
1736
1756
|
export {
|
|
1757
|
+
create2 as create,
|
|
1737
1758
|
decrypt,
|
|
1738
1759
|
encrypt,
|
|
1739
1760
|
open,
|