@voidly/agent-sdk 2.1.0 → 3.0.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/dist/index.d.mts +141 -1
- package/dist/index.d.ts +141 -1
- package/dist/index.js +2407 -275
- package/dist/index.mjs +2407 -275
- package/package.json +16 -4
package/dist/index.mjs
CHANGED
|
@@ -49,11 +49,11 @@ var require_nacl_fast = __commonJS({
|
|
|
49
49
|
var _9 = new Uint8Array(32);
|
|
50
50
|
_9[0] = 9;
|
|
51
51
|
var gf0 = gf(), gf1 = gf([1]), _121665 = gf([56129, 1]), D = gf([30883, 4953, 19914, 30187, 55467, 16705, 2637, 112, 59544, 30585, 16505, 36039, 65139, 11119, 27886, 20995]), D2 = gf([61785, 9906, 39828, 60374, 45398, 33411, 5274, 224, 53552, 61171, 33010, 6542, 64743, 22239, 55772, 9222]), X = gf([54554, 36645, 11616, 51542, 42930, 38181, 51040, 26924, 56412, 64982, 57905, 49316, 21502, 52590, 14035, 8553]), Y = gf([26200, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214, 26214]), I = gf([41136, 18958, 6951, 50414, 58488, 44335, 6150, 12099, 55207, 15867, 153, 11085, 57099, 20417, 9344, 11139]);
|
|
52
|
-
function ts64(x, i,
|
|
53
|
-
x[i] =
|
|
54
|
-
x[i + 1] =
|
|
55
|
-
x[i + 2] =
|
|
56
|
-
x[i + 3] =
|
|
52
|
+
function ts64(x, i, h2, l) {
|
|
53
|
+
x[i] = h2 >> 24 & 255;
|
|
54
|
+
x[i + 1] = h2 >> 16 & 255;
|
|
55
|
+
x[i + 2] = h2 >> 8 & 255;
|
|
56
|
+
x[i + 3] = h2 & 255;
|
|
57
57
|
x[i + 4] = l >> 24 & 255;
|
|
58
58
|
x[i + 5] = l >> 16 & 255;
|
|
59
59
|
x[i + 6] = l >> 8 & 255;
|
|
@@ -631,7 +631,7 @@ var require_nacl_fast = __commonJS({
|
|
|
631
631
|
this.h[9] = h9;
|
|
632
632
|
};
|
|
633
633
|
poly1305.prototype.finish = function(mac, macpos) {
|
|
634
|
-
var
|
|
634
|
+
var g2 = new Uint16Array(10);
|
|
635
635
|
var c, mask, f, i;
|
|
636
636
|
if (this.leftover) {
|
|
637
637
|
i = this.leftover;
|
|
@@ -654,19 +654,19 @@ var require_nacl_fast = __commonJS({
|
|
|
654
654
|
c = this.h[1] >>> 13;
|
|
655
655
|
this.h[1] &= 8191;
|
|
656
656
|
this.h[2] += c;
|
|
657
|
-
|
|
658
|
-
c =
|
|
659
|
-
|
|
657
|
+
g2[0] = this.h[0] + 5;
|
|
658
|
+
c = g2[0] >>> 13;
|
|
659
|
+
g2[0] &= 8191;
|
|
660
660
|
for (i = 1; i < 10; i++) {
|
|
661
|
-
|
|
662
|
-
c =
|
|
663
|
-
|
|
661
|
+
g2[i] = this.h[i] + c;
|
|
662
|
+
c = g2[i] >>> 13;
|
|
663
|
+
g2[i] &= 8191;
|
|
664
664
|
}
|
|
665
|
-
|
|
665
|
+
g2[9] -= 1 << 13;
|
|
666
666
|
mask = (c ^ 1) - 1;
|
|
667
|
-
for (i = 0; i < 10; i++)
|
|
667
|
+
for (i = 0; i < 10; i++) g2[i] &= mask;
|
|
668
668
|
mask = ~mask;
|
|
669
|
-
for (i = 0; i < 10; i++) this.h[i] = this.h[i] & mask |
|
|
669
|
+
for (i = 0; i < 10; i++) this.h[i] = this.h[i] & mask | g2[i];
|
|
670
670
|
this.h[0] = (this.h[0] | this.h[1] << 13) & 65535;
|
|
671
671
|
this.h[1] = (this.h[1] >>> 3 | this.h[2] << 10) & 65535;
|
|
672
672
|
this.h[2] = (this.h[2] >>> 6 | this.h[3] << 7) & 65535;
|
|
@@ -732,10 +732,10 @@ var require_nacl_fast = __commonJS({
|
|
|
732
732
|
s.finish(out, outpos);
|
|
733
733
|
return 0;
|
|
734
734
|
}
|
|
735
|
-
function crypto_onetimeauth_verify(
|
|
735
|
+
function crypto_onetimeauth_verify(h2, hpos, m, mpos, n, k) {
|
|
736
736
|
var x = new Uint8Array(16);
|
|
737
737
|
crypto_onetimeauth(x, 0, m, mpos, n, k);
|
|
738
|
-
return crypto_verify_16(
|
|
738
|
+
return crypto_verify_16(h2, hpos, x, 0);
|
|
739
739
|
}
|
|
740
740
|
function crypto_secretbox(c, m, d, n, k) {
|
|
741
741
|
var i;
|
|
@@ -1488,7 +1488,7 @@ var require_nacl_fast = __commonJS({
|
|
|
1488
1488
|
1246189591
|
|
1489
1489
|
];
|
|
1490
1490
|
function crypto_hashblocks_hl(hh, hl, m, n) {
|
|
1491
|
-
var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j,
|
|
1491
|
+
var wh = new Int32Array(16), wl = new Int32Array(16), bh0, bh1, bh2, bh3, bh4, bh5, bh6, bh7, bl0, bl1, bl2, bl3, bl4, bl5, bl6, bl7, th, tl, i, j, h2, l, a, b, c, d;
|
|
1492
1492
|
var ah0 = hh[0], ah1 = hh[1], ah2 = hh[2], ah3 = hh[3], ah4 = hh[4], ah5 = hh[5], ah6 = hh[6], ah7 = hh[7], al0 = hl[0], al1 = hl[1], al2 = hl[2], al3 = hl[3], al4 = hl[4], al5 = hl[5], al6 = hl[6], al7 = hl[7];
|
|
1493
1493
|
var pos = 0;
|
|
1494
1494
|
while (n >= 128) {
|
|
@@ -1514,76 +1514,76 @@ var require_nacl_fast = __commonJS({
|
|
|
1514
1514
|
bl5 = al5;
|
|
1515
1515
|
bl6 = al6;
|
|
1516
1516
|
bl7 = al7;
|
|
1517
|
-
|
|
1517
|
+
h2 = ah7;
|
|
1518
1518
|
l = al7;
|
|
1519
1519
|
a = l & 65535;
|
|
1520
1520
|
b = l >>> 16;
|
|
1521
|
-
c =
|
|
1522
|
-
d =
|
|
1523
|
-
|
|
1521
|
+
c = h2 & 65535;
|
|
1522
|
+
d = h2 >>> 16;
|
|
1523
|
+
h2 = (ah4 >>> 14 | al4 << 32 - 14) ^ (ah4 >>> 18 | al4 << 32 - 18) ^ (al4 >>> 41 - 32 | ah4 << 32 - (41 - 32));
|
|
1524
1524
|
l = (al4 >>> 14 | ah4 << 32 - 14) ^ (al4 >>> 18 | ah4 << 32 - 18) ^ (ah4 >>> 41 - 32 | al4 << 32 - (41 - 32));
|
|
1525
1525
|
a += l & 65535;
|
|
1526
1526
|
b += l >>> 16;
|
|
1527
|
-
c +=
|
|
1528
|
-
d +=
|
|
1529
|
-
|
|
1527
|
+
c += h2 & 65535;
|
|
1528
|
+
d += h2 >>> 16;
|
|
1529
|
+
h2 = ah4 & ah5 ^ ~ah4 & ah6;
|
|
1530
1530
|
l = al4 & al5 ^ ~al4 & al6;
|
|
1531
1531
|
a += l & 65535;
|
|
1532
1532
|
b += l >>> 16;
|
|
1533
|
-
c +=
|
|
1534
|
-
d +=
|
|
1535
|
-
|
|
1533
|
+
c += h2 & 65535;
|
|
1534
|
+
d += h2 >>> 16;
|
|
1535
|
+
h2 = K[i * 2];
|
|
1536
1536
|
l = K[i * 2 + 1];
|
|
1537
1537
|
a += l & 65535;
|
|
1538
1538
|
b += l >>> 16;
|
|
1539
|
-
c +=
|
|
1540
|
-
d +=
|
|
1541
|
-
|
|
1539
|
+
c += h2 & 65535;
|
|
1540
|
+
d += h2 >>> 16;
|
|
1541
|
+
h2 = wh[i % 16];
|
|
1542
1542
|
l = wl[i % 16];
|
|
1543
1543
|
a += l & 65535;
|
|
1544
1544
|
b += l >>> 16;
|
|
1545
|
-
c +=
|
|
1546
|
-
d +=
|
|
1545
|
+
c += h2 & 65535;
|
|
1546
|
+
d += h2 >>> 16;
|
|
1547
1547
|
b += a >>> 16;
|
|
1548
1548
|
c += b >>> 16;
|
|
1549
1549
|
d += c >>> 16;
|
|
1550
1550
|
th = c & 65535 | d << 16;
|
|
1551
1551
|
tl = a & 65535 | b << 16;
|
|
1552
|
-
|
|
1552
|
+
h2 = th;
|
|
1553
1553
|
l = tl;
|
|
1554
1554
|
a = l & 65535;
|
|
1555
1555
|
b = l >>> 16;
|
|
1556
|
-
c =
|
|
1557
|
-
d =
|
|
1558
|
-
|
|
1556
|
+
c = h2 & 65535;
|
|
1557
|
+
d = h2 >>> 16;
|
|
1558
|
+
h2 = (ah0 >>> 28 | al0 << 32 - 28) ^ (al0 >>> 34 - 32 | ah0 << 32 - (34 - 32)) ^ (al0 >>> 39 - 32 | ah0 << 32 - (39 - 32));
|
|
1559
1559
|
l = (al0 >>> 28 | ah0 << 32 - 28) ^ (ah0 >>> 34 - 32 | al0 << 32 - (34 - 32)) ^ (ah0 >>> 39 - 32 | al0 << 32 - (39 - 32));
|
|
1560
1560
|
a += l & 65535;
|
|
1561
1561
|
b += l >>> 16;
|
|
1562
|
-
c +=
|
|
1563
|
-
d +=
|
|
1564
|
-
|
|
1562
|
+
c += h2 & 65535;
|
|
1563
|
+
d += h2 >>> 16;
|
|
1564
|
+
h2 = ah0 & ah1 ^ ah0 & ah2 ^ ah1 & ah2;
|
|
1565
1565
|
l = al0 & al1 ^ al0 & al2 ^ al1 & al2;
|
|
1566
1566
|
a += l & 65535;
|
|
1567
1567
|
b += l >>> 16;
|
|
1568
|
-
c +=
|
|
1569
|
-
d +=
|
|
1568
|
+
c += h2 & 65535;
|
|
1569
|
+
d += h2 >>> 16;
|
|
1570
1570
|
b += a >>> 16;
|
|
1571
1571
|
c += b >>> 16;
|
|
1572
1572
|
d += c >>> 16;
|
|
1573
1573
|
bh7 = c & 65535 | d << 16;
|
|
1574
1574
|
bl7 = a & 65535 | b << 16;
|
|
1575
|
-
|
|
1575
|
+
h2 = bh3;
|
|
1576
1576
|
l = bl3;
|
|
1577
1577
|
a = l & 65535;
|
|
1578
1578
|
b = l >>> 16;
|
|
1579
|
-
c =
|
|
1580
|
-
d =
|
|
1581
|
-
|
|
1579
|
+
c = h2 & 65535;
|
|
1580
|
+
d = h2 >>> 16;
|
|
1581
|
+
h2 = th;
|
|
1582
1582
|
l = tl;
|
|
1583
1583
|
a += l & 65535;
|
|
1584
1584
|
b += l >>> 16;
|
|
1585
|
-
c +=
|
|
1586
|
-
d +=
|
|
1585
|
+
c += h2 & 65535;
|
|
1586
|
+
d += h2 >>> 16;
|
|
1587
1587
|
b += a >>> 16;
|
|
1588
1588
|
c += b >>> 16;
|
|
1589
1589
|
d += c >>> 16;
|
|
@@ -1607,34 +1607,34 @@ var require_nacl_fast = __commonJS({
|
|
|
1607
1607
|
al0 = bl7;
|
|
1608
1608
|
if (i % 16 === 15) {
|
|
1609
1609
|
for (j = 0; j < 16; j++) {
|
|
1610
|
-
|
|
1610
|
+
h2 = wh[j];
|
|
1611
1611
|
l = wl[j];
|
|
1612
1612
|
a = l & 65535;
|
|
1613
1613
|
b = l >>> 16;
|
|
1614
|
-
c =
|
|
1615
|
-
d =
|
|
1616
|
-
|
|
1614
|
+
c = h2 & 65535;
|
|
1615
|
+
d = h2 >>> 16;
|
|
1616
|
+
h2 = wh[(j + 9) % 16];
|
|
1617
1617
|
l = wl[(j + 9) % 16];
|
|
1618
1618
|
a += l & 65535;
|
|
1619
1619
|
b += l >>> 16;
|
|
1620
|
-
c +=
|
|
1621
|
-
d +=
|
|
1620
|
+
c += h2 & 65535;
|
|
1621
|
+
d += h2 >>> 16;
|
|
1622
1622
|
th = wh[(j + 1) % 16];
|
|
1623
1623
|
tl = wl[(j + 1) % 16];
|
|
1624
|
-
|
|
1624
|
+
h2 = (th >>> 1 | tl << 32 - 1) ^ (th >>> 8 | tl << 32 - 8) ^ th >>> 7;
|
|
1625
1625
|
l = (tl >>> 1 | th << 32 - 1) ^ (tl >>> 8 | th << 32 - 8) ^ (tl >>> 7 | th << 32 - 7);
|
|
1626
1626
|
a += l & 65535;
|
|
1627
1627
|
b += l >>> 16;
|
|
1628
|
-
c +=
|
|
1629
|
-
d +=
|
|
1628
|
+
c += h2 & 65535;
|
|
1629
|
+
d += h2 >>> 16;
|
|
1630
1630
|
th = wh[(j + 14) % 16];
|
|
1631
1631
|
tl = wl[(j + 14) % 16];
|
|
1632
|
-
|
|
1632
|
+
h2 = (th >>> 19 | tl << 32 - 19) ^ (tl >>> 61 - 32 | th << 32 - (61 - 32)) ^ th >>> 6;
|
|
1633
1633
|
l = (tl >>> 19 | th << 32 - 19) ^ (th >>> 61 - 32 | tl << 32 - (61 - 32)) ^ (tl >>> 6 | th << 32 - 6);
|
|
1634
1634
|
a += l & 65535;
|
|
1635
1635
|
b += l >>> 16;
|
|
1636
|
-
c +=
|
|
1637
|
-
d +=
|
|
1636
|
+
c += h2 & 65535;
|
|
1637
|
+
d += h2 >>> 16;
|
|
1638
1638
|
b += a >>> 16;
|
|
1639
1639
|
c += b >>> 16;
|
|
1640
1640
|
d += c >>> 16;
|
|
@@ -1643,137 +1643,137 @@ var require_nacl_fast = __commonJS({
|
|
|
1643
1643
|
}
|
|
1644
1644
|
}
|
|
1645
1645
|
}
|
|
1646
|
-
|
|
1646
|
+
h2 = ah0;
|
|
1647
1647
|
l = al0;
|
|
1648
1648
|
a = l & 65535;
|
|
1649
1649
|
b = l >>> 16;
|
|
1650
|
-
c =
|
|
1651
|
-
d =
|
|
1652
|
-
|
|
1650
|
+
c = h2 & 65535;
|
|
1651
|
+
d = h2 >>> 16;
|
|
1652
|
+
h2 = hh[0];
|
|
1653
1653
|
l = hl[0];
|
|
1654
1654
|
a += l & 65535;
|
|
1655
1655
|
b += l >>> 16;
|
|
1656
|
-
c +=
|
|
1657
|
-
d +=
|
|
1656
|
+
c += h2 & 65535;
|
|
1657
|
+
d += h2 >>> 16;
|
|
1658
1658
|
b += a >>> 16;
|
|
1659
1659
|
c += b >>> 16;
|
|
1660
1660
|
d += c >>> 16;
|
|
1661
1661
|
hh[0] = ah0 = c & 65535 | d << 16;
|
|
1662
1662
|
hl[0] = al0 = a & 65535 | b << 16;
|
|
1663
|
-
|
|
1663
|
+
h2 = ah1;
|
|
1664
1664
|
l = al1;
|
|
1665
1665
|
a = l & 65535;
|
|
1666
1666
|
b = l >>> 16;
|
|
1667
|
-
c =
|
|
1668
|
-
d =
|
|
1669
|
-
|
|
1667
|
+
c = h2 & 65535;
|
|
1668
|
+
d = h2 >>> 16;
|
|
1669
|
+
h2 = hh[1];
|
|
1670
1670
|
l = hl[1];
|
|
1671
1671
|
a += l & 65535;
|
|
1672
1672
|
b += l >>> 16;
|
|
1673
|
-
c +=
|
|
1674
|
-
d +=
|
|
1673
|
+
c += h2 & 65535;
|
|
1674
|
+
d += h2 >>> 16;
|
|
1675
1675
|
b += a >>> 16;
|
|
1676
1676
|
c += b >>> 16;
|
|
1677
1677
|
d += c >>> 16;
|
|
1678
1678
|
hh[1] = ah1 = c & 65535 | d << 16;
|
|
1679
1679
|
hl[1] = al1 = a & 65535 | b << 16;
|
|
1680
|
-
|
|
1680
|
+
h2 = ah2;
|
|
1681
1681
|
l = al2;
|
|
1682
1682
|
a = l & 65535;
|
|
1683
1683
|
b = l >>> 16;
|
|
1684
|
-
c =
|
|
1685
|
-
d =
|
|
1686
|
-
|
|
1684
|
+
c = h2 & 65535;
|
|
1685
|
+
d = h2 >>> 16;
|
|
1686
|
+
h2 = hh[2];
|
|
1687
1687
|
l = hl[2];
|
|
1688
1688
|
a += l & 65535;
|
|
1689
1689
|
b += l >>> 16;
|
|
1690
|
-
c +=
|
|
1691
|
-
d +=
|
|
1690
|
+
c += h2 & 65535;
|
|
1691
|
+
d += h2 >>> 16;
|
|
1692
1692
|
b += a >>> 16;
|
|
1693
1693
|
c += b >>> 16;
|
|
1694
1694
|
d += c >>> 16;
|
|
1695
1695
|
hh[2] = ah2 = c & 65535 | d << 16;
|
|
1696
1696
|
hl[2] = al2 = a & 65535 | b << 16;
|
|
1697
|
-
|
|
1697
|
+
h2 = ah3;
|
|
1698
1698
|
l = al3;
|
|
1699
1699
|
a = l & 65535;
|
|
1700
1700
|
b = l >>> 16;
|
|
1701
|
-
c =
|
|
1702
|
-
d =
|
|
1703
|
-
|
|
1701
|
+
c = h2 & 65535;
|
|
1702
|
+
d = h2 >>> 16;
|
|
1703
|
+
h2 = hh[3];
|
|
1704
1704
|
l = hl[3];
|
|
1705
1705
|
a += l & 65535;
|
|
1706
1706
|
b += l >>> 16;
|
|
1707
|
-
c +=
|
|
1708
|
-
d +=
|
|
1707
|
+
c += h2 & 65535;
|
|
1708
|
+
d += h2 >>> 16;
|
|
1709
1709
|
b += a >>> 16;
|
|
1710
1710
|
c += b >>> 16;
|
|
1711
1711
|
d += c >>> 16;
|
|
1712
1712
|
hh[3] = ah3 = c & 65535 | d << 16;
|
|
1713
1713
|
hl[3] = al3 = a & 65535 | b << 16;
|
|
1714
|
-
|
|
1714
|
+
h2 = ah4;
|
|
1715
1715
|
l = al4;
|
|
1716
1716
|
a = l & 65535;
|
|
1717
1717
|
b = l >>> 16;
|
|
1718
|
-
c =
|
|
1719
|
-
d =
|
|
1720
|
-
|
|
1718
|
+
c = h2 & 65535;
|
|
1719
|
+
d = h2 >>> 16;
|
|
1720
|
+
h2 = hh[4];
|
|
1721
1721
|
l = hl[4];
|
|
1722
1722
|
a += l & 65535;
|
|
1723
1723
|
b += l >>> 16;
|
|
1724
|
-
c +=
|
|
1725
|
-
d +=
|
|
1724
|
+
c += h2 & 65535;
|
|
1725
|
+
d += h2 >>> 16;
|
|
1726
1726
|
b += a >>> 16;
|
|
1727
1727
|
c += b >>> 16;
|
|
1728
1728
|
d += c >>> 16;
|
|
1729
1729
|
hh[4] = ah4 = c & 65535 | d << 16;
|
|
1730
1730
|
hl[4] = al4 = a & 65535 | b << 16;
|
|
1731
|
-
|
|
1731
|
+
h2 = ah5;
|
|
1732
1732
|
l = al5;
|
|
1733
1733
|
a = l & 65535;
|
|
1734
1734
|
b = l >>> 16;
|
|
1735
|
-
c =
|
|
1736
|
-
d =
|
|
1737
|
-
|
|
1735
|
+
c = h2 & 65535;
|
|
1736
|
+
d = h2 >>> 16;
|
|
1737
|
+
h2 = hh[5];
|
|
1738
1738
|
l = hl[5];
|
|
1739
1739
|
a += l & 65535;
|
|
1740
1740
|
b += l >>> 16;
|
|
1741
|
-
c +=
|
|
1742
|
-
d +=
|
|
1741
|
+
c += h2 & 65535;
|
|
1742
|
+
d += h2 >>> 16;
|
|
1743
1743
|
b += a >>> 16;
|
|
1744
1744
|
c += b >>> 16;
|
|
1745
1745
|
d += c >>> 16;
|
|
1746
1746
|
hh[5] = ah5 = c & 65535 | d << 16;
|
|
1747
1747
|
hl[5] = al5 = a & 65535 | b << 16;
|
|
1748
|
-
|
|
1748
|
+
h2 = ah6;
|
|
1749
1749
|
l = al6;
|
|
1750
1750
|
a = l & 65535;
|
|
1751
1751
|
b = l >>> 16;
|
|
1752
|
-
c =
|
|
1753
|
-
d =
|
|
1754
|
-
|
|
1752
|
+
c = h2 & 65535;
|
|
1753
|
+
d = h2 >>> 16;
|
|
1754
|
+
h2 = hh[6];
|
|
1755
1755
|
l = hl[6];
|
|
1756
1756
|
a += l & 65535;
|
|
1757
1757
|
b += l >>> 16;
|
|
1758
|
-
c +=
|
|
1759
|
-
d +=
|
|
1758
|
+
c += h2 & 65535;
|
|
1759
|
+
d += h2 >>> 16;
|
|
1760
1760
|
b += a >>> 16;
|
|
1761
1761
|
c += b >>> 16;
|
|
1762
1762
|
d += c >>> 16;
|
|
1763
1763
|
hh[6] = ah6 = c & 65535 | d << 16;
|
|
1764
1764
|
hl[6] = al6 = a & 65535 | b << 16;
|
|
1765
|
-
|
|
1765
|
+
h2 = ah7;
|
|
1766
1766
|
l = al7;
|
|
1767
1767
|
a = l & 65535;
|
|
1768
1768
|
b = l >>> 16;
|
|
1769
|
-
c =
|
|
1770
|
-
d =
|
|
1771
|
-
|
|
1769
|
+
c = h2 & 65535;
|
|
1770
|
+
d = h2 >>> 16;
|
|
1771
|
+
h2 = hh[7];
|
|
1772
1772
|
l = hl[7];
|
|
1773
1773
|
a += l & 65535;
|
|
1774
1774
|
b += l >>> 16;
|
|
1775
|
-
c +=
|
|
1776
|
-
d +=
|
|
1775
|
+
c += h2 & 65535;
|
|
1776
|
+
d += h2 >>> 16;
|
|
1777
1777
|
b += a >>> 16;
|
|
1778
1778
|
c += b >>> 16;
|
|
1779
1779
|
d += c >>> 16;
|
|
@@ -1813,8 +1813,8 @@ var require_nacl_fast = __commonJS({
|
|
|
1813
1813
|
for (i = 0; i < 8; i++) ts64(out, 8 * i, hh[i], hl[i]);
|
|
1814
1814
|
return 0;
|
|
1815
1815
|
}
|
|
1816
|
-
function
|
|
1817
|
-
var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(),
|
|
1816
|
+
function add2(p, q) {
|
|
1817
|
+
var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g2 = gf(), h2 = gf(), t = gf();
|
|
1818
1818
|
Z(a, p[1], p[0]);
|
|
1819
1819
|
Z(t, q[1], q[0]);
|
|
1820
1820
|
M(a, a, t);
|
|
@@ -1827,12 +1827,12 @@ var require_nacl_fast = __commonJS({
|
|
|
1827
1827
|
A(d, d, d);
|
|
1828
1828
|
Z(e, b, a);
|
|
1829
1829
|
Z(f, d, c);
|
|
1830
|
-
A(
|
|
1831
|
-
A(
|
|
1830
|
+
A(g2, d, c);
|
|
1831
|
+
A(h2, b, a);
|
|
1832
1832
|
M(p[0], e, f);
|
|
1833
|
-
M(p[1],
|
|
1834
|
-
M(p[2],
|
|
1835
|
-
M(p[3], e,
|
|
1833
|
+
M(p[1], h2, g2);
|
|
1834
|
+
M(p[2], g2, f);
|
|
1835
|
+
M(p[3], e, h2);
|
|
1836
1836
|
}
|
|
1837
1837
|
function cswap(p, q, b) {
|
|
1838
1838
|
var i;
|
|
@@ -1857,8 +1857,8 @@ var require_nacl_fast = __commonJS({
|
|
|
1857
1857
|
for (i = 255; i >= 0; --i) {
|
|
1858
1858
|
b = s[i / 8 | 0] >> (i & 7) & 1;
|
|
1859
1859
|
cswap(p, q, b);
|
|
1860
|
-
|
|
1861
|
-
|
|
1860
|
+
add2(q, p);
|
|
1861
|
+
add2(p, p);
|
|
1862
1862
|
cswap(p, q, b);
|
|
1863
1863
|
}
|
|
1864
1864
|
}
|
|
@@ -1909,14 +1909,14 @@ var require_nacl_fast = __commonJS({
|
|
|
1909
1909
|
r[i] = x[i] & 255;
|
|
1910
1910
|
}
|
|
1911
1911
|
}
|
|
1912
|
-
function
|
|
1912
|
+
function reduce2(r) {
|
|
1913
1913
|
var x = new Float64Array(64), i;
|
|
1914
1914
|
for (i = 0; i < 64; i++) x[i] = r[i];
|
|
1915
1915
|
for (i = 0; i < 64; i++) r[i] = 0;
|
|
1916
1916
|
modL(r, x);
|
|
1917
1917
|
}
|
|
1918
1918
|
function crypto_sign(sm, m, n, sk) {
|
|
1919
|
-
var d = new Uint8Array(64),
|
|
1919
|
+
var d = new Uint8Array(64), h2 = new Uint8Array(64), r = new Uint8Array(64);
|
|
1920
1920
|
var i, j, x = new Float64Array(64);
|
|
1921
1921
|
var p = [gf(), gf(), gf(), gf()];
|
|
1922
1922
|
crypto_hash(d, sk, 32);
|
|
@@ -1927,17 +1927,17 @@ var require_nacl_fast = __commonJS({
|
|
|
1927
1927
|
for (i = 0; i < n; i++) sm[64 + i] = m[i];
|
|
1928
1928
|
for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
|
|
1929
1929
|
crypto_hash(r, sm.subarray(32), n + 32);
|
|
1930
|
-
|
|
1930
|
+
reduce2(r);
|
|
1931
1931
|
scalarbase(p, r);
|
|
1932
1932
|
pack(sm, p);
|
|
1933
1933
|
for (i = 32; i < 64; i++) sm[i] = sk[i];
|
|
1934
|
-
crypto_hash(
|
|
1935
|
-
|
|
1934
|
+
crypto_hash(h2, sm, n + 64);
|
|
1935
|
+
reduce2(h2);
|
|
1936
1936
|
for (i = 0; i < 64; i++) x[i] = 0;
|
|
1937
1937
|
for (i = 0; i < 32; i++) x[i] = r[i];
|
|
1938
1938
|
for (i = 0; i < 32; i++) {
|
|
1939
1939
|
for (j = 0; j < 32; j++) {
|
|
1940
|
-
x[i + j] +=
|
|
1940
|
+
x[i + j] += h2[i] * d[j];
|
|
1941
1941
|
}
|
|
1942
1942
|
}
|
|
1943
1943
|
modL(sm.subarray(32), x);
|
|
@@ -1973,17 +1973,17 @@ var require_nacl_fast = __commonJS({
|
|
|
1973
1973
|
}
|
|
1974
1974
|
function crypto_sign_open(m, sm, n, pk) {
|
|
1975
1975
|
var i;
|
|
1976
|
-
var t = new Uint8Array(32),
|
|
1976
|
+
var t = new Uint8Array(32), h2 = new Uint8Array(64);
|
|
1977
1977
|
var p = [gf(), gf(), gf(), gf()], q = [gf(), gf(), gf(), gf()];
|
|
1978
1978
|
if (n < 64) return -1;
|
|
1979
1979
|
if (unpackneg(q, pk)) return -1;
|
|
1980
1980
|
for (i = 0; i < n; i++) m[i] = sm[i];
|
|
1981
1981
|
for (i = 0; i < 32; i++) m[i + 32] = pk[i];
|
|
1982
|
-
crypto_hash(
|
|
1983
|
-
|
|
1984
|
-
scalarmult(p, q,
|
|
1982
|
+
crypto_hash(h2, m, n);
|
|
1983
|
+
reduce2(h2);
|
|
1984
|
+
scalarmult(p, q, h2);
|
|
1985
1985
|
scalarbase(q, sm.subarray(32));
|
|
1986
|
-
|
|
1986
|
+
add2(p, q);
|
|
1987
1987
|
pack(t, p);
|
|
1988
1988
|
n -= 64;
|
|
1989
1989
|
if (crypto_verify_32(sm, 0, t, 0)) {
|
|
@@ -2044,7 +2044,7 @@ var require_nacl_fast = __commonJS({
|
|
|
2044
2044
|
S,
|
|
2045
2045
|
Z,
|
|
2046
2046
|
pow2523,
|
|
2047
|
-
add,
|
|
2047
|
+
add: add2,
|
|
2048
2048
|
set25519,
|
|
2049
2049
|
modL,
|
|
2050
2050
|
scalarmult,
|
|
@@ -2215,9 +2215,9 @@ var require_nacl_fast = __commonJS({
|
|
|
2215
2215
|
nacl2.sign.signatureLength = crypto_sign_BYTES;
|
|
2216
2216
|
nacl2.hash = function(msg) {
|
|
2217
2217
|
checkArrayTypes(msg);
|
|
2218
|
-
var
|
|
2219
|
-
crypto_hash(
|
|
2220
|
-
return
|
|
2218
|
+
var h2 = new Uint8Array(crypto_hash_BYTES);
|
|
2219
|
+
crypto_hash(h2, msg, msg.length);
|
|
2220
|
+
return h2;
|
|
2221
2221
|
};
|
|
2222
2222
|
nacl2.hash.hashLength = crypto_hash_BYTES;
|
|
2223
2223
|
nacl2.verify = function(x, y) {
|
|
@@ -2230,22 +2230,22 @@ var require_nacl_fast = __commonJS({
|
|
|
2230
2230
|
randombytes = fn;
|
|
2231
2231
|
};
|
|
2232
2232
|
(function() {
|
|
2233
|
-
var
|
|
2234
|
-
if (
|
|
2233
|
+
var crypto2 = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
|
|
2234
|
+
if (crypto2 && crypto2.getRandomValues) {
|
|
2235
2235
|
var QUOTA = 65536;
|
|
2236
2236
|
nacl2.setPRNG(function(x, n) {
|
|
2237
2237
|
var i, v = new Uint8Array(n);
|
|
2238
2238
|
for (i = 0; i < n; i += QUOTA) {
|
|
2239
|
-
|
|
2239
|
+
crypto2.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
|
|
2240
2240
|
}
|
|
2241
2241
|
for (i = 0; i < n; i++) x[i] = v[i];
|
|
2242
2242
|
cleanup(v);
|
|
2243
2243
|
});
|
|
2244
2244
|
} else if (typeof __require !== "undefined") {
|
|
2245
|
-
|
|
2246
|
-
if (
|
|
2245
|
+
crypto2 = __require("crypto");
|
|
2246
|
+
if (crypto2 && crypto2.randomBytes) {
|
|
2247
2247
|
nacl2.setPRNG(function(x, n) {
|
|
2248
|
-
var i, v =
|
|
2248
|
+
var i, v = crypto2.randomBytes(n);
|
|
2249
2249
|
for (i = 0; i < n; i++) x[i] = v[i];
|
|
2250
2250
|
cleanup(v);
|
|
2251
2251
|
});
|
|
@@ -2326,6 +2326,1603 @@ var require_nacl_util = __commonJS({
|
|
|
2326
2326
|
// src/index.ts
|
|
2327
2327
|
var import_tweetnacl = __toESM(require_nacl_fast());
|
|
2328
2328
|
var import_tweetnacl_util = __toESM(require_nacl_util());
|
|
2329
|
+
|
|
2330
|
+
// node_modules/mlkem/esm/src/errors.js
|
|
2331
|
+
var MlKemError = class extends Error {
|
|
2332
|
+
constructor(e) {
|
|
2333
|
+
let message;
|
|
2334
|
+
if (e instanceof Error) {
|
|
2335
|
+
message = e.message;
|
|
2336
|
+
} else if (typeof e === "string") {
|
|
2337
|
+
message = e;
|
|
2338
|
+
} else {
|
|
2339
|
+
message = "";
|
|
2340
|
+
}
|
|
2341
|
+
super(message);
|
|
2342
|
+
this.name = this.constructor.name;
|
|
2343
|
+
}
|
|
2344
|
+
};
|
|
2345
|
+
|
|
2346
|
+
// node_modules/mlkem/esm/src/consts.js
|
|
2347
|
+
var N = 256;
|
|
2348
|
+
var Q = 3329;
|
|
2349
|
+
var Q_INV = 62209;
|
|
2350
|
+
var NTT_ZETAS = [
|
|
2351
|
+
2285,
|
|
2352
|
+
2571,
|
|
2353
|
+
2970,
|
|
2354
|
+
1812,
|
|
2355
|
+
1493,
|
|
2356
|
+
1422,
|
|
2357
|
+
287,
|
|
2358
|
+
202,
|
|
2359
|
+
3158,
|
|
2360
|
+
622,
|
|
2361
|
+
1577,
|
|
2362
|
+
182,
|
|
2363
|
+
962,
|
|
2364
|
+
2127,
|
|
2365
|
+
1855,
|
|
2366
|
+
1468,
|
|
2367
|
+
573,
|
|
2368
|
+
2004,
|
|
2369
|
+
264,
|
|
2370
|
+
383,
|
|
2371
|
+
2500,
|
|
2372
|
+
1458,
|
|
2373
|
+
1727,
|
|
2374
|
+
3199,
|
|
2375
|
+
2648,
|
|
2376
|
+
1017,
|
|
2377
|
+
732,
|
|
2378
|
+
608,
|
|
2379
|
+
1787,
|
|
2380
|
+
411,
|
|
2381
|
+
3124,
|
|
2382
|
+
1758,
|
|
2383
|
+
1223,
|
|
2384
|
+
652,
|
|
2385
|
+
2777,
|
|
2386
|
+
1015,
|
|
2387
|
+
2036,
|
|
2388
|
+
1491,
|
|
2389
|
+
3047,
|
|
2390
|
+
1785,
|
|
2391
|
+
516,
|
|
2392
|
+
3321,
|
|
2393
|
+
3009,
|
|
2394
|
+
2663,
|
|
2395
|
+
1711,
|
|
2396
|
+
2167,
|
|
2397
|
+
126,
|
|
2398
|
+
1469,
|
|
2399
|
+
2476,
|
|
2400
|
+
3239,
|
|
2401
|
+
3058,
|
|
2402
|
+
830,
|
|
2403
|
+
107,
|
|
2404
|
+
1908,
|
|
2405
|
+
3082,
|
|
2406
|
+
2378,
|
|
2407
|
+
2931,
|
|
2408
|
+
961,
|
|
2409
|
+
1821,
|
|
2410
|
+
2604,
|
|
2411
|
+
448,
|
|
2412
|
+
2264,
|
|
2413
|
+
677,
|
|
2414
|
+
2054,
|
|
2415
|
+
2226,
|
|
2416
|
+
430,
|
|
2417
|
+
555,
|
|
2418
|
+
843,
|
|
2419
|
+
2078,
|
|
2420
|
+
871,
|
|
2421
|
+
1550,
|
|
2422
|
+
105,
|
|
2423
|
+
422,
|
|
2424
|
+
587,
|
|
2425
|
+
177,
|
|
2426
|
+
3094,
|
|
2427
|
+
3038,
|
|
2428
|
+
2869,
|
|
2429
|
+
1574,
|
|
2430
|
+
1653,
|
|
2431
|
+
3083,
|
|
2432
|
+
778,
|
|
2433
|
+
1159,
|
|
2434
|
+
3182,
|
|
2435
|
+
2552,
|
|
2436
|
+
1483,
|
|
2437
|
+
2727,
|
|
2438
|
+
1119,
|
|
2439
|
+
1739,
|
|
2440
|
+
644,
|
|
2441
|
+
2457,
|
|
2442
|
+
349,
|
|
2443
|
+
418,
|
|
2444
|
+
329,
|
|
2445
|
+
3173,
|
|
2446
|
+
3254,
|
|
2447
|
+
817,
|
|
2448
|
+
1097,
|
|
2449
|
+
603,
|
|
2450
|
+
610,
|
|
2451
|
+
1322,
|
|
2452
|
+
2044,
|
|
2453
|
+
1864,
|
|
2454
|
+
384,
|
|
2455
|
+
2114,
|
|
2456
|
+
3193,
|
|
2457
|
+
1218,
|
|
2458
|
+
1994,
|
|
2459
|
+
2455,
|
|
2460
|
+
220,
|
|
2461
|
+
2142,
|
|
2462
|
+
1670,
|
|
2463
|
+
2144,
|
|
2464
|
+
1799,
|
|
2465
|
+
2051,
|
|
2466
|
+
794,
|
|
2467
|
+
1819,
|
|
2468
|
+
2475,
|
|
2469
|
+
2459,
|
|
2470
|
+
478,
|
|
2471
|
+
3221,
|
|
2472
|
+
3021,
|
|
2473
|
+
996,
|
|
2474
|
+
991,
|
|
2475
|
+
958,
|
|
2476
|
+
1869,
|
|
2477
|
+
1522,
|
|
2478
|
+
1628
|
|
2479
|
+
];
|
|
2480
|
+
var NTT_ZETAS_INV = [
|
|
2481
|
+
1701,
|
|
2482
|
+
1807,
|
|
2483
|
+
1460,
|
|
2484
|
+
2371,
|
|
2485
|
+
2338,
|
|
2486
|
+
2333,
|
|
2487
|
+
308,
|
|
2488
|
+
108,
|
|
2489
|
+
2851,
|
|
2490
|
+
870,
|
|
2491
|
+
854,
|
|
2492
|
+
1510,
|
|
2493
|
+
2535,
|
|
2494
|
+
1278,
|
|
2495
|
+
1530,
|
|
2496
|
+
1185,
|
|
2497
|
+
1659,
|
|
2498
|
+
1187,
|
|
2499
|
+
3109,
|
|
2500
|
+
874,
|
|
2501
|
+
1335,
|
|
2502
|
+
2111,
|
|
2503
|
+
136,
|
|
2504
|
+
1215,
|
|
2505
|
+
2945,
|
|
2506
|
+
1465,
|
|
2507
|
+
1285,
|
|
2508
|
+
2007,
|
|
2509
|
+
2719,
|
|
2510
|
+
2726,
|
|
2511
|
+
2232,
|
|
2512
|
+
2512,
|
|
2513
|
+
75,
|
|
2514
|
+
156,
|
|
2515
|
+
3e3,
|
|
2516
|
+
2911,
|
|
2517
|
+
2980,
|
|
2518
|
+
872,
|
|
2519
|
+
2685,
|
|
2520
|
+
1590,
|
|
2521
|
+
2210,
|
|
2522
|
+
602,
|
|
2523
|
+
1846,
|
|
2524
|
+
777,
|
|
2525
|
+
147,
|
|
2526
|
+
2170,
|
|
2527
|
+
2551,
|
|
2528
|
+
246,
|
|
2529
|
+
1676,
|
|
2530
|
+
1755,
|
|
2531
|
+
460,
|
|
2532
|
+
291,
|
|
2533
|
+
235,
|
|
2534
|
+
3152,
|
|
2535
|
+
2742,
|
|
2536
|
+
2907,
|
|
2537
|
+
3224,
|
|
2538
|
+
1779,
|
|
2539
|
+
2458,
|
|
2540
|
+
1251,
|
|
2541
|
+
2486,
|
|
2542
|
+
2774,
|
|
2543
|
+
2899,
|
|
2544
|
+
1103,
|
|
2545
|
+
1275,
|
|
2546
|
+
2652,
|
|
2547
|
+
1065,
|
|
2548
|
+
2881,
|
|
2549
|
+
725,
|
|
2550
|
+
1508,
|
|
2551
|
+
2368,
|
|
2552
|
+
398,
|
|
2553
|
+
951,
|
|
2554
|
+
247,
|
|
2555
|
+
1421,
|
|
2556
|
+
3222,
|
|
2557
|
+
2499,
|
|
2558
|
+
271,
|
|
2559
|
+
90,
|
|
2560
|
+
853,
|
|
2561
|
+
1860,
|
|
2562
|
+
3203,
|
|
2563
|
+
1162,
|
|
2564
|
+
1618,
|
|
2565
|
+
666,
|
|
2566
|
+
320,
|
|
2567
|
+
8,
|
|
2568
|
+
2813,
|
|
2569
|
+
1544,
|
|
2570
|
+
282,
|
|
2571
|
+
1838,
|
|
2572
|
+
1293,
|
|
2573
|
+
2314,
|
|
2574
|
+
552,
|
|
2575
|
+
2677,
|
|
2576
|
+
2106,
|
|
2577
|
+
1571,
|
|
2578
|
+
205,
|
|
2579
|
+
2918,
|
|
2580
|
+
1542,
|
|
2581
|
+
2721,
|
|
2582
|
+
2597,
|
|
2583
|
+
2312,
|
|
2584
|
+
681,
|
|
2585
|
+
130,
|
|
2586
|
+
1602,
|
|
2587
|
+
1871,
|
|
2588
|
+
829,
|
|
2589
|
+
2946,
|
|
2590
|
+
3065,
|
|
2591
|
+
1325,
|
|
2592
|
+
2756,
|
|
2593
|
+
1861,
|
|
2594
|
+
1474,
|
|
2595
|
+
1202,
|
|
2596
|
+
2367,
|
|
2597
|
+
3147,
|
|
2598
|
+
1752,
|
|
2599
|
+
2707,
|
|
2600
|
+
171,
|
|
2601
|
+
3127,
|
|
2602
|
+
3042,
|
|
2603
|
+
1907,
|
|
2604
|
+
1836,
|
|
2605
|
+
1517,
|
|
2606
|
+
359,
|
|
2607
|
+
758,
|
|
2608
|
+
1441
|
|
2609
|
+
];
|
|
2610
|
+
|
|
2611
|
+
// node_modules/mlkem/esm/src/sha3/_u64.js
|
|
2612
|
+
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
2613
|
+
var _32n = /* @__PURE__ */ BigInt(32);
|
|
2614
|
+
function fromBig(n, le = false) {
|
|
2615
|
+
if (le) {
|
|
2616
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
2617
|
+
}
|
|
2618
|
+
return {
|
|
2619
|
+
h: Number(n >> _32n & U32_MASK64) | 0,
|
|
2620
|
+
l: Number(n & U32_MASK64) | 0
|
|
2621
|
+
};
|
|
2622
|
+
}
|
|
2623
|
+
function split(lst, le = false) {
|
|
2624
|
+
const len = lst.length;
|
|
2625
|
+
const Ah = new Uint32Array(len);
|
|
2626
|
+
const Al = new Uint32Array(len);
|
|
2627
|
+
for (let i = 0; i < len; i++) {
|
|
2628
|
+
const { h: h2, l } = fromBig(lst[i], le);
|
|
2629
|
+
[Ah[i], Al[i]] = [h2, l];
|
|
2630
|
+
}
|
|
2631
|
+
return [Ah, Al];
|
|
2632
|
+
}
|
|
2633
|
+
var rotlSH = (h2, l, s) => h2 << s | l >>> 32 - s;
|
|
2634
|
+
var rotlSL = (h2, l, s) => l << s | h2 >>> 32 - s;
|
|
2635
|
+
var rotlBH = (h2, l, s) => l << s - 32 | h2 >>> 64 - s;
|
|
2636
|
+
var rotlBL = (h2, l, s) => h2 << s - 32 | l >>> 64 - s;
|
|
2637
|
+
|
|
2638
|
+
// node_modules/mlkem/esm/src/sha3/utils.js
|
|
2639
|
+
function isBytes(a) {
|
|
2640
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
2641
|
+
}
|
|
2642
|
+
function anumber(n, title = "") {
|
|
2643
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
2644
|
+
const prefix = title && `"${title}" `;
|
|
2645
|
+
throw new Error(`${prefix}expected integer >0, got ${n}`);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
function abytes(value, length, title = "") {
|
|
2649
|
+
const bytes = isBytes(value);
|
|
2650
|
+
const len = value?.length;
|
|
2651
|
+
const needsLen = length !== void 0;
|
|
2652
|
+
if (!bytes || needsLen && len !== length) {
|
|
2653
|
+
const prefix = title && `"${title}" `;
|
|
2654
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
2655
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
2656
|
+
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
2657
|
+
}
|
|
2658
|
+
return value;
|
|
2659
|
+
}
|
|
2660
|
+
function aexists(instance, checkFinished = true) {
|
|
2661
|
+
if (instance.destroyed)
|
|
2662
|
+
throw new Error("Hash instance has been destroyed");
|
|
2663
|
+
if (checkFinished && instance.finished) {
|
|
2664
|
+
throw new Error("Hash#digest() has already been called");
|
|
2665
|
+
}
|
|
2666
|
+
}
|
|
2667
|
+
function aoutput(out, instance) {
|
|
2668
|
+
abytes(out, void 0, "digestInto() output");
|
|
2669
|
+
const min = instance.outputLen;
|
|
2670
|
+
if (out.length < min) {
|
|
2671
|
+
throw new Error('"digestInto() output" expected to be of length >=' + min);
|
|
2672
|
+
}
|
|
2673
|
+
}
|
|
2674
|
+
function u32(arr) {
|
|
2675
|
+
return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
|
|
2676
|
+
}
|
|
2677
|
+
function clean(...arrays) {
|
|
2678
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
2679
|
+
arrays[i].fill(0);
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
|
|
2683
|
+
function byteSwap(word) {
|
|
2684
|
+
return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
|
|
2685
|
+
}
|
|
2686
|
+
function byteSwap32(arr) {
|
|
2687
|
+
for (let i = 0; i < arr.length; i++) {
|
|
2688
|
+
arr[i] = byteSwap(arr[i]);
|
|
2689
|
+
}
|
|
2690
|
+
return arr;
|
|
2691
|
+
}
|
|
2692
|
+
var swap32IfBE = isLE ? (u) => u : byteSwap32;
|
|
2693
|
+
function createHasher(hashCons, info = {}) {
|
|
2694
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
2695
|
+
const tmp = hashCons(void 0);
|
|
2696
|
+
hashC.outputLen = tmp.outputLen;
|
|
2697
|
+
hashC.blockLen = tmp.blockLen;
|
|
2698
|
+
hashC.create = (opts) => hashCons(opts);
|
|
2699
|
+
Object.assign(hashC, info);
|
|
2700
|
+
return Object.freeze(hashC);
|
|
2701
|
+
}
|
|
2702
|
+
var oidNist = (suffix) => ({
|
|
2703
|
+
oid: Uint8Array.from([
|
|
2704
|
+
6,
|
|
2705
|
+
9,
|
|
2706
|
+
96,
|
|
2707
|
+
134,
|
|
2708
|
+
72,
|
|
2709
|
+
1,
|
|
2710
|
+
101,
|
|
2711
|
+
3,
|
|
2712
|
+
4,
|
|
2713
|
+
2,
|
|
2714
|
+
suffix
|
|
2715
|
+
])
|
|
2716
|
+
});
|
|
2717
|
+
|
|
2718
|
+
// node_modules/mlkem/esm/src/sha3/sha3.js
|
|
2719
|
+
var _0n = BigInt(0);
|
|
2720
|
+
var _1n = BigInt(1);
|
|
2721
|
+
var _2n = BigInt(2);
|
|
2722
|
+
var _7n = BigInt(7);
|
|
2723
|
+
var _256n = BigInt(256);
|
|
2724
|
+
var _0x71n = BigInt(113);
|
|
2725
|
+
var SHA3_PI = [];
|
|
2726
|
+
var SHA3_ROTL = [];
|
|
2727
|
+
var _SHA3_IOTA = [];
|
|
2728
|
+
for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
|
|
2729
|
+
[x, y] = [y, (2 * x + 3 * y) % 5];
|
|
2730
|
+
SHA3_PI.push(2 * (5 * y + x));
|
|
2731
|
+
SHA3_ROTL.push((round + 1) * (round + 2) / 2 % 64);
|
|
2732
|
+
let t = _0n;
|
|
2733
|
+
for (let j = 0; j < 7; j++) {
|
|
2734
|
+
R = (R << _1n ^ (R >> _7n) * _0x71n) % _256n;
|
|
2735
|
+
if (R & _2n)
|
|
2736
|
+
t ^= _1n << (_1n << BigInt(j)) - _1n;
|
|
2737
|
+
}
|
|
2738
|
+
_SHA3_IOTA.push(t);
|
|
2739
|
+
}
|
|
2740
|
+
var IOTAS = split(_SHA3_IOTA, true);
|
|
2741
|
+
var SHA3_IOTA_H = IOTAS[0];
|
|
2742
|
+
var SHA3_IOTA_L = IOTAS[1];
|
|
2743
|
+
var rotlH = (h2, l, s) => s > 32 ? rotlBH(h2, l, s) : rotlSH(h2, l, s);
|
|
2744
|
+
var rotlL = (h2, l, s) => s > 32 ? rotlBL(h2, l, s) : rotlSL(h2, l, s);
|
|
2745
|
+
function keccakP(s, rounds = 24) {
|
|
2746
|
+
const B = new Uint32Array(5 * 2);
|
|
2747
|
+
for (let round = 24 - rounds; round < 24; round++) {
|
|
2748
|
+
for (let x = 0; x < 10; x++) {
|
|
2749
|
+
B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
|
|
2750
|
+
}
|
|
2751
|
+
for (let x = 0; x < 10; x += 2) {
|
|
2752
|
+
const idx1 = (x + 8) % 10;
|
|
2753
|
+
const idx0 = (x + 2) % 10;
|
|
2754
|
+
const B0 = B[idx0];
|
|
2755
|
+
const B1 = B[idx0 + 1];
|
|
2756
|
+
const Th = rotlH(B0, B1, 1) ^ B[idx1];
|
|
2757
|
+
const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
|
|
2758
|
+
for (let y = 0; y < 50; y += 10) {
|
|
2759
|
+
s[x + y] ^= Th;
|
|
2760
|
+
s[x + y + 1] ^= Tl;
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
let curH = s[2];
|
|
2764
|
+
let curL = s[3];
|
|
2765
|
+
for (let t = 0; t < 24; t++) {
|
|
2766
|
+
const shift = SHA3_ROTL[t];
|
|
2767
|
+
const Th = rotlH(curH, curL, shift);
|
|
2768
|
+
const Tl = rotlL(curH, curL, shift);
|
|
2769
|
+
const PI = SHA3_PI[t];
|
|
2770
|
+
curH = s[PI];
|
|
2771
|
+
curL = s[PI + 1];
|
|
2772
|
+
s[PI] = Th;
|
|
2773
|
+
s[PI + 1] = Tl;
|
|
2774
|
+
}
|
|
2775
|
+
for (let y = 0; y < 50; y += 10) {
|
|
2776
|
+
for (let x = 0; x < 10; x++)
|
|
2777
|
+
B[x] = s[y + x];
|
|
2778
|
+
for (let x = 0; x < 10; x++) {
|
|
2779
|
+
s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
|
|
2780
|
+
}
|
|
2781
|
+
}
|
|
2782
|
+
s[0] ^= SHA3_IOTA_H[round];
|
|
2783
|
+
s[1] ^= SHA3_IOTA_L[round];
|
|
2784
|
+
}
|
|
2785
|
+
clean(B);
|
|
2786
|
+
}
|
|
2787
|
+
var Keccak = class _Keccak {
|
|
2788
|
+
// NOTE: we accept arguments in bytes instead of bits here.
|
|
2789
|
+
constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
|
|
2790
|
+
Object.defineProperty(this, "state", {
|
|
2791
|
+
enumerable: true,
|
|
2792
|
+
configurable: true,
|
|
2793
|
+
writable: true,
|
|
2794
|
+
value: void 0
|
|
2795
|
+
});
|
|
2796
|
+
Object.defineProperty(this, "pos", {
|
|
2797
|
+
enumerable: true,
|
|
2798
|
+
configurable: true,
|
|
2799
|
+
writable: true,
|
|
2800
|
+
value: 0
|
|
2801
|
+
});
|
|
2802
|
+
Object.defineProperty(this, "posOut", {
|
|
2803
|
+
enumerable: true,
|
|
2804
|
+
configurable: true,
|
|
2805
|
+
writable: true,
|
|
2806
|
+
value: 0
|
|
2807
|
+
});
|
|
2808
|
+
Object.defineProperty(this, "finished", {
|
|
2809
|
+
enumerable: true,
|
|
2810
|
+
configurable: true,
|
|
2811
|
+
writable: true,
|
|
2812
|
+
value: false
|
|
2813
|
+
});
|
|
2814
|
+
Object.defineProperty(this, "state32", {
|
|
2815
|
+
enumerable: true,
|
|
2816
|
+
configurable: true,
|
|
2817
|
+
writable: true,
|
|
2818
|
+
value: void 0
|
|
2819
|
+
});
|
|
2820
|
+
Object.defineProperty(this, "destroyed", {
|
|
2821
|
+
enumerable: true,
|
|
2822
|
+
configurable: true,
|
|
2823
|
+
writable: true,
|
|
2824
|
+
value: false
|
|
2825
|
+
});
|
|
2826
|
+
Object.defineProperty(this, "blockLen", {
|
|
2827
|
+
enumerable: true,
|
|
2828
|
+
configurable: true,
|
|
2829
|
+
writable: true,
|
|
2830
|
+
value: void 0
|
|
2831
|
+
});
|
|
2832
|
+
Object.defineProperty(this, "suffix", {
|
|
2833
|
+
enumerable: true,
|
|
2834
|
+
configurable: true,
|
|
2835
|
+
writable: true,
|
|
2836
|
+
value: void 0
|
|
2837
|
+
});
|
|
2838
|
+
Object.defineProperty(this, "outputLen", {
|
|
2839
|
+
enumerable: true,
|
|
2840
|
+
configurable: true,
|
|
2841
|
+
writable: true,
|
|
2842
|
+
value: void 0
|
|
2843
|
+
});
|
|
2844
|
+
Object.defineProperty(this, "enableXOF", {
|
|
2845
|
+
enumerable: true,
|
|
2846
|
+
configurable: true,
|
|
2847
|
+
writable: true,
|
|
2848
|
+
value: false
|
|
2849
|
+
});
|
|
2850
|
+
Object.defineProperty(this, "rounds", {
|
|
2851
|
+
enumerable: true,
|
|
2852
|
+
configurable: true,
|
|
2853
|
+
writable: true,
|
|
2854
|
+
value: void 0
|
|
2855
|
+
});
|
|
2856
|
+
this.blockLen = blockLen;
|
|
2857
|
+
this.suffix = suffix;
|
|
2858
|
+
this.outputLen = outputLen;
|
|
2859
|
+
this.enableXOF = enableXOF;
|
|
2860
|
+
this.rounds = rounds;
|
|
2861
|
+
anumber(outputLen, "outputLen");
|
|
2862
|
+
if (!(0 < blockLen && blockLen < 200)) {
|
|
2863
|
+
throw new Error("only keccak-f1600 function is supported");
|
|
2864
|
+
}
|
|
2865
|
+
this.state = new Uint8Array(200);
|
|
2866
|
+
this.state32 = u32(this.state);
|
|
2867
|
+
}
|
|
2868
|
+
clone() {
|
|
2869
|
+
return this._cloneInto();
|
|
2870
|
+
}
|
|
2871
|
+
keccak() {
|
|
2872
|
+
swap32IfBE(this.state32);
|
|
2873
|
+
keccakP(this.state32, this.rounds);
|
|
2874
|
+
swap32IfBE(this.state32);
|
|
2875
|
+
this.posOut = 0;
|
|
2876
|
+
this.pos = 0;
|
|
2877
|
+
}
|
|
2878
|
+
update(data) {
|
|
2879
|
+
aexists(this);
|
|
2880
|
+
abytes(data);
|
|
2881
|
+
const { blockLen, state } = this;
|
|
2882
|
+
const len = data.length;
|
|
2883
|
+
for (let pos = 0; pos < len; ) {
|
|
2884
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
2885
|
+
for (let i = 0; i < take; i++)
|
|
2886
|
+
state[this.pos++] ^= data[pos++];
|
|
2887
|
+
if (this.pos === blockLen)
|
|
2888
|
+
this.keccak();
|
|
2889
|
+
}
|
|
2890
|
+
return this;
|
|
2891
|
+
}
|
|
2892
|
+
finish() {
|
|
2893
|
+
if (this.finished)
|
|
2894
|
+
return;
|
|
2895
|
+
this.finished = true;
|
|
2896
|
+
const { state, suffix, pos, blockLen } = this;
|
|
2897
|
+
state[pos] ^= suffix;
|
|
2898
|
+
if ((suffix & 128) !== 0 && pos === blockLen - 1)
|
|
2899
|
+
this.keccak();
|
|
2900
|
+
state[blockLen - 1] ^= 128;
|
|
2901
|
+
this.keccak();
|
|
2902
|
+
}
|
|
2903
|
+
writeInto(out) {
|
|
2904
|
+
aexists(this, false);
|
|
2905
|
+
abytes(out);
|
|
2906
|
+
this.finish();
|
|
2907
|
+
const bufferOut = this.state;
|
|
2908
|
+
const { blockLen } = this;
|
|
2909
|
+
for (let pos = 0, len = out.length; pos < len; ) {
|
|
2910
|
+
if (this.posOut >= blockLen)
|
|
2911
|
+
this.keccak();
|
|
2912
|
+
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
2913
|
+
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
2914
|
+
this.posOut += take;
|
|
2915
|
+
pos += take;
|
|
2916
|
+
}
|
|
2917
|
+
return out;
|
|
2918
|
+
}
|
|
2919
|
+
xofInto(out) {
|
|
2920
|
+
if (!this.enableXOF) {
|
|
2921
|
+
throw new Error("XOF is not possible for this instance");
|
|
2922
|
+
}
|
|
2923
|
+
return this.writeInto(out);
|
|
2924
|
+
}
|
|
2925
|
+
xof(bytes) {
|
|
2926
|
+
anumber(bytes);
|
|
2927
|
+
return this.xofInto(new Uint8Array(bytes));
|
|
2928
|
+
}
|
|
2929
|
+
digestInto(out) {
|
|
2930
|
+
aoutput(out, this);
|
|
2931
|
+
if (this.finished)
|
|
2932
|
+
throw new Error("digest() was already called");
|
|
2933
|
+
this.writeInto(out);
|
|
2934
|
+
this.destroy();
|
|
2935
|
+
return out;
|
|
2936
|
+
}
|
|
2937
|
+
digest() {
|
|
2938
|
+
return this.digestInto(new Uint8Array(this.outputLen));
|
|
2939
|
+
}
|
|
2940
|
+
destroy() {
|
|
2941
|
+
this.destroyed = true;
|
|
2942
|
+
clean(this.state);
|
|
2943
|
+
}
|
|
2944
|
+
_cloneInto(to) {
|
|
2945
|
+
const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
|
|
2946
|
+
to || (to = new _Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
|
|
2947
|
+
to.state32.set(this.state32);
|
|
2948
|
+
to.pos = this.pos;
|
|
2949
|
+
to.posOut = this.posOut;
|
|
2950
|
+
to.finished = this.finished;
|
|
2951
|
+
to.rounds = rounds;
|
|
2952
|
+
to.suffix = suffix;
|
|
2953
|
+
to.outputLen = outputLen;
|
|
2954
|
+
to.enableXOF = enableXOF;
|
|
2955
|
+
to.destroyed = this.destroyed;
|
|
2956
|
+
return to;
|
|
2957
|
+
}
|
|
2958
|
+
};
|
|
2959
|
+
var genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info);
|
|
2960
|
+
var sha3_256 = /* @__PURE__ */ genKeccak(
|
|
2961
|
+
6,
|
|
2962
|
+
136,
|
|
2963
|
+
32,
|
|
2964
|
+
/* @__PURE__ */ oidNist(8)
|
|
2965
|
+
);
|
|
2966
|
+
var sha3_512 = /* @__PURE__ */ genKeccak(
|
|
2967
|
+
6,
|
|
2968
|
+
72,
|
|
2969
|
+
64,
|
|
2970
|
+
/* @__PURE__ */ oidNist(10)
|
|
2971
|
+
);
|
|
2972
|
+
var genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === void 0 ? outputLen : opts.dkLen, true), info);
|
|
2973
|
+
var shake128 = /* @__PURE__ */ genShake(31, 168, 16, /* @__PURE__ */ oidNist(11));
|
|
2974
|
+
var shake256 = /* @__PURE__ */ genShake(31, 136, 32, /* @__PURE__ */ oidNist(12));
|
|
2975
|
+
|
|
2976
|
+
// node_modules/mlkem/esm/_dnt.shims.js
|
|
2977
|
+
var dntGlobals = {};
|
|
2978
|
+
var dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
|
|
2979
|
+
function createMergeProxy(baseObj, extObj) {
|
|
2980
|
+
return new Proxy(baseObj, {
|
|
2981
|
+
get(_target, prop, _receiver) {
|
|
2982
|
+
if (prop in extObj) {
|
|
2983
|
+
return extObj[prop];
|
|
2984
|
+
} else {
|
|
2985
|
+
return baseObj[prop];
|
|
2986
|
+
}
|
|
2987
|
+
},
|
|
2988
|
+
set(_target, prop, value) {
|
|
2989
|
+
if (prop in extObj) {
|
|
2990
|
+
delete extObj[prop];
|
|
2991
|
+
}
|
|
2992
|
+
baseObj[prop] = value;
|
|
2993
|
+
return true;
|
|
2994
|
+
},
|
|
2995
|
+
deleteProperty(_target, prop) {
|
|
2996
|
+
let success = false;
|
|
2997
|
+
if (prop in extObj) {
|
|
2998
|
+
delete extObj[prop];
|
|
2999
|
+
success = true;
|
|
3000
|
+
}
|
|
3001
|
+
if (prop in baseObj) {
|
|
3002
|
+
delete baseObj[prop];
|
|
3003
|
+
success = true;
|
|
3004
|
+
}
|
|
3005
|
+
return success;
|
|
3006
|
+
},
|
|
3007
|
+
ownKeys(_target) {
|
|
3008
|
+
const baseKeys = Reflect.ownKeys(baseObj);
|
|
3009
|
+
const extKeys = Reflect.ownKeys(extObj);
|
|
3010
|
+
const extKeysSet = new Set(extKeys);
|
|
3011
|
+
return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
|
|
3012
|
+
},
|
|
3013
|
+
defineProperty(_target, prop, desc) {
|
|
3014
|
+
if (prop in extObj) {
|
|
3015
|
+
delete extObj[prop];
|
|
3016
|
+
}
|
|
3017
|
+
Reflect.defineProperty(baseObj, prop, desc);
|
|
3018
|
+
return true;
|
|
3019
|
+
},
|
|
3020
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
3021
|
+
if (prop in extObj) {
|
|
3022
|
+
return Reflect.getOwnPropertyDescriptor(extObj, prop);
|
|
3023
|
+
} else {
|
|
3024
|
+
return Reflect.getOwnPropertyDescriptor(baseObj, prop);
|
|
3025
|
+
}
|
|
3026
|
+
},
|
|
3027
|
+
has(_target, prop) {
|
|
3028
|
+
return prop in extObj || prop in baseObj;
|
|
3029
|
+
}
|
|
3030
|
+
});
|
|
3031
|
+
}
|
|
3032
|
+
|
|
3033
|
+
// node_modules/mlkem/esm/src/utils.js
|
|
3034
|
+
function byte(n) {
|
|
3035
|
+
return n % 256;
|
|
3036
|
+
}
|
|
3037
|
+
function int16(n) {
|
|
3038
|
+
const end = -32768;
|
|
3039
|
+
const start = 32767;
|
|
3040
|
+
if (n >= end && n <= start) {
|
|
3041
|
+
return n;
|
|
3042
|
+
}
|
|
3043
|
+
if (n < end) {
|
|
3044
|
+
n = n + 32769;
|
|
3045
|
+
n = n % 65536;
|
|
3046
|
+
return start + n;
|
|
3047
|
+
}
|
|
3048
|
+
n = n - 32768;
|
|
3049
|
+
n = n % 65536;
|
|
3050
|
+
return end + n;
|
|
3051
|
+
}
|
|
3052
|
+
function uint16(n) {
|
|
3053
|
+
return n % 65536;
|
|
3054
|
+
}
|
|
3055
|
+
function int32(n) {
|
|
3056
|
+
const end = -2147483648;
|
|
3057
|
+
const start = 2147483647;
|
|
3058
|
+
if (n >= end && n <= start) {
|
|
3059
|
+
return n;
|
|
3060
|
+
}
|
|
3061
|
+
if (n < end) {
|
|
3062
|
+
n = n + 2147483649;
|
|
3063
|
+
n = n % 4294967296;
|
|
3064
|
+
return start + n;
|
|
3065
|
+
}
|
|
3066
|
+
n = n - 2147483648;
|
|
3067
|
+
n = n % 4294967296;
|
|
3068
|
+
return end + n;
|
|
3069
|
+
}
|
|
3070
|
+
function uint32(n) {
|
|
3071
|
+
return n % 4294967296;
|
|
3072
|
+
}
|
|
3073
|
+
function constantTimeCompare(x, y) {
|
|
3074
|
+
if (x.length != y.length) {
|
|
3075
|
+
return 0;
|
|
3076
|
+
}
|
|
3077
|
+
const v = new Uint8Array([0]);
|
|
3078
|
+
for (let i = 0; i < x.length; i++) {
|
|
3079
|
+
v[0] |= x[i] ^ y[i];
|
|
3080
|
+
}
|
|
3081
|
+
const z = new Uint8Array([0]);
|
|
3082
|
+
z[0] = ~(v[0] ^ z[0]);
|
|
3083
|
+
z[0] &= z[0] >> 4;
|
|
3084
|
+
z[0] &= z[0] >> 2;
|
|
3085
|
+
z[0] &= z[0] >> 1;
|
|
3086
|
+
return z[0];
|
|
3087
|
+
}
|
|
3088
|
+
function equalUint8Array(x, y) {
|
|
3089
|
+
if (x.length != y.length) {
|
|
3090
|
+
return false;
|
|
3091
|
+
}
|
|
3092
|
+
for (let i = 0; i < x.length; i++) {
|
|
3093
|
+
if (x[i] !== y[i]) {
|
|
3094
|
+
return false;
|
|
3095
|
+
}
|
|
3096
|
+
}
|
|
3097
|
+
return true;
|
|
3098
|
+
}
|
|
3099
|
+
async function loadCrypto() {
|
|
3100
|
+
if (typeof dntGlobalThis !== "undefined" && globalThis.crypto !== void 0) {
|
|
3101
|
+
return globalThis.crypto;
|
|
3102
|
+
}
|
|
3103
|
+
try {
|
|
3104
|
+
const { webcrypto } = await import("crypto");
|
|
3105
|
+
return webcrypto;
|
|
3106
|
+
} catch (_e) {
|
|
3107
|
+
throw new Error("failed to load Crypto");
|
|
3108
|
+
}
|
|
3109
|
+
}
|
|
3110
|
+
function prf(len, seed, nonce) {
|
|
3111
|
+
return shake256.create({ dkLen: len }).update(seed).update(new Uint8Array([nonce])).digest();
|
|
3112
|
+
}
|
|
3113
|
+
function byteopsLoad32(x) {
|
|
3114
|
+
let r = uint32(x[0]);
|
|
3115
|
+
r |= uint32(x[1]) << 8;
|
|
3116
|
+
r |= uint32(x[2]) << 16;
|
|
3117
|
+
r |= uint32(x[3]) << 24;
|
|
3118
|
+
return uint32(r);
|
|
3119
|
+
}
|
|
3120
|
+
|
|
3121
|
+
// node_modules/mlkem/esm/src/mlKemBase.js
|
|
3122
|
+
var MlKemBase = class {
|
|
3123
|
+
/**
|
|
3124
|
+
* Creates a new instance of the MlKemBase class.
|
|
3125
|
+
*/
|
|
3126
|
+
constructor() {
|
|
3127
|
+
Object.defineProperty(this, "_api", {
|
|
3128
|
+
enumerable: true,
|
|
3129
|
+
configurable: true,
|
|
3130
|
+
writable: true,
|
|
3131
|
+
value: void 0
|
|
3132
|
+
});
|
|
3133
|
+
Object.defineProperty(this, "_k", {
|
|
3134
|
+
enumerable: true,
|
|
3135
|
+
configurable: true,
|
|
3136
|
+
writable: true,
|
|
3137
|
+
value: 0
|
|
3138
|
+
});
|
|
3139
|
+
Object.defineProperty(this, "_du", {
|
|
3140
|
+
enumerable: true,
|
|
3141
|
+
configurable: true,
|
|
3142
|
+
writable: true,
|
|
3143
|
+
value: 0
|
|
3144
|
+
});
|
|
3145
|
+
Object.defineProperty(this, "_dv", {
|
|
3146
|
+
enumerable: true,
|
|
3147
|
+
configurable: true,
|
|
3148
|
+
writable: true,
|
|
3149
|
+
value: 0
|
|
3150
|
+
});
|
|
3151
|
+
Object.defineProperty(this, "_eta1", {
|
|
3152
|
+
enumerable: true,
|
|
3153
|
+
configurable: true,
|
|
3154
|
+
writable: true,
|
|
3155
|
+
value: 0
|
|
3156
|
+
});
|
|
3157
|
+
Object.defineProperty(this, "_eta2", {
|
|
3158
|
+
enumerable: true,
|
|
3159
|
+
configurable: true,
|
|
3160
|
+
writable: true,
|
|
3161
|
+
value: 0
|
|
3162
|
+
});
|
|
3163
|
+
Object.defineProperty(this, "_skSize", {
|
|
3164
|
+
enumerable: true,
|
|
3165
|
+
configurable: true,
|
|
3166
|
+
writable: true,
|
|
3167
|
+
value: 0
|
|
3168
|
+
});
|
|
3169
|
+
Object.defineProperty(this, "_pkSize", {
|
|
3170
|
+
enumerable: true,
|
|
3171
|
+
configurable: true,
|
|
3172
|
+
writable: true,
|
|
3173
|
+
value: 0
|
|
3174
|
+
});
|
|
3175
|
+
Object.defineProperty(this, "_compressedUSize", {
|
|
3176
|
+
enumerable: true,
|
|
3177
|
+
configurable: true,
|
|
3178
|
+
writable: true,
|
|
3179
|
+
value: 0
|
|
3180
|
+
});
|
|
3181
|
+
Object.defineProperty(this, "_compressedVSize", {
|
|
3182
|
+
enumerable: true,
|
|
3183
|
+
configurable: true,
|
|
3184
|
+
writable: true,
|
|
3185
|
+
value: 0
|
|
3186
|
+
});
|
|
3187
|
+
}
|
|
3188
|
+
/**
|
|
3189
|
+
* Generates a keypair [publicKey, privateKey].
|
|
3190
|
+
*
|
|
3191
|
+
* If an error occurred, throws {@link MlKemError}.
|
|
3192
|
+
*
|
|
3193
|
+
* @returns A kaypair [publicKey, privateKey].
|
|
3194
|
+
* @throws {@link MlKemError}
|
|
3195
|
+
*
|
|
3196
|
+
* @example Generates a {@link MlKem768} keypair.
|
|
3197
|
+
*
|
|
3198
|
+
* ```ts
|
|
3199
|
+
* // Using jsr:
|
|
3200
|
+
* import { MlKem768 } from "@dajiaji/mlkem";
|
|
3201
|
+
* // Using npm:
|
|
3202
|
+
* // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
|
|
3203
|
+
*
|
|
3204
|
+
* const kyber = new MlKem768();
|
|
3205
|
+
* const [pk, sk] = await kyber.generateKeyPair();
|
|
3206
|
+
* ```
|
|
3207
|
+
*/
|
|
3208
|
+
async generateKeyPair() {
|
|
3209
|
+
await this._setup();
|
|
3210
|
+
try {
|
|
3211
|
+
const rnd = new Uint8Array(64);
|
|
3212
|
+
this._api.getRandomValues(rnd);
|
|
3213
|
+
return this._deriveKeyPair(rnd);
|
|
3214
|
+
} catch (e) {
|
|
3215
|
+
throw new MlKemError(e);
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3218
|
+
/**
|
|
3219
|
+
* Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed.
|
|
3220
|
+
*
|
|
3221
|
+
* If an error occurred, throws {@link MlKemError}.
|
|
3222
|
+
*
|
|
3223
|
+
* @param seed A 64-octet seed for the deterministic key generation.
|
|
3224
|
+
* @returns A kaypair [publicKey, privateKey].
|
|
3225
|
+
* @throws {@link MlKemError}
|
|
3226
|
+
*
|
|
3227
|
+
* @example Derives a {@link MlKem768} keypair deterministically.
|
|
3228
|
+
*
|
|
3229
|
+
* ```ts
|
|
3230
|
+
* // Using jsr:
|
|
3231
|
+
* import { MlKem768 } from "@dajiaji/mlkem";
|
|
3232
|
+
* // Using npm:
|
|
3233
|
+
* // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
|
|
3234
|
+
*
|
|
3235
|
+
* const kyber = new MlKem768();
|
|
3236
|
+
* const seed = new Uint8Array(64);
|
|
3237
|
+
* globalThis.crypto.getRandomValues(seed);
|
|
3238
|
+
* const [pk, sk] = await kyber.deriveKeyPair(seed);
|
|
3239
|
+
* ```
|
|
3240
|
+
*/
|
|
3241
|
+
async deriveKeyPair(seed) {
|
|
3242
|
+
await this._setup();
|
|
3243
|
+
try {
|
|
3244
|
+
if (seed.byteLength !== 64) {
|
|
3245
|
+
throw new Error("seed must be 64 bytes in length");
|
|
3246
|
+
}
|
|
3247
|
+
return this._deriveKeyPair(seed);
|
|
3248
|
+
} catch (e) {
|
|
3249
|
+
throw new MlKemError(e);
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
/**
|
|
3253
|
+
* Generates a shared secret from the encapsulated ciphertext and the private key.
|
|
3254
|
+
*
|
|
3255
|
+
* If an error occurred, throws {@link MlKemError}.
|
|
3256
|
+
*
|
|
3257
|
+
* @param pk A public key.
|
|
3258
|
+
* @param seed An optional 32-octet seed for the deterministic shared secret generation.
|
|
3259
|
+
* @returns A ciphertext (encapsulated public key) and a shared secret.
|
|
3260
|
+
* @throws {@link MlKemError}
|
|
3261
|
+
*
|
|
3262
|
+
* @example The {@link MlKem768} encapsulation.
|
|
3263
|
+
*
|
|
3264
|
+
* ```ts
|
|
3265
|
+
* // Using jsr:
|
|
3266
|
+
* import { MlKem768 } from "@dajiaji/mlkem";
|
|
3267
|
+
* // Using npm:
|
|
3268
|
+
* // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
|
|
3269
|
+
*
|
|
3270
|
+
* const kyber = new MlKem768();
|
|
3271
|
+
* const [pk, sk] = await kyber.generateKeyPair();
|
|
3272
|
+
* const [ct, ss] = await kyber.encap(pk);
|
|
3273
|
+
* ```
|
|
3274
|
+
*/
|
|
3275
|
+
async encap(pk, seed) {
|
|
3276
|
+
await this._setup();
|
|
3277
|
+
try {
|
|
3278
|
+
if (pk.length !== 384 * this._k + 32) {
|
|
3279
|
+
throw new Error("invalid encapsulation key");
|
|
3280
|
+
}
|
|
3281
|
+
const m = this._getSeed(seed);
|
|
3282
|
+
const [k, r] = g(m, h(pk));
|
|
3283
|
+
const ct = this._encap(pk, m, r);
|
|
3284
|
+
return [ct, k];
|
|
3285
|
+
} catch (e) {
|
|
3286
|
+
throw new MlKemError(e);
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
/**
|
|
3290
|
+
* Generates a ciphertext for the public key and a shared secret.
|
|
3291
|
+
*
|
|
3292
|
+
* If an error occurred, throws {@link MlKemError}.
|
|
3293
|
+
*
|
|
3294
|
+
* @param ct A ciphertext generated by {@link encap}.
|
|
3295
|
+
* @param sk A private key.
|
|
3296
|
+
* @returns A shared secret.
|
|
3297
|
+
* @throws {@link MlKemError}
|
|
3298
|
+
*
|
|
3299
|
+
* @example The {@link MlKem768} decapsulation.
|
|
3300
|
+
*
|
|
3301
|
+
* ```ts
|
|
3302
|
+
* // Using jsr:
|
|
3303
|
+
* import { MlKem768 } from "@dajiaji/mlkem";
|
|
3304
|
+
* // Using npm:
|
|
3305
|
+
* // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
|
|
3306
|
+
*
|
|
3307
|
+
* const kyber = new MlKem768();
|
|
3308
|
+
* const [pk, sk] = await kyber.generateKeyPair();
|
|
3309
|
+
* const [ct, ssS] = await kyber.encap(pk);
|
|
3310
|
+
* const ssR = await kyber.decap(ct, sk);
|
|
3311
|
+
* // ssS === ssR
|
|
3312
|
+
* ```
|
|
3313
|
+
*/
|
|
3314
|
+
async decap(ct, sk) {
|
|
3315
|
+
await this._setup();
|
|
3316
|
+
try {
|
|
3317
|
+
if (ct.byteLength !== this._compressedUSize + this._compressedVSize) {
|
|
3318
|
+
throw new Error("Invalid ct size");
|
|
3319
|
+
}
|
|
3320
|
+
if (sk.length !== 768 * this._k + 96) {
|
|
3321
|
+
throw new Error("Invalid decapsulation key");
|
|
3322
|
+
}
|
|
3323
|
+
const sk2 = sk.subarray(0, this._skSize);
|
|
3324
|
+
const pk = sk.subarray(this._skSize, this._skSize + this._pkSize);
|
|
3325
|
+
const hpk = sk.subarray(this._skSize + this._pkSize, this._skSize + this._pkSize + 32);
|
|
3326
|
+
const z = sk.subarray(this._skSize + this._pkSize + 32, this._skSize + this._pkSize + 64);
|
|
3327
|
+
const m2 = this._decap(ct, sk2);
|
|
3328
|
+
const [k2, r2] = g(m2, hpk);
|
|
3329
|
+
const kBar = kdf(z, ct);
|
|
3330
|
+
const ct2 = this._encap(pk, m2, r2);
|
|
3331
|
+
return constantTimeCompare(ct, ct2) === 1 ? k2 : kBar;
|
|
3332
|
+
} catch (e) {
|
|
3333
|
+
throw new MlKemError(e);
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
/**
|
|
3337
|
+
* Sets up the MlKemBase instance by loading the necessary crypto library.
|
|
3338
|
+
* If the crypto library is already loaded, this method does nothing.
|
|
3339
|
+
* @returns {Promise<void>} A promise that resolves when the setup is complete.
|
|
3340
|
+
*/
|
|
3341
|
+
async _setup() {
|
|
3342
|
+
if (this._api !== void 0) {
|
|
3343
|
+
return;
|
|
3344
|
+
}
|
|
3345
|
+
this._api = await loadCrypto();
|
|
3346
|
+
}
|
|
3347
|
+
/**
|
|
3348
|
+
* Returns a Uint8Array seed for cryptographic operations.
|
|
3349
|
+
* If no seed is provided, a random seed of length 32 bytes is generated.
|
|
3350
|
+
* If a seed is provided, it must be exactly 32 bytes in length.
|
|
3351
|
+
*
|
|
3352
|
+
* @param seed - Optional seed for cryptographic operations.
|
|
3353
|
+
* @returns A Uint8Array seed.
|
|
3354
|
+
* @throws Error if the provided seed is not 32 bytes in length.
|
|
3355
|
+
*/
|
|
3356
|
+
_getSeed(seed) {
|
|
3357
|
+
if (seed == void 0) {
|
|
3358
|
+
const s = new Uint8Array(32);
|
|
3359
|
+
this._api.getRandomValues(s);
|
|
3360
|
+
return s;
|
|
3361
|
+
}
|
|
3362
|
+
if (seed.byteLength !== 32) {
|
|
3363
|
+
throw new Error("seed must be 32 bytes in length");
|
|
3364
|
+
}
|
|
3365
|
+
return seed;
|
|
3366
|
+
}
|
|
3367
|
+
/**
|
|
3368
|
+
* Derives a key pair from a given seed.
|
|
3369
|
+
*
|
|
3370
|
+
* @param seed - The seed used for key derivation.
|
|
3371
|
+
* @returns An array containing the public key and secret key.
|
|
3372
|
+
*/
|
|
3373
|
+
_deriveKeyPair(seed) {
|
|
3374
|
+
const cpaSeed = seed.subarray(0, 32);
|
|
3375
|
+
const z = seed.subarray(32, 64);
|
|
3376
|
+
const [pk, skBody] = this._deriveCpaKeyPair(cpaSeed);
|
|
3377
|
+
const pkh = h(pk);
|
|
3378
|
+
const sk = new Uint8Array(this._skSize + this._pkSize + 64);
|
|
3379
|
+
sk.set(skBody, 0);
|
|
3380
|
+
sk.set(pk, this._skSize);
|
|
3381
|
+
sk.set(pkh, this._skSize + this._pkSize);
|
|
3382
|
+
sk.set(z, this._skSize + this._pkSize + 32);
|
|
3383
|
+
return [pk, sk];
|
|
3384
|
+
}
|
|
3385
|
+
// indcpaKeyGen generates public and private keys for the CPA-secure
|
|
3386
|
+
// public-key encryption scheme underlying ML-KEM.
|
|
3387
|
+
/**
|
|
3388
|
+
* Derives a CPA key pair using the provided CPA seed.
|
|
3389
|
+
*
|
|
3390
|
+
* @param cpaSeed - The CPA seed used for key derivation.
|
|
3391
|
+
* @returns An array containing the public key and private key.
|
|
3392
|
+
*/
|
|
3393
|
+
_deriveCpaKeyPair(cpaSeed) {
|
|
3394
|
+
const [publicSeed, noiseSeed] = g(cpaSeed, new Uint8Array([this._k]));
|
|
3395
|
+
const a = this._sampleMatrix(publicSeed, false);
|
|
3396
|
+
const s = this._sampleNoise1(noiseSeed, 0, this._k);
|
|
3397
|
+
const e = this._sampleNoise1(noiseSeed, this._k, this._k);
|
|
3398
|
+
for (let i = 0; i < this._k; i++) {
|
|
3399
|
+
s[i] = ntt(s[i]);
|
|
3400
|
+
s[i] = reduce(s[i]);
|
|
3401
|
+
e[i] = ntt(e[i]);
|
|
3402
|
+
}
|
|
3403
|
+
const pk = new Array(this._k);
|
|
3404
|
+
for (let i = 0; i < this._k; i++) {
|
|
3405
|
+
pk[i] = polyToMont(multiply(a[i], s));
|
|
3406
|
+
pk[i] = add(pk[i], e[i]);
|
|
3407
|
+
pk[i] = reduce(pk[i]);
|
|
3408
|
+
}
|
|
3409
|
+
const pubKey = new Uint8Array(this._pkSize);
|
|
3410
|
+
for (let i = 0; i < this._k; i++) {
|
|
3411
|
+
pubKey.set(polyToBytes(pk[i]), i * 384);
|
|
3412
|
+
}
|
|
3413
|
+
pubKey.set(publicSeed, this._skSize);
|
|
3414
|
+
const privKey = new Uint8Array(this._skSize);
|
|
3415
|
+
for (let i = 0; i < this._k; i++) {
|
|
3416
|
+
privKey.set(polyToBytes(s[i]), i * 384);
|
|
3417
|
+
}
|
|
3418
|
+
return [pubKey, privKey];
|
|
3419
|
+
}
|
|
3420
|
+
// _encap is the encapsulation function of the CPA-secure
|
|
3421
|
+
// public-key encryption scheme underlying ML-KEM.
|
|
3422
|
+
/**
|
|
3423
|
+
* Encapsulates a message using the ML-KEM encryption scheme.
|
|
3424
|
+
*
|
|
3425
|
+
* @param pk - The public key.
|
|
3426
|
+
* @param msg - The message to be encapsulated.
|
|
3427
|
+
* @param seed - The seed used for generating random values.
|
|
3428
|
+
* @returns The encapsulated message as a Uint8Array.
|
|
3429
|
+
*/
|
|
3430
|
+
_encap(pk, msg, seed) {
|
|
3431
|
+
const tHat = new Array(this._k);
|
|
3432
|
+
const pkCheck = new Uint8Array(384 * this._k);
|
|
3433
|
+
for (let i = 0; i < this._k; i++) {
|
|
3434
|
+
tHat[i] = polyFromBytes(pk.subarray(i * 384, (i + 1) * 384));
|
|
3435
|
+
pkCheck.set(polyToBytes(tHat[i]), i * 384);
|
|
3436
|
+
}
|
|
3437
|
+
if (!equalUint8Array(pk.subarray(0, pkCheck.length), pkCheck)) {
|
|
3438
|
+
throw new Error("invalid encapsulation key");
|
|
3439
|
+
}
|
|
3440
|
+
const rho = pk.subarray(this._skSize);
|
|
3441
|
+
const a = this._sampleMatrix(rho, true);
|
|
3442
|
+
const r = this._sampleNoise1(seed, 0, this._k);
|
|
3443
|
+
const e1 = this._sampleNoise2(seed, this._k, this._k);
|
|
3444
|
+
const e2 = this._sampleNoise2(seed, this._k * 2, 1)[0];
|
|
3445
|
+
for (let i = 0; i < this._k; i++) {
|
|
3446
|
+
r[i] = ntt(r[i]);
|
|
3447
|
+
r[i] = reduce(r[i]);
|
|
3448
|
+
}
|
|
3449
|
+
const u = new Array(this._k);
|
|
3450
|
+
for (let i = 0; i < this._k; i++) {
|
|
3451
|
+
u[i] = multiply(a[i], r);
|
|
3452
|
+
u[i] = nttInverse(u[i]);
|
|
3453
|
+
u[i] = add(u[i], e1[i]);
|
|
3454
|
+
u[i] = reduce(u[i]);
|
|
3455
|
+
}
|
|
3456
|
+
const m = polyFromMsg(msg);
|
|
3457
|
+
let v = multiply(tHat, r);
|
|
3458
|
+
v = nttInverse(v);
|
|
3459
|
+
v = add(v, e2);
|
|
3460
|
+
v = add(v, m);
|
|
3461
|
+
v = reduce(v);
|
|
3462
|
+
const ret = new Uint8Array(this._compressedUSize + this._compressedVSize);
|
|
3463
|
+
this._compressU(ret.subarray(0, this._compressedUSize), u);
|
|
3464
|
+
this._compressV(ret.subarray(this._compressedUSize), v);
|
|
3465
|
+
return ret;
|
|
3466
|
+
}
|
|
3467
|
+
// indcpaDecrypt is the decryption function of the CPA-secure
|
|
3468
|
+
// public-key encryption scheme underlying ML-KEM.
|
|
3469
|
+
/**
|
|
3470
|
+
* Decapsulates the ciphertext using the provided secret key.
|
|
3471
|
+
*
|
|
3472
|
+
* @param ct - The ciphertext to be decapsulated.
|
|
3473
|
+
* @param sk - The secret key used for decapsulation.
|
|
3474
|
+
* @returns The decapsulated message as a Uint8Array.
|
|
3475
|
+
*/
|
|
3476
|
+
_decap(ct, sk) {
|
|
3477
|
+
const u = this._decompressU(ct.subarray(0, this._compressedUSize));
|
|
3478
|
+
const v = this._decompressV(ct.subarray(this._compressedUSize));
|
|
3479
|
+
const privateKeyPolyvec = this._polyvecFromBytes(sk);
|
|
3480
|
+
for (let i = 0; i < this._k; i++) {
|
|
3481
|
+
u[i] = ntt(u[i]);
|
|
3482
|
+
}
|
|
3483
|
+
let mp = multiply(privateKeyPolyvec, u);
|
|
3484
|
+
mp = nttInverse(mp);
|
|
3485
|
+
mp = subtract(v, mp);
|
|
3486
|
+
mp = reduce(mp);
|
|
3487
|
+
return polyToMsg(mp);
|
|
3488
|
+
}
|
|
3489
|
+
// generateMatrixA deterministically generates a matrix `A` (or the transpose of `A`)
|
|
3490
|
+
// from a seed. Entries of the matrix are polynomials that look uniformly random.
|
|
3491
|
+
// Performs rejection sampling on the output of an extendable-output function (XOF).
|
|
3492
|
+
/**
|
|
3493
|
+
* Generates a sample matrix based on the provided seed and transposition flag.
|
|
3494
|
+
*
|
|
3495
|
+
* @param seed - The seed used for generating the matrix.
|
|
3496
|
+
* @param transposed - A flag indicating whether the matrix should be transposed or not.
|
|
3497
|
+
* @returns The generated sample matrix.
|
|
3498
|
+
*/
|
|
3499
|
+
_sampleMatrix(seed, transposed) {
|
|
3500
|
+
const a = new Array(this._k);
|
|
3501
|
+
const transpose = new Uint8Array(2);
|
|
3502
|
+
for (let ctr = 0, i = 0; i < this._k; i++) {
|
|
3503
|
+
a[i] = new Array(this._k);
|
|
3504
|
+
for (let j = 0; j < this._k; j++) {
|
|
3505
|
+
if (transposed) {
|
|
3506
|
+
transpose[0] = i;
|
|
3507
|
+
transpose[1] = j;
|
|
3508
|
+
} else {
|
|
3509
|
+
transpose[0] = j;
|
|
3510
|
+
transpose[1] = i;
|
|
3511
|
+
}
|
|
3512
|
+
const output = xof(seed, transpose);
|
|
3513
|
+
const result = indcpaRejUniform(output.subarray(0, 504), 504, N);
|
|
3514
|
+
a[i][j] = result[0];
|
|
3515
|
+
ctr = result[1];
|
|
3516
|
+
while (ctr < N) {
|
|
3517
|
+
const outputn = output.subarray(504, 672);
|
|
3518
|
+
const result1 = indcpaRejUniform(outputn, 168, N - ctr);
|
|
3519
|
+
const missing = result1[0];
|
|
3520
|
+
const ctrn = result1[1];
|
|
3521
|
+
for (let k = ctr; k < N; k++) {
|
|
3522
|
+
a[i][j][k] = missing[k - ctr];
|
|
3523
|
+
}
|
|
3524
|
+
ctr = ctr + ctrn;
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
return a;
|
|
3529
|
+
}
|
|
3530
|
+
/**
|
|
3531
|
+
* Generates a 2D array of noise samples.
|
|
3532
|
+
*
|
|
3533
|
+
* @param sigma - The noise parameter.
|
|
3534
|
+
* @param offset - The offset value.
|
|
3535
|
+
* @param size - The size of the array.
|
|
3536
|
+
* @returns The generated 2D array of noise samples.
|
|
3537
|
+
*/
|
|
3538
|
+
_sampleNoise1(sigma, offset, size) {
|
|
3539
|
+
const r = new Array(size);
|
|
3540
|
+
for (let i = 0; i < size; i++) {
|
|
3541
|
+
r[i] = byteopsCbd(prf(this._eta1 * N / 4, sigma, offset), this._eta1);
|
|
3542
|
+
offset++;
|
|
3543
|
+
}
|
|
3544
|
+
return r;
|
|
3545
|
+
}
|
|
3546
|
+
/**
|
|
3547
|
+
* Generates a 2-dimensional array of noise samples.
|
|
3548
|
+
*
|
|
3549
|
+
* @param sigma - The noise parameter.
|
|
3550
|
+
* @param offset - The offset value.
|
|
3551
|
+
* @param size - The size of the array.
|
|
3552
|
+
* @returns The generated 2-dimensional array of noise samples.
|
|
3553
|
+
*/
|
|
3554
|
+
_sampleNoise2(sigma, offset, size) {
|
|
3555
|
+
const r = new Array(size);
|
|
3556
|
+
for (let i = 0; i < size; i++) {
|
|
3557
|
+
r[i] = byteopsCbd(prf(this._eta2 * N / 4, sigma, offset), this._eta2);
|
|
3558
|
+
offset++;
|
|
3559
|
+
}
|
|
3560
|
+
return r;
|
|
3561
|
+
}
|
|
3562
|
+
// polyvecFromBytes deserializes a vector of polynomials.
|
|
3563
|
+
/**
|
|
3564
|
+
* Converts a Uint8Array to a 2D array of numbers representing a polynomial vector.
|
|
3565
|
+
* Each element in the resulting array represents a polynomial.
|
|
3566
|
+
* @param a The Uint8Array to convert.
|
|
3567
|
+
* @returns The 2D array of numbers representing the polynomial vector.
|
|
3568
|
+
*/
|
|
3569
|
+
_polyvecFromBytes(a) {
|
|
3570
|
+
const r = new Array(this._k);
|
|
3571
|
+
for (let i = 0; i < this._k; i++) {
|
|
3572
|
+
r[i] = polyFromBytes(a.subarray(i * 384, (i + 1) * 384));
|
|
3573
|
+
}
|
|
3574
|
+
return r;
|
|
3575
|
+
}
|
|
3576
|
+
// compressU lossily compresses and serializes a vector of polynomials.
|
|
3577
|
+
/**
|
|
3578
|
+
* Compresses the given array of coefficients into a Uint8Array.
|
|
3579
|
+
*
|
|
3580
|
+
* @param r - The output Uint8Array.
|
|
3581
|
+
* @param u - The array of coefficients.
|
|
3582
|
+
* @returns The compressed Uint8Array.
|
|
3583
|
+
*/
|
|
3584
|
+
_compressU(r, u) {
|
|
3585
|
+
const t = new Array(4);
|
|
3586
|
+
for (let rr = 0, i = 0; i < this._k; i++) {
|
|
3587
|
+
for (let j = 0; j < N / 4; j++) {
|
|
3588
|
+
for (let k = 0; k < 4; k++) {
|
|
3589
|
+
t[k] = ((u[i][4 * j + k] << 10) + Q / 2) / Q & 1023;
|
|
3590
|
+
}
|
|
3591
|
+
r[rr++] = byte(t[0] >> 0);
|
|
3592
|
+
r[rr++] = byte(t[0] >> 8 | t[1] << 2);
|
|
3593
|
+
r[rr++] = byte(t[1] >> 6 | t[2] << 4);
|
|
3594
|
+
r[rr++] = byte(t[2] >> 4 | t[3] << 6);
|
|
3595
|
+
r[rr++] = byte(t[3] >> 2);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
return r;
|
|
3599
|
+
}
|
|
3600
|
+
// compressV lossily compresses and subsequently serializes a polynomial.
|
|
3601
|
+
/**
|
|
3602
|
+
* Compresses the given array of numbers into a Uint8Array.
|
|
3603
|
+
*
|
|
3604
|
+
* @param r - The Uint8Array to store the compressed values.
|
|
3605
|
+
* @param v - The array of numbers to compress.
|
|
3606
|
+
* @returns The compressed Uint8Array.
|
|
3607
|
+
*/
|
|
3608
|
+
_compressV(r, v) {
|
|
3609
|
+
const t = new Uint8Array(8);
|
|
3610
|
+
for (let rr = 0, i = 0; i < N / 8; i++) {
|
|
3611
|
+
for (let j = 0; j < 8; j++) {
|
|
3612
|
+
t[j] = byte(((v[8 * i + j] << 4) + Q / 2) / Q) & 15;
|
|
3613
|
+
}
|
|
3614
|
+
r[rr++] = t[0] | t[1] << 4;
|
|
3615
|
+
r[rr++] = t[2] | t[3] << 4;
|
|
3616
|
+
r[rr++] = t[4] | t[5] << 4;
|
|
3617
|
+
r[rr++] = t[6] | t[7] << 4;
|
|
3618
|
+
}
|
|
3619
|
+
return r;
|
|
3620
|
+
}
|
|
3621
|
+
// decompressU de-serializes and decompresses a vector of polynomials and
|
|
3622
|
+
// represents the approximate inverse of compress1. Since compression is lossy,
|
|
3623
|
+
// the results of decompression will may not match the original vector of polynomials.
|
|
3624
|
+
/**
|
|
3625
|
+
* Decompresses a Uint8Array into a two-dimensional array of numbers.
|
|
3626
|
+
*
|
|
3627
|
+
* @param a The Uint8Array to decompress.
|
|
3628
|
+
* @returns The decompressed two-dimensional array.
|
|
3629
|
+
*/
|
|
3630
|
+
_decompressU(a) {
|
|
3631
|
+
const r = new Array(this._k);
|
|
3632
|
+
for (let i = 0; i < this._k; i++) {
|
|
3633
|
+
r[i] = new Array(384);
|
|
3634
|
+
}
|
|
3635
|
+
const t = new Array(4);
|
|
3636
|
+
for (let aa = 0, i = 0; i < this._k; i++) {
|
|
3637
|
+
for (let j = 0; j < N / 4; j++) {
|
|
3638
|
+
t[0] = uint16(a[aa + 0]) >> 0 | uint16(a[aa + 1]) << 8;
|
|
3639
|
+
t[1] = uint16(a[aa + 1]) >> 2 | uint16(a[aa + 2]) << 6;
|
|
3640
|
+
t[2] = uint16(a[aa + 2]) >> 4 | uint16(a[aa + 3]) << 4;
|
|
3641
|
+
t[3] = uint16(a[aa + 3]) >> 6 | uint16(a[aa + 4]) << 2;
|
|
3642
|
+
aa = aa + 5;
|
|
3643
|
+
for (let k = 0; k < 4; k++) {
|
|
3644
|
+
r[i][4 * j + k] = int16(uint32(t[k] & 1023) * uint32(Q) + 512 >> 10);
|
|
3645
|
+
}
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
return r;
|
|
3649
|
+
}
|
|
3650
|
+
// decompressV de-serializes and subsequently decompresses a polynomial,
|
|
3651
|
+
// representing the approximate inverse of compress2.
|
|
3652
|
+
// Note that compression is lossy, and thus decompression will not match the
|
|
3653
|
+
// original input.
|
|
3654
|
+
/**
|
|
3655
|
+
* Decompresses a Uint8Array into an array of numbers.
|
|
3656
|
+
*
|
|
3657
|
+
* @param a - The Uint8Array to decompress.
|
|
3658
|
+
* @returns An array of numbers.
|
|
3659
|
+
*/
|
|
3660
|
+
_decompressV(a) {
|
|
3661
|
+
const r = new Array(384);
|
|
3662
|
+
for (let aa = 0, i = 0; i < N / 2; i++, aa++) {
|
|
3663
|
+
r[2 * i + 0] = int16(uint16(a[aa] & 15) * uint16(Q) + 8 >> 4);
|
|
3664
|
+
r[2 * i + 1] = int16(uint16(a[aa] >> 4) * uint16(Q) + 8 >> 4);
|
|
3665
|
+
}
|
|
3666
|
+
return r;
|
|
3667
|
+
}
|
|
3668
|
+
};
|
|
3669
|
+
function g(a, b) {
|
|
3670
|
+
const hash = sha3_512.create().update(a);
|
|
3671
|
+
if (b !== void 0) {
|
|
3672
|
+
hash.update(b);
|
|
3673
|
+
}
|
|
3674
|
+
const res = hash.digest();
|
|
3675
|
+
return [res.subarray(0, 32), res.subarray(32, 64)];
|
|
3676
|
+
}
|
|
3677
|
+
function h(msg) {
|
|
3678
|
+
return sha3_256.create().update(msg).digest();
|
|
3679
|
+
}
|
|
3680
|
+
function kdf(a, b) {
|
|
3681
|
+
const hash = shake256.create({ dkLen: 32 }).update(a);
|
|
3682
|
+
if (b !== void 0) {
|
|
3683
|
+
hash.update(b);
|
|
3684
|
+
}
|
|
3685
|
+
return hash.digest();
|
|
3686
|
+
}
|
|
3687
|
+
function xof(seed, transpose) {
|
|
3688
|
+
return shake128.create({ dkLen: 672 }).update(seed).update(transpose).digest();
|
|
3689
|
+
}
|
|
3690
|
+
function polyToBytes(a) {
|
|
3691
|
+
let t0 = 0;
|
|
3692
|
+
let t1 = 0;
|
|
3693
|
+
const r = new Uint8Array(384);
|
|
3694
|
+
const a2 = subtractQ(a);
|
|
3695
|
+
for (let i = 0; i < N / 2; i++) {
|
|
3696
|
+
t0 = uint16(a2[2 * i]);
|
|
3697
|
+
t1 = uint16(a2[2 * i + 1]);
|
|
3698
|
+
r[3 * i + 0] = byte(t0 >> 0);
|
|
3699
|
+
r[3 * i + 1] = byte(t0 >> 8) | byte(t1 << 4);
|
|
3700
|
+
r[3 * i + 2] = byte(t1 >> 4);
|
|
3701
|
+
}
|
|
3702
|
+
return r;
|
|
3703
|
+
}
|
|
3704
|
+
function polyFromBytes(a) {
|
|
3705
|
+
const r = new Array(384).fill(0);
|
|
3706
|
+
for (let i = 0; i < N / 2; i++) {
|
|
3707
|
+
r[2 * i] = int16((uint16(a[3 * i + 0]) >> 0 | uint16(a[3 * i + 1]) << 8) & 4095);
|
|
3708
|
+
r[2 * i + 1] = int16((uint16(a[3 * i + 1]) >> 4 | uint16(a[3 * i + 2]) << 4) & 4095);
|
|
3709
|
+
}
|
|
3710
|
+
return r;
|
|
3711
|
+
}
|
|
3712
|
+
function polyToMsg(a) {
|
|
3713
|
+
const msg = new Uint8Array(32);
|
|
3714
|
+
let t;
|
|
3715
|
+
const a2 = subtractQ(a);
|
|
3716
|
+
for (let i = 0; i < N / 8; i++) {
|
|
3717
|
+
msg[i] = 0;
|
|
3718
|
+
for (let j = 0; j < 8; j++) {
|
|
3719
|
+
t = ((uint16(a2[8 * i + j]) << 1) + uint16(Q / 2)) / uint16(Q) & 1;
|
|
3720
|
+
msg[i] |= byte(t << j);
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
return msg;
|
|
3724
|
+
}
|
|
3725
|
+
function polyFromMsg(msg) {
|
|
3726
|
+
const r = new Array(384).fill(0);
|
|
3727
|
+
let mask;
|
|
3728
|
+
for (let i = 0; i < N / 8; i++) {
|
|
3729
|
+
for (let j = 0; j < 8; j++) {
|
|
3730
|
+
mask = -1 * int16(msg[i] >> j & 1);
|
|
3731
|
+
r[8 * i + j] = mask & int16((Q + 1) / 2);
|
|
3732
|
+
}
|
|
3733
|
+
}
|
|
3734
|
+
return r;
|
|
3735
|
+
}
|
|
3736
|
+
function indcpaRejUniform(buf, bufl, len) {
|
|
3737
|
+
const r = new Array(384).fill(0);
|
|
3738
|
+
let ctr = 0;
|
|
3739
|
+
let val0, val1;
|
|
3740
|
+
for (let pos = 0; ctr < len && pos + 3 <= bufl; ) {
|
|
3741
|
+
val0 = (uint16(buf[pos] >> 0) | uint16(buf[pos + 1]) << 8) & 4095;
|
|
3742
|
+
val1 = (uint16(buf[pos + 1] >> 4) | uint16(buf[pos + 2]) << 4) & 4095;
|
|
3743
|
+
pos = pos + 3;
|
|
3744
|
+
if (val0 < Q) {
|
|
3745
|
+
r[ctr] = val0;
|
|
3746
|
+
ctr = ctr + 1;
|
|
3747
|
+
}
|
|
3748
|
+
if (ctr < len && val1 < Q) {
|
|
3749
|
+
r[ctr] = val1;
|
|
3750
|
+
ctr = ctr + 1;
|
|
3751
|
+
}
|
|
3752
|
+
}
|
|
3753
|
+
return [r, ctr];
|
|
3754
|
+
}
|
|
3755
|
+
function byteopsCbd(buf, eta) {
|
|
3756
|
+
let t, d;
|
|
3757
|
+
let a, b;
|
|
3758
|
+
const r = new Array(384).fill(0);
|
|
3759
|
+
for (let i = 0; i < N / 8; i++) {
|
|
3760
|
+
t = byteopsLoad32(buf.subarray(4 * i, buf.length));
|
|
3761
|
+
d = t & 1431655765;
|
|
3762
|
+
d = d + (t >> 1 & 1431655765);
|
|
3763
|
+
for (let j = 0; j < 8; j++) {
|
|
3764
|
+
a = int16(d >> 4 * j + 0 & 3);
|
|
3765
|
+
b = int16(d >> 4 * j + eta & 3);
|
|
3766
|
+
r[8 * i + j] = a - b;
|
|
3767
|
+
}
|
|
3768
|
+
}
|
|
3769
|
+
return r;
|
|
3770
|
+
}
|
|
3771
|
+
function ntt(r) {
|
|
3772
|
+
for (let j = 0, k = 1, l = 128; l >= 2; l >>= 1) {
|
|
3773
|
+
for (let start = 0; start < 256; start = j + l) {
|
|
3774
|
+
const zeta = NTT_ZETAS[k];
|
|
3775
|
+
k = k + 1;
|
|
3776
|
+
for (j = start; j < start + l; j++) {
|
|
3777
|
+
const t = nttFqMul(zeta, r[j + l]);
|
|
3778
|
+
r[j + l] = r[j] - t;
|
|
3779
|
+
r[j] = r[j] + t;
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
return r;
|
|
3784
|
+
}
|
|
3785
|
+
function nttFqMul(a, b) {
|
|
3786
|
+
return byteopsMontgomeryReduce(a * b);
|
|
3787
|
+
}
|
|
3788
|
+
function reduce(r) {
|
|
3789
|
+
for (let i = 0; i < N; i++) {
|
|
3790
|
+
r[i] = barrett(r[i]);
|
|
3791
|
+
}
|
|
3792
|
+
return r;
|
|
3793
|
+
}
|
|
3794
|
+
function barrett(a) {
|
|
3795
|
+
const v = ((1 << 24) + Q / 2) / Q;
|
|
3796
|
+
let t = v * a >> 24;
|
|
3797
|
+
t = t * Q;
|
|
3798
|
+
return a - t;
|
|
3799
|
+
}
|
|
3800
|
+
function byteopsMontgomeryReduce(a) {
|
|
3801
|
+
const u = int16(int32(a) * Q_INV);
|
|
3802
|
+
let t = u * Q;
|
|
3803
|
+
t = a - t;
|
|
3804
|
+
t >>= 16;
|
|
3805
|
+
return int16(t);
|
|
3806
|
+
}
|
|
3807
|
+
function polyToMont(r) {
|
|
3808
|
+
const f = 1353;
|
|
3809
|
+
for (let i = 0; i < N; i++) {
|
|
3810
|
+
r[i] = byteopsMontgomeryReduce(int32(r[i]) * int32(f));
|
|
3811
|
+
}
|
|
3812
|
+
return r;
|
|
3813
|
+
}
|
|
3814
|
+
function multiply(a, b) {
|
|
3815
|
+
let r = polyBaseMulMontgomery(a[0], b[0]);
|
|
3816
|
+
let t;
|
|
3817
|
+
for (let i = 1; i < a.length; i++) {
|
|
3818
|
+
t = polyBaseMulMontgomery(a[i], b[i]);
|
|
3819
|
+
r = add(r, t);
|
|
3820
|
+
}
|
|
3821
|
+
return reduce(r);
|
|
3822
|
+
}
|
|
3823
|
+
function polyBaseMulMontgomery(a, b) {
|
|
3824
|
+
let rx, ry;
|
|
3825
|
+
for (let i = 0; i < N / 4; i++) {
|
|
3826
|
+
rx = nttBaseMul(a[4 * i + 0], a[4 * i + 1], b[4 * i + 0], b[4 * i + 1], NTT_ZETAS[64 + i]);
|
|
3827
|
+
ry = nttBaseMul(a[4 * i + 2], a[4 * i + 3], b[4 * i + 2], b[4 * i + 3], -NTT_ZETAS[64 + i]);
|
|
3828
|
+
a[4 * i + 0] = rx[0];
|
|
3829
|
+
a[4 * i + 1] = rx[1];
|
|
3830
|
+
a[4 * i + 2] = ry[0];
|
|
3831
|
+
a[4 * i + 3] = ry[1];
|
|
3832
|
+
}
|
|
3833
|
+
return a;
|
|
3834
|
+
}
|
|
3835
|
+
function nttBaseMul(a0, a1, b0, b1, zeta) {
|
|
3836
|
+
const r = new Array(2);
|
|
3837
|
+
r[0] = nttFqMul(a1, b1);
|
|
3838
|
+
r[0] = nttFqMul(r[0], zeta);
|
|
3839
|
+
r[0] += nttFqMul(a0, b0);
|
|
3840
|
+
r[1] = nttFqMul(a0, b1);
|
|
3841
|
+
r[1] += nttFqMul(a1, b0);
|
|
3842
|
+
return r;
|
|
3843
|
+
}
|
|
3844
|
+
function add(a, b) {
|
|
3845
|
+
const c = new Array(384);
|
|
3846
|
+
for (let i = 0; i < N; i++) {
|
|
3847
|
+
c[i] = a[i] + b[i];
|
|
3848
|
+
}
|
|
3849
|
+
return c;
|
|
3850
|
+
}
|
|
3851
|
+
function subtract(a, b) {
|
|
3852
|
+
for (let i = 0; i < N; i++) {
|
|
3853
|
+
a[i] -= b[i];
|
|
3854
|
+
}
|
|
3855
|
+
return a;
|
|
3856
|
+
}
|
|
3857
|
+
function nttInverse(r) {
|
|
3858
|
+
let j = 0;
|
|
3859
|
+
for (let k = 0, l = 2; l <= 128; l <<= 1) {
|
|
3860
|
+
for (let start = 0; start < 256; start = j + l) {
|
|
3861
|
+
const zeta = NTT_ZETAS_INV[k];
|
|
3862
|
+
k = k + 1;
|
|
3863
|
+
for (j = start; j < start + l; j++) {
|
|
3864
|
+
const t = r[j];
|
|
3865
|
+
r[j] = barrett(t + r[j + l]);
|
|
3866
|
+
r[j + l] = t - r[j + l];
|
|
3867
|
+
r[j + l] = nttFqMul(zeta, r[j + l]);
|
|
3868
|
+
}
|
|
3869
|
+
}
|
|
3870
|
+
}
|
|
3871
|
+
for (j = 0; j < 256; j++) {
|
|
3872
|
+
r[j] = nttFqMul(r[j], NTT_ZETAS_INV[127]);
|
|
3873
|
+
}
|
|
3874
|
+
return r;
|
|
3875
|
+
}
|
|
3876
|
+
function subtractQ(r) {
|
|
3877
|
+
for (let i = 0; i < N; i++) {
|
|
3878
|
+
r[i] -= Q;
|
|
3879
|
+
r[i] += r[i] >> 31 & Q;
|
|
3880
|
+
}
|
|
3881
|
+
return r;
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
// node_modules/mlkem/esm/src/mlKem768.js
|
|
3885
|
+
var MlKem768 = class extends MlKemBase {
|
|
3886
|
+
constructor() {
|
|
3887
|
+
super();
|
|
3888
|
+
Object.defineProperty(this, "_k", {
|
|
3889
|
+
enumerable: true,
|
|
3890
|
+
configurable: true,
|
|
3891
|
+
writable: true,
|
|
3892
|
+
value: 3
|
|
3893
|
+
});
|
|
3894
|
+
Object.defineProperty(this, "_du", {
|
|
3895
|
+
enumerable: true,
|
|
3896
|
+
configurable: true,
|
|
3897
|
+
writable: true,
|
|
3898
|
+
value: 10
|
|
3899
|
+
});
|
|
3900
|
+
Object.defineProperty(this, "_dv", {
|
|
3901
|
+
enumerable: true,
|
|
3902
|
+
configurable: true,
|
|
3903
|
+
writable: true,
|
|
3904
|
+
value: 4
|
|
3905
|
+
});
|
|
3906
|
+
Object.defineProperty(this, "_eta1", {
|
|
3907
|
+
enumerable: true,
|
|
3908
|
+
configurable: true,
|
|
3909
|
+
writable: true,
|
|
3910
|
+
value: 2
|
|
3911
|
+
});
|
|
3912
|
+
Object.defineProperty(this, "_eta2", {
|
|
3913
|
+
enumerable: true,
|
|
3914
|
+
configurable: true,
|
|
3915
|
+
writable: true,
|
|
3916
|
+
value: 2
|
|
3917
|
+
});
|
|
3918
|
+
this._skSize = 12 * this._k * N / 8;
|
|
3919
|
+
this._pkSize = this._skSize + 32;
|
|
3920
|
+
this._compressedUSize = this._k * this._du * N / 8;
|
|
3921
|
+
this._compressedVSize = this._dv * N / 8;
|
|
3922
|
+
}
|
|
3923
|
+
};
|
|
3924
|
+
|
|
3925
|
+
// src/index.ts
|
|
2329
3926
|
async function sha256(data) {
|
|
2330
3927
|
if (typeof globalThis.crypto?.subtle !== "undefined") {
|
|
2331
3928
|
const encoder = new TextEncoder();
|
|
@@ -2398,6 +3995,9 @@ var PROTO_MARKER = 86;
|
|
|
2398
3995
|
var FLAG_PADDED = 1;
|
|
2399
3996
|
var FLAG_SEALED = 2;
|
|
2400
3997
|
var FLAG_RATCHET = 4;
|
|
3998
|
+
var FLAG_PQ = 8;
|
|
3999
|
+
var FLAG_DH_RATCHET = 16;
|
|
4000
|
+
var FLAG_DENIABLE = 32;
|
|
2401
4001
|
function makeProtoHeader(flags, ratchetStep2) {
|
|
2402
4002
|
return new Uint8Array([PROTO_MARKER, flags, ratchetStep2 >> 8 & 255, ratchetStep2 & 255]);
|
|
2403
4003
|
}
|
|
@@ -2409,6 +4009,30 @@ function parseProtoHeader(data) {
|
|
|
2409
4009
|
content: data.slice(4)
|
|
2410
4010
|
};
|
|
2411
4011
|
}
|
|
4012
|
+
async function kdfRK(rootKey, dhOutput) {
|
|
4013
|
+
const combined = new Uint8Array(rootKey.length + dhOutput.length);
|
|
4014
|
+
combined.set(rootKey, 0);
|
|
4015
|
+
combined.set(dhOutput, rootKey.length);
|
|
4016
|
+
if (typeof globalThis.crypto?.subtle !== "undefined") {
|
|
4017
|
+
const prk2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined.buffer));
|
|
4018
|
+
const newRootKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array([...prk2, 1]).buffer));
|
|
4019
|
+
const newChainKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array([...prk2, 2]).buffer));
|
|
4020
|
+
return { newRootKey: newRootKey2, newChainKey: newChainKey2 };
|
|
4021
|
+
}
|
|
4022
|
+
const { createHash } = await import("crypto");
|
|
4023
|
+
const prk = new Uint8Array(createHash("sha256").update(Buffer.from(combined)).digest());
|
|
4024
|
+
const newRootKey = new Uint8Array(createHash("sha256").update(Buffer.from([...prk, 1])).digest());
|
|
4025
|
+
const newChainKey = new Uint8Array(createHash("sha256").update(Buffer.from([...prk, 2])).digest());
|
|
4026
|
+
return { newRootKey, newChainKey };
|
|
4027
|
+
}
|
|
4028
|
+
async function hmacSha256(key, data) {
|
|
4029
|
+
if (typeof globalThis.crypto?.subtle !== "undefined") {
|
|
4030
|
+
const cryptoKey = await globalThis.crypto.subtle.importKey("raw", key.buffer, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
|
|
4031
|
+
return new Uint8Array(await globalThis.crypto.subtle.sign("HMAC", cryptoKey, data.buffer));
|
|
4032
|
+
}
|
|
4033
|
+
const { createHmac } = await import("crypto");
|
|
4034
|
+
return new Uint8Array(createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest());
|
|
4035
|
+
}
|
|
2412
4036
|
var MAX_SKIP = 200;
|
|
2413
4037
|
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2414
4038
|
function toBase58(bytes) {
|
|
@@ -2420,14 +4044,16 @@ function toBase58(bytes) {
|
|
|
2420
4044
|
num = num / 58n;
|
|
2421
4045
|
result = BASE58_ALPHABET[Number(remainder)] + result;
|
|
2422
4046
|
}
|
|
2423
|
-
for (const
|
|
2424
|
-
if (
|
|
4047
|
+
for (const byte2 of bytes) {
|
|
4048
|
+
if (byte2 === 0) result = "1" + result;
|
|
2425
4049
|
else break;
|
|
2426
4050
|
}
|
|
2427
4051
|
return result || "1";
|
|
2428
4052
|
}
|
|
2429
4053
|
var VoidlyAgent = class _VoidlyAgent {
|
|
2430
4054
|
constructor(identity, config) {
|
|
4055
|
+
this._signedPrekey = null;
|
|
4056
|
+
this._signedPrekeyId = 0;
|
|
2431
4057
|
this._pinnedDids = /* @__PURE__ */ new Set();
|
|
2432
4058
|
this._listeners = /* @__PURE__ */ new Set();
|
|
2433
4059
|
this._conversations = /* @__PURE__ */ new Map();
|
|
@@ -2448,6 +4074,13 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2448
4074
|
this.sealedSender = config?.sealedSender || false;
|
|
2449
4075
|
this.requireSignatures = config?.requireSignatures || false;
|
|
2450
4076
|
this.timeout = config?.timeout ?? 3e4;
|
|
4077
|
+
this.postQuantum = config?.postQuantum !== false;
|
|
4078
|
+
this.deniable = config?.deniable || false;
|
|
4079
|
+
this.doubleRatchet = config?.doubleRatchet !== false;
|
|
4080
|
+
this.jitterMs = config?.jitterMs || 0;
|
|
4081
|
+
this.longPoll = config?.longPoll !== false;
|
|
4082
|
+
this.mlkemPublicKey = identity.mlkemPublicKey || null;
|
|
4083
|
+
this.mlkemSecretKey = identity.mlkemSecretKey || null;
|
|
2451
4084
|
}
|
|
2452
4085
|
// ─── Factory Methods ────────────────────────────────────────────────────────
|
|
2453
4086
|
/**
|
|
@@ -2458,15 +4091,33 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2458
4091
|
const baseUrl = config?.baseUrl || "https://api.voidly.ai";
|
|
2459
4092
|
const signingKeyPair = import_tweetnacl.default.sign.keyPair();
|
|
2460
4093
|
const encryptionKeyPair = import_tweetnacl.default.box.keyPair();
|
|
4094
|
+
const usePQ = config?.postQuantum !== false;
|
|
4095
|
+
let mlkemPk;
|
|
4096
|
+
let mlkemSk;
|
|
4097
|
+
if (usePQ) {
|
|
4098
|
+
const kem = new MlKem768();
|
|
4099
|
+
[mlkemPk, mlkemSk] = await kem.generateKeyPair();
|
|
4100
|
+
}
|
|
4101
|
+
const signedPrekeyPair = import_tweetnacl.default.box.keyPair();
|
|
4102
|
+
const signedPrekeyId = 1;
|
|
4103
|
+
const prekeySignature = import_tweetnacl.default.sign.detached(signedPrekeyPair.publicKey, signingKeyPair.secretKey);
|
|
4104
|
+
const regBody = {
|
|
4105
|
+
name: options.name,
|
|
4106
|
+
capabilities: options.capabilities,
|
|
4107
|
+
signing_public_key: (0, import_tweetnacl_util.encodeBase64)(signingKeyPair.publicKey),
|
|
4108
|
+
encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(encryptionKeyPair.publicKey),
|
|
4109
|
+
// X3DH signed prekey
|
|
4110
|
+
signed_prekey_public: (0, import_tweetnacl_util.encodeBase64)(signedPrekeyPair.publicKey),
|
|
4111
|
+
signed_prekey_signature: (0, import_tweetnacl_util.encodeBase64)(prekeySignature),
|
|
4112
|
+
signed_prekey_id: signedPrekeyId
|
|
4113
|
+
};
|
|
4114
|
+
if (mlkemPk) {
|
|
4115
|
+
regBody.mlkem_public_key = (0, import_tweetnacl_util.encodeBase64)(mlkemPk);
|
|
4116
|
+
}
|
|
2461
4117
|
const res = await fetch(`${baseUrl}/v1/agent/register`, {
|
|
2462
4118
|
method: "POST",
|
|
2463
4119
|
headers: { "Content-Type": "application/json" },
|
|
2464
|
-
body: JSON.stringify(
|
|
2465
|
-
name: options.name,
|
|
2466
|
-
capabilities: options.capabilities,
|
|
2467
|
-
signing_public_key: (0, import_tweetnacl_util.encodeBase64)(signingKeyPair.publicKey),
|
|
2468
|
-
encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(encryptionKeyPair.publicKey)
|
|
2469
|
-
})
|
|
4120
|
+
body: JSON.stringify(regBody)
|
|
2470
4121
|
});
|
|
2471
4122
|
if (!res.ok) {
|
|
2472
4123
|
const err = await res.json().catch(() => ({}));
|
|
@@ -2474,12 +4125,17 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2474
4125
|
throw new Error(`Registration failed: ${errMsg}`);
|
|
2475
4126
|
}
|
|
2476
4127
|
const data = await res.json();
|
|
2477
|
-
|
|
4128
|
+
const agent = new _VoidlyAgent({
|
|
2478
4129
|
did: data.did,
|
|
2479
4130
|
apiKey: data.api_key,
|
|
2480
4131
|
signingKeyPair,
|
|
2481
|
-
encryptionKeyPair
|
|
4132
|
+
encryptionKeyPair,
|
|
4133
|
+
mlkemPublicKey: mlkemPk,
|
|
4134
|
+
mlkemSecretKey: mlkemSk
|
|
2482
4135
|
}, config);
|
|
4136
|
+
agent._signedPrekey = signedPrekeyPair;
|
|
4137
|
+
agent._signedPrekeyId = signedPrekeyId;
|
|
4138
|
+
return agent;
|
|
2483
4139
|
}
|
|
2484
4140
|
/**
|
|
2485
4141
|
* Restore an agent from saved credentials.
|
|
@@ -2509,28 +4165,124 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2509
4165
|
if (encryptionSecret.length !== 32) {
|
|
2510
4166
|
throw new Error(`Invalid credentials: encryption key must be 32 bytes, got ${encryptionSecret.length}`);
|
|
2511
4167
|
}
|
|
2512
|
-
|
|
4168
|
+
let mlkemPk;
|
|
4169
|
+
let mlkemSk;
|
|
4170
|
+
if (creds.mlkemPublicKey && creds.mlkemSecretKey) {
|
|
4171
|
+
try {
|
|
4172
|
+
mlkemPk = (0, import_tweetnacl_util.decodeBase64)(creds.mlkemPublicKey);
|
|
4173
|
+
mlkemSk = (0, import_tweetnacl_util.decodeBase64)(creds.mlkemSecretKey);
|
|
4174
|
+
if (mlkemPk.length !== 1184 || mlkemSk.length !== 2400) {
|
|
4175
|
+
mlkemPk = void 0;
|
|
4176
|
+
mlkemSk = void 0;
|
|
4177
|
+
}
|
|
4178
|
+
} catch {
|
|
4179
|
+
}
|
|
4180
|
+
}
|
|
4181
|
+
const agent = new _VoidlyAgent({
|
|
2513
4182
|
did: creds.did,
|
|
2514
4183
|
apiKey: creds.apiKey,
|
|
2515
4184
|
signingKeyPair: import_tweetnacl.default.sign.keyPair.fromSecretKey(signingSecret),
|
|
2516
4185
|
encryptionKeyPair: {
|
|
2517
4186
|
publicKey: import_tweetnacl.default.box.keyPair.fromSecretKey(encryptionSecret).publicKey,
|
|
2518
4187
|
secretKey: encryptionSecret
|
|
2519
|
-
}
|
|
4188
|
+
},
|
|
4189
|
+
mlkemPublicKey: mlkemPk,
|
|
4190
|
+
mlkemSecretKey: mlkemSk
|
|
2520
4191
|
}, config);
|
|
4192
|
+
if (creds.ratchetStates) {
|
|
4193
|
+
for (const [pairId, rs] of Object.entries(creds.ratchetStates)) {
|
|
4194
|
+
try {
|
|
4195
|
+
const sendChainKey = (0, import_tweetnacl_util.decodeBase64)(rs.sendChainKey);
|
|
4196
|
+
const recvChainKey = (0, import_tweetnacl_util.decodeBase64)(rs.recvChainKey);
|
|
4197
|
+
if (sendChainKey.length !== 32 || recvChainKey.length !== 32) continue;
|
|
4198
|
+
const state = {
|
|
4199
|
+
sendChainKey,
|
|
4200
|
+
sendStep: rs.sendStep || 0,
|
|
4201
|
+
recvChainKey,
|
|
4202
|
+
recvStep: rs.recvStep || 0,
|
|
4203
|
+
skippedKeys: /* @__PURE__ */ new Map()
|
|
4204
|
+
};
|
|
4205
|
+
if (rs.rootKey) {
|
|
4206
|
+
try {
|
|
4207
|
+
state.rootKey = (0, import_tweetnacl_util.decodeBase64)(rs.rootKey);
|
|
4208
|
+
if (state.rootKey.length !== 32) state.rootKey = void 0;
|
|
4209
|
+
} catch {
|
|
4210
|
+
}
|
|
4211
|
+
}
|
|
4212
|
+
if (rs.dhSendSecretKey && rs.dhSendPublicKey) {
|
|
4213
|
+
try {
|
|
4214
|
+
const sk = (0, import_tweetnacl_util.decodeBase64)(rs.dhSendSecretKey);
|
|
4215
|
+
const pk = (0, import_tweetnacl_util.decodeBase64)(rs.dhSendPublicKey);
|
|
4216
|
+
if (sk.length === 32 && pk.length === 32) {
|
|
4217
|
+
state.dhSendKeyPair = { publicKey: pk, secretKey: sk };
|
|
4218
|
+
}
|
|
4219
|
+
} catch {
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4222
|
+
if (rs.dhRecvPubKey) {
|
|
4223
|
+
try {
|
|
4224
|
+
const pk = (0, import_tweetnacl_util.decodeBase64)(rs.dhRecvPubKey);
|
|
4225
|
+
if (pk.length === 32) state.dhRecvPubKey = pk;
|
|
4226
|
+
} catch {
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
if (rs.prevSendStep !== void 0) state.prevSendStep = rs.prevSendStep;
|
|
4230
|
+
state.dhSkippedKeys = /* @__PURE__ */ new Map();
|
|
4231
|
+
agent._ratchetStates.set(pairId, state);
|
|
4232
|
+
} catch {
|
|
4233
|
+
}
|
|
4234
|
+
}
|
|
4235
|
+
}
|
|
4236
|
+
if (creds.signedPrekeySecret && creds.signedPrekeyPublic) {
|
|
4237
|
+
try {
|
|
4238
|
+
const sk = (0, import_tweetnacl_util.decodeBase64)(creds.signedPrekeySecret);
|
|
4239
|
+
const pk = (0, import_tweetnacl_util.decodeBase64)(creds.signedPrekeyPublic);
|
|
4240
|
+
if (sk.length === 32 && pk.length === 32) {
|
|
4241
|
+
agent._signedPrekey = { publicKey: pk, secretKey: sk };
|
|
4242
|
+
agent._signedPrekeyId = creds.signedPrekeyId || 0;
|
|
4243
|
+
}
|
|
4244
|
+
} catch {
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
return agent;
|
|
2521
4248
|
}
|
|
2522
4249
|
/**
|
|
2523
4250
|
* Export credentials for persistence.
|
|
2524
4251
|
* Store these securely — they contain private keys.
|
|
2525
4252
|
*/
|
|
2526
4253
|
exportCredentials() {
|
|
4254
|
+
const ratchetStates = {};
|
|
4255
|
+
for (const [pairId, state] of this._ratchetStates) {
|
|
4256
|
+
const rs = {
|
|
4257
|
+
sendChainKey: (0, import_tweetnacl_util.encodeBase64)(state.sendChainKey),
|
|
4258
|
+
sendStep: state.sendStep,
|
|
4259
|
+
recvChainKey: (0, import_tweetnacl_util.encodeBase64)(state.recvChainKey),
|
|
4260
|
+
recvStep: state.recvStep
|
|
4261
|
+
};
|
|
4262
|
+
if (state.rootKey) rs.rootKey = (0, import_tweetnacl_util.encodeBase64)(state.rootKey);
|
|
4263
|
+
if (state.dhSendKeyPair) {
|
|
4264
|
+
rs.dhSendSecretKey = (0, import_tweetnacl_util.encodeBase64)(state.dhSendKeyPair.secretKey);
|
|
4265
|
+
rs.dhSendPublicKey = (0, import_tweetnacl_util.encodeBase64)(state.dhSendKeyPair.publicKey);
|
|
4266
|
+
}
|
|
4267
|
+
if (state.dhRecvPubKey) rs.dhRecvPubKey = (0, import_tweetnacl_util.encodeBase64)(state.dhRecvPubKey);
|
|
4268
|
+
if (state.prevSendStep !== void 0) rs.prevSendStep = state.prevSendStep;
|
|
4269
|
+
ratchetStates[pairId] = rs;
|
|
4270
|
+
}
|
|
2527
4271
|
return {
|
|
2528
4272
|
did: this.did,
|
|
2529
4273
|
apiKey: this.apiKey,
|
|
2530
4274
|
signingSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.signingKeyPair.secretKey),
|
|
2531
4275
|
encryptionSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.secretKey),
|
|
2532
4276
|
signingPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.signingKeyPair.publicKey),
|
|
2533
|
-
encryptionPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.publicKey)
|
|
4277
|
+
encryptionPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.publicKey),
|
|
4278
|
+
...Object.keys(ratchetStates).length > 0 ? { ratchetStates } : {},
|
|
4279
|
+
...this.mlkemPublicKey ? { mlkemPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.mlkemPublicKey) } : {},
|
|
4280
|
+
...this.mlkemSecretKey ? { mlkemSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.mlkemSecretKey) } : {},
|
|
4281
|
+
...this._signedPrekey ? {
|
|
4282
|
+
signedPrekeySecret: (0, import_tweetnacl_util.encodeBase64)(this._signedPrekey.secretKey),
|
|
4283
|
+
signedPrekeyPublic: (0, import_tweetnacl_util.encodeBase64)(this._signedPrekey.publicKey),
|
|
4284
|
+
signedPrekeyId: this._signedPrekeyId
|
|
4285
|
+
} : {}
|
|
2534
4286
|
};
|
|
2535
4287
|
}
|
|
2536
4288
|
/**
|
|
@@ -2590,17 +4342,58 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2590
4342
|
}
|
|
2591
4343
|
const pairId = `${this.did}:${recipientDid}`;
|
|
2592
4344
|
let state = this._ratchetStates.get(pairId);
|
|
4345
|
+
let pqCiphertext = null;
|
|
4346
|
+
let dhRatchetPub = null;
|
|
2593
4347
|
if (!state) {
|
|
2594
|
-
const
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
4348
|
+
const x25519Shared = import_tweetnacl.default.box.before(recipientPubKey, this.encryptionKeyPair.secretKey);
|
|
4349
|
+
let initialKey;
|
|
4350
|
+
if (this.postQuantum && profile.mlkem_public_key) {
|
|
4351
|
+
try {
|
|
4352
|
+
const recipientPqPk = (0, import_tweetnacl_util.decodeBase64)(profile.mlkem_public_key);
|
|
4353
|
+
const kem = new MlKem768();
|
|
4354
|
+
const [ct, pqShared] = await kem.encap(recipientPqPk);
|
|
4355
|
+
pqCiphertext = ct;
|
|
4356
|
+
const combined = new Uint8Array(x25519Shared.length + pqShared.length);
|
|
4357
|
+
combined.set(x25519Shared, 0);
|
|
4358
|
+
combined.set(pqShared, x25519Shared.length);
|
|
4359
|
+
initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
|
|
4360
|
+
} catch {
|
|
4361
|
+
initialKey = x25519Shared;
|
|
4362
|
+
}
|
|
4363
|
+
} else {
|
|
4364
|
+
initialKey = x25519Shared;
|
|
4365
|
+
}
|
|
4366
|
+
if (this.doubleRatchet) {
|
|
4367
|
+
const dhSendKeyPair = import_tweetnacl.default.box.keyPair();
|
|
4368
|
+
const dhOutput = import_tweetnacl.default.box.before(recipientPubKey, dhSendKeyPair.secretKey);
|
|
4369
|
+
const { newRootKey, newChainKey } = await kdfRK(initialKey, dhOutput);
|
|
4370
|
+
dhRatchetPub = dhSendKeyPair.publicKey;
|
|
4371
|
+
state = {
|
|
4372
|
+
sendChainKey: newChainKey,
|
|
4373
|
+
sendStep: 0,
|
|
4374
|
+
recvChainKey: initialKey,
|
|
4375
|
+
// Will be updated on first receive
|
|
4376
|
+
recvStep: 0,
|
|
4377
|
+
skippedKeys: /* @__PURE__ */ new Map(),
|
|
4378
|
+
// Double Ratchet state
|
|
4379
|
+
rootKey: newRootKey,
|
|
4380
|
+
dhSendKeyPair,
|
|
4381
|
+
dhRecvPubKey: void 0,
|
|
4382
|
+
prevSendStep: 0,
|
|
4383
|
+
dhSkippedKeys: /* @__PURE__ */ new Map()
|
|
4384
|
+
};
|
|
4385
|
+
} else {
|
|
4386
|
+
state = {
|
|
4387
|
+
sendChainKey: initialKey,
|
|
4388
|
+
sendStep: 0,
|
|
4389
|
+
recvChainKey: initialKey,
|
|
4390
|
+
recvStep: 0,
|
|
4391
|
+
skippedKeys: /* @__PURE__ */ new Map()
|
|
4392
|
+
};
|
|
4393
|
+
}
|
|
2603
4394
|
this._ratchetStates.set(pairId, state);
|
|
4395
|
+
} else if (state.rootKey && state.dhSendKeyPair) {
|
|
4396
|
+
dhRatchetPub = state.dhSendKeyPair.publicKey;
|
|
2604
4397
|
}
|
|
2605
4398
|
const { nextChainKey, messageKey } = await ratchetStep(state.sendChainKey);
|
|
2606
4399
|
state.sendChainKey = nextChainKey;
|
|
@@ -2609,6 +4402,9 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2609
4402
|
let flags = FLAG_RATCHET;
|
|
2610
4403
|
if (usePadding) flags |= FLAG_PADDED;
|
|
2611
4404
|
if (useSealed) flags |= FLAG_SEALED;
|
|
4405
|
+
if (pqCiphertext) flags |= FLAG_PQ;
|
|
4406
|
+
if (dhRatchetPub) flags |= FLAG_DH_RATCHET;
|
|
4407
|
+
if (this.deniable) flags |= FLAG_DENIABLE;
|
|
2612
4408
|
const header = makeProtoHeader(flags, currentStep);
|
|
2613
4409
|
const messageBytes = new Uint8Array(header.length + contentBytes.length);
|
|
2614
4410
|
messageBytes.set(header, 0);
|
|
@@ -2618,15 +4414,33 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2618
4414
|
if (!ciphertext) {
|
|
2619
4415
|
throw new Error("Encryption failed");
|
|
2620
4416
|
}
|
|
2621
|
-
|
|
4417
|
+
if (this.jitterMs > 0) {
|
|
4418
|
+
const jitter = Math.random() * this.jitterMs;
|
|
4419
|
+
await new Promise((r) => setTimeout(r, jitter));
|
|
4420
|
+
}
|
|
4421
|
+
const envelopeObj = {
|
|
2622
4422
|
from: this.did,
|
|
2623
4423
|
to: recipientDid,
|
|
2624
4424
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2625
4425
|
nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
2626
4426
|
ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(ciphertext)),
|
|
2627
4427
|
ratchet_step: currentStep
|
|
2628
|
-
}
|
|
2629
|
-
|
|
4428
|
+
};
|
|
4429
|
+
if (pqCiphertext) {
|
|
4430
|
+
envelopeObj.pq_ciphertext = (0, import_tweetnacl_util.encodeBase64)(pqCiphertext);
|
|
4431
|
+
}
|
|
4432
|
+
if (dhRatchetPub) {
|
|
4433
|
+
envelopeObj.dh_ratchet_key = (0, import_tweetnacl_util.encodeBase64)(dhRatchetPub);
|
|
4434
|
+
envelopeObj.pn = state.prevSendStep || 0;
|
|
4435
|
+
}
|
|
4436
|
+
const envelopeData = JSON.stringify(envelopeObj);
|
|
4437
|
+
let signature;
|
|
4438
|
+
if (this.deniable) {
|
|
4439
|
+
const sharedSecret = import_tweetnacl.default.box.before(recipientPubKey, this.encryptionKeyPair.secretKey);
|
|
4440
|
+
signature = await hmacSha256(sharedSecret, (0, import_tweetnacl_util.decodeUTF8)(envelopeData));
|
|
4441
|
+
} else {
|
|
4442
|
+
signature = import_tweetnacl.default.sign.detached((0, import_tweetnacl_util.decodeUTF8)(envelopeData), this.signingKeyPair.secretKey);
|
|
4443
|
+
}
|
|
2630
4444
|
const payload = {
|
|
2631
4445
|
to: recipientDid,
|
|
2632
4446
|
ciphertext: (0, import_tweetnacl_util.encodeBase64)(ciphertext),
|
|
@@ -2689,7 +4503,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2689
4503
|
if (options.contentType) params.set("content_type", options.contentType);
|
|
2690
4504
|
if (options.messageType) params.set("message_type", options.messageType);
|
|
2691
4505
|
if (options.unreadOnly) params.set("unread", "true");
|
|
2692
|
-
const res = await
|
|
4506
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/receive/raw?${params}`, {
|
|
2693
4507
|
headers: { "X-Agent-Key": this.apiKey }
|
|
2694
4508
|
});
|
|
2695
4509
|
if (!res.ok) {
|
|
@@ -2706,12 +4520,25 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2706
4520
|
const nonce = (0, import_tweetnacl_util.decodeBase64)(msg.nonce);
|
|
2707
4521
|
let rawPlaintext = null;
|
|
2708
4522
|
let envelopeRatchetStep = 0;
|
|
4523
|
+
let envelopePqCiphertext = null;
|
|
4524
|
+
let envelopeDhRatchetKey = null;
|
|
4525
|
+
let envelopePn = 0;
|
|
4526
|
+
let envelopeDeniable = false;
|
|
2709
4527
|
if (msg.envelope) {
|
|
2710
4528
|
try {
|
|
2711
4529
|
const env = JSON.parse(msg.envelope);
|
|
2712
4530
|
if (typeof env.ratchet_step === "number") {
|
|
2713
4531
|
envelopeRatchetStep = env.ratchet_step;
|
|
2714
4532
|
}
|
|
4533
|
+
if (typeof env.pq_ciphertext === "string") {
|
|
4534
|
+
envelopePqCiphertext = env.pq_ciphertext;
|
|
4535
|
+
}
|
|
4536
|
+
if (typeof env.dh_ratchet_key === "string") {
|
|
4537
|
+
envelopeDhRatchetKey = env.dh_ratchet_key;
|
|
4538
|
+
}
|
|
4539
|
+
if (typeof env.pn === "number") {
|
|
4540
|
+
envelopePn = env.pn;
|
|
4541
|
+
}
|
|
2715
4542
|
} catch {
|
|
2716
4543
|
}
|
|
2717
4544
|
}
|
|
@@ -2719,20 +4546,90 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2719
4546
|
const pairId = `${msg.from}:${this.did}`;
|
|
2720
4547
|
let state = this._ratchetStates.get(pairId);
|
|
2721
4548
|
if (!state) {
|
|
2722
|
-
const
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
4549
|
+
const x25519Shared = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4550
|
+
let initialKey;
|
|
4551
|
+
if (envelopePqCiphertext && this.mlkemSecretKey) {
|
|
4552
|
+
try {
|
|
4553
|
+
const pqCt = (0, import_tweetnacl_util.decodeBase64)(envelopePqCiphertext);
|
|
4554
|
+
const kem = new MlKem768();
|
|
4555
|
+
const pqShared = await kem.decap(pqCt, this.mlkemSecretKey);
|
|
4556
|
+
const combined = new Uint8Array(x25519Shared.length + pqShared.length);
|
|
4557
|
+
combined.set(x25519Shared, 0);
|
|
4558
|
+
combined.set(pqShared, x25519Shared.length);
|
|
4559
|
+
initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
|
|
4560
|
+
} catch {
|
|
4561
|
+
initialKey = x25519Shared;
|
|
4562
|
+
}
|
|
4563
|
+
} else {
|
|
4564
|
+
initialKey = x25519Shared;
|
|
4565
|
+
}
|
|
4566
|
+
if (envelopeDhRatchetKey && this.doubleRatchet) {
|
|
4567
|
+
const senderDhPub = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
|
|
4568
|
+
const dhOutput = import_tweetnacl.default.box.before(senderDhPub, this.encryptionKeyPair.secretKey);
|
|
4569
|
+
const { newRootKey, newChainKey } = await kdfRK(initialKey, dhOutput);
|
|
4570
|
+
state = {
|
|
4571
|
+
sendChainKey: initialKey,
|
|
4572
|
+
sendStep: 0,
|
|
4573
|
+
recvChainKey: newChainKey,
|
|
4574
|
+
recvStep: 0,
|
|
4575
|
+
skippedKeys: /* @__PURE__ */ new Map(),
|
|
4576
|
+
rootKey: newRootKey,
|
|
4577
|
+
dhSendKeyPair: void 0,
|
|
4578
|
+
dhRecvPubKey: senderDhPub,
|
|
4579
|
+
prevSendStep: 0,
|
|
4580
|
+
dhSkippedKeys: /* @__PURE__ */ new Map()
|
|
4581
|
+
};
|
|
4582
|
+
} else {
|
|
4583
|
+
state = {
|
|
4584
|
+
sendChainKey: initialKey,
|
|
4585
|
+
sendStep: 0,
|
|
4586
|
+
recvChainKey: initialKey,
|
|
4587
|
+
recvStep: 0,
|
|
4588
|
+
skippedKeys: /* @__PURE__ */ new Map()
|
|
4589
|
+
};
|
|
4590
|
+
}
|
|
2732
4591
|
this._ratchetStates.set(pairId, state);
|
|
4592
|
+
} else if (envelopeDhRatchetKey && state.rootKey) {
|
|
4593
|
+
const senderDhPub = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
|
|
4594
|
+
const currentDhRecv = state.dhRecvPubKey;
|
|
4595
|
+
if (!currentDhRecv || (0, import_tweetnacl_util.encodeBase64)(senderDhPub) !== (0, import_tweetnacl_util.encodeBase64)(currentDhRecv)) {
|
|
4596
|
+
if (envelopePn > state.recvStep) {
|
|
4597
|
+
let ck = state.recvChainKey;
|
|
4598
|
+
for (let i = state.recvStep + 1; i <= envelopePn && i - state.recvStep <= MAX_SKIP; i++) {
|
|
4599
|
+
const { nextChainKey, messageKey: skippedMk } = await ratchetStep(ck);
|
|
4600
|
+
const skipKey = `${currentDhRecv ? (0, import_tweetnacl_util.encodeBase64)(currentDhRecv) : "init"}:${i}`;
|
|
4601
|
+
if (!state.dhSkippedKeys) state.dhSkippedKeys = /* @__PURE__ */ new Map();
|
|
4602
|
+
state.dhSkippedKeys.set(skipKey, skippedMk);
|
|
4603
|
+
ck = nextChainKey;
|
|
4604
|
+
if (state.dhSkippedKeys.size > MAX_SKIP) {
|
|
4605
|
+
const oldest = state.dhSkippedKeys.keys().next().value;
|
|
4606
|
+
if (oldest !== void 0) state.dhSkippedKeys.delete(oldest);
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
}
|
|
4610
|
+
state.dhRecvPubKey = senderDhPub;
|
|
4611
|
+
const myKey = state.dhSendKeyPair || this.encryptionKeyPair;
|
|
4612
|
+
const dhOutput1 = import_tweetnacl.default.box.before(senderDhPub, myKey.secretKey);
|
|
4613
|
+
const kdf1 = await kdfRK(state.rootKey, dhOutput1);
|
|
4614
|
+
state.rootKey = kdf1.newRootKey;
|
|
4615
|
+
state.recvChainKey = kdf1.newChainKey;
|
|
4616
|
+
state.recvStep = 0;
|
|
4617
|
+
state.prevSendStep = state.sendStep;
|
|
4618
|
+
state.dhSendKeyPair = import_tweetnacl.default.box.keyPair();
|
|
4619
|
+
state.sendStep = 0;
|
|
4620
|
+
const dhOutput2 = import_tweetnacl.default.box.before(senderDhPub, state.dhSendKeyPair.secretKey);
|
|
4621
|
+
const kdf2 = await kdfRK(state.rootKey, dhOutput2);
|
|
4622
|
+
state.rootKey = kdf2.newRootKey;
|
|
4623
|
+
state.sendChainKey = kdf2.newChainKey;
|
|
4624
|
+
}
|
|
2733
4625
|
}
|
|
2734
4626
|
const targetStep = envelopeRatchetStep;
|
|
2735
|
-
|
|
4627
|
+
const dhSkipKey = envelopeDhRatchetKey ? `${envelopeDhRatchetKey}:${targetStep}` : `init:${targetStep}`;
|
|
4628
|
+
if (state.dhSkippedKeys?.has(dhSkipKey)) {
|
|
4629
|
+
const mk = state.dhSkippedKeys.get(dhSkipKey);
|
|
4630
|
+
rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, mk);
|
|
4631
|
+
state.dhSkippedKeys.delete(dhSkipKey);
|
|
4632
|
+
} else if (state.skippedKeys.has(targetStep)) {
|
|
2736
4633
|
const mk = state.skippedKeys.get(targetStep);
|
|
2737
4634
|
rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, mk);
|
|
2738
4635
|
state.skippedKeys.delete(targetStep);
|
|
@@ -2795,7 +4692,6 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2795
4692
|
}
|
|
2796
4693
|
let signatureValid = false;
|
|
2797
4694
|
try {
|
|
2798
|
-
const senderSignPub = (0, import_tweetnacl_util.decodeBase64)(msg.sender_signing_key);
|
|
2799
4695
|
const signatureBytes = (0, import_tweetnacl_util.decodeBase64)(msg.signature);
|
|
2800
4696
|
const envelopeStr = msg.envelope || JSON.stringify({
|
|
2801
4697
|
from: senderDid,
|
|
@@ -2804,11 +4700,22 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2804
4700
|
nonce: msg.nonce,
|
|
2805
4701
|
ciphertext_hash: await sha256(msg.ciphertext)
|
|
2806
4702
|
});
|
|
2807
|
-
|
|
2808
|
-
(
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
4703
|
+
if (signatureBytes.length === 32) {
|
|
4704
|
+
const sharedSecret = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
|
|
4705
|
+
const expectedHmac = await hmacSha256(sharedSecret, (0, import_tweetnacl_util.decodeUTF8)(envelopeStr));
|
|
4706
|
+
if (expectedHmac.length === signatureBytes.length) {
|
|
4707
|
+
let diff = 0;
|
|
4708
|
+
for (let i = 0; i < expectedHmac.length; i++) diff |= expectedHmac[i] ^ signatureBytes[i];
|
|
4709
|
+
signatureValid = diff === 0;
|
|
4710
|
+
}
|
|
4711
|
+
} else {
|
|
4712
|
+
const senderSignPub = (0, import_tweetnacl_util.decodeBase64)(msg.sender_signing_key);
|
|
4713
|
+
signatureValid = import_tweetnacl.default.sign.detached.verify(
|
|
4714
|
+
(0, import_tweetnacl_util.decodeUTF8)(envelopeStr),
|
|
4715
|
+
signatureBytes,
|
|
4716
|
+
senderSignPub
|
|
4717
|
+
);
|
|
4718
|
+
}
|
|
2812
4719
|
} catch {
|
|
2813
4720
|
signatureValid = false;
|
|
2814
4721
|
}
|
|
@@ -2845,7 +4752,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2845
4752
|
* Delete a message by ID (must be sender or recipient).
|
|
2846
4753
|
*/
|
|
2847
4754
|
async deleteMessage(messageId) {
|
|
2848
|
-
const res = await
|
|
4755
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/${messageId}`, {
|
|
2849
4756
|
method: "DELETE",
|
|
2850
4757
|
headers: { "X-Agent-Key": this.apiKey }
|
|
2851
4758
|
});
|
|
@@ -2856,7 +4763,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2856
4763
|
* Get this agent's own profile.
|
|
2857
4764
|
*/
|
|
2858
4765
|
async getProfile() {
|
|
2859
|
-
const res = await
|
|
4766
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/profile`, {
|
|
2860
4767
|
headers: { "X-Agent-Key": this.apiKey }
|
|
2861
4768
|
});
|
|
2862
4769
|
if (!res.ok) {
|
|
@@ -2868,7 +4775,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2868
4775
|
* Update this agent's profile (name, capabilities, metadata).
|
|
2869
4776
|
*/
|
|
2870
4777
|
async updateProfile(updates) {
|
|
2871
|
-
const res = await
|
|
4778
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/profile`, {
|
|
2872
4779
|
method: "PATCH",
|
|
2873
4780
|
headers: {
|
|
2874
4781
|
"Content-Type": "application/json",
|
|
@@ -2890,7 +4797,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2890
4797
|
if (cached && Date.now() - cached.cachedAt < 3e5) {
|
|
2891
4798
|
return cached.profile;
|
|
2892
4799
|
}
|
|
2893
|
-
const res = await
|
|
4800
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${did}`);
|
|
2894
4801
|
if (!res.ok) return null;
|
|
2895
4802
|
const profile = await res.json();
|
|
2896
4803
|
this._identityCache.set(did, { profile, cachedAt: Date.now() });
|
|
@@ -2908,7 +4815,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2908
4815
|
if (options.query) params.set("query", options.query);
|
|
2909
4816
|
if (options.capability) params.set("capability", options.capability);
|
|
2910
4817
|
if (options.limit) params.set("limit", String(options.limit));
|
|
2911
|
-
const res = await
|
|
4818
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/discover?${params}`);
|
|
2912
4819
|
if (!res.ok) return [];
|
|
2913
4820
|
const data = await res.json();
|
|
2914
4821
|
return data.agents;
|
|
@@ -2917,7 +4824,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2917
4824
|
* Get relay network statistics.
|
|
2918
4825
|
*/
|
|
2919
4826
|
async stats() {
|
|
2920
|
-
const res = await
|
|
4827
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/stats`);
|
|
2921
4828
|
return await res.json();
|
|
2922
4829
|
}
|
|
2923
4830
|
// ─── Webhooks ──────────────────────────────────────────────────────────────
|
|
@@ -2926,7 +4833,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2926
4833
|
* Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
|
|
2927
4834
|
*/
|
|
2928
4835
|
async registerWebhook(webhookUrl, options = {}) {
|
|
2929
|
-
const res = await
|
|
4836
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks`, {
|
|
2930
4837
|
method: "POST",
|
|
2931
4838
|
headers: {
|
|
2932
4839
|
"Content-Type": "application/json",
|
|
@@ -2947,7 +4854,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2947
4854
|
* List registered webhooks.
|
|
2948
4855
|
*/
|
|
2949
4856
|
async listWebhooks() {
|
|
2950
|
-
const res = await
|
|
4857
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks`, {
|
|
2951
4858
|
headers: { "X-Agent-Key": this.apiKey }
|
|
2952
4859
|
});
|
|
2953
4860
|
if (!res.ok) return [];
|
|
@@ -2958,7 +4865,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
2958
4865
|
* Delete a webhook.
|
|
2959
4866
|
*/
|
|
2960
4867
|
async deleteWebhook(webhookId) {
|
|
2961
|
-
const res = await
|
|
4868
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks/${webhookId}`, {
|
|
2962
4869
|
method: "DELETE",
|
|
2963
4870
|
headers: { "X-Agent-Key": this.apiKey }
|
|
2964
4871
|
});
|
|
@@ -3002,22 +4909,35 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3002
4909
|
async rotateKeys() {
|
|
3003
4910
|
const newSigningKeyPair = import_tweetnacl.default.sign.keyPair();
|
|
3004
4911
|
const newEncryptionKeyPair = import_tweetnacl.default.box.keyPair();
|
|
3005
|
-
const
|
|
4912
|
+
const newSignedPrekey = import_tweetnacl.default.box.keyPair();
|
|
4913
|
+
const newSignedPrekeyId = (this._signedPrekeyId || 0) + 1;
|
|
4914
|
+
const signedPrekeySignature = import_tweetnacl.default.sign.detached(newSignedPrekey.publicKey, newSigningKeyPair.secretKey);
|
|
4915
|
+
const body = {
|
|
4916
|
+
signing_public_key: (0, import_tweetnacl_util.encodeBase64)(newSigningKeyPair.publicKey),
|
|
4917
|
+
encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(newEncryptionKeyPair.publicKey),
|
|
4918
|
+
signed_prekey_public: (0, import_tweetnacl_util.encodeBase64)(newSignedPrekey.publicKey),
|
|
4919
|
+
signed_prekey_signature: (0, import_tweetnacl_util.encodeBase64)(signedPrekeySignature),
|
|
4920
|
+
signed_prekey_id: newSignedPrekeyId
|
|
4921
|
+
};
|
|
4922
|
+
if (this.postQuantum && this.mlkemPublicKey) {
|
|
4923
|
+
body.mlkem_public_key = this.mlkemPublicKey;
|
|
4924
|
+
}
|
|
4925
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/rotate-keys`, {
|
|
3006
4926
|
method: "POST",
|
|
3007
4927
|
headers: {
|
|
3008
4928
|
"Content-Type": "application/json",
|
|
3009
4929
|
"X-Agent-Key": this.apiKey
|
|
3010
4930
|
},
|
|
3011
|
-
body: JSON.stringify(
|
|
3012
|
-
signing_public_key: (0, import_tweetnacl_util.encodeBase64)(newSigningKeyPair.publicKey),
|
|
3013
|
-
encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(newEncryptionKeyPair.publicKey)
|
|
3014
|
-
})
|
|
4931
|
+
body: JSON.stringify(body)
|
|
3015
4932
|
});
|
|
3016
4933
|
if (!res.ok) {
|
|
3017
4934
|
throw new Error("Key rotation failed");
|
|
3018
4935
|
}
|
|
3019
4936
|
this.signingKeyPair = newSigningKeyPair;
|
|
3020
4937
|
this.encryptionKeyPair = newEncryptionKeyPair;
|
|
4938
|
+
this._signedPrekey = newSignedPrekey;
|
|
4939
|
+
this._signedPrekeyId = newSignedPrekeyId;
|
|
4940
|
+
await this.uploadPrekeys(10);
|
|
3021
4941
|
}
|
|
3022
4942
|
// ─── Channels (Encrypted AI Forum) ──────────────────────────────────────────
|
|
3023
4943
|
/**
|
|
@@ -3025,7 +4945,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3025
4945
|
* Only authenticated agents with did:voidly: identities can join and read.
|
|
3026
4946
|
*/
|
|
3027
4947
|
async createChannel(options) {
|
|
3028
|
-
const res = await
|
|
4948
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels`, {
|
|
3029
4949
|
method: "POST",
|
|
3030
4950
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3031
4951
|
body: JSON.stringify(options)
|
|
@@ -3045,7 +4965,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3045
4965
|
if (options.query) params.set("q", options.query);
|
|
3046
4966
|
if (options.mine) params.set("mine", "true");
|
|
3047
4967
|
if (options.limit) params.set("limit", String(options.limit));
|
|
3048
|
-
const res = await
|
|
4968
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels?${params}`, {
|
|
3049
4969
|
headers: options.mine ? { "X-Agent-Key": this.apiKey } : {}
|
|
3050
4970
|
});
|
|
3051
4971
|
if (!res.ok) return [];
|
|
@@ -3056,7 +4976,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3056
4976
|
* Join an encrypted channel.
|
|
3057
4977
|
*/
|
|
3058
4978
|
async joinChannel(channelId) {
|
|
3059
|
-
const res = await
|
|
4979
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/join`, {
|
|
3060
4980
|
method: "POST",
|
|
3061
4981
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3062
4982
|
});
|
|
@@ -3070,7 +4990,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3070
4990
|
* Leave a channel.
|
|
3071
4991
|
*/
|
|
3072
4992
|
async leaveChannel(channelId) {
|
|
3073
|
-
const res = await
|
|
4993
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/leave`, {
|
|
3074
4994
|
method: "POST",
|
|
3075
4995
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3076
4996
|
});
|
|
@@ -3083,7 +5003,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3083
5003
|
* Post an encrypted message to a channel.
|
|
3084
5004
|
*/
|
|
3085
5005
|
async postToChannel(channelId, message, replyTo) {
|
|
3086
|
-
const res = await
|
|
5006
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages`, {
|
|
3087
5007
|
method: "POST",
|
|
3088
5008
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3089
5009
|
body: JSON.stringify({ message, reply_to: replyTo })
|
|
@@ -3102,7 +5022,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3102
5022
|
if (options.since) params.set("since", options.since);
|
|
3103
5023
|
if (options.before) params.set("before", options.before);
|
|
3104
5024
|
if (options.limit) params.set("limit", String(options.limit));
|
|
3105
|
-
const res = await
|
|
5025
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages?${params}`, {
|
|
3106
5026
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3107
5027
|
});
|
|
3108
5028
|
if (!res.ok) {
|
|
@@ -3116,7 +5036,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3116
5036
|
* This is a soft delete — messages expire per TTL. Re-register for a new identity.
|
|
3117
5037
|
*/
|
|
3118
5038
|
async deactivate() {
|
|
3119
|
-
const res = await
|
|
5039
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/deactivate`, {
|
|
3120
5040
|
method: "DELETE",
|
|
3121
5041
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3122
5042
|
});
|
|
@@ -3139,7 +5059,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3139
5059
|
* ```
|
|
3140
5060
|
*/
|
|
3141
5061
|
async registerCapability(options) {
|
|
3142
|
-
const res = await
|
|
5062
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities`, {
|
|
3143
5063
|
method: "POST",
|
|
3144
5064
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3145
5065
|
body: JSON.stringify({
|
|
@@ -3160,7 +5080,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3160
5080
|
* List this agent's registered capabilities.
|
|
3161
5081
|
*/
|
|
3162
5082
|
async listCapabilities() {
|
|
3163
|
-
const res = await
|
|
5083
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities`, {
|
|
3164
5084
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3165
5085
|
});
|
|
3166
5086
|
if (!res.ok) return [];
|
|
@@ -3182,7 +5102,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3182
5102
|
if (options.query) params.set("q", options.query);
|
|
3183
5103
|
if (options.name) params.set("name", options.name);
|
|
3184
5104
|
if (options.limit) params.set("limit", String(options.limit));
|
|
3185
|
-
const res = await
|
|
5105
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities/search?${params}`);
|
|
3186
5106
|
if (!res.ok) return [];
|
|
3187
5107
|
const data = await res.json();
|
|
3188
5108
|
return data.results;
|
|
@@ -3191,7 +5111,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3191
5111
|
* Remove a capability.
|
|
3192
5112
|
*/
|
|
3193
5113
|
async deleteCapability(capabilityId) {
|
|
3194
|
-
const res = await
|
|
5114
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities/${capabilityId}`, {
|
|
3195
5115
|
method: "DELETE",
|
|
3196
5116
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3197
5117
|
});
|
|
@@ -3216,14 +5136,14 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3216
5136
|
* ```
|
|
3217
5137
|
*/
|
|
3218
5138
|
async createTask(options) {
|
|
3219
|
-
const identityRes = await
|
|
5139
|
+
const identityRes = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${options.to}`);
|
|
3220
5140
|
if (!identityRes.ok) throw new Error("Recipient agent not found");
|
|
3221
5141
|
const identity = await identityRes.json();
|
|
3222
5142
|
const recipientPubKey = (0, import_tweetnacl_util.decodeBase64)(identity.encryption_public_key);
|
|
3223
5143
|
const plaintext = (0, import_tweetnacl_util.decodeUTF8)(JSON.stringify(options.input));
|
|
3224
5144
|
const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
|
|
3225
5145
|
const encrypted = import_tweetnacl.default.box(plaintext, nonce, recipientPubKey, this.encryptionKeyPair.secretKey);
|
|
3226
|
-
const res = await
|
|
5146
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks`, {
|
|
3227
5147
|
method: "POST",
|
|
3228
5148
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3229
5149
|
body: JSON.stringify({
|
|
@@ -3250,7 +5170,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3250
5170
|
if (options.status) params.set("status", options.status);
|
|
3251
5171
|
if (options.capability) params.set("capability", options.capability);
|
|
3252
5172
|
if (options.limit) params.set("limit", String(options.limit));
|
|
3253
|
-
const res = await
|
|
5173
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks?${params}`, {
|
|
3254
5174
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3255
5175
|
});
|
|
3256
5176
|
if (!res.ok) return [];
|
|
@@ -3261,7 +5181,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3261
5181
|
* Get task detail. Includes encrypted input/output (only visible to participants).
|
|
3262
5182
|
*/
|
|
3263
5183
|
async getTask(taskId) {
|
|
3264
|
-
const res = await
|
|
5184
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
|
|
3265
5185
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3266
5186
|
});
|
|
3267
5187
|
if (!res.ok) {
|
|
@@ -3293,7 +5213,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3293
5213
|
if (update.output && (update.status === "completed" || update.status === "failed")) {
|
|
3294
5214
|
const task = await this.getTask(taskId);
|
|
3295
5215
|
const requesterDid = task.from;
|
|
3296
|
-
const identityRes = await
|
|
5216
|
+
const identityRes = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${requesterDid}`);
|
|
3297
5217
|
if (identityRes.ok) {
|
|
3298
5218
|
const identity = await identityRes.json();
|
|
3299
5219
|
const requesterPubKey = (0, import_tweetnacl_util.decodeBase64)(identity.encryption_public_key);
|
|
@@ -3306,7 +5226,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3306
5226
|
body.output_signature = (0, import_tweetnacl_util.encodeBase64)(signature);
|
|
3307
5227
|
}
|
|
3308
5228
|
}
|
|
3309
|
-
const res = await
|
|
5229
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
|
|
3310
5230
|
method: "PATCH",
|
|
3311
5231
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3312
5232
|
body: JSON.stringify(body)
|
|
@@ -3373,7 +5293,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3373
5293
|
const payload = options.claimType + JSON.stringify(options.claimData) + timestamp;
|
|
3374
5294
|
const payloadBytes = (0, import_tweetnacl_util.decodeUTF8)(payload);
|
|
3375
5295
|
const signature = import_tweetnacl.default.sign.detached(payloadBytes, this.signingKeyPair.secretKey);
|
|
3376
|
-
const res = await
|
|
5296
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations`, {
|
|
3377
5297
|
method: "POST",
|
|
3378
5298
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3379
5299
|
body: JSON.stringify({
|
|
@@ -3410,7 +5330,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3410
5330
|
const payload = attestationId + vote;
|
|
3411
5331
|
const payloadBytes = (0, import_tweetnacl_util.decodeUTF8)(payload);
|
|
3412
5332
|
const signature = import_tweetnacl.default.sign.detached(payloadBytes, this.signingKeyPair.secretKey);
|
|
3413
|
-
const res = await
|
|
5333
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}/corroborate`, {
|
|
3414
5334
|
method: "POST",
|
|
3415
5335
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3416
5336
|
body: JSON.stringify({ vote, signature: (0, import_tweetnacl_util.encodeBase64)(signature), comment })
|
|
@@ -3433,7 +5353,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3433
5353
|
if (options.minConsensus !== void 0) params.set("min_consensus", String(options.minConsensus));
|
|
3434
5354
|
if (options.since) params.set("since", options.since);
|
|
3435
5355
|
if (options.limit) params.set("limit", String(options.limit));
|
|
3436
|
-
const res = await
|
|
5356
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations?${params}`);
|
|
3437
5357
|
if (!res.ok) return [];
|
|
3438
5358
|
const data = await res.json();
|
|
3439
5359
|
return data.attestations;
|
|
@@ -3442,7 +5362,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3442
5362
|
* Get attestation detail including all corroborations.
|
|
3443
5363
|
*/
|
|
3444
5364
|
async getAttestation(attestationId) {
|
|
3445
|
-
const res = await
|
|
5365
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}`);
|
|
3446
5366
|
if (!res.ok) {
|
|
3447
5367
|
const err = await res.json().catch(() => ({}));
|
|
3448
5368
|
throw new Error(`Get attestation failed: ${err.error || res.statusText}`);
|
|
@@ -3457,7 +5377,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3457
5377
|
if (options.country) params.set("country", options.country);
|
|
3458
5378
|
if (options.domain) params.set("domain", options.domain);
|
|
3459
5379
|
if (options.type) params.set("type", options.type);
|
|
3460
|
-
const res = await
|
|
5380
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/consensus?${params}`);
|
|
3461
5381
|
if (!res.ok) return [];
|
|
3462
5382
|
const data = await res.json();
|
|
3463
5383
|
return data.consensus;
|
|
@@ -3470,7 +5390,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3470
5390
|
* Only channel members can invite.
|
|
3471
5391
|
*/
|
|
3472
5392
|
async inviteToChannel(channelId, inviteeDid, options) {
|
|
3473
|
-
const res = await
|
|
5393
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/invite`, {
|
|
3474
5394
|
method: "POST",
|
|
3475
5395
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3476
5396
|
body: JSON.stringify({
|
|
@@ -3489,7 +5409,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3489
5409
|
* List pending channel invites for this agent.
|
|
3490
5410
|
*/
|
|
3491
5411
|
async listInvites(status = "pending") {
|
|
3492
|
-
const res = await
|
|
5412
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/invites?status=${status}`, {
|
|
3493
5413
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3494
5414
|
});
|
|
3495
5415
|
if (!res.ok) return [];
|
|
@@ -3500,7 +5420,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3500
5420
|
* Accept or decline a channel invite.
|
|
3501
5421
|
*/
|
|
3502
5422
|
async respondToInvite(inviteId, action) {
|
|
3503
|
-
const res = await
|
|
5423
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/invites/${inviteId}/respond`, {
|
|
3504
5424
|
method: "POST",
|
|
3505
5425
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3506
5426
|
body: JSON.stringify({ action })
|
|
@@ -3518,7 +5438,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3518
5438
|
* Get an agent's trust score and reputation breakdown.
|
|
3519
5439
|
*/
|
|
3520
5440
|
async getTrustScore(did) {
|
|
3521
|
-
const res = await
|
|
5441
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/trust/${did}`);
|
|
3522
5442
|
if (!res.ok) {
|
|
3523
5443
|
const err = await res.json().catch(() => ({}));
|
|
3524
5444
|
throw new Error(`Trust score failed: ${err.error || res.statusText}`);
|
|
@@ -3532,7 +5452,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3532
5452
|
const params = new URLSearchParams();
|
|
3533
5453
|
if (options?.limit) params.set("limit", options.limit.toString());
|
|
3534
5454
|
if (options?.minLevel) params.set("min_level", options.minLevel);
|
|
3535
|
-
const res = await
|
|
5455
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/trust/leaderboard?${params}`);
|
|
3536
5456
|
if (!res.ok) return [];
|
|
3537
5457
|
const data = await res.json();
|
|
3538
5458
|
return data.leaderboard;
|
|
@@ -3544,7 +5464,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3544
5464
|
* Mark a message as read.
|
|
3545
5465
|
*/
|
|
3546
5466
|
async markRead(messageId) {
|
|
3547
|
-
const res = await
|
|
5467
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/${messageId}/read`, {
|
|
3548
5468
|
method: "POST",
|
|
3549
5469
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3550
5470
|
});
|
|
@@ -3555,7 +5475,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3555
5475
|
* Mark multiple messages as read in one call.
|
|
3556
5476
|
*/
|
|
3557
5477
|
async markReadBatch(messageIds) {
|
|
3558
|
-
const res = await
|
|
5478
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/read-batch`, {
|
|
3559
5479
|
method: "POST",
|
|
3560
5480
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3561
5481
|
body: JSON.stringify({ message_ids: messageIds })
|
|
@@ -3569,7 +5489,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3569
5489
|
async getUnreadCount(fromDid) {
|
|
3570
5490
|
const params = new URLSearchParams();
|
|
3571
5491
|
if (fromDid) params.set("from", fromDid);
|
|
3572
|
-
const res = await
|
|
5492
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/unread-count?${params}`, {
|
|
3573
5493
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3574
5494
|
});
|
|
3575
5495
|
if (!res.ok) throw new Error(`Failed to get unread count: ${res.status}`);
|
|
@@ -3590,7 +5510,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3590
5510
|
this.encryptionKeyPair.secretKey
|
|
3591
5511
|
));
|
|
3592
5512
|
const broadcastSig = import_tweetnacl.default.sign.detached(inputBytes, this.signingKeyPair.secretKey);
|
|
3593
|
-
const res = await
|
|
5513
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcast`, {
|
|
3594
5514
|
method: "POST",
|
|
3595
5515
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3596
5516
|
body: JSON.stringify({
|
|
@@ -3616,7 +5536,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3616
5536
|
async listBroadcasts(status) {
|
|
3617
5537
|
const params = new URLSearchParams();
|
|
3618
5538
|
if (status) params.set("status", status);
|
|
3619
|
-
const res = await
|
|
5539
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcasts?${params}`, {
|
|
3620
5540
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3621
5541
|
});
|
|
3622
5542
|
if (!res.ok) return [];
|
|
@@ -3627,7 +5547,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3627
5547
|
* Get broadcast detail with individual task statuses.
|
|
3628
5548
|
*/
|
|
3629
5549
|
async getBroadcast(broadcastId) {
|
|
3630
|
-
const res = await
|
|
5550
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcasts/${broadcastId}`, {
|
|
3631
5551
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3632
5552
|
});
|
|
3633
5553
|
if (!res.ok) throw new Error(`Failed to get broadcast: ${res.status}`);
|
|
@@ -3643,7 +5563,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3643
5563
|
async getAnalytics(period) {
|
|
3644
5564
|
const params = new URLSearchParams();
|
|
3645
5565
|
if (period) params.set("period", period);
|
|
3646
|
-
const res = await
|
|
5566
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/analytics?${params}`, {
|
|
3647
5567
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
|
|
3648
5568
|
});
|
|
3649
5569
|
if (!res.ok) throw new Error(`Failed to get analytics: ${res.status}`);
|
|
@@ -3683,7 +5603,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3683
5603
|
memKey = new Uint8Array(createHash("sha256").update(Buffer.from(memKeyInput)).digest());
|
|
3684
5604
|
}
|
|
3685
5605
|
const encryptedValue = import_tweetnacl.default.secretbox(valueBytes, memNonce, memKey);
|
|
3686
|
-
const res = await
|
|
5606
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3687
5607
|
method: "PUT",
|
|
3688
5608
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3689
5609
|
body: JSON.stringify({
|
|
@@ -3701,7 +5621,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3701
5621
|
* Decrypted CLIENT-SIDE — relay never sees plaintext.
|
|
3702
5622
|
*/
|
|
3703
5623
|
async memoryGet(namespace, key) {
|
|
3704
|
-
const res = await
|
|
5624
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3705
5625
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3706
5626
|
});
|
|
3707
5627
|
if (res.status === 404) return null;
|
|
@@ -3733,7 +5653,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3733
5653
|
* Delete a key from persistent memory.
|
|
3734
5654
|
*/
|
|
3735
5655
|
async memoryDelete(namespace, key) {
|
|
3736
|
-
const res = await
|
|
5656
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
|
|
3737
5657
|
method: "DELETE",
|
|
3738
5658
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3739
5659
|
});
|
|
@@ -3749,7 +5669,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3749
5669
|
if (options?.prefix) params.set("prefix", options.prefix);
|
|
3750
5670
|
if (options?.limit) params.set("limit", String(options.limit));
|
|
3751
5671
|
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3752
|
-
const res = await
|
|
5672
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(ns)}${qs}`, {
|
|
3753
5673
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3754
5674
|
});
|
|
3755
5675
|
if (!res.ok) throw new Error(`Memory list failed: ${res.status} ${await res.text()}`);
|
|
@@ -3759,7 +5679,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3759
5679
|
* List all memory namespaces and quota usage.
|
|
3760
5680
|
*/
|
|
3761
5681
|
async memoryNamespaces() {
|
|
3762
|
-
const res = await
|
|
5682
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory`, {
|
|
3763
5683
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3764
5684
|
});
|
|
3765
5685
|
if (!res.ok) throw new Error(`Memory namespaces failed: ${res.status} ${await res.text()}`);
|
|
@@ -3772,7 +5692,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3772
5692
|
* Memory values remain encrypted — portable to another relay.
|
|
3773
5693
|
*/
|
|
3774
5694
|
async exportData(options) {
|
|
3775
|
-
const res = await
|
|
5695
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/export`, {
|
|
3776
5696
|
method: "POST",
|
|
3777
5697
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3778
5698
|
body: JSON.stringify({
|
|
@@ -3791,7 +5711,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3791
5711
|
* List past data export records.
|
|
3792
5712
|
*/
|
|
3793
5713
|
async listExports() {
|
|
3794
|
-
const res = await
|
|
5714
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/exports`, {
|
|
3795
5715
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3796
5716
|
});
|
|
3797
5717
|
if (!res.ok) throw new Error(`List exports failed: ${res.status} ${await res.text()}`);
|
|
@@ -3803,7 +5723,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3803
5723
|
* Includes federation capabilities and known peers.
|
|
3804
5724
|
*/
|
|
3805
5725
|
async getRelayInfo() {
|
|
3806
|
-
const res = await
|
|
5726
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/relay/info`);
|
|
3807
5727
|
if (!res.ok) throw new Error(`Relay info failed: ${res.status} ${await res.text()}`);
|
|
3808
5728
|
return res.json();
|
|
3809
5729
|
}
|
|
@@ -3811,7 +5731,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3811
5731
|
* List known federated relay peers.
|
|
3812
5732
|
*/
|
|
3813
5733
|
async getRelayPeers() {
|
|
3814
|
-
const res = await
|
|
5734
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/relay/peers`);
|
|
3815
5735
|
if (!res.ok) throw new Error(`Relay peers failed: ${res.status} ${await res.text()}`);
|
|
3816
5736
|
return res.json();
|
|
3817
5737
|
}
|
|
@@ -3833,7 +5753,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3833
5753
|
ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(encrypted))
|
|
3834
5754
|
}));
|
|
3835
5755
|
const signature = import_tweetnacl.default.sign.detached(signaturePayload, this.signingKeyPair.secretKey);
|
|
3836
|
-
const res = await
|
|
5756
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/relay/route`, {
|
|
3837
5757
|
method: "POST",
|
|
3838
5758
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3839
5759
|
body: JSON.stringify({
|
|
@@ -3851,7 +5771,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3851
5771
|
// ── Heartbeat ──────────────────────────────────────────────────────────────
|
|
3852
5772
|
/** Send heartbeat — signals agent is alive, updates last_seen */
|
|
3853
5773
|
async ping() {
|
|
3854
|
-
const res = await
|
|
5774
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/ping`, {
|
|
3855
5775
|
method: "POST",
|
|
3856
5776
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3857
5777
|
});
|
|
@@ -3860,14 +5780,14 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3860
5780
|
}
|
|
3861
5781
|
/** Check if another agent is online (public) */
|
|
3862
5782
|
async checkOnline(did) {
|
|
3863
|
-
const res = await
|
|
5783
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/ping/${encodeURIComponent(did)}`);
|
|
3864
5784
|
if (!res.ok) throw new Error(`Ping check failed: ${res.status}`);
|
|
3865
5785
|
return res.json();
|
|
3866
5786
|
}
|
|
3867
5787
|
// ── Key Pinning (TOFU) ────────────────────────────────────────────────────
|
|
3868
5788
|
/** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
|
|
3869
5789
|
async pinKeys(did) {
|
|
3870
|
-
const res = await
|
|
5790
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/pin`, {
|
|
3871
5791
|
method: "POST",
|
|
3872
5792
|
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
3873
5793
|
body: JSON.stringify({ did })
|
|
@@ -3880,7 +5800,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3880
5800
|
const params = new URLSearchParams();
|
|
3881
5801
|
if (options?.status) params.set("status", options.status);
|
|
3882
5802
|
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
3883
|
-
const res = await
|
|
5803
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/pins${qs}`, {
|
|
3884
5804
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3885
5805
|
});
|
|
3886
5806
|
if (!res.ok) throw new Error(`List pins failed: ${res.status}`);
|
|
@@ -3888,13 +5808,165 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3888
5808
|
}
|
|
3889
5809
|
/** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
|
|
3890
5810
|
async verifyKeys(did) {
|
|
3891
|
-
const res = await
|
|
5811
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/verify/${encodeURIComponent(did)}`, {
|
|
3892
5812
|
headers: { "X-Agent-Key": this.apiKey }
|
|
3893
5813
|
});
|
|
3894
5814
|
if (!res.ok) throw new Error(`Key verify failed: ${res.status}`);
|
|
3895
5815
|
return res.json();
|
|
3896
5816
|
}
|
|
3897
5817
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
5818
|
+
// X3DH — Async Key Agreement (prekey bundles for offline agents)
|
|
5819
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
5820
|
+
/**
|
|
5821
|
+
* Upload prekey bundle for X3DH async key agreement.
|
|
5822
|
+
* Other agents can fetch your prekeys and establish encrypted sessions
|
|
5823
|
+
* even while you're offline.
|
|
5824
|
+
*
|
|
5825
|
+
* @param count Number of one-time prekeys to upload (default: 20)
|
|
5826
|
+
*/
|
|
5827
|
+
async uploadPrekeys(count = 20) {
|
|
5828
|
+
const prekeys = [];
|
|
5829
|
+
for (let i = 0; i < count; i++) {
|
|
5830
|
+
const kp = import_tweetnacl.default.box.keyPair();
|
|
5831
|
+
prekeys.push({
|
|
5832
|
+
id: Date.now() + i,
|
|
5833
|
+
public_key: (0, import_tweetnacl_util.encodeBase64)(kp.publicKey),
|
|
5834
|
+
secretKey: kp.secretKey
|
|
5835
|
+
});
|
|
5836
|
+
}
|
|
5837
|
+
const newPrekey = import_tweetnacl.default.box.keyPair();
|
|
5838
|
+
this._signedPrekeyId++;
|
|
5839
|
+
const prekeySignature = import_tweetnacl.default.sign.detached(newPrekey.publicKey, this.signingKeyPair.secretKey);
|
|
5840
|
+
this._signedPrekey = newPrekey;
|
|
5841
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/prekeys`, {
|
|
5842
|
+
method: "POST",
|
|
5843
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
5844
|
+
body: JSON.stringify({
|
|
5845
|
+
prekeys: prekeys.map((pk) => ({ id: pk.id, public_key: pk.public_key })),
|
|
5846
|
+
signed_prekey: {
|
|
5847
|
+
public_key: (0, import_tweetnacl_util.encodeBase64)(newPrekey.publicKey),
|
|
5848
|
+
signature: (0, import_tweetnacl_util.encodeBase64)(prekeySignature),
|
|
5849
|
+
id: this._signedPrekeyId
|
|
5850
|
+
}
|
|
5851
|
+
})
|
|
5852
|
+
});
|
|
5853
|
+
if (!res.ok) throw new Error(`Prekey upload failed: ${res.status}`);
|
|
5854
|
+
return await res.json();
|
|
5855
|
+
}
|
|
5856
|
+
/**
|
|
5857
|
+
* Fetch another agent's prekey bundle for X3DH key agreement.
|
|
5858
|
+
* Use this to establish an encrypted session with an offline agent.
|
|
5859
|
+
*/
|
|
5860
|
+
async fetchPrekeys(did) {
|
|
5861
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/prekeys/${encodeURIComponent(did)}`);
|
|
5862
|
+
if (!res.ok) return null;
|
|
5863
|
+
return await res.json();
|
|
5864
|
+
}
|
|
5865
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
5866
|
+
// CLIENT-SIDE CHANNEL ENCRYPTION
|
|
5867
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
5868
|
+
/**
|
|
5869
|
+
* Create a channel with client-side encryption.
|
|
5870
|
+
* The channel symmetric key is generated locally and encrypted per-member.
|
|
5871
|
+
* The relay NEVER sees the plaintext channel key — true E2E for groups.
|
|
5872
|
+
*/
|
|
5873
|
+
async createEncryptedChannel(options) {
|
|
5874
|
+
const channelKey = import_tweetnacl.default.randomBytes(32);
|
|
5875
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels`, {
|
|
5876
|
+
method: "POST",
|
|
5877
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
5878
|
+
body: JSON.stringify(options)
|
|
5879
|
+
});
|
|
5880
|
+
if (!res.ok) {
|
|
5881
|
+
const err = await res.json().catch(() => ({}));
|
|
5882
|
+
throw new Error(`Channel creation failed: ${err.error || res.statusText}`);
|
|
5883
|
+
}
|
|
5884
|
+
const channel = await res.json();
|
|
5885
|
+
const selfNonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
|
|
5886
|
+
const selfEncrypted = import_tweetnacl.default.box(channelKey, selfNonce, this.encryptionKeyPair.publicKey, this.encryptionKeyPair.secretKey);
|
|
5887
|
+
await this.memorySet("channel-keys", channel.id, {
|
|
5888
|
+
key: (0, import_tweetnacl_util.encodeBase64)(channelKey),
|
|
5889
|
+
nonce: (0, import_tweetnacl_util.encodeBase64)(selfNonce)
|
|
5890
|
+
});
|
|
5891
|
+
return { ...channel, channelKey };
|
|
5892
|
+
}
|
|
5893
|
+
/**
|
|
5894
|
+
* Post a client-side encrypted message to a channel.
|
|
5895
|
+
* Uses the channel's shared symmetric key — relay never sees plaintext.
|
|
5896
|
+
*
|
|
5897
|
+
* @param channelId Channel ID
|
|
5898
|
+
* @param message Plaintext message
|
|
5899
|
+
* @param channelKey 32-byte symmetric channel key (from createEncryptedChannel or received via invite)
|
|
5900
|
+
*/
|
|
5901
|
+
async postEncrypted(channelId, message, channelKey) {
|
|
5902
|
+
const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.secretbox.nonceLength);
|
|
5903
|
+
const ciphertext = import_tweetnacl.default.secretbox((0, import_tweetnacl_util.decodeUTF8)(message), nonce, channelKey);
|
|
5904
|
+
const sigPayload = new Uint8Array([...ciphertext, ...nonce]);
|
|
5905
|
+
const signature = import_tweetnacl.default.sign.detached(sigPayload, this.signingKeyPair.secretKey);
|
|
5906
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages`, {
|
|
5907
|
+
method: "POST",
|
|
5908
|
+
headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
|
|
5909
|
+
body: JSON.stringify({
|
|
5910
|
+
message: JSON.stringify({
|
|
5911
|
+
v: 3,
|
|
5912
|
+
ct: (0, import_tweetnacl_util.encodeBase64)(ciphertext),
|
|
5913
|
+
n: (0, import_tweetnacl_util.encodeBase64)(nonce),
|
|
5914
|
+
sig: (0, import_tweetnacl_util.encodeBase64)(signature),
|
|
5915
|
+
from: this.did
|
|
5916
|
+
})
|
|
5917
|
+
})
|
|
5918
|
+
});
|
|
5919
|
+
if (!res.ok) throw new Error(`Post failed: ${res.status}`);
|
|
5920
|
+
return await res.json();
|
|
5921
|
+
}
|
|
5922
|
+
/**
|
|
5923
|
+
* Read and decrypt channel messages using client-side channel key.
|
|
5924
|
+
* Ignores server-side encryption entirely — true E2E.
|
|
5925
|
+
*
|
|
5926
|
+
* @param channelId Channel ID
|
|
5927
|
+
* @param channelKey 32-byte symmetric channel key
|
|
5928
|
+
*/
|
|
5929
|
+
async readEncrypted(channelId, channelKey, options) {
|
|
5930
|
+
const raw = await this.readChannel(channelId, options);
|
|
5931
|
+
const decrypted = [];
|
|
5932
|
+
for (const msg of raw.messages) {
|
|
5933
|
+
try {
|
|
5934
|
+
const parsed = JSON.parse(typeof msg.content === "string" ? msg.content : msg.message || "");
|
|
5935
|
+
if (parsed.v === 3 && parsed.ct && parsed.n) {
|
|
5936
|
+
const ct = (0, import_tweetnacl_util.decodeBase64)(parsed.ct);
|
|
5937
|
+
const nonce = (0, import_tweetnacl_util.decodeBase64)(parsed.n);
|
|
5938
|
+
const plain = import_tweetnacl.default.secretbox.open(ct, nonce, channelKey);
|
|
5939
|
+
if (plain) {
|
|
5940
|
+
let sigValid = false;
|
|
5941
|
+
if (parsed.sig && parsed.from) {
|
|
5942
|
+
try {
|
|
5943
|
+
const profile = await this.getIdentity(parsed.from);
|
|
5944
|
+
if (profile) {
|
|
5945
|
+
const sigPayload = new Uint8Array([...ct, ...nonce]);
|
|
5946
|
+
sigValid = import_tweetnacl.default.sign.detached.verify(
|
|
5947
|
+
sigPayload,
|
|
5948
|
+
(0, import_tweetnacl_util.decodeBase64)(parsed.sig),
|
|
5949
|
+
(0, import_tweetnacl_util.decodeBase64)(profile.signing_public_key)
|
|
5950
|
+
);
|
|
5951
|
+
}
|
|
5952
|
+
} catch {
|
|
5953
|
+
}
|
|
5954
|
+
}
|
|
5955
|
+
decrypted.push({
|
|
5956
|
+
id: msg.id,
|
|
5957
|
+
from: parsed.from || msg.author || "unknown",
|
|
5958
|
+
content: (0, import_tweetnacl_util.encodeUTF8)(plain),
|
|
5959
|
+
timestamp: msg.created_at || msg.timestamp,
|
|
5960
|
+
signatureValid: sigValid
|
|
5961
|
+
});
|
|
5962
|
+
}
|
|
5963
|
+
}
|
|
5964
|
+
} catch {
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5967
|
+
return { messages: decrypted, count: decrypted.length };
|
|
5968
|
+
}
|
|
5969
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
3898
5970
|
// LISTEN — Event-Driven Message Receiving
|
|
3899
5971
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
3900
5972
|
/**
|
|
@@ -3961,20 +6033,54 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3961
6033
|
this.ping().catch(() => {
|
|
3962
6034
|
});
|
|
3963
6035
|
}
|
|
6036
|
+
const useLongPoll = this.longPoll;
|
|
3964
6037
|
const poll = async () => {
|
|
3965
6038
|
if (!active || options.signal?.aborted) {
|
|
3966
6039
|
handle.stop();
|
|
3967
6040
|
return;
|
|
3968
6041
|
}
|
|
3969
6042
|
try {
|
|
3970
|
-
|
|
3971
|
-
|
|
3972
|
-
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
6043
|
+
let messages;
|
|
6044
|
+
if (useLongPoll) {
|
|
6045
|
+
const params = new URLSearchParams({ timeout: "25" });
|
|
6046
|
+
if (lastSeen) params.set("since", lastSeen);
|
|
6047
|
+
if (options.from) params.set("from", options.from);
|
|
6048
|
+
const res = await this._timedFetch(`${this.baseUrl}/v1/agent/receive/poll?${params}`, {
|
|
6049
|
+
headers: { "X-Agent-Key": this.apiKey }
|
|
6050
|
+
});
|
|
6051
|
+
if (res.ok) {
|
|
6052
|
+
const data = await res.json();
|
|
6053
|
+
messages = [];
|
|
6054
|
+
for (const raw of data.messages) {
|
|
6055
|
+
try {
|
|
6056
|
+
if (this._seenMessageIds.has(raw.id)) continue;
|
|
6057
|
+
this._seenMessageIds.add(raw.id);
|
|
6058
|
+
} catch {
|
|
6059
|
+
}
|
|
6060
|
+
}
|
|
6061
|
+
if (data.messages.length > 0) {
|
|
6062
|
+
messages = await this.receive({
|
|
6063
|
+
since: lastSeen,
|
|
6064
|
+
from: options.from,
|
|
6065
|
+
threadId: options.threadId,
|
|
6066
|
+
messageType: options.messageType,
|
|
6067
|
+
unreadOnly,
|
|
6068
|
+
limit: 50
|
|
6069
|
+
});
|
|
6070
|
+
}
|
|
6071
|
+
} else {
|
|
6072
|
+
messages = [];
|
|
6073
|
+
}
|
|
6074
|
+
} else {
|
|
6075
|
+
messages = await this.receive({
|
|
6076
|
+
since: lastSeen,
|
|
6077
|
+
from: options.from,
|
|
6078
|
+
threadId: options.threadId,
|
|
6079
|
+
messageType: options.messageType,
|
|
6080
|
+
unreadOnly,
|
|
6081
|
+
limit: 50
|
|
6082
|
+
});
|
|
6083
|
+
}
|
|
3978
6084
|
if (messages.length > 0) {
|
|
3979
6085
|
consecutiveEmpty = 0;
|
|
3980
6086
|
if (adaptive) currentInterval = Math.max(interval / 2, 500);
|
|
@@ -3992,7 +6098,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
3992
6098
|
lastSeen = messages[messages.length - 1].timestamp;
|
|
3993
6099
|
} else {
|
|
3994
6100
|
consecutiveEmpty++;
|
|
3995
|
-
if (adaptive && consecutiveEmpty > 3) {
|
|
6101
|
+
if (adaptive && consecutiveEmpty > 3 && !useLongPoll) {
|
|
3996
6102
|
currentInterval = Math.min(currentInterval * 1.5, interval * 4);
|
|
3997
6103
|
}
|
|
3998
6104
|
}
|
|
@@ -4001,7 +6107,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4001
6107
|
currentInterval = Math.min(currentInterval * 2, interval * 8);
|
|
4002
6108
|
}
|
|
4003
6109
|
if (active && !options.signal?.aborted) {
|
|
4004
|
-
timer = setTimeout(poll, currentInterval);
|
|
6110
|
+
timer = setTimeout(poll, useLongPoll ? 100 : currentInterval);
|
|
4005
6111
|
}
|
|
4006
6112
|
};
|
|
4007
6113
|
poll();
|
|
@@ -4099,6 +6205,21 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4099
6205
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
4100
6206
|
// INTERNAL — Retry, Auto-Pin
|
|
4101
6207
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
6208
|
+
/** @internal Fetch with timeout via AbortController */
|
|
6209
|
+
async _timedFetch(url, init) {
|
|
6210
|
+
const controller = new AbortController();
|
|
6211
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
6212
|
+
try {
|
|
6213
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
6214
|
+
} catch (err) {
|
|
6215
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
6216
|
+
throw new Error(`Request timed out after ${this.timeout}ms: ${url.replace(this.baseUrl, "")}`);
|
|
6217
|
+
}
|
|
6218
|
+
throw err;
|
|
6219
|
+
} finally {
|
|
6220
|
+
clearTimeout(timer);
|
|
6221
|
+
}
|
|
6222
|
+
}
|
|
4102
6223
|
/** @internal Auto-pin keys on first contact (TOFU) */
|
|
4103
6224
|
async _autoPinKeys(did) {
|
|
4104
6225
|
if (this._pinnedDids.has(did)) return;
|
|
@@ -4119,7 +6240,7 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4119
6240
|
let lastError = null;
|
|
4120
6241
|
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
4121
6242
|
try {
|
|
4122
|
-
const res = await
|
|
6243
|
+
const res = await this._timedFetch(url, init);
|
|
4123
6244
|
if (res.ok) {
|
|
4124
6245
|
return await res.json();
|
|
4125
6246
|
}
|
|
@@ -4186,50 +6307,56 @@ var VoidlyAgent = class _VoidlyAgent {
|
|
|
4186
6307
|
return {
|
|
4187
6308
|
relayCanSee: [
|
|
4188
6309
|
"Your DID (public identifier)",
|
|
4189
|
-
"Who you message (recipient DIDs)",
|
|
4190
|
-
"When you message (timestamps)",
|
|
6310
|
+
...this.sealedSender ? [] : ["Who you message (recipient DIDs)"],
|
|
6311
|
+
...this.jitterMs > 0 ? ["Approximate timing (jittered timestamps)"] : ["When you message (timestamps)"],
|
|
4191
6312
|
"Message types (text, task-request, etc.)",
|
|
4192
6313
|
"Thread structure (which messages are replies)",
|
|
4193
|
-
"Channel membership",
|
|
6314
|
+
"Channel membership (but NOT channel message content with client-side encryption)",
|
|
4194
6315
|
"Capability registrations",
|
|
4195
6316
|
"Online/offline status",
|
|
4196
6317
|
"Approximate message size (even with padding, bounded to power-of-2)"
|
|
4197
6318
|
],
|
|
4198
6319
|
relayCannotSee: [
|
|
4199
|
-
"Message content (E2E encrypted \u2014 nacl.
|
|
6320
|
+
"Message content (E2E encrypted \u2014 nacl.box with Double Ratchet per-message keys)",
|
|
4200
6321
|
"Private keys (generated and stored client-side only)",
|
|
4201
6322
|
"Memory values (encrypted CLIENT-SIDE with nacl.secretbox before relay storage)",
|
|
4202
|
-
"Past message keys (hash ratchet
|
|
4203
|
-
|
|
6323
|
+
"Past message keys (forward secrecy \u2014 hash ratchet + DH ratchet, old keys deleted)",
|
|
6324
|
+
"Future message keys (post-compromise recovery via DH ratchet \u2014 compromise heals after one round-trip)",
|
|
6325
|
+
"Channel message content (client-side nacl.secretbox encryption \u2014 relay stores only ciphertext)",
|
|
6326
|
+
...this.sealedSender ? ["Sender identity (sealed inside ciphertext)"] : [],
|
|
6327
|
+
...this.deniable ? ["Who authored a message (HMAC is symmetric \u2014 either party could have produced it)"] : []
|
|
4204
6328
|
],
|
|
4205
6329
|
protections: [
|
|
4206
|
-
"Hash ratchet forward secrecy \u2014 per-message key derivation, old keys deleted",
|
|
6330
|
+
...this.doubleRatchet ? ["Double Ratchet (Signal Protocol) \u2014 DH ratchet for post-compromise recovery + hash ratchet for forward secrecy"] : ["Hash ratchet forward secrecy \u2014 per-message key derivation, old keys deleted"],
|
|
6331
|
+
...this.postQuantum && this.mlkemPublicKey ? ["ML-KEM-768 + X25519 hybrid key exchange (NIST FIPS 203 post-quantum, harvest-now-decrypt-later resistant)"] : [],
|
|
6332
|
+
"X3DH async key agreement (signed prekeys + one-time prekeys for offline session establishment)",
|
|
4207
6333
|
"X25519 key exchange + XSalsa20-Poly1305 authenticated encryption",
|
|
4208
|
-
"Ed25519 signatures on every message (envelope + ciphertext hash)",
|
|
6334
|
+
...this.deniable ? ["Deniable authentication (HMAC-SHA256 with shared DH secret \u2014 both parties can produce the MAC)"] : ["Ed25519 signatures on every message (envelope + ciphertext hash)"],
|
|
4209
6335
|
"TOFU key pinning (MitM detection on key change)",
|
|
4210
6336
|
"Client-side memory encryption (relay never sees plaintext values)",
|
|
4211
|
-
"
|
|
6337
|
+
"Client-side channel encryption (nacl.secretbox \u2014 relay never sees channel plaintext)",
|
|
6338
|
+
"Protocol version header (deterministic padding/sealing/ratchet detection, no heuristics)",
|
|
4212
6339
|
"Identity cache (reduced key lookups, 5-min TTL)",
|
|
4213
6340
|
"Message deduplication (track seen message IDs)",
|
|
6341
|
+
"Request timeouts (AbortController on all HTTP, configurable)",
|
|
4214
6342
|
"Request validation (fromCredentials validates key sizes and format)",
|
|
4215
6343
|
...this.paddingEnabled ? ["Message padding to power-of-2 boundary (traffic analysis resistance)"] : [],
|
|
4216
6344
|
...this.sealedSender ? ["Sealed sender (relay cannot see who sent a message)"] : [],
|
|
4217
6345
|
...this.requireSignatures ? ["Strict signature enforcement (reject unsigned/invalid messages)"] : [],
|
|
4218
6346
|
...this.fallbackRelays.length > 0 ? [`Multi-relay fallback (${this.fallbackRelays.length} backup relays)`] : [],
|
|
6347
|
+
...this.jitterMs > 0 ? [`Timing jitter (random ${this.jitterMs}ms delay \u2014 metadata timing protection)`] : [],
|
|
6348
|
+
...this.longPoll ? ["Long-poll transport (25s server-held connection \u2014 near-real-time delivery)"] : [],
|
|
4219
6349
|
"Auto-retry with exponential backoff",
|
|
4220
6350
|
"Offline message queue",
|
|
4221
6351
|
"did:key interoperability (W3C standard DID format)"
|
|
4222
6352
|
],
|
|
4223
6353
|
gaps: [
|
|
4224
|
-
"No
|
|
4225
|
-
"
|
|
4226
|
-
"
|
|
4227
|
-
"
|
|
4228
|
-
"
|
|
4229
|
-
"
|
|
4230
|
-
"No async key agreement (no X3DH prekeys)",
|
|
4231
|
-
"Polling-based (no WebSocket real-time transport)",
|
|
4232
|
-
"Ratchet state is in-memory (lost on process restart \u2014 export credentials to persist)"
|
|
6354
|
+
...!this.postQuantum || !this.mlkemPublicKey ? ["No post-quantum protection \u2014 enable postQuantum option and re-register"] : [],
|
|
6355
|
+
"Single relay architecture (no onion routing, no mix network \u2014 mitigated by multi-relay fallback)",
|
|
6356
|
+
"Ratchet state is in-memory (lost on process restart \u2014 export credentials to persist)",
|
|
6357
|
+
...!this.deniable ? ["Ed25519 signatures are non-repudiable \u2014 enable deniable option for HMAC auth"] : [],
|
|
6358
|
+
...!this.doubleRatchet ? ["Hash ratchet only \u2014 enable doubleRatchet option for post-compromise recovery"] : [],
|
|
6359
|
+
...this.jitterMs === 0 ? ["No timing jitter \u2014 enable jitterMs option for metadata protection"] : []
|
|
4233
6360
|
]
|
|
4234
6361
|
};
|
|
4235
6362
|
}
|
|
@@ -4312,9 +6439,9 @@ var Conversation = class {
|
|
|
4312
6439
|
messageType: msg.messageType
|
|
4313
6440
|
});
|
|
4314
6441
|
this._lastMessageId = msg.id;
|
|
4315
|
-
for (const
|
|
6442
|
+
for (const h2 of this._replyHandlers) {
|
|
4316
6443
|
try {
|
|
4317
|
-
await
|
|
6444
|
+
await h2(msg);
|
|
4318
6445
|
} catch {
|
|
4319
6446
|
}
|
|
4320
6447
|
}
|
|
@@ -4424,3 +6551,8 @@ export {
|
|
|
4424
6551
|
export_encodeUTF8 as encodeUTF8,
|
|
4425
6552
|
export_nacl as nacl
|
|
4426
6553
|
};
|
|
6554
|
+
/*! Bundled license information:
|
|
6555
|
+
|
|
6556
|
+
mlkem/esm/src/sha3/utils.js:
|
|
6557
|
+
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
6558
|
+
*/
|