signify-ts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +25 -0
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +8 -0
  5. package/dist/keri/core/cigar.d.ts +8 -0
  6. package/dist/keri/core/cipher.d.ts +5 -0
  7. package/dist/keri/core/core.d.ts +68 -0
  8. package/dist/keri/core/decrypter.d.ts +10 -0
  9. package/dist/keri/core/diger.d.ts +21 -0
  10. package/dist/keri/core/encrypter.d.ts +9 -0
  11. package/dist/keri/core/indexer.d.ts +88 -0
  12. package/dist/keri/core/keeping.d.ts +1 -0
  13. package/dist/keri/core/kering.d.ts +5 -0
  14. package/dist/keri/core/manager.d.ts +151 -0
  15. package/dist/keri/core/matter.d.ts +47 -0
  16. package/dist/keri/core/siger.d.ts +22 -0
  17. package/dist/keri/core/signer.d.ts +34 -0
  18. package/dist/keri/core/utils.d.ts +16 -0
  19. package/dist/signify-ts.cjs.development.js +13 -0
  20. package/dist/signify-ts.cjs.development.js.map +1 -0
  21. package/dist/signify-ts.cjs.production.min.js +2 -0
  22. package/dist/signify-ts.cjs.production.min.js.map +1 -0
  23. package/dist/signify-ts.esm.js +9 -0
  24. package/dist/signify-ts.esm.js.map +1 -0
  25. package/package.json +66 -0
  26. package/src/index.ts +6 -0
  27. package/src/keri/core/cigar.ts +19 -0
  28. package/src/keri/core/cipher.ts +25 -0
  29. package/src/keri/core/core.ts +174 -0
  30. package/src/keri/core/decrypter.ts +66 -0
  31. package/src/keri/core/diger.ts +82 -0
  32. package/src/keri/core/encrypter.ts +60 -0
  33. package/src/keri/core/indexer.ts +406 -0
  34. package/src/keri/core/keeping.ts +9 -0
  35. package/src/keri/core/kering.ts +12 -0
  36. package/src/keri/core/manager.ts +874 -0
  37. package/src/keri/core/matter.ts +252 -0
  38. package/src/keri/core/salter.ts +85 -0
  39. package/src/keri/core/siger.ts +39 -0
  40. package/src/keri/core/signer.ts +112 -0
  41. package/src/keri/core/tsconfig.json +100 -0
  42. package/src/keri/core/utils.ts +94 -0
  43. package/src/keri/core/verfer.ts +33 -0
@@ -0,0 +1,874 @@
1
+ import {Encrypter} from "./encrypter"
2
+ import {Decrypter} from "./decrypter"
3
+ import {Salter, Tier} from "./salter"
4
+ import {Signer} from "./signer"
5
+ import {Verfer} from "./verfer";
6
+ import {MtrDex} from "./matter";
7
+ import {Diger} from "./diger";
8
+ import {Cigar} from "./cigar";
9
+ import {Siger} from "./siger";
10
+ import {b} from "./core";
11
+
12
+
13
+ export enum Algos {
14
+ randy = "randy",
15
+ salty = "salty"
16
+ }
17
+
18
+ class PubLot {
19
+ public pubs: Array<string> = new Array<string>() // list qb64 public keys.
20
+ public ridx: number = 0 // index of rotation (est event) that uses public key set
21
+ public kidx: number = 0 // index of key in sequence of public keys
22
+ public dt:string = "" // datetime ISO8601 when key set created
23
+ }
24
+
25
+ class PreSit {
26
+ public old: PubLot = new PubLot() //previous publot
27
+ public new: PubLot = new PubLot() //newly current publot
28
+ public nxt: PubLot = new PubLot() //next public publot
29
+ }
30
+
31
+ class PrePrm {
32
+ public pidx: number = 0 // prefix index for this keypair sequence
33
+ public algo: Algos = Algos.salty // salty default uses indices and salt to create new key pairs
34
+ public salt: string = '' // empty salt used for salty algo.
35
+ public stem: string = '' // default unique path stem for salty algo
36
+ public tier: string = '' // security tier for stretch index salty algo
37
+
38
+ }
39
+
40
+ class PubSet {
41
+ pubs: Array<string> = new Array<string>() // list qb64 public keys.
42
+ }
43
+
44
+ export interface Creator {
45
+ create(codes: Array<string> | undefined, count: number, code: string, transferable: boolean,
46
+ pidx: number, ridx: number, kidx: number, temp: boolean): Array<Signer>
47
+ get salt(): string
48
+ get stem(): string
49
+ get tier(): Tier
50
+ }
51
+
52
+ export class RandyCreator implements Creator {
53
+
54
+ create(codes: Array<string> | undefined = undefined, count: number = 1, code: string = MtrDex.Ed25519_Seed,
55
+ transferable: boolean = true): Array<Signer> {
56
+ let signers = new Array<Signer>()
57
+ if (codes == undefined) {
58
+ codes = new Array(count).fill(code)
59
+ }
60
+
61
+ codes.forEach(function(code) {
62
+ signers.push(new Signer({code: code, transferable: transferable}))
63
+ })
64
+
65
+ return signers
66
+ }
67
+
68
+ get salt(): string {
69
+ return "";
70
+ }
71
+
72
+ get stem(): string {
73
+ return "";
74
+ }
75
+
76
+ get tier(): Tier {
77
+ return Tier.low;
78
+ }
79
+ }
80
+
81
+ export class SaltyCreator implements Creator {
82
+
83
+ public salter: Salter
84
+ private readonly _stem: string
85
+ constructor(salt: string | undefined = undefined, tier: Tier | undefined = undefined,
86
+ stem: string | undefined = undefined) {
87
+
88
+ this.salter = new Salter({qb64: salt, tier: tier})
89
+ this._stem = stem == undefined ? "" : stem
90
+
91
+ }
92
+
93
+ get salt(): string {
94
+ return this.salter.qb64;
95
+ }
96
+
97
+ get stem(): string {
98
+ return this._stem;
99
+ }
100
+
101
+ get tier(): Tier {
102
+ return this.salter.tier;
103
+ }
104
+
105
+ create(codes: Array<string> | undefined = undefined, count: number = 1, code: string = MtrDex.Ed25519_Seed,
106
+ transferable: boolean = true, pidx: number = 0, ridx: number = 0, kidx: number = 0,
107
+ temp: boolean = false): Array<Signer> {
108
+ let signers = new Array<Signer>()
109
+ if (codes == undefined) {
110
+ codes = new Array(count).fill(code)
111
+ }
112
+
113
+ let stem = this.stem == "" ? pidx.toString(16) : this.stem
114
+
115
+ codes.forEach((code, idx) => {
116
+ let path = stem + ridx.toString(16) + (kidx+idx).toString(16)
117
+ signers.push(this.salter.signer(code, transferable, path, this.tier, temp))
118
+ })
119
+
120
+ return signers
121
+ }
122
+
123
+ }
124
+
125
+ export class Creatory {
126
+ private _make: any
127
+ constructor(algo: Algos = Algos.salty) {
128
+ switch(algo) {
129
+ case Algos.randy:
130
+ this._make = this._makeRandy
131
+ break;
132
+ case Algos.salty:
133
+ this._make = this._makeSalty
134
+ break;
135
+ default:
136
+ throw new Error(`unsupported algo=${algo}`)
137
+ }
138
+ }
139
+
140
+ make(...args: any[]) {
141
+ return this._make(...args)
142
+ }
143
+
144
+ _makeRandy() {
145
+ return new RandyCreator()
146
+ }
147
+
148
+ _makeSalty(...args: any[]) {
149
+ return new SaltyCreator(...args)
150
+ }
151
+ }
152
+
153
+ export interface ManagerArgs {
154
+ ks?: KeyStore | undefined
155
+ seed?: string | undefined
156
+ aeid?: string | undefined
157
+ pidx?: number | undefined
158
+ algo?: string | undefined
159
+ salt?: string | undefined
160
+ tier?: string | undefined
161
+ }
162
+
163
+ interface InceptArgs {
164
+ icodes?: any | undefined
165
+ icount?: number
166
+ icode?: string
167
+ ncodes?: any | undefined
168
+ ncount?: number
169
+ ncode?: string
170
+ dcode?: string
171
+ algo?: Algos | undefined
172
+ salt?: string | undefined
173
+ stem?: string | undefined
174
+ tier?: string | undefined
175
+ rooted?: boolean
176
+ transferable?: boolean
177
+ temp?: boolean
178
+ }
179
+
180
+ interface RotateArgs {
181
+ pre: string
182
+ ncodes?: any | undefined
183
+ ncount?: number
184
+ ncode?: string
185
+ dcode?: string
186
+ transferable?: boolean
187
+ temp?: boolean
188
+ erase?: boolean
189
+ }
190
+
191
+ interface SignArgs {
192
+ ser: Uint8Array
193
+ pubs?: Array<string> | undefined
194
+ verfers?: Array<Verfer> | undefined
195
+ indexed?: boolean
196
+ indices?: Array<number> | undefined
197
+ ondices?: Array<number> | undefined
198
+ }
199
+
200
+ export class Manager {
201
+ private _seed: string
202
+ private _encrypter: Encrypter | undefined
203
+ private _decrypter: Decrypter | undefined
204
+ private _ks: KeyStore
205
+
206
+ constructor({ks, seed, aeid, pidx, algo, salt, tier}: ManagerArgs) {
207
+
208
+ this._ks = ks == undefined ? new Keeper() : ks
209
+ this._seed = seed == undefined ? "" : seed
210
+ this._encrypter = undefined
211
+ this._decrypter = undefined
212
+
213
+ aeid = aeid == undefined ? "" : aeid
214
+ pidx = pidx == undefined ? 0 : pidx
215
+ algo = algo == undefined ? Algos.salty : algo
216
+
217
+ if (salt == undefined) {
218
+ salt = new Salter({}).qb64
219
+ } else {
220
+ if (new Salter({qb64: salt}).qb64 != salt) {
221
+ throw new Error(`Invalid qb64 for salt=${salt}.`)
222
+ }
223
+ }
224
+
225
+ tier = tier == undefined ? Tier.low : tier
226
+
227
+ if (this.pidx == undefined) {
228
+ this.pidx = pidx
229
+ }
230
+
231
+ if (this.algo == undefined) {
232
+ this.algo = algo
233
+ }
234
+
235
+ if (this.salt == undefined) {
236
+ this.salt = salt
237
+ }
238
+
239
+ if (this.tier == undefined) {
240
+ this.tier = tier
241
+ }
242
+
243
+ if (this.aeid == undefined) {
244
+ this.updateAeid(aeid, this._seed)
245
+ }
246
+ }
247
+
248
+ get ks(): KeyStore {
249
+ return this._ks
250
+ }
251
+
252
+ get encrypter(): Encrypter {
253
+ return this._encrypter!
254
+ }
255
+
256
+ get decrypter(): Decrypter {
257
+ return this._decrypter!
258
+ }
259
+
260
+ get seed(): string {
261
+ return this._seed
262
+ }
263
+
264
+ get aeid(): string | undefined {
265
+ return this.ks.getGbls('aeid')
266
+ }
267
+
268
+ get pidx(): number | undefined {
269
+ let pidx = this.ks.getGbls('pidx')
270
+ if (pidx != undefined) {
271
+ return parseInt(pidx, 16)
272
+ }
273
+ return undefined
274
+ }
275
+
276
+ set pidx(pidx: number | undefined) {
277
+ this.ks.pinGbls('pidx', pidx!.toString(16))
278
+ }
279
+
280
+ get salt(): string | undefined{
281
+ let salt = this.ks.getGbls('salt')
282
+ if (this._decrypter != undefined) {
283
+ return this._decrypter?.decrypt(b(salt)).qb64
284
+ }
285
+ return salt
286
+ }
287
+
288
+ set salt(salt: string | undefined) {
289
+ if(this._encrypter != undefined) {
290
+ salt = this._encrypter.encrypt(b(salt)).qb64
291
+ }
292
+ this.ks.pinGbls('salt', salt!)
293
+ }
294
+
295
+ get tier(): string | undefined {
296
+ return this.ks.getGbls('tier')
297
+ }
298
+
299
+ set tier(tier: string | undefined) {
300
+ this.ks.pinGbls('tier', tier!)
301
+ }
302
+
303
+ get algo(): Algos | undefined {
304
+ let a = this.ks.getGbls('algo')
305
+ let ta = a as keyof typeof Algos
306
+ return Algos[ta]
307
+ }
308
+
309
+ set algo(algo: string | undefined) {
310
+ this.ks.pinGbls('algo', algo!)
311
+ }
312
+
313
+ private updateAeid(aeid: string | undefined, seed: string) {
314
+ if (this.aeid != undefined) {
315
+ let seed = b(this._seed)
316
+ if (this._seed == undefined || !this._encrypter?.verifySeed(seed)) {
317
+ throw new Error(`Last seed missing or provided last seed "
318
+ "not associated with last aeid=${this.aeid}.`)
319
+ }
320
+ }
321
+
322
+ if (aeid != "" && aeid != undefined) {
323
+ if (aeid != this.aeid) {
324
+ this._encrypter = new Encrypter({}, b(aeid))
325
+ if (seed == undefined || !this._encrypter.verifySeed(b(seed))) {
326
+ throw new Error(`Seed missing or provided seed not associated"
327
+ " with provided aeid=${aeid}.`)
328
+ }
329
+ }
330
+ } else {
331
+ // Unlike KERIpy, we don't support unencrypted secrets
332
+ throw new Error("Invalid use of Manager, unencrypted keystore not supported")
333
+ }
334
+
335
+ let salt = this.salt
336
+ if(salt != undefined) {
337
+ this.salt = salt
338
+ }
339
+
340
+ if (this._decrypter != undefined) {
341
+ for (const [keys, data] of this.ks.prmsElements()) {
342
+ if (data.salt != undefined) {
343
+ let salter = this._decrypter.decrypt(b(data.salt))
344
+ data.salt = this._encrypter == undefined ? salter.qb64 : this._encrypter.encrypt(null, salter)
345
+ this.ks.pinPrms(keys, data)
346
+ }
347
+ }
348
+
349
+ for (const [pubKey, signer] of this.ks.prisElements(this._decrypter)) {
350
+ this.ks.pinPris(pubKey, signer, this._encrypter!)
351
+ }
352
+
353
+ }
354
+
355
+ this.ks.pinGbls("aeid", aeid) // set aeid in db
356
+ this._seed = seed // set .seed in memory
357
+
358
+ // update .decrypter
359
+ this._decrypter = seed != undefined ? new Decrypter({}, b(seed)) : undefined
360
+ }
361
+
362
+ incept({icodes=undefined, icount=1, icode=MtrDex.Ed25519_Seed,
363
+ ncodes=undefined, ncount=1, ncode=MtrDex.Ed25519_Seed,
364
+ dcode=MtrDex.Blake3_256, algo=undefined, salt=undefined, stem=undefined, tier=undefined,
365
+ rooted=true, transferable=true, temp=false }: InceptArgs): [Array<Verfer>, Array<Diger>] {
366
+
367
+ if (rooted && algo == undefined) {
368
+ algo = this.algo
369
+ }
370
+ if (rooted && salt == undefined) {
371
+ salt = this.salt
372
+ }
373
+ if (rooted && tier == undefined) {
374
+ tier = this.tier
375
+ }
376
+
377
+ let pidx = this.pidx
378
+ let ridx = 0
379
+ let kidx = 0
380
+
381
+ let creator = new Creatory(algo).make(salt, tier, stem)
382
+
383
+ if (icodes == undefined) {
384
+ if (icount < 0) {
385
+ throw new Error(`Invalid icount=${icount} must be >= 0.`)
386
+ }
387
+
388
+ icodes = new Array<string>(icount).fill(icode)
389
+ }
390
+
391
+ let isigners = creator.create(icodes, 0, MtrDex.Ed25519_Seed, transferable, pidx, ridx, kidx, temp)
392
+ let verfers = Array.from(isigners, (signer: Signer) => signer.verfer)
393
+
394
+ if (ncodes == undefined) {
395
+ if (ncount < 0) {
396
+ throw new Error(`Invalid ncount=${ncount} must be >= 0.`)
397
+ }
398
+
399
+ ncodes = new Array<string>(ncount).fill(ncode)
400
+ }
401
+
402
+ let nsigners = creator.create(ncodes, 0, MtrDex.Ed25519_Seed, transferable, pidx, ridx+1, kidx+icodes.length,
403
+ temp)
404
+
405
+ let digers = Array.from(nsigners, (signer: Signer) => new Diger({code: dcode}, signer.verfer.qb64b))
406
+
407
+ let pp = new PrePrm()
408
+ pp.pidx = pidx!
409
+ pp.algo = algo!
410
+ pp.salt = this._encrypter?.encrypt(b(creator.salt)).qb64
411
+ pp.stem = creator.stem
412
+ pp.tier = creator.tier
413
+
414
+ let dt = new Date().toString()
415
+ let nw = new PubLot()
416
+ nw.pubs = Array.from(verfers, (verfer: Verfer) => verfer.qb64)
417
+ nw.ridx = ridx
418
+ nw.kidx = kidx
419
+ nw.dt = dt
420
+
421
+ let nt = new PubLot()
422
+ nt.pubs = Array.from(nsigners, (signer: Signer) => signer.verfer.qb64)
423
+ nt.ridx = ridx + 1
424
+ nt.kidx = kidx + icodes.length
425
+ nt.dt = dt
426
+
427
+ let ps = new PreSit()
428
+ ps.new = nw
429
+ ps.nxt = nt
430
+
431
+ let pre = verfers[0].qb64
432
+ if (!this.ks.putPres(pre, verfers[0].qb64b)) {
433
+ throw new Error(`Already incepted pre=${pre}.`)
434
+ }
435
+
436
+ if (!this.ks.putPrms(pre, pp)) {
437
+ throw new Error(`Already incepted prm for pre=${pre}.`)
438
+ }
439
+
440
+ this.pidx = pidx! + 1
441
+
442
+ if (!this.ks.putSits(pre, ps)) {
443
+ throw new Error(`Already incepted sit for pre=${pre}.`)
444
+ }
445
+
446
+ isigners.forEach((signer: Signer) => {
447
+ this.ks.putPris(signer.verfer.qb64, signer, this._encrypter!)
448
+ })
449
+
450
+ let pubSet = new PubSet()
451
+ pubSet.pubs = ps.new.pubs
452
+ this.ks.putPubs(riKey(pre, ridx), pubSet)
453
+
454
+ nsigners.forEach((signer: Signer) => {
455
+ this.ks.putPris(signer.verfer.qb64, signer, this._encrypter!)
456
+ })
457
+
458
+ let nxtPubSet = new PubSet()
459
+ nxtPubSet.pubs = ps.nxt.pubs
460
+ this.ks.putPubs(riKey(pre, ridx+1), nxtPubSet)
461
+
462
+ return [verfers, digers]
463
+ }
464
+
465
+ move(old: string, gnu: string) {
466
+ if (old == gnu) {
467
+ return
468
+ }
469
+
470
+ if (this.ks.getPres(old) == undefined) {
471
+ throw new Error(`Nonexistent old pre=${old}, nothing to assign.`)
472
+ }
473
+
474
+ if (this.ks.getPres(gnu) != undefined) {
475
+ throw new Error(`Preexistent new pre=${gnu} may not clobber.`)
476
+ }
477
+
478
+ let oldprm = this.ks.getPrms(old)
479
+ if (oldprm == undefined) {
480
+ throw new Error(`Nonexistent old prm for pre=${old}, nothing to move.`)
481
+ }
482
+
483
+ if (this.ks.getPrms(gnu) != undefined) {
484
+ throw new Error(`Preexistent new prm for pre=${gnu} may not clobber.`)
485
+ }
486
+
487
+ let oldsit = this.ks.getSits(old)
488
+ if (oldsit == undefined) {
489
+ throw new Error(`Nonexistent old sit for pre=${old}, nothing to move.`)
490
+ }
491
+
492
+ if (this.ks.getSits(gnu) != undefined) {
493
+ throw new Error(`Preexistent new sit for pre=${gnu} may not clobber.`)
494
+ }
495
+
496
+ if (!this.ks.putPrms(gnu, oldprm)) {
497
+ throw new Error(`Failed moving prm from old pre=${old} to new pre=${gnu}.`)
498
+ } else {
499
+ this.ks.remPrms(old)
500
+ }
501
+
502
+ if (!this.ks.putSits(gnu, oldsit)) {
503
+ throw new Error(`Failed moving sit from old pre=${old} to new pre=${gnu}.`)
504
+ } else {
505
+ this.ks.remSits(old)
506
+ }
507
+
508
+ let i = 0
509
+ while (true) {
510
+ let pl = this.ks.getPubs(riKey(old, i))
511
+ if (pl == undefined) {
512
+ break
513
+ }
514
+
515
+ if (!this.ks.putPubs(riKey(gnu, i), pl)) {
516
+ throw new Error(`Failed moving pubs at pre=${old} ri=${i} to new pre=${gnu}`)
517
+ }
518
+ i = i + 1
519
+ }
520
+
521
+ if (!this.ks.pinPres(old, b(gnu))) {
522
+ throw new Error(`Failed assiging new pre=${gnu} to old pre=${old}.`)
523
+ }
524
+
525
+ if (!this.ks.putPres(gnu, b(gnu))) {
526
+ throw new Error(`Failed assiging new pre=${gnu}.`)
527
+ }
528
+ }
529
+
530
+ rotate({pre, ncodes=undefined, ncount=1, ncode=MtrDex.Ed25519_Seed, dcode=MtrDex.Blake3_256,
531
+ transferable=true, temp=false, erase=true}:RotateArgs) {
532
+ let pp = this.ks.getPrms(pre)
533
+ if (pp == undefined) {
534
+ throw new Error(`Attempt to rotate nonexistent pre=${pre}.`)
535
+ }
536
+
537
+ let ps = this.ks.getSits(pre)
538
+ if (ps == undefined) {
539
+ throw new Error(`Attempt to rotate nonexistent pre=${pre}.`)
540
+ }
541
+
542
+ if (ps.nxt.pubs == undefined) {
543
+ throw new Error(`Attempt to rotate nontransferable pre=${pre}.`)
544
+ }
545
+
546
+ let old = ps.old
547
+ ps.old = ps.new
548
+ ps.new = ps.nxt
549
+
550
+ if (this.aeid != undefined && this.decrypter == undefined) {
551
+ throw new Error("Unauthorized decryption attempt. Aeid but no decrypter.")
552
+ }
553
+
554
+ let verfers = new Array<Verfer>()
555
+ ps.new.pubs.forEach((pub) => {
556
+ let signer = this.ks.getPris(pub, this.decrypter)
557
+ if (signer == undefined) {
558
+ throw new Error(`Missing prikey in db for pubkey=${pub}`)
559
+ }
560
+
561
+ verfers.push(signer.verfer)
562
+ })
563
+
564
+ let salt = pp.salt
565
+ if (salt != undefined && salt != "") {
566
+ salt = this.decrypter.decrypt(b(salt)).qb64
567
+ }
568
+
569
+ let creator = new Creatory(pp.algo).make(salt, pp.stem, pp.tier)
570
+
571
+ if (ncodes == undefined) {
572
+ if (ncount < 0) {
573
+ throw new Error(`Invalid count=${ncount} must be >= 0`)
574
+ }
575
+ ncodes = new Array<string>(ncount).fill(ncode)
576
+ }
577
+
578
+ let pidx = pp.pidx
579
+ let ridx = ps.new.ridx + 1
580
+ let kidx = ps.nxt.kidx + ps.new.pubs.length
581
+
582
+ let signers = creator.create(ncodes, 0, undefined, transferable, pidx, ridx, kidx, temp)
583
+ let digers = Array.from(signers, (signer: Signer) => new Diger({code: dcode}, signer.verfer.qb64b))
584
+
585
+ let dt = new Date().toString()
586
+ ps.nxt = new PubLot()
587
+ ps.nxt.pubs = Array.from(signers, (signer: Signer) => signer.verfer.qb64)
588
+ ps.nxt.ridx = ridx
589
+ ps.nxt.kidx = kidx
590
+ ps.nxt.dt = dt
591
+
592
+ if (!this.ks.pinSits(pre, ps)) {
593
+ throw new Error(`Problem updating pubsit db for pre=${pre}.`)
594
+ }
595
+
596
+ signers.forEach((signer: Signer) => {
597
+ this.ks.putPris(signer.verfer.qb64, signer, this.encrypter)
598
+ })
599
+
600
+ let newPs = new PubSet()
601
+ newPs.pubs = ps.nxt.pubs
602
+ this.ks.putPubs(riKey(pre, ps.nxt.ridx), newPs)
603
+
604
+ if (erase) {
605
+ old.pubs.forEach((pub) => {
606
+ this.ks.remPubs(pub)
607
+ })
608
+ }
609
+
610
+ return [verfers, digers]
611
+ }
612
+
613
+ sign({ser, pubs=undefined, verfers=undefined, indexed=true, indices=undefined, ondices=undefined}: SignArgs) {
614
+ let signers = new Array<Signer>()
615
+
616
+ if (pubs == undefined && verfers == undefined) {
617
+ throw new Error("pubs or verfers required")
618
+ }
619
+
620
+ if (pubs != undefined) {
621
+ if (this.aeid != undefined && this.decrypter == undefined) {
622
+ throw new Error("Unauthorized decryption attempt. Aeid but no decrypter.")
623
+ }
624
+
625
+ pubs.forEach((pub) => {
626
+ let signer = this.ks.getPris(pub, this.decrypter)
627
+ if (signer == undefined) {
628
+ throw new Error(`Missing prikey in db for pubkey=${pub}`)
629
+ }
630
+ signers.push(signer)
631
+ })
632
+ } else {
633
+ verfers!.forEach((verfer: Verfer) => {
634
+ let signer = this.ks.getPris(verfer.qb64, this.decrypter)
635
+ if (signer == undefined) {
636
+ throw new Error(`Missing prikey in db for pubkey=${verfer.qb64}`)
637
+ }
638
+ signers.push(signer)
639
+ })
640
+ }
641
+
642
+ if (indices != undefined && indices.length != signers.length) {
643
+ throw new Error(`Mismatch indices length=${indices.length} and resultant signers length=${signers.length}`)
644
+ }
645
+
646
+ if (ondices != undefined && ondices.length != signers.length) {
647
+ throw new Error(`Mismatch ondices length=${ondices.length} and resultant signers length=${signers.length}`)
648
+ }
649
+
650
+ if (indexed) {
651
+ let sigers = new Array<Siger>()
652
+ signers.forEach((signer, idx) => {
653
+ let i
654
+ if (indices != undefined) {
655
+ i = indices[idx]
656
+ if (i < 0) {
657
+ throw new Error(`Invalid signing index = ${i}, not whole number.`)
658
+ }
659
+ } else {
660
+ i = idx
661
+ }
662
+
663
+ let o
664
+ if (ondices != undefined) {
665
+ o = ondices[idx]
666
+ if (o <= 0) {
667
+ throw new Error(`Invalid other signing index = {o}, not None or not whole number.`)
668
+ }
669
+ } else {
670
+ o = i
671
+ }
672
+
673
+ let only = o == undefined
674
+ sigers.push(signer.sign(ser, i, only, o) as Siger)
675
+ })
676
+ return sigers
677
+ } else {
678
+ let cigars = new Array<Cigar>()
679
+ signers.forEach((signer: Signer) => {
680
+ cigars.push(signer.sign(ser) as Cigar)
681
+ })
682
+
683
+ return cigars
684
+ }
685
+ }
686
+ }
687
+
688
+ export function riKey(pre: string, ridx: number) {
689
+ return pre + "." + ridx.toString(16).padStart(32, '0')
690
+
691
+ }
692
+
693
+ export interface KeyStore {
694
+ getGbls(key: string): string | undefined
695
+ pinGbls(key: string, val: string): void
696
+
697
+ prmsElements(): Array<[string, PrePrm]>
698
+ getPrms(keys: string) :PrePrm | undefined
699
+ pinPrms(keys: string, data: PrePrm): void
700
+ putPrms(keys: string, data: PrePrm): boolean
701
+ remPrms(keys: string): boolean
702
+
703
+ prisElements(decrypter: Decrypter): Array<[string, Signer]>
704
+ getPris(keys: string, decrypter: Decrypter): Signer | undefined
705
+ pinPris(keys: string, data: Signer, encrypter: Encrypter): void
706
+ putPris(pubKey: string, signer: Signer, encrypter: Encrypter): boolean
707
+
708
+ getPres(pre: string): Uint8Array | undefined
709
+ putPres(pre: string, val: Uint8Array): boolean
710
+ pinPres(pre: string, val: Uint8Array): boolean
711
+
712
+ getSits(keys: string) :PreSit | undefined
713
+ putSits(pre: string, val: PreSit): boolean
714
+ pinSits(pre: string, val: PreSit): boolean
715
+ remSits(keys: string): boolean
716
+
717
+ getPubs(keys: string): PubSet | undefined
718
+ putPubs(keys: string, data: PubSet): boolean
719
+ remPubs(keys: string): boolean
720
+ }
721
+
722
+ /*
723
+ In memory test implementation of Keeper key store
724
+ */
725
+ class Keeper implements KeyStore {
726
+ private readonly _gbls: Map<string, string>
727
+ private readonly _pris: Map<string, Uint8Array>
728
+ private readonly _pres: Map<string, Uint8Array>
729
+ private readonly _prms: Map<string, PrePrm>
730
+ private readonly _sits: Map<string, PreSit>
731
+ private readonly _pubs: Map<string, PubSet>
732
+
733
+ constructor() {
734
+ this._gbls = new Map<string, string>()
735
+ this._pris = new Map<string, Uint8Array>()
736
+ this._pres = new Map<string, Uint8Array>()
737
+ this._prms = new Map<string, PrePrm>()
738
+ this._sits = new Map<string, PreSit>()
739
+ this._pubs = new Map<string, PubSet>()
740
+
741
+ }
742
+
743
+ getGbls(key: string): string | undefined {
744
+ return this._gbls.get(key)
745
+ }
746
+
747
+ pinGbls(key: string, val: string): void {
748
+ this._gbls.set(key, val)
749
+ }
750
+
751
+ prmsElements(): Array<[string, PrePrm]> {
752
+ let out = new Array<[string, PrePrm]>()
753
+ this._prms.forEach((value, key) => {
754
+ out.push([key, value])
755
+ })
756
+
757
+ return out
758
+ }
759
+
760
+ getPrms(keys: string) :PrePrm | undefined {
761
+ return this._prms.get(keys)
762
+ }
763
+
764
+ pinPrms(keys: string, data: PrePrm): void {
765
+ this._prms.set(keys, data)
766
+ }
767
+
768
+ putPrms(keys: string, data: PrePrm): boolean {
769
+ if (this._prms.has(keys)) {
770
+ return false
771
+ }
772
+ this._prms.set(keys, data)
773
+ return true
774
+ }
775
+
776
+ remPrms(keys: string): boolean {
777
+ return this._prms.delete(keys)
778
+ }
779
+
780
+ prisElements(decrypter: Decrypter): Array<[string, Signer]> {
781
+ let out = new Array<[string, Signer]>()
782
+ this._pris.forEach(function(val, pubKey) {
783
+ let verfer = new Verfer({qb64: pubKey})
784
+ let signer = decrypter.decrypt(val, null, verfer.transferable)
785
+ out.push([pubKey, signer])
786
+ })
787
+ return out
788
+ }
789
+
790
+ pinPris(pubKey: string, signer: Signer, encrypter: Encrypter): void {
791
+ let cipher = encrypter.encrypt(null, signer)
792
+ this._pris.set(pubKey, cipher.qb64b)
793
+ }
794
+
795
+ putPris(pubKey: string, signer: Signer, encrypter: Encrypter): boolean {
796
+ if (this._pris.has(pubKey)) {
797
+ return false
798
+ }
799
+ let cipher = encrypter.encrypt(null, signer)
800
+ this._pris.set(pubKey, cipher.qb64b)
801
+ return true
802
+ }
803
+
804
+ getPris(pubKey: string, decrypter: Decrypter): Signer | undefined {
805
+ let val = this._pris.get(pubKey)
806
+ if (val == undefined) {
807
+ return undefined
808
+ }
809
+ let verfer = new Verfer({qb64: pubKey})
810
+
811
+
812
+ return decrypter.decrypt(val, null, verfer.transferable)
813
+ }
814
+
815
+ remPris(pubKey: string): void {
816
+ this._pris.delete(pubKey)
817
+ }
818
+
819
+ getPres(pre: string): Uint8Array | undefined {
820
+ return this._pres.get(pre)
821
+ }
822
+
823
+ pinPres(pre: string, val: Uint8Array): boolean {
824
+ this._pres.set(pre, val)
825
+ return true
826
+ }
827
+
828
+ putPres(pre: string, val: Uint8Array): boolean {
829
+ if (this._pres.has(pre)) {
830
+ return false
831
+ }
832
+
833
+ this._pres.set(pre, val)
834
+ return true
835
+ }
836
+
837
+ getSits(keys: string) :PreSit | undefined {
838
+ return this._sits.get(keys)
839
+ }
840
+
841
+ putSits(pre: string, val: PreSit): boolean {
842
+ if (this._sits.has(pre)) {
843
+ return false
844
+ }
845
+
846
+ this._sits.set(pre, val)
847
+ return true
848
+ }
849
+
850
+ pinSits(pre: string, val: PreSit): boolean {
851
+ this._sits.set(pre, val)
852
+ return true
853
+ }
854
+
855
+ remSits(keys: string): boolean {
856
+ return this._sits.delete(keys)
857
+ }
858
+
859
+ getPubs(keys: string): PubSet | undefined {
860
+ return this._pubs.get(keys)
861
+ }
862
+
863
+ putPubs(keys: string, data: PubSet): boolean {
864
+ if (this._pubs.has(keys)) {
865
+ return false
866
+ }
867
+ this._pubs.set(keys, data)
868
+ return true
869
+ }
870
+
871
+ remPubs(keys: string): boolean {
872
+ return this._pubs.delete(keys)
873
+ }
874
+ }