@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.js 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, h, l) {
53
- x[i] = h >> 24 & 255;
54
- x[i + 1] = h >> 16 & 255;
55
- x[i + 2] = h >> 8 & 255;
56
- x[i + 3] = h & 255;
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 g = new Uint16Array(10);
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
- g[0] = this.h[0] + 5;
658
- c = g[0] >>> 13;
659
- g[0] &= 8191;
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
- g[i] = this.h[i] + c;
662
- c = g[i] >>> 13;
663
- g[i] &= 8191;
661
+ g2[i] = this.h[i] + c;
662
+ c = g2[i] >>> 13;
663
+ g2[i] &= 8191;
664
664
  }
665
- g[9] -= 1 << 13;
665
+ g2[9] -= 1 << 13;
666
666
  mask = (c ^ 1) - 1;
667
- for (i = 0; i < 10; i++) g[i] &= mask;
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 | g[i];
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(h, hpos, m, mpos, n, k) {
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(h, hpos, x, 0);
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, h, l, a, b, c, d;
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
- h = ah7;
1517
+ h2 = ah7;
1518
1518
  l = al7;
1519
1519
  a = l & 65535;
1520
1520
  b = l >>> 16;
1521
- c = h & 65535;
1522
- d = h >>> 16;
1523
- h = (ah4 >>> 14 | al4 << 32 - 14) ^ (ah4 >>> 18 | al4 << 32 - 18) ^ (al4 >>> 41 - 32 | ah4 << 32 - (41 - 32));
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 += h & 65535;
1528
- d += h >>> 16;
1529
- h = ah4 & ah5 ^ ~ah4 & ah6;
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 += h & 65535;
1534
- d += h >>> 16;
1535
- h = K[i * 2];
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 += h & 65535;
1540
- d += h >>> 16;
1541
- h = wh[i % 16];
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 += h & 65535;
1546
- d += h >>> 16;
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
- h = th;
1552
+ h2 = th;
1553
1553
  l = tl;
1554
1554
  a = l & 65535;
1555
1555
  b = l >>> 16;
1556
- c = h & 65535;
1557
- d = h >>> 16;
1558
- h = (ah0 >>> 28 | al0 << 32 - 28) ^ (al0 >>> 34 - 32 | ah0 << 32 - (34 - 32)) ^ (al0 >>> 39 - 32 | ah0 << 32 - (39 - 32));
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 += h & 65535;
1563
- d += h >>> 16;
1564
- h = ah0 & ah1 ^ ah0 & ah2 ^ ah1 & ah2;
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 += h & 65535;
1569
- d += h >>> 16;
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
- h = bh3;
1575
+ h2 = bh3;
1576
1576
  l = bl3;
1577
1577
  a = l & 65535;
1578
1578
  b = l >>> 16;
1579
- c = h & 65535;
1580
- d = h >>> 16;
1581
- h = th;
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 += h & 65535;
1586
- d += h >>> 16;
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
- h = wh[j];
1610
+ h2 = wh[j];
1611
1611
  l = wl[j];
1612
1612
  a = l & 65535;
1613
1613
  b = l >>> 16;
1614
- c = h & 65535;
1615
- d = h >>> 16;
1616
- h = wh[(j + 9) % 16];
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 += h & 65535;
1621
- d += h >>> 16;
1620
+ c += h2 & 65535;
1621
+ d += h2 >>> 16;
1622
1622
  th = wh[(j + 1) % 16];
1623
1623
  tl = wl[(j + 1) % 16];
1624
- h = (th >>> 1 | tl << 32 - 1) ^ (th >>> 8 | tl << 32 - 8) ^ th >>> 7;
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 += h & 65535;
1629
- d += h >>> 16;
1628
+ c += h2 & 65535;
1629
+ d += h2 >>> 16;
1630
1630
  th = wh[(j + 14) % 16];
1631
1631
  tl = wl[(j + 14) % 16];
1632
- h = (th >>> 19 | tl << 32 - 19) ^ (tl >>> 61 - 32 | th << 32 - (61 - 32)) ^ th >>> 6;
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 += h & 65535;
1637
- d += h >>> 16;
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
- h = ah0;
1646
+ h2 = ah0;
1647
1647
  l = al0;
1648
1648
  a = l & 65535;
1649
1649
  b = l >>> 16;
1650
- c = h & 65535;
1651
- d = h >>> 16;
1652
- h = hh[0];
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 += h & 65535;
1657
- d += h >>> 16;
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
- h = ah1;
1663
+ h2 = ah1;
1664
1664
  l = al1;
1665
1665
  a = l & 65535;
1666
1666
  b = l >>> 16;
1667
- c = h & 65535;
1668
- d = h >>> 16;
1669
- h = hh[1];
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 += h & 65535;
1674
- d += h >>> 16;
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
- h = ah2;
1680
+ h2 = ah2;
1681
1681
  l = al2;
1682
1682
  a = l & 65535;
1683
1683
  b = l >>> 16;
1684
- c = h & 65535;
1685
- d = h >>> 16;
1686
- h = hh[2];
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 += h & 65535;
1691
- d += h >>> 16;
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
- h = ah3;
1697
+ h2 = ah3;
1698
1698
  l = al3;
1699
1699
  a = l & 65535;
1700
1700
  b = l >>> 16;
1701
- c = h & 65535;
1702
- d = h >>> 16;
1703
- h = hh[3];
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 += h & 65535;
1708
- d += h >>> 16;
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
- h = ah4;
1714
+ h2 = ah4;
1715
1715
  l = al4;
1716
1716
  a = l & 65535;
1717
1717
  b = l >>> 16;
1718
- c = h & 65535;
1719
- d = h >>> 16;
1720
- h = hh[4];
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 += h & 65535;
1725
- d += h >>> 16;
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
- h = ah5;
1731
+ h2 = ah5;
1732
1732
  l = al5;
1733
1733
  a = l & 65535;
1734
1734
  b = l >>> 16;
1735
- c = h & 65535;
1736
- d = h >>> 16;
1737
- h = hh[5];
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 += h & 65535;
1742
- d += h >>> 16;
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
- h = ah6;
1748
+ h2 = ah6;
1749
1749
  l = al6;
1750
1750
  a = l & 65535;
1751
1751
  b = l >>> 16;
1752
- c = h & 65535;
1753
- d = h >>> 16;
1754
- h = hh[6];
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 += h & 65535;
1759
- d += h >>> 16;
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
- h = ah7;
1765
+ h2 = ah7;
1766
1766
  l = al7;
1767
1767
  a = l & 65535;
1768
1768
  b = l >>> 16;
1769
- c = h & 65535;
1770
- d = h >>> 16;
1771
- h = hh[7];
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 += h & 65535;
1776
- d += h >>> 16;
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 add(p, q) {
1817
- var a = gf(), b = gf(), c = gf(), d = gf(), e = gf(), f = gf(), g = gf(), h = gf(), t = 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(g, d, c);
1831
- A(h, b, a);
1830
+ A(g2, d, c);
1831
+ A(h2, b, a);
1832
1832
  M(p[0], e, f);
1833
- M(p[1], h, g);
1834
- M(p[2], g, f);
1835
- M(p[3], e, h);
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
- add(q, p);
1861
- add(p, p);
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 reduce(r) {
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), h = new Uint8Array(64), r = 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
- reduce(r);
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(h, sm, n + 64);
1935
- reduce(h);
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] += h[i] * d[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), h = new Uint8Array(64);
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(h, m, n);
1983
- reduce(h);
1984
- scalarmult(p, q, h);
1982
+ crypto_hash(h2, m, n);
1983
+ reduce2(h2);
1984
+ scalarmult(p, q, h2);
1985
1985
  scalarbase(q, sm.subarray(32));
1986
- add(p, q);
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 h = new Uint8Array(crypto_hash_BYTES);
2219
- crypto_hash(h, msg, msg.length);
2220
- return h;
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 crypto = typeof self !== "undefined" ? self.crypto || self.msCrypto : null;
2234
- if (crypto && crypto.getRandomValues) {
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
- crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
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
- crypto = require("crypto");
2246
- if (crypto && crypto.randomBytes) {
2245
+ crypto2 = require("crypto");
2246
+ if (crypto2 && crypto2.randomBytes) {
2247
2247
  nacl2.setPRNG(function(x, n) {
2248
- var i, v = crypto.randomBytes(n);
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
  });
@@ -2337,6 +2337,1603 @@ __export(index_exports, {
2337
2337
  module.exports = __toCommonJS(index_exports);
2338
2338
  var import_tweetnacl = __toESM(require_nacl_fast());
2339
2339
  var import_tweetnacl_util = __toESM(require_nacl_util());
2340
+
2341
+ // node_modules/mlkem/esm/src/errors.js
2342
+ var MlKemError = class extends Error {
2343
+ constructor(e) {
2344
+ let message;
2345
+ if (e instanceof Error) {
2346
+ message = e.message;
2347
+ } else if (typeof e === "string") {
2348
+ message = e;
2349
+ } else {
2350
+ message = "";
2351
+ }
2352
+ super(message);
2353
+ this.name = this.constructor.name;
2354
+ }
2355
+ };
2356
+
2357
+ // node_modules/mlkem/esm/src/consts.js
2358
+ var N = 256;
2359
+ var Q = 3329;
2360
+ var Q_INV = 62209;
2361
+ var NTT_ZETAS = [
2362
+ 2285,
2363
+ 2571,
2364
+ 2970,
2365
+ 1812,
2366
+ 1493,
2367
+ 1422,
2368
+ 287,
2369
+ 202,
2370
+ 3158,
2371
+ 622,
2372
+ 1577,
2373
+ 182,
2374
+ 962,
2375
+ 2127,
2376
+ 1855,
2377
+ 1468,
2378
+ 573,
2379
+ 2004,
2380
+ 264,
2381
+ 383,
2382
+ 2500,
2383
+ 1458,
2384
+ 1727,
2385
+ 3199,
2386
+ 2648,
2387
+ 1017,
2388
+ 732,
2389
+ 608,
2390
+ 1787,
2391
+ 411,
2392
+ 3124,
2393
+ 1758,
2394
+ 1223,
2395
+ 652,
2396
+ 2777,
2397
+ 1015,
2398
+ 2036,
2399
+ 1491,
2400
+ 3047,
2401
+ 1785,
2402
+ 516,
2403
+ 3321,
2404
+ 3009,
2405
+ 2663,
2406
+ 1711,
2407
+ 2167,
2408
+ 126,
2409
+ 1469,
2410
+ 2476,
2411
+ 3239,
2412
+ 3058,
2413
+ 830,
2414
+ 107,
2415
+ 1908,
2416
+ 3082,
2417
+ 2378,
2418
+ 2931,
2419
+ 961,
2420
+ 1821,
2421
+ 2604,
2422
+ 448,
2423
+ 2264,
2424
+ 677,
2425
+ 2054,
2426
+ 2226,
2427
+ 430,
2428
+ 555,
2429
+ 843,
2430
+ 2078,
2431
+ 871,
2432
+ 1550,
2433
+ 105,
2434
+ 422,
2435
+ 587,
2436
+ 177,
2437
+ 3094,
2438
+ 3038,
2439
+ 2869,
2440
+ 1574,
2441
+ 1653,
2442
+ 3083,
2443
+ 778,
2444
+ 1159,
2445
+ 3182,
2446
+ 2552,
2447
+ 1483,
2448
+ 2727,
2449
+ 1119,
2450
+ 1739,
2451
+ 644,
2452
+ 2457,
2453
+ 349,
2454
+ 418,
2455
+ 329,
2456
+ 3173,
2457
+ 3254,
2458
+ 817,
2459
+ 1097,
2460
+ 603,
2461
+ 610,
2462
+ 1322,
2463
+ 2044,
2464
+ 1864,
2465
+ 384,
2466
+ 2114,
2467
+ 3193,
2468
+ 1218,
2469
+ 1994,
2470
+ 2455,
2471
+ 220,
2472
+ 2142,
2473
+ 1670,
2474
+ 2144,
2475
+ 1799,
2476
+ 2051,
2477
+ 794,
2478
+ 1819,
2479
+ 2475,
2480
+ 2459,
2481
+ 478,
2482
+ 3221,
2483
+ 3021,
2484
+ 996,
2485
+ 991,
2486
+ 958,
2487
+ 1869,
2488
+ 1522,
2489
+ 1628
2490
+ ];
2491
+ var NTT_ZETAS_INV = [
2492
+ 1701,
2493
+ 1807,
2494
+ 1460,
2495
+ 2371,
2496
+ 2338,
2497
+ 2333,
2498
+ 308,
2499
+ 108,
2500
+ 2851,
2501
+ 870,
2502
+ 854,
2503
+ 1510,
2504
+ 2535,
2505
+ 1278,
2506
+ 1530,
2507
+ 1185,
2508
+ 1659,
2509
+ 1187,
2510
+ 3109,
2511
+ 874,
2512
+ 1335,
2513
+ 2111,
2514
+ 136,
2515
+ 1215,
2516
+ 2945,
2517
+ 1465,
2518
+ 1285,
2519
+ 2007,
2520
+ 2719,
2521
+ 2726,
2522
+ 2232,
2523
+ 2512,
2524
+ 75,
2525
+ 156,
2526
+ 3e3,
2527
+ 2911,
2528
+ 2980,
2529
+ 872,
2530
+ 2685,
2531
+ 1590,
2532
+ 2210,
2533
+ 602,
2534
+ 1846,
2535
+ 777,
2536
+ 147,
2537
+ 2170,
2538
+ 2551,
2539
+ 246,
2540
+ 1676,
2541
+ 1755,
2542
+ 460,
2543
+ 291,
2544
+ 235,
2545
+ 3152,
2546
+ 2742,
2547
+ 2907,
2548
+ 3224,
2549
+ 1779,
2550
+ 2458,
2551
+ 1251,
2552
+ 2486,
2553
+ 2774,
2554
+ 2899,
2555
+ 1103,
2556
+ 1275,
2557
+ 2652,
2558
+ 1065,
2559
+ 2881,
2560
+ 725,
2561
+ 1508,
2562
+ 2368,
2563
+ 398,
2564
+ 951,
2565
+ 247,
2566
+ 1421,
2567
+ 3222,
2568
+ 2499,
2569
+ 271,
2570
+ 90,
2571
+ 853,
2572
+ 1860,
2573
+ 3203,
2574
+ 1162,
2575
+ 1618,
2576
+ 666,
2577
+ 320,
2578
+ 8,
2579
+ 2813,
2580
+ 1544,
2581
+ 282,
2582
+ 1838,
2583
+ 1293,
2584
+ 2314,
2585
+ 552,
2586
+ 2677,
2587
+ 2106,
2588
+ 1571,
2589
+ 205,
2590
+ 2918,
2591
+ 1542,
2592
+ 2721,
2593
+ 2597,
2594
+ 2312,
2595
+ 681,
2596
+ 130,
2597
+ 1602,
2598
+ 1871,
2599
+ 829,
2600
+ 2946,
2601
+ 3065,
2602
+ 1325,
2603
+ 2756,
2604
+ 1861,
2605
+ 1474,
2606
+ 1202,
2607
+ 2367,
2608
+ 3147,
2609
+ 1752,
2610
+ 2707,
2611
+ 171,
2612
+ 3127,
2613
+ 3042,
2614
+ 1907,
2615
+ 1836,
2616
+ 1517,
2617
+ 359,
2618
+ 758,
2619
+ 1441
2620
+ ];
2621
+
2622
+ // node_modules/mlkem/esm/src/sha3/_u64.js
2623
+ var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
2624
+ var _32n = /* @__PURE__ */ BigInt(32);
2625
+ function fromBig(n, le = false) {
2626
+ if (le) {
2627
+ return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
2628
+ }
2629
+ return {
2630
+ h: Number(n >> _32n & U32_MASK64) | 0,
2631
+ l: Number(n & U32_MASK64) | 0
2632
+ };
2633
+ }
2634
+ function split(lst, le = false) {
2635
+ const len = lst.length;
2636
+ const Ah = new Uint32Array(len);
2637
+ const Al = new Uint32Array(len);
2638
+ for (let i = 0; i < len; i++) {
2639
+ const { h: h2, l } = fromBig(lst[i], le);
2640
+ [Ah[i], Al[i]] = [h2, l];
2641
+ }
2642
+ return [Ah, Al];
2643
+ }
2644
+ var rotlSH = (h2, l, s) => h2 << s | l >>> 32 - s;
2645
+ var rotlSL = (h2, l, s) => l << s | h2 >>> 32 - s;
2646
+ var rotlBH = (h2, l, s) => l << s - 32 | h2 >>> 64 - s;
2647
+ var rotlBL = (h2, l, s) => h2 << s - 32 | l >>> 64 - s;
2648
+
2649
+ // node_modules/mlkem/esm/src/sha3/utils.js
2650
+ function isBytes(a) {
2651
+ return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
2652
+ }
2653
+ function anumber(n, title = "") {
2654
+ if (!Number.isSafeInteger(n) || n < 0) {
2655
+ const prefix = title && `"${title}" `;
2656
+ throw new Error(`${prefix}expected integer >0, got ${n}`);
2657
+ }
2658
+ }
2659
+ function abytes(value, length, title = "") {
2660
+ const bytes = isBytes(value);
2661
+ const len = value?.length;
2662
+ const needsLen = length !== void 0;
2663
+ if (!bytes || needsLen && len !== length) {
2664
+ const prefix = title && `"${title}" `;
2665
+ const ofLen = needsLen ? ` of length ${length}` : "";
2666
+ const got = bytes ? `length=${len}` : `type=${typeof value}`;
2667
+ throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
2668
+ }
2669
+ return value;
2670
+ }
2671
+ function aexists(instance, checkFinished = true) {
2672
+ if (instance.destroyed)
2673
+ throw new Error("Hash instance has been destroyed");
2674
+ if (checkFinished && instance.finished) {
2675
+ throw new Error("Hash#digest() has already been called");
2676
+ }
2677
+ }
2678
+ function aoutput(out, instance) {
2679
+ abytes(out, void 0, "digestInto() output");
2680
+ const min = instance.outputLen;
2681
+ if (out.length < min) {
2682
+ throw new Error('"digestInto() output" expected to be of length >=' + min);
2683
+ }
2684
+ }
2685
+ function u32(arr) {
2686
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
2687
+ }
2688
+ function clean(...arrays) {
2689
+ for (let i = 0; i < arrays.length; i++) {
2690
+ arrays[i].fill(0);
2691
+ }
2692
+ }
2693
+ var isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68)();
2694
+ function byteSwap(word) {
2695
+ return word << 24 & 4278190080 | word << 8 & 16711680 | word >>> 8 & 65280 | word >>> 24 & 255;
2696
+ }
2697
+ function byteSwap32(arr) {
2698
+ for (let i = 0; i < arr.length; i++) {
2699
+ arr[i] = byteSwap(arr[i]);
2700
+ }
2701
+ return arr;
2702
+ }
2703
+ var swap32IfBE = isLE ? (u) => u : byteSwap32;
2704
+ function createHasher(hashCons, info = {}) {
2705
+ const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
2706
+ const tmp = hashCons(void 0);
2707
+ hashC.outputLen = tmp.outputLen;
2708
+ hashC.blockLen = tmp.blockLen;
2709
+ hashC.create = (opts) => hashCons(opts);
2710
+ Object.assign(hashC, info);
2711
+ return Object.freeze(hashC);
2712
+ }
2713
+ var oidNist = (suffix) => ({
2714
+ oid: Uint8Array.from([
2715
+ 6,
2716
+ 9,
2717
+ 96,
2718
+ 134,
2719
+ 72,
2720
+ 1,
2721
+ 101,
2722
+ 3,
2723
+ 4,
2724
+ 2,
2725
+ suffix
2726
+ ])
2727
+ });
2728
+
2729
+ // node_modules/mlkem/esm/src/sha3/sha3.js
2730
+ var _0n = BigInt(0);
2731
+ var _1n = BigInt(1);
2732
+ var _2n = BigInt(2);
2733
+ var _7n = BigInt(7);
2734
+ var _256n = BigInt(256);
2735
+ var _0x71n = BigInt(113);
2736
+ var SHA3_PI = [];
2737
+ var SHA3_ROTL = [];
2738
+ var _SHA3_IOTA = [];
2739
+ for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
2740
+ [x, y] = [y, (2 * x + 3 * y) % 5];
2741
+ SHA3_PI.push(2 * (5 * y + x));
2742
+ SHA3_ROTL.push((round + 1) * (round + 2) / 2 % 64);
2743
+ let t = _0n;
2744
+ for (let j = 0; j < 7; j++) {
2745
+ R = (R << _1n ^ (R >> _7n) * _0x71n) % _256n;
2746
+ if (R & _2n)
2747
+ t ^= _1n << (_1n << BigInt(j)) - _1n;
2748
+ }
2749
+ _SHA3_IOTA.push(t);
2750
+ }
2751
+ var IOTAS = split(_SHA3_IOTA, true);
2752
+ var SHA3_IOTA_H = IOTAS[0];
2753
+ var SHA3_IOTA_L = IOTAS[1];
2754
+ var rotlH = (h2, l, s) => s > 32 ? rotlBH(h2, l, s) : rotlSH(h2, l, s);
2755
+ var rotlL = (h2, l, s) => s > 32 ? rotlBL(h2, l, s) : rotlSL(h2, l, s);
2756
+ function keccakP(s, rounds = 24) {
2757
+ const B = new Uint32Array(5 * 2);
2758
+ for (let round = 24 - rounds; round < 24; round++) {
2759
+ for (let x = 0; x < 10; x++) {
2760
+ B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
2761
+ }
2762
+ for (let x = 0; x < 10; x += 2) {
2763
+ const idx1 = (x + 8) % 10;
2764
+ const idx0 = (x + 2) % 10;
2765
+ const B0 = B[idx0];
2766
+ const B1 = B[idx0 + 1];
2767
+ const Th = rotlH(B0, B1, 1) ^ B[idx1];
2768
+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
2769
+ for (let y = 0; y < 50; y += 10) {
2770
+ s[x + y] ^= Th;
2771
+ s[x + y + 1] ^= Tl;
2772
+ }
2773
+ }
2774
+ let curH = s[2];
2775
+ let curL = s[3];
2776
+ for (let t = 0; t < 24; t++) {
2777
+ const shift = SHA3_ROTL[t];
2778
+ const Th = rotlH(curH, curL, shift);
2779
+ const Tl = rotlL(curH, curL, shift);
2780
+ const PI = SHA3_PI[t];
2781
+ curH = s[PI];
2782
+ curL = s[PI + 1];
2783
+ s[PI] = Th;
2784
+ s[PI + 1] = Tl;
2785
+ }
2786
+ for (let y = 0; y < 50; y += 10) {
2787
+ for (let x = 0; x < 10; x++)
2788
+ B[x] = s[y + x];
2789
+ for (let x = 0; x < 10; x++) {
2790
+ s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
2791
+ }
2792
+ }
2793
+ s[0] ^= SHA3_IOTA_H[round];
2794
+ s[1] ^= SHA3_IOTA_L[round];
2795
+ }
2796
+ clean(B);
2797
+ }
2798
+ var Keccak = class _Keccak {
2799
+ // NOTE: we accept arguments in bytes instead of bits here.
2800
+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
2801
+ Object.defineProperty(this, "state", {
2802
+ enumerable: true,
2803
+ configurable: true,
2804
+ writable: true,
2805
+ value: void 0
2806
+ });
2807
+ Object.defineProperty(this, "pos", {
2808
+ enumerable: true,
2809
+ configurable: true,
2810
+ writable: true,
2811
+ value: 0
2812
+ });
2813
+ Object.defineProperty(this, "posOut", {
2814
+ enumerable: true,
2815
+ configurable: true,
2816
+ writable: true,
2817
+ value: 0
2818
+ });
2819
+ Object.defineProperty(this, "finished", {
2820
+ enumerable: true,
2821
+ configurable: true,
2822
+ writable: true,
2823
+ value: false
2824
+ });
2825
+ Object.defineProperty(this, "state32", {
2826
+ enumerable: true,
2827
+ configurable: true,
2828
+ writable: true,
2829
+ value: void 0
2830
+ });
2831
+ Object.defineProperty(this, "destroyed", {
2832
+ enumerable: true,
2833
+ configurable: true,
2834
+ writable: true,
2835
+ value: false
2836
+ });
2837
+ Object.defineProperty(this, "blockLen", {
2838
+ enumerable: true,
2839
+ configurable: true,
2840
+ writable: true,
2841
+ value: void 0
2842
+ });
2843
+ Object.defineProperty(this, "suffix", {
2844
+ enumerable: true,
2845
+ configurable: true,
2846
+ writable: true,
2847
+ value: void 0
2848
+ });
2849
+ Object.defineProperty(this, "outputLen", {
2850
+ enumerable: true,
2851
+ configurable: true,
2852
+ writable: true,
2853
+ value: void 0
2854
+ });
2855
+ Object.defineProperty(this, "enableXOF", {
2856
+ enumerable: true,
2857
+ configurable: true,
2858
+ writable: true,
2859
+ value: false
2860
+ });
2861
+ Object.defineProperty(this, "rounds", {
2862
+ enumerable: true,
2863
+ configurable: true,
2864
+ writable: true,
2865
+ value: void 0
2866
+ });
2867
+ this.blockLen = blockLen;
2868
+ this.suffix = suffix;
2869
+ this.outputLen = outputLen;
2870
+ this.enableXOF = enableXOF;
2871
+ this.rounds = rounds;
2872
+ anumber(outputLen, "outputLen");
2873
+ if (!(0 < blockLen && blockLen < 200)) {
2874
+ throw new Error("only keccak-f1600 function is supported");
2875
+ }
2876
+ this.state = new Uint8Array(200);
2877
+ this.state32 = u32(this.state);
2878
+ }
2879
+ clone() {
2880
+ return this._cloneInto();
2881
+ }
2882
+ keccak() {
2883
+ swap32IfBE(this.state32);
2884
+ keccakP(this.state32, this.rounds);
2885
+ swap32IfBE(this.state32);
2886
+ this.posOut = 0;
2887
+ this.pos = 0;
2888
+ }
2889
+ update(data) {
2890
+ aexists(this);
2891
+ abytes(data);
2892
+ const { blockLen, state } = this;
2893
+ const len = data.length;
2894
+ for (let pos = 0; pos < len; ) {
2895
+ const take = Math.min(blockLen - this.pos, len - pos);
2896
+ for (let i = 0; i < take; i++)
2897
+ state[this.pos++] ^= data[pos++];
2898
+ if (this.pos === blockLen)
2899
+ this.keccak();
2900
+ }
2901
+ return this;
2902
+ }
2903
+ finish() {
2904
+ if (this.finished)
2905
+ return;
2906
+ this.finished = true;
2907
+ const { state, suffix, pos, blockLen } = this;
2908
+ state[pos] ^= suffix;
2909
+ if ((suffix & 128) !== 0 && pos === blockLen - 1)
2910
+ this.keccak();
2911
+ state[blockLen - 1] ^= 128;
2912
+ this.keccak();
2913
+ }
2914
+ writeInto(out) {
2915
+ aexists(this, false);
2916
+ abytes(out);
2917
+ this.finish();
2918
+ const bufferOut = this.state;
2919
+ const { blockLen } = this;
2920
+ for (let pos = 0, len = out.length; pos < len; ) {
2921
+ if (this.posOut >= blockLen)
2922
+ this.keccak();
2923
+ const take = Math.min(blockLen - this.posOut, len - pos);
2924
+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
2925
+ this.posOut += take;
2926
+ pos += take;
2927
+ }
2928
+ return out;
2929
+ }
2930
+ xofInto(out) {
2931
+ if (!this.enableXOF) {
2932
+ throw new Error("XOF is not possible for this instance");
2933
+ }
2934
+ return this.writeInto(out);
2935
+ }
2936
+ xof(bytes) {
2937
+ anumber(bytes);
2938
+ return this.xofInto(new Uint8Array(bytes));
2939
+ }
2940
+ digestInto(out) {
2941
+ aoutput(out, this);
2942
+ if (this.finished)
2943
+ throw new Error("digest() was already called");
2944
+ this.writeInto(out);
2945
+ this.destroy();
2946
+ return out;
2947
+ }
2948
+ digest() {
2949
+ return this.digestInto(new Uint8Array(this.outputLen));
2950
+ }
2951
+ destroy() {
2952
+ this.destroyed = true;
2953
+ clean(this.state);
2954
+ }
2955
+ _cloneInto(to) {
2956
+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
2957
+ to || (to = new _Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
2958
+ to.state32.set(this.state32);
2959
+ to.pos = this.pos;
2960
+ to.posOut = this.posOut;
2961
+ to.finished = this.finished;
2962
+ to.rounds = rounds;
2963
+ to.suffix = suffix;
2964
+ to.outputLen = outputLen;
2965
+ to.enableXOF = enableXOF;
2966
+ to.destroyed = this.destroyed;
2967
+ return to;
2968
+ }
2969
+ };
2970
+ var genKeccak = (suffix, blockLen, outputLen, info = {}) => createHasher(() => new Keccak(blockLen, suffix, outputLen), info);
2971
+ var sha3_256 = /* @__PURE__ */ genKeccak(
2972
+ 6,
2973
+ 136,
2974
+ 32,
2975
+ /* @__PURE__ */ oidNist(8)
2976
+ );
2977
+ var sha3_512 = /* @__PURE__ */ genKeccak(
2978
+ 6,
2979
+ 72,
2980
+ 64,
2981
+ /* @__PURE__ */ oidNist(10)
2982
+ );
2983
+ var genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => new Keccak(blockLen, suffix, opts.dkLen === void 0 ? outputLen : opts.dkLen, true), info);
2984
+ var shake128 = /* @__PURE__ */ genShake(31, 168, 16, /* @__PURE__ */ oidNist(11));
2985
+ var shake256 = /* @__PURE__ */ genShake(31, 136, 32, /* @__PURE__ */ oidNist(12));
2986
+
2987
+ // node_modules/mlkem/esm/_dnt.shims.js
2988
+ var dntGlobals = {};
2989
+ var dntGlobalThis = createMergeProxy(globalThis, dntGlobals);
2990
+ function createMergeProxy(baseObj, extObj) {
2991
+ return new Proxy(baseObj, {
2992
+ get(_target, prop, _receiver) {
2993
+ if (prop in extObj) {
2994
+ return extObj[prop];
2995
+ } else {
2996
+ return baseObj[prop];
2997
+ }
2998
+ },
2999
+ set(_target, prop, value) {
3000
+ if (prop in extObj) {
3001
+ delete extObj[prop];
3002
+ }
3003
+ baseObj[prop] = value;
3004
+ return true;
3005
+ },
3006
+ deleteProperty(_target, prop) {
3007
+ let success = false;
3008
+ if (prop in extObj) {
3009
+ delete extObj[prop];
3010
+ success = true;
3011
+ }
3012
+ if (prop in baseObj) {
3013
+ delete baseObj[prop];
3014
+ success = true;
3015
+ }
3016
+ return success;
3017
+ },
3018
+ ownKeys(_target) {
3019
+ const baseKeys = Reflect.ownKeys(baseObj);
3020
+ const extKeys = Reflect.ownKeys(extObj);
3021
+ const extKeysSet = new Set(extKeys);
3022
+ return [...baseKeys.filter((k) => !extKeysSet.has(k)), ...extKeys];
3023
+ },
3024
+ defineProperty(_target, prop, desc) {
3025
+ if (prop in extObj) {
3026
+ delete extObj[prop];
3027
+ }
3028
+ Reflect.defineProperty(baseObj, prop, desc);
3029
+ return true;
3030
+ },
3031
+ getOwnPropertyDescriptor(_target, prop) {
3032
+ if (prop in extObj) {
3033
+ return Reflect.getOwnPropertyDescriptor(extObj, prop);
3034
+ } else {
3035
+ return Reflect.getOwnPropertyDescriptor(baseObj, prop);
3036
+ }
3037
+ },
3038
+ has(_target, prop) {
3039
+ return prop in extObj || prop in baseObj;
3040
+ }
3041
+ });
3042
+ }
3043
+
3044
+ // node_modules/mlkem/esm/src/utils.js
3045
+ function byte(n) {
3046
+ return n % 256;
3047
+ }
3048
+ function int16(n) {
3049
+ const end = -32768;
3050
+ const start = 32767;
3051
+ if (n >= end && n <= start) {
3052
+ return n;
3053
+ }
3054
+ if (n < end) {
3055
+ n = n + 32769;
3056
+ n = n % 65536;
3057
+ return start + n;
3058
+ }
3059
+ n = n - 32768;
3060
+ n = n % 65536;
3061
+ return end + n;
3062
+ }
3063
+ function uint16(n) {
3064
+ return n % 65536;
3065
+ }
3066
+ function int32(n) {
3067
+ const end = -2147483648;
3068
+ const start = 2147483647;
3069
+ if (n >= end && n <= start) {
3070
+ return n;
3071
+ }
3072
+ if (n < end) {
3073
+ n = n + 2147483649;
3074
+ n = n % 4294967296;
3075
+ return start + n;
3076
+ }
3077
+ n = n - 2147483648;
3078
+ n = n % 4294967296;
3079
+ return end + n;
3080
+ }
3081
+ function uint32(n) {
3082
+ return n % 4294967296;
3083
+ }
3084
+ function constantTimeCompare(x, y) {
3085
+ if (x.length != y.length) {
3086
+ return 0;
3087
+ }
3088
+ const v = new Uint8Array([0]);
3089
+ for (let i = 0; i < x.length; i++) {
3090
+ v[0] |= x[i] ^ y[i];
3091
+ }
3092
+ const z = new Uint8Array([0]);
3093
+ z[0] = ~(v[0] ^ z[0]);
3094
+ z[0] &= z[0] >> 4;
3095
+ z[0] &= z[0] >> 2;
3096
+ z[0] &= z[0] >> 1;
3097
+ return z[0];
3098
+ }
3099
+ function equalUint8Array(x, y) {
3100
+ if (x.length != y.length) {
3101
+ return false;
3102
+ }
3103
+ for (let i = 0; i < x.length; i++) {
3104
+ if (x[i] !== y[i]) {
3105
+ return false;
3106
+ }
3107
+ }
3108
+ return true;
3109
+ }
3110
+ async function loadCrypto() {
3111
+ if (typeof dntGlobalThis !== "undefined" && globalThis.crypto !== void 0) {
3112
+ return globalThis.crypto;
3113
+ }
3114
+ try {
3115
+ const { webcrypto } = await import("crypto");
3116
+ return webcrypto;
3117
+ } catch (_e) {
3118
+ throw new Error("failed to load Crypto");
3119
+ }
3120
+ }
3121
+ function prf(len, seed, nonce) {
3122
+ return shake256.create({ dkLen: len }).update(seed).update(new Uint8Array([nonce])).digest();
3123
+ }
3124
+ function byteopsLoad32(x) {
3125
+ let r = uint32(x[0]);
3126
+ r |= uint32(x[1]) << 8;
3127
+ r |= uint32(x[2]) << 16;
3128
+ r |= uint32(x[3]) << 24;
3129
+ return uint32(r);
3130
+ }
3131
+
3132
+ // node_modules/mlkem/esm/src/mlKemBase.js
3133
+ var MlKemBase = class {
3134
+ /**
3135
+ * Creates a new instance of the MlKemBase class.
3136
+ */
3137
+ constructor() {
3138
+ Object.defineProperty(this, "_api", {
3139
+ enumerable: true,
3140
+ configurable: true,
3141
+ writable: true,
3142
+ value: void 0
3143
+ });
3144
+ Object.defineProperty(this, "_k", {
3145
+ enumerable: true,
3146
+ configurable: true,
3147
+ writable: true,
3148
+ value: 0
3149
+ });
3150
+ Object.defineProperty(this, "_du", {
3151
+ enumerable: true,
3152
+ configurable: true,
3153
+ writable: true,
3154
+ value: 0
3155
+ });
3156
+ Object.defineProperty(this, "_dv", {
3157
+ enumerable: true,
3158
+ configurable: true,
3159
+ writable: true,
3160
+ value: 0
3161
+ });
3162
+ Object.defineProperty(this, "_eta1", {
3163
+ enumerable: true,
3164
+ configurable: true,
3165
+ writable: true,
3166
+ value: 0
3167
+ });
3168
+ Object.defineProperty(this, "_eta2", {
3169
+ enumerable: true,
3170
+ configurable: true,
3171
+ writable: true,
3172
+ value: 0
3173
+ });
3174
+ Object.defineProperty(this, "_skSize", {
3175
+ enumerable: true,
3176
+ configurable: true,
3177
+ writable: true,
3178
+ value: 0
3179
+ });
3180
+ Object.defineProperty(this, "_pkSize", {
3181
+ enumerable: true,
3182
+ configurable: true,
3183
+ writable: true,
3184
+ value: 0
3185
+ });
3186
+ Object.defineProperty(this, "_compressedUSize", {
3187
+ enumerable: true,
3188
+ configurable: true,
3189
+ writable: true,
3190
+ value: 0
3191
+ });
3192
+ Object.defineProperty(this, "_compressedVSize", {
3193
+ enumerable: true,
3194
+ configurable: true,
3195
+ writable: true,
3196
+ value: 0
3197
+ });
3198
+ }
3199
+ /**
3200
+ * Generates a keypair [publicKey, privateKey].
3201
+ *
3202
+ * If an error occurred, throws {@link MlKemError}.
3203
+ *
3204
+ * @returns A kaypair [publicKey, privateKey].
3205
+ * @throws {@link MlKemError}
3206
+ *
3207
+ * @example Generates a {@link MlKem768} keypair.
3208
+ *
3209
+ * ```ts
3210
+ * // Using jsr:
3211
+ * import { MlKem768 } from "@dajiaji/mlkem";
3212
+ * // Using npm:
3213
+ * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
3214
+ *
3215
+ * const kyber = new MlKem768();
3216
+ * const [pk, sk] = await kyber.generateKeyPair();
3217
+ * ```
3218
+ */
3219
+ async generateKeyPair() {
3220
+ await this._setup();
3221
+ try {
3222
+ const rnd = new Uint8Array(64);
3223
+ this._api.getRandomValues(rnd);
3224
+ return this._deriveKeyPair(rnd);
3225
+ } catch (e) {
3226
+ throw new MlKemError(e);
3227
+ }
3228
+ }
3229
+ /**
3230
+ * Derives a keypair [publicKey, privateKey] deterministically from a 64-octet seed.
3231
+ *
3232
+ * If an error occurred, throws {@link MlKemError}.
3233
+ *
3234
+ * @param seed A 64-octet seed for the deterministic key generation.
3235
+ * @returns A kaypair [publicKey, privateKey].
3236
+ * @throws {@link MlKemError}
3237
+ *
3238
+ * @example Derives a {@link MlKem768} keypair deterministically.
3239
+ *
3240
+ * ```ts
3241
+ * // Using jsr:
3242
+ * import { MlKem768 } from "@dajiaji/mlkem";
3243
+ * // Using npm:
3244
+ * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
3245
+ *
3246
+ * const kyber = new MlKem768();
3247
+ * const seed = new Uint8Array(64);
3248
+ * globalThis.crypto.getRandomValues(seed);
3249
+ * const [pk, sk] = await kyber.deriveKeyPair(seed);
3250
+ * ```
3251
+ */
3252
+ async deriveKeyPair(seed) {
3253
+ await this._setup();
3254
+ try {
3255
+ if (seed.byteLength !== 64) {
3256
+ throw new Error("seed must be 64 bytes in length");
3257
+ }
3258
+ return this._deriveKeyPair(seed);
3259
+ } catch (e) {
3260
+ throw new MlKemError(e);
3261
+ }
3262
+ }
3263
+ /**
3264
+ * Generates a shared secret from the encapsulated ciphertext and the private key.
3265
+ *
3266
+ * If an error occurred, throws {@link MlKemError}.
3267
+ *
3268
+ * @param pk A public key.
3269
+ * @param seed An optional 32-octet seed for the deterministic shared secret generation.
3270
+ * @returns A ciphertext (encapsulated public key) and a shared secret.
3271
+ * @throws {@link MlKemError}
3272
+ *
3273
+ * @example The {@link MlKem768} encapsulation.
3274
+ *
3275
+ * ```ts
3276
+ * // Using jsr:
3277
+ * import { MlKem768 } from "@dajiaji/mlkem";
3278
+ * // Using npm:
3279
+ * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
3280
+ *
3281
+ * const kyber = new MlKem768();
3282
+ * const [pk, sk] = await kyber.generateKeyPair();
3283
+ * const [ct, ss] = await kyber.encap(pk);
3284
+ * ```
3285
+ */
3286
+ async encap(pk, seed) {
3287
+ await this._setup();
3288
+ try {
3289
+ if (pk.length !== 384 * this._k + 32) {
3290
+ throw new Error("invalid encapsulation key");
3291
+ }
3292
+ const m = this._getSeed(seed);
3293
+ const [k, r] = g(m, h(pk));
3294
+ const ct = this._encap(pk, m, r);
3295
+ return [ct, k];
3296
+ } catch (e) {
3297
+ throw new MlKemError(e);
3298
+ }
3299
+ }
3300
+ /**
3301
+ * Generates a ciphertext for the public key and a shared secret.
3302
+ *
3303
+ * If an error occurred, throws {@link MlKemError}.
3304
+ *
3305
+ * @param ct A ciphertext generated by {@link encap}.
3306
+ * @param sk A private key.
3307
+ * @returns A shared secret.
3308
+ * @throws {@link MlKemError}
3309
+ *
3310
+ * @example The {@link MlKem768} decapsulation.
3311
+ *
3312
+ * ```ts
3313
+ * // Using jsr:
3314
+ * import { MlKem768 } from "@dajiaji/mlkem";
3315
+ * // Using npm:
3316
+ * // import { MlKem768 } from "mlkem"; // or "crystals-kyber-js"
3317
+ *
3318
+ * const kyber = new MlKem768();
3319
+ * const [pk, sk] = await kyber.generateKeyPair();
3320
+ * const [ct, ssS] = await kyber.encap(pk);
3321
+ * const ssR = await kyber.decap(ct, sk);
3322
+ * // ssS === ssR
3323
+ * ```
3324
+ */
3325
+ async decap(ct, sk) {
3326
+ await this._setup();
3327
+ try {
3328
+ if (ct.byteLength !== this._compressedUSize + this._compressedVSize) {
3329
+ throw new Error("Invalid ct size");
3330
+ }
3331
+ if (sk.length !== 768 * this._k + 96) {
3332
+ throw new Error("Invalid decapsulation key");
3333
+ }
3334
+ const sk2 = sk.subarray(0, this._skSize);
3335
+ const pk = sk.subarray(this._skSize, this._skSize + this._pkSize);
3336
+ const hpk = sk.subarray(this._skSize + this._pkSize, this._skSize + this._pkSize + 32);
3337
+ const z = sk.subarray(this._skSize + this._pkSize + 32, this._skSize + this._pkSize + 64);
3338
+ const m2 = this._decap(ct, sk2);
3339
+ const [k2, r2] = g(m2, hpk);
3340
+ const kBar = kdf(z, ct);
3341
+ const ct2 = this._encap(pk, m2, r2);
3342
+ return constantTimeCompare(ct, ct2) === 1 ? k2 : kBar;
3343
+ } catch (e) {
3344
+ throw new MlKemError(e);
3345
+ }
3346
+ }
3347
+ /**
3348
+ * Sets up the MlKemBase instance by loading the necessary crypto library.
3349
+ * If the crypto library is already loaded, this method does nothing.
3350
+ * @returns {Promise<void>} A promise that resolves when the setup is complete.
3351
+ */
3352
+ async _setup() {
3353
+ if (this._api !== void 0) {
3354
+ return;
3355
+ }
3356
+ this._api = await loadCrypto();
3357
+ }
3358
+ /**
3359
+ * Returns a Uint8Array seed for cryptographic operations.
3360
+ * If no seed is provided, a random seed of length 32 bytes is generated.
3361
+ * If a seed is provided, it must be exactly 32 bytes in length.
3362
+ *
3363
+ * @param seed - Optional seed for cryptographic operations.
3364
+ * @returns A Uint8Array seed.
3365
+ * @throws Error if the provided seed is not 32 bytes in length.
3366
+ */
3367
+ _getSeed(seed) {
3368
+ if (seed == void 0) {
3369
+ const s = new Uint8Array(32);
3370
+ this._api.getRandomValues(s);
3371
+ return s;
3372
+ }
3373
+ if (seed.byteLength !== 32) {
3374
+ throw new Error("seed must be 32 bytes in length");
3375
+ }
3376
+ return seed;
3377
+ }
3378
+ /**
3379
+ * Derives a key pair from a given seed.
3380
+ *
3381
+ * @param seed - The seed used for key derivation.
3382
+ * @returns An array containing the public key and secret key.
3383
+ */
3384
+ _deriveKeyPair(seed) {
3385
+ const cpaSeed = seed.subarray(0, 32);
3386
+ const z = seed.subarray(32, 64);
3387
+ const [pk, skBody] = this._deriveCpaKeyPair(cpaSeed);
3388
+ const pkh = h(pk);
3389
+ const sk = new Uint8Array(this._skSize + this._pkSize + 64);
3390
+ sk.set(skBody, 0);
3391
+ sk.set(pk, this._skSize);
3392
+ sk.set(pkh, this._skSize + this._pkSize);
3393
+ sk.set(z, this._skSize + this._pkSize + 32);
3394
+ return [pk, sk];
3395
+ }
3396
+ // indcpaKeyGen generates public and private keys for the CPA-secure
3397
+ // public-key encryption scheme underlying ML-KEM.
3398
+ /**
3399
+ * Derives a CPA key pair using the provided CPA seed.
3400
+ *
3401
+ * @param cpaSeed - The CPA seed used for key derivation.
3402
+ * @returns An array containing the public key and private key.
3403
+ */
3404
+ _deriveCpaKeyPair(cpaSeed) {
3405
+ const [publicSeed, noiseSeed] = g(cpaSeed, new Uint8Array([this._k]));
3406
+ const a = this._sampleMatrix(publicSeed, false);
3407
+ const s = this._sampleNoise1(noiseSeed, 0, this._k);
3408
+ const e = this._sampleNoise1(noiseSeed, this._k, this._k);
3409
+ for (let i = 0; i < this._k; i++) {
3410
+ s[i] = ntt(s[i]);
3411
+ s[i] = reduce(s[i]);
3412
+ e[i] = ntt(e[i]);
3413
+ }
3414
+ const pk = new Array(this._k);
3415
+ for (let i = 0; i < this._k; i++) {
3416
+ pk[i] = polyToMont(multiply(a[i], s));
3417
+ pk[i] = add(pk[i], e[i]);
3418
+ pk[i] = reduce(pk[i]);
3419
+ }
3420
+ const pubKey = new Uint8Array(this._pkSize);
3421
+ for (let i = 0; i < this._k; i++) {
3422
+ pubKey.set(polyToBytes(pk[i]), i * 384);
3423
+ }
3424
+ pubKey.set(publicSeed, this._skSize);
3425
+ const privKey = new Uint8Array(this._skSize);
3426
+ for (let i = 0; i < this._k; i++) {
3427
+ privKey.set(polyToBytes(s[i]), i * 384);
3428
+ }
3429
+ return [pubKey, privKey];
3430
+ }
3431
+ // _encap is the encapsulation function of the CPA-secure
3432
+ // public-key encryption scheme underlying ML-KEM.
3433
+ /**
3434
+ * Encapsulates a message using the ML-KEM encryption scheme.
3435
+ *
3436
+ * @param pk - The public key.
3437
+ * @param msg - The message to be encapsulated.
3438
+ * @param seed - The seed used for generating random values.
3439
+ * @returns The encapsulated message as a Uint8Array.
3440
+ */
3441
+ _encap(pk, msg, seed) {
3442
+ const tHat = new Array(this._k);
3443
+ const pkCheck = new Uint8Array(384 * this._k);
3444
+ for (let i = 0; i < this._k; i++) {
3445
+ tHat[i] = polyFromBytes(pk.subarray(i * 384, (i + 1) * 384));
3446
+ pkCheck.set(polyToBytes(tHat[i]), i * 384);
3447
+ }
3448
+ if (!equalUint8Array(pk.subarray(0, pkCheck.length), pkCheck)) {
3449
+ throw new Error("invalid encapsulation key");
3450
+ }
3451
+ const rho = pk.subarray(this._skSize);
3452
+ const a = this._sampleMatrix(rho, true);
3453
+ const r = this._sampleNoise1(seed, 0, this._k);
3454
+ const e1 = this._sampleNoise2(seed, this._k, this._k);
3455
+ const e2 = this._sampleNoise2(seed, this._k * 2, 1)[0];
3456
+ for (let i = 0; i < this._k; i++) {
3457
+ r[i] = ntt(r[i]);
3458
+ r[i] = reduce(r[i]);
3459
+ }
3460
+ const u = new Array(this._k);
3461
+ for (let i = 0; i < this._k; i++) {
3462
+ u[i] = multiply(a[i], r);
3463
+ u[i] = nttInverse(u[i]);
3464
+ u[i] = add(u[i], e1[i]);
3465
+ u[i] = reduce(u[i]);
3466
+ }
3467
+ const m = polyFromMsg(msg);
3468
+ let v = multiply(tHat, r);
3469
+ v = nttInverse(v);
3470
+ v = add(v, e2);
3471
+ v = add(v, m);
3472
+ v = reduce(v);
3473
+ const ret = new Uint8Array(this._compressedUSize + this._compressedVSize);
3474
+ this._compressU(ret.subarray(0, this._compressedUSize), u);
3475
+ this._compressV(ret.subarray(this._compressedUSize), v);
3476
+ return ret;
3477
+ }
3478
+ // indcpaDecrypt is the decryption function of the CPA-secure
3479
+ // public-key encryption scheme underlying ML-KEM.
3480
+ /**
3481
+ * Decapsulates the ciphertext using the provided secret key.
3482
+ *
3483
+ * @param ct - The ciphertext to be decapsulated.
3484
+ * @param sk - The secret key used for decapsulation.
3485
+ * @returns The decapsulated message as a Uint8Array.
3486
+ */
3487
+ _decap(ct, sk) {
3488
+ const u = this._decompressU(ct.subarray(0, this._compressedUSize));
3489
+ const v = this._decompressV(ct.subarray(this._compressedUSize));
3490
+ const privateKeyPolyvec = this._polyvecFromBytes(sk);
3491
+ for (let i = 0; i < this._k; i++) {
3492
+ u[i] = ntt(u[i]);
3493
+ }
3494
+ let mp = multiply(privateKeyPolyvec, u);
3495
+ mp = nttInverse(mp);
3496
+ mp = subtract(v, mp);
3497
+ mp = reduce(mp);
3498
+ return polyToMsg(mp);
3499
+ }
3500
+ // generateMatrixA deterministically generates a matrix `A` (or the transpose of `A`)
3501
+ // from a seed. Entries of the matrix are polynomials that look uniformly random.
3502
+ // Performs rejection sampling on the output of an extendable-output function (XOF).
3503
+ /**
3504
+ * Generates a sample matrix based on the provided seed and transposition flag.
3505
+ *
3506
+ * @param seed - The seed used for generating the matrix.
3507
+ * @param transposed - A flag indicating whether the matrix should be transposed or not.
3508
+ * @returns The generated sample matrix.
3509
+ */
3510
+ _sampleMatrix(seed, transposed) {
3511
+ const a = new Array(this._k);
3512
+ const transpose = new Uint8Array(2);
3513
+ for (let ctr = 0, i = 0; i < this._k; i++) {
3514
+ a[i] = new Array(this._k);
3515
+ for (let j = 0; j < this._k; j++) {
3516
+ if (transposed) {
3517
+ transpose[0] = i;
3518
+ transpose[1] = j;
3519
+ } else {
3520
+ transpose[0] = j;
3521
+ transpose[1] = i;
3522
+ }
3523
+ const output = xof(seed, transpose);
3524
+ const result = indcpaRejUniform(output.subarray(0, 504), 504, N);
3525
+ a[i][j] = result[0];
3526
+ ctr = result[1];
3527
+ while (ctr < N) {
3528
+ const outputn = output.subarray(504, 672);
3529
+ const result1 = indcpaRejUniform(outputn, 168, N - ctr);
3530
+ const missing = result1[0];
3531
+ const ctrn = result1[1];
3532
+ for (let k = ctr; k < N; k++) {
3533
+ a[i][j][k] = missing[k - ctr];
3534
+ }
3535
+ ctr = ctr + ctrn;
3536
+ }
3537
+ }
3538
+ }
3539
+ return a;
3540
+ }
3541
+ /**
3542
+ * Generates a 2D array of noise samples.
3543
+ *
3544
+ * @param sigma - The noise parameter.
3545
+ * @param offset - The offset value.
3546
+ * @param size - The size of the array.
3547
+ * @returns The generated 2D array of noise samples.
3548
+ */
3549
+ _sampleNoise1(sigma, offset, size) {
3550
+ const r = new Array(size);
3551
+ for (let i = 0; i < size; i++) {
3552
+ r[i] = byteopsCbd(prf(this._eta1 * N / 4, sigma, offset), this._eta1);
3553
+ offset++;
3554
+ }
3555
+ return r;
3556
+ }
3557
+ /**
3558
+ * Generates a 2-dimensional array of noise samples.
3559
+ *
3560
+ * @param sigma - The noise parameter.
3561
+ * @param offset - The offset value.
3562
+ * @param size - The size of the array.
3563
+ * @returns The generated 2-dimensional array of noise samples.
3564
+ */
3565
+ _sampleNoise2(sigma, offset, size) {
3566
+ const r = new Array(size);
3567
+ for (let i = 0; i < size; i++) {
3568
+ r[i] = byteopsCbd(prf(this._eta2 * N / 4, sigma, offset), this._eta2);
3569
+ offset++;
3570
+ }
3571
+ return r;
3572
+ }
3573
+ // polyvecFromBytes deserializes a vector of polynomials.
3574
+ /**
3575
+ * Converts a Uint8Array to a 2D array of numbers representing a polynomial vector.
3576
+ * Each element in the resulting array represents a polynomial.
3577
+ * @param a The Uint8Array to convert.
3578
+ * @returns The 2D array of numbers representing the polynomial vector.
3579
+ */
3580
+ _polyvecFromBytes(a) {
3581
+ const r = new Array(this._k);
3582
+ for (let i = 0; i < this._k; i++) {
3583
+ r[i] = polyFromBytes(a.subarray(i * 384, (i + 1) * 384));
3584
+ }
3585
+ return r;
3586
+ }
3587
+ // compressU lossily compresses and serializes a vector of polynomials.
3588
+ /**
3589
+ * Compresses the given array of coefficients into a Uint8Array.
3590
+ *
3591
+ * @param r - The output Uint8Array.
3592
+ * @param u - The array of coefficients.
3593
+ * @returns The compressed Uint8Array.
3594
+ */
3595
+ _compressU(r, u) {
3596
+ const t = new Array(4);
3597
+ for (let rr = 0, i = 0; i < this._k; i++) {
3598
+ for (let j = 0; j < N / 4; j++) {
3599
+ for (let k = 0; k < 4; k++) {
3600
+ t[k] = ((u[i][4 * j + k] << 10) + Q / 2) / Q & 1023;
3601
+ }
3602
+ r[rr++] = byte(t[0] >> 0);
3603
+ r[rr++] = byte(t[0] >> 8 | t[1] << 2);
3604
+ r[rr++] = byte(t[1] >> 6 | t[2] << 4);
3605
+ r[rr++] = byte(t[2] >> 4 | t[3] << 6);
3606
+ r[rr++] = byte(t[3] >> 2);
3607
+ }
3608
+ }
3609
+ return r;
3610
+ }
3611
+ // compressV lossily compresses and subsequently serializes a polynomial.
3612
+ /**
3613
+ * Compresses the given array of numbers into a Uint8Array.
3614
+ *
3615
+ * @param r - The Uint8Array to store the compressed values.
3616
+ * @param v - The array of numbers to compress.
3617
+ * @returns The compressed Uint8Array.
3618
+ */
3619
+ _compressV(r, v) {
3620
+ const t = new Uint8Array(8);
3621
+ for (let rr = 0, i = 0; i < N / 8; i++) {
3622
+ for (let j = 0; j < 8; j++) {
3623
+ t[j] = byte(((v[8 * i + j] << 4) + Q / 2) / Q) & 15;
3624
+ }
3625
+ r[rr++] = t[0] | t[1] << 4;
3626
+ r[rr++] = t[2] | t[3] << 4;
3627
+ r[rr++] = t[4] | t[5] << 4;
3628
+ r[rr++] = t[6] | t[7] << 4;
3629
+ }
3630
+ return r;
3631
+ }
3632
+ // decompressU de-serializes and decompresses a vector of polynomials and
3633
+ // represents the approximate inverse of compress1. Since compression is lossy,
3634
+ // the results of decompression will may not match the original vector of polynomials.
3635
+ /**
3636
+ * Decompresses a Uint8Array into a two-dimensional array of numbers.
3637
+ *
3638
+ * @param a The Uint8Array to decompress.
3639
+ * @returns The decompressed two-dimensional array.
3640
+ */
3641
+ _decompressU(a) {
3642
+ const r = new Array(this._k);
3643
+ for (let i = 0; i < this._k; i++) {
3644
+ r[i] = new Array(384);
3645
+ }
3646
+ const t = new Array(4);
3647
+ for (let aa = 0, i = 0; i < this._k; i++) {
3648
+ for (let j = 0; j < N / 4; j++) {
3649
+ t[0] = uint16(a[aa + 0]) >> 0 | uint16(a[aa + 1]) << 8;
3650
+ t[1] = uint16(a[aa + 1]) >> 2 | uint16(a[aa + 2]) << 6;
3651
+ t[2] = uint16(a[aa + 2]) >> 4 | uint16(a[aa + 3]) << 4;
3652
+ t[3] = uint16(a[aa + 3]) >> 6 | uint16(a[aa + 4]) << 2;
3653
+ aa = aa + 5;
3654
+ for (let k = 0; k < 4; k++) {
3655
+ r[i][4 * j + k] = int16(uint32(t[k] & 1023) * uint32(Q) + 512 >> 10);
3656
+ }
3657
+ }
3658
+ }
3659
+ return r;
3660
+ }
3661
+ // decompressV de-serializes and subsequently decompresses a polynomial,
3662
+ // representing the approximate inverse of compress2.
3663
+ // Note that compression is lossy, and thus decompression will not match the
3664
+ // original input.
3665
+ /**
3666
+ * Decompresses a Uint8Array into an array of numbers.
3667
+ *
3668
+ * @param a - The Uint8Array to decompress.
3669
+ * @returns An array of numbers.
3670
+ */
3671
+ _decompressV(a) {
3672
+ const r = new Array(384);
3673
+ for (let aa = 0, i = 0; i < N / 2; i++, aa++) {
3674
+ r[2 * i + 0] = int16(uint16(a[aa] & 15) * uint16(Q) + 8 >> 4);
3675
+ r[2 * i + 1] = int16(uint16(a[aa] >> 4) * uint16(Q) + 8 >> 4);
3676
+ }
3677
+ return r;
3678
+ }
3679
+ };
3680
+ function g(a, b) {
3681
+ const hash = sha3_512.create().update(a);
3682
+ if (b !== void 0) {
3683
+ hash.update(b);
3684
+ }
3685
+ const res = hash.digest();
3686
+ return [res.subarray(0, 32), res.subarray(32, 64)];
3687
+ }
3688
+ function h(msg) {
3689
+ return sha3_256.create().update(msg).digest();
3690
+ }
3691
+ function kdf(a, b) {
3692
+ const hash = shake256.create({ dkLen: 32 }).update(a);
3693
+ if (b !== void 0) {
3694
+ hash.update(b);
3695
+ }
3696
+ return hash.digest();
3697
+ }
3698
+ function xof(seed, transpose) {
3699
+ return shake128.create({ dkLen: 672 }).update(seed).update(transpose).digest();
3700
+ }
3701
+ function polyToBytes(a) {
3702
+ let t0 = 0;
3703
+ let t1 = 0;
3704
+ const r = new Uint8Array(384);
3705
+ const a2 = subtractQ(a);
3706
+ for (let i = 0; i < N / 2; i++) {
3707
+ t0 = uint16(a2[2 * i]);
3708
+ t1 = uint16(a2[2 * i + 1]);
3709
+ r[3 * i + 0] = byte(t0 >> 0);
3710
+ r[3 * i + 1] = byte(t0 >> 8) | byte(t1 << 4);
3711
+ r[3 * i + 2] = byte(t1 >> 4);
3712
+ }
3713
+ return r;
3714
+ }
3715
+ function polyFromBytes(a) {
3716
+ const r = new Array(384).fill(0);
3717
+ for (let i = 0; i < N / 2; i++) {
3718
+ r[2 * i] = int16((uint16(a[3 * i + 0]) >> 0 | uint16(a[3 * i + 1]) << 8) & 4095);
3719
+ r[2 * i + 1] = int16((uint16(a[3 * i + 1]) >> 4 | uint16(a[3 * i + 2]) << 4) & 4095);
3720
+ }
3721
+ return r;
3722
+ }
3723
+ function polyToMsg(a) {
3724
+ const msg = new Uint8Array(32);
3725
+ let t;
3726
+ const a2 = subtractQ(a);
3727
+ for (let i = 0; i < N / 8; i++) {
3728
+ msg[i] = 0;
3729
+ for (let j = 0; j < 8; j++) {
3730
+ t = ((uint16(a2[8 * i + j]) << 1) + uint16(Q / 2)) / uint16(Q) & 1;
3731
+ msg[i] |= byte(t << j);
3732
+ }
3733
+ }
3734
+ return msg;
3735
+ }
3736
+ function polyFromMsg(msg) {
3737
+ const r = new Array(384).fill(0);
3738
+ let mask;
3739
+ for (let i = 0; i < N / 8; i++) {
3740
+ for (let j = 0; j < 8; j++) {
3741
+ mask = -1 * int16(msg[i] >> j & 1);
3742
+ r[8 * i + j] = mask & int16((Q + 1) / 2);
3743
+ }
3744
+ }
3745
+ return r;
3746
+ }
3747
+ function indcpaRejUniform(buf, bufl, len) {
3748
+ const r = new Array(384).fill(0);
3749
+ let ctr = 0;
3750
+ let val0, val1;
3751
+ for (let pos = 0; ctr < len && pos + 3 <= bufl; ) {
3752
+ val0 = (uint16(buf[pos] >> 0) | uint16(buf[pos + 1]) << 8) & 4095;
3753
+ val1 = (uint16(buf[pos + 1] >> 4) | uint16(buf[pos + 2]) << 4) & 4095;
3754
+ pos = pos + 3;
3755
+ if (val0 < Q) {
3756
+ r[ctr] = val0;
3757
+ ctr = ctr + 1;
3758
+ }
3759
+ if (ctr < len && val1 < Q) {
3760
+ r[ctr] = val1;
3761
+ ctr = ctr + 1;
3762
+ }
3763
+ }
3764
+ return [r, ctr];
3765
+ }
3766
+ function byteopsCbd(buf, eta) {
3767
+ let t, d;
3768
+ let a, b;
3769
+ const r = new Array(384).fill(0);
3770
+ for (let i = 0; i < N / 8; i++) {
3771
+ t = byteopsLoad32(buf.subarray(4 * i, buf.length));
3772
+ d = t & 1431655765;
3773
+ d = d + (t >> 1 & 1431655765);
3774
+ for (let j = 0; j < 8; j++) {
3775
+ a = int16(d >> 4 * j + 0 & 3);
3776
+ b = int16(d >> 4 * j + eta & 3);
3777
+ r[8 * i + j] = a - b;
3778
+ }
3779
+ }
3780
+ return r;
3781
+ }
3782
+ function ntt(r) {
3783
+ for (let j = 0, k = 1, l = 128; l >= 2; l >>= 1) {
3784
+ for (let start = 0; start < 256; start = j + l) {
3785
+ const zeta = NTT_ZETAS[k];
3786
+ k = k + 1;
3787
+ for (j = start; j < start + l; j++) {
3788
+ const t = nttFqMul(zeta, r[j + l]);
3789
+ r[j + l] = r[j] - t;
3790
+ r[j] = r[j] + t;
3791
+ }
3792
+ }
3793
+ }
3794
+ return r;
3795
+ }
3796
+ function nttFqMul(a, b) {
3797
+ return byteopsMontgomeryReduce(a * b);
3798
+ }
3799
+ function reduce(r) {
3800
+ for (let i = 0; i < N; i++) {
3801
+ r[i] = barrett(r[i]);
3802
+ }
3803
+ return r;
3804
+ }
3805
+ function barrett(a) {
3806
+ const v = ((1 << 24) + Q / 2) / Q;
3807
+ let t = v * a >> 24;
3808
+ t = t * Q;
3809
+ return a - t;
3810
+ }
3811
+ function byteopsMontgomeryReduce(a) {
3812
+ const u = int16(int32(a) * Q_INV);
3813
+ let t = u * Q;
3814
+ t = a - t;
3815
+ t >>= 16;
3816
+ return int16(t);
3817
+ }
3818
+ function polyToMont(r) {
3819
+ const f = 1353;
3820
+ for (let i = 0; i < N; i++) {
3821
+ r[i] = byteopsMontgomeryReduce(int32(r[i]) * int32(f));
3822
+ }
3823
+ return r;
3824
+ }
3825
+ function multiply(a, b) {
3826
+ let r = polyBaseMulMontgomery(a[0], b[0]);
3827
+ let t;
3828
+ for (let i = 1; i < a.length; i++) {
3829
+ t = polyBaseMulMontgomery(a[i], b[i]);
3830
+ r = add(r, t);
3831
+ }
3832
+ return reduce(r);
3833
+ }
3834
+ function polyBaseMulMontgomery(a, b) {
3835
+ let rx, ry;
3836
+ for (let i = 0; i < N / 4; i++) {
3837
+ rx = nttBaseMul(a[4 * i + 0], a[4 * i + 1], b[4 * i + 0], b[4 * i + 1], NTT_ZETAS[64 + i]);
3838
+ ry = nttBaseMul(a[4 * i + 2], a[4 * i + 3], b[4 * i + 2], b[4 * i + 3], -NTT_ZETAS[64 + i]);
3839
+ a[4 * i + 0] = rx[0];
3840
+ a[4 * i + 1] = rx[1];
3841
+ a[4 * i + 2] = ry[0];
3842
+ a[4 * i + 3] = ry[1];
3843
+ }
3844
+ return a;
3845
+ }
3846
+ function nttBaseMul(a0, a1, b0, b1, zeta) {
3847
+ const r = new Array(2);
3848
+ r[0] = nttFqMul(a1, b1);
3849
+ r[0] = nttFqMul(r[0], zeta);
3850
+ r[0] += nttFqMul(a0, b0);
3851
+ r[1] = nttFqMul(a0, b1);
3852
+ r[1] += nttFqMul(a1, b0);
3853
+ return r;
3854
+ }
3855
+ function add(a, b) {
3856
+ const c = new Array(384);
3857
+ for (let i = 0; i < N; i++) {
3858
+ c[i] = a[i] + b[i];
3859
+ }
3860
+ return c;
3861
+ }
3862
+ function subtract(a, b) {
3863
+ for (let i = 0; i < N; i++) {
3864
+ a[i] -= b[i];
3865
+ }
3866
+ return a;
3867
+ }
3868
+ function nttInverse(r) {
3869
+ let j = 0;
3870
+ for (let k = 0, l = 2; l <= 128; l <<= 1) {
3871
+ for (let start = 0; start < 256; start = j + l) {
3872
+ const zeta = NTT_ZETAS_INV[k];
3873
+ k = k + 1;
3874
+ for (j = start; j < start + l; j++) {
3875
+ const t = r[j];
3876
+ r[j] = barrett(t + r[j + l]);
3877
+ r[j + l] = t - r[j + l];
3878
+ r[j + l] = nttFqMul(zeta, r[j + l]);
3879
+ }
3880
+ }
3881
+ }
3882
+ for (j = 0; j < 256; j++) {
3883
+ r[j] = nttFqMul(r[j], NTT_ZETAS_INV[127]);
3884
+ }
3885
+ return r;
3886
+ }
3887
+ function subtractQ(r) {
3888
+ for (let i = 0; i < N; i++) {
3889
+ r[i] -= Q;
3890
+ r[i] += r[i] >> 31 & Q;
3891
+ }
3892
+ return r;
3893
+ }
3894
+
3895
+ // node_modules/mlkem/esm/src/mlKem768.js
3896
+ var MlKem768 = class extends MlKemBase {
3897
+ constructor() {
3898
+ super();
3899
+ Object.defineProperty(this, "_k", {
3900
+ enumerable: true,
3901
+ configurable: true,
3902
+ writable: true,
3903
+ value: 3
3904
+ });
3905
+ Object.defineProperty(this, "_du", {
3906
+ enumerable: true,
3907
+ configurable: true,
3908
+ writable: true,
3909
+ value: 10
3910
+ });
3911
+ Object.defineProperty(this, "_dv", {
3912
+ enumerable: true,
3913
+ configurable: true,
3914
+ writable: true,
3915
+ value: 4
3916
+ });
3917
+ Object.defineProperty(this, "_eta1", {
3918
+ enumerable: true,
3919
+ configurable: true,
3920
+ writable: true,
3921
+ value: 2
3922
+ });
3923
+ Object.defineProperty(this, "_eta2", {
3924
+ enumerable: true,
3925
+ configurable: true,
3926
+ writable: true,
3927
+ value: 2
3928
+ });
3929
+ this._skSize = 12 * this._k * N / 8;
3930
+ this._pkSize = this._skSize + 32;
3931
+ this._compressedUSize = this._k * this._du * N / 8;
3932
+ this._compressedVSize = this._dv * N / 8;
3933
+ }
3934
+ };
3935
+
3936
+ // src/index.ts
2340
3937
  async function sha256(data) {
2341
3938
  if (typeof globalThis.crypto?.subtle !== "undefined") {
2342
3939
  const encoder = new TextEncoder();
@@ -2409,6 +4006,9 @@ var PROTO_MARKER = 86;
2409
4006
  var FLAG_PADDED = 1;
2410
4007
  var FLAG_SEALED = 2;
2411
4008
  var FLAG_RATCHET = 4;
4009
+ var FLAG_PQ = 8;
4010
+ var FLAG_DH_RATCHET = 16;
4011
+ var FLAG_DENIABLE = 32;
2412
4012
  function makeProtoHeader(flags, ratchetStep2) {
2413
4013
  return new Uint8Array([PROTO_MARKER, flags, ratchetStep2 >> 8 & 255, ratchetStep2 & 255]);
2414
4014
  }
@@ -2420,6 +4020,30 @@ function parseProtoHeader(data) {
2420
4020
  content: data.slice(4)
2421
4021
  };
2422
4022
  }
4023
+ async function kdfRK(rootKey, dhOutput) {
4024
+ const combined = new Uint8Array(rootKey.length + dhOutput.length);
4025
+ combined.set(rootKey, 0);
4026
+ combined.set(dhOutput, rootKey.length);
4027
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
4028
+ const prk2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", combined.buffer));
4029
+ const newRootKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array([...prk2, 1]).buffer));
4030
+ const newChainKey2 = new Uint8Array(await globalThis.crypto.subtle.digest("SHA-256", new Uint8Array([...prk2, 2]).buffer));
4031
+ return { newRootKey: newRootKey2, newChainKey: newChainKey2 };
4032
+ }
4033
+ const { createHash } = await import("crypto");
4034
+ const prk = new Uint8Array(createHash("sha256").update(Buffer.from(combined)).digest());
4035
+ const newRootKey = new Uint8Array(createHash("sha256").update(Buffer.from([...prk, 1])).digest());
4036
+ const newChainKey = new Uint8Array(createHash("sha256").update(Buffer.from([...prk, 2])).digest());
4037
+ return { newRootKey, newChainKey };
4038
+ }
4039
+ async function hmacSha256(key, data) {
4040
+ if (typeof globalThis.crypto?.subtle !== "undefined") {
4041
+ const cryptoKey = await globalThis.crypto.subtle.importKey("raw", key.buffer, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
4042
+ return new Uint8Array(await globalThis.crypto.subtle.sign("HMAC", cryptoKey, data.buffer));
4043
+ }
4044
+ const { createHmac } = await import("crypto");
4045
+ return new Uint8Array(createHmac("sha256", Buffer.from(key)).update(Buffer.from(data)).digest());
4046
+ }
2423
4047
  var MAX_SKIP = 200;
2424
4048
  var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
2425
4049
  function toBase58(bytes) {
@@ -2431,14 +4055,16 @@ function toBase58(bytes) {
2431
4055
  num = num / 58n;
2432
4056
  result = BASE58_ALPHABET[Number(remainder)] + result;
2433
4057
  }
2434
- for (const byte of bytes) {
2435
- if (byte === 0) result = "1" + result;
4058
+ for (const byte2 of bytes) {
4059
+ if (byte2 === 0) result = "1" + result;
2436
4060
  else break;
2437
4061
  }
2438
4062
  return result || "1";
2439
4063
  }
2440
4064
  var VoidlyAgent = class _VoidlyAgent {
2441
4065
  constructor(identity, config) {
4066
+ this._signedPrekey = null;
4067
+ this._signedPrekeyId = 0;
2442
4068
  this._pinnedDids = /* @__PURE__ */ new Set();
2443
4069
  this._listeners = /* @__PURE__ */ new Set();
2444
4070
  this._conversations = /* @__PURE__ */ new Map();
@@ -2459,6 +4085,13 @@ var VoidlyAgent = class _VoidlyAgent {
2459
4085
  this.sealedSender = config?.sealedSender || false;
2460
4086
  this.requireSignatures = config?.requireSignatures || false;
2461
4087
  this.timeout = config?.timeout ?? 3e4;
4088
+ this.postQuantum = config?.postQuantum !== false;
4089
+ this.deniable = config?.deniable || false;
4090
+ this.doubleRatchet = config?.doubleRatchet !== false;
4091
+ this.jitterMs = config?.jitterMs || 0;
4092
+ this.longPoll = config?.longPoll !== false;
4093
+ this.mlkemPublicKey = identity.mlkemPublicKey || null;
4094
+ this.mlkemSecretKey = identity.mlkemSecretKey || null;
2462
4095
  }
2463
4096
  // ─── Factory Methods ────────────────────────────────────────────────────────
2464
4097
  /**
@@ -2469,15 +4102,33 @@ var VoidlyAgent = class _VoidlyAgent {
2469
4102
  const baseUrl = config?.baseUrl || "https://api.voidly.ai";
2470
4103
  const signingKeyPair = import_tweetnacl.default.sign.keyPair();
2471
4104
  const encryptionKeyPair = import_tweetnacl.default.box.keyPair();
4105
+ const usePQ = config?.postQuantum !== false;
4106
+ let mlkemPk;
4107
+ let mlkemSk;
4108
+ if (usePQ) {
4109
+ const kem = new MlKem768();
4110
+ [mlkemPk, mlkemSk] = await kem.generateKeyPair();
4111
+ }
4112
+ const signedPrekeyPair = import_tweetnacl.default.box.keyPair();
4113
+ const signedPrekeyId = 1;
4114
+ const prekeySignature = import_tweetnacl.default.sign.detached(signedPrekeyPair.publicKey, signingKeyPair.secretKey);
4115
+ const regBody = {
4116
+ name: options.name,
4117
+ capabilities: options.capabilities,
4118
+ signing_public_key: (0, import_tweetnacl_util.encodeBase64)(signingKeyPair.publicKey),
4119
+ encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(encryptionKeyPair.publicKey),
4120
+ // X3DH signed prekey
4121
+ signed_prekey_public: (0, import_tweetnacl_util.encodeBase64)(signedPrekeyPair.publicKey),
4122
+ signed_prekey_signature: (0, import_tweetnacl_util.encodeBase64)(prekeySignature),
4123
+ signed_prekey_id: signedPrekeyId
4124
+ };
4125
+ if (mlkemPk) {
4126
+ regBody.mlkem_public_key = (0, import_tweetnacl_util.encodeBase64)(mlkemPk);
4127
+ }
2472
4128
  const res = await fetch(`${baseUrl}/v1/agent/register`, {
2473
4129
  method: "POST",
2474
4130
  headers: { "Content-Type": "application/json" },
2475
- body: JSON.stringify({
2476
- name: options.name,
2477
- capabilities: options.capabilities,
2478
- signing_public_key: (0, import_tweetnacl_util.encodeBase64)(signingKeyPair.publicKey),
2479
- encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(encryptionKeyPair.publicKey)
2480
- })
4131
+ body: JSON.stringify(regBody)
2481
4132
  });
2482
4133
  if (!res.ok) {
2483
4134
  const err = await res.json().catch(() => ({}));
@@ -2485,12 +4136,17 @@ var VoidlyAgent = class _VoidlyAgent {
2485
4136
  throw new Error(`Registration failed: ${errMsg}`);
2486
4137
  }
2487
4138
  const data = await res.json();
2488
- return new _VoidlyAgent({
4139
+ const agent = new _VoidlyAgent({
2489
4140
  did: data.did,
2490
4141
  apiKey: data.api_key,
2491
4142
  signingKeyPair,
2492
- encryptionKeyPair
4143
+ encryptionKeyPair,
4144
+ mlkemPublicKey: mlkemPk,
4145
+ mlkemSecretKey: mlkemSk
2493
4146
  }, config);
4147
+ agent._signedPrekey = signedPrekeyPair;
4148
+ agent._signedPrekeyId = signedPrekeyId;
4149
+ return agent;
2494
4150
  }
2495
4151
  /**
2496
4152
  * Restore an agent from saved credentials.
@@ -2520,28 +4176,124 @@ var VoidlyAgent = class _VoidlyAgent {
2520
4176
  if (encryptionSecret.length !== 32) {
2521
4177
  throw new Error(`Invalid credentials: encryption key must be 32 bytes, got ${encryptionSecret.length}`);
2522
4178
  }
2523
- return new _VoidlyAgent({
4179
+ let mlkemPk;
4180
+ let mlkemSk;
4181
+ if (creds.mlkemPublicKey && creds.mlkemSecretKey) {
4182
+ try {
4183
+ mlkemPk = (0, import_tweetnacl_util.decodeBase64)(creds.mlkemPublicKey);
4184
+ mlkemSk = (0, import_tweetnacl_util.decodeBase64)(creds.mlkemSecretKey);
4185
+ if (mlkemPk.length !== 1184 || mlkemSk.length !== 2400) {
4186
+ mlkemPk = void 0;
4187
+ mlkemSk = void 0;
4188
+ }
4189
+ } catch {
4190
+ }
4191
+ }
4192
+ const agent = new _VoidlyAgent({
2524
4193
  did: creds.did,
2525
4194
  apiKey: creds.apiKey,
2526
4195
  signingKeyPair: import_tweetnacl.default.sign.keyPair.fromSecretKey(signingSecret),
2527
4196
  encryptionKeyPair: {
2528
4197
  publicKey: import_tweetnacl.default.box.keyPair.fromSecretKey(encryptionSecret).publicKey,
2529
4198
  secretKey: encryptionSecret
2530
- }
4199
+ },
4200
+ mlkemPublicKey: mlkemPk,
4201
+ mlkemSecretKey: mlkemSk
2531
4202
  }, config);
4203
+ if (creds.ratchetStates) {
4204
+ for (const [pairId, rs] of Object.entries(creds.ratchetStates)) {
4205
+ try {
4206
+ const sendChainKey = (0, import_tweetnacl_util.decodeBase64)(rs.sendChainKey);
4207
+ const recvChainKey = (0, import_tweetnacl_util.decodeBase64)(rs.recvChainKey);
4208
+ if (sendChainKey.length !== 32 || recvChainKey.length !== 32) continue;
4209
+ const state = {
4210
+ sendChainKey,
4211
+ sendStep: rs.sendStep || 0,
4212
+ recvChainKey,
4213
+ recvStep: rs.recvStep || 0,
4214
+ skippedKeys: /* @__PURE__ */ new Map()
4215
+ };
4216
+ if (rs.rootKey) {
4217
+ try {
4218
+ state.rootKey = (0, import_tweetnacl_util.decodeBase64)(rs.rootKey);
4219
+ if (state.rootKey.length !== 32) state.rootKey = void 0;
4220
+ } catch {
4221
+ }
4222
+ }
4223
+ if (rs.dhSendSecretKey && rs.dhSendPublicKey) {
4224
+ try {
4225
+ const sk = (0, import_tweetnacl_util.decodeBase64)(rs.dhSendSecretKey);
4226
+ const pk = (0, import_tweetnacl_util.decodeBase64)(rs.dhSendPublicKey);
4227
+ if (sk.length === 32 && pk.length === 32) {
4228
+ state.dhSendKeyPair = { publicKey: pk, secretKey: sk };
4229
+ }
4230
+ } catch {
4231
+ }
4232
+ }
4233
+ if (rs.dhRecvPubKey) {
4234
+ try {
4235
+ const pk = (0, import_tweetnacl_util.decodeBase64)(rs.dhRecvPubKey);
4236
+ if (pk.length === 32) state.dhRecvPubKey = pk;
4237
+ } catch {
4238
+ }
4239
+ }
4240
+ if (rs.prevSendStep !== void 0) state.prevSendStep = rs.prevSendStep;
4241
+ state.dhSkippedKeys = /* @__PURE__ */ new Map();
4242
+ agent._ratchetStates.set(pairId, state);
4243
+ } catch {
4244
+ }
4245
+ }
4246
+ }
4247
+ if (creds.signedPrekeySecret && creds.signedPrekeyPublic) {
4248
+ try {
4249
+ const sk = (0, import_tweetnacl_util.decodeBase64)(creds.signedPrekeySecret);
4250
+ const pk = (0, import_tweetnacl_util.decodeBase64)(creds.signedPrekeyPublic);
4251
+ if (sk.length === 32 && pk.length === 32) {
4252
+ agent._signedPrekey = { publicKey: pk, secretKey: sk };
4253
+ agent._signedPrekeyId = creds.signedPrekeyId || 0;
4254
+ }
4255
+ } catch {
4256
+ }
4257
+ }
4258
+ return agent;
2532
4259
  }
2533
4260
  /**
2534
4261
  * Export credentials for persistence.
2535
4262
  * Store these securely — they contain private keys.
2536
4263
  */
2537
4264
  exportCredentials() {
4265
+ const ratchetStates = {};
4266
+ for (const [pairId, state] of this._ratchetStates) {
4267
+ const rs = {
4268
+ sendChainKey: (0, import_tweetnacl_util.encodeBase64)(state.sendChainKey),
4269
+ sendStep: state.sendStep,
4270
+ recvChainKey: (0, import_tweetnacl_util.encodeBase64)(state.recvChainKey),
4271
+ recvStep: state.recvStep
4272
+ };
4273
+ if (state.rootKey) rs.rootKey = (0, import_tweetnacl_util.encodeBase64)(state.rootKey);
4274
+ if (state.dhSendKeyPair) {
4275
+ rs.dhSendSecretKey = (0, import_tweetnacl_util.encodeBase64)(state.dhSendKeyPair.secretKey);
4276
+ rs.dhSendPublicKey = (0, import_tweetnacl_util.encodeBase64)(state.dhSendKeyPair.publicKey);
4277
+ }
4278
+ if (state.dhRecvPubKey) rs.dhRecvPubKey = (0, import_tweetnacl_util.encodeBase64)(state.dhRecvPubKey);
4279
+ if (state.prevSendStep !== void 0) rs.prevSendStep = state.prevSendStep;
4280
+ ratchetStates[pairId] = rs;
4281
+ }
2538
4282
  return {
2539
4283
  did: this.did,
2540
4284
  apiKey: this.apiKey,
2541
4285
  signingSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.signingKeyPair.secretKey),
2542
4286
  encryptionSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.secretKey),
2543
4287
  signingPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.signingKeyPair.publicKey),
2544
- encryptionPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.publicKey)
4288
+ encryptionPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.encryptionKeyPair.publicKey),
4289
+ ...Object.keys(ratchetStates).length > 0 ? { ratchetStates } : {},
4290
+ ...this.mlkemPublicKey ? { mlkemPublicKey: (0, import_tweetnacl_util.encodeBase64)(this.mlkemPublicKey) } : {},
4291
+ ...this.mlkemSecretKey ? { mlkemSecretKey: (0, import_tweetnacl_util.encodeBase64)(this.mlkemSecretKey) } : {},
4292
+ ...this._signedPrekey ? {
4293
+ signedPrekeySecret: (0, import_tweetnacl_util.encodeBase64)(this._signedPrekey.secretKey),
4294
+ signedPrekeyPublic: (0, import_tweetnacl_util.encodeBase64)(this._signedPrekey.publicKey),
4295
+ signedPrekeyId: this._signedPrekeyId
4296
+ } : {}
2545
4297
  };
2546
4298
  }
2547
4299
  /**
@@ -2601,17 +4353,58 @@ var VoidlyAgent = class _VoidlyAgent {
2601
4353
  }
2602
4354
  const pairId = `${this.did}:${recipientDid}`;
2603
4355
  let state = this._ratchetStates.get(pairId);
4356
+ let pqCiphertext = null;
4357
+ let dhRatchetPub = null;
2604
4358
  if (!state) {
2605
- const sharedSecret = import_tweetnacl.default.box.before(recipientPubKey, this.encryptionKeyPair.secretKey);
2606
- state = {
2607
- sendChainKey: sharedSecret,
2608
- sendStep: 0,
2609
- recvChainKey: sharedSecret,
2610
- // Will be synced on first receive
2611
- recvStep: 0,
2612
- skippedKeys: /* @__PURE__ */ new Map()
2613
- };
4359
+ const x25519Shared = import_tweetnacl.default.box.before(recipientPubKey, this.encryptionKeyPair.secretKey);
4360
+ let initialKey;
4361
+ if (this.postQuantum && profile.mlkem_public_key) {
4362
+ try {
4363
+ const recipientPqPk = (0, import_tweetnacl_util.decodeBase64)(profile.mlkem_public_key);
4364
+ const kem = new MlKem768();
4365
+ const [ct, pqShared] = await kem.encap(recipientPqPk);
4366
+ pqCiphertext = ct;
4367
+ const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4368
+ combined.set(x25519Shared, 0);
4369
+ combined.set(pqShared, x25519Shared.length);
4370
+ initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4371
+ } catch {
4372
+ initialKey = x25519Shared;
4373
+ }
4374
+ } else {
4375
+ initialKey = x25519Shared;
4376
+ }
4377
+ if (this.doubleRatchet) {
4378
+ const dhSendKeyPair = import_tweetnacl.default.box.keyPair();
4379
+ const dhOutput = import_tweetnacl.default.box.before(recipientPubKey, dhSendKeyPair.secretKey);
4380
+ const { newRootKey, newChainKey } = await kdfRK(initialKey, dhOutput);
4381
+ dhRatchetPub = dhSendKeyPair.publicKey;
4382
+ state = {
4383
+ sendChainKey: newChainKey,
4384
+ sendStep: 0,
4385
+ recvChainKey: initialKey,
4386
+ // Will be updated on first receive
4387
+ recvStep: 0,
4388
+ skippedKeys: /* @__PURE__ */ new Map(),
4389
+ // Double Ratchet state
4390
+ rootKey: newRootKey,
4391
+ dhSendKeyPair,
4392
+ dhRecvPubKey: void 0,
4393
+ prevSendStep: 0,
4394
+ dhSkippedKeys: /* @__PURE__ */ new Map()
4395
+ };
4396
+ } else {
4397
+ state = {
4398
+ sendChainKey: initialKey,
4399
+ sendStep: 0,
4400
+ recvChainKey: initialKey,
4401
+ recvStep: 0,
4402
+ skippedKeys: /* @__PURE__ */ new Map()
4403
+ };
4404
+ }
2614
4405
  this._ratchetStates.set(pairId, state);
4406
+ } else if (state.rootKey && state.dhSendKeyPair) {
4407
+ dhRatchetPub = state.dhSendKeyPair.publicKey;
2615
4408
  }
2616
4409
  const { nextChainKey, messageKey } = await ratchetStep(state.sendChainKey);
2617
4410
  state.sendChainKey = nextChainKey;
@@ -2620,6 +4413,9 @@ var VoidlyAgent = class _VoidlyAgent {
2620
4413
  let flags = FLAG_RATCHET;
2621
4414
  if (usePadding) flags |= FLAG_PADDED;
2622
4415
  if (useSealed) flags |= FLAG_SEALED;
4416
+ if (pqCiphertext) flags |= FLAG_PQ;
4417
+ if (dhRatchetPub) flags |= FLAG_DH_RATCHET;
4418
+ if (this.deniable) flags |= FLAG_DENIABLE;
2623
4419
  const header = makeProtoHeader(flags, currentStep);
2624
4420
  const messageBytes = new Uint8Array(header.length + contentBytes.length);
2625
4421
  messageBytes.set(header, 0);
@@ -2629,15 +4425,33 @@ var VoidlyAgent = class _VoidlyAgent {
2629
4425
  if (!ciphertext) {
2630
4426
  throw new Error("Encryption failed");
2631
4427
  }
2632
- const envelopeData = JSON.stringify({
4428
+ if (this.jitterMs > 0) {
4429
+ const jitter = Math.random() * this.jitterMs;
4430
+ await new Promise((r) => setTimeout(r, jitter));
4431
+ }
4432
+ const envelopeObj = {
2633
4433
  from: this.did,
2634
4434
  to: recipientDid,
2635
4435
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2636
4436
  nonce: (0, import_tweetnacl_util.encodeBase64)(nonce),
2637
4437
  ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(ciphertext)),
2638
4438
  ratchet_step: currentStep
2639
- });
2640
- const signature = import_tweetnacl.default.sign.detached((0, import_tweetnacl_util.decodeUTF8)(envelopeData), this.signingKeyPair.secretKey);
4439
+ };
4440
+ if (pqCiphertext) {
4441
+ envelopeObj.pq_ciphertext = (0, import_tweetnacl_util.encodeBase64)(pqCiphertext);
4442
+ }
4443
+ if (dhRatchetPub) {
4444
+ envelopeObj.dh_ratchet_key = (0, import_tweetnacl_util.encodeBase64)(dhRatchetPub);
4445
+ envelopeObj.pn = state.prevSendStep || 0;
4446
+ }
4447
+ const envelopeData = JSON.stringify(envelopeObj);
4448
+ let signature;
4449
+ if (this.deniable) {
4450
+ const sharedSecret = import_tweetnacl.default.box.before(recipientPubKey, this.encryptionKeyPair.secretKey);
4451
+ signature = await hmacSha256(sharedSecret, (0, import_tweetnacl_util.decodeUTF8)(envelopeData));
4452
+ } else {
4453
+ signature = import_tweetnacl.default.sign.detached((0, import_tweetnacl_util.decodeUTF8)(envelopeData), this.signingKeyPair.secretKey);
4454
+ }
2641
4455
  const payload = {
2642
4456
  to: recipientDid,
2643
4457
  ciphertext: (0, import_tweetnacl_util.encodeBase64)(ciphertext),
@@ -2700,7 +4514,7 @@ var VoidlyAgent = class _VoidlyAgent {
2700
4514
  if (options.contentType) params.set("content_type", options.contentType);
2701
4515
  if (options.messageType) params.set("message_type", options.messageType);
2702
4516
  if (options.unreadOnly) params.set("unread", "true");
2703
- const res = await fetch(`${this.baseUrl}/v1/agent/receive/raw?${params}`, {
4517
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/receive/raw?${params}`, {
2704
4518
  headers: { "X-Agent-Key": this.apiKey }
2705
4519
  });
2706
4520
  if (!res.ok) {
@@ -2717,12 +4531,25 @@ var VoidlyAgent = class _VoidlyAgent {
2717
4531
  const nonce = (0, import_tweetnacl_util.decodeBase64)(msg.nonce);
2718
4532
  let rawPlaintext = null;
2719
4533
  let envelopeRatchetStep = 0;
4534
+ let envelopePqCiphertext = null;
4535
+ let envelopeDhRatchetKey = null;
4536
+ let envelopePn = 0;
4537
+ let envelopeDeniable = false;
2720
4538
  if (msg.envelope) {
2721
4539
  try {
2722
4540
  const env = JSON.parse(msg.envelope);
2723
4541
  if (typeof env.ratchet_step === "number") {
2724
4542
  envelopeRatchetStep = env.ratchet_step;
2725
4543
  }
4544
+ if (typeof env.pq_ciphertext === "string") {
4545
+ envelopePqCiphertext = env.pq_ciphertext;
4546
+ }
4547
+ if (typeof env.dh_ratchet_key === "string") {
4548
+ envelopeDhRatchetKey = env.dh_ratchet_key;
4549
+ }
4550
+ if (typeof env.pn === "number") {
4551
+ envelopePn = env.pn;
4552
+ }
2726
4553
  } catch {
2727
4554
  }
2728
4555
  }
@@ -2730,20 +4557,90 @@ var VoidlyAgent = class _VoidlyAgent {
2730
4557
  const pairId = `${msg.from}:${this.did}`;
2731
4558
  let state = this._ratchetStates.get(pairId);
2732
4559
  if (!state) {
2733
- const sharedSecret = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
2734
- state = {
2735
- sendChainKey: sharedSecret,
2736
- // Our sending chain to this peer
2737
- sendStep: 0,
2738
- recvChainKey: sharedSecret,
2739
- // Their sending chain (our receiving)
2740
- recvStep: 0,
2741
- skippedKeys: /* @__PURE__ */ new Map()
2742
- };
4560
+ const x25519Shared = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
4561
+ let initialKey;
4562
+ if (envelopePqCiphertext && this.mlkemSecretKey) {
4563
+ try {
4564
+ const pqCt = (0, import_tweetnacl_util.decodeBase64)(envelopePqCiphertext);
4565
+ const kem = new MlKem768();
4566
+ const pqShared = await kem.decap(pqCt, this.mlkemSecretKey);
4567
+ const combined = new Uint8Array(x25519Shared.length + pqShared.length);
4568
+ combined.set(x25519Shared, 0);
4569
+ combined.set(pqShared, x25519Shared.length);
4570
+ initialKey = new Uint8Array(await crypto.subtle.digest("SHA-256", combined));
4571
+ } catch {
4572
+ initialKey = x25519Shared;
4573
+ }
4574
+ } else {
4575
+ initialKey = x25519Shared;
4576
+ }
4577
+ if (envelopeDhRatchetKey && this.doubleRatchet) {
4578
+ const senderDhPub = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
4579
+ const dhOutput = import_tweetnacl.default.box.before(senderDhPub, this.encryptionKeyPair.secretKey);
4580
+ const { newRootKey, newChainKey } = await kdfRK(initialKey, dhOutput);
4581
+ state = {
4582
+ sendChainKey: initialKey,
4583
+ sendStep: 0,
4584
+ recvChainKey: newChainKey,
4585
+ recvStep: 0,
4586
+ skippedKeys: /* @__PURE__ */ new Map(),
4587
+ rootKey: newRootKey,
4588
+ dhSendKeyPair: void 0,
4589
+ dhRecvPubKey: senderDhPub,
4590
+ prevSendStep: 0,
4591
+ dhSkippedKeys: /* @__PURE__ */ new Map()
4592
+ };
4593
+ } else {
4594
+ state = {
4595
+ sendChainKey: initialKey,
4596
+ sendStep: 0,
4597
+ recvChainKey: initialKey,
4598
+ recvStep: 0,
4599
+ skippedKeys: /* @__PURE__ */ new Map()
4600
+ };
4601
+ }
2743
4602
  this._ratchetStates.set(pairId, state);
4603
+ } else if (envelopeDhRatchetKey && state.rootKey) {
4604
+ const senderDhPub = (0, import_tweetnacl_util.decodeBase64)(envelopeDhRatchetKey);
4605
+ const currentDhRecv = state.dhRecvPubKey;
4606
+ if (!currentDhRecv || (0, import_tweetnacl_util.encodeBase64)(senderDhPub) !== (0, import_tweetnacl_util.encodeBase64)(currentDhRecv)) {
4607
+ if (envelopePn > state.recvStep) {
4608
+ let ck = state.recvChainKey;
4609
+ for (let i = state.recvStep + 1; i <= envelopePn && i - state.recvStep <= MAX_SKIP; i++) {
4610
+ const { nextChainKey, messageKey: skippedMk } = await ratchetStep(ck);
4611
+ const skipKey = `${currentDhRecv ? (0, import_tweetnacl_util.encodeBase64)(currentDhRecv) : "init"}:${i}`;
4612
+ if (!state.dhSkippedKeys) state.dhSkippedKeys = /* @__PURE__ */ new Map();
4613
+ state.dhSkippedKeys.set(skipKey, skippedMk);
4614
+ ck = nextChainKey;
4615
+ if (state.dhSkippedKeys.size > MAX_SKIP) {
4616
+ const oldest = state.dhSkippedKeys.keys().next().value;
4617
+ if (oldest !== void 0) state.dhSkippedKeys.delete(oldest);
4618
+ }
4619
+ }
4620
+ }
4621
+ state.dhRecvPubKey = senderDhPub;
4622
+ const myKey = state.dhSendKeyPair || this.encryptionKeyPair;
4623
+ const dhOutput1 = import_tweetnacl.default.box.before(senderDhPub, myKey.secretKey);
4624
+ const kdf1 = await kdfRK(state.rootKey, dhOutput1);
4625
+ state.rootKey = kdf1.newRootKey;
4626
+ state.recvChainKey = kdf1.newChainKey;
4627
+ state.recvStep = 0;
4628
+ state.prevSendStep = state.sendStep;
4629
+ state.dhSendKeyPair = import_tweetnacl.default.box.keyPair();
4630
+ state.sendStep = 0;
4631
+ const dhOutput2 = import_tweetnacl.default.box.before(senderDhPub, state.dhSendKeyPair.secretKey);
4632
+ const kdf2 = await kdfRK(state.rootKey, dhOutput2);
4633
+ state.rootKey = kdf2.newRootKey;
4634
+ state.sendChainKey = kdf2.newChainKey;
4635
+ }
2744
4636
  }
2745
4637
  const targetStep = envelopeRatchetStep;
2746
- if (state.skippedKeys.has(targetStep)) {
4638
+ const dhSkipKey = envelopeDhRatchetKey ? `${envelopeDhRatchetKey}:${targetStep}` : `init:${targetStep}`;
4639
+ if (state.dhSkippedKeys?.has(dhSkipKey)) {
4640
+ const mk = state.dhSkippedKeys.get(dhSkipKey);
4641
+ rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, mk);
4642
+ state.dhSkippedKeys.delete(dhSkipKey);
4643
+ } else if (state.skippedKeys.has(targetStep)) {
2747
4644
  const mk = state.skippedKeys.get(targetStep);
2748
4645
  rawPlaintext = import_tweetnacl.default.secretbox.open(ciphertext, nonce, mk);
2749
4646
  state.skippedKeys.delete(targetStep);
@@ -2806,7 +4703,6 @@ var VoidlyAgent = class _VoidlyAgent {
2806
4703
  }
2807
4704
  let signatureValid = false;
2808
4705
  try {
2809
- const senderSignPub = (0, import_tweetnacl_util.decodeBase64)(msg.sender_signing_key);
2810
4706
  const signatureBytes = (0, import_tweetnacl_util.decodeBase64)(msg.signature);
2811
4707
  const envelopeStr = msg.envelope || JSON.stringify({
2812
4708
  from: senderDid,
@@ -2815,11 +4711,22 @@ var VoidlyAgent = class _VoidlyAgent {
2815
4711
  nonce: msg.nonce,
2816
4712
  ciphertext_hash: await sha256(msg.ciphertext)
2817
4713
  });
2818
- signatureValid = import_tweetnacl.default.sign.detached.verify(
2819
- (0, import_tweetnacl_util.decodeUTF8)(envelopeStr),
2820
- signatureBytes,
2821
- senderSignPub
2822
- );
4714
+ if (signatureBytes.length === 32) {
4715
+ const sharedSecret = import_tweetnacl.default.box.before(senderEncPub, this.encryptionKeyPair.secretKey);
4716
+ const expectedHmac = await hmacSha256(sharedSecret, (0, import_tweetnacl_util.decodeUTF8)(envelopeStr));
4717
+ if (expectedHmac.length === signatureBytes.length) {
4718
+ let diff = 0;
4719
+ for (let i = 0; i < expectedHmac.length; i++) diff |= expectedHmac[i] ^ signatureBytes[i];
4720
+ signatureValid = diff === 0;
4721
+ }
4722
+ } else {
4723
+ const senderSignPub = (0, import_tweetnacl_util.decodeBase64)(msg.sender_signing_key);
4724
+ signatureValid = import_tweetnacl.default.sign.detached.verify(
4725
+ (0, import_tweetnacl_util.decodeUTF8)(envelopeStr),
4726
+ signatureBytes,
4727
+ senderSignPub
4728
+ );
4729
+ }
2823
4730
  } catch {
2824
4731
  signatureValid = false;
2825
4732
  }
@@ -2856,7 +4763,7 @@ var VoidlyAgent = class _VoidlyAgent {
2856
4763
  * Delete a message by ID (must be sender or recipient).
2857
4764
  */
2858
4765
  async deleteMessage(messageId) {
2859
- const res = await fetch(`${this.baseUrl}/v1/agent/messages/${messageId}`, {
4766
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/${messageId}`, {
2860
4767
  method: "DELETE",
2861
4768
  headers: { "X-Agent-Key": this.apiKey }
2862
4769
  });
@@ -2867,7 +4774,7 @@ var VoidlyAgent = class _VoidlyAgent {
2867
4774
  * Get this agent's own profile.
2868
4775
  */
2869
4776
  async getProfile() {
2870
- const res = await fetch(`${this.baseUrl}/v1/agent/profile`, {
4777
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/profile`, {
2871
4778
  headers: { "X-Agent-Key": this.apiKey }
2872
4779
  });
2873
4780
  if (!res.ok) {
@@ -2879,7 +4786,7 @@ var VoidlyAgent = class _VoidlyAgent {
2879
4786
  * Update this agent's profile (name, capabilities, metadata).
2880
4787
  */
2881
4788
  async updateProfile(updates) {
2882
- const res = await fetch(`${this.baseUrl}/v1/agent/profile`, {
4789
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/profile`, {
2883
4790
  method: "PATCH",
2884
4791
  headers: {
2885
4792
  "Content-Type": "application/json",
@@ -2901,7 +4808,7 @@ var VoidlyAgent = class _VoidlyAgent {
2901
4808
  if (cached && Date.now() - cached.cachedAt < 3e5) {
2902
4809
  return cached.profile;
2903
4810
  }
2904
- const res = await fetch(`${this.baseUrl}/v1/agent/identity/${did}`);
4811
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${did}`);
2905
4812
  if (!res.ok) return null;
2906
4813
  const profile = await res.json();
2907
4814
  this._identityCache.set(did, { profile, cachedAt: Date.now() });
@@ -2919,7 +4826,7 @@ var VoidlyAgent = class _VoidlyAgent {
2919
4826
  if (options.query) params.set("query", options.query);
2920
4827
  if (options.capability) params.set("capability", options.capability);
2921
4828
  if (options.limit) params.set("limit", String(options.limit));
2922
- const res = await fetch(`${this.baseUrl}/v1/agent/discover?${params}`);
4829
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/discover?${params}`);
2923
4830
  if (!res.ok) return [];
2924
4831
  const data = await res.json();
2925
4832
  return data.agents;
@@ -2928,7 +4835,7 @@ var VoidlyAgent = class _VoidlyAgent {
2928
4835
  * Get relay network statistics.
2929
4836
  */
2930
4837
  async stats() {
2931
- const res = await fetch(`${this.baseUrl}/v1/agent/stats`);
4838
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/stats`);
2932
4839
  return await res.json();
2933
4840
  }
2934
4841
  // ─── Webhooks ──────────────────────────────────────────────────────────────
@@ -2937,7 +4844,7 @@ var VoidlyAgent = class _VoidlyAgent {
2937
4844
  * Instead of polling receive(), messages are POSTed to your URL with HMAC signatures.
2938
4845
  */
2939
4846
  async registerWebhook(webhookUrl, options = {}) {
2940
- const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
4847
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks`, {
2941
4848
  method: "POST",
2942
4849
  headers: {
2943
4850
  "Content-Type": "application/json",
@@ -2958,7 +4865,7 @@ var VoidlyAgent = class _VoidlyAgent {
2958
4865
  * List registered webhooks.
2959
4866
  */
2960
4867
  async listWebhooks() {
2961
- const res = await fetch(`${this.baseUrl}/v1/agent/webhooks`, {
4868
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks`, {
2962
4869
  headers: { "X-Agent-Key": this.apiKey }
2963
4870
  });
2964
4871
  if (!res.ok) return [];
@@ -2969,7 +4876,7 @@ var VoidlyAgent = class _VoidlyAgent {
2969
4876
  * Delete a webhook.
2970
4877
  */
2971
4878
  async deleteWebhook(webhookId) {
2972
- const res = await fetch(`${this.baseUrl}/v1/agent/webhooks/${webhookId}`, {
4879
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/webhooks/${webhookId}`, {
2973
4880
  method: "DELETE",
2974
4881
  headers: { "X-Agent-Key": this.apiKey }
2975
4882
  });
@@ -3013,22 +4920,35 @@ var VoidlyAgent = class _VoidlyAgent {
3013
4920
  async rotateKeys() {
3014
4921
  const newSigningKeyPair = import_tweetnacl.default.sign.keyPair();
3015
4922
  const newEncryptionKeyPair = import_tweetnacl.default.box.keyPair();
3016
- const res = await fetch(`${this.baseUrl}/v1/agent/rotate-keys`, {
4923
+ const newSignedPrekey = import_tweetnacl.default.box.keyPair();
4924
+ const newSignedPrekeyId = (this._signedPrekeyId || 0) + 1;
4925
+ const signedPrekeySignature = import_tweetnacl.default.sign.detached(newSignedPrekey.publicKey, newSigningKeyPair.secretKey);
4926
+ const body = {
4927
+ signing_public_key: (0, import_tweetnacl_util.encodeBase64)(newSigningKeyPair.publicKey),
4928
+ encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(newEncryptionKeyPair.publicKey),
4929
+ signed_prekey_public: (0, import_tweetnacl_util.encodeBase64)(newSignedPrekey.publicKey),
4930
+ signed_prekey_signature: (0, import_tweetnacl_util.encodeBase64)(signedPrekeySignature),
4931
+ signed_prekey_id: newSignedPrekeyId
4932
+ };
4933
+ if (this.postQuantum && this.mlkemPublicKey) {
4934
+ body.mlkem_public_key = this.mlkemPublicKey;
4935
+ }
4936
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/rotate-keys`, {
3017
4937
  method: "POST",
3018
4938
  headers: {
3019
4939
  "Content-Type": "application/json",
3020
4940
  "X-Agent-Key": this.apiKey
3021
4941
  },
3022
- body: JSON.stringify({
3023
- signing_public_key: (0, import_tweetnacl_util.encodeBase64)(newSigningKeyPair.publicKey),
3024
- encryption_public_key: (0, import_tweetnacl_util.encodeBase64)(newEncryptionKeyPair.publicKey)
3025
- })
4942
+ body: JSON.stringify(body)
3026
4943
  });
3027
4944
  if (!res.ok) {
3028
4945
  throw new Error("Key rotation failed");
3029
4946
  }
3030
4947
  this.signingKeyPair = newSigningKeyPair;
3031
4948
  this.encryptionKeyPair = newEncryptionKeyPair;
4949
+ this._signedPrekey = newSignedPrekey;
4950
+ this._signedPrekeyId = newSignedPrekeyId;
4951
+ await this.uploadPrekeys(10);
3032
4952
  }
3033
4953
  // ─── Channels (Encrypted AI Forum) ──────────────────────────────────────────
3034
4954
  /**
@@ -3036,7 +4956,7 @@ var VoidlyAgent = class _VoidlyAgent {
3036
4956
  * Only authenticated agents with did:voidly: identities can join and read.
3037
4957
  */
3038
4958
  async createChannel(options) {
3039
- const res = await fetch(`${this.baseUrl}/v1/agent/channels`, {
4959
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels`, {
3040
4960
  method: "POST",
3041
4961
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3042
4962
  body: JSON.stringify(options)
@@ -3056,7 +4976,7 @@ var VoidlyAgent = class _VoidlyAgent {
3056
4976
  if (options.query) params.set("q", options.query);
3057
4977
  if (options.mine) params.set("mine", "true");
3058
4978
  if (options.limit) params.set("limit", String(options.limit));
3059
- const res = await fetch(`${this.baseUrl}/v1/agent/channels?${params}`, {
4979
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels?${params}`, {
3060
4980
  headers: options.mine ? { "X-Agent-Key": this.apiKey } : {}
3061
4981
  });
3062
4982
  if (!res.ok) return [];
@@ -3067,7 +4987,7 @@ var VoidlyAgent = class _VoidlyAgent {
3067
4987
  * Join an encrypted channel.
3068
4988
  */
3069
4989
  async joinChannel(channelId) {
3070
- const res = await fetch(`${this.baseUrl}/v1/agent/channels/${channelId}/join`, {
4990
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/join`, {
3071
4991
  method: "POST",
3072
4992
  headers: { "X-Agent-Key": this.apiKey }
3073
4993
  });
@@ -3081,7 +5001,7 @@ var VoidlyAgent = class _VoidlyAgent {
3081
5001
  * Leave a channel.
3082
5002
  */
3083
5003
  async leaveChannel(channelId) {
3084
- const res = await fetch(`${this.baseUrl}/v1/agent/channels/${channelId}/leave`, {
5004
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/leave`, {
3085
5005
  method: "POST",
3086
5006
  headers: { "X-Agent-Key": this.apiKey }
3087
5007
  });
@@ -3094,7 +5014,7 @@ var VoidlyAgent = class _VoidlyAgent {
3094
5014
  * Post an encrypted message to a channel.
3095
5015
  */
3096
5016
  async postToChannel(channelId, message, replyTo) {
3097
- const res = await fetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages`, {
5017
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages`, {
3098
5018
  method: "POST",
3099
5019
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3100
5020
  body: JSON.stringify({ message, reply_to: replyTo })
@@ -3113,7 +5033,7 @@ var VoidlyAgent = class _VoidlyAgent {
3113
5033
  if (options.since) params.set("since", options.since);
3114
5034
  if (options.before) params.set("before", options.before);
3115
5035
  if (options.limit) params.set("limit", String(options.limit));
3116
- const res = await fetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages?${params}`, {
5036
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages?${params}`, {
3117
5037
  headers: { "X-Agent-Key": this.apiKey }
3118
5038
  });
3119
5039
  if (!res.ok) {
@@ -3127,7 +5047,7 @@ var VoidlyAgent = class _VoidlyAgent {
3127
5047
  * This is a soft delete — messages expire per TTL. Re-register for a new identity.
3128
5048
  */
3129
5049
  async deactivate() {
3130
- const res = await fetch(`${this.baseUrl}/v1/agent/deactivate`, {
5050
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/deactivate`, {
3131
5051
  method: "DELETE",
3132
5052
  headers: { "X-Agent-Key": this.apiKey }
3133
5053
  });
@@ -3150,7 +5070,7 @@ var VoidlyAgent = class _VoidlyAgent {
3150
5070
  * ```
3151
5071
  */
3152
5072
  async registerCapability(options) {
3153
- const res = await fetch(`${this.baseUrl}/v1/agent/capabilities`, {
5073
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities`, {
3154
5074
  method: "POST",
3155
5075
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3156
5076
  body: JSON.stringify({
@@ -3171,7 +5091,7 @@ var VoidlyAgent = class _VoidlyAgent {
3171
5091
  * List this agent's registered capabilities.
3172
5092
  */
3173
5093
  async listCapabilities() {
3174
- const res = await fetch(`${this.baseUrl}/v1/agent/capabilities`, {
5094
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities`, {
3175
5095
  headers: { "X-Agent-Key": this.apiKey }
3176
5096
  });
3177
5097
  if (!res.ok) return [];
@@ -3193,7 +5113,7 @@ var VoidlyAgent = class _VoidlyAgent {
3193
5113
  if (options.query) params.set("q", options.query);
3194
5114
  if (options.name) params.set("name", options.name);
3195
5115
  if (options.limit) params.set("limit", String(options.limit));
3196
- const res = await fetch(`${this.baseUrl}/v1/agent/capabilities/search?${params}`);
5116
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities/search?${params}`);
3197
5117
  if (!res.ok) return [];
3198
5118
  const data = await res.json();
3199
5119
  return data.results;
@@ -3202,7 +5122,7 @@ var VoidlyAgent = class _VoidlyAgent {
3202
5122
  * Remove a capability.
3203
5123
  */
3204
5124
  async deleteCapability(capabilityId) {
3205
- const res = await fetch(`${this.baseUrl}/v1/agent/capabilities/${capabilityId}`, {
5125
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/capabilities/${capabilityId}`, {
3206
5126
  method: "DELETE",
3207
5127
  headers: { "X-Agent-Key": this.apiKey }
3208
5128
  });
@@ -3227,14 +5147,14 @@ var VoidlyAgent = class _VoidlyAgent {
3227
5147
  * ```
3228
5148
  */
3229
5149
  async createTask(options) {
3230
- const identityRes = await fetch(`${this.baseUrl}/v1/agent/identity/${options.to}`);
5150
+ const identityRes = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${options.to}`);
3231
5151
  if (!identityRes.ok) throw new Error("Recipient agent not found");
3232
5152
  const identity = await identityRes.json();
3233
5153
  const recipientPubKey = (0, import_tweetnacl_util.decodeBase64)(identity.encryption_public_key);
3234
5154
  const plaintext = (0, import_tweetnacl_util.decodeUTF8)(JSON.stringify(options.input));
3235
5155
  const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
3236
5156
  const encrypted = import_tweetnacl.default.box(plaintext, nonce, recipientPubKey, this.encryptionKeyPair.secretKey);
3237
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks`, {
5157
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks`, {
3238
5158
  method: "POST",
3239
5159
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3240
5160
  body: JSON.stringify({
@@ -3261,7 +5181,7 @@ var VoidlyAgent = class _VoidlyAgent {
3261
5181
  if (options.status) params.set("status", options.status);
3262
5182
  if (options.capability) params.set("capability", options.capability);
3263
5183
  if (options.limit) params.set("limit", String(options.limit));
3264
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks?${params}`, {
5184
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks?${params}`, {
3265
5185
  headers: { "X-Agent-Key": this.apiKey }
3266
5186
  });
3267
5187
  if (!res.ok) return [];
@@ -3272,7 +5192,7 @@ var VoidlyAgent = class _VoidlyAgent {
3272
5192
  * Get task detail. Includes encrypted input/output (only visible to participants).
3273
5193
  */
3274
5194
  async getTask(taskId) {
3275
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
5195
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
3276
5196
  headers: { "X-Agent-Key": this.apiKey }
3277
5197
  });
3278
5198
  if (!res.ok) {
@@ -3304,7 +5224,7 @@ var VoidlyAgent = class _VoidlyAgent {
3304
5224
  if (update.output && (update.status === "completed" || update.status === "failed")) {
3305
5225
  const task = await this.getTask(taskId);
3306
5226
  const requesterDid = task.from;
3307
- const identityRes = await fetch(`${this.baseUrl}/v1/agent/identity/${requesterDid}`);
5227
+ const identityRes = await this._timedFetch(`${this.baseUrl}/v1/agent/identity/${requesterDid}`);
3308
5228
  if (identityRes.ok) {
3309
5229
  const identity = await identityRes.json();
3310
5230
  const requesterPubKey = (0, import_tweetnacl_util.decodeBase64)(identity.encryption_public_key);
@@ -3317,7 +5237,7 @@ var VoidlyAgent = class _VoidlyAgent {
3317
5237
  body.output_signature = (0, import_tweetnacl_util.encodeBase64)(signature);
3318
5238
  }
3319
5239
  }
3320
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
5240
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/${taskId}`, {
3321
5241
  method: "PATCH",
3322
5242
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3323
5243
  body: JSON.stringify(body)
@@ -3384,7 +5304,7 @@ var VoidlyAgent = class _VoidlyAgent {
3384
5304
  const payload = options.claimType + JSON.stringify(options.claimData) + timestamp;
3385
5305
  const payloadBytes = (0, import_tweetnacl_util.decodeUTF8)(payload);
3386
5306
  const signature = import_tweetnacl.default.sign.detached(payloadBytes, this.signingKeyPair.secretKey);
3387
- const res = await fetch(`${this.baseUrl}/v1/agent/attestations`, {
5307
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations`, {
3388
5308
  method: "POST",
3389
5309
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3390
5310
  body: JSON.stringify({
@@ -3421,7 +5341,7 @@ var VoidlyAgent = class _VoidlyAgent {
3421
5341
  const payload = attestationId + vote;
3422
5342
  const payloadBytes = (0, import_tweetnacl_util.decodeUTF8)(payload);
3423
5343
  const signature = import_tweetnacl.default.sign.detached(payloadBytes, this.signingKeyPair.secretKey);
3424
- const res = await fetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}/corroborate`, {
5344
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}/corroborate`, {
3425
5345
  method: "POST",
3426
5346
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3427
5347
  body: JSON.stringify({ vote, signature: (0, import_tweetnacl_util.encodeBase64)(signature), comment })
@@ -3444,7 +5364,7 @@ var VoidlyAgent = class _VoidlyAgent {
3444
5364
  if (options.minConsensus !== void 0) params.set("min_consensus", String(options.minConsensus));
3445
5365
  if (options.since) params.set("since", options.since);
3446
5366
  if (options.limit) params.set("limit", String(options.limit));
3447
- const res = await fetch(`${this.baseUrl}/v1/agent/attestations?${params}`);
5367
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations?${params}`);
3448
5368
  if (!res.ok) return [];
3449
5369
  const data = await res.json();
3450
5370
  return data.attestations;
@@ -3453,7 +5373,7 @@ var VoidlyAgent = class _VoidlyAgent {
3453
5373
  * Get attestation detail including all corroborations.
3454
5374
  */
3455
5375
  async getAttestation(attestationId) {
3456
- const res = await fetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}`);
5376
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/${attestationId}`);
3457
5377
  if (!res.ok) {
3458
5378
  const err = await res.json().catch(() => ({}));
3459
5379
  throw new Error(`Get attestation failed: ${err.error || res.statusText}`);
@@ -3468,7 +5388,7 @@ var VoidlyAgent = class _VoidlyAgent {
3468
5388
  if (options.country) params.set("country", options.country);
3469
5389
  if (options.domain) params.set("domain", options.domain);
3470
5390
  if (options.type) params.set("type", options.type);
3471
- const res = await fetch(`${this.baseUrl}/v1/agent/attestations/consensus?${params}`);
5391
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/attestations/consensus?${params}`);
3472
5392
  if (!res.ok) return [];
3473
5393
  const data = await res.json();
3474
5394
  return data.consensus;
@@ -3481,7 +5401,7 @@ var VoidlyAgent = class _VoidlyAgent {
3481
5401
  * Only channel members can invite.
3482
5402
  */
3483
5403
  async inviteToChannel(channelId, inviteeDid, options) {
3484
- const res = await fetch(`${this.baseUrl}/v1/agent/channels/${channelId}/invite`, {
5404
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/invite`, {
3485
5405
  method: "POST",
3486
5406
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3487
5407
  body: JSON.stringify({
@@ -3500,7 +5420,7 @@ var VoidlyAgent = class _VoidlyAgent {
3500
5420
  * List pending channel invites for this agent.
3501
5421
  */
3502
5422
  async listInvites(status = "pending") {
3503
- const res = await fetch(`${this.baseUrl}/v1/agent/invites?status=${status}`, {
5423
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/invites?status=${status}`, {
3504
5424
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3505
5425
  });
3506
5426
  if (!res.ok) return [];
@@ -3511,7 +5431,7 @@ var VoidlyAgent = class _VoidlyAgent {
3511
5431
  * Accept or decline a channel invite.
3512
5432
  */
3513
5433
  async respondToInvite(inviteId, action) {
3514
- const res = await fetch(`${this.baseUrl}/v1/agent/invites/${inviteId}/respond`, {
5434
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/invites/${inviteId}/respond`, {
3515
5435
  method: "POST",
3516
5436
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3517
5437
  body: JSON.stringify({ action })
@@ -3529,7 +5449,7 @@ var VoidlyAgent = class _VoidlyAgent {
3529
5449
  * Get an agent's trust score and reputation breakdown.
3530
5450
  */
3531
5451
  async getTrustScore(did) {
3532
- const res = await fetch(`${this.baseUrl}/v1/agent/trust/${did}`);
5452
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/trust/${did}`);
3533
5453
  if (!res.ok) {
3534
5454
  const err = await res.json().catch(() => ({}));
3535
5455
  throw new Error(`Trust score failed: ${err.error || res.statusText}`);
@@ -3543,7 +5463,7 @@ var VoidlyAgent = class _VoidlyAgent {
3543
5463
  const params = new URLSearchParams();
3544
5464
  if (options?.limit) params.set("limit", options.limit.toString());
3545
5465
  if (options?.minLevel) params.set("min_level", options.minLevel);
3546
- const res = await fetch(`${this.baseUrl}/v1/agent/trust/leaderboard?${params}`);
5466
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/trust/leaderboard?${params}`);
3547
5467
  if (!res.ok) return [];
3548
5468
  const data = await res.json();
3549
5469
  return data.leaderboard;
@@ -3555,7 +5475,7 @@ var VoidlyAgent = class _VoidlyAgent {
3555
5475
  * Mark a message as read.
3556
5476
  */
3557
5477
  async markRead(messageId) {
3558
- const res = await fetch(`${this.baseUrl}/v1/agent/messages/${messageId}/read`, {
5478
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/${messageId}/read`, {
3559
5479
  method: "POST",
3560
5480
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3561
5481
  });
@@ -3566,7 +5486,7 @@ var VoidlyAgent = class _VoidlyAgent {
3566
5486
  * Mark multiple messages as read in one call.
3567
5487
  */
3568
5488
  async markReadBatch(messageIds) {
3569
- const res = await fetch(`${this.baseUrl}/v1/agent/messages/read-batch`, {
5489
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/read-batch`, {
3570
5490
  method: "POST",
3571
5491
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3572
5492
  body: JSON.stringify({ message_ids: messageIds })
@@ -3580,7 +5500,7 @@ var VoidlyAgent = class _VoidlyAgent {
3580
5500
  async getUnreadCount(fromDid) {
3581
5501
  const params = new URLSearchParams();
3582
5502
  if (fromDid) params.set("from", fromDid);
3583
- const res = await fetch(`${this.baseUrl}/v1/agent/messages/unread-count?${params}`, {
5503
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/messages/unread-count?${params}`, {
3584
5504
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3585
5505
  });
3586
5506
  if (!res.ok) throw new Error(`Failed to get unread count: ${res.status}`);
@@ -3601,7 +5521,7 @@ var VoidlyAgent = class _VoidlyAgent {
3601
5521
  this.encryptionKeyPair.secretKey
3602
5522
  ));
3603
5523
  const broadcastSig = import_tweetnacl.default.sign.detached(inputBytes, this.signingKeyPair.secretKey);
3604
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks/broadcast`, {
5524
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcast`, {
3605
5525
  method: "POST",
3606
5526
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3607
5527
  body: JSON.stringify({
@@ -3627,7 +5547,7 @@ var VoidlyAgent = class _VoidlyAgent {
3627
5547
  async listBroadcasts(status) {
3628
5548
  const params = new URLSearchParams();
3629
5549
  if (status) params.set("status", status);
3630
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks/broadcasts?${params}`, {
5550
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcasts?${params}`, {
3631
5551
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3632
5552
  });
3633
5553
  if (!res.ok) return [];
@@ -3638,7 +5558,7 @@ var VoidlyAgent = class _VoidlyAgent {
3638
5558
  * Get broadcast detail with individual task statuses.
3639
5559
  */
3640
5560
  async getBroadcast(broadcastId) {
3641
- const res = await fetch(`${this.baseUrl}/v1/agent/tasks/broadcasts/${broadcastId}`, {
5561
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/tasks/broadcasts/${broadcastId}`, {
3642
5562
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3643
5563
  });
3644
5564
  if (!res.ok) throw new Error(`Failed to get broadcast: ${res.status}`);
@@ -3654,7 +5574,7 @@ var VoidlyAgent = class _VoidlyAgent {
3654
5574
  async getAnalytics(period) {
3655
5575
  const params = new URLSearchParams();
3656
5576
  if (period) params.set("period", period);
3657
- const res = await fetch(`${this.baseUrl}/v1/agent/analytics?${params}`, {
5577
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/analytics?${params}`, {
3658
5578
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey }
3659
5579
  });
3660
5580
  if (!res.ok) throw new Error(`Failed to get analytics: ${res.status}`);
@@ -3694,7 +5614,7 @@ var VoidlyAgent = class _VoidlyAgent {
3694
5614
  memKey = new Uint8Array(createHash("sha256").update(Buffer.from(memKeyInput)).digest());
3695
5615
  }
3696
5616
  const encryptedValue = import_tweetnacl.default.secretbox(valueBytes, memNonce, memKey);
3697
- const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
5617
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
3698
5618
  method: "PUT",
3699
5619
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3700
5620
  body: JSON.stringify({
@@ -3712,7 +5632,7 @@ var VoidlyAgent = class _VoidlyAgent {
3712
5632
  * Decrypted CLIENT-SIDE — relay never sees plaintext.
3713
5633
  */
3714
5634
  async memoryGet(namespace, key) {
3715
- const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
5635
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
3716
5636
  headers: { "X-Agent-Key": this.apiKey }
3717
5637
  });
3718
5638
  if (res.status === 404) return null;
@@ -3744,7 +5664,7 @@ var VoidlyAgent = class _VoidlyAgent {
3744
5664
  * Delete a key from persistent memory.
3745
5665
  */
3746
5666
  async memoryDelete(namespace, key) {
3747
- const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
5667
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(namespace)}/${encodeURIComponent(key)}`, {
3748
5668
  method: "DELETE",
3749
5669
  headers: { "X-Agent-Key": this.apiKey }
3750
5670
  });
@@ -3760,7 +5680,7 @@ var VoidlyAgent = class _VoidlyAgent {
3760
5680
  if (options?.prefix) params.set("prefix", options.prefix);
3761
5681
  if (options?.limit) params.set("limit", String(options.limit));
3762
5682
  const qs = params.toString() ? `?${params.toString()}` : "";
3763
- const res = await fetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(ns)}${qs}`, {
5683
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory/${encodeURIComponent(ns)}${qs}`, {
3764
5684
  headers: { "X-Agent-Key": this.apiKey }
3765
5685
  });
3766
5686
  if (!res.ok) throw new Error(`Memory list failed: ${res.status} ${await res.text()}`);
@@ -3770,7 +5690,7 @@ var VoidlyAgent = class _VoidlyAgent {
3770
5690
  * List all memory namespaces and quota usage.
3771
5691
  */
3772
5692
  async memoryNamespaces() {
3773
- const res = await fetch(`${this.baseUrl}/v1/agent/memory`, {
5693
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/memory`, {
3774
5694
  headers: { "X-Agent-Key": this.apiKey }
3775
5695
  });
3776
5696
  if (!res.ok) throw new Error(`Memory namespaces failed: ${res.status} ${await res.text()}`);
@@ -3783,7 +5703,7 @@ var VoidlyAgent = class _VoidlyAgent {
3783
5703
  * Memory values remain encrypted — portable to another relay.
3784
5704
  */
3785
5705
  async exportData(options) {
3786
- const res = await fetch(`${this.baseUrl}/v1/agent/export`, {
5706
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/export`, {
3787
5707
  method: "POST",
3788
5708
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3789
5709
  body: JSON.stringify({
@@ -3802,7 +5722,7 @@ var VoidlyAgent = class _VoidlyAgent {
3802
5722
  * List past data export records.
3803
5723
  */
3804
5724
  async listExports() {
3805
- const res = await fetch(`${this.baseUrl}/v1/agent/exports`, {
5725
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/exports`, {
3806
5726
  headers: { "X-Agent-Key": this.apiKey }
3807
5727
  });
3808
5728
  if (!res.ok) throw new Error(`List exports failed: ${res.status} ${await res.text()}`);
@@ -3814,7 +5734,7 @@ var VoidlyAgent = class _VoidlyAgent {
3814
5734
  * Includes federation capabilities and known peers.
3815
5735
  */
3816
5736
  async getRelayInfo() {
3817
- const res = await fetch(`${this.baseUrl}/v1/relay/info`);
5737
+ const res = await this._timedFetch(`${this.baseUrl}/v1/relay/info`);
3818
5738
  if (!res.ok) throw new Error(`Relay info failed: ${res.status} ${await res.text()}`);
3819
5739
  return res.json();
3820
5740
  }
@@ -3822,7 +5742,7 @@ var VoidlyAgent = class _VoidlyAgent {
3822
5742
  * List known federated relay peers.
3823
5743
  */
3824
5744
  async getRelayPeers() {
3825
- const res = await fetch(`${this.baseUrl}/v1/relay/peers`);
5745
+ const res = await this._timedFetch(`${this.baseUrl}/v1/relay/peers`);
3826
5746
  if (!res.ok) throw new Error(`Relay peers failed: ${res.status} ${await res.text()}`);
3827
5747
  return res.json();
3828
5748
  }
@@ -3844,7 +5764,7 @@ var VoidlyAgent = class _VoidlyAgent {
3844
5764
  ciphertext_hash: await sha256((0, import_tweetnacl_util.encodeBase64)(encrypted))
3845
5765
  }));
3846
5766
  const signature = import_tweetnacl.default.sign.detached(signaturePayload, this.signingKeyPair.secretKey);
3847
- const res = await fetch(`${this.baseUrl}/v1/relay/route`, {
5767
+ const res = await this._timedFetch(`${this.baseUrl}/v1/relay/route`, {
3848
5768
  method: "POST",
3849
5769
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3850
5770
  body: JSON.stringify({
@@ -3862,7 +5782,7 @@ var VoidlyAgent = class _VoidlyAgent {
3862
5782
  // ── Heartbeat ──────────────────────────────────────────────────────────────
3863
5783
  /** Send heartbeat — signals agent is alive, updates last_seen */
3864
5784
  async ping() {
3865
- const res = await fetch(`${this.baseUrl}/v1/agent/ping`, {
5785
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/ping`, {
3866
5786
  method: "POST",
3867
5787
  headers: { "X-Agent-Key": this.apiKey }
3868
5788
  });
@@ -3871,14 +5791,14 @@ var VoidlyAgent = class _VoidlyAgent {
3871
5791
  }
3872
5792
  /** Check if another agent is online (public) */
3873
5793
  async checkOnline(did) {
3874
- const res = await fetch(`${this.baseUrl}/v1/agent/ping/${encodeURIComponent(did)}`);
5794
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/ping/${encodeURIComponent(did)}`);
3875
5795
  if (!res.ok) throw new Error(`Ping check failed: ${res.status}`);
3876
5796
  return res.json();
3877
5797
  }
3878
5798
  // ── Key Pinning (TOFU) ────────────────────────────────────────────────────
3879
5799
  /** Pin another agent's public keys (Trust On First Use). Returns warning if keys changed since last pin. */
3880
5800
  async pinKeys(did) {
3881
- const res = await fetch(`${this.baseUrl}/v1/agent/keys/pin`, {
5801
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/pin`, {
3882
5802
  method: "POST",
3883
5803
  headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
3884
5804
  body: JSON.stringify({ did })
@@ -3891,7 +5811,7 @@ var VoidlyAgent = class _VoidlyAgent {
3891
5811
  const params = new URLSearchParams();
3892
5812
  if (options?.status) params.set("status", options.status);
3893
5813
  const qs = params.toString() ? `?${params.toString()}` : "";
3894
- const res = await fetch(`${this.baseUrl}/v1/agent/keys/pins${qs}`, {
5814
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/pins${qs}`, {
3895
5815
  headers: { "X-Agent-Key": this.apiKey }
3896
5816
  });
3897
5817
  if (!res.ok) throw new Error(`List pins failed: ${res.status}`);
@@ -3899,13 +5819,165 @@ var VoidlyAgent = class _VoidlyAgent {
3899
5819
  }
3900
5820
  /** Verify an agent's keys against your pinned copy. Detects key changes (potential MitM). */
3901
5821
  async verifyKeys(did) {
3902
- const res = await fetch(`${this.baseUrl}/v1/agent/keys/verify/${encodeURIComponent(did)}`, {
5822
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/keys/verify/${encodeURIComponent(did)}`, {
3903
5823
  headers: { "X-Agent-Key": this.apiKey }
3904
5824
  });
3905
5825
  if (!res.ok) throw new Error(`Key verify failed: ${res.status}`);
3906
5826
  return res.json();
3907
5827
  }
3908
5828
  // ═══════════════════════════════════════════════════════════════════════════
5829
+ // X3DH — Async Key Agreement (prekey bundles for offline agents)
5830
+ // ═══════════════════════════════════════════════════════════════════════════
5831
+ /**
5832
+ * Upload prekey bundle for X3DH async key agreement.
5833
+ * Other agents can fetch your prekeys and establish encrypted sessions
5834
+ * even while you're offline.
5835
+ *
5836
+ * @param count Number of one-time prekeys to upload (default: 20)
5837
+ */
5838
+ async uploadPrekeys(count = 20) {
5839
+ const prekeys = [];
5840
+ for (let i = 0; i < count; i++) {
5841
+ const kp = import_tweetnacl.default.box.keyPair();
5842
+ prekeys.push({
5843
+ id: Date.now() + i,
5844
+ public_key: (0, import_tweetnacl_util.encodeBase64)(kp.publicKey),
5845
+ secretKey: kp.secretKey
5846
+ });
5847
+ }
5848
+ const newPrekey = import_tweetnacl.default.box.keyPair();
5849
+ this._signedPrekeyId++;
5850
+ const prekeySignature = import_tweetnacl.default.sign.detached(newPrekey.publicKey, this.signingKeyPair.secretKey);
5851
+ this._signedPrekey = newPrekey;
5852
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/prekeys`, {
5853
+ method: "POST",
5854
+ headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
5855
+ body: JSON.stringify({
5856
+ prekeys: prekeys.map((pk) => ({ id: pk.id, public_key: pk.public_key })),
5857
+ signed_prekey: {
5858
+ public_key: (0, import_tweetnacl_util.encodeBase64)(newPrekey.publicKey),
5859
+ signature: (0, import_tweetnacl_util.encodeBase64)(prekeySignature),
5860
+ id: this._signedPrekeyId
5861
+ }
5862
+ })
5863
+ });
5864
+ if (!res.ok) throw new Error(`Prekey upload failed: ${res.status}`);
5865
+ return await res.json();
5866
+ }
5867
+ /**
5868
+ * Fetch another agent's prekey bundle for X3DH key agreement.
5869
+ * Use this to establish an encrypted session with an offline agent.
5870
+ */
5871
+ async fetchPrekeys(did) {
5872
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/prekeys/${encodeURIComponent(did)}`);
5873
+ if (!res.ok) return null;
5874
+ return await res.json();
5875
+ }
5876
+ // ═══════════════════════════════════════════════════════════════════════════
5877
+ // CLIENT-SIDE CHANNEL ENCRYPTION
5878
+ // ═══════════════════════════════════════════════════════════════════════════
5879
+ /**
5880
+ * Create a channel with client-side encryption.
5881
+ * The channel symmetric key is generated locally and encrypted per-member.
5882
+ * The relay NEVER sees the plaintext channel key — true E2E for groups.
5883
+ */
5884
+ async createEncryptedChannel(options) {
5885
+ const channelKey = import_tweetnacl.default.randomBytes(32);
5886
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels`, {
5887
+ method: "POST",
5888
+ headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
5889
+ body: JSON.stringify(options)
5890
+ });
5891
+ if (!res.ok) {
5892
+ const err = await res.json().catch(() => ({}));
5893
+ throw new Error(`Channel creation failed: ${err.error || res.statusText}`);
5894
+ }
5895
+ const channel = await res.json();
5896
+ const selfNonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.box.nonceLength);
5897
+ const selfEncrypted = import_tweetnacl.default.box(channelKey, selfNonce, this.encryptionKeyPair.publicKey, this.encryptionKeyPair.secretKey);
5898
+ await this.memorySet("channel-keys", channel.id, {
5899
+ key: (0, import_tweetnacl_util.encodeBase64)(channelKey),
5900
+ nonce: (0, import_tweetnacl_util.encodeBase64)(selfNonce)
5901
+ });
5902
+ return { ...channel, channelKey };
5903
+ }
5904
+ /**
5905
+ * Post a client-side encrypted message to a channel.
5906
+ * Uses the channel's shared symmetric key — relay never sees plaintext.
5907
+ *
5908
+ * @param channelId Channel ID
5909
+ * @param message Plaintext message
5910
+ * @param channelKey 32-byte symmetric channel key (from createEncryptedChannel or received via invite)
5911
+ */
5912
+ async postEncrypted(channelId, message, channelKey) {
5913
+ const nonce = import_tweetnacl.default.randomBytes(import_tweetnacl.default.secretbox.nonceLength);
5914
+ const ciphertext = import_tweetnacl.default.secretbox((0, import_tweetnacl_util.decodeUTF8)(message), nonce, channelKey);
5915
+ const sigPayload = new Uint8Array([...ciphertext, ...nonce]);
5916
+ const signature = import_tweetnacl.default.sign.detached(sigPayload, this.signingKeyPair.secretKey);
5917
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/channels/${channelId}/messages`, {
5918
+ method: "POST",
5919
+ headers: { "Content-Type": "application/json", "X-Agent-Key": this.apiKey },
5920
+ body: JSON.stringify({
5921
+ message: JSON.stringify({
5922
+ v: 3,
5923
+ ct: (0, import_tweetnacl_util.encodeBase64)(ciphertext),
5924
+ n: (0, import_tweetnacl_util.encodeBase64)(nonce),
5925
+ sig: (0, import_tweetnacl_util.encodeBase64)(signature),
5926
+ from: this.did
5927
+ })
5928
+ })
5929
+ });
5930
+ if (!res.ok) throw new Error(`Post failed: ${res.status}`);
5931
+ return await res.json();
5932
+ }
5933
+ /**
5934
+ * Read and decrypt channel messages using client-side channel key.
5935
+ * Ignores server-side encryption entirely — true E2E.
5936
+ *
5937
+ * @param channelId Channel ID
5938
+ * @param channelKey 32-byte symmetric channel key
5939
+ */
5940
+ async readEncrypted(channelId, channelKey, options) {
5941
+ const raw = await this.readChannel(channelId, options);
5942
+ const decrypted = [];
5943
+ for (const msg of raw.messages) {
5944
+ try {
5945
+ const parsed = JSON.parse(typeof msg.content === "string" ? msg.content : msg.message || "");
5946
+ if (parsed.v === 3 && parsed.ct && parsed.n) {
5947
+ const ct = (0, import_tweetnacl_util.decodeBase64)(parsed.ct);
5948
+ const nonce = (0, import_tweetnacl_util.decodeBase64)(parsed.n);
5949
+ const plain = import_tweetnacl.default.secretbox.open(ct, nonce, channelKey);
5950
+ if (plain) {
5951
+ let sigValid = false;
5952
+ if (parsed.sig && parsed.from) {
5953
+ try {
5954
+ const profile = await this.getIdentity(parsed.from);
5955
+ if (profile) {
5956
+ const sigPayload = new Uint8Array([...ct, ...nonce]);
5957
+ sigValid = import_tweetnacl.default.sign.detached.verify(
5958
+ sigPayload,
5959
+ (0, import_tweetnacl_util.decodeBase64)(parsed.sig),
5960
+ (0, import_tweetnacl_util.decodeBase64)(profile.signing_public_key)
5961
+ );
5962
+ }
5963
+ } catch {
5964
+ }
5965
+ }
5966
+ decrypted.push({
5967
+ id: msg.id,
5968
+ from: parsed.from || msg.author || "unknown",
5969
+ content: (0, import_tweetnacl_util.encodeUTF8)(plain),
5970
+ timestamp: msg.created_at || msg.timestamp,
5971
+ signatureValid: sigValid
5972
+ });
5973
+ }
5974
+ }
5975
+ } catch {
5976
+ }
5977
+ }
5978
+ return { messages: decrypted, count: decrypted.length };
5979
+ }
5980
+ // ═══════════════════════════════════════════════════════════════════════════
3909
5981
  // LISTEN — Event-Driven Message Receiving
3910
5982
  // ═══════════════════════════════════════════════════════════════════════════
3911
5983
  /**
@@ -3972,20 +6044,54 @@ var VoidlyAgent = class _VoidlyAgent {
3972
6044
  this.ping().catch(() => {
3973
6045
  });
3974
6046
  }
6047
+ const useLongPoll = this.longPoll;
3975
6048
  const poll = async () => {
3976
6049
  if (!active || options.signal?.aborted) {
3977
6050
  handle.stop();
3978
6051
  return;
3979
6052
  }
3980
6053
  try {
3981
- const messages = await this.receive({
3982
- since: lastSeen,
3983
- from: options.from,
3984
- threadId: options.threadId,
3985
- messageType: options.messageType,
3986
- unreadOnly,
3987
- limit: 50
3988
- });
6054
+ let messages;
6055
+ if (useLongPoll) {
6056
+ const params = new URLSearchParams({ timeout: "25" });
6057
+ if (lastSeen) params.set("since", lastSeen);
6058
+ if (options.from) params.set("from", options.from);
6059
+ const res = await this._timedFetch(`${this.baseUrl}/v1/agent/receive/poll?${params}`, {
6060
+ headers: { "X-Agent-Key": this.apiKey }
6061
+ });
6062
+ if (res.ok) {
6063
+ const data = await res.json();
6064
+ messages = [];
6065
+ for (const raw of data.messages) {
6066
+ try {
6067
+ if (this._seenMessageIds.has(raw.id)) continue;
6068
+ this._seenMessageIds.add(raw.id);
6069
+ } catch {
6070
+ }
6071
+ }
6072
+ if (data.messages.length > 0) {
6073
+ messages = await this.receive({
6074
+ since: lastSeen,
6075
+ from: options.from,
6076
+ threadId: options.threadId,
6077
+ messageType: options.messageType,
6078
+ unreadOnly,
6079
+ limit: 50
6080
+ });
6081
+ }
6082
+ } else {
6083
+ messages = [];
6084
+ }
6085
+ } else {
6086
+ messages = await this.receive({
6087
+ since: lastSeen,
6088
+ from: options.from,
6089
+ threadId: options.threadId,
6090
+ messageType: options.messageType,
6091
+ unreadOnly,
6092
+ limit: 50
6093
+ });
6094
+ }
3989
6095
  if (messages.length > 0) {
3990
6096
  consecutiveEmpty = 0;
3991
6097
  if (adaptive) currentInterval = Math.max(interval / 2, 500);
@@ -4003,7 +6109,7 @@ var VoidlyAgent = class _VoidlyAgent {
4003
6109
  lastSeen = messages[messages.length - 1].timestamp;
4004
6110
  } else {
4005
6111
  consecutiveEmpty++;
4006
- if (adaptive && consecutiveEmpty > 3) {
6112
+ if (adaptive && consecutiveEmpty > 3 && !useLongPoll) {
4007
6113
  currentInterval = Math.min(currentInterval * 1.5, interval * 4);
4008
6114
  }
4009
6115
  }
@@ -4012,7 +6118,7 @@ var VoidlyAgent = class _VoidlyAgent {
4012
6118
  currentInterval = Math.min(currentInterval * 2, interval * 8);
4013
6119
  }
4014
6120
  if (active && !options.signal?.aborted) {
4015
- timer = setTimeout(poll, currentInterval);
6121
+ timer = setTimeout(poll, useLongPoll ? 100 : currentInterval);
4016
6122
  }
4017
6123
  };
4018
6124
  poll();
@@ -4110,6 +6216,21 @@ var VoidlyAgent = class _VoidlyAgent {
4110
6216
  // ═══════════════════════════════════════════════════════════════════════════
4111
6217
  // INTERNAL — Retry, Auto-Pin
4112
6218
  // ═══════════════════════════════════════════════════════════════════════════
6219
+ /** @internal Fetch with timeout via AbortController */
6220
+ async _timedFetch(url, init) {
6221
+ const controller = new AbortController();
6222
+ const timer = setTimeout(() => controller.abort(), this.timeout);
6223
+ try {
6224
+ return await fetch(url, { ...init, signal: controller.signal });
6225
+ } catch (err) {
6226
+ if (err instanceof Error && err.name === "AbortError") {
6227
+ throw new Error(`Request timed out after ${this.timeout}ms: ${url.replace(this.baseUrl, "")}`);
6228
+ }
6229
+ throw err;
6230
+ } finally {
6231
+ clearTimeout(timer);
6232
+ }
6233
+ }
4113
6234
  /** @internal Auto-pin keys on first contact (TOFU) */
4114
6235
  async _autoPinKeys(did) {
4115
6236
  if (this._pinnedDids.has(did)) return;
@@ -4130,7 +6251,7 @@ var VoidlyAgent = class _VoidlyAgent {
4130
6251
  let lastError = null;
4131
6252
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
4132
6253
  try {
4133
- const res = await fetch(url, init);
6254
+ const res = await this._timedFetch(url, init);
4134
6255
  if (res.ok) {
4135
6256
  return await res.json();
4136
6257
  }
@@ -4197,50 +6318,56 @@ var VoidlyAgent = class _VoidlyAgent {
4197
6318
  return {
4198
6319
  relayCanSee: [
4199
6320
  "Your DID (public identifier)",
4200
- "Who you message (recipient DIDs)",
4201
- "When you message (timestamps)",
6321
+ ...this.sealedSender ? [] : ["Who you message (recipient DIDs)"],
6322
+ ...this.jitterMs > 0 ? ["Approximate timing (jittered timestamps)"] : ["When you message (timestamps)"],
4202
6323
  "Message types (text, task-request, etc.)",
4203
6324
  "Thread structure (which messages are replies)",
4204
- "Channel membership",
6325
+ "Channel membership (but NOT channel message content with client-side encryption)",
4205
6326
  "Capability registrations",
4206
6327
  "Online/offline status",
4207
6328
  "Approximate message size (even with padding, bounded to power-of-2)"
4208
6329
  ],
4209
6330
  relayCannotSee: [
4210
- "Message content (E2E encrypted \u2014 nacl.secretbox with ratchet-derived per-message keys)",
6331
+ "Message content (E2E encrypted \u2014 nacl.box with Double Ratchet per-message keys)",
4211
6332
  "Private keys (generated and stored client-side only)",
4212
6333
  "Memory values (encrypted CLIENT-SIDE with nacl.secretbox before relay storage)",
4213
- "Past message keys (hash ratchet provides forward secrecy \u2014 old keys are deleted)",
4214
- ...this.sealedSender ? ["Sender identity (sealed inside ciphertext)"] : []
6334
+ "Past message keys (forward secrecy \u2014 hash ratchet + DH ratchet, old keys deleted)",
6335
+ "Future message keys (post-compromise recovery via DH ratchet \u2014 compromise heals after one round-trip)",
6336
+ "Channel message content (client-side nacl.secretbox encryption \u2014 relay stores only ciphertext)",
6337
+ ...this.sealedSender ? ["Sender identity (sealed inside ciphertext)"] : [],
6338
+ ...this.deniable ? ["Who authored a message (HMAC is symmetric \u2014 either party could have produced it)"] : []
4215
6339
  ],
4216
6340
  protections: [
4217
- "Hash ratchet forward secrecy \u2014 per-message key derivation, old keys deleted",
6341
+ ...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"],
6342
+ ...this.postQuantum && this.mlkemPublicKey ? ["ML-KEM-768 + X25519 hybrid key exchange (NIST FIPS 203 post-quantum, harvest-now-decrypt-later resistant)"] : [],
6343
+ "X3DH async key agreement (signed prekeys + one-time prekeys for offline session establishment)",
4218
6344
  "X25519 key exchange + XSalsa20-Poly1305 authenticated encryption",
4219
- "Ed25519 signatures on every message (envelope + ciphertext hash)",
6345
+ ...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)"],
4220
6346
  "TOFU key pinning (MitM detection on key change)",
4221
6347
  "Client-side memory encryption (relay never sees plaintext values)",
4222
- "Protocol version header (deterministic padding/sealing detection, no heuristics)",
6348
+ "Client-side channel encryption (nacl.secretbox \u2014 relay never sees channel plaintext)",
6349
+ "Protocol version header (deterministic padding/sealing/ratchet detection, no heuristics)",
4223
6350
  "Identity cache (reduced key lookups, 5-min TTL)",
4224
6351
  "Message deduplication (track seen message IDs)",
6352
+ "Request timeouts (AbortController on all HTTP, configurable)",
4225
6353
  "Request validation (fromCredentials validates key sizes and format)",
4226
6354
  ...this.paddingEnabled ? ["Message padding to power-of-2 boundary (traffic analysis resistance)"] : [],
4227
6355
  ...this.sealedSender ? ["Sealed sender (relay cannot see who sent a message)"] : [],
4228
6356
  ...this.requireSignatures ? ["Strict signature enforcement (reject unsigned/invalid messages)"] : [],
4229
6357
  ...this.fallbackRelays.length > 0 ? [`Multi-relay fallback (${this.fallbackRelays.length} backup relays)`] : [],
6358
+ ...this.jitterMs > 0 ? [`Timing jitter (random ${this.jitterMs}ms delay \u2014 metadata timing protection)`] : [],
6359
+ ...this.longPoll ? ["Long-poll transport (25s server-held connection \u2014 near-real-time delivery)"] : [],
4230
6360
  "Auto-retry with exponential backoff",
4231
6361
  "Offline message queue",
4232
6362
  "did:key interoperability (W3C standard DID format)"
4233
6363
  ],
4234
6364
  gaps: [
4235
- "No DH ratchet yet \u2014 hash ratchet only (no post-compromise recovery, planned for v3)",
4236
- "No post-quantum protection \u2014 vulnerable to harvest-now-decrypt-later (planned for v3)",
4237
- "Channel encryption is server-side (relay holds channel keys, NOT true E2E)",
4238
- "Metadata (who, when, thread structure) visible to relay operator",
4239
- "Single relay architecture (no onion routing, no mix network)",
4240
- "Ed25519 signatures are non-repudiable (no deniable messaging)",
4241
- "No async key agreement (no X3DH prekeys)",
4242
- "Polling-based (no WebSocket real-time transport)",
4243
- "Ratchet state is in-memory (lost on process restart \u2014 export credentials to persist)"
6365
+ ...!this.postQuantum || !this.mlkemPublicKey ? ["No post-quantum protection \u2014 enable postQuantum option and re-register"] : [],
6366
+ "Single relay architecture (no onion routing, no mix network \u2014 mitigated by multi-relay fallback)",
6367
+ "Ratchet state is in-memory (lost on process restart \u2014 export credentials to persist)",
6368
+ ...!this.deniable ? ["Ed25519 signatures are non-repudiable \u2014 enable deniable option for HMAC auth"] : [],
6369
+ ...!this.doubleRatchet ? ["Hash ratchet only \u2014 enable doubleRatchet option for post-compromise recovery"] : [],
6370
+ ...this.jitterMs === 0 ? ["No timing jitter \u2014 enable jitterMs option for metadata protection"] : []
4244
6371
  ]
4245
6372
  };
4246
6373
  }
@@ -4323,9 +6450,9 @@ var Conversation = class {
4323
6450
  messageType: msg.messageType
4324
6451
  });
4325
6452
  this._lastMessageId = msg.id;
4326
- for (const h of this._replyHandlers) {
6453
+ for (const h2 of this._replyHandlers) {
4327
6454
  try {
4328
- await h(msg);
6455
+ await h2(msg);
4329
6456
  } catch {
4330
6457
  }
4331
6458
  }
@@ -4431,3 +6558,8 @@ var Conversation = class {
4431
6558
  encodeUTF8,
4432
6559
  nacl
4433
6560
  });
6561
+ /*! Bundled license information:
6562
+
6563
+ mlkem/esm/src/sha3/utils.js:
6564
+ (*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
6565
+ */