@snaha/swarm-id 0.0.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 +431 -0
- package/dist/chunk/bmt.d.ts +17 -0
- package/dist/chunk/bmt.d.ts.map +1 -0
- package/dist/chunk/cac.d.ts +18 -0
- package/dist/chunk/cac.d.ts.map +1 -0
- package/dist/chunk/constants.d.ts +10 -0
- package/dist/chunk/constants.d.ts.map +1 -0
- package/dist/chunk/encrypted-cac.d.ts +48 -0
- package/dist/chunk/encrypted-cac.d.ts.map +1 -0
- package/dist/chunk/encryption.d.ts +86 -0
- package/dist/chunk/encryption.d.ts.map +1 -0
- package/dist/chunk/index.d.ts +6 -0
- package/dist/chunk/index.d.ts.map +1 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/proxy/act/act.d.ts +78 -0
- package/dist/proxy/act/act.d.ts.map +1 -0
- package/dist/proxy/act/crypto.d.ts +44 -0
- package/dist/proxy/act/crypto.d.ts.map +1 -0
- package/dist/proxy/act/grantee-list.d.ts +82 -0
- package/dist/proxy/act/grantee-list.d.ts.map +1 -0
- package/dist/proxy/act/history.d.ts +183 -0
- package/dist/proxy/act/history.d.ts.map +1 -0
- package/dist/proxy/act/index.d.ts +104 -0
- package/dist/proxy/act/index.d.ts.map +1 -0
- package/dist/proxy/chunking-encrypted.d.ts +14 -0
- package/dist/proxy/chunking-encrypted.d.ts.map +1 -0
- package/dist/proxy/chunking.d.ts +15 -0
- package/dist/proxy/chunking.d.ts.map +1 -0
- package/dist/proxy/download-data.d.ts +16 -0
- package/dist/proxy/download-data.d.ts.map +1 -0
- package/dist/proxy/feed-manifest.d.ts +62 -0
- package/dist/proxy/feed-manifest.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/async-finder.d.ts +77 -0
- package/dist/proxy/feeds/epochs/async-finder.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/epoch.d.ts +88 -0
- package/dist/proxy/feeds/epochs/epoch.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/finder.d.ts +67 -0
- package/dist/proxy/feeds/epochs/finder.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/index.d.ts +35 -0
- package/dist/proxy/feeds/epochs/index.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/test-utils.d.ts +93 -0
- package/dist/proxy/feeds/epochs/test-utils.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/types.d.ts +109 -0
- package/dist/proxy/feeds/epochs/types.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/updater.d.ts +68 -0
- package/dist/proxy/feeds/epochs/updater.d.ts.map +1 -0
- package/dist/proxy/feeds/epochs/utils.d.ts +22 -0
- package/dist/proxy/feeds/epochs/utils.d.ts.map +1 -0
- package/dist/proxy/feeds/index.d.ts +5 -0
- package/dist/proxy/feeds/index.d.ts.map +1 -0
- package/dist/proxy/feeds/sequence/async-finder.d.ts +14 -0
- package/dist/proxy/feeds/sequence/async-finder.d.ts.map +1 -0
- package/dist/proxy/feeds/sequence/finder.d.ts +17 -0
- package/dist/proxy/feeds/sequence/finder.d.ts.map +1 -0
- package/dist/proxy/feeds/sequence/index.d.ts +23 -0
- package/dist/proxy/feeds/sequence/index.d.ts.map +1 -0
- package/dist/proxy/feeds/sequence/types.d.ts +80 -0
- package/dist/proxy/feeds/sequence/types.d.ts.map +1 -0
- package/dist/proxy/feeds/sequence/updater.d.ts +26 -0
- package/dist/proxy/feeds/sequence/updater.d.ts.map +1 -0
- package/dist/proxy/index.d.ts +6 -0
- package/dist/proxy/index.d.ts.map +1 -0
- package/dist/proxy/manifest-builder.d.ts +183 -0
- package/dist/proxy/manifest-builder.d.ts.map +1 -0
- package/dist/proxy/mantaray-encrypted.d.ts +27 -0
- package/dist/proxy/mantaray-encrypted.d.ts.map +1 -0
- package/dist/proxy/mantaray.d.ts +26 -0
- package/dist/proxy/mantaray.d.ts.map +1 -0
- package/dist/proxy/types.d.ts +29 -0
- package/dist/proxy/types.d.ts.map +1 -0
- package/dist/proxy/upload-data.d.ts +17 -0
- package/dist/proxy/upload-data.d.ts.map +1 -0
- package/dist/proxy/upload-encrypted-data.d.ts +103 -0
- package/dist/proxy/upload-encrypted-data.d.ts.map +1 -0
- package/dist/schemas.d.ts +240 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/storage/debounced-uploader.d.ts +62 -0
- package/dist/storage/debounced-uploader.d.ts.map +1 -0
- package/dist/storage/utilization-store.d.ts +108 -0
- package/dist/storage/utilization-store.d.ts.map +1 -0
- package/dist/swarm-id-auth.d.ts +74 -0
- package/dist/swarm-id-auth.d.ts.map +1 -0
- package/dist/swarm-id-auth.js +2 -0
- package/dist/swarm-id-auth.js.map +1 -0
- package/dist/swarm-id-client.d.ts +878 -0
- package/dist/swarm-id-client.d.ts.map +1 -0
- package/dist/swarm-id-client.js +2 -0
- package/dist/swarm-id-client.js.map +1 -0
- package/dist/swarm-id-proxy.d.ts +236 -0
- package/dist/swarm-id-proxy.d.ts.map +1 -0
- package/dist/swarm-id-proxy.js +2 -0
- package/dist/swarm-id-proxy.js.map +1 -0
- package/dist/swarm-id.esm.js +2 -0
- package/dist/swarm-id.esm.js.map +1 -0
- package/dist/swarm-id.umd.js +2 -0
- package/dist/swarm-id.umd.js.map +1 -0
- package/dist/sync/index.d.ts +9 -0
- package/dist/sync/index.d.ts.map +1 -0
- package/dist/sync/key-derivation.d.ts +25 -0
- package/dist/sync/key-derivation.d.ts.map +1 -0
- package/dist/sync/restore-account.d.ts +28 -0
- package/dist/sync/restore-account.d.ts.map +1 -0
- package/dist/sync/serialization.d.ts +16 -0
- package/dist/sync/serialization.d.ts.map +1 -0
- package/dist/sync/store-interfaces.d.ts +53 -0
- package/dist/sync/store-interfaces.d.ts.map +1 -0
- package/dist/sync/sync-account.d.ts +44 -0
- package/dist/sync/sync-account.d.ts.map +1 -0
- package/dist/sync/types.d.ts +13 -0
- package/dist/sync/types.d.ts.map +1 -0
- package/dist/test-fixtures.d.ts +17 -0
- package/dist/test-fixtures.d.ts.map +1 -0
- package/dist/types-BD_VkNn0.js +2 -0
- package/dist/types-BD_VkNn0.js.map +1 -0
- package/dist/types-lJCaT-50.js +2 -0
- package/dist/types-lJCaT-50.js.map +1 -0
- package/dist/types.d.ts +2157 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/utils/account-payload.d.ts +94 -0
- package/dist/utils/account-payload.d.ts.map +1 -0
- package/dist/utils/account-state-snapshot.d.ts +38 -0
- package/dist/utils/account-state-snapshot.d.ts.map +1 -0
- package/dist/utils/backup-encryption.d.ts +127 -0
- package/dist/utils/backup-encryption.d.ts.map +1 -0
- package/dist/utils/batch-utilization.d.ts +432 -0
- package/dist/utils/batch-utilization.d.ts.map +1 -0
- package/dist/utils/constants.d.ts +11 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/hex.d.ts +17 -0
- package/dist/utils/hex.d.ts.map +1 -0
- package/dist/utils/key-derivation.d.ts +92 -0
- package/dist/utils/key-derivation.d.ts.map +1 -0
- package/dist/utils/storage-managers.d.ts +65 -0
- package/dist/utils/storage-managers.d.ts.map +1 -0
- package/dist/utils/swarm-id-export.d.ts +24 -0
- package/dist/utils/swarm-id-export.d.ts.map +1 -0
- package/dist/utils/ttl.d.ts +49 -0
- package/dist/utils/ttl.d.ts.map +1 -0
- package/dist/utils/url.d.ts +41 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/versioned-storage.d.ts +131 -0
- package/dist/utils/versioned-storage.d.ts.map +1 -0
- package/package.json +78 -0
- package/src/chunk/bmt.test.ts +217 -0
- package/src/chunk/bmt.ts +57 -0
- package/src/chunk/cac.test.ts +214 -0
- package/src/chunk/cac.ts +65 -0
- package/src/chunk/constants.ts +18 -0
- package/src/chunk/encrypted-cac.test.ts +385 -0
- package/src/chunk/encrypted-cac.ts +131 -0
- package/src/chunk/encryption.test.ts +352 -0
- package/src/chunk/encryption.ts +300 -0
- package/src/chunk/index.ts +47 -0
- package/src/index.ts +430 -0
- package/src/proxy/act/act.test.ts +278 -0
- package/src/proxy/act/act.ts +158 -0
- package/src/proxy/act/bee-compat.test.ts +948 -0
- package/src/proxy/act/crypto.test.ts +436 -0
- package/src/proxy/act/crypto.ts +376 -0
- package/src/proxy/act/grantee-list.test.ts +393 -0
- package/src/proxy/act/grantee-list.ts +239 -0
- package/src/proxy/act/history.test.ts +360 -0
- package/src/proxy/act/history.ts +413 -0
- package/src/proxy/act/index.test.ts +748 -0
- package/src/proxy/act/index.ts +853 -0
- package/src/proxy/chunking-encrypted.ts +95 -0
- package/src/proxy/chunking.ts +65 -0
- package/src/proxy/download-data.ts +448 -0
- package/src/proxy/feed-manifest.ts +174 -0
- package/src/proxy/feeds/epochs/async-finder.ts +372 -0
- package/src/proxy/feeds/epochs/epoch.test.ts +249 -0
- package/src/proxy/feeds/epochs/epoch.ts +181 -0
- package/src/proxy/feeds/epochs/finder.ts +282 -0
- package/src/proxy/feeds/epochs/index.ts +73 -0
- package/src/proxy/feeds/epochs/integration.test.ts +1336 -0
- package/src/proxy/feeds/epochs/test-utils.ts +274 -0
- package/src/proxy/feeds/epochs/types.ts +128 -0
- package/src/proxy/feeds/epochs/updater.ts +192 -0
- package/src/proxy/feeds/epochs/utils.ts +62 -0
- package/src/proxy/feeds/index.ts +5 -0
- package/src/proxy/feeds/sequence/async-finder.ts +31 -0
- package/src/proxy/feeds/sequence/finder.ts +73 -0
- package/src/proxy/feeds/sequence/index.ts +54 -0
- package/src/proxy/feeds/sequence/integration.test.ts +966 -0
- package/src/proxy/feeds/sequence/types.ts +103 -0
- package/src/proxy/feeds/sequence/updater.ts +71 -0
- package/src/proxy/index.ts +5 -0
- package/src/proxy/manifest-builder.test.ts +427 -0
- package/src/proxy/manifest-builder.ts +679 -0
- package/src/proxy/mantaray-encrypted.ts +78 -0
- package/src/proxy/mantaray.ts +104 -0
- package/src/proxy/types.ts +32 -0
- package/src/proxy/upload-data.ts +189 -0
- package/src/proxy/upload-encrypted-data.ts +658 -0
- package/src/schemas.ts +299 -0
- package/src/storage/debounced-uploader.ts +192 -0
- package/src/storage/utilization-store.ts +397 -0
- package/src/swarm-id-client.test.ts +99 -0
- package/src/swarm-id-client.ts +3095 -0
- package/src/swarm-id-proxy.ts +3891 -0
- package/src/sync/index.ts +28 -0
- package/src/sync/restore-account.ts +90 -0
- package/src/sync/serialization.ts +39 -0
- package/src/sync/store-interfaces.ts +62 -0
- package/src/sync/sync-account.test.ts +302 -0
- package/src/sync/sync-account.ts +396 -0
- package/src/sync/types.ts +11 -0
- package/src/test-fixtures.ts +109 -0
- package/src/types.ts +1651 -0
- package/src/utils/account-state-snapshot.test.ts +595 -0
- package/src/utils/account-state-snapshot.ts +94 -0
- package/src/utils/backup-encryption.test.ts +442 -0
- package/src/utils/backup-encryption.ts +352 -0
- package/src/utils/batch-utilization.ts +1309 -0
- package/src/utils/constants.ts +20 -0
- package/src/utils/hex.ts +27 -0
- package/src/utils/key-derivation.ts +197 -0
- package/src/utils/storage-managers.ts +365 -0
- package/src/utils/ttl.ts +129 -0
- package/src/utils/url.test.ts +136 -0
- package/src/utils/url.ts +71 -0
- package/src/utils/versioned-storage.ts +323 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// Copyright 2024 The Swarm Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style
|
|
3
|
+
// license that can be found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import { Binary } from "cafe-utility"
|
|
6
|
+
|
|
7
|
+
export const KEY_LENGTH = 32
|
|
8
|
+
export const REFERENCE_SIZE = 64
|
|
9
|
+
|
|
10
|
+
export type Key = Uint8Array
|
|
11
|
+
|
|
12
|
+
export interface Encrypter {
|
|
13
|
+
key(): Key
|
|
14
|
+
encrypt(data: Uint8Array): Uint8Array
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface Decrypter {
|
|
18
|
+
key(): Key
|
|
19
|
+
decrypt(data: Uint8Array): Uint8Array
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface EncryptionInterface extends Encrypter, Decrypter {
|
|
23
|
+
reset(): void
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Core encryption class implementing CTR-mode encryption with Keccak256
|
|
28
|
+
* This matches the Go implementation in bee/pkg/encryption/encryption.go
|
|
29
|
+
*/
|
|
30
|
+
export class Encryption implements EncryptionInterface {
|
|
31
|
+
private readonly encryptionKey: Key
|
|
32
|
+
private readonly keyLen: number
|
|
33
|
+
private readonly padding: number
|
|
34
|
+
private index: number
|
|
35
|
+
private readonly initCtr: number
|
|
36
|
+
|
|
37
|
+
constructor(key: Key, padding: number, initCtr: number) {
|
|
38
|
+
this.encryptionKey = key
|
|
39
|
+
this.keyLen = key.length
|
|
40
|
+
this.padding = padding
|
|
41
|
+
this.initCtr = initCtr
|
|
42
|
+
this.index = 0
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
key(): Key {
|
|
46
|
+
return this.encryptionKey
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Encrypts data with optional padding
|
|
51
|
+
*/
|
|
52
|
+
encrypt(data: Uint8Array): Uint8Array {
|
|
53
|
+
const length = data.length
|
|
54
|
+
let outLength = length
|
|
55
|
+
const isFixedPadding = this.padding > 0
|
|
56
|
+
|
|
57
|
+
if (isFixedPadding) {
|
|
58
|
+
if (length > this.padding) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
`data length ${length} longer than padding ${this.padding}`,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
outLength = this.padding
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const out = new Uint8Array(outLength)
|
|
67
|
+
this.transform(data, out)
|
|
68
|
+
|
|
69
|
+
return out
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Decrypts data (caller must know original length if padding was used)
|
|
74
|
+
*/
|
|
75
|
+
decrypt(data: Uint8Array): Uint8Array {
|
|
76
|
+
const length = data.length
|
|
77
|
+
|
|
78
|
+
if (this.padding > 0 && length !== this.padding) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
`data length ${length} different than padding ${this.padding}`,
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const out = new Uint8Array(length)
|
|
85
|
+
this.transform(data, out)
|
|
86
|
+
|
|
87
|
+
return out
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resets the counter - only safe to call after encryption/decryption is completed
|
|
92
|
+
*/
|
|
93
|
+
reset(): void {
|
|
94
|
+
this.index = 0
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Transforms data by splitting into key-length segments and encrypting sequentially
|
|
99
|
+
*/
|
|
100
|
+
private transform(input: Uint8Array, out: Uint8Array): void {
|
|
101
|
+
const inLength = input.length
|
|
102
|
+
|
|
103
|
+
for (let i = 0; i < inLength; i += this.keyLen) {
|
|
104
|
+
const l = Math.min(this.keyLen, inLength - i)
|
|
105
|
+
this.transcrypt(
|
|
106
|
+
this.index,
|
|
107
|
+
input.subarray(i, i + l),
|
|
108
|
+
out.subarray(i, i + l),
|
|
109
|
+
)
|
|
110
|
+
this.index++
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Pad the rest if out is longer
|
|
114
|
+
// Use deterministic padding based on encryption key
|
|
115
|
+
if (out.length > inLength) {
|
|
116
|
+
padDeterministic(out.subarray(inLength), this.encryptionKey, inLength)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Segment-wise transformation using XOR with Keccak256-derived keys
|
|
122
|
+
* Matches the Go implementation's Transcrypt function
|
|
123
|
+
*/
|
|
124
|
+
private transcrypt(i: number, input: Uint8Array, out: Uint8Array): void {
|
|
125
|
+
// First hash: key with counter (initial counter + i)
|
|
126
|
+
const ctrBytes = new Uint8Array(4)
|
|
127
|
+
const view = new DataView(ctrBytes.buffer)
|
|
128
|
+
view.setUint32(0, i + this.initCtr, true) // little-endian
|
|
129
|
+
|
|
130
|
+
const keyAndCtr = new Uint8Array(this.encryptionKey.length + 4)
|
|
131
|
+
keyAndCtr.set(this.encryptionKey)
|
|
132
|
+
keyAndCtr.set(ctrBytes, this.encryptionKey.length)
|
|
133
|
+
const ctrHash = Binary.keccak256(keyAndCtr)
|
|
134
|
+
|
|
135
|
+
// Second round of hashing for selective disclosure
|
|
136
|
+
const segmentKey = Binary.keccak256(ctrHash)
|
|
137
|
+
|
|
138
|
+
// XOR bytes up to length of input (out must be at least as long)
|
|
139
|
+
const inLength = input.length
|
|
140
|
+
for (let j = 0; j < inLength; j++) {
|
|
141
|
+
out[j] = input[j] ^ segmentKey[j]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Insert padding if out is longer
|
|
145
|
+
// Use deterministic padding based on encryption key
|
|
146
|
+
if (out.length > inLength) {
|
|
147
|
+
padDeterministic(
|
|
148
|
+
out.subarray(inLength),
|
|
149
|
+
this.encryptionKey,
|
|
150
|
+
i * this.keyLen + inLength,
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Fills buffer with cryptographically secure random data
|
|
158
|
+
* Works in both browser (Web Crypto API) and Node.js environments
|
|
159
|
+
*/
|
|
160
|
+
function getRandomValues(buffer: Uint8Array): void {
|
|
161
|
+
if (buffer.length === 0) return
|
|
162
|
+
|
|
163
|
+
// Use Web Crypto API for secure random bytes
|
|
164
|
+
crypto.getRandomValues(buffer)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Fills buffer with pseudo-random data derived from a key
|
|
169
|
+
* This makes padding deterministic for testing purposes
|
|
170
|
+
*
|
|
171
|
+
* @param buffer Buffer to fill with padding
|
|
172
|
+
* @param key Encryption key to use as seed for deterministic padding
|
|
173
|
+
* @param offset Offset within the logical data stream (for uniqueness)
|
|
174
|
+
*/
|
|
175
|
+
function padDeterministic(buffer: Uint8Array, key: Key, offset: number): void {
|
|
176
|
+
if (buffer.length === 0) return
|
|
177
|
+
|
|
178
|
+
// Generate deterministic padding by hashing key + offset
|
|
179
|
+
let filled = 0
|
|
180
|
+
let counter = offset
|
|
181
|
+
|
|
182
|
+
while (filled < buffer.length) {
|
|
183
|
+
// Hash: key || counter
|
|
184
|
+
const counterBytes = new Uint8Array(4)
|
|
185
|
+
new DataView(counterBytes.buffer).setUint32(0, counter, true)
|
|
186
|
+
|
|
187
|
+
const seedData = new Uint8Array(key.length + counterBytes.length)
|
|
188
|
+
seedData.set(key)
|
|
189
|
+
seedData.set(counterBytes, key.length)
|
|
190
|
+
|
|
191
|
+
const hash = Binary.keccak256(seedData)
|
|
192
|
+
|
|
193
|
+
// Copy as many bytes as needed from the hash
|
|
194
|
+
const toCopy = Math.min(hash.length, buffer.length - filled)
|
|
195
|
+
buffer.set(hash.subarray(0, toCopy), filled)
|
|
196
|
+
|
|
197
|
+
filled += toCopy
|
|
198
|
+
counter++
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Generates a cryptographically secure random key
|
|
204
|
+
*/
|
|
205
|
+
export function generateRandomKey(length: number = KEY_LENGTH): Key {
|
|
206
|
+
const key = new Uint8Array(length)
|
|
207
|
+
getRandomValues(key)
|
|
208
|
+
|
|
209
|
+
return key
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Creates encryption interface for chunk span (first 8 bytes)
|
|
214
|
+
*/
|
|
215
|
+
export function newSpanEncryption(key: Key): EncryptionInterface {
|
|
216
|
+
// ChunkSize is typically 4096, so ChunkSize/KeyLength = 128
|
|
217
|
+
const CHUNK_SIZE = 4096
|
|
218
|
+
|
|
219
|
+
return new Encryption(key, 0, Math.floor(CHUNK_SIZE / KEY_LENGTH))
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Creates encryption interface for chunk data
|
|
224
|
+
*/
|
|
225
|
+
export function newDataEncryption(key: Key): EncryptionInterface {
|
|
226
|
+
const CHUNK_SIZE = 4096
|
|
227
|
+
|
|
228
|
+
return new Encryption(key, CHUNK_SIZE, 0)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export interface ChunkEncrypter {
|
|
232
|
+
encryptChunk(
|
|
233
|
+
chunkData: Uint8Array,
|
|
234
|
+
key?: Key,
|
|
235
|
+
): {
|
|
236
|
+
key: Key
|
|
237
|
+
encryptedSpan: Uint8Array
|
|
238
|
+
encryptedData: Uint8Array
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Default chunk encrypter implementation
|
|
244
|
+
*/
|
|
245
|
+
export class DefaultChunkEncrypter implements ChunkEncrypter {
|
|
246
|
+
encryptChunk(
|
|
247
|
+
chunkData: Uint8Array,
|
|
248
|
+
key?: Key,
|
|
249
|
+
): {
|
|
250
|
+
key: Key
|
|
251
|
+
encryptedSpan: Uint8Array
|
|
252
|
+
encryptedData: Uint8Array
|
|
253
|
+
} {
|
|
254
|
+
const encryptionKey = key || generateRandomKey(KEY_LENGTH)
|
|
255
|
+
|
|
256
|
+
// Encrypt span (first 8 bytes)
|
|
257
|
+
const spanEncrypter = newSpanEncryption(encryptionKey)
|
|
258
|
+
const encryptedSpan = spanEncrypter.encrypt(chunkData.subarray(0, 8))
|
|
259
|
+
|
|
260
|
+
// Encrypt data (remaining bytes)
|
|
261
|
+
const dataEncrypter = newDataEncryption(encryptionKey)
|
|
262
|
+
const encryptedData = dataEncrypter.encrypt(chunkData.subarray(8))
|
|
263
|
+
|
|
264
|
+
return {
|
|
265
|
+
key: encryptionKey,
|
|
266
|
+
encryptedSpan,
|
|
267
|
+
encryptedData,
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Creates a new chunk encrypter
|
|
274
|
+
*/
|
|
275
|
+
export function newChunkEncrypter(): ChunkEncrypter {
|
|
276
|
+
return new DefaultChunkEncrypter()
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Decrypts encrypted chunk data using the provided encryption key
|
|
281
|
+
*/
|
|
282
|
+
export function decryptChunkData(
|
|
283
|
+
key: Key,
|
|
284
|
+
encryptedChunkData: Uint8Array,
|
|
285
|
+
): Uint8Array {
|
|
286
|
+
// Decrypt span (first 8 bytes)
|
|
287
|
+
const spanDecrypter = newSpanEncryption(key)
|
|
288
|
+
const decryptedSpan = spanDecrypter.decrypt(encryptedChunkData.subarray(0, 8))
|
|
289
|
+
|
|
290
|
+
// Decrypt data (remaining bytes - should be 4096 bytes due to padding)
|
|
291
|
+
const dataDecrypter = newDataEncryption(key)
|
|
292
|
+
const decryptedData = dataDecrypter.decrypt(encryptedChunkData.subarray(8))
|
|
293
|
+
|
|
294
|
+
// Concatenate span and data
|
|
295
|
+
const result = new Uint8Array(8 + decryptedData.length)
|
|
296
|
+
result.set(decryptedSpan)
|
|
297
|
+
result.set(decryptedData, 8)
|
|
298
|
+
|
|
299
|
+
return result
|
|
300
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// Re-export public API for chunk functionality
|
|
2
|
+
|
|
3
|
+
// Constants
|
|
4
|
+
export {
|
|
5
|
+
MIN_PAYLOAD_SIZE,
|
|
6
|
+
MAX_PAYLOAD_SIZE,
|
|
7
|
+
SPAN_SIZE,
|
|
8
|
+
UNENCRYPTED_REF_SIZE,
|
|
9
|
+
ENCRYPTED_REF_SIZE,
|
|
10
|
+
IDENTIFIER_SIZE,
|
|
11
|
+
SIGNATURE_SIZE,
|
|
12
|
+
SOC_HEADER_SIZE,
|
|
13
|
+
DEFAULT_DOWNLOAD_CONCURRENCY,
|
|
14
|
+
} from "./constants"
|
|
15
|
+
|
|
16
|
+
// Encryption utilities
|
|
17
|
+
export {
|
|
18
|
+
type Key,
|
|
19
|
+
type ChunkEncrypter,
|
|
20
|
+
type Encrypter,
|
|
21
|
+
type Decrypter,
|
|
22
|
+
type EncryptionInterface,
|
|
23
|
+
KEY_LENGTH,
|
|
24
|
+
REFERENCE_SIZE,
|
|
25
|
+
newChunkEncrypter,
|
|
26
|
+
decryptChunkData,
|
|
27
|
+
generateRandomKey,
|
|
28
|
+
newSpanEncryption,
|
|
29
|
+
newDataEncryption,
|
|
30
|
+
Encryption,
|
|
31
|
+
DefaultChunkEncrypter,
|
|
32
|
+
} from "./encryption"
|
|
33
|
+
|
|
34
|
+
// BMT hash calculation
|
|
35
|
+
export { calculateChunkAddress } from "./bmt"
|
|
36
|
+
|
|
37
|
+
// Content-addressed chunks
|
|
38
|
+
export { type ContentAddressedChunk, makeContentAddressedChunk } from "./cac"
|
|
39
|
+
|
|
40
|
+
// Encrypted content-addressed chunks
|
|
41
|
+
export {
|
|
42
|
+
type EncryptedChunk,
|
|
43
|
+
makeEncryptedContentAddressedChunk,
|
|
44
|
+
decryptEncryptedChunk,
|
|
45
|
+
extractEncryptionKey,
|
|
46
|
+
extractChunkAddress,
|
|
47
|
+
} from "./encrypted-cac"
|