@teepin/sdk 0.2.1 → 0.3.0-rc.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 +41 -36
- package/dist/cjs/client.js +42 -4
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/direct/bytes.js +50 -0
- package/dist/cjs/direct/bytes.js.map +1 -0
- package/dist/cjs/direct/common.js +167 -0
- package/dist/cjs/direct/common.js.map +1 -0
- package/dist/cjs/direct/downloads-plan.js +127 -0
- package/dist/cjs/direct/downloads-plan.js.map +1 -0
- package/dist/cjs/direct/engine.js +405 -0
- package/dist/cjs/direct/engine.js.map +1 -0
- package/dist/cjs/direct/formats.js +44 -0
- package/dist/cjs/direct/formats.js.map +1 -0
- package/dist/cjs/direct/hpke.js +275 -0
- package/dist/cjs/direct/hpke.js.map +1 -0
- package/dist/cjs/direct/journal.js +80 -0
- package/dist/cjs/direct/journal.js.map +1 -0
- package/dist/cjs/direct/large.js +850 -0
- package/dist/cjs/direct/large.js.map +1 -0
- package/dist/cjs/direct/reads.js +1314 -0
- package/dist/cjs/direct/reads.js.map +1 -0
- package/dist/cjs/direct/sha256.js +122 -0
- package/dist/cjs/direct/sha256.js.map +1 -0
- package/dist/cjs/direct/tws1.js +480 -0
- package/dist/cjs/direct/tws1.js.map +1 -0
- package/dist/cjs/direct/uploads.js +1706 -0
- package/dist/cjs/direct/uploads.js.map +1 -0
- package/dist/cjs/errors.js +70 -13
- package/dist/cjs/errors.js.map +1 -1
- package/dist/cjs/index.js +5 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/links.js +195 -0
- package/dist/cjs/links.js.map +1 -0
- package/dist/cjs/node/downloads.js +835 -0
- package/dist/cjs/node/downloads.js.map +1 -0
- package/dist/cjs/node/journal.js +841 -0
- package/dist/cjs/node/journal.js.map +1 -0
- package/dist/cjs/node/uploads.js +219 -0
- package/dist/cjs/node/uploads.js.map +1 -0
- package/dist/cjs/node.js +26 -39
- package/dist/cjs/node.js.map +1 -1
- package/dist/cjs/storage.js +214 -184
- package/dist/cjs/storage.js.map +1 -1
- package/dist/cjs/transfer.js +18 -351
- package/dist/cjs/transfer.js.map +1 -1
- package/dist/esm/client.js +42 -4
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/direct/bytes.js +42 -0
- package/dist/esm/direct/bytes.js.map +1 -0
- package/dist/esm/direct/common.js +155 -0
- package/dist/esm/direct/common.js.map +1 -0
- package/dist/esm/direct/downloads-plan.js +117 -0
- package/dist/esm/direct/downloads-plan.js.map +1 -0
- package/dist/esm/direct/engine.js +385 -0
- package/dist/esm/direct/engine.js.map +1 -0
- package/dist/esm/direct/formats.js +40 -0
- package/dist/esm/direct/formats.js.map +1 -0
- package/dist/esm/direct/hpke.js +262 -0
- package/dist/esm/direct/hpke.js.map +1 -0
- package/dist/esm/direct/journal.js +75 -0
- package/dist/esm/direct/journal.js.map +1 -0
- package/dist/esm/direct/large.js +816 -0
- package/dist/esm/direct/large.js.map +1 -0
- package/dist/esm/direct/reads.js +1275 -0
- package/dist/esm/direct/reads.js.map +1 -0
- package/dist/esm/direct/sha256.js +118 -0
- package/dist/esm/direct/sha256.js.map +1 -0
- package/dist/esm/direct/tws1.js +460 -0
- package/dist/esm/direct/tws1.js.map +1 -0
- package/dist/esm/direct/uploads.js +1660 -0
- package/dist/esm/direct/uploads.js.map +1 -0
- package/dist/esm/errors.js +64 -11
- package/dist/esm/errors.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/links.js +189 -0
- package/dist/esm/links.js.map +1 -0
- package/dist/esm/node/downloads.js +829 -0
- package/dist/esm/node/downloads.js.map +1 -0
- package/dist/esm/node/journal.js +824 -0
- package/dist/esm/node/journal.js.map +1 -0
- package/dist/esm/node/uploads.js +187 -0
- package/dist/esm/node/uploads.js.map +1 -0
- package/dist/esm/node.js +17 -14
- package/dist/esm/node.js.map +1 -1
- package/dist/esm/storage.js +214 -184
- package/dist/esm/storage.js.map +1 -1
- package/dist/esm/transfer.js +19 -349
- package/dist/esm/transfer.js.map +1 -1
- package/dist/types/client.d.ts +45 -4
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/direct/bytes.d.ts +11 -0
- package/dist/types/direct/bytes.d.ts.map +1 -0
- package/dist/types/direct/common.d.ts +47 -0
- package/dist/types/direct/common.d.ts.map +1 -0
- package/dist/types/direct/downloads-plan.d.ts +75 -0
- package/dist/types/direct/downloads-plan.d.ts.map +1 -0
- package/dist/types/direct/engine.d.ts +191 -0
- package/dist/types/direct/engine.d.ts.map +1 -0
- package/dist/types/direct/formats.d.ts +9 -0
- package/dist/types/direct/formats.d.ts.map +1 -0
- package/dist/types/direct/hpke.d.ts +55 -0
- package/dist/types/direct/hpke.d.ts.map +1 -0
- package/dist/types/direct/journal.d.ts +55 -0
- package/dist/types/direct/journal.d.ts.map +1 -0
- package/dist/types/direct/large.d.ts +170 -0
- package/dist/types/direct/large.d.ts.map +1 -0
- package/dist/types/direct/reads.d.ts +306 -0
- package/dist/types/direct/reads.d.ts.map +1 -0
- package/dist/types/direct/sha256.d.ts +16 -0
- package/dist/types/direct/sha256.d.ts.map +1 -0
- package/dist/types/direct/tws1.d.ts +157 -0
- package/dist/types/direct/tws1.d.ts.map +1 -0
- package/dist/types/direct/uploads.d.ts +461 -0
- package/dist/types/direct/uploads.d.ts.map +1 -0
- package/dist/types/errors.d.ts +47 -8
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/links.d.ts +86 -0
- package/dist/types/links.d.ts.map +1 -0
- package/dist/types/node/downloads.d.ts +73 -0
- package/dist/types/node/downloads.d.ts.map +1 -0
- package/dist/types/node/journal.d.ts +162 -0
- package/dist/types/node/journal.d.ts.map +1 -0
- package/dist/types/node/uploads.d.ts +86 -0
- package/dist/types/node/uploads.d.ts.map +1 -0
- package/dist/types/node.d.ts +4 -2
- package/dist/types/node.d.ts.map +1 -1
- package/dist/types/storage.d.ts +107 -64
- package/dist/types/storage.d.ts.map +1 -1
- package/dist/types/transfer.d.ts +14 -23
- package/dist/types/transfer.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 TEEPIN Project
|
|
3
|
+
// Licensed under the Apache License, Version 2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.unwrapKey = exports.wrapKey = exports.generateKeyPair = exports.openSealed = exports.sealWith = exports.seal = exports.publicKeyOf = exports.importPrivateKey = exports.keyInfo = exports.UnwrapError = exports.WRAPPED_KEY_SIZE = exports.DATA_KEY_SIZE = exports.ENC_SIZE = exports.PRIVATE_KEY_SIZE = exports.PUBLIC_KEY_SIZE = exports.AEAD_ID = exports.KDF_ID = exports.KEM_ID = exports.SUITE = void 0;
|
|
6
|
+
// Wrapping data keys to an account's public key (TEEPIN-STORAGE-DESIGN.md
|
|
7
|
+
// section 20.1): HPKE (RFC 9180) in base mode, with the suite DHKEM(X25519,
|
|
8
|
+
// HKDF-SHA256) / HKDF-SHA256 / AES-128-GCM (KEM 0x0020, KDF 0x0001, AEAD
|
|
9
|
+
// 0x0001), RFC 9180 appendix A.1's suite, so this module is checked against
|
|
10
|
+
// the RFC's own vectors.
|
|
11
|
+
//
|
|
12
|
+
// A wrapped key is enc (32 bytes) followed by the sealed data key (48 bytes),
|
|
13
|
+
// 80 bytes in all, with info = "teepin/tws1/dek/v1" | account id | object id,
|
|
14
|
+
// so a wrap opens only for its own object. It matches teepin-core's
|
|
15
|
+
// tws1.WrapKey.
|
|
16
|
+
//
|
|
17
|
+
// Built from WebCrypto's X25519, HMAC-SHA256 and AES-GCM, so it runs in Node
|
|
18
|
+
// 20+ and browsers:
|
|
19
|
+
//
|
|
20
|
+
// - WebCrypto's HKDF does Extract and Expand in one step and HPKE needs them
|
|
21
|
+
// apart, so both are built on HMAC here.
|
|
22
|
+
// - WebCrypto imports an X25519 private key only as PKCS #8 or JWK, so a raw
|
|
23
|
+
// key goes in through its fixed PKCS #8 encoding (RFC 8410), non-extractable.
|
|
24
|
+
// Its public key is X25519 of the private key and the base point, so the
|
|
25
|
+
// private key never has to be exported.
|
|
26
|
+
// - Secrets that pass through JavaScript (the DH output, the shared secret, the
|
|
27
|
+
// raw AEAD key, the PKCS #8 bytes) are zeroed after use; keys held inside
|
|
28
|
+
// WebCrypto can't be.
|
|
29
|
+
const errors_js_1 = require("../errors.js");
|
|
30
|
+
const bytes_js_1 = require("./bytes.js");
|
|
31
|
+
/** The suite's name, as the control plane reports it with an account key. */
|
|
32
|
+
exports.SUITE = 'x25519-hkdfsha256-aes128gcm';
|
|
33
|
+
exports.KEM_ID = 0x0020;
|
|
34
|
+
exports.KDF_ID = 0x0001;
|
|
35
|
+
exports.AEAD_ID = 0x0001;
|
|
36
|
+
exports.PUBLIC_KEY_SIZE = 32;
|
|
37
|
+
exports.PRIVATE_KEY_SIZE = 32;
|
|
38
|
+
exports.ENC_SIZE = 32;
|
|
39
|
+
exports.DATA_KEY_SIZE = 32;
|
|
40
|
+
exports.WRAPPED_KEY_SIZE = exports.ENC_SIZE + exports.DATA_KEY_SIZE + 16;
|
|
41
|
+
const INFO_LABEL = (0, bytes_js_1.utf8)('teepin/tws1/dek/v1');
|
|
42
|
+
const HPKE_V1 = (0, bytes_js_1.utf8)('HPKE-v1');
|
|
43
|
+
const KEM_SUITE = (0, bytes_js_1.concat)([(0, bytes_js_1.utf8)('KEM'), u16(exports.KEM_ID)]);
|
|
44
|
+
const HPKE_SUITE = (0, bytes_js_1.concat)([(0, bytes_js_1.utf8)('HPKE'), u16(exports.KEM_ID), u16(exports.KDF_ID), u16(exports.AEAD_ID)]);
|
|
45
|
+
const NK = 16; // AES-128-GCM key
|
|
46
|
+
const NN = 12; // its nonce
|
|
47
|
+
const NSECRET = 32;
|
|
48
|
+
const MODE_BASE = 0x00;
|
|
49
|
+
const EMPTY = new Uint8Array(0);
|
|
50
|
+
const X25519 = { name: 'X25519' };
|
|
51
|
+
// An X25519 private key in PKCS #8 (RFC 8410) is this prefix, then the key's 32 bytes.
|
|
52
|
+
const PKCS8_PREFIX = new Uint8Array([0x30, 0x2e, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, 0x6e, 0x04, 0x22, 0x04, 0x20]);
|
|
53
|
+
// The X25519 base point, u = 9.
|
|
54
|
+
const BASE_POINT = (0, bytes_js_1.concat)([new Uint8Array([9]), new Uint8Array(31)]);
|
|
55
|
+
/** A wrapped key that does not open for this account and object. */
|
|
56
|
+
class UnwrapError extends errors_js_1.TeepinError {
|
|
57
|
+
constructor(message, options) {
|
|
58
|
+
super(message, options);
|
|
59
|
+
this.name = 'UnwrapError';
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.UnwrapError = UnwrapError;
|
|
63
|
+
function u16(n) {
|
|
64
|
+
return new Uint8Array([n >>> 8, n & 0xff]);
|
|
65
|
+
}
|
|
66
|
+
function errorMessage(err) {
|
|
67
|
+
return err instanceof Error ? err.message : String(err);
|
|
68
|
+
}
|
|
69
|
+
/** info for an object's wrapped key: the label, then the account's and the object's 16-byte ids. */
|
|
70
|
+
function keyInfo(accountId, objectId) {
|
|
71
|
+
if (accountId.length !== 16 || objectId.length !== 16)
|
|
72
|
+
throw new errors_js_1.TeepinError('hpke: account and object ids are 16 bytes each');
|
|
73
|
+
return (0, bytes_js_1.concat)([INFO_LABEL, accountId, objectId]);
|
|
74
|
+
}
|
|
75
|
+
exports.keyInfo = keyInfo;
|
|
76
|
+
// --- RFC 9180 building blocks ------------------------------------------------
|
|
77
|
+
async function hmac(key, data) {
|
|
78
|
+
// WebCrypto refuses an empty HMAC key. HMAC pads every key with zeros to the
|
|
79
|
+
// block size, so HashLen zeros (RFC 5869's default salt) give the same MAC.
|
|
80
|
+
const raw = key.length > 0 ? key : new Uint8Array(32);
|
|
81
|
+
const k = await crypto.subtle.importKey('raw', raw, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
82
|
+
return new Uint8Array(await crypto.subtle.sign('HMAC', k, data));
|
|
83
|
+
}
|
|
84
|
+
function extract(salt, ikm) {
|
|
85
|
+
return hmac(salt, ikm);
|
|
86
|
+
}
|
|
87
|
+
async function expand(prk, info, length) {
|
|
88
|
+
const out = new Uint8Array(length);
|
|
89
|
+
let block = new Uint8Array(0);
|
|
90
|
+
for (let off = 0, counter = 1; off < length; counter++) {
|
|
91
|
+
const input = (0, bytes_js_1.concat)([block, info, new Uint8Array([counter])]);
|
|
92
|
+
block.fill(0);
|
|
93
|
+
block = await hmac(prk, input);
|
|
94
|
+
input.fill(0);
|
|
95
|
+
out.set(block.subarray(0, length - off), off);
|
|
96
|
+
off += block.length;
|
|
97
|
+
}
|
|
98
|
+
block.fill(0);
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
async function labeledExtract(suite, salt, label, ikm) {
|
|
102
|
+
const labeled = (0, bytes_js_1.concat)([HPKE_V1, suite, (0, bytes_js_1.utf8)(label), ikm]);
|
|
103
|
+
const prk = await extract(salt, labeled);
|
|
104
|
+
labeled.fill(0);
|
|
105
|
+
return prk;
|
|
106
|
+
}
|
|
107
|
+
function labeledExpand(suite, prk, label, info, length) {
|
|
108
|
+
return expand(prk, (0, bytes_js_1.concat)([u16(length), HPKE_V1, suite, (0, bytes_js_1.utf8)(label), info]), length);
|
|
109
|
+
}
|
|
110
|
+
async function sharedSecret(dh, kemContext) {
|
|
111
|
+
const eaePrk = await labeledExtract(KEM_SUITE, EMPTY, 'eae_prk', dh);
|
|
112
|
+
const shared = await labeledExpand(KEM_SUITE, eaePrk, 'shared_secret', kemContext, NSECRET);
|
|
113
|
+
eaePrk.fill(0);
|
|
114
|
+
return shared;
|
|
115
|
+
}
|
|
116
|
+
async function keySchedule(shared, info) {
|
|
117
|
+
const pskIdHash = await labeledExtract(HPKE_SUITE, EMPTY, 'psk_id_hash', EMPTY);
|
|
118
|
+
const infoHash = await labeledExtract(HPKE_SUITE, EMPTY, 'info_hash', info);
|
|
119
|
+
const context = (0, bytes_js_1.concat)([new Uint8Array([MODE_BASE]), pskIdHash, infoHash]);
|
|
120
|
+
const secret = await labeledExtract(HPKE_SUITE, shared, 'secret', EMPTY);
|
|
121
|
+
const raw = await labeledExpand(HPKE_SUITE, secret, 'key', context, NK);
|
|
122
|
+
const baseNonce = await labeledExpand(HPKE_SUITE, secret, 'base_nonce', context, NN);
|
|
123
|
+
secret.fill(0);
|
|
124
|
+
const key = await crypto.subtle.importKey('raw', raw, { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']);
|
|
125
|
+
raw.fill(0);
|
|
126
|
+
return { key, baseNonce };
|
|
127
|
+
}
|
|
128
|
+
function nonce(baseNonce, seq) {
|
|
129
|
+
if (!Number.isSafeInteger(seq) || seq < 0)
|
|
130
|
+
throw new errors_js_1.TeepinError(`hpke: sequence number ${seq}`);
|
|
131
|
+
const out = baseNonce.slice();
|
|
132
|
+
for (let i = NN - 1, s = seq; s > 0; i--, s = Math.floor(s / 256))
|
|
133
|
+
out[i] ^= s % 256;
|
|
134
|
+
return out;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* A raw 32-byte X25519 private key as a non-extractable WebCrypto key, for deriveBits. WebCrypto has no raw import
|
|
138
|
+
* for private keys, so it goes in as PKCS #8.
|
|
139
|
+
*/
|
|
140
|
+
async function importPrivateKey(privateKey) {
|
|
141
|
+
if (privateKey.length !== exports.PRIVATE_KEY_SIZE)
|
|
142
|
+
throw new errors_js_1.TeepinError('hpke: a private key is 32 bytes');
|
|
143
|
+
const pkcs8 = (0, bytes_js_1.concat)([PKCS8_PREFIX, privateKey]);
|
|
144
|
+
try {
|
|
145
|
+
return await crypto.subtle.importKey('pkcs8', pkcs8, X25519, false, ['deriveBits']);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
throw new errors_js_1.TeepinError(`hpke: the private key is not usable: ${errorMessage(err)}`, { cause: err });
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
pkcs8.fill(0);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.importPrivateKey = importPrivateKey;
|
|
155
|
+
async function dh(privateKey, publicKey) {
|
|
156
|
+
let out;
|
|
157
|
+
try {
|
|
158
|
+
const pub = await crypto.subtle.importKey('raw', publicKey, X25519, true, []);
|
|
159
|
+
out = new Uint8Array(await crypto.subtle.deriveBits({ name: 'X25519', public: pub }, privateKey, 256));
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
throw new errors_js_1.TeepinError(`hpke: the public key is not usable: ${errorMessage(err)}`, { cause: err });
|
|
163
|
+
}
|
|
164
|
+
// A low-order point gives an all-zero secret, which RFC 9180 refuses.
|
|
165
|
+
let any = 0;
|
|
166
|
+
for (const b of out)
|
|
167
|
+
any |= b;
|
|
168
|
+
if (any === 0)
|
|
169
|
+
throw new errors_js_1.TeepinError('hpke: the public key is not usable: the shared secret is all zeros');
|
|
170
|
+
return out;
|
|
171
|
+
}
|
|
172
|
+
/** The raw public key of a WebCrypto X25519 private key: X25519 of the key and the base point. */
|
|
173
|
+
function publicOf(privateKey) {
|
|
174
|
+
return dh(privateKey, BASE_POINT);
|
|
175
|
+
}
|
|
176
|
+
/** The raw public key that belongs to a raw 32-byte private key. */
|
|
177
|
+
async function publicKeyOf(privateKey) {
|
|
178
|
+
return publicOf(await importPrivateKey(privateKey));
|
|
179
|
+
}
|
|
180
|
+
exports.publicKeyOf = publicKeyOf;
|
|
181
|
+
async function newEphemeral() {
|
|
182
|
+
const pair = await crypto.subtle.generateKey(X25519, false, ['deriveBits']);
|
|
183
|
+
if (!('privateKey' in pair))
|
|
184
|
+
throw new errors_js_1.TeepinError('hpke: X25519 key generation gave no key pair');
|
|
185
|
+
return { privateKey: pair.privateKey, publicKey: new Uint8Array(await crypto.subtle.exportKey('raw', pair.publicKey)) };
|
|
186
|
+
}
|
|
187
|
+
// --- seal and open ------------------------------------------------------------
|
|
188
|
+
/** A single-shot base-mode seal to publicKey: enc | ciphertext, under a fresh ephemeral key. */
|
|
189
|
+
async function seal(publicKey, info, plaintext, aad = EMPTY) {
|
|
190
|
+
return sealWith(await newEphemeral(), publicKey, info, plaintext, aad);
|
|
191
|
+
}
|
|
192
|
+
exports.seal = seal;
|
|
193
|
+
/**
|
|
194
|
+
* seal under a given ephemeral key: only the RFC's own vectors need it. An ephemeral key used twice with one
|
|
195
|
+
* recipient gives the same AES-GCM key and nonce twice, which gives away both plaintexts' XOR. So the SDK only ever
|
|
196
|
+
* calls seal, which makes a fresh one each time, and a test checks that nothing under src calls sealWith. It takes
|
|
197
|
+
* the key per call, never from shared state another module could change.
|
|
198
|
+
*/
|
|
199
|
+
async function sealWith(ephemeral, publicKey, info, plaintext, aad = EMPTY) {
|
|
200
|
+
if (publicKey.length !== exports.PUBLIC_KEY_SIZE)
|
|
201
|
+
throw new errors_js_1.TeepinError('hpke: a public key is 32 bytes');
|
|
202
|
+
const enc = ephemeral.publicKey;
|
|
203
|
+
const secret = await dh(ephemeral.privateKey, publicKey);
|
|
204
|
+
const shared = await sharedSecret(secret, (0, bytes_js_1.concat)([enc, publicKey]));
|
|
205
|
+
secret.fill(0);
|
|
206
|
+
const { key, baseNonce } = await keySchedule(shared, info);
|
|
207
|
+
shared.fill(0);
|
|
208
|
+
const ciphertext = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: nonce(baseNonce, 0), additionalData: aad }, key, plaintext);
|
|
209
|
+
return (0, bytes_js_1.concat)([enc, new Uint8Array(ciphertext)]);
|
|
210
|
+
}
|
|
211
|
+
exports.sealWith = sealWith;
|
|
212
|
+
/**
|
|
213
|
+
* Opens the seq-th message of a base-mode context set up by enc. A single-shot seal is message 0. UnwrapError if it
|
|
214
|
+
* doesn't open.
|
|
215
|
+
*/
|
|
216
|
+
async function openSealed(privateKey, enc, info, ciphertext, aad = EMPTY, seq = 0) {
|
|
217
|
+
const priv = await importPrivateKey(privateKey);
|
|
218
|
+
const secret = await dh(priv, enc);
|
|
219
|
+
const shared = await sharedSecret(secret, (0, bytes_js_1.concat)([enc, await publicOf(priv)]));
|
|
220
|
+
secret.fill(0);
|
|
221
|
+
const { key, baseNonce } = await keySchedule(shared, info);
|
|
222
|
+
shared.fill(0);
|
|
223
|
+
const iv = nonce(baseNonce, seq);
|
|
224
|
+
try {
|
|
225
|
+
return new Uint8Array(await crypto.subtle.decrypt({ name: 'AES-GCM', iv, additionalData: aad }, key, ciphertext));
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
throw new UnwrapError('hpke: the message does not open');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
exports.openSealed = openSealed;
|
|
232
|
+
/** A new X25519 key pair, raw 32 bytes each: for tests and the fake API. */
|
|
233
|
+
async function generateKeyPair() {
|
|
234
|
+
const pair = await crypto.subtle.generateKey(X25519, true, ['deriveBits']);
|
|
235
|
+
if (!('privateKey' in pair))
|
|
236
|
+
throw new errors_js_1.TeepinError('hpke: X25519 key generation gave no key pair');
|
|
237
|
+
const pkcs8 = new Uint8Array(await crypto.subtle.exportKey('pkcs8', pair.privateKey));
|
|
238
|
+
try {
|
|
239
|
+
if (pkcs8.length !== PKCS8_PREFIX.length + exports.PRIVATE_KEY_SIZE || !(0, bytes_js_1.constantTimeEqual)(pkcs8.subarray(0, PKCS8_PREFIX.length), PKCS8_PREFIX)) {
|
|
240
|
+
throw new errors_js_1.TeepinError('hpke: an X25519 private key came out in an unexpected PKCS #8 encoding');
|
|
241
|
+
}
|
|
242
|
+
const publicKey = new Uint8Array(await crypto.subtle.exportKey('raw', pair.publicKey));
|
|
243
|
+
return { privateKey: pkcs8.slice(PKCS8_PREFIX.length), publicKey };
|
|
244
|
+
}
|
|
245
|
+
finally {
|
|
246
|
+
pkcs8.fill(0);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
exports.generateKeyPair = generateKeyPair;
|
|
250
|
+
// --- data keys ----------------------------------------------------------------
|
|
251
|
+
/** An object's data key, wrapped to its account's public key: 80 bytes. */
|
|
252
|
+
async function wrapKey(publicKey, accountId, objectId, dataKey) {
|
|
253
|
+
if (dataKey.length !== exports.DATA_KEY_SIZE)
|
|
254
|
+
throw new errors_js_1.TeepinError('hpke: a data key is 32 bytes');
|
|
255
|
+
const wrapped = await seal(publicKey, keyInfo(accountId, objectId), dataKey);
|
|
256
|
+
if (wrapped.length !== exports.WRAPPED_KEY_SIZE)
|
|
257
|
+
throw new errors_js_1.TeepinError(`hpke: a wrapped key is ${wrapped.length} bytes, want ${exports.WRAPPED_KEY_SIZE}`);
|
|
258
|
+
return wrapped;
|
|
259
|
+
}
|
|
260
|
+
exports.wrapKey = wrapKey;
|
|
261
|
+
/** The data key inside wrapped, which must have been wrapped for this account and object; UnwrapError otherwise. */
|
|
262
|
+
async function unwrapKey(privateKey, accountId, objectId, wrapped) {
|
|
263
|
+
if (wrapped.length !== exports.WRAPPED_KEY_SIZE)
|
|
264
|
+
throw new UnwrapError('hpke: a wrapped key is 80 bytes');
|
|
265
|
+
try {
|
|
266
|
+
return await openSealed(privateKey, wrapped.subarray(0, exports.ENC_SIZE), keyInfo(accountId, objectId), wrapped.subarray(exports.ENC_SIZE));
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (err instanceof errors_js_1.TeepinError && !(err instanceof UnwrapError))
|
|
270
|
+
throw new UnwrapError(err.message, { cause: err });
|
|
271
|
+
throw err;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
exports.unwrapKey = unwrapKey;
|
|
275
|
+
//# sourceMappingURL=hpke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hpke.js","sourceRoot":"","sources":["../../../src/direct/hpke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Copyright 2026 TEEPIN Project
|
|
3
|
+
// Licensed under the Apache License, Version 2.0
|
|
4
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.MemoryJournal = exports.Rows = void 0;
|
|
6
|
+
/** Rows as a journal keeps them in memory: the shared core of every journal. */
|
|
7
|
+
class Rows {
|
|
8
|
+
tables = new Map();
|
|
9
|
+
counters = new Map();
|
|
10
|
+
apply(entry) {
|
|
11
|
+
let t = this.tables.get(entry.table);
|
|
12
|
+
if (!t) {
|
|
13
|
+
t = new Map();
|
|
14
|
+
this.tables.set(entry.table, t);
|
|
15
|
+
}
|
|
16
|
+
if ('remove' in entry) {
|
|
17
|
+
t.delete(entry.id);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// A row keeps its first place: Map keeps insertion order, so delete only on removal.
|
|
21
|
+
t.set(entry.id, structuredClone(entry.row));
|
|
22
|
+
const n = Number(entry.id);
|
|
23
|
+
if (Number.isSafeInteger(n) && n > (this.counters.get(entry.table) ?? 0))
|
|
24
|
+
this.counters.set(entry.table, n);
|
|
25
|
+
}
|
|
26
|
+
get(table, id) {
|
|
27
|
+
const row = this.tables.get(table)?.get(id);
|
|
28
|
+
return row === undefined ? undefined : structuredClone(row);
|
|
29
|
+
}
|
|
30
|
+
rows(table) {
|
|
31
|
+
return [...(this.tables.get(table)?.values() ?? [])].map((r) => structuredClone(r));
|
|
32
|
+
}
|
|
33
|
+
nextId(table) {
|
|
34
|
+
const n = (this.counters.get(table) ?? 0) + 1;
|
|
35
|
+
this.counters.set(table, n);
|
|
36
|
+
return String(n);
|
|
37
|
+
}
|
|
38
|
+
/** Every row, as entries: what a file journal writes when it compacts. */
|
|
39
|
+
entries() {
|
|
40
|
+
const out = [];
|
|
41
|
+
for (const [table, t] of this.tables)
|
|
42
|
+
for (const [id, row] of t)
|
|
43
|
+
out.push({ table, id, row: structuredClone(row) });
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.Rows = Rows;
|
|
48
|
+
/** A run journaled in memory: not resumable after the process ends (browsers, and journal: false). */
|
|
49
|
+
class MemoryJournal {
|
|
50
|
+
durable = false;
|
|
51
|
+
data = new Rows();
|
|
52
|
+
closed = false;
|
|
53
|
+
async put(table, id, row) {
|
|
54
|
+
this.check();
|
|
55
|
+
this.data.apply({ table, id, row });
|
|
56
|
+
}
|
|
57
|
+
async write(entries) {
|
|
58
|
+
this.check();
|
|
59
|
+
for (const e of entries)
|
|
60
|
+
this.data.apply(e);
|
|
61
|
+
}
|
|
62
|
+
get(table, id) {
|
|
63
|
+
return this.data.get(table, id);
|
|
64
|
+
}
|
|
65
|
+
rows(table) {
|
|
66
|
+
return this.data.rows(table);
|
|
67
|
+
}
|
|
68
|
+
nextId(table) {
|
|
69
|
+
return this.data.nextId(table);
|
|
70
|
+
}
|
|
71
|
+
async close() {
|
|
72
|
+
this.closed = true;
|
|
73
|
+
}
|
|
74
|
+
check() {
|
|
75
|
+
if (this.closed)
|
|
76
|
+
throw new Error('journal: written after it was closed');
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
exports.MemoryJournal = MemoryJournal;
|
|
80
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../../src/direct/journal.ts"],"names":[],"mappings":"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"}
|