@ibgib/core-gib 0.1.42 → 0.1.44
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/dist/keystone/kdf/kdf-constants.d.mts +25 -0
- package/dist/keystone/kdf/kdf-constants.d.mts.map +1 -0
- package/dist/keystone/kdf/kdf-constants.mjs +28 -0
- package/dist/keystone/kdf/kdf-constants.mjs.map +1 -0
- package/dist/keystone/kdf/kdf-helpers.d.mts +45 -0
- package/dist/keystone/kdf/kdf-helpers.d.mts.map +1 -0
- package/dist/keystone/kdf/kdf-helpers.mjs +94 -0
- package/dist/keystone/kdf/kdf-helpers.mjs.map +1 -0
- package/dist/keystone/kdf/kdf-types.d.mts +49 -0
- package/dist/keystone/kdf/kdf-types.d.mts.map +1 -0
- package/dist/keystone/kdf/kdf-types.mjs +2 -0
- package/dist/keystone/kdf/kdf-types.mjs.map +1 -0
- package/dist/keystone/keystone-config-builder.d.mts +65 -12
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +138 -46
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.respec.mjs +21 -13
- package/dist/keystone/keystone-config-builder.respec.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +15 -0
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +16 -0
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts +4 -4
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +8 -5
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.d.mts +1 -1
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.mjs +6 -5
- package/dist/keystone/keystone-service-v1.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.respec.mjs +72 -45
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
- package/dist/keystone/keystone-types.d.mts +28 -18
- package/dist/keystone/keystone-types.d.mts.map +1 -1
- package/dist/keystone/keystone-types.mjs +26 -15
- package/dist/keystone/keystone-types.mjs.map +1 -1
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.d.mts.map +1 -1
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs +7 -10
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs.map +1 -1
- package/dist/sync/sync-conflict-text-merge.respec.mjs +26 -26
- package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +9 -0
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +10 -0
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts +7 -0
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.d.mts.map +1 -0
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +282 -0
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -0
- package/dist/sync/sync-saga-coordinator.d.mts +22 -11
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +120 -27
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts +1 -7
- package/dist/sync/sync-saga-message/sync-saga-message-types.d.mts.map +1 -1
- package/dist/sync/sync-types.d.mts +11 -0
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/dist/sync/sync-types.mjs.map +1 -1
- package/dist/test/mock-space.d.mts +1 -38
- package/dist/test/mock-space.d.mts.map +1 -1
- package/dist/test/mock-space.mjs +73 -78
- package/dist/test/mock-space.mjs.map +1 -1
- package/package.json +1 -1
- package/src/keystone/README.md +119 -0
- package/src/keystone/docs/architecture.md +32 -1
- package/src/keystone/kdf/kdf-constants.mts +34 -0
- package/src/keystone/kdf/kdf-helpers.mts +105 -0
- package/src/keystone/kdf/kdf-types.mts +58 -0
- package/src/keystone/keystone-config-builder.mts +170 -47
- package/src/keystone/keystone-config-builder.respec.mts +21 -14
- package/src/keystone/keystone-constants.mts +21 -2
- package/src/keystone/keystone-helpers.mts +19 -14
- package/src/keystone/keystone-service-v1.mts +23 -22
- package/src/keystone/keystone-service-v1.respec.mts +71 -44
- package/src/keystone/keystone-types.mts +37 -23
- package/src/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mts +9 -13
- package/src/sync/README.md +122 -5
- package/src/sync/docs/architecture.md +2 -2
- package/src/sync/{SYNC_TESTING.md → docs/testing.md} +113 -28
- package/src/sync/sync-conflict-text-merge.respec.mts +25 -25
- package/src/sync/sync-constants.mts +12 -0
- package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +349 -0
- package/src/sync/sync-saga-coordinator.mts +158 -33
- package/src/sync/sync-saga-message/sync-saga-message-types.mts +1 -7
- package/src/sync/sync-types.mts +12 -0
- package/src/test/mock-space.mts +72 -72
- package/tmp.md +0 -274
- package/src/sync/docs/verification.md +0 -43
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { extractErrorMsg, HashAlgorithm } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
|
+
|
|
3
|
+
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
|
|
1
4
|
import {
|
|
2
|
-
KeystonePoolConfig,
|
|
3
|
-
|
|
4
|
-
KeystonePoolBehavior,
|
|
5
|
-
KeystoneReplenishStrategy,
|
|
6
|
-
KeystonePoolConfigBase
|
|
5
|
+
KeystonePoolConfig, KeystonePoolConfig_HashV1, KeystonePoolBehavior,
|
|
6
|
+
KeystoneReplenishStrategy, KeystonePoolConfigBase, KeystoneChallengeType,
|
|
7
7
|
} from './keystone-types.mjs';
|
|
8
|
-
import {
|
|
8
|
+
import { POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE, KEYSTONE_CONFIG_DEFAULT_SIZE, KEYSTONE_CONFIG_DEFAULT_BINDING, KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY, KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL, KEYSTONE_CONFIG_DEFAULT_RANDOM, KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY, KeystoneVerb, KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM, KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS, KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY, KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY } from './keystone-constants.mjs';
|
|
9
|
+
|
|
10
|
+
const logalot = GLOBAL_LOG_A_LOT;
|
|
9
11
|
|
|
10
12
|
/**
|
|
11
13
|
* Abstract Base Builder.
|
|
@@ -14,17 +16,25 @@ import { POOL_ID_DEFAULT, POOL_ID_REVOKE, KEYSTONE_VERB_REVOKE } from './keyston
|
|
|
14
16
|
* @template TConfig The concrete config type being built.
|
|
15
17
|
*/
|
|
16
18
|
export abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConfigBase> {
|
|
17
|
-
protected
|
|
18
|
-
protected
|
|
19
|
-
protected
|
|
20
|
-
protected
|
|
21
|
-
protected
|
|
19
|
+
protected _id: string | undefined;
|
|
20
|
+
protected _salt: string | undefined;
|
|
21
|
+
protected _size: number | undefined;
|
|
22
|
+
protected _replenish: KeystoneReplenishStrategy | undefined;
|
|
23
|
+
protected _seq: number | undefined;
|
|
24
|
+
protected _rand: number | undefined;
|
|
22
25
|
protected _verbs: string[] = [];
|
|
23
|
-
protected _targetBinding: number
|
|
26
|
+
protected _targetBinding: number | undefined;
|
|
24
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Sets the unique id for this pool.
|
|
30
|
+
*/
|
|
31
|
+
withId(id: string): this {
|
|
32
|
+
this._id = id;
|
|
33
|
+
return this;
|
|
34
|
+
}
|
|
25
35
|
|
|
26
36
|
/**
|
|
27
|
-
* Sets the unique salt
|
|
37
|
+
* Sets the unique salt for this pool.
|
|
28
38
|
*/
|
|
29
39
|
withSalt(salt: string): this {
|
|
30
40
|
this._salt = salt;
|
|
@@ -71,7 +81,7 @@ export abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConf
|
|
|
71
81
|
/**
|
|
72
82
|
* Configures the pool to use Hybrid (Both FIFO and Random) selection.
|
|
73
83
|
*/
|
|
74
|
-
withHybrid(seqCount: number, randCount: number): this {
|
|
84
|
+
withHybrid({ seqCount, randCount }: { seqCount: number, randCount: number }): this {
|
|
75
85
|
this._seq = seqCount;
|
|
76
86
|
this._rand = randCount;
|
|
77
87
|
return this;
|
|
@@ -90,6 +100,11 @@ export abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConf
|
|
|
90
100
|
* Helper for subclasses.
|
|
91
101
|
*/
|
|
92
102
|
protected buildBehavior(): KeystonePoolBehavior {
|
|
103
|
+
if (this._size === undefined) { throw new Error(`size required (E: 68320865d9adb8477836485b20b08826)`); }
|
|
104
|
+
if (this._replenish === undefined) { throw new Error(`replenish strategy required (E: 9f8798d1a568763a282e53c89185b826)`); }
|
|
105
|
+
if (this._seq === undefined) { throw new Error(`sequential required (E: e0da08a24e9790d0a8c1a9322f8eb826)`); }
|
|
106
|
+
if (this._rand === undefined) { throw new Error(`selectRandomly required (E: 7721d84d1a8b7d020d0ab33c3f811426)`); }
|
|
107
|
+
if (this._targetBinding === undefined) { throw new Error(`targetBinding required (E: 9add64d7e8e8cba01d901727a8e9b826)`); }
|
|
93
108
|
return {
|
|
94
109
|
size: this._size,
|
|
95
110
|
replenish: this._replenish,
|
|
@@ -108,14 +123,14 @@ export abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConf
|
|
|
108
123
|
return this;
|
|
109
124
|
}
|
|
110
125
|
|
|
111
|
-
protected buildBase(): KeystonePoolConfigBase {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
126
|
+
// protected buildBase(): KeystonePoolConfigBase {
|
|
127
|
+
// // Helper to keep the concrete build() clean
|
|
128
|
+
// return {
|
|
129
|
+
// type: KeystoneChallengeType.hash_reveal_v1, // This is overridden by concrete/interface usually, but needed for base shape
|
|
130
|
+
// salt: this._salt,
|
|
131
|
+
// allowedVerbs: this._verbs
|
|
132
|
+
// } as any;
|
|
133
|
+
// }
|
|
119
134
|
|
|
120
135
|
abstract build(): TConfig;
|
|
121
136
|
}
|
|
@@ -124,28 +139,56 @@ export abstract class KeystoneConfigBuilderBase<TConfig extends KeystonePoolConf
|
|
|
124
139
|
* Concrete Builder for Hash-Reveal V1 Strategy.
|
|
125
140
|
*/
|
|
126
141
|
export class KeystoneConfigBuilder_HashV1 extends KeystoneConfigBuilderBase<KeystonePoolConfig_HashV1> {
|
|
127
|
-
|
|
128
|
-
private
|
|
142
|
+
protected lc: string = `[${KeystoneConfigBuilder_HashV1}]`;
|
|
143
|
+
private _algo: HashAlgorithm | undefined;
|
|
144
|
+
private _rounds: number | undefined;
|
|
129
145
|
|
|
130
146
|
/**
|
|
131
147
|
* Sets the hashing strength.
|
|
132
148
|
*/
|
|
133
|
-
withHash(algo:
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
149
|
+
withHash({ algo, rounds }: { algo: HashAlgorithm, rounds: number }): this {
|
|
150
|
+
const lc = `${this.lc}[${this.withHash.name}]`;
|
|
151
|
+
try {
|
|
152
|
+
if (logalot) { console.log(`${lc} starting... (I: 15d1b3bd2e98bba33fc6c78228755826)`); }
|
|
153
|
+
|
|
154
|
+
this._algo = algo;
|
|
155
|
+
this._rounds = rounds;
|
|
156
|
+
return this;
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
159
|
+
throw error;
|
|
160
|
+
} finally {
|
|
161
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
162
|
+
}
|
|
137
163
|
}
|
|
138
164
|
|
|
139
165
|
build(): KeystonePoolConfig_HashV1 {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
166
|
+
const lc = `${this.lc}[${this.build.name}]`;
|
|
167
|
+
try {
|
|
168
|
+
if (logalot) { console.log(`${lc} starting... (I: 5df568c63c4993bb98df0a319ee16826)`); }
|
|
169
|
+
|
|
170
|
+
if (!this._id) { throw new Error(`id required (E: b50d082adf38bcbf463552f80d2c3226)`); }
|
|
171
|
+
if (!this._salt) { throw new Error(`salt required (E: b0f1926657b8d7d3a88fb9385ead5826)`); }
|
|
172
|
+
if (!this._algo) { throw new Error(`algorithm required (E: cff228f9898fd6383ef752088dae6826)`); }
|
|
173
|
+
if (this._rounds === undefined) { throw new Error(`rounds required (E: eb72580f3b014cda18cba3e399683c26)`); }
|
|
174
|
+
|
|
175
|
+
const result: KeystonePoolConfig_HashV1 = {
|
|
176
|
+
id: this._id,
|
|
177
|
+
type: KeystoneChallengeType.hash_reveal_v1,
|
|
178
|
+
salt: this._salt,
|
|
179
|
+
allowedVerbs: this._verbs,
|
|
180
|
+
behavior: this.buildBehavior(),
|
|
181
|
+
algo: this._algo,
|
|
182
|
+
rounds: this._rounds,
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
return result;
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
188
|
+
throw error;
|
|
189
|
+
} finally {
|
|
190
|
+
if (logalot) { console.log(`${lc} complete.`); }
|
|
191
|
+
}
|
|
149
192
|
}
|
|
150
193
|
}
|
|
151
194
|
|
|
@@ -166,22 +209,102 @@ export class KeystoneConfig {
|
|
|
166
209
|
// FACTORY FUNCTIONS (Presets)
|
|
167
210
|
// ===========================================================================
|
|
168
211
|
|
|
169
|
-
|
|
212
|
+
interface KeystoneConfigFactoryOptions_Standard {
|
|
213
|
+
/**
|
|
214
|
+
* id for pool that this config pertains to
|
|
215
|
+
*/
|
|
216
|
+
id: string;
|
|
217
|
+
/**
|
|
218
|
+
* should be a unique string
|
|
219
|
+
*/
|
|
220
|
+
salt: string;
|
|
221
|
+
/**
|
|
222
|
+
* number of challenges in the pool
|
|
223
|
+
* @see {@link KeystonePoolConfig}
|
|
224
|
+
*/
|
|
225
|
+
size?: number;
|
|
226
|
+
/**
|
|
227
|
+
* number of sequential challenges required for solution per action
|
|
228
|
+
*/
|
|
229
|
+
sequential?: number;
|
|
230
|
+
/**
|
|
231
|
+
* number of random challenges required for solution per action
|
|
232
|
+
*/
|
|
233
|
+
random?: number;
|
|
234
|
+
/**
|
|
235
|
+
* number of target binding characters required for solution per action
|
|
236
|
+
* @see {@link KeystonePoolBehavior.targetBindingChars}
|
|
237
|
+
*/
|
|
238
|
+
targetBinding?: number;
|
|
239
|
+
/**
|
|
240
|
+
* @see {@link KeystonePoolBehavior.replenish}
|
|
241
|
+
*/
|
|
242
|
+
replenishStrategy?: KeystoneReplenishStrategy;
|
|
243
|
+
/**
|
|
244
|
+
* verbs for the pool
|
|
245
|
+
*/
|
|
246
|
+
verbs?: string[];
|
|
247
|
+
hashAlgorithm?: HashAlgorithm;
|
|
248
|
+
hashRounds?: number;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function createStandardPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
|
|
252
|
+
let {
|
|
253
|
+
salt, id, size, sequential, random, targetBinding, replenishStrategy,
|
|
254
|
+
verbs, hashAlgorithm, hashRounds,
|
|
255
|
+
} = opts;
|
|
170
256
|
return KeystoneConfig.hash()
|
|
257
|
+
.withId(id)
|
|
171
258
|
.withSalt(salt)
|
|
172
|
-
.withSize(
|
|
173
|
-
.withHybrid(
|
|
174
|
-
|
|
259
|
+
.withSize(size ?? KEYSTONE_CONFIG_DEFAULT_SIZE)
|
|
260
|
+
.withHybrid({
|
|
261
|
+
seqCount: sequential ?? KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL,
|
|
262
|
+
randCount: random ?? KEYSTONE_CONFIG_DEFAULT_RANDOM,
|
|
263
|
+
})
|
|
264
|
+
.withTargetBinding(targetBinding ?? KEYSTONE_CONFIG_DEFAULT_BINDING)
|
|
265
|
+
.withReplenishStrategy(replenishStrategy ?? KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY)
|
|
266
|
+
.withHash({
|
|
267
|
+
algo: hashAlgorithm ?? KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM,
|
|
268
|
+
rounds: hashRounds ?? KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS
|
|
269
|
+
})
|
|
270
|
+
.forVerbs(verbs ?? [])
|
|
175
271
|
.build();
|
|
176
272
|
}
|
|
177
273
|
|
|
178
|
-
export function
|
|
274
|
+
export function createHighSecurityPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
|
|
275
|
+
let {
|
|
276
|
+
salt, id, size, sequential, random, targetBinding, replenishStrategy,
|
|
277
|
+
verbs, hashAlgorithm, hashRounds,
|
|
278
|
+
} = opts;
|
|
179
279
|
return KeystoneConfig.hash()
|
|
280
|
+
.withId(id)
|
|
180
281
|
.withSalt(salt)
|
|
181
|
-
.
|
|
182
|
-
.
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
282
|
+
.withSize(size ?? KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY)
|
|
283
|
+
.withHybrid({
|
|
284
|
+
seqCount: sequential ?? KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY,
|
|
285
|
+
randCount: random ?? KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY,
|
|
286
|
+
})
|
|
287
|
+
.withTargetBinding(targetBinding ?? KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY)
|
|
288
|
+
.withReplenishStrategy(replenishStrategy ?? KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY)
|
|
289
|
+
.withHash({
|
|
290
|
+
algo: hashAlgorithm ?? KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY,
|
|
291
|
+
rounds: hashRounds ?? KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY
|
|
292
|
+
})
|
|
293
|
+
.forVerbs(verbs ?? [])
|
|
186
294
|
.build();
|
|
187
295
|
}
|
|
296
|
+
|
|
297
|
+
export function createManagePoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
|
|
298
|
+
return createHighSecurityPoolConfig({
|
|
299
|
+
...opts,
|
|
300
|
+
verbs: [KeystoneVerb.MANAGE],
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function createRevocationPoolConfig(opts: KeystoneConfigFactoryOptions_Standard): KeystonePoolConfig {
|
|
305
|
+
return createHighSecurityPoolConfig({
|
|
306
|
+
...opts,
|
|
307
|
+
verbs: [KeystoneVerb.REVOKE],
|
|
308
|
+
replenishStrategy: KeystoneReplenishStrategy.deleteAll,
|
|
309
|
+
});
|
|
310
|
+
}
|
|
@@ -5,9 +5,9 @@ const maam = `[${import.meta.url}]`, sir = maam;
|
|
|
5
5
|
import { } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
6
6
|
|
|
7
7
|
import { GLOBAL_LOG_A_LOT } from '../core-constants.mjs';
|
|
8
|
-
import { KeystonePoolConfig_HashV1 } from './keystone-types.mjs';
|
|
8
|
+
import { KEYSTONE_REPLENISH_STRATEGY_DELETE_ALL, KeystoneChallengeType, KeystonePoolConfig_HashV1, KeystoneReplenishStrategy } from './keystone-types.mjs';
|
|
9
9
|
import { createRevocationPoolConfig, createStandardPoolConfig } from './keystone-config-builder.mjs';
|
|
10
|
-
import { KEYSTONE_VERB_REVOKE, } from './keystone-constants.mjs';
|
|
10
|
+
import { KEYSTONE_CONFIG_DEFAULT_RANDOM, KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY, KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL, KEYSTONE_CONFIG_DEFAULT_SIZE, KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY, KEYSTONE_VERB_REVOKE, POOL_ID_REVOKE, } from './keystone-constants.mjs';
|
|
11
11
|
|
|
12
12
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
13
13
|
|
|
@@ -15,32 +15,39 @@ const logalot = GLOBAL_LOG_A_LOT;
|
|
|
15
15
|
await respecfully(sir, 'Config Builders', async () => {
|
|
16
16
|
|
|
17
17
|
await ifWe(sir, 'createStandardPoolConfig defaults are correct', async () => {
|
|
18
|
-
const
|
|
18
|
+
const id = "test_id";
|
|
19
|
+
const salt = "test_salt";
|
|
20
|
+
const config = createStandardPoolConfig({ id, salt }) as KeystonePoolConfig_HashV1;
|
|
19
21
|
|
|
20
|
-
iReckon(sir, config.
|
|
21
|
-
iReckon(sir, config.
|
|
22
|
-
iReckon(sir, config.type).willEqual(
|
|
22
|
+
iReckon(sir, config.id).willEqual(id);
|
|
23
|
+
iReckon(sir, config.salt).willEqual(salt);
|
|
24
|
+
iReckon(sir, config.type).willEqual(KeystoneChallengeType.hash_reveal_v1);
|
|
23
25
|
|
|
24
26
|
// Behavior check
|
|
25
27
|
const b = config.behavior;
|
|
26
|
-
iReckon(sir, b.size).willEqual(
|
|
27
|
-
iReckon(sir, b.selectSequentially).willEqual(
|
|
28
|
-
iReckon(sir, b.selectRandomly).willEqual(
|
|
29
|
-
iReckon(sir, b.replenish).willEqual(
|
|
28
|
+
iReckon(sir, b.size).willEqual(KEYSTONE_CONFIG_DEFAULT_SIZE);
|
|
29
|
+
iReckon(sir, b.selectSequentially).willEqual(KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL);
|
|
30
|
+
iReckon(sir, b.selectRandomly).willEqual(KEYSTONE_CONFIG_DEFAULT_RANDOM);
|
|
31
|
+
iReckon(sir, b.replenish).willEqual(KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY);
|
|
30
32
|
|
|
31
33
|
// Verbs should be empty/undefined (permissive)
|
|
32
34
|
iReckon(sir, config.allowedVerbs.length).willEqual(0);
|
|
33
35
|
});
|
|
34
36
|
|
|
35
37
|
await ifWe(sir, 'createRevocationPoolConfig defaults are correct', async () => {
|
|
36
|
-
const
|
|
38
|
+
const salt = "revoke_salt";
|
|
39
|
+
const config = createRevocationPoolConfig({
|
|
40
|
+
id: POOL_ID_REVOKE,
|
|
41
|
+
salt,
|
|
42
|
+
}) as KeystonePoolConfig_HashV1;
|
|
37
43
|
|
|
38
|
-
iReckon(sir, config.
|
|
44
|
+
iReckon(sir, config.id).willEqual(POOL_ID_REVOKE);
|
|
45
|
+
iReckon(sir, config.salt).willEqual(salt);
|
|
39
46
|
|
|
40
47
|
// Behavior check
|
|
41
48
|
const b = config.behavior;
|
|
42
|
-
iReckon(sir, b.size).willEqual(
|
|
43
|
-
iReckon(sir, b.replenish).willEqual(
|
|
49
|
+
iReckon(sir, b.size).willEqual(KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY); // Higher security
|
|
50
|
+
iReckon(sir, b.replenish).willEqual(KeystoneReplenishStrategy.deleteAll);
|
|
44
51
|
|
|
45
52
|
// Verbs should be restricted
|
|
46
53
|
iReckon(sir, config.allowedVerbs).includes(KEYSTONE_VERB_REVOKE);
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { HashAlgorithm } from "@ibgib/helper-gib/dist/helpers/utils-helper.mjs";
|
|
2
|
+
import { KeystoneReplenishStrategy } from "./keystone-types.mjs";
|
|
3
|
+
|
|
1
4
|
export const KEYSTONE_ATOM = "keystone";
|
|
2
5
|
|
|
3
6
|
// #region KeystoneVerb enum
|
|
@@ -25,9 +28,9 @@ export const KeystoneVerb = {
|
|
|
25
28
|
/**
|
|
26
29
|
* The meta-verb used to authorize structural changes to the Keystone,
|
|
27
30
|
* specifically adding or removing challenge pools.
|
|
28
|
-
*
|
|
31
|
+
*
|
|
29
32
|
* "Root access" to the identity.
|
|
30
|
-
*
|
|
33
|
+
*
|
|
31
34
|
* Basically, this is the verb for the "admin" pool.
|
|
32
35
|
*/
|
|
33
36
|
MANAGE: KEYSTONE_VERB_MANAGE,
|
|
@@ -44,3 +47,19 @@ export function isKeystoneVerb(value: string): value is KeystoneVerb {
|
|
|
44
47
|
export const POOL_ID_REVOKE = KEYSTONE_VERB_REVOKE;
|
|
45
48
|
export const POOL_ID_MANAGE = KEYSTONE_VERB_MANAGE;
|
|
46
49
|
export const POOL_ID_DEFAULT = "default";
|
|
50
|
+
|
|
51
|
+
export const KEYSTONE_CONFIG_DEFAULT_SIZE = 200;
|
|
52
|
+
export const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL = 2;
|
|
53
|
+
export const KEYSTONE_CONFIG_DEFAULT_RANDOM = 2;
|
|
54
|
+
export const KEYSTONE_CONFIG_DEFAULT_BINDING = 5;
|
|
55
|
+
export const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY = KeystoneReplenishStrategy.topUp;
|
|
56
|
+
export const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM = HashAlgorithm.sha_256;
|
|
57
|
+
export const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS = 1;
|
|
58
|
+
|
|
59
|
+
export const KEYSTONE_CONFIG_DEFAULT_SIZE_HIGHSECURITY = 2000;
|
|
60
|
+
export const KEYSTONE_CONFIG_DEFAULT_SEQUENTIAL_HIGHSECURITY = 5;
|
|
61
|
+
export const KEYSTONE_CONFIG_DEFAULT_RANDOM_HIGHSECURITY = 5;
|
|
62
|
+
export const KEYSTONE_CONFIG_DEFAULT_BINDING_HIGHSECURITY = 16;
|
|
63
|
+
export const KEYSTONE_CONFIG_DEFAULT_REPLENISH_STRATEGY_HIGHSECURITY = KeystoneReplenishStrategy.replaceAll;
|
|
64
|
+
export const KEYSTONE_CONFIG_DEFAULT_HASH_ALGORITHM_HIGHSECURITY = HashAlgorithm.sha_256;
|
|
65
|
+
export const KEYSTONE_CONFIG_DEFAULT_HASH_ROUNDS_HIGHSECURITY = 10;
|
|
@@ -8,10 +8,11 @@ import { getGib } from "@ibgib/ts-gib/dist/V1/transforms/transform-helper.mjs";
|
|
|
8
8
|
|
|
9
9
|
import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
|
|
10
10
|
import { KEYSTONE_ATOM } from "./keystone-constants.mjs";
|
|
11
|
-
import { KeystoneData_V1, KeystoneIbGib_V1,
|
|
11
|
+
import { KeystoneData_V1, KeystoneIbGib_V1, KeystoneIb_V1, KeystoneChallengePool, DeterministicResult, KeystoneProof, KeystonePoolConfig, KeystoneReplenishStrategy, KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES, KeystoneClaim, KeystoneSolution } from "./keystone-types.mjs";
|
|
12
12
|
import { MetaspaceService } from "../witness/space/metaspace/metaspace-types.mjs";
|
|
13
13
|
import { IbGibSpaceAny } from "../witness/space/space-base-v1.mjs";
|
|
14
14
|
import { KeystoneStrategyFactory } from "./strategy/keystone-strategy-factory.mjs";
|
|
15
|
+
import { GIB } from "@ibgib/ts-gib/dist/V1/constants.mjs";
|
|
15
16
|
|
|
16
17
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
17
18
|
|
|
@@ -19,7 +20,7 @@ const logalot = GLOBAL_LOG_A_LOT;
|
|
|
19
20
|
* space-delimited keystone ib containing select keystone metadata.
|
|
20
21
|
*
|
|
21
22
|
* NOTE: This must match {@link parseKeystoneIb}
|
|
22
|
-
* @see {@link
|
|
23
|
+
* @see {@link KeystoneIb_V1}
|
|
23
24
|
*/
|
|
24
25
|
export async function getKeystoneIb({
|
|
25
26
|
keystoneData,
|
|
@@ -47,13 +48,13 @@ export async function getKeystoneIb({
|
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* NOTE: This must match {@link getKeystoneIb}
|
|
50
|
-
* @see {@link
|
|
51
|
+
* @see {@link KeystoneIb_V1}
|
|
51
52
|
*/
|
|
52
53
|
export async function parseKeystoneIb({
|
|
53
54
|
ib,
|
|
54
55
|
}: {
|
|
55
56
|
ib: Ib,
|
|
56
|
-
}): Promise<
|
|
57
|
+
}): Promise<KeystoneIb_V1> {
|
|
57
58
|
const lc = `[${parseKeystoneIb.name}]`;
|
|
58
59
|
try {
|
|
59
60
|
if (logalot) { console.log(`${lc} starting... (I: 73cb6832984255ed48b2f44db6a21e25)`); }
|
|
@@ -123,7 +124,9 @@ export function getDeterministicRequirements({
|
|
|
123
124
|
const { gib } = getIbAndGib({ ibGibAddr: targetAddr });
|
|
124
125
|
if (gib) {
|
|
125
126
|
// Get required hex prefixes (e.g. 'a', 'b', 'c', '1')
|
|
126
|
-
const prefixes = gib
|
|
127
|
+
const prefixes = gib !== GIB ?
|
|
128
|
+
gib.substring(0, behavior.targetBindingChars).toLowerCase() :
|
|
129
|
+
'abc'; // arbitrary for primitive binding target ibgib
|
|
127
130
|
|
|
128
131
|
for (const char of prefixes) {
|
|
129
132
|
// Look in the Explicit Bucket
|
|
@@ -200,7 +203,7 @@ export function removeFromBindingMap(
|
|
|
200
203
|
|
|
201
204
|
/**
|
|
202
205
|
* Selects the specific pool to use for an operation based on ID, filter criteria, or verb authorization.
|
|
203
|
-
*
|
|
206
|
+
*
|
|
204
207
|
* @returns The matching KeystoneChallengePool
|
|
205
208
|
* @throws If no pool matches or if multiple pools match but one was expected.
|
|
206
209
|
*/
|
|
@@ -216,7 +219,7 @@ export function resolveTargetPool({
|
|
|
216
219
|
*/
|
|
217
220
|
poolId?: string;
|
|
218
221
|
/**
|
|
219
|
-
* Optional predicate to find a pool.
|
|
222
|
+
* Optional predicate to find a pool.
|
|
220
223
|
* Useful for finding delegates via metadata.
|
|
221
224
|
*/
|
|
222
225
|
poolFilter?: (pool: KeystoneChallengePool) => boolean;
|
|
@@ -276,7 +279,7 @@ export function resolveTargetPool({
|
|
|
276
279
|
/**
|
|
277
280
|
* Calculates the complete list of Challenge IDs to solve for a given operation.
|
|
278
281
|
* Combines Deterministic requirements (Mandatory/Binding/FIFO) with Stochastic requirements.
|
|
279
|
-
*
|
|
282
|
+
*
|
|
280
283
|
* @returns Array of unique challenge IDs.
|
|
281
284
|
*/
|
|
282
285
|
export function selectChallengeIds({
|
|
@@ -312,7 +315,7 @@ export function selectChallengeIds({
|
|
|
312
315
|
throw new Error(`Insufficient challenges for random requirement. Need ${randomCount}, have ${availableIds.length} (E: 9f7a67428515c1e82813158581898125)`);
|
|
313
316
|
}
|
|
314
317
|
// Shuffle & Pick
|
|
315
|
-
// Note: simple Math.random sort is sufficient for V1 stochastic selection
|
|
318
|
+
// Note: simple Math.random sort is sufficient for V1 stochastic selection
|
|
316
319
|
// as we are just picking from valid available options.
|
|
317
320
|
const shuffled = [...availableIds].sort(() => 0.5 - Math.random());
|
|
318
321
|
randomIds.push(...shuffled.slice(0, randomCount));
|
|
@@ -347,7 +350,7 @@ export async function generateOpaqueChallengeId({
|
|
|
347
350
|
/**
|
|
348
351
|
* Calculates the NEXT state of the Challenge Pools given a specific consumption event.
|
|
349
352
|
* Handles TopUp, ReplaceAll, Consume, and ScorchedEarth strategies.
|
|
350
|
-
*
|
|
353
|
+
*
|
|
351
354
|
* @returns The new array of KeystoneChallengePools (including the modified one).
|
|
352
355
|
*/
|
|
353
356
|
export async function applyReplenishmentStrategy({
|
|
@@ -420,7 +423,7 @@ export async function applyReplenishmentStrategy({
|
|
|
420
423
|
}
|
|
421
424
|
} else if (strategyType === KeystoneReplenishStrategy.consume) {
|
|
422
425
|
consumedIds.forEach(id => delete pool.challenges[id]);
|
|
423
|
-
} else if (strategyType === KeystoneReplenishStrategy.
|
|
426
|
+
} else if (strategyType === KeystoneReplenishStrategy.deleteAll) {
|
|
424
427
|
pool.challenges = {};
|
|
425
428
|
pool.bindingMap = {};
|
|
426
429
|
} else {
|
|
@@ -441,7 +444,7 @@ export async function applyReplenishmentStrategy({
|
|
|
441
444
|
* 3. Solves Challenges (Generates Solutions).
|
|
442
445
|
* 4. Replenishes Pool (Calculates the next state of ALL pools).
|
|
443
446
|
* 5. Constructs Proof.
|
|
444
|
-
*
|
|
447
|
+
*
|
|
445
448
|
* @returns The resulting Proof and the full list of Next Pools.
|
|
446
449
|
*/
|
|
447
450
|
export async function solveAndReplenish({
|
|
@@ -512,7 +515,7 @@ export async function solveAndReplenish({
|
|
|
512
515
|
/**
|
|
513
516
|
* Validates the transition from Prev -> Curr.
|
|
514
517
|
* Enforces Cryptography AND Behavioral Policy.
|
|
515
|
-
*
|
|
518
|
+
*
|
|
516
519
|
* @returns Array of validation error strings. Empty array means Valid.
|
|
517
520
|
*/
|
|
518
521
|
export async function validateKeystoneTransition({
|
|
@@ -525,7 +528,9 @@ export async function validateKeystoneTransition({
|
|
|
525
528
|
const lc = `[${validateKeystoneTransition.name}]`;
|
|
526
529
|
const errors: string[] = [];
|
|
527
530
|
try {
|
|
528
|
-
if (!currentIbGib) {
|
|
531
|
+
if (!currentIbGib) {
|
|
532
|
+
throw new Error(`(UNEXPECTED) currentIbGib falsy? (E: 3c0f02655fa8279e386a079ebb604b25)`);
|
|
533
|
+
}
|
|
529
534
|
if (!prevIbGib) { throw new Error(`(UNEXPECTED) prevIbGib falsy? (E: 0d07c812634d839c784f31b8848ba825)`); }
|
|
530
535
|
|
|
531
536
|
// intrinsic validation
|
|
@@ -20,7 +20,7 @@ const logalot = GLOBAL_LOG_A_LOT || true;
|
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
22
|
* Facade for managing Keystone Identities.
|
|
23
|
-
*
|
|
23
|
+
*
|
|
24
24
|
* Handles Genesis, Authorized Evolution (Signing), and Validation.
|
|
25
25
|
*/
|
|
26
26
|
export class KeystoneService_V1 {
|
|
@@ -93,9 +93,9 @@ export class KeystoneService_V1 {
|
|
|
93
93
|
|
|
94
94
|
/**
|
|
95
95
|
* Signs a claim by solving challenges from a specific pool and evolving the Keystone timeline.
|
|
96
|
-
*
|
|
96
|
+
*
|
|
97
97
|
* Uses a hybrid selection strategy: Mandatory IDs (Alice) + Sequential (FIFO) + Random (Stochastic).
|
|
98
|
-
*
|
|
98
|
+
*
|
|
99
99
|
* Supports Delegation via `poolFilter` to find specific foreign pools.
|
|
100
100
|
*/
|
|
101
101
|
async sign({
|
|
@@ -122,7 +122,7 @@ export class KeystoneService_V1 {
|
|
|
122
122
|
*/
|
|
123
123
|
poolId?: string;
|
|
124
124
|
/**
|
|
125
|
-
* Optional predicate to find a pool.
|
|
125
|
+
* Optional predicate to find a pool.
|
|
126
126
|
* Useful for finding delegates via metadata without knowing the exact ID.
|
|
127
127
|
* e.g. (p) => p.metadata?.delegate === 'Bob'
|
|
128
128
|
*/
|
|
@@ -158,7 +158,7 @@ export class KeystoneService_V1 {
|
|
|
158
158
|
});
|
|
159
159
|
|
|
160
160
|
// 3. Pay the Cost (Solve & Replenish)
|
|
161
|
-
// This helper handles the Strategy creation, Secret derivation, Solving,
|
|
161
|
+
// This helper handles the Strategy creation, Secret derivation, Solving,
|
|
162
162
|
// and the calculation of the Next state for ALL pools.
|
|
163
163
|
const { proof, nextPools } = await solveAndReplenish({
|
|
164
164
|
targetPoolId: pool.id,
|
|
@@ -196,13 +196,13 @@ export class KeystoneService_V1 {
|
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
198
|
* Validates a keystone.
|
|
199
|
-
*
|
|
199
|
+
*
|
|
200
200
|
* ## NOTES
|
|
201
|
-
*
|
|
201
|
+
*
|
|
202
202
|
* Atow (12/22/2025) this only validates the transition from Prev -> Curr.
|
|
203
|
-
*
|
|
203
|
+
*
|
|
204
204
|
* @returns Array of validation error strings. Empty array means Valid.
|
|
205
|
-
*
|
|
205
|
+
*
|
|
206
206
|
* @see {@link validateKeystoneTransition}
|
|
207
207
|
*/
|
|
208
208
|
async validate({
|
|
@@ -220,11 +220,11 @@ export class KeystoneService_V1 {
|
|
|
220
220
|
|
|
221
221
|
/**
|
|
222
222
|
* Permanently revokes the Identity.
|
|
223
|
-
*
|
|
223
|
+
*
|
|
224
224
|
* Logic:
|
|
225
225
|
* 1. Locates the 'revoke' pool.
|
|
226
226
|
* 2. Solves required challenges to prove ownership.
|
|
227
|
-
* 3. Wipes the pool (via
|
|
227
|
+
* 3. Wipes the pool (via the delete all strategy in solveAndReplenish).
|
|
228
228
|
* 4. Sets the revocationInfo on the new frame.
|
|
229
229
|
*/
|
|
230
230
|
async revoke({
|
|
@@ -270,8 +270,9 @@ export class KeystoneService_V1 {
|
|
|
270
270
|
if (idsToSolve.length === 0) { throw new Error(`Revocation policy selected 0 challenges? Check config for pool ${pool.id}. Revocation requires proof. (E: 97e5a8356d241ae7b882db791cb1f825)`); }
|
|
271
271
|
|
|
272
272
|
// 4. Pay the Cost & Scorched Earth
|
|
273
|
-
// The revoke pool config should have '
|
|
274
|
-
// causing solveAndReplenish
|
|
273
|
+
// The revoke pool config should have 'replenishStrategy:
|
|
274
|
+
// KeystoneReplenishStrategy.deleteAll', causing solveAndReplenish
|
|
275
|
+
// to return an empty pool in nextPools.
|
|
275
276
|
const { proof, nextPools } = await solveAndReplenish({
|
|
276
277
|
targetPoolId: pool.id,
|
|
277
278
|
prevPools: prevData.challengePools,
|
|
@@ -283,7 +284,7 @@ export class KeystoneService_V1 {
|
|
|
283
284
|
// warn if nextPools contains pool.id that isn't empty (we were
|
|
284
285
|
// supposed to do "scorched earth" which empties the pool)
|
|
285
286
|
if (nextPools.find(p => p.id === pool.id && Object.keys(p.challenges).length > 0)) {
|
|
286
|
-
console.warn(`${lc} revocation pool ${pool.id} is not empty after revocation. Is the revocation pool replenish strategy set to ${KeystoneReplenishStrategy.
|
|
287
|
+
console.warn(`${lc} revocation pool ${pool.id} is not empty after revocation. Is the revocation pool replenish strategy set to ${KeystoneReplenishStrategy.deleteAll}? (W: 300c28bc8b98fc3e3c0b0d988344f825)`);
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
// 5. Construct Revocation Info
|
|
@@ -316,11 +317,11 @@ export class KeystoneService_V1 {
|
|
|
316
317
|
|
|
317
318
|
/**
|
|
318
319
|
* Structural evolution: Adds new challenge pools to the keystone.
|
|
319
|
-
*
|
|
320
|
-
* Use Case: Adding a delegate (Server) for SSO, adding a recovery key,
|
|
320
|
+
*
|
|
321
|
+
* Use Case: Adding a delegate (Server) for SSO, adding a recovery key,
|
|
321
322
|
* or rotating to a new set of pools.
|
|
322
|
-
*
|
|
323
|
-
* Requires the Master Secret to authorize the change via a pool containing
|
|
323
|
+
*
|
|
324
|
+
* Requires the Master Secret to authorize the change via a pool containing
|
|
324
325
|
* the 'manage' verb.
|
|
325
326
|
*/
|
|
326
327
|
async addPools({
|
|
@@ -332,14 +333,14 @@ export class KeystoneService_V1 {
|
|
|
332
333
|
}: {
|
|
333
334
|
latestKeystone: KeystoneIbGib_V1;
|
|
334
335
|
/**
|
|
335
|
-
* Alice's Master Secret.
|
|
336
|
+
* Alice's Master Secret.
|
|
336
337
|
* Required to solve challenges from the Admin/Manage pool to authorize this change.
|
|
337
338
|
*/
|
|
338
339
|
masterSecret: string;
|
|
339
340
|
/**
|
|
340
|
-
* The pools to add.
|
|
341
|
-
* NOTE: These are fully constructed Pool objects.
|
|
342
|
-
* If they are foreign (Bob's), Alice must have constructed them
|
|
341
|
+
* The pools to add.
|
|
342
|
+
* NOTE: These are fully constructed Pool objects.
|
|
343
|
+
* If they are foreign (Bob's), Alice must have constructed them
|
|
343
344
|
* using Bob's challenges + Her config restrictions + isForeign=true.
|
|
344
345
|
*/
|
|
345
346
|
newPools: KeystoneChallengePool[];
|