@ibgib/core-gib 0.1.4 → 0.1.8
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 +26 -0
- package/dist/assumptions.respec.mjs.map +1 -1
- package/dist/common/alias/alias-helper.mjs +1 -1
- package/dist/common/alias/alias-helper.mjs.map +1 -1
- package/dist/common/comment/comment-helper.mjs.map +1 -1
- package/dist/common/display/display-helper.mjs.map +1 -1
- package/dist/common/display/display-types.d.mts +1 -1
- package/dist/common/display/display-types.d.mts.map +1 -1
- package/dist/common/encrypt/encrypt-helper.mjs.map +1 -1
- package/dist/common/encrypt/encrypt-types.d.mts +1 -1
- package/dist/common/encrypt/encrypt-types.d.mts.map +1 -1
- package/dist/common/error/error-helper.mjs.map +1 -1
- package/dist/common/form/form-helper.mjs.map +1 -1
- package/dist/common/form/form-items.d.mts.map +1 -1
- package/dist/common/import-export/import-export-helper.web.mjs.map +1 -1
- package/dist/common/link/link-helper.mjs.map +1 -1
- package/dist/common/meta-stone/meta-stone-helper.mjs.map +1 -1
- package/dist/common/meta-stone/meta-stone.respec.mjs.map +1 -1
- package/dist/common/other/graph-helper.mjs +3 -3
- package/dist/common/other/graph-helper.mjs.map +1 -1
- package/dist/common/other/ibgib-helper.mjs.map +1 -1
- package/dist/common/other/ibgib-helper.respec.mjs.map +1 -1
- package/dist/common/other/other-constants.mjs +4 -4
- package/dist/common/other/other-constants.mjs.map +1 -1
- package/dist/common/other/other-helper.web.mjs.map +1 -1
- package/dist/common/other/other-types.d.mts +10 -10
- package/dist/common/other/other-types.d.mts.map +1 -1
- package/dist/common/other/svg-helper.mjs.map +1 -1
- package/dist/common/pic/pic-helper.mjs.map +1 -1
- package/dist/common/pubsub/observable/observable-base-v1.mjs +1 -1
- package/dist/common/pubsub/observable/observable-base-v1.mjs.map +1 -1
- package/dist/common/pubsub/observable/observable-event/observable-event-helper.mjs.map +1 -1
- package/dist/common/pubsub/observable/observable-helper.mjs.map +1 -1
- package/dist/common/pubsub/observable/observable-types.d.mts +1 -1
- package/dist/common/pubsub/observable/observable-types.d.mts.map +1 -1
- package/dist/common/pubsub/observer/observer-helper.mjs.map +1 -1
- package/dist/common/pubsub/observer/observer-types.d.mts.map +1 -1
- package/dist/common/pubsub/subject/subject-helper.mjs.map +1 -1
- package/dist/common/pubsub/subject/subject-types.d.mts +1 -1
- package/dist/common/pubsub/subject/subject-types.d.mts.map +1 -1
- package/dist/common/pubsub/subject/subject-v1.mjs.map +1 -1
- package/dist/common/pubsub/subject/subject.respec.mjs.map +1 -1
- package/dist/common/pubsub/subscription/subscription-helper.mjs.map +1 -1
- package/dist/common/pubsub/subscription/subscription-types.d.mts.map +1 -1
- package/dist/common/pubsub/subscription/subscription-v1.mjs.map +1 -1
- package/dist/common/secret/secret-helper.mjs.map +1 -1
- package/dist/common/secret/secret-types.d.mts +1 -1
- package/dist/common/secret/secret-types.d.mts.map +1 -1
- package/dist/common/secret/secret.respec.mjs +1 -1
- package/dist/common/secret/secret.respec.mjs.map +1 -1
- package/dist/common/tag/tag-helper.mjs.map +1 -1
- package/dist/core-helper.respec.mjs.map +1 -1
- package/dist/keystone/keystone-config-builder.d.mts +77 -0
- package/dist/keystone/keystone-config-builder.d.mts.map +1 -0
- package/dist/keystone/keystone-config-builder.mjs +157 -0
- package/dist/keystone/keystone-config-builder.mjs.map +1 -0
- package/dist/keystone/keystone-constants.d.mts +36 -0
- package/dist/keystone/keystone-constants.d.mts.map +1 -0
- package/dist/keystone/keystone-constants.mjs +39 -0
- package/dist/keystone/keystone-constants.mjs.map +1 -0
- package/dist/keystone/keystone-helpers.d.mts +117 -0
- package/dist/keystone/keystone-helpers.d.mts.map +1 -0
- package/dist/keystone/keystone-helpers.mjs +455 -0
- package/dist/keystone/keystone-helpers.mjs.map +1 -0
- package/dist/keystone/keystone-service-v1.d.mts +77 -0
- package/dist/keystone/keystone-service-v1.d.mts.map +1 -0
- package/dist/keystone/keystone-service-v1.mjs +502 -0
- package/dist/keystone/keystone-service-v1.mjs.map +1 -0
- package/dist/keystone/keystone-service-v1.respec.d.mts +2 -0
- package/dist/keystone/keystone-service-v1.respec.d.mts.map +1 -0
- package/dist/keystone/keystone-service-v1.respec.mjs +460 -0
- package/dist/keystone/keystone-service-v1.respec.mjs.map +1 -0
- package/dist/keystone/keystone-types.d.mts +248 -0
- package/dist/keystone/keystone-types.d.mts.map +1 -0
- package/dist/keystone/keystone-types.mjs +50 -0
- package/dist/keystone/keystone-types.mjs.map +1 -0
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.d.mts +35 -0
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.d.mts.map +1 -0
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs +107 -0
- package/dist/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mjs.map +1 -0
- package/dist/keystone/strategy/keystone-strategy-factory.d.mts +15 -0
- package/dist/keystone/strategy/keystone-strategy-factory.d.mts.map +1 -0
- package/dist/keystone/strategy/keystone-strategy-factory.mjs +26 -0
- package/dist/keystone/strategy/keystone-strategy-factory.mjs.map +1 -0
- package/dist/keystone/strategy/keystone-strategy.d.mts +48 -0
- package/dist/keystone/strategy/keystone-strategy.d.mts.map +1 -0
- package/dist/keystone/strategy/keystone-strategy.mjs +14 -0
- package/dist/keystone/strategy/keystone-strategy.mjs.map +1 -0
- package/dist/respec-gib.node.mjs +3 -1
- package/dist/respec-gib.node.mjs.map +1 -1
- package/dist/spec-helper.node.respec.d.mts.map +1 -1
- package/dist/spec-helper.node.respec.mjs +4 -6
- package/dist/spec-helper.node.respec.mjs.map +1 -1
- package/dist/timeline/timeline-api.mjs +12 -12
- package/dist/timeline/timeline-api.mjs.map +1 -1
- package/dist/witness/anonymous-fn/anonymous-fn-helper.mjs.map +1 -1
- package/dist/witness/anonymous-fn/anonymous-fn-v1.mjs.map +1 -1
- package/dist/witness/app/app-base-v1.mjs.map +1 -1
- package/dist/witness/app/app-helper.mjs.map +1 -1
- package/dist/witness/app/app-types.d.mts.map +1 -1
- package/dist/witness/factory/dynamic-form-factory-base.mjs.map +1 -1
- package/dist/witness/light-witness-base-v1.mjs.map +1 -1
- package/dist/witness/robbot/robbot-base-v1.mjs +1 -1
- package/dist/witness/robbot/robbot-base-v1.mjs.map +1 -1
- package/dist/witness/robbot/robbot-helper.mjs.map +1 -1
- package/dist/witness/robbot/robbot-types.d.mts +20 -20
- package/dist/witness/robbot/robbot-types.d.mts.map +1 -1
- package/dist/witness/space/bootstrap/bootstrap-helper.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/filesystem-space-v1.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/filesystem-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/node-filesystem-space-helper.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/node-filesystem-space-types.d.mts.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/node-filesystem-space-v1.mjs +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/node-filesystem-space-v1.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/respec/testSpace_createAndInit.node-filesystem-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/respec/testSpace_persistTransformResult.node-filesystem-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/respec/testSpace_putGetDelete.node-filesystem-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/filesystem-space/node-filesystem-space/respec/testSpace_registerNewIbGib_GetLatest.node-filesystem-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.mjs.map +1 -1
- package/dist/witness/space/inner-space/inner-space-v1.respec.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-base.mjs +1 -1
- package/dist/witness/space/metaspace/metaspace-base.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace-helper.mjs.map +1 -1
- package/dist/witness/space/metaspace/metaspace-innerspace/metaspace-innerspace.mjs.map +1 -1
- package/dist/witness/space/outer-space/outer-space-helper.mjs.map +1 -1
- package/dist/witness/space/outer-space/outer-space-types.d.mts.map +1 -1
- package/dist/witness/space/outer-space/outer-space-types.mjs +1 -1
- package/dist/witness/space/outer-space/outer-space-types.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-base.mjs.map +1 -1
- package/dist/witness/space/reconciliation-space/reconciliation-space-helper.mjs.map +1 -1
- package/dist/witness/space/space-base-v1.mjs.map +1 -1
- package/dist/witness/space/space-constants.mjs +4 -4
- package/dist/witness/space/space-constants.mjs.map +1 -1
- package/dist/witness/space/space-helper.mjs +2 -2
- package/dist/witness/space/space-helper.mjs.map +1 -1
- package/dist/witness/space/space-respec-helper.mjs.map +1 -1
- package/dist/witness/space/space-types.d.mts +4 -4
- package/dist/witness/space/space-types.d.mts.map +1 -1
- package/dist/witness/witness-base-v1.mjs.map +1 -1
- package/dist/witness/witness-form-builder.mjs.map +1 -1
- package/dist/witness/witness-helper.mjs.map +1 -1
- package/dist/witness/witness-with-context/witness-with-context-base-v1.mjs.map +1 -1
- package/package.json +6 -5
- package/src/keystone/README.md +162 -0
- package/src/keystone/keystone-config-builder.mts +187 -0
- package/src/keystone/keystone-constants.mts +44 -0
- package/src/keystone/keystone-helpers.mts +571 -0
- package/src/keystone/keystone-service-v1.mts +611 -0
- package/src/keystone/keystone-service-v1.respec.mts +555 -0
- package/src/keystone/keystone-types.mts +315 -0
- package/src/keystone/strategy/hash-reveal-v1/hash-reveal-v1.mts +146 -0
- package/src/keystone/strategy/keystone-strategy-factory.mts +35 -0
- package/src/keystone/strategy/keystone-strategy.mts +71 -0
- package/src/respec-gib.node.mts +3 -1
- package/src/spec-helper.node.respec.mts +4 -6
- package/src/witness/robbot/robbot-base-v1.mts +1 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { IbGib_V1, IbGibData_V1, IbGibRel8ns_V1 } from "@ibgib/ts-gib/dist/V1/types.mjs";
|
|
2
|
+
|
|
3
|
+
import { KEYSTONE_ATOM } from "./keystone-constants.mjs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The discriminator for the mechanism.
|
|
7
|
+
* 'hash-reveal-v1': Standard Hash chain (Sigma-like).
|
|
8
|
+
*/
|
|
9
|
+
export type KeystoneChallengeType =
|
|
10
|
+
| 'hash-reveal-v1'
|
|
11
|
+
// | 'decrypt-v1' // Future
|
|
12
|
+
// | 'pow-v1'; // Future
|
|
13
|
+
;
|
|
14
|
+
|
|
15
|
+
// ===========================================================================
|
|
16
|
+
// CONFIGURATION
|
|
17
|
+
// ===========================================================================
|
|
18
|
+
|
|
19
|
+
// #region KeystoneReplenishStrategy
|
|
20
|
+
/**
|
|
21
|
+
* replaces each used challenge, "topping up" the pool to the pool's size
|
|
22
|
+
*/
|
|
23
|
+
export const KEYSTONE_REPLENISH_STRATEGY_TOP_UP = 'top-up';
|
|
24
|
+
/**
|
|
25
|
+
* replaces the entire pool with the new challenges
|
|
26
|
+
*/
|
|
27
|
+
export const KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL = 'replace-all';
|
|
28
|
+
/**
|
|
29
|
+
* do not replenish, only consume
|
|
30
|
+
*
|
|
31
|
+
* ## intent
|
|
32
|
+
* adding this for revocation
|
|
33
|
+
*/
|
|
34
|
+
export const KEYSTONE_REPLENISH_STRATEGY_CONSUME = 'consume';
|
|
35
|
+
/**
|
|
36
|
+
* Deletes ALL challenges in the pool, regardless of how many were used.
|
|
37
|
+
* The "Nuclear Option" for revocation.
|
|
38
|
+
*/
|
|
39
|
+
export const KEYSTONE_REPLENISH_STRATEGY_SCORCHED_EARTH = 'scorched-earth';
|
|
40
|
+
export type KeystoneReplenishStrategy =
|
|
41
|
+
| typeof KEYSTONE_REPLENISH_STRATEGY_TOP_UP
|
|
42
|
+
| typeof KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL
|
|
43
|
+
| typeof KEYSTONE_REPLENISH_STRATEGY_CONSUME
|
|
44
|
+
| typeof KEYSTONE_REPLENISH_STRATEGY_SCORCHED_EARTH
|
|
45
|
+
;
|
|
46
|
+
/**
|
|
47
|
+
* @see {@link KeystonePoolBehavior.replenish}
|
|
48
|
+
*/
|
|
49
|
+
export const KeystoneReplenishStrategy = {
|
|
50
|
+
/**
|
|
51
|
+
* @see {@link KEYSTONE_REPLENISH_STRATEGY_TOP_UP}
|
|
52
|
+
*/
|
|
53
|
+
topUp: KEYSTONE_REPLENISH_STRATEGY_TOP_UP,
|
|
54
|
+
/**
|
|
55
|
+
* @see {@link KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL}
|
|
56
|
+
*/
|
|
57
|
+
replaceAll: KEYSTONE_REPLENISH_STRATEGY_REPLACE_ALL,
|
|
58
|
+
/**
|
|
59
|
+
* @see {@link KEYSTONE_REPLENISH_STRATEGY_CONSUME}
|
|
60
|
+
*/
|
|
61
|
+
consume: KEYSTONE_REPLENISH_STRATEGY_CONSUME,
|
|
62
|
+
/**
|
|
63
|
+
* @see {@link KEYSTONE_REPLENISH_STRATEGY_SCORCHED_EARTH}
|
|
64
|
+
*/
|
|
65
|
+
scorchedEarth: KEYSTONE_REPLENISH_STRATEGY_SCORCHED_EARTH,
|
|
66
|
+
} satisfies { [key: string]: KeystoneReplenishStrategy };
|
|
67
|
+
export const KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES = Object.values(KeystoneReplenishStrategy);
|
|
68
|
+
export function isKeystoneReplenishStrategy(x: any): x is KeystoneReplenishStrategy {
|
|
69
|
+
return KEYSTONE_REPLENISH_STRATEGY_VALID_VALUES.includes(x);
|
|
70
|
+
}
|
|
71
|
+
// #endregion KeystoneReplenishStrategy
|
|
72
|
+
|
|
73
|
+
export interface KeystonePoolBehavior {
|
|
74
|
+
/**
|
|
75
|
+
* Target number of challenges to maintain in the pool.
|
|
76
|
+
*/
|
|
77
|
+
size: number;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* How do we fill the void left by consumed challenges?
|
|
81
|
+
*/
|
|
82
|
+
replenish: KeystoneReplenishStrategy;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Minimum number of challenges to consume from the "front" (oldest) of the pool.
|
|
86
|
+
* Mitigates sequence prediction attacks if high, allows strictly ordered audit if used alone.
|
|
87
|
+
*/
|
|
88
|
+
selectSequentially: number;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Minimum number of challenges to consume randomly from the remainder.
|
|
92
|
+
* Mitigates pre-computation attacks on the sequence.
|
|
93
|
+
*/
|
|
94
|
+
selectRandomly: number;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Number of hex characters from the Target's Gib to match.
|
|
98
|
+
* @default 0
|
|
99
|
+
*/
|
|
100
|
+
targetBindingChars: number;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export interface KeystonePoolConfigBase {
|
|
104
|
+
/**
|
|
105
|
+
* The ID of the pool this config belongs to.
|
|
106
|
+
*/
|
|
107
|
+
id: string;
|
|
108
|
+
|
|
109
|
+
type: KeystoneChallengeType;
|
|
110
|
+
/**
|
|
111
|
+
* Unique salt for this pool's derivation path from the Master Secret.
|
|
112
|
+
*/
|
|
113
|
+
salt: string;
|
|
114
|
+
behavior: KeystonePoolBehavior;
|
|
115
|
+
/**
|
|
116
|
+
* The list of Verbs (primitive ibGib addresses) this pool is authorized to sign.
|
|
117
|
+
* e.g. ["revoke^gib", "admin^gib"]
|
|
118
|
+
*
|
|
119
|
+
* If undefined or empty, this pool is considered a "General/Default" pool
|
|
120
|
+
* and can sign any verb NOT explicitly claimed by another pool (implementation detail of selection)
|
|
121
|
+
* or simply any verb at all (permissive).
|
|
122
|
+
*
|
|
123
|
+
* For V1 Security: If this is set, Validation MUST enforce it.
|
|
124
|
+
*/
|
|
125
|
+
allowedVerbs: string[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface KeystonePoolConfig_HashV1 extends KeystonePoolConfigBase {
|
|
129
|
+
type: 'hash-reveal-v1';
|
|
130
|
+
algo: 'SHA-256' | 'SHA-512';
|
|
131
|
+
rounds: number;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export type KeystonePoolConfig = KeystonePoolConfig_HashV1;
|
|
135
|
+
|
|
136
|
+
// ===========================================================================
|
|
137
|
+
// CHALLENGES (Public Puzzles)
|
|
138
|
+
// ===========================================================================
|
|
139
|
+
|
|
140
|
+
export interface KeystoneChallengeBase {
|
|
141
|
+
type: KeystoneChallengeType;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export interface KeystoneChallenge_HashV1 extends KeystoneChallengeBase {
|
|
145
|
+
id: string;
|
|
146
|
+
type: 'hash-reveal-v1';
|
|
147
|
+
/**
|
|
148
|
+
* The hash that must be matched by the solution.
|
|
149
|
+
*/
|
|
150
|
+
hash: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type KeystoneChallenge = KeystoneChallenge_HashV1;
|
|
154
|
+
|
|
155
|
+
// ===========================================================================
|
|
156
|
+
// SOLUTIONS (Private Answers revealed in Proofs)
|
|
157
|
+
// ===========================================================================
|
|
158
|
+
|
|
159
|
+
export interface KeystoneSolutionBase {
|
|
160
|
+
type: KeystoneChallengeType;
|
|
161
|
+
/**
|
|
162
|
+
* The ID of the pool this solution comes from.
|
|
163
|
+
*/
|
|
164
|
+
poolId: string;
|
|
165
|
+
/**
|
|
166
|
+
* The ID of the specific challenge being solved.
|
|
167
|
+
*/
|
|
168
|
+
challengeId: string;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface KeystoneSolution_HashV1 extends KeystoneSolutionBase {
|
|
172
|
+
type: 'hash-reveal-v1';
|
|
173
|
+
/**
|
|
174
|
+
* The Pre-image value.
|
|
175
|
+
*/
|
|
176
|
+
value: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
export type KeystoneSolution = KeystoneSolution_HashV1;
|
|
180
|
+
|
|
181
|
+
// ===========================================================================
|
|
182
|
+
// HIGH-LEVEL STRUCTURES
|
|
183
|
+
// ===========================================================================
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* A container for a set of challenges.
|
|
187
|
+
*/
|
|
188
|
+
export interface KeystoneChallengePool {
|
|
189
|
+
/**
|
|
190
|
+
* Unique ID (e.g. "default", "admin").
|
|
191
|
+
*/
|
|
192
|
+
id: string;
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Parameterization of this pool.
|
|
196
|
+
*
|
|
197
|
+
* Signing and validating this pool must observe this config.
|
|
198
|
+
*/
|
|
199
|
+
config: KeystonePoolConfig;
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Default claim values for this pool.
|
|
203
|
+
* Useful for "verb-stones".
|
|
204
|
+
*/
|
|
205
|
+
defaultClaim?: Partial<KeystoneClaim>;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* The currently active challenges.
|
|
209
|
+
* Key: The unique Challenge ID (e.g. "poolSalt_0").
|
|
210
|
+
*/
|
|
211
|
+
challenges: { [challengeId: string]: KeystoneChallenge };
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Explicit Buckets for Target Binding.
|
|
215
|
+
* Key: Hex Character ('0'-'f').
|
|
216
|
+
* Value: Array of Challenge IDs that satisfy this bucket.
|
|
217
|
+
* Note: A single ID may appear in multiple buckets (Coverage Strategy).
|
|
218
|
+
*/
|
|
219
|
+
bindingMap: { [hexChar: string]: string[] };
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Semantic intent.
|
|
224
|
+
*/
|
|
225
|
+
export interface KeystoneClaim {
|
|
226
|
+
target: string; // ibGib address
|
|
227
|
+
verb: string; // ibGib address (primitive)
|
|
228
|
+
scope?: string; // ibGib address (primitive)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Authorization Proof.
|
|
233
|
+
*/
|
|
234
|
+
export interface KeystoneProof {
|
|
235
|
+
id?: string;
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* The claim being made.
|
|
239
|
+
*/
|
|
240
|
+
claim: Partial<KeystoneClaim>;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* The solutions required to validate this claim.
|
|
244
|
+
*/
|
|
245
|
+
solutions: KeystoneSolution[];
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* The list of specific Challenge IDs that were mandatorily requested
|
|
249
|
+
* by the verifier/context during the signing process.
|
|
250
|
+
* Essential for deterministic validation.
|
|
251
|
+
*/
|
|
252
|
+
requiredChallengeIds?: string[];
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Revocation Context.
|
|
257
|
+
*/
|
|
258
|
+
export interface KeystoneRevocationInfo {
|
|
259
|
+
reason: string;
|
|
260
|
+
proof: KeystoneProof;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// ===========================================================================
|
|
264
|
+
// TOP LEVEL IBGIB DATA
|
|
265
|
+
// ===========================================================================
|
|
266
|
+
|
|
267
|
+
export interface KeystoneIbInfo_V1 {
|
|
268
|
+
atom: typeof KEYSTONE_ATOM;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export interface KeystoneData_V1 extends IbGibData_V1 {
|
|
272
|
+
/**
|
|
273
|
+
* The pools containing the FUTURE challenges.
|
|
274
|
+
* (Always topped up in V1 implementation).
|
|
275
|
+
*/
|
|
276
|
+
challengePools: KeystoneChallengePool[];
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* The proofs authorizing THIS frame's evolution.
|
|
280
|
+
*/
|
|
281
|
+
proofs: KeystoneProof[];
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* If present, this Keystone is dead.
|
|
285
|
+
*/
|
|
286
|
+
revocationInfo?: KeystoneRevocationInfo;
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Ephemeral details specific to this frame's creation context.
|
|
290
|
+
* Meant to be observed on this frame, but NOT automatically carried forward
|
|
291
|
+
* to the next frame's data during evolution.
|
|
292
|
+
*/
|
|
293
|
+
frameDetails?: any;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export interface KeystoneRel8ns_V1 extends IbGibRel8ns_V1 {
|
|
297
|
+
// Standard ibGib relations (ancestor, past, etc.)
|
|
298
|
+
// Specific hard-links for composite keystones go here later.
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export interface KeystoneIbGib_V1 extends IbGib_V1<KeystoneData_V1, KeystoneRel8ns_V1> { }
|
|
302
|
+
|
|
303
|
+
export interface DeterministicResult {
|
|
304
|
+
/**
|
|
305
|
+
* The Set of IDs that MUST be present in the solution.
|
|
306
|
+
* Includes Alice's Demands + Target Binding Matches + FIFO.
|
|
307
|
+
*/
|
|
308
|
+
mandatoryIds: Set<string>;
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* The IDs remaining in the pool that are valid candidates for
|
|
312
|
+
* the Random/Stochastic step.
|
|
313
|
+
*/
|
|
314
|
+
availableIds: string[];
|
|
315
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { hash } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
2
|
+
import { KeystoneStrategy } from '../keystone-strategy.mjs';
|
|
3
|
+
import {
|
|
4
|
+
KeystonePoolConfig_HashV1,
|
|
5
|
+
KeystoneChallenge_HashV1,
|
|
6
|
+
KeystoneSolution_HashV1
|
|
7
|
+
} from '../../keystone-types.mjs';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The concrete implementation of the "Salted Wrap" Hash Reveal strategy.
|
|
11
|
+
*/
|
|
12
|
+
export class KeystoneStrategy_HashRevealV1 extends KeystoneStrategy<
|
|
13
|
+
KeystonePoolConfig_HashV1,
|
|
14
|
+
KeystoneChallenge_HashV1,
|
|
15
|
+
KeystoneSolution_HashV1
|
|
16
|
+
> {
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Derives Pool Secret = Hash(PoolSalt + MasterSecret + PoolSalt) ^ Rounds
|
|
20
|
+
*/
|
|
21
|
+
override async derivePoolSecret({
|
|
22
|
+
masterSecret
|
|
23
|
+
}: {
|
|
24
|
+
masterSecret: string
|
|
25
|
+
}): Promise<string> {
|
|
26
|
+
const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.derivePoolSecret.name}]`;
|
|
27
|
+
try {
|
|
28
|
+
const { salt, rounds, algo } = this.config;
|
|
29
|
+
// Map algo string to HashAlgorithm type if needed,
|
|
30
|
+
// assuming config.algo matches the helper's expected inputs.
|
|
31
|
+
|
|
32
|
+
let current = masterSecret;
|
|
33
|
+
for (let i = 0; i < rounds; i++) {
|
|
34
|
+
current = await hash({
|
|
35
|
+
s: `${salt}${current}${salt}`,
|
|
36
|
+
algorithm: algo
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return current;
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(`${lc} Error deriving pool secret: ${error.message}`);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Solution Value = Hash(IndexSalt + PoolSecret + IndexSalt) ^ Rounds
|
|
48
|
+
*/
|
|
49
|
+
override async generateSolution({
|
|
50
|
+
poolSecret,
|
|
51
|
+
poolId,
|
|
52
|
+
challengeId,
|
|
53
|
+
}: {
|
|
54
|
+
poolSecret: string;
|
|
55
|
+
poolId: string;
|
|
56
|
+
challengeId: string;
|
|
57
|
+
}): Promise<KeystoneSolution_HashV1> {
|
|
58
|
+
const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateSolution.name}]`;
|
|
59
|
+
try {
|
|
60
|
+
const { rounds, algo } = this.config;
|
|
61
|
+
|
|
62
|
+
// The Index Salt is the unique identifier for this slot
|
|
63
|
+
const indexSalt = challengeId;
|
|
64
|
+
|
|
65
|
+
let current = poolSecret;
|
|
66
|
+
for (let i = 0; i < rounds; i++) {
|
|
67
|
+
current = await hash({
|
|
68
|
+
s: `${indexSalt}${current}${indexSalt}`,
|
|
69
|
+
algorithm: algo
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
type: 'hash-reveal-v1',
|
|
75
|
+
poolId,
|
|
76
|
+
challengeId,
|
|
77
|
+
value: current
|
|
78
|
+
};
|
|
79
|
+
} catch (error) {
|
|
80
|
+
console.error(`${lc} ${error.message}`);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Challenge Hash = Hash(IndexSalt + SolutionValue + IndexSalt) ^ Rounds
|
|
87
|
+
*/
|
|
88
|
+
override async generateChallenge({
|
|
89
|
+
solution,
|
|
90
|
+
}: {
|
|
91
|
+
solution: KeystoneSolution_HashV1;
|
|
92
|
+
}): Promise<KeystoneChallenge_HashV1> {
|
|
93
|
+
const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.generateChallenge.name}]`;
|
|
94
|
+
try {
|
|
95
|
+
const { rounds, algo } = this.config;
|
|
96
|
+
const { challengeId, value } = solution;
|
|
97
|
+
const indexSalt = challengeId;
|
|
98
|
+
|
|
99
|
+
let current = value;
|
|
100
|
+
for (let i = 0; i < rounds; i++) {
|
|
101
|
+
current = await hash({
|
|
102
|
+
s: `${indexSalt}${current}${indexSalt}`,
|
|
103
|
+
algorithm: algo
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return {
|
|
108
|
+
id: challengeId,
|
|
109
|
+
type: 'hash-reveal-v1',
|
|
110
|
+
hash: current
|
|
111
|
+
};
|
|
112
|
+
} catch (error) {
|
|
113
|
+
console.error(`${lc} ${error.message}`);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Re-generates the challenge from the candidate solution and compares.
|
|
120
|
+
*/
|
|
121
|
+
override async validateSolution({
|
|
122
|
+
solution,
|
|
123
|
+
challenge,
|
|
124
|
+
}: {
|
|
125
|
+
solution: KeystoneSolution_HashV1;
|
|
126
|
+
challenge: KeystoneChallenge_HashV1;
|
|
127
|
+
}): Promise<boolean> {
|
|
128
|
+
const lc = `[${KeystoneStrategy_HashRevealV1.name}.${this.validateSolution.name}]`;
|
|
129
|
+
try {
|
|
130
|
+
// 1. Check Type Compatibility
|
|
131
|
+
if (solution.type !== 'hash-reveal-v1' || challenge.type !== 'hash-reveal-v1') {
|
|
132
|
+
console.warn(`${lc} Mismatched types provided.`);
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// 2. Generate the expected challenge hash from the solution provided
|
|
137
|
+
const calculatedChallenge = await this.generateChallenge({ solution });
|
|
138
|
+
|
|
139
|
+
// 3. Compare
|
|
140
|
+
return calculatedChallenge.hash === challenge.hash;
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error(`${lc} ${error.message}`);
|
|
143
|
+
return false; // Fail closed
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KeystonePoolConfig
|
|
3
|
+
} from '../keystone-types.mjs';
|
|
4
|
+
import { KeystoneStrategyAny } from './keystone-strategy.mjs';
|
|
5
|
+
import { KeystoneStrategy_HashRevealV1 } from './hash-reveal-v1/hash-reveal-v1.mjs';
|
|
6
|
+
|
|
7
|
+
export class KeystoneStrategyFactory {
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Instantiates the appropriate concrete KeystoneStrategy based on the
|
|
11
|
+
* provided configuration type.
|
|
12
|
+
*
|
|
13
|
+
* @param config The configuration object for the pool (contains 'type').
|
|
14
|
+
* @returns An instance of the specific strategy class.
|
|
15
|
+
*/
|
|
16
|
+
static create({
|
|
17
|
+
config,
|
|
18
|
+
}: {
|
|
19
|
+
config: KeystonePoolConfig,
|
|
20
|
+
}): KeystoneStrategyAny {
|
|
21
|
+
const lc = `[${KeystoneStrategyFactory.name}.create]`;
|
|
22
|
+
try {
|
|
23
|
+
switch (config.type) {
|
|
24
|
+
case 'hash-reveal-v1':
|
|
25
|
+
return new KeystoneStrategy_HashRevealV1(config);
|
|
26
|
+
|
|
27
|
+
default:
|
|
28
|
+
throw new Error(`Unknown strategy type: ${(config as any).type} (E: 4e3c2f7129a241c1b687555e678c1065)`);
|
|
29
|
+
}
|
|
30
|
+
} catch (error) {
|
|
31
|
+
console.error(`${lc} ${error.message}`);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {
|
|
2
|
+
KeystonePoolConfigBase,
|
|
3
|
+
KeystoneChallengeBase,
|
|
4
|
+
KeystoneSolutionBase
|
|
5
|
+
} from '../keystone-types.mjs';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Abstract base class for all Keystone Challenge Strategies.
|
|
9
|
+
*
|
|
10
|
+
* @template TConfig The specific configuration interface (e.g. HashV1).
|
|
11
|
+
* @template TChallenge The specific public challenge interface.
|
|
12
|
+
* @template TSolution The specific private solution interface.
|
|
13
|
+
*/
|
|
14
|
+
export abstract class KeystoneStrategy<
|
|
15
|
+
TConfig extends KeystonePoolConfigBase,
|
|
16
|
+
TChallenge extends KeystoneChallengeBase,
|
|
17
|
+
TSolution extends KeystoneSolutionBase
|
|
18
|
+
> {
|
|
19
|
+
constructor(protected config: TConfig) {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Derives the secret specific to this pool from the master keystone secret.
|
|
23
|
+
* This isolates the pool so the master secret is never used directly
|
|
24
|
+
* in challenge generation.
|
|
25
|
+
*/
|
|
26
|
+
abstract derivePoolSecret({
|
|
27
|
+
masterSecret
|
|
28
|
+
}: {
|
|
29
|
+
masterSecret: string
|
|
30
|
+
}): Promise<string>;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generates the private solution (Pre-image) for a specific challenge ID.
|
|
34
|
+
*
|
|
35
|
+
* @returns The concrete solution object (not just the value string).
|
|
36
|
+
*/
|
|
37
|
+
abstract generateSolution({
|
|
38
|
+
poolSecret,
|
|
39
|
+
poolId,
|
|
40
|
+
challengeId,
|
|
41
|
+
}: {
|
|
42
|
+
poolSecret: string;
|
|
43
|
+
poolId: string;
|
|
44
|
+
challengeId: string;
|
|
45
|
+
}): Promise<TSolution>;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generates the public challenge from a given solution.
|
|
49
|
+
* Used when creating the pool (Top Up) or verifying a solution.
|
|
50
|
+
*/
|
|
51
|
+
abstract generateChallenge({
|
|
52
|
+
solution,
|
|
53
|
+
}: {
|
|
54
|
+
solution: TSolution;
|
|
55
|
+
}): Promise<TChallenge>;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validates that a given solution mathematically solves the given challenge.
|
|
59
|
+
*
|
|
60
|
+
* @returns true if valid, false otherwise.
|
|
61
|
+
*/
|
|
62
|
+
abstract validateSolution({
|
|
63
|
+
solution,
|
|
64
|
+
challenge,
|
|
65
|
+
}: {
|
|
66
|
+
solution: TSolution;
|
|
67
|
+
challenge: TChallenge;
|
|
68
|
+
}): Promise<boolean>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export type KeystoneStrategyAny = KeystoneStrategy<any,any,any>;
|
package/src/respec-gib.node.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { readdir, open } from 'node:fs/promises';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
2
3
|
import { statSync } from 'node:fs';
|
|
3
4
|
import * as pathUtils from 'path';
|
|
4
5
|
|
|
@@ -95,7 +96,8 @@ if (logalot) { console.log(`respecPaths found:\n${respecPaths}`); }
|
|
|
95
96
|
for (let i = 0; i < respecPaths.length; i++) {
|
|
96
97
|
const respecPath = respecPaths[i];
|
|
97
98
|
if (logalot) { console.log(respecPath); }
|
|
98
|
-
const
|
|
99
|
+
const respecPathUrl = pathToFileURL(respecPath).href;
|
|
100
|
+
const esm = await import(respecPathUrl);
|
|
99
101
|
if (logalot) { console.log(pretty(Object.keys(esm))); }
|
|
100
102
|
}
|
|
101
103
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { default as pathUtils } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
2
3
|
|
|
3
4
|
import { delay, getUUID, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs';
|
|
4
5
|
|
|
@@ -11,12 +12,9 @@ import { delay, getUUID, } from '@ibgib/helper-gib/dist/helpers/utils-helper.mjs
|
|
|
11
12
|
export async function getCurrentFilename(importMetaUrl: string): Promise<string> {
|
|
12
13
|
const lc = `[${getCurrentFilename.name}]`;
|
|
13
14
|
try {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
console.warn(`filename not able to be gotten?`);
|
|
18
|
-
filename = (new Date()).toTimeString() + (await getUUID());
|
|
19
|
-
}
|
|
15
|
+
const filePath = fileURLToPath(importMetaUrl);
|
|
16
|
+
const filenameWithExt = pathUtils.basename(filePath);
|
|
17
|
+
const filename = filenameWithExt.replace(/\.respec\.mjs$/, '');
|
|
20
18
|
return `ibgib${pathUtils.sep}${filename}`;
|
|
21
19
|
} catch (error) {
|
|
22
20
|
console.error(`${lc} ${error.message}`);
|
|
@@ -694,7 +694,7 @@ export abstract class RobbotBase_V1<
|
|
|
694
694
|
// todo: adjust to use the cacheIbGibs (not get them if already have in cache, but still return them in this fn's result)
|
|
695
695
|
for (let i = 0; i < rel8nNames.length; i++) {
|
|
696
696
|
const rel8nName = rel8nNames[i];
|
|
697
|
-
const rel8dAddrs: IbGibAddr[] = this.rel8ns
|
|
697
|
+
const rel8dAddrs: IbGibAddr[] = this.rel8ns?.[rel8nName] ?? [];
|
|
698
698
|
|
|
699
699
|
if (rel8dAddrs.length > 0) {
|
|
700
700
|
const resGet = await getFromSpace({ addrs: rel8dAddrs, space });
|