@ibgib/core-gib 0.1.45 → 0.1.48
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/common/other/ibgib-helper.d.mts +12 -0
- package/dist/common/other/ibgib-helper.d.mts.map +1 -1
- package/dist/common/other/ibgib-helper.mjs +39 -0
- package/dist/common/other/ibgib-helper.mjs.map +1 -1
- package/dist/keystone/kdf/kdf-helpers.mjs +2 -2
- package/dist/keystone/kdf/kdf-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.d.mts +2 -1
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -1
- package/dist/keystone/keystone-config-builder.mjs +8 -2
- package/dist/keystone/keystone-config-builder.mjs.map +1 -1
- package/dist/keystone/keystone-constants.d.mts +33 -3
- package/dist/keystone/keystone-constants.d.mts.map +1 -1
- package/dist/keystone/keystone-constants.mjs +31 -1
- package/dist/keystone/keystone-constants.mjs.map +1 -1
- package/dist/keystone/keystone-helpers.d.mts +16 -1
- package/dist/keystone/keystone-helpers.d.mts.map +1 -1
- package/dist/keystone/keystone-helpers.mjs +227 -8
- package/dist/keystone/keystone-helpers.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.d.mts +4 -1
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -1
- package/dist/keystone/keystone-service-v1.mjs +6 -1
- package/dist/keystone/keystone-service-v1.mjs.map +1 -1
- package/dist/keystone/keystone-service-v1.respec.mjs +26 -26
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -1
- package/dist/keystone/keystone-types.d.mts +26 -5
- package/dist/keystone/keystone-types.d.mts.map +1 -1
- package/dist/keystone/keystone-types.mjs.map +1 -1
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs +1 -1
- package/dist/sync/sync-conflict-adv-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs +1 -1
- package/dist/sync/sync-conflict-basic-divergence.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs +1 -1
- package/dist/sync/sync-conflict-basic-multitimelines.respec.mjs.map +1 -1
- package/dist/sync/sync-conflict-text-merge.respec.mjs +1 -1
- package/dist/sync/sync-conflict-text-merge.respec.mjs.map +1 -1
- package/dist/sync/sync-constants.d.mts +47 -1
- package/dist/sync/sync-constants.d.mts.map +1 -1
- package/dist/sync/sync-constants.mjs +49 -1
- package/dist/sync/sync-constants.mjs.map +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs +1 -1
- package/dist/sync/sync-innerspace-constants.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs +1 -1
- package/dist/sync/sync-innerspace-deep-updates.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs +33 -19
- package/dist/sync/sync-innerspace-dest-ahead-withid.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs +1 -1
- package/dist/sync/sync-innerspace-dest-ahead.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs +1 -1
- package/dist/sync/sync-innerspace-multiple-timelines.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs +1 -1
- package/dist/sync/sync-innerspace-partial-update.respec.mjs.map +1 -1
- package/dist/sync/sync-innerspace.respec.mjs +1 -1
- package/dist/sync/sync-innerspace.respec.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs +5 -0
- package/dist/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mjs.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts +6 -1
- package/dist/sync/sync-peer/sync-peer-v1.d.mts.map +1 -1
- package/dist/sync/sync-peer/sync-peer-v1.mjs +56 -14
- package/dist/sync/sync-peer/sync-peer-v1.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts +7 -3
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.d.mts.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs +32 -3
- package/dist/sync/sync-saga-context/sync-saga-context-helpers.mjs.map +1 -1
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts +16 -0
- package/dist/sync/sync-saga-context/sync-saga-context-types.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.d.mts +18 -3
- package/dist/sync/sync-saga-coordinator.d.mts.map +1 -1
- package/dist/sync/sync-saga-coordinator.mjs +243 -56
- package/dist/sync/sync-saga-coordinator.mjs.map +1 -1
- package/dist/sync/sync-types.d.mts +1 -1
- package/dist/sync/sync-types.d.mts.map +1 -1
- package/package.json +1 -1
- package/src/common/other/ibgib-helper.mts +39 -0
- package/src/keystone/kdf/kdf-helpers.mts +2 -2
- package/src/keystone/keystone-config-builder.mts +13 -2
- package/src/keystone/keystone-constants.mts +33 -2
- package/src/keystone/keystone-helpers.mts +237 -8
- package/src/keystone/keystone-service-v1.mts +5 -0
- package/src/keystone/keystone-service-v1.respec.mts +25 -25
- package/src/keystone/keystone-types.mts +31 -8
- package/src/sync/sync-conflict-adv-multitimelines.respec.mts +1 -1
- package/src/sync/sync-conflict-basic-divergence.respec.mts +1 -1
- package/src/sync/sync-conflict-basic-multitimelines.respec.mts +1 -1
- package/src/sync/sync-conflict-text-merge.respec.mts +1 -1
- package/src/sync/sync-constants.mts +51 -1
- package/src/sync/sync-innerspace-constants.respec.mts +1 -1
- package/src/sync/sync-innerspace-deep-updates.respec.mts +1 -1
- package/src/sync/sync-innerspace-dest-ahead-withid.respec.mts +36 -19
- package/src/sync/sync-innerspace-dest-ahead.respec.mts +1 -1
- package/src/sync/sync-innerspace-multiple-timelines.respec.mts +1 -1
- package/src/sync/sync-innerspace-partial-update.respec.mts +1 -1
- package/src/sync/sync-innerspace.respec.mts +1 -1
- package/src/sync/sync-peer/sync-peer-innerspace/sync-peer-innerspace-v1.mts +5 -0
- package/src/sync/sync-peer/sync-peer-v1.mts +63 -15
- package/src/sync/sync-saga-context/sync-saga-context-helpers.mts +52 -4
- package/src/sync/sync-saga-context/sync-saga-context-types.mts +17 -0
- package/src/sync/sync-saga-coordinator.mts +298 -63
- package/src/sync/sync-types.mts +1 -1
|
@@ -5,9 +5,10 @@ import { getIbGibAddr } from "@ibgib/ts-gib/dist/helper.mjs";
|
|
|
5
5
|
import { Factory_V1 } from "@ibgib/ts-gib/dist/V1/factory.mjs";
|
|
6
6
|
import { GLOBAL_LOG_A_LOT } from "../core-constants.mjs";
|
|
7
7
|
import { putInSpace, getLatestAddrs, getFromSpace, registerNewIbGib } from "../witness/space/space-helper.mjs";
|
|
8
|
+
import { KeystoneChallengeType } from "../keystone/keystone-types.mjs";
|
|
8
9
|
import { deriveKey } from "../keystone/kdf/kdf-helpers.mjs";
|
|
9
10
|
import { KdfStrategy } from "../keystone/kdf/kdf-constants.mjs";
|
|
10
|
-
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN, SyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES,
|
|
11
|
+
import { SyncStage, SYNC_ATOM, SYNC_MSG_REL8N_NAME, SYNC_SAGA_PAYLOAD_ADDRS_DOMAIN, SyncConflictStrategy, SYNC_CONFLICT_STRATEGY_VALID_VALUES, SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO, SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS, SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM, SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY, SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL, SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING, SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID, SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_TRANSITIONPOOL, SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_DELEGATE, SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID, SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID, } from "./sync-constants.mjs";
|
|
11
12
|
import { appendToTimeline, createTimeline, getHistory, getHistoryAddrs } from "../timeline/timeline-api.mjs";
|
|
12
13
|
import { SyncMode, } from "./sync-types.mjs";
|
|
13
14
|
import { getSyncSagaFrameOrigin, getFullSyncSagaHistory, getSyncIb, getTempSpaceName, isPastFrame, putInSpace_dnasThenNonDnas, validateFullSyncSagaHistory, getAllOrphanedAddresses, getFinalConflictsInfo } from "./sync-helpers.mjs";
|
|
@@ -22,9 +23,11 @@ import { fnObs } from "../common/pubsub/observer/observer-helper.mjs";
|
|
|
22
23
|
import { graftTimelines, } from "./graft-info/graft-info-helpers.mjs";
|
|
23
24
|
import { GRAFT_INFO_REL8N_NAME } from "./graft-info/graft-info-constants.mjs";
|
|
24
25
|
import { validateIbGibIntrinsically } from "@ibgib/ts-gib/dist/V1/validate-helper.mjs";
|
|
25
|
-
import { KEYSTONE_VERB_MANAGE } from "../keystone/keystone-constants.mjs";
|
|
26
|
-
import { validateKeystoneGraph } from "../keystone/keystone-helpers.mjs";
|
|
26
|
+
import { KEYSTONE_VERB_MANAGE, KEYSTONE_VERB_SIGN } from "../keystone/keystone-constants.mjs";
|
|
27
|
+
import { addToBindingMap, generateOpaqueChallengeId, validateGenesisKeystone, validateKeystoneGraph } from "../keystone/keystone-helpers.mjs";
|
|
27
28
|
import { SYNC_SAGA_CONTEXT_ATOM } from "./sync-saga-context/sync-saga-context-constants.mjs";
|
|
29
|
+
import { createStandardPoolConfig } from "../keystone/keystone-config-builder.mjs";
|
|
30
|
+
import { KeystoneStrategyFactory } from "../keystone/strategy/keystone-strategy-factory.mjs";
|
|
28
31
|
const logalot = GLOBAL_LOG_A_LOT;
|
|
29
32
|
const logalotControlDomain = false;
|
|
30
33
|
const lcControlDomain = '[ControlDomain]';
|
|
@@ -107,7 +110,20 @@ export class SyncSagaCoordinator {
|
|
|
107
110
|
// creates the initial session identity (keystone). the flow
|
|
108
111
|
// (i think) will go: evolve saga frame, then sign keystone,
|
|
109
112
|
// then create/send context.
|
|
110
|
-
|
|
113
|
+
const resCreateSessionIdentity = await this.createSessionIdentity({
|
|
114
|
+
sagaId,
|
|
115
|
+
primaryIdentity: identity,
|
|
116
|
+
nonSessionSecret: identitySecret,
|
|
117
|
+
metaspace,
|
|
118
|
+
localSpace
|
|
119
|
+
});
|
|
120
|
+
sessionIdentity = resCreateSessionIdentity.sessionIdentity;
|
|
121
|
+
if (identity) {
|
|
122
|
+
if (!resCreateSessionIdentity.newPrimaryIdentity) {
|
|
123
|
+
throw new Error(`(UNEXPECTED) identity truthy but resCreateSessionIdentity.newPrimaryIdentity falsy? (E: 4f82e88a3cc5bd7e58a40f8d77bda826)`);
|
|
124
|
+
}
|
|
125
|
+
identity = resCreateSessionIdentity.newPrimaryIdentity;
|
|
126
|
+
}
|
|
111
127
|
}
|
|
112
128
|
// if (logalot) { console.log(`${lc} sessionIdentity: ${sessionIdentity ? pretty(sessionIdentity) : 'undefined'} (I: abc01872800b3a66b819a05898bba826)`); }
|
|
113
129
|
// CREATE INITIAL FRAME (Stage.init)
|
|
@@ -220,15 +236,20 @@ export class SyncSagaCoordinator {
|
|
|
220
236
|
}
|
|
221
237
|
}
|
|
222
238
|
}
|
|
223
|
-
|
|
224
|
-
|
|
239
|
+
/**
|
|
240
|
+
* helper that KDFs the given identitySecret, using {@link sagaId} to do so.
|
|
241
|
+
*
|
|
242
|
+
* @returns deterministically derived session secret
|
|
243
|
+
*/
|
|
244
|
+
async deriveSessionSecret({ sagaId, nonSessionSecret, }) {
|
|
245
|
+
const lc = `${this.lc}[${this.deriveSessionSecret.name}]`;
|
|
225
246
|
try {
|
|
226
247
|
if (logalot) {
|
|
227
248
|
console.log(`${lc} starting... (I: 0de03f8dcd3e32f1fca244e8f2a8a826)`);
|
|
228
249
|
}
|
|
229
250
|
// Derive session-specific secret using KDF
|
|
230
251
|
const sessionSecret = await deriveKey({
|
|
231
|
-
masterSecret:
|
|
252
|
+
masterSecret: nonSessionSecret,
|
|
232
253
|
kdfOpts: {
|
|
233
254
|
strategy: KdfStrategy.recursive_salt_wrap,
|
|
234
255
|
salt: sagaId,
|
|
@@ -248,15 +269,15 @@ export class SyncSagaCoordinator {
|
|
|
248
269
|
}
|
|
249
270
|
}
|
|
250
271
|
}
|
|
251
|
-
async
|
|
252
|
-
const lc = `${this.lc}[${this.
|
|
272
|
+
async getInitialWeakTransitionSessionSecret({ sagaId, }) {
|
|
273
|
+
const lc = `${this.lc}[${this.getInitialWeakTransitionSessionSecret.name}]`;
|
|
253
274
|
try {
|
|
254
275
|
if (logalot) {
|
|
255
276
|
console.log(`${lc} starting... (I: 872ab81a78827b9f2822b78459203226)`);
|
|
256
277
|
}
|
|
257
278
|
// Create delegate pool bootstrap secret (publicly derivable)
|
|
258
|
-
const
|
|
259
|
-
masterSecret:
|
|
279
|
+
const initialTransitionSecret = await deriveKey({
|
|
280
|
+
masterSecret: SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL, // Weak, publicly derivable secret
|
|
260
281
|
kdfOpts: {
|
|
261
282
|
strategy: KdfStrategy.recursive_salt_wrap,
|
|
262
283
|
salt: sagaId,
|
|
@@ -264,7 +285,128 @@ export class SyncSagaCoordinator {
|
|
|
264
285
|
algorithm: 'SHA-256'
|
|
265
286
|
}
|
|
266
287
|
});
|
|
267
|
-
return
|
|
288
|
+
return initialTransitionSecret;
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
294
|
+
finally {
|
|
295
|
+
if (logalot) {
|
|
296
|
+
console.log(`${lc} complete.`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async getTransitionKeystonePool({ sagaId, }) {
|
|
301
|
+
const lc = `${this.lc}[${this.getTransitionKeystonePool.name}]`;
|
|
302
|
+
try {
|
|
303
|
+
if (logalot) {
|
|
304
|
+
console.log(`${lc} starting... (I: 1ec1c8db7438938b08b96559fcee0826)`);
|
|
305
|
+
}
|
|
306
|
+
const config = createStandardPoolConfig({
|
|
307
|
+
salt: sagaId,
|
|
308
|
+
id: SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID,
|
|
309
|
+
type: KeystoneChallengeType.hash_reveal_v1,
|
|
310
|
+
size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE_TRANSITIONPOOL,
|
|
311
|
+
replenishStrategy: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY_TRANSITIONPOOL,
|
|
312
|
+
random: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM_TRANSITIONPOOL,
|
|
313
|
+
sequential: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL_TRANSITIONPOOL,
|
|
314
|
+
targetBinding: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING_TRANSITIONPOOL,
|
|
315
|
+
hashAlgorithm: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO_TRANSITIONPOOL,
|
|
316
|
+
hashRounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS_TRANSITIONPOOL,
|
|
317
|
+
verbs: SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_TRANSITIONPOOL,
|
|
318
|
+
});
|
|
319
|
+
const strategy = KeystoneStrategyFactory.create({ config });
|
|
320
|
+
const poolSecret = await strategy.derivePoolSecret({
|
|
321
|
+
masterSecret: await this.getInitialWeakTransitionSessionSecret({ sagaId }),
|
|
322
|
+
});
|
|
323
|
+
const challenges = {};
|
|
324
|
+
const bindingMap = {};
|
|
325
|
+
const targetSize = config.behavior.size;
|
|
326
|
+
const timestamp = Date.now().toString();
|
|
327
|
+
for (let i = 0; i < targetSize; i++) {
|
|
328
|
+
const challengeId = await generateOpaqueChallengeId({
|
|
329
|
+
salt: config.salt, timestamp, index: i
|
|
330
|
+
});
|
|
331
|
+
const solution = await strategy.generateSolution({
|
|
332
|
+
poolSecret, poolId: config.salt, challengeId,
|
|
333
|
+
});
|
|
334
|
+
const challenge = await strategy.generateChallenge({ solution });
|
|
335
|
+
challenges[challengeId] = challenge;
|
|
336
|
+
// Populate Binding Map
|
|
337
|
+
addToBindingMap(bindingMap, challengeId);
|
|
338
|
+
}
|
|
339
|
+
const transitionPool = {
|
|
340
|
+
id: SESSION_IDENTITY_KEYSTONE_TRANSITION_POOL_ID,
|
|
341
|
+
config,
|
|
342
|
+
challenges,
|
|
343
|
+
bindingMap,
|
|
344
|
+
isForeign: true,
|
|
345
|
+
// metadata: { origin: 'receiver', role: 'delegate' } // don't need metadata since we have the pool id being 'delegate' (i think)
|
|
346
|
+
};
|
|
347
|
+
return transitionPool;
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
351
|
+
throw error;
|
|
352
|
+
}
|
|
353
|
+
finally {
|
|
354
|
+
if (logalot) {
|
|
355
|
+
console.log(`${lc} complete.`);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
async getDelegateKeystonePool({ sagaId, }) {
|
|
360
|
+
const lc = `${this.lc}[${this.getDelegateKeystonePool.name}]`;
|
|
361
|
+
try {
|
|
362
|
+
if (logalot) {
|
|
363
|
+
console.log(`${lc} starting... (I: 6b1d338f8e988e68f8d77e72ed00d526)`);
|
|
364
|
+
}
|
|
365
|
+
// todo: change this to a helper function that does the delegated
|
|
366
|
+
// functionality better. also the f***ing binding map needs better
|
|
367
|
+
// implementation. f***ng glazed over by AI.
|
|
368
|
+
const config = createStandardPoolConfig({
|
|
369
|
+
salt: sagaId,
|
|
370
|
+
id: SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID,
|
|
371
|
+
type: KeystoneChallengeType.hash_reveal_v1,
|
|
372
|
+
size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE,
|
|
373
|
+
replenishStrategy: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,
|
|
374
|
+
random: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,
|
|
375
|
+
sequential: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,
|
|
376
|
+
targetBinding: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,
|
|
377
|
+
hashAlgorithm: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,
|
|
378
|
+
hashRounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,
|
|
379
|
+
verbs: SESSION_IDENTITY_KEYSTONE_CONFIG_VERBS_DELEGATE,
|
|
380
|
+
});
|
|
381
|
+
const strategy = KeystoneStrategyFactory.create({ config });
|
|
382
|
+
const poolSecret = await strategy.derivePoolSecret({
|
|
383
|
+
masterSecret: SESSION_IDENTITY_KEYSTONE_SECRET_TRANSITIONPOOL
|
|
384
|
+
});
|
|
385
|
+
const challenges = {};
|
|
386
|
+
const bindingMap = {};
|
|
387
|
+
const targetSize = config.behavior.size;
|
|
388
|
+
const timestamp = Date.now().toString();
|
|
389
|
+
for (let i = 0; i < targetSize; i++) {
|
|
390
|
+
const challengeId = await generateOpaqueChallengeId({
|
|
391
|
+
salt: config.salt, timestamp, index: i
|
|
392
|
+
});
|
|
393
|
+
const solution = await strategy.generateSolution({
|
|
394
|
+
poolSecret, poolId: config.salt, challengeId,
|
|
395
|
+
});
|
|
396
|
+
const challenge = await strategy.generateChallenge({ solution });
|
|
397
|
+
challenges[challengeId] = challenge;
|
|
398
|
+
// Populate Binding Map
|
|
399
|
+
addToBindingMap(bindingMap, challengeId);
|
|
400
|
+
}
|
|
401
|
+
const delegatePool = {
|
|
402
|
+
id: SESSION_IDENTITY_KEYSTONE_DELEGATE_POOL_ID,
|
|
403
|
+
config,
|
|
404
|
+
challenges,
|
|
405
|
+
bindingMap,
|
|
406
|
+
isForeign: true,
|
|
407
|
+
// metadata: { origin: 'receiver', role: 'delegate' } // don't need metadata since we have the pool id being 'delegate' (i think)
|
|
408
|
+
};
|
|
409
|
+
return delegatePool;
|
|
268
410
|
}
|
|
269
411
|
catch (error) {
|
|
270
412
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
@@ -276,60 +418,102 @@ export class SyncSagaCoordinator {
|
|
|
276
418
|
}
|
|
277
419
|
}
|
|
278
420
|
}
|
|
279
|
-
|
|
280
|
-
|
|
421
|
+
/**
|
|
422
|
+
* creates a session identity keystone based off of the given args.
|
|
423
|
+
*
|
|
424
|
+
* Then, if the {@link primaryIdentity} keystone is provided, this also
|
|
425
|
+
* **signs** this keystone pointing to the address of the sess
|
|
426
|
+
* @param param0
|
|
427
|
+
* @returns
|
|
428
|
+
*/
|
|
429
|
+
async createSessionIdentity({ sagaId, primaryIdentity, nonSessionSecret, metaspace, localSpace, }) {
|
|
430
|
+
const lc = `${this.lc}[${this.createSessionIdentity.name}]`;
|
|
281
431
|
try {
|
|
282
432
|
if (logalot) {
|
|
283
433
|
console.log(`${lc} starting... (I: 428392a4ee636b7bd8f7d5d89a87e826)`);
|
|
284
434
|
}
|
|
285
|
-
if (!
|
|
286
|
-
throw new Error(`(UNEXPECTED)
|
|
435
|
+
if (!nonSessionSecret) {
|
|
436
|
+
throw new Error(`(UNEXPECTED) nonSessionSecret falsy? This is expected to be truthy by this point. (E: 8ce053fe59825a6678713128953b9d26)`);
|
|
287
437
|
}
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
438
|
+
const primarySessionSecret = await this.deriveSessionSecret({
|
|
439
|
+
sagaId, nonSessionSecret
|
|
440
|
+
});
|
|
441
|
+
// Generate keystone with two initial pools in two steps.
|
|
442
|
+
// 1. Create primary pool with genesis method to correspond to the
|
|
443
|
+
// sender/sender's secret/identity.
|
|
444
|
+
// 2. Create a separate pool and add separately because a
|
|
445
|
+
// different pw + config is used for the transition pool.
|
|
291
446
|
const primaryPoolConfig = {
|
|
292
447
|
allowedVerbs: [KEYSTONE_VERB_MANAGE],
|
|
293
|
-
id:
|
|
294
|
-
type: 'hash-reveal-v1',
|
|
448
|
+
id: SESSION_IDENTITY_KEYSTONE_PRIMARY_POOL_ID,
|
|
295
449
|
salt: sagaId,
|
|
296
450
|
behavior: {
|
|
297
|
-
size:
|
|
298
|
-
replenish:
|
|
299
|
-
selectSequentially:
|
|
300
|
-
selectRandomly:
|
|
301
|
-
targetBindingChars:
|
|
451
|
+
size: SESSION_IDENTITY_KEYSTONE_CONFIG_SIZE, // Large pool for many signatures
|
|
452
|
+
replenish: SESSION_IDENTITY_KEYSTONE_CONFIG_REPLENISH_STRATEGY,
|
|
453
|
+
selectSequentially: SESSION_IDENTITY_KEYSTONE_CONFIG_SEQUENTIAL,
|
|
454
|
+
selectRandomly: SESSION_IDENTITY_KEYSTONE_CONFIG_RANDOM,
|
|
455
|
+
targetBindingChars: SESSION_IDENTITY_KEYSTONE_CONFIG_TARGET_BINDING,
|
|
302
456
|
},
|
|
303
|
-
|
|
304
|
-
|
|
457
|
+
type: KeystoneChallengeType.hash_reveal_v1,
|
|
458
|
+
algo: SESSION_IDENTITY_KEYSTONE_CONFIG_ALGO,
|
|
459
|
+
rounds: SESSION_IDENTITY_KEYSTONE_CONFIG_ROUNDS,
|
|
305
460
|
};
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
type: 'hash-reveal-v1',
|
|
309
|
-
salt: sagaId,
|
|
310
|
-
behavior: {
|
|
311
|
-
size: 10, // Small pool - only for initial handshake
|
|
312
|
-
replenish: 'top-up',
|
|
313
|
-
selectSequentially: 1,
|
|
314
|
-
selectRandomly: 1,
|
|
315
|
-
targetBindingChars: 0
|
|
316
|
-
},
|
|
317
|
-
algo: 'SHA-256',
|
|
318
|
-
rounds: 1
|
|
319
|
-
};
|
|
320
|
-
// Generate keystone with DUAL pools. We have to first genesis with
|
|
321
|
-
// one and then add the other, because we have two distinct
|
|
322
|
-
// secrets.
|
|
323
|
-
const sessionIdentity = await this.keystoneSvc.genesis({
|
|
324
|
-
masterSecret: sessionSecret,
|
|
461
|
+
const sessionIdentity_genesis = await this.keystoneSvc.genesis({
|
|
462
|
+
masterSecret: primarySessionSecret,
|
|
325
463
|
configs: [primaryPoolConfig],
|
|
326
464
|
metaspace,
|
|
327
|
-
space: localSpace
|
|
465
|
+
space: localSpace,
|
|
328
466
|
});
|
|
329
|
-
//
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
467
|
+
// #region sanity validation of genesis keystone
|
|
468
|
+
/**
|
|
469
|
+
* not necessary but since it's a new design, I'm putting in this
|
|
470
|
+
* immediate validation just to put it through its paces. (worth the
|
|
471
|
+
* slight perf hit).
|
|
472
|
+
*/
|
|
473
|
+
const validationErrors = await validateGenesisKeystone({
|
|
474
|
+
keystoneIbGib: sessionIdentity_genesis
|
|
475
|
+
});
|
|
476
|
+
if (validationErrors) {
|
|
477
|
+
throw new Error(`(UNEXPECTED) the sessionIdentity_genesis that we just created already has validation errors just after creation? (E: e9ca08cf0f8858bb1ace8b9fa89f8726)`);
|
|
478
|
+
}
|
|
479
|
+
// #endregion sanity validation of genesis keystone
|
|
480
|
+
const transitionPool = await this.getTransitionKeystonePool({ sagaId });
|
|
481
|
+
/**
|
|
482
|
+
* Note this actually **signs** the initial {@link sessionIdentity_genesis}
|
|
483
|
+
* and requires the use of a pool with management priveleges.
|
|
484
|
+
*/
|
|
485
|
+
const sessionIdentity_withTransitionPool = await this.keystoneSvc.addPools({
|
|
486
|
+
latestKeystone: sessionIdentity_genesis,
|
|
487
|
+
/**
|
|
488
|
+
* this secret does not do the delegate pool challenges,
|
|
489
|
+
* rather, this is the sessionSecret itself to evolve the
|
|
490
|
+
* keystone **to add** the delegate pool in the first place.
|
|
491
|
+
*/
|
|
492
|
+
masterSecret: primarySessionSecret,
|
|
493
|
+
metaspace,
|
|
494
|
+
space: localSpace,
|
|
495
|
+
newPools: [transitionPool],
|
|
496
|
+
});
|
|
497
|
+
let newPrimaryIdentity = undefined;
|
|
498
|
+
if (primaryIdentity) {
|
|
499
|
+
newPrimaryIdentity = await this.keystoneSvc.sign({
|
|
500
|
+
latestKeystone: primaryIdentity,
|
|
501
|
+
poolId: primaryPoolConfig.id,
|
|
502
|
+
claim: {
|
|
503
|
+
verb: KEYSTONE_VERB_SIGN,
|
|
504
|
+
target: getIbGibAddr({ ibGib: sessionIdentity_withTransitionPool }),
|
|
505
|
+
},
|
|
506
|
+
masterSecret: nonSessionSecret,
|
|
507
|
+
metaspace,
|
|
508
|
+
space: localSpace,
|
|
509
|
+
// frameDetails: undefined, // anything to put here?
|
|
510
|
+
// requiredChallengeIds: undefined, // not relevant I think
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
sessionIdentity: sessionIdentity_withTransitionPool,
|
|
515
|
+
newPrimaryIdentity,
|
|
516
|
+
};
|
|
333
517
|
}
|
|
334
518
|
catch (error) {
|
|
335
519
|
console.error(`${lc} ${extractErrorMsg(error)}`);
|
|
@@ -589,7 +773,9 @@ export class SyncSagaCoordinator {
|
|
|
589
773
|
if (sessionKeystone) {
|
|
590
774
|
const keystoneErrors = await validateKeystoneGraph({
|
|
591
775
|
keystoneIbGib: sessionKeystone,
|
|
592
|
-
space: localSpace
|
|
776
|
+
space: localSpace,
|
|
777
|
+
getLatest: true,
|
|
778
|
+
invalidIfMoreRecentKeystoneFoundInSpace: true,
|
|
593
779
|
});
|
|
594
780
|
if (keystoneErrors.length > 0) {
|
|
595
781
|
throw new Error(`invalid sessionKeystone. errors: ${keystoneErrors} (E: 3881b8caf2d803767a331e1141e84826)`);
|
|
@@ -632,6 +818,7 @@ export class SyncSagaCoordinator {
|
|
|
632
818
|
masterSecret: sessionSecret,
|
|
633
819
|
metaspace,
|
|
634
820
|
});
|
|
821
|
+
contextIbGib.fnIdentitySecret = () => Promise.resolve(sessionSecret);
|
|
635
822
|
}
|
|
636
823
|
return contextIbGib;
|
|
637
824
|
}
|
|
@@ -1366,10 +1553,10 @@ export class SyncSagaCoordinator {
|
|
|
1366
1553
|
throw new Error(`${lc} Invalid ack frame: ackData.stage !== SyncStage.ack (E: 2e8b0a94b5954a66a6a1a7a0b3f5b7a1)`);
|
|
1367
1554
|
}
|
|
1368
1555
|
if (logalot) {
|
|
1369
|
-
console.log(`${lc} ackData: ${pretty(ackData)} (I:
|
|
1556
|
+
console.log(`${lc} ackData: ${pretty(ackData)} (I: b817c5571c5e916fe8f90b892b3e8e26)`);
|
|
1370
1557
|
}
|
|
1371
1558
|
if (!sagaIbGib.data) {
|
|
1372
|
-
throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E:
|
|
1559
|
+
throw new Error(`(UNEXPECTED) sagaIbGib.data falsy? (E: e3f2e8f162484859787651b85c011826)`);
|
|
1373
1560
|
}
|
|
1374
1561
|
// #region sanity/validation
|
|
1375
1562
|
// 1. Check for Conflicts
|
|
@@ -2490,7 +2677,7 @@ export class SyncSagaCoordinator {
|
|
|
2490
2677
|
}
|
|
2491
2678
|
// Attach session keystone to saga frame via hard rel8n
|
|
2492
2679
|
if (sessionIdentity) {
|
|
2493
|
-
rel8ns.
|
|
2680
|
+
rel8ns.sessionKeystone = [getIbGibAddr({ ibGib: sessionIdentity })];
|
|
2494
2681
|
}
|
|
2495
2682
|
const resNew = await createTimeline({
|
|
2496
2683
|
space: localSpace,
|