signify-ts 0.1.0 → 0.2.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.
- package/README.md +101 -5
- package/dist/buffer-polyfill.d.ts +1 -0
- package/dist/exports.d.ts +40 -0
- package/dist/index.d.ts +4 -1
- package/dist/keri/app/aiding.d.ts +138 -0
- package/dist/keri/app/clienting.d.ts +182 -0
- package/dist/keri/app/contacting.d.ts +93 -0
- package/dist/keri/app/controller.d.ts +49 -0
- package/dist/keri/app/coring.d.ts +121 -0
- package/dist/keri/app/credentialing.d.ts +239 -0
- package/dist/keri/app/escrowing.d.ts +19 -0
- package/dist/keri/app/exchanging.d.ts +60 -0
- package/dist/keri/app/grouping.d.ts +44 -0
- package/dist/keri/app/habery.d.ts +48 -0
- package/dist/keri/app/notifying.d.ts +34 -0
- package/dist/keri/core/authing.d.ts +10 -0
- package/dist/keri/core/bexter.d.ts +7 -0
- package/dist/keri/core/cigar.d.ts +8 -8
- package/dist/keri/core/cipher.d.ts +5 -5
- package/dist/keri/core/core.d.ts +59 -68
- package/dist/keri/core/counter.d.ts +43 -0
- package/dist/keri/core/decrypter.d.ts +10 -10
- package/dist/keri/core/diger.d.ts +21 -21
- package/dist/keri/core/encrypter.d.ts +9 -9
- package/dist/keri/core/eventing.d.ts +54 -0
- package/dist/keri/core/httping.d.ts +44 -0
- package/dist/keri/core/indexer.d.ts +98 -88
- package/dist/keri/core/keeping.d.ts +103 -1
- package/dist/keri/core/kering.d.ts +5 -5
- package/dist/keri/core/manager.d.ts +174 -151
- package/dist/keri/core/matter.d.ts +116 -47
- package/dist/keri/core/number.d.ts +7 -0
- package/dist/keri/core/pather.d.ts +7 -0
- package/dist/keri/core/prefixer.d.ts +15 -0
- package/dist/keri/core/saider.d.ts +23 -0
- package/dist/keri/core/salter.d.ts +23 -0
- package/dist/keri/core/seqner.d.ts +15 -0
- package/dist/keri/core/serder.d.ts +31 -0
- package/dist/keri/core/siger.d.ts +18 -18
- package/dist/keri/core/signer.d.ts +34 -34
- package/dist/keri/core/tholder.d.ts +29 -0
- package/dist/keri/core/utils.d.ts +20 -14
- package/dist/keri/core/vdring.d.ts +16 -0
- package/dist/keri/core/verfer.d.ts +13 -0
- package/dist/keri/end/ending.d.ts +13 -0
- package/dist/math.d.ts +1 -0
- package/dist/ready.d.ts +1 -0
- package/dist/signify-ts.cjs +7835 -0
- package/dist/signify-ts.cjs.development.js +9493 -5
- package/dist/signify-ts.cjs.development.js.map +1 -1
- package/dist/signify-ts.cjs.map +7 -0
- package/dist/signify-ts.cjs.production.min.js +1 -1
- package/dist/signify-ts.cjs.production.min.js.map +1 -1
- package/dist/signify-ts.esm.js +9341 -5
- package/dist/signify-ts.esm.js.map +1 -1
- package/dist/signify-ts.mjs +7811 -0
- package/dist/signify-ts.mjs.map +7 -0
- package/package.json +51 -49
- package/src/buffer-polyfill.ts +5 -0
- package/src/exports.ts +44 -0
- package/src/index.ts +4 -6
- package/src/keri/app/aiding.ts +493 -0
- package/src/keri/app/clienting.ts +492 -0
- package/src/keri/app/contacting.ts +188 -0
- package/src/keri/app/controller.ts +372 -0
- package/src/keri/app/coring.ts +225 -0
- package/src/keri/app/credentialing.ts +820 -0
- package/src/keri/app/escrowing.ts +34 -0
- package/src/keri/app/exchanging.ts +220 -0
- package/src/keri/app/grouping.ts +90 -0
- package/src/keri/app/habery.ts +185 -0
- package/src/keri/app/notifying.ts +69 -0
- package/src/keri/core/authing.ts +117 -0
- package/src/keri/core/bexter.ts +138 -0
- package/src/keri/core/cigar.ts +11 -12
- package/src/keri/core/cipher.ts +23 -14
- package/src/keri/core/core.ts +249 -97
- package/src/keri/core/counter.ts +273 -0
- package/src/keri/core/decrypter.ts +48 -34
- package/src/keri/core/diger.ts +25 -24
- package/src/keri/core/encrypter.ts +37 -27
- package/src/keri/core/eventing.ts +581 -0
- package/src/keri/core/httping.ts +209 -0
- package/src/keri/core/indexer.ts +314 -211
- package/src/keri/core/keeping.ts +679 -4
- package/src/keri/core/kering.ts +4 -6
- package/src/keri/core/manager.ts +759 -450
- package/src/keri/core/matter.ts +404 -135
- package/src/keri/core/number.ts +66 -0
- package/src/keri/core/pather.ts +98 -0
- package/src/keri/core/prefixer.ts +233 -0
- package/src/keri/core/saider.ts +186 -0
- package/src/keri/core/salter.ts +76 -41
- package/src/keri/core/seqner.ts +46 -0
- package/src/keri/core/serder.ts +163 -0
- package/src/keri/core/siger.ts +19 -18
- package/src/keri/core/signer.ts +74 -53
- package/src/keri/core/tholder.ts +218 -0
- package/src/keri/core/utils.ts +120 -45
- package/src/keri/core/vdring.ts +94 -0
- package/src/keri/core/verfer.ts +25 -11
- package/src/keri/end/ending.ts +170 -0
- package/src/math.ts +3 -0
- package/src/ready.ts +5 -0
- package/src/keri/core/tsconfig.json +0 -100
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { BexDex, Matter, NumDex } from './matter';
|
|
2
|
+
import { CesrNumber } from './number';
|
|
3
|
+
import { Fraction } from 'mathjs';
|
|
4
|
+
import { math } from '../../index';
|
|
5
|
+
|
|
6
|
+
export class Tholder {
|
|
7
|
+
private _weighted: boolean = false;
|
|
8
|
+
private _thold: any = undefined;
|
|
9
|
+
private _size: number = 0;
|
|
10
|
+
private _number: CesrNumber | undefined = undefined;
|
|
11
|
+
private _satisfy: any = undefined;
|
|
12
|
+
|
|
13
|
+
// private _bexter: any
|
|
14
|
+
|
|
15
|
+
constructor(kargs: { thold?: any; limen?: any; sith?: any }) {
|
|
16
|
+
if (kargs.thold !== undefined) {
|
|
17
|
+
this._processThold(kargs.thold);
|
|
18
|
+
} else if (kargs.limen != undefined) {
|
|
19
|
+
this._processLimen(kargs.limen);
|
|
20
|
+
} else if (kargs.sith !== undefined) {
|
|
21
|
+
this._processSith(kargs.sith);
|
|
22
|
+
} else {
|
|
23
|
+
throw new Error('Missing threshold expression');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get weighted(): boolean {
|
|
28
|
+
return this._weighted;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get thold(): any {
|
|
32
|
+
return this._thold;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
get size(): number {
|
|
36
|
+
return this._size;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get limen(): any {
|
|
40
|
+
return this._number?.qb64b;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get sith(): string {
|
|
44
|
+
if (this.weighted) {
|
|
45
|
+
let sith = this.thold.map((clause: Fraction[]) => {
|
|
46
|
+
return clause.map((c) => {
|
|
47
|
+
if (0 < Number(c) && Number(c) < 1) {
|
|
48
|
+
return math.format(c, { fraction: 'ratio' });
|
|
49
|
+
} else {
|
|
50
|
+
return math.format(c, { fraction: 'decimal' });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
if (sith.length == 1) {
|
|
55
|
+
sith = sith[0];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return sith;
|
|
59
|
+
} else {
|
|
60
|
+
return this.thold.toString(16);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get json(): string {
|
|
65
|
+
return JSON.stringify(this.sith);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get num(): number | undefined {
|
|
69
|
+
return this._weighted ? undefined : this._thold;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private _processThold(thold: number | Array<Array<Fraction>>) {
|
|
73
|
+
if (typeof thold === 'number') {
|
|
74
|
+
this._processUnweighted(thold);
|
|
75
|
+
} else {
|
|
76
|
+
this._processWeighted(thold);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private _processLimen(limen: string) {
|
|
81
|
+
const matter = new Matter({ qb64: limen });
|
|
82
|
+
if (NumDex.has(matter.code)) {
|
|
83
|
+
const number = new CesrNumber({
|
|
84
|
+
raw: matter.raw,
|
|
85
|
+
code: matter.code,
|
|
86
|
+
});
|
|
87
|
+
this._processUnweighted(number.num);
|
|
88
|
+
} else if (BexDex.has(matter.code)) {
|
|
89
|
+
// TODO: Implement Bexter
|
|
90
|
+
} else {
|
|
91
|
+
throw new Error('Invalid code for limen=' + matter.code);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
private _processSith(sith: string | number | Array<string>) {
|
|
96
|
+
if (typeof sith == 'number') {
|
|
97
|
+
this._processUnweighted(sith);
|
|
98
|
+
} else if (typeof sith == 'string' && sith.indexOf('[') == -1) {
|
|
99
|
+
this._processUnweighted(parseInt(sith, 16));
|
|
100
|
+
} else {
|
|
101
|
+
let _sith: any = sith;
|
|
102
|
+
if (typeof sith == 'string') {
|
|
103
|
+
_sith = JSON.parse(sith);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (_sith.length == 0) {
|
|
107
|
+
throw new Error('Empty weight list');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const mask = _sith.map((x: any) => {
|
|
111
|
+
return typeof x !== 'string';
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (mask.length > 0 && !mask.every((x: boolean) => x)) {
|
|
115
|
+
_sith = [_sith];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
for (const c of _sith) {
|
|
119
|
+
const mask = c.map((x: any) => {
|
|
120
|
+
return typeof x === 'string';
|
|
121
|
+
});
|
|
122
|
+
if (mask.length > 0 && !mask.every((x: boolean) => x)) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
'Invalid sith, some weights in clause ' +
|
|
125
|
+
mask +
|
|
126
|
+
' are non string'
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const thold = this._processClauses(_sith);
|
|
132
|
+
this._processWeighted(thold);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
private _processClauses(sith: Array<Array<string>>): Fraction[][] {
|
|
137
|
+
const thold = new Array<Array<Fraction>>();
|
|
138
|
+
sith.forEach((clause) => {
|
|
139
|
+
thold.push(
|
|
140
|
+
clause.map((w) => {
|
|
141
|
+
return this.weight(w);
|
|
142
|
+
})
|
|
143
|
+
);
|
|
144
|
+
});
|
|
145
|
+
return thold;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private _processUnweighted(thold: number) {
|
|
149
|
+
if (thold < 0) {
|
|
150
|
+
throw new Error('Non-positive int threshold = {thold}.');
|
|
151
|
+
}
|
|
152
|
+
this._thold = thold;
|
|
153
|
+
this._weighted = false;
|
|
154
|
+
this._size = this._thold; // used to verify that keys list size is at least size
|
|
155
|
+
this._satisfy = this._satisfy_numeric;
|
|
156
|
+
this._number = new CesrNumber({}, thold);
|
|
157
|
+
// this._bexter = undefined
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private _processWeighted(thold: Array<Array<Fraction>>) {
|
|
161
|
+
for (const clause of thold) {
|
|
162
|
+
if (Number(math.sum(clause)) < 1) {
|
|
163
|
+
throw new Error(
|
|
164
|
+
'Invalid sith clause: ' +
|
|
165
|
+
thold +
|
|
166
|
+
'all clause weight sums must be >= 1'
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
this._thold = thold;
|
|
172
|
+
this._weighted = true;
|
|
173
|
+
this._size = thold.reduce((acc, currentValue) => {
|
|
174
|
+
return acc + currentValue.length;
|
|
175
|
+
}, 0);
|
|
176
|
+
this._satisfy = this._satisfy_weighted;
|
|
177
|
+
//TODO: created Bexter if needed
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private weight(w: string): Fraction {
|
|
181
|
+
return math.fraction(w);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
private _satisfy_numeric(indices: any[]) {
|
|
185
|
+
return this.thold > 0 && indices.length >= this.thold; // at least one
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
private _satisfy_weighted(indices: any) {
|
|
189
|
+
if (indices.length === 0) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const indexes: Set<number> = new Set(indices.sort());
|
|
194
|
+
const sats = new Array(indices.length).fill(false);
|
|
195
|
+
for (const idx of indexes) {
|
|
196
|
+
sats[idx] = true;
|
|
197
|
+
}
|
|
198
|
+
let wio = 0;
|
|
199
|
+
for (const clause of this.thold) {
|
|
200
|
+
let cw = 0;
|
|
201
|
+
for (const w of clause) {
|
|
202
|
+
if (sats[wio]) {
|
|
203
|
+
cw += Number(w);
|
|
204
|
+
}
|
|
205
|
+
wio += 1;
|
|
206
|
+
}
|
|
207
|
+
if (cw < 1) {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public satisfy(indices: any): boolean {
|
|
216
|
+
return this._satisfy(indices);
|
|
217
|
+
}
|
|
218
|
+
}
|
package/src/keri/core/utils.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { Counter, CtrDex } from './counter';
|
|
2
|
+
import { Seqner } from './seqner';
|
|
3
|
+
import { Prefixer } from './prefixer';
|
|
4
|
+
import { Saider } from './saider';
|
|
5
|
+
import { Serder } from './serder';
|
|
6
|
+
import { b } from './core';
|
|
1
7
|
|
|
2
8
|
export function pad(n: any, width = 3, z = 0) {
|
|
3
|
-
|
|
9
|
+
return (String(z).repeat(width) + String(n)).slice(String(n).length);
|
|
4
10
|
}
|
|
5
11
|
|
|
6
12
|
/**
|
|
@@ -11,19 +17,19 @@ export function pad(n: any, width = 3, z = 0) {
|
|
|
11
17
|
* @param {*} labels labels is list of element labels in ked from which to extract values
|
|
12
18
|
*/
|
|
13
19
|
export function extractValues(ked: any, labels: any) {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
20
|
+
let values = [];
|
|
21
|
+
for (const label of labels) {
|
|
22
|
+
values = extractElementValues(ked[label], values);
|
|
23
|
+
}
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
return values;
|
|
20
26
|
}
|
|
21
27
|
|
|
22
28
|
export function arrayEquals(ar1: Uint8Array, ar2: Uint8Array) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
return (
|
|
30
|
+
ar1.length === ar2.length &&
|
|
31
|
+
ar1.every((val, index) => val === ar2[index])
|
|
32
|
+
);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
/**
|
|
@@ -36,27 +42,22 @@ export function arrayEquals(ar1: Uint8Array, ar2: Uint8Array) {
|
|
|
36
42
|
*/
|
|
37
43
|
|
|
38
44
|
function extractElementValues(element: any, values: any) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
let data = [];
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
if (element instanceof Array && !(typeof element == 'string')) {
|
|
49
|
+
for (const k in element) extractElementValues(element[k], values);
|
|
50
|
+
} else if (typeof element == 'string') {
|
|
51
|
+
values.push(element);
|
|
52
|
+
}
|
|
53
|
+
data = values;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
throw new Error(error as string);
|
|
48
56
|
}
|
|
49
|
-
data = values;
|
|
50
|
-
} catch (error:any) {
|
|
51
|
-
throw new Error(error);
|
|
52
|
-
}
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
return data;
|
|
55
59
|
}
|
|
56
60
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
61
|
/**
|
|
61
62
|
* @description Returns True if obj is non-string iterable, False otherwise
|
|
62
63
|
|
|
@@ -68,27 +69,101 @@ function extractElementValues(element: any, values: any) {
|
|
|
68
69
|
// return instanceof(obj, (str, bytes)) && instanceof(obj, Iterable))
|
|
69
70
|
// }
|
|
70
71
|
|
|
72
|
+
export function nowUTC(): Date {
|
|
73
|
+
return new Date();
|
|
74
|
+
}
|
|
71
75
|
|
|
76
|
+
export function range(start: number, stop: number, step: number) {
|
|
77
|
+
if (typeof stop == 'undefined') {
|
|
78
|
+
// one param defined
|
|
79
|
+
stop = start;
|
|
80
|
+
start = 0;
|
|
81
|
+
}
|
|
72
82
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
stop = start;
|
|
77
|
-
start = 0;
|
|
78
|
-
}
|
|
83
|
+
if (typeof step == 'undefined') {
|
|
84
|
+
step = 1;
|
|
85
|
+
}
|
|
79
86
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
83
90
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
const result = new Array<number>();
|
|
92
|
+
for (let i: number = start; step > 0 ? i < stop : i > stop; i += step) {
|
|
93
|
+
result.push(i);
|
|
94
|
+
}
|
|
87
95
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
result.push(i);
|
|
91
|
-
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
92
98
|
|
|
93
|
-
|
|
94
|
-
|
|
99
|
+
export function intToBytes(value: number, length: number): Uint8Array {
|
|
100
|
+
const byteArray = new Uint8Array(length); // Assuming a 4-byte integer (32 bits)
|
|
101
|
+
|
|
102
|
+
for (let index = byteArray.length - 1; index >= 0; index--) {
|
|
103
|
+
const byte = value & 0xff;
|
|
104
|
+
byteArray[index] = byte;
|
|
105
|
+
value = (value - byte) / 256;
|
|
106
|
+
}
|
|
107
|
+
return byteArray;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function bytesToInt(ar: Uint8Array): number {
|
|
111
|
+
let value = 0;
|
|
112
|
+
for (let i = 0; i < ar.length; i++) {
|
|
113
|
+
value = value * 256 + ar[i];
|
|
114
|
+
}
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function serializeACDCAttachment(anc: Serder): Uint8Array {
|
|
119
|
+
const prefixer = new Prefixer({ qb64: anc.pre });
|
|
120
|
+
const seqner = new Seqner({ sn: anc.sn });
|
|
121
|
+
const saider = new Saider({ qb64: anc.ked['d'] });
|
|
122
|
+
const craw = new Uint8Array();
|
|
123
|
+
const ctr = new Counter({ code: CtrDex.SealSourceTriples, count: 1 }).qb64b;
|
|
124
|
+
const prefix = prefixer.qb64b;
|
|
125
|
+
const seq = seqner.qb64b;
|
|
126
|
+
const said = saider.qb64b;
|
|
127
|
+
const newCraw = new Uint8Array(
|
|
128
|
+
craw.length + ctr.length + prefix.length + seq.length + said.length
|
|
129
|
+
);
|
|
130
|
+
newCraw.set(craw);
|
|
131
|
+
newCraw.set(ctr, craw.length);
|
|
132
|
+
newCraw.set(prefix, craw.length + ctr.length);
|
|
133
|
+
newCraw.set(seq, craw.length + ctr.length + prefix.length);
|
|
134
|
+
newCraw.set(said, craw.length + ctr.length + prefix.length + seq.length);
|
|
135
|
+
return newCraw;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function serializeIssExnAttachment(anc: Serder): Uint8Array {
|
|
139
|
+
const seqner = new Seqner({ sn: anc.sn });
|
|
140
|
+
const ancSaider = new Saider({ qb64: anc.ked['d'] });
|
|
141
|
+
const coupleArray = new Uint8Array(
|
|
142
|
+
seqner.qb64b.length + ancSaider.qb64b.length
|
|
143
|
+
);
|
|
144
|
+
coupleArray.set(seqner.qb64b);
|
|
145
|
+
coupleArray.set(ancSaider.qb64b, seqner.qb64b.length);
|
|
146
|
+
const counter = new Counter({
|
|
147
|
+
code: CtrDex.SealSourceCouples,
|
|
148
|
+
count: 1,
|
|
149
|
+
});
|
|
150
|
+
const counterQb64b = counter.qb64b;
|
|
151
|
+
const atc = new Uint8Array(counter.qb64b.length + coupleArray.length);
|
|
152
|
+
atc.set(counterQb64b);
|
|
153
|
+
atc.set(coupleArray, counterQb64b.length);
|
|
154
|
+
|
|
155
|
+
if (atc.length % 4 !== 0) {
|
|
156
|
+
throw new Error(
|
|
157
|
+
`Invalid attachments size: ${atc.length}, non-integral quadlets detected.`
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
const pcnt = new Counter({
|
|
161
|
+
code: CtrDex.AttachedMaterialQuadlets,
|
|
162
|
+
count: Math.floor(atc.length / 4),
|
|
163
|
+
});
|
|
164
|
+
const msg = new Uint8Array(pcnt.qb64b.length + atc.length);
|
|
165
|
+
msg.set(pcnt.qb64b);
|
|
166
|
+
msg.set(atc, pcnt.qb64b.length);
|
|
167
|
+
|
|
168
|
+
return msg;
|
|
169
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { randomNonce } from '../app/coring';
|
|
2
|
+
import { TraitDex } from '../app/habery';
|
|
3
|
+
import {
|
|
4
|
+
Serials,
|
|
5
|
+
Versionage,
|
|
6
|
+
Version,
|
|
7
|
+
Ident,
|
|
8
|
+
versify,
|
|
9
|
+
Ilks,
|
|
10
|
+
} from '../core/core';
|
|
11
|
+
import { ample } from './eventing';
|
|
12
|
+
import { MtrDex } from './matter';
|
|
13
|
+
import { Prefixer } from './prefixer';
|
|
14
|
+
import { Serder } from './serder';
|
|
15
|
+
|
|
16
|
+
namespace vdr {
|
|
17
|
+
export interface VDRInceptArgs {
|
|
18
|
+
pre: string;
|
|
19
|
+
toad?: number | string;
|
|
20
|
+
nonce?: string;
|
|
21
|
+
baks?: string[];
|
|
22
|
+
cnfg?: string[];
|
|
23
|
+
version?: Version;
|
|
24
|
+
kind?: Serials;
|
|
25
|
+
code?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function incept({
|
|
29
|
+
pre,
|
|
30
|
+
toad,
|
|
31
|
+
nonce = randomNonce(),
|
|
32
|
+
baks = [],
|
|
33
|
+
cnfg = [],
|
|
34
|
+
version = Versionage,
|
|
35
|
+
kind = Serials.JSON,
|
|
36
|
+
code = MtrDex.Blake3_256,
|
|
37
|
+
}: VDRInceptArgs): Serder {
|
|
38
|
+
const vs = versify(Ident.KERI, version, kind, 0);
|
|
39
|
+
const isn = 0;
|
|
40
|
+
const ilk = Ilks.vcp;
|
|
41
|
+
|
|
42
|
+
if (cnfg.includes(TraitDex.NoBackers) && baks.length > 0) {
|
|
43
|
+
throw new Error(
|
|
44
|
+
`${baks.length} backers specified for NB vcp, 0 allowed`
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (new Set(baks).size < baks.length) {
|
|
49
|
+
throw new Error(`Invalid baks ${baks} has duplicates`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
let _toad: number;
|
|
53
|
+
if (toad === undefined) {
|
|
54
|
+
if (baks.length === 0) {
|
|
55
|
+
_toad = 0;
|
|
56
|
+
} else {
|
|
57
|
+
_toad = ample(baks.length);
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
_toad = +toad;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (baks.length > 0) {
|
|
64
|
+
if (_toad < 1 || _toad > baks.length) {
|
|
65
|
+
throw new Error(`Invalid toad ${_toad} for baks in ${baks}`);
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
if (_toad != 0) {
|
|
69
|
+
throw new Error(`Invalid toad ${_toad} for no baks`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const ked = {
|
|
74
|
+
v: vs,
|
|
75
|
+
t: ilk,
|
|
76
|
+
d: '',
|
|
77
|
+
i: '',
|
|
78
|
+
ii: pre,
|
|
79
|
+
s: '' + isn,
|
|
80
|
+
c: cnfg,
|
|
81
|
+
bt: _toad.toString(16),
|
|
82
|
+
b: baks,
|
|
83
|
+
n: nonce,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const prefixer = new Prefixer({ code }, ked);
|
|
87
|
+
ked.i = prefixer.qb64;
|
|
88
|
+
ked.d = prefixer.qb64;
|
|
89
|
+
|
|
90
|
+
return new Serder(ked);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export { vdr };
|
package/src/keri/core/verfer.ts
CHANGED
|
@@ -1,33 +1,47 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
2
|
+
import libsodium from 'libsodium-wrappers-sumo';
|
|
3
|
+
import { Matter, MatterArgs, MtrDex } from './matter';
|
|
4
|
+
import secp256r1 from 'ecdsa-secp256r1';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @description Verfer :sublclass of Matter,helps to verify signature of serialization
|
|
8
8
|
* using .raw as verifier key and .code as signature cypher suite
|
|
9
9
|
*/
|
|
10
10
|
export class Verfer extends Matter {
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
private readonly _verify: (sig: any, ser: any, key: any) => boolean;
|
|
12
|
+
constructor({ raw, code, qb64, qb64b, qb2 }: MatterArgs) {
|
|
13
|
+
super({ raw, code, qb64, qb64b, qb2 });
|
|
13
14
|
|
|
14
15
|
if (Array.from([MtrDex.Ed25519N, MtrDex.Ed25519]).includes(this.code)) {
|
|
15
|
-
this._verify = this._ed25519
|
|
16
|
+
this._verify = this._ed25519;
|
|
17
|
+
} else if (
|
|
18
|
+
Array.from([MtrDex.ECDSA_256r1N, MtrDex.ECDSA_256r1]).includes(
|
|
19
|
+
this.code
|
|
20
|
+
)
|
|
21
|
+
) {
|
|
22
|
+
this._verify = this._secp256r1;
|
|
16
23
|
} else {
|
|
17
|
-
throw new Error(`Unsupported code = ${this.code} for verifier.`)
|
|
24
|
+
throw new Error(`Unsupported code = ${this.code} for verifier.`);
|
|
18
25
|
}
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
verify(sig: any, ser: any) {
|
|
22
|
-
return this._verify(sig, ser, this.raw)
|
|
29
|
+
return this._verify(sig, ser, this.raw);
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
_ed25519(sig: any, ser: any, key: any) {
|
|
26
33
|
try {
|
|
27
34
|
return libsodium.crypto_sign_verify_detached(sig, ser, key);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw new Error(error as string);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
_secp256r1(sig: any, ser: any, key: any) {
|
|
40
|
+
try {
|
|
41
|
+
const publicKey = secp256r1.fromCompressedPublicKey(key);
|
|
42
|
+
return publicKey.verify(ser, sig);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
throw new Error(error as string);
|
|
31
45
|
}
|
|
32
46
|
}
|
|
33
47
|
}
|