@omnituum/pqc-shared 0.2.6
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 +22 -0
- package/README.md +543 -0
- package/dist/crypto/index.cjs +807 -0
- package/dist/crypto/index.d.cts +641 -0
- package/dist/crypto/index.d.ts +641 -0
- package/dist/crypto/index.js +716 -0
- package/dist/decrypt-eSHlbh1j.d.cts +321 -0
- package/dist/decrypt-eSHlbh1j.d.ts +321 -0
- package/dist/fs/index.cjs +1168 -0
- package/dist/fs/index.d.cts +400 -0
- package/dist/fs/index.d.ts +400 -0
- package/dist/fs/index.js +1091 -0
- package/dist/index.cjs +2160 -0
- package/dist/index.d.cts +282 -0
- package/dist/index.d.ts +282 -0
- package/dist/index.js +2031 -0
- package/dist/integrity-CCYjrap3.d.ts +31 -0
- package/dist/integrity-Dx9jukMH.d.cts +31 -0
- package/dist/types-61c7Q9ri.d.ts +134 -0
- package/dist/types-Ch0y-n7K.d.cts +134 -0
- package/dist/utils/index.cjs +129 -0
- package/dist/utils/index.d.cts +49 -0
- package/dist/utils/index.d.ts +49 -0
- package/dist/utils/index.js +114 -0
- package/dist/vault/index.cjs +713 -0
- package/dist/vault/index.d.cts +237 -0
- package/dist/vault/index.d.ts +237 -0
- package/dist/vault/index.js +677 -0
- package/dist/version-BygzPVGs.d.cts +55 -0
- package/dist/version-BygzPVGs.d.ts +55 -0
- package/package.json +86 -0
- package/src/crypto/dilithium.ts +233 -0
- package/src/crypto/hybrid.ts +358 -0
- package/src/crypto/index.ts +181 -0
- package/src/crypto/kyber.ts +199 -0
- package/src/crypto/nacl.ts +204 -0
- package/src/crypto/primitives/blake3.ts +141 -0
- package/src/crypto/primitives/chacha.ts +211 -0
- package/src/crypto/primitives/hkdf.ts +192 -0
- package/src/crypto/primitives/index.ts +54 -0
- package/src/crypto/primitives.ts +144 -0
- package/src/crypto/x25519.ts +134 -0
- package/src/fs/aes.ts +343 -0
- package/src/fs/argon2.ts +184 -0
- package/src/fs/browser.ts +408 -0
- package/src/fs/decrypt.ts +320 -0
- package/src/fs/encrypt.ts +324 -0
- package/src/fs/format.ts +425 -0
- package/src/fs/index.ts +144 -0
- package/src/fs/types.ts +304 -0
- package/src/index.ts +414 -0
- package/src/kdf/index.ts +311 -0
- package/src/runtime/crypto.ts +16 -0
- package/src/security/index.ts +345 -0
- package/src/tunnel/index.ts +39 -0
- package/src/tunnel/session.ts +229 -0
- package/src/tunnel/types.ts +115 -0
- package/src/utils/entropy.ts +128 -0
- package/src/utils/index.ts +25 -0
- package/src/utils/integrity.ts +95 -0
- package/src/vault/decrypt.ts +167 -0
- package/src/vault/encrypt.ts +207 -0
- package/src/vault/index.ts +71 -0
- package/src/vault/manager.ts +327 -0
- package/src/vault/migrate.ts +190 -0
- package/src/vault/types.ts +177 -0
- package/src/version.ts +304 -0
package/src/fs/types.ts
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Omnituum FS - File Encryption Types
|
|
3
|
+
*
|
|
4
|
+
* Type definitions for the .oqe (Omnituum Quantum Encrypted) file format.
|
|
5
|
+
* Supports two encryption modes:
|
|
6
|
+
* - Mode A: Hybrid (X25519 + Kyber768) - for identity-based encryption
|
|
7
|
+
* - Mode B: Password (Argon2id) - for standalone file protection
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
11
|
+
// OQE FILE FORMAT CONSTANTS
|
|
12
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
13
|
+
|
|
14
|
+
/** Magic bytes: "OQEF" (Omnituum Quantum Encrypted File) */
|
|
15
|
+
export const OQE_MAGIC = new Uint8Array([0x4f, 0x51, 0x45, 0x46]);
|
|
16
|
+
|
|
17
|
+
/** Current format version */
|
|
18
|
+
export const OQE_FORMAT_VERSION = 1;
|
|
19
|
+
|
|
20
|
+
/** Supported encryption modes */
|
|
21
|
+
export type OQEMode = 'hybrid' | 'password';
|
|
22
|
+
|
|
23
|
+
/** Algorithm suite identifiers */
|
|
24
|
+
export const ALGORITHM_SUITES = {
|
|
25
|
+
/** Hybrid: X25519 ECDH + Kyber768 KEM + AES-256-GCM */
|
|
26
|
+
HYBRID_X25519_KYBER768_AES256GCM: 0x01,
|
|
27
|
+
/** Password: Argon2id + AES-256-GCM */
|
|
28
|
+
PASSWORD_ARGON2ID_AES256GCM: 0x02,
|
|
29
|
+
} as const;
|
|
30
|
+
|
|
31
|
+
export type AlgorithmSuiteId = typeof ALGORITHM_SUITES[keyof typeof ALGORITHM_SUITES];
|
|
32
|
+
|
|
33
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
34
|
+
// ARGON2ID PARAMETERS (OWASP 2024 Recommendations)
|
|
35
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
36
|
+
|
|
37
|
+
export interface Argon2idParams {
|
|
38
|
+
/** Memory cost in KiB (default: 65536 = 64MB) */
|
|
39
|
+
memoryCost: number;
|
|
40
|
+
/** Time cost / iterations (default: 3) */
|
|
41
|
+
timeCost: number;
|
|
42
|
+
/** Parallelism (default: 4) */
|
|
43
|
+
parallelism: number;
|
|
44
|
+
/** Output key length in bytes (default: 32 for AES-256) */
|
|
45
|
+
hashLength: number;
|
|
46
|
+
/** Salt length in bytes (default: 32) */
|
|
47
|
+
saltLength: number;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Default Argon2id parameters - OWASP 2024 recommended */
|
|
51
|
+
export const DEFAULT_ARGON2ID_PARAMS: Argon2idParams = {
|
|
52
|
+
memoryCost: 65536, // 64 MB
|
|
53
|
+
timeCost: 3,
|
|
54
|
+
parallelism: 4,
|
|
55
|
+
hashLength: 32,
|
|
56
|
+
saltLength: 32,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** Minimum Argon2id parameters for low-memory environments */
|
|
60
|
+
export const MIN_ARGON2ID_PARAMS: Argon2idParams = {
|
|
61
|
+
memoryCost: 19456, // ~19 MB (OWASP minimum)
|
|
62
|
+
timeCost: 2,
|
|
63
|
+
parallelism: 1,
|
|
64
|
+
hashLength: 32,
|
|
65
|
+
saltLength: 32,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
69
|
+
// OQE FILE METADATA
|
|
70
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
71
|
+
|
|
72
|
+
export interface OQEMetadata {
|
|
73
|
+
/** Original filename (encrypted in file) */
|
|
74
|
+
filename: string;
|
|
75
|
+
/** Original file size in bytes */
|
|
76
|
+
originalSize: number;
|
|
77
|
+
/** Original MIME type (optional) */
|
|
78
|
+
mimeType?: string;
|
|
79
|
+
/** Encryption timestamp (ISO 8601) */
|
|
80
|
+
encryptedAt: string;
|
|
81
|
+
/** Encryptor identity hash (hybrid mode only) */
|
|
82
|
+
encryptorIdHash?: string;
|
|
83
|
+
/** Recipient identity hash (hybrid mode only) */
|
|
84
|
+
recipientIdHash?: string;
|
|
85
|
+
/** Custom metadata (optional) */
|
|
86
|
+
custom?: Record<string, string>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
90
|
+
// OQE FILE HEADER (Binary Format)
|
|
91
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* OQE Binary Header Layout:
|
|
95
|
+
*
|
|
96
|
+
* Offset | Size | Description
|
|
97
|
+
* -------|------|------------
|
|
98
|
+
* 0 | 4 | Magic bytes "OQEF"
|
|
99
|
+
* 4 | 1 | Format version (1)
|
|
100
|
+
* 5 | 1 | Algorithm suite ID
|
|
101
|
+
* 6 | 4 | Flags (reserved)
|
|
102
|
+
* 10 | 4 | Metadata length (encrypted JSON)
|
|
103
|
+
* 14 | 4 | Key material length
|
|
104
|
+
* 18 | 12 | AES-GCM IV
|
|
105
|
+
* 30 | var | Key material (mode-specific)
|
|
106
|
+
* --- | var | Encrypted metadata (JSON + auth tag)
|
|
107
|
+
* --- | var | Encrypted file content (with auth tag)
|
|
108
|
+
*/
|
|
109
|
+
export interface OQEHeader {
|
|
110
|
+
/** Format version */
|
|
111
|
+
version: number;
|
|
112
|
+
/** Algorithm suite ID */
|
|
113
|
+
algorithmSuite: AlgorithmSuiteId;
|
|
114
|
+
/** Header flags (reserved for future use) */
|
|
115
|
+
flags: number;
|
|
116
|
+
/** Length of encrypted metadata */
|
|
117
|
+
metadataLength: number;
|
|
118
|
+
/** Length of key material section */
|
|
119
|
+
keyMaterialLength: number;
|
|
120
|
+
/** AES-GCM initialization vector */
|
|
121
|
+
iv: Uint8Array;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/** Fixed header size in bytes (before variable-length sections) */
|
|
125
|
+
export const OQE_HEADER_SIZE = 30;
|
|
126
|
+
|
|
127
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
128
|
+
// KEY MATERIAL (Mode-Specific)
|
|
129
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Hybrid Mode Key Material:
|
|
133
|
+
* - X25519 ephemeral public key (32 bytes)
|
|
134
|
+
* - X25519 wrapped content key (32 + 16 bytes auth tag = 48 bytes)
|
|
135
|
+
* - X25519 wrap nonce (24 bytes for XSalsa20-Poly1305)
|
|
136
|
+
* - Kyber KEM ciphertext (~1088 bytes for Kyber768)
|
|
137
|
+
* - Kyber wrapped content key (48 bytes)
|
|
138
|
+
* - Kyber wrap nonce (24 bytes)
|
|
139
|
+
*/
|
|
140
|
+
export interface HybridKeyMaterial {
|
|
141
|
+
/** X25519 ephemeral public key */
|
|
142
|
+
x25519EphemeralPk: Uint8Array;
|
|
143
|
+
/** X25519 wrapped content key (NaCl secretbox) */
|
|
144
|
+
x25519WrappedKey: Uint8Array;
|
|
145
|
+
/** X25519 wrap nonce */
|
|
146
|
+
x25519Nonce: Uint8Array;
|
|
147
|
+
/** Kyber KEM ciphertext */
|
|
148
|
+
kyberCiphertext: Uint8Array;
|
|
149
|
+
/** Kyber wrapped content key (NaCl secretbox) */
|
|
150
|
+
kyberWrappedKey: Uint8Array;
|
|
151
|
+
/** Kyber wrap nonce */
|
|
152
|
+
kyberNonce: Uint8Array;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Password Mode Key Material:
|
|
157
|
+
* - Argon2id salt (32 bytes)
|
|
158
|
+
* - Argon2id parameters (encoded as 4 bytes each: mem, time, parallelism)
|
|
159
|
+
*/
|
|
160
|
+
export interface PasswordKeyMaterial {
|
|
161
|
+
/** Argon2id salt */
|
|
162
|
+
salt: Uint8Array;
|
|
163
|
+
/** Argon2id memory cost in KiB */
|
|
164
|
+
memoryCost: number;
|
|
165
|
+
/** Argon2id time cost (iterations) */
|
|
166
|
+
timeCost: number;
|
|
167
|
+
/** Argon2id parallelism */
|
|
168
|
+
parallelism: number;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
172
|
+
// ENCRYPTION/DECRYPTION OPTIONS
|
|
173
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
174
|
+
|
|
175
|
+
/** Options for hybrid mode encryption */
|
|
176
|
+
export interface HybridEncryptOptions {
|
|
177
|
+
mode: 'hybrid';
|
|
178
|
+
/** Recipient's public keys */
|
|
179
|
+
recipientPublicKeys: {
|
|
180
|
+
x25519PubHex: string;
|
|
181
|
+
kyberPubB64: string;
|
|
182
|
+
};
|
|
183
|
+
/** Sender identity (optional, for metadata) */
|
|
184
|
+
sender?: {
|
|
185
|
+
id: string;
|
|
186
|
+
name?: string;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Options for password mode encryption */
|
|
191
|
+
export interface PasswordEncryptOptions {
|
|
192
|
+
mode: 'password';
|
|
193
|
+
/** User password */
|
|
194
|
+
password: string;
|
|
195
|
+
/** Argon2id parameters (uses defaults if not specified) */
|
|
196
|
+
argon2Params?: Partial<Argon2idParams>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export type EncryptOptions = HybridEncryptOptions | PasswordEncryptOptions;
|
|
200
|
+
|
|
201
|
+
/** Options for hybrid mode decryption */
|
|
202
|
+
export interface HybridDecryptOptions {
|
|
203
|
+
mode: 'hybrid';
|
|
204
|
+
/** Recipient's secret keys */
|
|
205
|
+
recipientSecretKeys: {
|
|
206
|
+
x25519SecHex: string;
|
|
207
|
+
kyberSecB64: string;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Options for password mode decryption */
|
|
212
|
+
export interface PasswordDecryptOptions {
|
|
213
|
+
mode: 'password';
|
|
214
|
+
/** User password */
|
|
215
|
+
password: string;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export type DecryptOptions = HybridDecryptOptions | PasswordDecryptOptions;
|
|
219
|
+
|
|
220
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
221
|
+
// ENCRYPTION RESULT
|
|
222
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
223
|
+
|
|
224
|
+
export interface OQEEncryptResult {
|
|
225
|
+
/** Complete .oqe file as bytes */
|
|
226
|
+
data: Uint8Array;
|
|
227
|
+
/** Suggested filename with .oqe extension */
|
|
228
|
+
filename: string;
|
|
229
|
+
/** File metadata (for UI display) */
|
|
230
|
+
metadata: OQEMetadata;
|
|
231
|
+
/** Encryption mode used */
|
|
232
|
+
mode: OQEMode;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
export interface OQEDecryptResult {
|
|
236
|
+
/** Decrypted file content */
|
|
237
|
+
data: Uint8Array;
|
|
238
|
+
/** Original filename */
|
|
239
|
+
filename: string;
|
|
240
|
+
/** Original MIME type */
|
|
241
|
+
mimeType?: string;
|
|
242
|
+
/** Original file size */
|
|
243
|
+
originalSize: number;
|
|
244
|
+
/** File metadata */
|
|
245
|
+
metadata: OQEMetadata;
|
|
246
|
+
/** Decryption mode used */
|
|
247
|
+
mode: OQEMode;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
251
|
+
// ERROR TYPES
|
|
252
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
253
|
+
|
|
254
|
+
export type OQEErrorCode =
|
|
255
|
+
| 'INVALID_MAGIC'
|
|
256
|
+
| 'UNSUPPORTED_VERSION'
|
|
257
|
+
| 'UNSUPPORTED_ALGORITHM'
|
|
258
|
+
| 'INVALID_HEADER'
|
|
259
|
+
| 'DECRYPTION_FAILED'
|
|
260
|
+
| 'PASSWORD_WRONG'
|
|
261
|
+
| 'KEY_UNWRAP_FAILED'
|
|
262
|
+
| 'INTEGRITY_CHECK_FAILED'
|
|
263
|
+
| 'KYBER_UNAVAILABLE'
|
|
264
|
+
| 'ARGON2_UNAVAILABLE'
|
|
265
|
+
| 'FILE_TOO_LARGE'
|
|
266
|
+
| 'ENCRYPTION_FAILED';
|
|
267
|
+
|
|
268
|
+
export class OQEError extends Error {
|
|
269
|
+
constructor(
|
|
270
|
+
public code: OQEErrorCode,
|
|
271
|
+
message: string
|
|
272
|
+
) {
|
|
273
|
+
super(message);
|
|
274
|
+
this.name = 'OQEError';
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
279
|
+
// UTILITY TYPES
|
|
280
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
281
|
+
|
|
282
|
+
/** Progress callback for large file operations */
|
|
283
|
+
export type ProgressCallback = (progress: {
|
|
284
|
+
phase: 'reading' | 'encrypting' | 'decrypting' | 'writing';
|
|
285
|
+
bytesProcessed: number;
|
|
286
|
+
totalBytes: number;
|
|
287
|
+
percent: number;
|
|
288
|
+
}) => void;
|
|
289
|
+
|
|
290
|
+
/** File input types supported */
|
|
291
|
+
export type FileInput = File | Blob | Uint8Array | ArrayBuffer;
|
|
292
|
+
|
|
293
|
+
/** Convert any file input to Uint8Array */
|
|
294
|
+
export async function toUint8Array(input: FileInput): Promise<Uint8Array> {
|
|
295
|
+
if (input instanceof Uint8Array) {
|
|
296
|
+
return input;
|
|
297
|
+
}
|
|
298
|
+
if (input instanceof ArrayBuffer) {
|
|
299
|
+
return new Uint8Array(input);
|
|
300
|
+
}
|
|
301
|
+
// File or Blob
|
|
302
|
+
const buffer = await input.arrayBuffer();
|
|
303
|
+
return new Uint8Array(buffer);
|
|
304
|
+
}
|