@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.
Files changed (67) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +543 -0
  3. package/dist/crypto/index.cjs +807 -0
  4. package/dist/crypto/index.d.cts +641 -0
  5. package/dist/crypto/index.d.ts +641 -0
  6. package/dist/crypto/index.js +716 -0
  7. package/dist/decrypt-eSHlbh1j.d.cts +321 -0
  8. package/dist/decrypt-eSHlbh1j.d.ts +321 -0
  9. package/dist/fs/index.cjs +1168 -0
  10. package/dist/fs/index.d.cts +400 -0
  11. package/dist/fs/index.d.ts +400 -0
  12. package/dist/fs/index.js +1091 -0
  13. package/dist/index.cjs +2160 -0
  14. package/dist/index.d.cts +282 -0
  15. package/dist/index.d.ts +282 -0
  16. package/dist/index.js +2031 -0
  17. package/dist/integrity-CCYjrap3.d.ts +31 -0
  18. package/dist/integrity-Dx9jukMH.d.cts +31 -0
  19. package/dist/types-61c7Q9ri.d.ts +134 -0
  20. package/dist/types-Ch0y-n7K.d.cts +134 -0
  21. package/dist/utils/index.cjs +129 -0
  22. package/dist/utils/index.d.cts +49 -0
  23. package/dist/utils/index.d.ts +49 -0
  24. package/dist/utils/index.js +114 -0
  25. package/dist/vault/index.cjs +713 -0
  26. package/dist/vault/index.d.cts +237 -0
  27. package/dist/vault/index.d.ts +237 -0
  28. package/dist/vault/index.js +677 -0
  29. package/dist/version-BygzPVGs.d.cts +55 -0
  30. package/dist/version-BygzPVGs.d.ts +55 -0
  31. package/package.json +86 -0
  32. package/src/crypto/dilithium.ts +233 -0
  33. package/src/crypto/hybrid.ts +358 -0
  34. package/src/crypto/index.ts +181 -0
  35. package/src/crypto/kyber.ts +199 -0
  36. package/src/crypto/nacl.ts +204 -0
  37. package/src/crypto/primitives/blake3.ts +141 -0
  38. package/src/crypto/primitives/chacha.ts +211 -0
  39. package/src/crypto/primitives/hkdf.ts +192 -0
  40. package/src/crypto/primitives/index.ts +54 -0
  41. package/src/crypto/primitives.ts +144 -0
  42. package/src/crypto/x25519.ts +134 -0
  43. package/src/fs/aes.ts +343 -0
  44. package/src/fs/argon2.ts +184 -0
  45. package/src/fs/browser.ts +408 -0
  46. package/src/fs/decrypt.ts +320 -0
  47. package/src/fs/encrypt.ts +324 -0
  48. package/src/fs/format.ts +425 -0
  49. package/src/fs/index.ts +144 -0
  50. package/src/fs/types.ts +304 -0
  51. package/src/index.ts +414 -0
  52. package/src/kdf/index.ts +311 -0
  53. package/src/runtime/crypto.ts +16 -0
  54. package/src/security/index.ts +345 -0
  55. package/src/tunnel/index.ts +39 -0
  56. package/src/tunnel/session.ts +229 -0
  57. package/src/tunnel/types.ts +115 -0
  58. package/src/utils/entropy.ts +128 -0
  59. package/src/utils/index.ts +25 -0
  60. package/src/utils/integrity.ts +95 -0
  61. package/src/vault/decrypt.ts +167 -0
  62. package/src/vault/encrypt.ts +207 -0
  63. package/src/vault/index.ts +71 -0
  64. package/src/vault/manager.ts +327 -0
  65. package/src/vault/migrate.ts +190 -0
  66. package/src/vault/types.ts +177 -0
  67. package/src/version.ts +304 -0
@@ -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
+ }