signify-ts 0.3.0 → 0.4.1
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 +18 -0
- package/dist/exports.d.ts +1 -0
- package/dist/exports.js +1 -0
- package/dist/keri/app/aiding.d.ts +20 -5
- package/dist/keri/app/aiding.js +15 -19
- package/dist/keri/app/clienting.d.ts +27 -24
- package/dist/keri/app/clienting.js +86 -92
- package/dist/keri/app/controller.d.ts +4 -1
- package/dist/keri/app/controller.js +7 -3
- package/dist/keri/app/coring.d.ts +8 -1
- package/dist/keri/app/coring.js +11 -0
- package/dist/keri/core/authing.d.ts +24 -5
- package/dist/keri/core/authing.js +188 -15
- package/dist/keri/core/eventing.js +1 -1
- package/dist/keri/core/httping.d.ts +3 -0
- package/dist/keri/core/httping.js +3 -0
- package/dist/keri/core/keeping.d.ts +98 -23
- package/dist/keri/core/keeping.js +124 -22
- package/dist/keri/core/keyState.d.ts +30 -3
- package/dist/keri/core/keyState.js +9 -1
- package/dist/keri/core/manager.d.ts +1 -1
- package/dist/keri/core/manager.js +3 -3
- package/dist/keri/end/ending.js +2 -1
- package/dist/types/keria-api-schema.d.ts +142 -209
- package/dist/types/keria-api-schema.js +5 -0
- package/package.json +5 -5
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import { Signer } from './signer.ts';
|
|
2
2
|
import { Verfer } from './verfer.ts';
|
|
3
|
-
export declare class
|
|
3
|
+
export declare abstract class Authenticator {
|
|
4
|
+
protected verfer: Verfer;
|
|
5
|
+
protected readonly csig: Signer;
|
|
6
|
+
constructor(csig: Signer, verfer: Verfer);
|
|
7
|
+
abstract prepare(request: Request, local: string, remote: string): Promise<Request>;
|
|
8
|
+
abstract verify(request: Request, response: Response, local: string, remote: string): Promise<Response>;
|
|
9
|
+
}
|
|
10
|
+
export declare class SignedHeaderAuthenticator extends Authenticator {
|
|
4
11
|
static DefaultFields: string[];
|
|
5
|
-
|
|
6
|
-
|
|
12
|
+
prepare(request: Request, _local: string, _remote: string): Promise<Request>;
|
|
13
|
+
verify(request: Request, response: Response, _local: string, remote: string): Promise<Response>;
|
|
14
|
+
private verifyHeaders;
|
|
15
|
+
private sign;
|
|
16
|
+
}
|
|
17
|
+
export declare class EssrAuthenticator extends Authenticator {
|
|
18
|
+
private readonly cx25519Pub;
|
|
19
|
+
private readonly cx25519Priv;
|
|
20
|
+
private readonly vx25519Pub;
|
|
7
21
|
constructor(csig: Signer, verfer: Verfer);
|
|
8
|
-
|
|
9
|
-
|
|
22
|
+
prepare(request: Request, local: string, remote: string): Promise<Request>;
|
|
23
|
+
verify(request: Request, response: Response, local: string, remote: string): Promise<Response>;
|
|
24
|
+
static serializeRequest(request: Request): Promise<string>;
|
|
25
|
+
static streamToBytes(stream: ReadableStream): Promise<Uint8Array>;
|
|
26
|
+
private unwrap;
|
|
27
|
+
private decrypt;
|
|
28
|
+
static deserializeResponse(httpString: string): Response;
|
|
10
29
|
}
|
|
@@ -1,16 +1,42 @@
|
|
|
1
|
-
import
|
|
1
|
+
import libsodium from 'libsodium-wrappers-sumo';
|
|
2
|
+
import { desiginput, HEADER_SIG, HEADER_SIG_DESTINATION, HEADER_SIG_INPUT, HEADER_SIG_SENDER, HEADER_SIG_TIME, normalize, siginput, } from "./httping.js";
|
|
2
3
|
import { Signage, signature, designature } from "../end/ending.js";
|
|
3
|
-
|
|
4
|
+
import { Diger } from "./diger.js";
|
|
5
|
+
import { MtrDex } from "./matter.js";
|
|
6
|
+
import { b, d } from "./core.js";
|
|
7
|
+
export class Authenticator {
|
|
4
8
|
constructor(csig, verfer) {
|
|
5
|
-
this.
|
|
6
|
-
this.
|
|
9
|
+
this.csig = csig;
|
|
10
|
+
this.verfer = verfer;
|
|
7
11
|
}
|
|
8
|
-
|
|
12
|
+
}
|
|
13
|
+
export class SignedHeaderAuthenticator extends Authenticator {
|
|
14
|
+
async prepare(request, _local, _remote) {
|
|
15
|
+
const headers = request.headers;
|
|
16
|
+
const signedHeaders = this.sign(request.headers, request.method, new URL(request.url).pathname);
|
|
17
|
+
signedHeaders.forEach((value, key) => {
|
|
18
|
+
headers.set(key, value);
|
|
19
|
+
});
|
|
20
|
+
return request;
|
|
21
|
+
}
|
|
22
|
+
async verify(request, response, _local, remote) {
|
|
23
|
+
if (response.status === 401) {
|
|
24
|
+
throw new Error(`HTTP ${request.method} ${new URL(request.url).pathname} - ${response.status} ${response.statusText}`);
|
|
25
|
+
}
|
|
26
|
+
if (remote !== response.headers.get(HEADER_SIG_SENDER)) {
|
|
27
|
+
throw new Error('message from a different remote agent');
|
|
28
|
+
}
|
|
29
|
+
if (!this.verifyHeaders(response.headers, request.method, new URL(request.url).pathname)) {
|
|
30
|
+
throw new Error('response verification failed');
|
|
31
|
+
}
|
|
32
|
+
return response;
|
|
33
|
+
}
|
|
34
|
+
verifyHeaders(headers, method, path) {
|
|
9
35
|
const siginput = headers.get(HEADER_SIG_INPUT);
|
|
10
36
|
if (siginput == null) {
|
|
11
37
|
return false;
|
|
12
38
|
}
|
|
13
|
-
const signature = headers.get(
|
|
39
|
+
const signature = headers.get(HEADER_SIG);
|
|
14
40
|
if (signature == null) {
|
|
15
41
|
return false;
|
|
16
42
|
}
|
|
@@ -61,24 +87,21 @@ export class Authenticater {
|
|
|
61
87
|
const signage = designature(signature);
|
|
62
88
|
const markers = signage[0].markers;
|
|
63
89
|
const cig = markers.get(input.name);
|
|
64
|
-
if (!cig || !this.
|
|
90
|
+
if (!cig || !this.verfer.verify(cig.raw, ser)) {
|
|
65
91
|
throw new Error(`Signature for ${input.keyid} invalid.`);
|
|
66
92
|
}
|
|
67
93
|
});
|
|
68
94
|
return true;
|
|
69
95
|
}
|
|
70
|
-
sign(headers, method, path
|
|
71
|
-
|
|
72
|
-
fields = Authenticater.DefaultFields;
|
|
73
|
-
}
|
|
74
|
-
const [header, sig] = siginput(this._csig, {
|
|
96
|
+
sign(headers, method, path) {
|
|
97
|
+
const [header, sig] = siginput(this.csig, {
|
|
75
98
|
name: 'signify',
|
|
76
99
|
method,
|
|
77
100
|
path,
|
|
78
101
|
headers,
|
|
79
|
-
fields,
|
|
102
|
+
fields: SignedHeaderAuthenticator.DefaultFields,
|
|
80
103
|
alg: 'ed25519',
|
|
81
|
-
keyid: this.
|
|
104
|
+
keyid: this.csig.verfer.qb64,
|
|
82
105
|
});
|
|
83
106
|
header.forEach((value, key) => {
|
|
84
107
|
headers.append(key, value);
|
|
@@ -93,9 +116,159 @@ export class Authenticater {
|
|
|
93
116
|
return headers;
|
|
94
117
|
}
|
|
95
118
|
}
|
|
96
|
-
|
|
119
|
+
SignedHeaderAuthenticator.DefaultFields = [
|
|
97
120
|
'@method',
|
|
98
121
|
'@path',
|
|
99
122
|
'signify-resource',
|
|
100
123
|
HEADER_SIG_TIME.toLowerCase(),
|
|
101
124
|
];
|
|
125
|
+
export class EssrAuthenticator extends Authenticator {
|
|
126
|
+
constructor(csig, verfer) {
|
|
127
|
+
super(csig, verfer);
|
|
128
|
+
const sigkey = new Uint8Array(this.csig.raw.length + this.csig.verfer.raw.length);
|
|
129
|
+
sigkey.set(this.csig.raw);
|
|
130
|
+
sigkey.set(this.csig.verfer.raw, this.csig.raw.length);
|
|
131
|
+
this.cx25519Priv =
|
|
132
|
+
libsodium.crypto_sign_ed25519_sk_to_curve25519(sigkey);
|
|
133
|
+
this.cx25519Pub = libsodium.crypto_scalarmult_base(this.cx25519Priv);
|
|
134
|
+
this.vx25519Pub = libsodium.crypto_sign_ed25519_pk_to_curve25519(this.verfer.raw);
|
|
135
|
+
}
|
|
136
|
+
async prepare(request, local, remote) {
|
|
137
|
+
const dt = new Date().toISOString().replace('Z', '000+00:00');
|
|
138
|
+
const headers = new Headers();
|
|
139
|
+
headers.set(HEADER_SIG_SENDER, local);
|
|
140
|
+
headers.set(HEADER_SIG_DESTINATION, remote);
|
|
141
|
+
headers.set(HEADER_SIG_TIME, dt);
|
|
142
|
+
headers.set('Content-Type', 'application/octet-stream');
|
|
143
|
+
const requestStr = await EssrAuthenticator.serializeRequest(request);
|
|
144
|
+
const raw = libsodium.crypto_box_seal(requestStr, this.vx25519Pub);
|
|
145
|
+
const diger = new Diger({ code: MtrDex.Blake3_256 }, raw);
|
|
146
|
+
const payload = {
|
|
147
|
+
src: local,
|
|
148
|
+
dest: remote,
|
|
149
|
+
d: diger.qb64,
|
|
150
|
+
dt,
|
|
151
|
+
};
|
|
152
|
+
const sig = this.csig.sign(b(JSON.stringify(payload)));
|
|
153
|
+
const markers = new Map();
|
|
154
|
+
markers.set('signify', sig);
|
|
155
|
+
const signage = new Signage(markers, false);
|
|
156
|
+
const signed = signature([signage]);
|
|
157
|
+
signed.forEach((value, key) => {
|
|
158
|
+
headers.append(key, value);
|
|
159
|
+
});
|
|
160
|
+
return new Request(new URL(request.url).origin + '/', {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
body: raw,
|
|
163
|
+
headers,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
async verify(request, response, local, remote) {
|
|
167
|
+
if (response.status === 401) {
|
|
168
|
+
throw new Error(`HTTP ${request.method} ${new URL(request.url).pathname} - ${response.status} ${response.statusText}`);
|
|
169
|
+
}
|
|
170
|
+
return await this.unwrap(response, remote, local);
|
|
171
|
+
}
|
|
172
|
+
static async serializeRequest(request) {
|
|
173
|
+
let headers = '';
|
|
174
|
+
request.headers.forEach((value, name) => {
|
|
175
|
+
headers += `${name}: ${value}\r\n`;
|
|
176
|
+
});
|
|
177
|
+
let body = '';
|
|
178
|
+
if (request.method !== 'GET' && request.body) {
|
|
179
|
+
const bytes = await this.streamToBytes(request.body);
|
|
180
|
+
try {
|
|
181
|
+
body = new TextDecoder('utf-8', { fatal: true }).decode(bytes);
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
throw new Error('Failed to serialize ESSR request - body is not valid UTF-8', { cause: e });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return `${request.method} ${request.url} HTTP/1.1\r\n${headers}\r\n${body}`;
|
|
188
|
+
}
|
|
189
|
+
static async streamToBytes(stream) {
|
|
190
|
+
const reader = stream.getReader();
|
|
191
|
+
const chunks = [];
|
|
192
|
+
let done, value;
|
|
193
|
+
while ((({ done, value } = await reader.read()), !done)) {
|
|
194
|
+
if (value)
|
|
195
|
+
chunks.push(value);
|
|
196
|
+
}
|
|
197
|
+
reader.releaseLock();
|
|
198
|
+
const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
|
|
199
|
+
const result = new Uint8Array(totalLength);
|
|
200
|
+
let offset = 0;
|
|
201
|
+
for (const chunk of chunks) {
|
|
202
|
+
result.set(chunk, offset);
|
|
203
|
+
offset += chunk.length;
|
|
204
|
+
}
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
async unwrap(wrapper, sender, receiver) {
|
|
208
|
+
const signature = wrapper.headers.get(HEADER_SIG);
|
|
209
|
+
if (!signature) {
|
|
210
|
+
throw new Error('Signature is missing from ESSR payload');
|
|
211
|
+
}
|
|
212
|
+
if (wrapper.headers.get(HEADER_SIG_SENDER) !== sender) {
|
|
213
|
+
throw new Error('Message from a different remote agent');
|
|
214
|
+
}
|
|
215
|
+
if (wrapper.headers.get(HEADER_SIG_DESTINATION) !== receiver) {
|
|
216
|
+
throw new Error('Invalid ESSR payload, missing or incorrect destination prefix');
|
|
217
|
+
}
|
|
218
|
+
const dt = wrapper.headers.get(HEADER_SIG_TIME);
|
|
219
|
+
if (!dt) {
|
|
220
|
+
throw new Error('Timestamp is missing from ESSR payload');
|
|
221
|
+
}
|
|
222
|
+
const ciphertext = new Uint8Array(await wrapper.arrayBuffer());
|
|
223
|
+
const diger = new Diger({ code: MtrDex.Blake3_256 }, ciphertext);
|
|
224
|
+
const payload = {
|
|
225
|
+
src: sender,
|
|
226
|
+
dest: receiver,
|
|
227
|
+
d: diger.qb64,
|
|
228
|
+
dt,
|
|
229
|
+
};
|
|
230
|
+
const signages = designature(signature);
|
|
231
|
+
const markers = signages[0].markers;
|
|
232
|
+
const cig = markers.get('signify');
|
|
233
|
+
if (!cig) {
|
|
234
|
+
throw new Error('Invalid signature format - missing "signify" marker');
|
|
235
|
+
}
|
|
236
|
+
const verified = this.verfer.verify(cig.raw, b(JSON.stringify(payload)));
|
|
237
|
+
if (!verified) {
|
|
238
|
+
throw new Error('Invalid signature');
|
|
239
|
+
}
|
|
240
|
+
const response = EssrAuthenticator.deserializeResponse(d(this.decrypt(ciphertext)));
|
|
241
|
+
if (response.headers.get(HEADER_SIG_SENDER) !== sender) {
|
|
242
|
+
throw new Error('Invalid ESSR payload, missing or incorrect encrypted sender');
|
|
243
|
+
}
|
|
244
|
+
return response;
|
|
245
|
+
}
|
|
246
|
+
// KERIA seals the response to the client key it has in the controller's KEL
|
|
247
|
+
decrypt(ciphertext) {
|
|
248
|
+
try {
|
|
249
|
+
return libsodium.crypto_box_seal_open(ciphertext, this.cx25519Pub, this.cx25519Priv);
|
|
250
|
+
}
|
|
251
|
+
catch (e) {
|
|
252
|
+
throw new Error('Failed to decrypt ESSR response - sealed to a different client key', { cause: e });
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
static deserializeResponse(httpString) {
|
|
256
|
+
const sep = httpString.indexOf('\r\n\r\n');
|
|
257
|
+
const head = sep === -1 ? httpString.trimEnd() : httpString.slice(0, sep);
|
|
258
|
+
const [statusLine, ...headerLines] = head.split('\r\n');
|
|
259
|
+
const [, statusCode, ...statusTextArr] = statusLine.split(' ');
|
|
260
|
+
const body = sep === -1 ? '' : httpString.slice(sep + 4);
|
|
261
|
+
const headers = new Headers();
|
|
262
|
+
for (const line of headerLines) {
|
|
263
|
+
const i = line.indexOf(':');
|
|
264
|
+
if (i !== -1) {
|
|
265
|
+
headers.append(line.slice(0, i).trim(), line.slice(i + 1).trim());
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
return new Response(body.length ? body : null, {
|
|
269
|
+
status: Number(statusCode),
|
|
270
|
+
statusText: statusTextArr.join(' '),
|
|
271
|
+
headers,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -286,7 +286,7 @@ export function messagize(serder, sigers, seal, wigers, cigars, pipelined = fals
|
|
|
286
286
|
atc = concat(atc, new Counter({ code: CtrDex.TransIdxSigGroups, count: 1 })
|
|
287
287
|
.qb64b);
|
|
288
288
|
atc = concat(atc, new TextEncoder().encode(seal[1].i));
|
|
289
|
-
atc = concat(atc, new Seqner({
|
|
289
|
+
atc = concat(atc, new Seqner({ snh: seal[1].s }).qb64b);
|
|
290
290
|
atc = concat(atc, new TextEncoder().encode(seal[1].d));
|
|
291
291
|
}
|
|
292
292
|
else if (seal[0] == 'SealLast') {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { Signer } from './signer.ts';
|
|
2
2
|
import { Cigar } from './cigar.ts';
|
|
3
3
|
import { Siger } from './siger.ts';
|
|
4
|
+
export declare const HEADER_SIG: string;
|
|
4
5
|
export declare const HEADER_SIG_INPUT: string;
|
|
5
6
|
export declare const HEADER_SIG_TIME: string;
|
|
7
|
+
export declare const HEADER_SIG_SENDER: string;
|
|
8
|
+
export declare const HEADER_SIG_DESTINATION: string;
|
|
6
9
|
export declare function normalize(header: string): string;
|
|
7
10
|
export interface SiginputArgs {
|
|
8
11
|
name: string;
|
|
@@ -2,8 +2,11 @@ import { serializeDictionary, parseDictionary, } from 'structured-headers';
|
|
|
2
2
|
import { b } from "./core.js";
|
|
3
3
|
import { nowUTC } from "./utils.js";
|
|
4
4
|
import { encodeBase64Url } from "./base64.js";
|
|
5
|
+
export const HEADER_SIG = normalize('Signature');
|
|
5
6
|
export const HEADER_SIG_INPUT = normalize('Signature-Input');
|
|
6
7
|
export const HEADER_SIG_TIME = normalize('Signify-Timestamp');
|
|
8
|
+
export const HEADER_SIG_SENDER = normalize('Signify-Resource');
|
|
9
|
+
export const HEADER_SIG_DESTINATION = normalize('Signify-Receiver');
|
|
7
10
|
export function normalize(header) {
|
|
8
11
|
return header.trim();
|
|
9
12
|
}
|
|
@@ -46,7 +46,18 @@ export interface IdentifierManager<T extends IdentifierManagerParams = Identifie
|
|
|
46
46
|
params(): T;
|
|
47
47
|
incept(transferable: boolean): Promise<IdentifierManagerResult>;
|
|
48
48
|
rotate(ncodes: string[], transferable: boolean, states?: KeyState[], rstates?: KeyState[]): Promise<IdentifierManagerResult>;
|
|
49
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Sign serialized bytes.
|
|
51
|
+
*
|
|
52
|
+
* `rotated` is meaningful for group identifiers only. Callers building a
|
|
53
|
+
* group rotation must pass `rotated=true` so the group signature exposes
|
|
54
|
+
* prior-next `ondex`; non-rotation calls leave it false/current-only.
|
|
55
|
+
*
|
|
56
|
+
* `ondices === undefined` uses the default dual-index behavior where each
|
|
57
|
+
* `ondex` matches its `index`. `ondices[j] === undefined` is the explicit
|
|
58
|
+
* current-only case for that signature, so no `ondex` is emitted.
|
|
59
|
+
*/
|
|
60
|
+
sign(ser: Uint8Array, indexed?: boolean, indices?: number[], ondices?: Ondex[], rotated?: boolean): Promise<SignResult>;
|
|
50
61
|
}
|
|
51
62
|
/**
|
|
52
63
|
* Creates IdentifierManager instances based on the algorithm and key indexes.
|
|
@@ -102,7 +113,7 @@ export declare class SaltyIdentifierManager implements IdentifierManager {
|
|
|
102
113
|
params(): SaltyManagerParams;
|
|
103
114
|
incept(transferable: boolean): Promise<IdentifierManagerResult>;
|
|
104
115
|
rotate(ncodes: string[], transferable: boolean): Promise<[string[], string[]]>;
|
|
105
|
-
sign(ser: Uint8Array, indexed?: boolean, indices?: number[] | undefined, ondices?:
|
|
116
|
+
sign(ser: Uint8Array, indexed?: boolean, indices?: number[] | undefined, ondices?: Ondex[] | undefined, _rotated?: boolean): Promise<SignResult>;
|
|
106
117
|
}
|
|
107
118
|
export declare class RandyIdentifierManager implements IdentifierManager {
|
|
108
119
|
private salter;
|
|
@@ -126,45 +137,109 @@ export declare class RandyIdentifierManager implements IdentifierManager {
|
|
|
126
137
|
params(): RandyManagerParams;
|
|
127
138
|
incept(transferable: boolean): Promise<IdentifierManagerResult>;
|
|
128
139
|
rotate(ncodes: string[], transferable: boolean): Promise<IdentifierManagerResult>;
|
|
129
|
-
sign(ser: Uint8Array, indexed?: boolean, indices?: number[] | undefined, ondices?:
|
|
140
|
+
sign(ser: Uint8Array, indexed?: boolean, indices?: number[] | undefined, ondices?: Ondex[] | undefined, _rotated?: boolean): Promise<SignResult>;
|
|
130
141
|
}
|
|
142
|
+
type Ondex = number | undefined;
|
|
143
|
+
/**
|
|
144
|
+
* Identifier manager for group identifiers.
|
|
145
|
+
*
|
|
146
|
+
* A group identifier does not have its own private signing keys. Instead, this
|
|
147
|
+
* manager maps group event signing indexes onto the local member AID (`mhab`)
|
|
148
|
+
* and delegates actual signing to that member's key manager.
|
|
149
|
+
*
|
|
150
|
+
* The central invariant is that indexed rotation signatures carry two
|
|
151
|
+
* positions:
|
|
152
|
+
*
|
|
153
|
+
* - `index` points to the signer's current key in the event's current key list
|
|
154
|
+
* (`k`), which SignifyTS derives from `states`.
|
|
155
|
+
* - `ondex` points to the prior establishment event's next digest list (`n`),
|
|
156
|
+
* proving that the current key was a precommitted key.
|
|
157
|
+
*
|
|
158
|
+
* `rstates` are the proposed next digest source for the new event. They are not
|
|
159
|
+
* the signer authorization set for the event being signed.
|
|
160
|
+
*/
|
|
131
161
|
export declare class GroupIdentifierManager implements IdentifierManager {
|
|
162
|
+
/** Factory used to recover the local member keeper that performs signing. */
|
|
132
163
|
private manager;
|
|
164
|
+
/** Local member AID whose private key signs on behalf of the group. */
|
|
133
165
|
private mhab;
|
|
166
|
+
/**
|
|
167
|
+
* Current group signing public keys for the event being built. During
|
|
168
|
+
* rotation these come from `states[*].k[0]` and define signature `index`.
|
|
169
|
+
*/
|
|
134
170
|
private gkeys;
|
|
171
|
+
/**
|
|
172
|
+
* Proposed next digest list for the event being built. During rotation
|
|
173
|
+
* these come from `rstates[*].n[0]`, are returned from `rotate()`, and are
|
|
174
|
+
* serialized as `group.ndigs`.
|
|
175
|
+
*/
|
|
135
176
|
private gdigs;
|
|
177
|
+
/**
|
|
178
|
+
* Prior next digest list from the current group establishment event. For
|
|
179
|
+
* rotations, this is the authorization commitment set used to derive
|
|
180
|
+
* `ondex`; it must remain separate from proposed next digests in `gdigs`.
|
|
181
|
+
*/
|
|
182
|
+
private gpndigs;
|
|
136
183
|
algo: Algos;
|
|
184
|
+
/**
|
|
185
|
+
* Retained for the `IdentifierManager` interface. Group signing delegates
|
|
186
|
+
* to the local member AID keeper instead of storing signers here.
|
|
187
|
+
*/
|
|
137
188
|
signers: Signer[];
|
|
189
|
+
/**
|
|
190
|
+
* Creates a manager for either a new group event or an existing group AID.
|
|
191
|
+
*
|
|
192
|
+
* `states` and `rstates` are app-level key state records used when creating
|
|
193
|
+
* a new group event. `keys` and `ndigs` are persisted group manager params
|
|
194
|
+
* used when loading an existing group. For an existing group, `ndigs` is
|
|
195
|
+
* expected to be the current establishment event's next digest list.
|
|
196
|
+
*
|
|
197
|
+
* During group inception there is no separate prior establishment event, so
|
|
198
|
+
* `gpndigs` starts as the same digest list as `gdigs`. During rotation,
|
|
199
|
+
* `gdigs` changes to the proposed next digests, while `gpndigs` stays
|
|
200
|
+
* fixed for `ondex` derivation.
|
|
201
|
+
*/
|
|
138
202
|
constructor(manager: IdentifierManagerFactory, mhab: HabState, states?: KeyState[] | undefined, rstates?: KeyState[] | undefined, keys?: string[], ndigs?: string[]);
|
|
203
|
+
/**
|
|
204
|
+
* Returns the inception key material for the group event.
|
|
205
|
+
*
|
|
206
|
+
* Inception has no prior group establishment event. The current keys and
|
|
207
|
+
* proposed next digests are therefore returned directly from the manager's
|
|
208
|
+
* configured `states` and `rstates`.
|
|
209
|
+
*/
|
|
139
210
|
incept(): Promise<IdentifierManagerResult>;
|
|
140
211
|
/**
|
|
141
|
-
* Performs a multisig rotation
|
|
212
|
+
* Performs a multisig rotation.
|
|
213
|
+
*
|
|
214
|
+
* `states` supplies the current group signing keys for the event being
|
|
215
|
+
* signed. `rstates` supplies the proposed next key digests to put in the
|
|
216
|
+
* new event. The prior next digests used for rotation `ondex` lookup stay
|
|
217
|
+
* unchanged until KERIA accepts the new establishment event and returns an
|
|
218
|
+
* updated group state.
|
|
219
|
+
*
|
|
142
220
|
* @param _ncodes
|
|
143
221
|
* @param _transferable
|
|
144
222
|
* @param states
|
|
145
|
-
* @param rstates
|
|
146
|
-
* You should pass in the current key
|
|
223
|
+
* @param rstates
|
|
147
224
|
*/
|
|
148
225
|
rotate(_ncodes: string[], _transferable: boolean, states: KeyState[], rstates: KeyState[]): Promise<IdentifierManagerResult>;
|
|
149
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Signs for the group by delegating to the local member keeper.
|
|
228
|
+
*/
|
|
229
|
+
sign(ser: Uint8Array, indexed?: boolean, _indices?: number[] | undefined, _ondices?: Ondex[] | undefined, rotated?: boolean): Promise<SignResult>;
|
|
230
|
+
/**
|
|
231
|
+
* Finds the prior next digest position that precommitted the current key.
|
|
232
|
+
*
|
|
233
|
+
* This mirrors KERIpy's exposed-prior-next behavior: for each prior next
|
|
234
|
+
* digest, hash the current verifier key using that digest's code and compare
|
|
235
|
+
* the result to the digest at that position. A match means the signer has
|
|
236
|
+
* exposed that precommitted key, and the matching position is the `ondex`.
|
|
237
|
+
*/
|
|
238
|
+
private priorNextIndexForKey;
|
|
150
239
|
params(): {
|
|
151
|
-
mhab:
|
|
152
|
-
name: string;
|
|
153
|
-
prefix: string;
|
|
154
|
-
icp_dt: string;
|
|
155
|
-
state: import("../../types/keria-api-schema.ts").components["schemas"]["KeyStateRecord"];
|
|
156
|
-
transferable: boolean;
|
|
157
|
-
windexes: string[];
|
|
158
|
-
} & ({
|
|
159
|
-
salty: import("../../types/keria-api-schema.ts").components["schemas"]["SaltyState"];
|
|
160
|
-
} | {
|
|
161
|
-
randy: import("../../types/keria-api-schema.ts").components["schemas"]["RandyKeyState"];
|
|
162
|
-
} | {
|
|
163
|
-
group: import("../../types/keria-api-schema.ts").components["schemas"]["GroupKeyState"];
|
|
164
|
-
} | {
|
|
165
|
-
extern: import("../../types/keria-api-schema.ts").components["schemas"]["ExternState"];
|
|
166
|
-
});
|
|
240
|
+
mhab: HabState;
|
|
167
241
|
keys: string[];
|
|
168
242
|
ndigs: string[];
|
|
169
243
|
};
|
|
170
244
|
}
|
|
245
|
+
export {};
|