@icp-sdk/vetkeys 0.5.0 → 0.7.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.
@@ -0,0 +1,901 @@
1
+ import { bls12_381 as i } from "@noble/curves/bls12-381";
2
+ import { shake256 as Z } from "@noble/hashes/sha3";
3
+ import { hkdf as $ } from "@noble/hashes/hkdf";
4
+ import { sha256 as tt } from "@noble/hashes/sha2";
5
+ const l = 48, a = 96;
6
+ class x {
7
+ #t;
8
+ #e;
9
+ /**
10
+ * Create a random transport secret key
11
+ */
12
+ static random() {
13
+ return new x(i.utils.randomSecretKey());
14
+ }
15
+ /**
16
+ * Deserialize TransportSecretKey from a bytestring
17
+ *
18
+ * The passed value would typically be a string previously returned
19
+ * by calling serialize on a randomly-created TransportSecretKey.
20
+ */
21
+ static deserialize(t) {
22
+ if (t.length !== 32)
23
+ throw new Error("Invalid size for transport secret key");
24
+ return new x(t);
25
+ }
26
+ /**
27
+ * Return the encoding of the transport public key; this value is
28
+ * sent to the IC
29
+ */
30
+ publicKeyBytes() {
31
+ return this.#e.toBytes(!0);
32
+ }
33
+ /**
34
+ * Return the transport secret key value
35
+ *
36
+ * Applications would not normally need to call this
37
+ */
38
+ serialize() {
39
+ return this.#t;
40
+ }
41
+ /**
42
+ * @internal constructor
43
+ */
44
+ constructor(t) {
45
+ this.#t = t;
46
+ const e = i.G1.Point.BASE.multiply(
47
+ i.G1.Point.Fn.fromBytes(this.#t)
48
+ );
49
+ this.#e = e;
50
+ }
51
+ }
52
+ function lt(n) {
53
+ if (n.length != 48)
54
+ return !1;
55
+ try {
56
+ return i.G1.Point.fromHex(n), !0;
57
+ } catch {
58
+ return !1;
59
+ }
60
+ }
61
+ function y(n) {
62
+ let t = n.length;
63
+ const e = new Uint8Array(8 + t);
64
+ for (let r = 7; r >= 0; r--)
65
+ e[r] = t & 255, t >>>= 8;
66
+ return e.set(n, 8), e;
67
+ }
68
+ var et = /* @__PURE__ */ ((n) => (n.KEY_1 = "key_1", n.TEST_KEY_1 = "test_key_1", n))(et || {}), rt = /* @__PURE__ */ ((n) => (n.KEY_1 = "key_1", n.TEST_KEY_1 = "test_key_1", n.DFX_TEST_KEY = "dfx_test_key", n))(rt || {});
69
+ function b(n) {
70
+ const t = new Uint8Array(n.length / 2);
71
+ for (let e = 0; e < n.length; e += 2)
72
+ t[e / 2] = parseInt(n.substring(e, e + 2), 16);
73
+ return t;
74
+ }
75
+ class d {
76
+ #t;
77
+ /**
78
+ * Read a MasterPublicKey from the bytestring encoding
79
+ *
80
+ * Normally the bytes provided here will have been returned by
81
+ * the `vetkd_public_key` management canister interface.
82
+ */
83
+ static deserialize(t) {
84
+ return new d(i.G2.Point.fromHex(t));
85
+ }
86
+ /**
87
+ * Derive a canister master key from the subnet master key
88
+ *
89
+ * To create the derived public key in VetKD, a two step derivation is performed. The first step
90
+ * creates a key that is specific to the canister that is making VetKD requests to the
91
+ * management canister, sometimes called canister master key.
92
+ *
93
+ * This function can be used to compute canister master keys knowing just the subnet master key
94
+ * plus the canister identity. This avoids having to interact with the IC for performing this
95
+ * computation.
96
+ */
97
+ deriveCanisterKey(t) {
98
+ const e = "ic-vetkd-bls12-381-g2-canister-id", r = this.publicKeyBytes(), s = new Uint8Array([
99
+ ...y(r),
100
+ ...y(t)
101
+ ]), o = P(s, e), c = i.G2.Point.BASE.multiply(o);
102
+ return new m(this.#t.add(c));
103
+ }
104
+ /**
105
+ * Return the bytestring encoding of the master public key
106
+ */
107
+ publicKeyBytes() {
108
+ return this.#t.toBytes(!0);
109
+ }
110
+ /**
111
+ * Return the hardcoded master public key used on IC
112
+ *
113
+ * This allows performing public key derivation offline
114
+ */
115
+ static productionKey(t = "key_1") {
116
+ if (t == "key_1")
117
+ return d.deserialize(
118
+ b(
119
+ "a9caf9ae8af0c7c7272f8a122133e2e0c7c0899b75e502bda9e109ca8193ded3ef042ed96db1125e1bdaad77d8cc60d917e122fe2501c45b96274f43705edf0cfd455bc66c3c060faa2fcd15486e76351edf91fecb993797273bbc8beaa47404"
120
+ )
121
+ );
122
+ if (t == "test_key_1")
123
+ return d.deserialize(
124
+ b(
125
+ "ad86e8ff845912f022a0838a502d763fdea547c9948f8cb20ea7738dd52c1c38dcb4c6ca9ac29f9ac690fc5ad7681cb41922b8dffbd65d94bff141f5fb5b6624eccc03bf850f222052df888cf9b1e47203556d7522271cbb879b2ef4b8c2bfb1"
126
+ )
127
+ );
128
+ throw new Error(
129
+ "Unknown MasterPublicKeyId value for productionKey"
130
+ );
131
+ }
132
+ /**
133
+ * Return the hardcoded master public key used in PocketIC
134
+ *
135
+ * This allows performing public key derivation offline
136
+ */
137
+ static pocketicKey(t = "key_1") {
138
+ if (t == "key_1")
139
+ return d.deserialize(
140
+ b(
141
+ "8c800b5cff00463d26e8167369168827f1e48f4d8d60f71dd6a295580f65275b5f5f8e6a792c876b2c72492136530d0710a27522ee63977a76216c3cef9e70bfcb45b88736fc62142e7e0737848ce06cbb1f45a4a6a349b142ae5cf7853561e0"
142
+ )
143
+ );
144
+ if (t == "test_key_1")
145
+ return d.deserialize(
146
+ b(
147
+ "9069b82c7aae418cef27678291e7f2cb1a008a500eceba7199bffca12421b07c158987c6a22618af3d1958738b2835691028801f7663d311799733286c557c8979184bb62cb559a4d582fca7d2e48b860f08ed6641aef66a059ec891889a6218"
148
+ )
149
+ );
150
+ if (t == "dfx_test_key")
151
+ return d.deserialize(
152
+ b(
153
+ "b181c14cf9d04ba45d782c0067a44b0aaa9fc2acf94f1a875f0dae801af4f80339a7e6bf8b09fcf993824c8df3080b3f1409b688ca08cbd44d2cb28db9899f4aa3b5f06b9174240448e10be2f01f9f80079ea5431ce2d11d1c8d1c775333315f"
154
+ )
155
+ );
156
+ throw new Error(
157
+ "Unknown PocketIcMasterPublicKeyId value for pocketicKey"
158
+ );
159
+ }
160
+ /**
161
+ * @internal constructor
162
+ */
163
+ constructor(t) {
164
+ this.#t = t;
165
+ }
166
+ }
167
+ class m {
168
+ #t;
169
+ /**
170
+ * Read a DerivedPublicKey from the bytestring encoding
171
+ *
172
+ * Normally the bytes provided here will have been returned by
173
+ * the `vetkd_public_key` management canister interface.
174
+ */
175
+ static deserialize(t) {
176
+ return new m(i.G2.Point.fromHex(t));
177
+ }
178
+ /**
179
+ * Perform second-stage derivation of a public key
180
+ *
181
+ * To create the derived public key in VetKD, a two step derivation is performed. The first step
182
+ * creates a key that is specific to the canister that is making VetKD requests to the
183
+ * management canister, sometimes called canister master key. The second step incorporates the
184
+ * "derivation context" value provided to the `vetkd_public_key` management canister interface.
185
+ *
186
+ * If `vetkd_public_key` is invoked with an empty derivation context, it simply returns the
187
+ * canister master key. Then the second derivation step can be done offline, using this
188
+ * function. This is useful if you wish to derive multiple keys without having to interact with
189
+ * the IC each time.
190
+ *
191
+ * If `context` is empty, then this simply returns the underlying key. This matches the behavior
192
+ * of `vetkd_public_key`
193
+ */
194
+ deriveSubKey(t) {
195
+ if (t.length === 0)
196
+ return this;
197
+ {
198
+ const e = "ic-vetkd-bls12-381-g2-context", r = this.publicKeyBytes(), s = new Uint8Array([
199
+ ...y(r),
200
+ ...y(t)
201
+ ]), o = P(s, e), c = i.G2.Point.BASE.multiply(o);
202
+ return new m(this.getPoint().add(c));
203
+ }
204
+ }
205
+ /**
206
+ * Return the bytestring encoding of the derived public key
207
+ *
208
+ * Applications would not normally need to call this, unless they
209
+ * are using VetKD for creating a random beacon, in which case
210
+ * these bytes are used by anyone verifying the beacon.
211
+ */
212
+ publicKeyBytes() {
213
+ return this.#t.toBytes(!0);
214
+ }
215
+ /**
216
+ * @internal getter returning the point element of the derived public key
217
+ *
218
+ * Applications would not normally need to call this
219
+ */
220
+ getPoint() {
221
+ return this.#t;
222
+ }
223
+ /**
224
+ * @internal constructor
225
+ *
226
+ * This is public for typing reasons but there should be no need
227
+ * for an application to call this.
228
+ */
229
+ constructor(t) {
230
+ this.#t = t;
231
+ }
232
+ }
233
+ function P(n, t) {
234
+ return i.G2.hashToScalar(n, { DST: t });
235
+ }
236
+ function U(n) {
237
+ if (typeof n == "string")
238
+ return new TextEncoder().encode(n);
239
+ const t = new Uint8Array(n.length);
240
+ return t.set(n), t;
241
+ }
242
+ function T(n, t) {
243
+ const e = new TextEncoder().encode(n), r = U(t), s = new Uint8Array(e.length + r.length);
244
+ return s.set(e, 0), s.set(r, e.length), s;
245
+ }
246
+ function A(n, t, e) {
247
+ const r = new Uint8Array();
248
+ return $(tt, n, r, t, e);
249
+ }
250
+ function nt(n, t) {
251
+ const e = "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_", r = n.publicKeyBytes(), s = new Uint8Array([...r, ...t]);
252
+ return i.G1.Point.fromAffine(
253
+ i.G1.hashToCurve(s, {
254
+ DST: e
255
+ }).toAffine()
256
+ );
257
+ }
258
+ function O(n, t, e) {
259
+ const r = n.publicKeyBytes(), s = new Uint8Array([...r, ...t]), c = i.shortSignatures.hash(
260
+ s,
261
+ "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_"
262
+ );
263
+ return i.shortSignatures.verify(
264
+ e,
265
+ c,
266
+ n.getPoint()
267
+ );
268
+ }
269
+ class _ {
270
+ #t;
271
+ #e;
272
+ /**
273
+ * Return the VetKey bytes, aka the BLS signature
274
+ *
275
+ * Use the raw bytes only if your design makes use of the fact that VetKeys
276
+ * are BLS signatures (eg for random beacon or threshold BLS signature
277
+ * generation). If you are using VetKD for key distribution, instead use
278
+ * deriveSymmetricKey or asHkdfCryptoKey
279
+ */
280
+ signatureBytes() {
281
+ return this.#e;
282
+ }
283
+ /**
284
+ * Return the serialization of the VetKey
285
+ *
286
+ * This is the byte encoding of the unencrypted VetKey.
287
+ */
288
+ serialize() {
289
+ return this.#e;
290
+ }
291
+ /**
292
+ * Derive a symmetric key of the requested length from the VetKey
293
+ *
294
+ * As an alternative to this function consider using asDerivedKeyMaterial,
295
+ * which uses the WebCrypto API and prevents export of the underlying key.
296
+ *
297
+ * The `domainSep` parameter should be a string unique to your application and
298
+ * also your usage of the resulting key. For example say your application
299
+ * "my-app" is deriving two keys, one for usage "foo" and the other for
300
+ * "bar". You might use as domain separators "my-app-foo" and "my-app-bar".
301
+ *
302
+ * The returned Uint8Array will be `outputLength` bytes long.
303
+ */
304
+ deriveSymmetricKey(t, e) {
305
+ return A(this.#e, t, e);
306
+ }
307
+ /**
308
+ * Return a DerivedKeyMaterial type which is suitable for further key derivation
309
+ */
310
+ async asDerivedKeyMaterial() {
311
+ return v.setup(this.#e);
312
+ }
313
+ /**
314
+ * Deserialize a VetKey from the 48 byte encoding of the BLS signature
315
+ *
316
+ * This deserializes the same value as returned by serialize (or signatureBytes)
317
+ */
318
+ static deserialize(t) {
319
+ return new _(i.G1.Point.fromHex(t));
320
+ }
321
+ /**
322
+ * @internal getter returning the point object of the VetKey
323
+ *
324
+ * Applications would not usually need to call this
325
+ */
326
+ getPoint() {
327
+ return this.#t;
328
+ }
329
+ /**
330
+ * @internal constructor
331
+ *
332
+ * This is public for typing reasons but there is no reason for an application
333
+ * to call this constructor.
334
+ */
335
+ constructor(t) {
336
+ this.#t = t, this.#e = new Uint8Array(t.toBytes(!0));
337
+ }
338
+ }
339
+ const E = 12, R = 2, D = "IC GCMv2", C = new TextEncoder().encode(
340
+ D
341
+ ), g = 8;
342
+ class v {
343
+ #t;
344
+ #e;
345
+ /**
346
+ * @internal constructor
347
+ */
348
+ constructor(t, e) {
349
+ this.#t = t, this.#e = e;
350
+ }
351
+ static async fromCryptoKey(t) {
352
+ const e = {
353
+ name: "HKDF",
354
+ hash: "SHA-256",
355
+ info: new TextEncoder().encode(
356
+ "ic-vetkd-bls12-381-g2-derived-key-material"
357
+ ),
358
+ salt: new Uint8Array()
359
+ }, r = {
360
+ name: "AES-GCM",
361
+ length: 256
362
+ }, s = await crypto.subtle.deriveKey(
363
+ e,
364
+ t,
365
+ r,
366
+ !0,
367
+ // exportable
368
+ ["encrypt"]
369
+ ), o = await crypto.subtle.exportKey(
370
+ "raw",
371
+ s
372
+ ), c = await crypto.subtle.importKey(
373
+ "raw",
374
+ o,
375
+ { name: "HKDF" },
376
+ !1,
377
+ ["deriveKey", "deriveBits"]
378
+ );
379
+ return new v(c, t);
380
+ }
381
+ /**
382
+ * @internal constructor
383
+ */
384
+ static async setup(t) {
385
+ const r = await globalThis.crypto.subtle.importKey(
386
+ "raw",
387
+ t,
388
+ "HKDF",
389
+ !1,
390
+ ["deriveKey", "deriveBits"]
391
+ );
392
+ return v.fromCryptoKey(r);
393
+ }
394
+ /**
395
+ * Return the CryptoKey
396
+ */
397
+ getCryptoKey() {
398
+ return this.#e;
399
+ }
400
+ /**
401
+ * Return a WebCrypto CryptoKey handle suitable for AES-GCM encryption/decryption
402
+ *
403
+ * The key is derived using HKDF with the provided domain separator
404
+ *
405
+ * The CryptoKey is not exportable
406
+ */
407
+ async deriveAesGcmCryptoKey(t, e) {
408
+ const r = {
409
+ name: "HKDF",
410
+ hash: "SHA-256",
411
+ length: 256,
412
+ info: T(
413
+ "ic-vetkd-bls12-381-g2-aes-gcm-v" + e.toString() + "-",
414
+ t
415
+ ),
416
+ salt: new Uint8Array()
417
+ }, s = {
418
+ name: "AES-GCM",
419
+ length: 256
420
+ };
421
+ return globalThis.crypto.subtle.deriveKey(
422
+ r,
423
+ this.#t,
424
+ s,
425
+ !1,
426
+ ["encrypt", "decrypt"]
427
+ );
428
+ }
429
+ /**
430
+ * Encrypt the provided message using AES-GCM and a key derived using HKDF
431
+ *
432
+ * The GCM key is derived using HKDF with the provided domain separator
433
+ */
434
+ async encryptMessage(t, e, r) {
435
+ const s = await this.deriveAesGcmCryptoKey(
436
+ e,
437
+ R
438
+ ), o = globalThis.crypto.getRandomValues(
439
+ new Uint8Array(E)
440
+ ), c = T(D, r), u = new Uint8Array(
441
+ await globalThis.crypto.subtle.encrypt(
442
+ { name: "AES-GCM", iv: o, additionalData: c },
443
+ s,
444
+ U(t)
445
+ )
446
+ );
447
+ return new Uint8Array([
448
+ ...C,
449
+ ...o,
450
+ ...u
451
+ ]);
452
+ }
453
+ /**
454
+ * Decrypt the provided ciphertext using AES-GCM and a key derived using HKDF
455
+ *
456
+ * The GCM key is derived using HKDF with the provided domain separator
457
+ */
458
+ async decryptMessage(t, e, r) {
459
+ const o = g + E + 16;
460
+ if (t.length < o)
461
+ throw new Error(
462
+ "Invalid ciphertext, too short to possibly be valid"
463
+ );
464
+ const c = t.slice(0, g);
465
+ if (!z(c, C))
466
+ if (r.length == 0) {
467
+ const w = t.slice(
468
+ 0,
469
+ E
470
+ ), X = t.slice(
471
+ E
472
+ ), q = {
473
+ name: "HKDF",
474
+ hash: "SHA-256",
475
+ length: 256,
476
+ info: U(e),
477
+ salt: new Uint8Array()
478
+ }, j = {
479
+ name: "AES-GCM",
480
+ length: 256
481
+ }, J = await globalThis.crypto.subtle.deriveKey(
482
+ q,
483
+ this.#e,
484
+ j,
485
+ !1,
486
+ ["decrypt"]
487
+ );
488
+ try {
489
+ const Q = await globalThis.crypto.subtle.decrypt(
490
+ { name: "AES-GCM", iv: w },
491
+ J,
492
+ X
493
+ );
494
+ return new Uint8Array(Q);
495
+ } catch {
496
+ throw new Error("Decryption failed");
497
+ }
498
+ } else
499
+ throw new Error(
500
+ "Unknown header for AES-GCM encrypted ciphertext"
501
+ );
502
+ const u = T(D, r), p = t.slice(
503
+ g,
504
+ g + E
505
+ ), G = t.slice(
506
+ g + E
507
+ ), K = await this.deriveAesGcmCryptoKey(
508
+ e,
509
+ R
510
+ );
511
+ try {
512
+ const w = await globalThis.crypto.subtle.decrypt(
513
+ { name: "AES-GCM", iv: p, additionalData: u },
514
+ K,
515
+ G
516
+ );
517
+ return new Uint8Array(w);
518
+ } catch {
519
+ throw new Error("Decryption failed");
520
+ }
521
+ }
522
+ }
523
+ class N {
524
+ #t;
525
+ #e;
526
+ #r;
527
+ /**
528
+ * Parse an encrypted key returned by the `vetkd_derive_encrypted_key`
529
+ * managment canister interface
530
+ */
531
+ static deserialize(t) {
532
+ if (t.length !== l + a + l)
533
+ throw new Error("Invalid EncryptedVetKey serialization");
534
+ const e = i.G1.Point.fromHex(t.subarray(0, l)), r = i.G2.Point.fromHex(
535
+ t.subarray(l, l + a)
536
+ ), s = i.G1.Point.fromHex(
537
+ t.subarray(l + a)
538
+ );
539
+ return new N(e, r, s);
540
+ }
541
+ /**
542
+ * Decrypt the encrypted key returning a VetKey
543
+ */
544
+ decryptAndVerify(t, e, r) {
545
+ const s = i.G1.Point.BASE, o = i.G2.Point.BASE.negate(), c = i.fields.Fp12.ONE, u = i.pairingBatch([
546
+ { g1: this.#t, g2: o },
547
+ { g1: s, g2: this.#e }
548
+ ]);
549
+ if (!i.fields.Fp12.eql(u, c))
550
+ throw new Error("Invalid VetKey");
551
+ const p = this.#r.subtract(
552
+ this.#t.multiply(i.G1.Point.Fn.fromBytes(t.serialize()))
553
+ );
554
+ if (O(e, r, p))
555
+ return new _(p);
556
+ throw new Error("Invalid VetKey");
557
+ }
558
+ /**
559
+ * @internal constructor
560
+ */
561
+ constructor(t, e, r) {
562
+ this.#t = t, this.#e = e, this.#r = r;
563
+ }
564
+ }
565
+ const V = new Uint8Array([
566
+ 73,
567
+ 67,
568
+ 32,
569
+ 73,
570
+ 66,
571
+ 69,
572
+ 0,
573
+ 1
574
+ ]), f = 8;
575
+ function M(n, t, e) {
576
+ const r = new Uint8Array([...n, ...t, ...e]);
577
+ return P(
578
+ r,
579
+ "ic-vetkd-bls12-381-ibe-hash-to-mask"
580
+ /* HashToMask */
581
+ );
582
+ }
583
+ function W(n, t) {
584
+ if (n.length !== t.length)
585
+ throw new Error("xorBuf arguments should have the same length");
586
+ const e = new Uint8Array(n.length);
587
+ for (let r = 0; r < n.length; r++)
588
+ e[r] = n[r] ^ t[r];
589
+ return e;
590
+ }
591
+ function L(n, t) {
592
+ if (t.length !== 576)
593
+ throw new Error("Unexpected size for Gt element");
594
+ const e = A(
595
+ t,
596
+ "ic-vetkd-bls12-381-ibe-mask-seed",
597
+ n.length
598
+ );
599
+ return W(e, n);
600
+ }
601
+ function Y(n, t) {
602
+ const e = "ic-vetkd-bls12-381-ibe-mask-msg-".concat(
603
+ n.length.toString().padStart(20, "0")
604
+ ), r = A(t, e, 32), s = Z(r, { dkLen: n.length });
605
+ return W(n, s);
606
+ }
607
+ function F(n) {
608
+ const t = i.fields.Fp12.toBytes(n), e = new Uint8Array(576), r = [11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
609
+ for (let s = 0; s < 12; ++s)
610
+ for (let o = 0; o < 48; ++o)
611
+ e[48 * s + o] = t[48 * r[s] + o];
612
+ return e;
613
+ }
614
+ function z(n, t) {
615
+ if (n.length !== t.length)
616
+ return !1;
617
+ let e = 0;
618
+ for (let r = 0; r < n.length; ++r)
619
+ e |= n[r] ^ t[r];
620
+ return e == 0;
621
+ }
622
+ class B {
623
+ #t;
624
+ constructor(t) {
625
+ this.#t = t;
626
+ }
627
+ /**
628
+ * Create an identity from a byte string
629
+ */
630
+ static fromBytes(t) {
631
+ return new B(t);
632
+ }
633
+ /**
634
+ * Create an identity from a string
635
+ */
636
+ static fromString(t) {
637
+ return B.fromBytes(new TextEncoder().encode(t));
638
+ }
639
+ /**
640
+ * Create an identity from a Principal
641
+ */
642
+ static fromPrincipal(t) {
643
+ return B.fromBytes(t.toUint8Array());
644
+ }
645
+ /**
646
+ * @internal getter returning the encoded
647
+ */
648
+ getBytes() {
649
+ return this.#t;
650
+ }
651
+ }
652
+ const h = 32;
653
+ class S {
654
+ #t;
655
+ constructor(t) {
656
+ if (t.length !== h)
657
+ throw new Error("IBE seed must be exactly IBE_SEED_BYTES long");
658
+ this.#t = t;
659
+ }
660
+ /**
661
+ * Create a seed for IBE encryption from a byte string
662
+ *
663
+ * This input should be randomly chosen by a secure random number generator.
664
+ * If the seed is not securely generated the IBE scheme will be insecure.
665
+ *
666
+ * At least 128 bits (16 bytes) must be provided.
667
+ *
668
+ * If the input is exactly 256 bits it is used directly. Otherwise the input
669
+ * is hashed with HKDF to produce a 256 bit seed.
670
+ */
671
+ static fromBytes(t) {
672
+ if (t.length < 16)
673
+ throw new Error(
674
+ "Insufficient input material for IbeSeed derivation"
675
+ );
676
+ return t.length == h ? new S(t) : new S(
677
+ A(
678
+ t,
679
+ "ic-vetkd-bls12-381-ibe-hash-seed",
680
+ h
681
+ )
682
+ );
683
+ }
684
+ /**
685
+ * Create a random seed for IBE encryption
686
+ */
687
+ static random() {
688
+ return new S(
689
+ globalThis.crypto.getRandomValues(new Uint8Array(h))
690
+ );
691
+ }
692
+ /**
693
+ * @internal getter returning the seed bytes
694
+ */
695
+ getBytes() {
696
+ return this.#t;
697
+ }
698
+ }
699
+ const k = f + h + a;
700
+ class H {
701
+ #t;
702
+ #e;
703
+ #r;
704
+ #n;
705
+ /**
706
+ * Helper function for determining the size of an IBE ciphertext in bytes.
707
+ */
708
+ static ciphertextSize(t) {
709
+ if (t < 0)
710
+ throw new Error(
711
+ "IbeCiphertext.ciphertextSize argument cannot be negative"
712
+ );
713
+ return t + k;
714
+ }
715
+ /**
716
+ * Helper function for determining the size of an IBE plaintext in bytes.
717
+ */
718
+ static plaintextSize(t) {
719
+ if (t < k)
720
+ throw new Error(
721
+ "IbeCiphertext.plaintextSize given ciphertext size is too small to be valid"
722
+ );
723
+ return t - k;
724
+ }
725
+ /**
726
+ * Serialize the IBE ciphertext to a bytestring
727
+ */
728
+ serialize() {
729
+ const t = this.#e.toBytes(!0);
730
+ return new Uint8Array([
731
+ ...this.#t,
732
+ ...t,
733
+ ...this.#r,
734
+ ...this.#n
735
+ ]);
736
+ }
737
+ /**
738
+ * Deserialize an IBE ciphertext
739
+ */
740
+ static deserialize(t) {
741
+ if (t.length < f + a + h)
742
+ throw new Error("Invalid IBE ciphertext");
743
+ const e = t.subarray(0, f), r = i.G2.Point.fromHex(
744
+ t.subarray(f, f + a)
745
+ ), s = t.subarray(
746
+ f + a,
747
+ f + a + h
748
+ ), o = t.subarray(f + a + h);
749
+ if (!z(e, V))
750
+ throw new Error("Unexpected header for IBE ciphertext");
751
+ return new H(e, r, s, o);
752
+ }
753
+ /**
754
+ * Encrypt a message using IBE, returning the ciphertext
755
+ *
756
+ * Any user who is able to retrieve the VetKey for the specified derived public key and
757
+ * identity will be able to decrypt this message.
758
+ *
759
+ * There is no fixed upper bound on the size of the message that can be encrypted using
760
+ * this scheme. However, internally during the encryption process several heap allocations
761
+ * are performed which are approximately the same length as the message itself, so
762
+ * encrypting or decrypting very large messages may result in memory allocation errors.
763
+ *
764
+ * If you anticipate using IBE to encrypt very large messages, consider using IBE just to
765
+ * encrypt a symmetric key, and then using a standard cipher such as AES-GCM to encrypt the
766
+ * data.
767
+ *
768
+ * The seed parameter must be a randomly generated value that was generated just for this
769
+ * one message. Using it for a second message, or for any other purpose, compromises the
770
+ * security of the IBE scheme.
771
+ */
772
+ static encrypt(t, e, r, s) {
773
+ const o = V, c = M(o, s.getBytes(), r), u = nt(t, e.getBytes()), p = i.fields.Fp12.pow(
774
+ i.pairing(u, t.getPoint()),
775
+ c
776
+ ), G = i.G2.Point.BASE.multiply(c), K = L(s.getBytes(), F(p)), w = Y(r, s.getBytes());
777
+ return new H(o, G, K, w);
778
+ }
779
+ /**
780
+ * Decrypt an IBE ciphertext, returning the message
781
+ *
782
+ * There is no fixed upper bound on the size of the message that can be encrypted using
783
+ * this scheme. However, internally during the encryption process several heap allocations
784
+ * are performed which are approximately the same length as the message itself, so
785
+ * encrypting or decrypting very large messages may result in memory allocation errors.
786
+ */
787
+ decrypt(t) {
788
+ const e = L(
789
+ this.#r,
790
+ F(i.pairing(t.getPoint(), this.#e))
791
+ ), r = Y(this.#n, e), s = M(this.#t, e, r);
792
+ if (z(
793
+ i.G2.Point.BASE.multiply(s).toBytes(!0),
794
+ this.#e.toBytes(!0)
795
+ ))
796
+ return r;
797
+ throw new Error("Decryption failed");
798
+ }
799
+ /**
800
+ * Private constructor
801
+ */
802
+ constructor(t, e, r, s) {
803
+ this.#t = t, this.#e = e, this.#r = r, this.#n = s;
804
+ }
805
+ }
806
+ const st = 32;
807
+ class I {
808
+ #t;
809
+ #e;
810
+ #r;
811
+ #n;
812
+ static computeVrfHash(t, e, r) {
813
+ const s = new Uint8Array([
814
+ ...y(t.serialize()),
815
+ ...y(e.publicKeyBytes()),
816
+ ...y(r)
817
+ ]);
818
+ return A(
819
+ s,
820
+ "ic-vetkd-bls12-381-g2-vrf",
821
+ st
822
+ );
823
+ }
824
+ /**
825
+ * Serialize a VrfOutput to a byte string
826
+ */
827
+ serialize() {
828
+ return new Uint8Array([
829
+ ...this.#t.serialize(),
830
+ ...this.#e.publicKeyBytes(),
831
+ ...this.#r
832
+ ]);
833
+ }
834
+ /**
835
+ * Deserialize and verify a VrfOutput
836
+ *
837
+ * Note this verifies the VrfOutput with respect to the derived public key
838
+ * and VRF input which are included in the struct. It is the responsibility
839
+ * of the application to examine the return value of `publicKey` and `input`
840
+ * and ensure these values make sense in the context where this VRF is being
841
+ * used.
842
+ */
843
+ static deserialize(t) {
844
+ if (t.length < l + a)
845
+ throw new Error(
846
+ "VrfOutput.deserialize input too short to possibly be valid"
847
+ );
848
+ const e = _.deserialize(t.slice(0, l)), r = m.deserialize(
849
+ t.slice(l, l + a)
850
+ ), s = t.slice(l + a);
851
+ if (!O(r, s, e.getPoint()))
852
+ throw new Error("VrfOutput.deserialize proof is invalid");
853
+ return new I(e, r, s);
854
+ }
855
+ /**
856
+ * Return the public key under which this VRF output was derived
857
+ */
858
+ publicKey() {
859
+ return this.#e;
860
+ }
861
+ /**
862
+ * Return the input that was used to create this VRF output
863
+ */
864
+ input() {
865
+ return this.#r;
866
+ }
867
+ /**
868
+ * Return the VRF output
869
+ *
870
+ * This is a random-looking value which was provably generated by some party with
871
+ * access to the VRF secret key.
872
+ */
873
+ output() {
874
+ return this.#n;
875
+ }
876
+ /**
877
+ * Private constructor
878
+ */
879
+ constructor(t, e, r) {
880
+ this.#t = t, this.#e = e, this.#r = r, this.#n = I.computeVrfHash(t, e, r);
881
+ }
882
+ }
883
+ export {
884
+ v as D,
885
+ N as E,
886
+ H as I,
887
+ d as M,
888
+ rt as P,
889
+ x as T,
890
+ _ as V,
891
+ m as a,
892
+ B as b,
893
+ S as c,
894
+ et as d,
895
+ I as e,
896
+ nt as f,
897
+ A as g,
898
+ P as h,
899
+ lt as i,
900
+ O as v
901
+ };