@blamejs/blamejs-shop 0.1.32 → 0.1.33

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.
Files changed (96) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +2 -0
  3. package/lib/admin.js +18 -10
  4. package/lib/asset-manifest.json +17 -5
  5. package/lib/storefront.js +326 -44
  6. package/lib/vendor/MANIFEST.json +2 -2
  7. package/lib/vendor/blamejs/CHANGELOG.md +8 -0
  8. package/lib/vendor/blamejs/README.md +3 -1
  9. package/lib/vendor/blamejs/api-snapshot.json +99 -2
  10. package/lib/vendor/blamejs/index.js +3 -0
  11. package/lib/vendor/blamejs/lib/crypto-oprf.js +110 -0
  12. package/lib/vendor/blamejs/lib/network-tsig.js +404 -0
  13. package/lib/vendor/blamejs/lib/network.js +1 -0
  14. package/lib/vendor/blamejs/lib/vendor/MANIFEST.json +44 -9
  15. package/lib/vendor/blamejs/lib/vendor/noble-curves.cjs +19 -0
  16. package/lib/vendor/blamejs/lib/worm.js +246 -0
  17. package/lib/vendor/blamejs/package.json +1 -1
  18. package/lib/vendor/blamejs/release-notes/v0.12.x.json +1844 -0
  19. package/lib/vendor/blamejs/release-notes/v0.13.0.json +22 -0
  20. package/lib/vendor/blamejs/release-notes/v0.13.1.json +18 -0
  21. package/lib/vendor/blamejs/scripts/vendor-update.sh +11 -1
  22. package/lib/vendor/blamejs/test/layer-0-primitives/codebase-patterns.test.js +3 -1
  23. package/lib/vendor/blamejs/test/layer-0-primitives/crypto-oprf.test.js +101 -0
  24. package/lib/vendor/blamejs/test/layer-0-primitives/network-tsig.test.js +149 -0
  25. package/lib/vendor/blamejs/test/layer-0-primitives/sandbox.test.js +2 -2
  26. package/lib/vendor/blamejs/test/layer-0-primitives/testing.test.js +3 -3
  27. package/lib/vendor/blamejs/test/layer-0-primitives/worm.test.js +126 -0
  28. package/package.json +2 -2
  29. package/lib/vendor/blamejs/release-notes/v0.12.0.json +0 -64
  30. package/lib/vendor/blamejs/release-notes/v0.12.1.json +0 -32
  31. package/lib/vendor/blamejs/release-notes/v0.12.10.json +0 -65
  32. package/lib/vendor/blamejs/release-notes/v0.12.11.json +0 -39
  33. package/lib/vendor/blamejs/release-notes/v0.12.12.json +0 -48
  34. package/lib/vendor/blamejs/release-notes/v0.12.13.json +0 -31
  35. package/lib/vendor/blamejs/release-notes/v0.12.14.json +0 -18
  36. package/lib/vendor/blamejs/release-notes/v0.12.15.json +0 -27
  37. package/lib/vendor/blamejs/release-notes/v0.12.16.json +0 -18
  38. package/lib/vendor/blamejs/release-notes/v0.12.17.json +0 -22
  39. package/lib/vendor/blamejs/release-notes/v0.12.18.json +0 -22
  40. package/lib/vendor/blamejs/release-notes/v0.12.19.json +0 -22
  41. package/lib/vendor/blamejs/release-notes/v0.12.2.json +0 -45
  42. package/lib/vendor/blamejs/release-notes/v0.12.20.json +0 -18
  43. package/lib/vendor/blamejs/release-notes/v0.12.21.json +0 -27
  44. package/lib/vendor/blamejs/release-notes/v0.12.22.json +0 -18
  45. package/lib/vendor/blamejs/release-notes/v0.12.23.json +0 -18
  46. package/lib/vendor/blamejs/release-notes/v0.12.24.json +0 -18
  47. package/lib/vendor/blamejs/release-notes/v0.12.25.json +0 -18
  48. package/lib/vendor/blamejs/release-notes/v0.12.26.json +0 -30
  49. package/lib/vendor/blamejs/release-notes/v0.12.27.json +0 -26
  50. package/lib/vendor/blamejs/release-notes/v0.12.28.json +0 -26
  51. package/lib/vendor/blamejs/release-notes/v0.12.29.json +0 -31
  52. package/lib/vendor/blamejs/release-notes/v0.12.3.json +0 -23
  53. package/lib/vendor/blamejs/release-notes/v0.12.30.json +0 -18
  54. package/lib/vendor/blamejs/release-notes/v0.12.31.json +0 -18
  55. package/lib/vendor/blamejs/release-notes/v0.12.32.json +0 -27
  56. package/lib/vendor/blamejs/release-notes/v0.12.33.json +0 -31
  57. package/lib/vendor/blamejs/release-notes/v0.12.34.json +0 -18
  58. package/lib/vendor/blamejs/release-notes/v0.12.35.json +0 -22
  59. package/lib/vendor/blamejs/release-notes/v0.12.36.json +0 -18
  60. package/lib/vendor/blamejs/release-notes/v0.12.37.json +0 -27
  61. package/lib/vendor/blamejs/release-notes/v0.12.38.json +0 -18
  62. package/lib/vendor/blamejs/release-notes/v0.12.39.json +0 -18
  63. package/lib/vendor/blamejs/release-notes/v0.12.4.json +0 -19
  64. package/lib/vendor/blamejs/release-notes/v0.12.40.json +0 -18
  65. package/lib/vendor/blamejs/release-notes/v0.12.41.json +0 -18
  66. package/lib/vendor/blamejs/release-notes/v0.12.42.json +0 -18
  67. package/lib/vendor/blamejs/release-notes/v0.12.43.json +0 -18
  68. package/lib/vendor/blamejs/release-notes/v0.12.44.json +0 -18
  69. package/lib/vendor/blamejs/release-notes/v0.12.45.json +0 -18
  70. package/lib/vendor/blamejs/release-notes/v0.12.46.json +0 -18
  71. package/lib/vendor/blamejs/release-notes/v0.12.47.json +0 -18
  72. package/lib/vendor/blamejs/release-notes/v0.12.48.json +0 -22
  73. package/lib/vendor/blamejs/release-notes/v0.12.49.json +0 -31
  74. package/lib/vendor/blamejs/release-notes/v0.12.5.json +0 -40
  75. package/lib/vendor/blamejs/release-notes/v0.12.50.json +0 -18
  76. package/lib/vendor/blamejs/release-notes/v0.12.51.json +0 -18
  77. package/lib/vendor/blamejs/release-notes/v0.12.52.json +0 -18
  78. package/lib/vendor/blamejs/release-notes/v0.12.53.json +0 -18
  79. package/lib/vendor/blamejs/release-notes/v0.12.54.json +0 -18
  80. package/lib/vendor/blamejs/release-notes/v0.12.55.json +0 -18
  81. package/lib/vendor/blamejs/release-notes/v0.12.56.json +0 -27
  82. package/lib/vendor/blamejs/release-notes/v0.12.57.json +0 -18
  83. package/lib/vendor/blamejs/release-notes/v0.12.58.json +0 -22
  84. package/lib/vendor/blamejs/release-notes/v0.12.6.json +0 -45
  85. package/lib/vendor/blamejs/release-notes/v0.12.60.json +0 -18
  86. package/lib/vendor/blamejs/release-notes/v0.12.61.json +0 -18
  87. package/lib/vendor/blamejs/release-notes/v0.12.62.json +0 -18
  88. package/lib/vendor/blamejs/release-notes/v0.12.63.json +0 -27
  89. package/lib/vendor/blamejs/release-notes/v0.12.64.json +0 -18
  90. package/lib/vendor/blamejs/release-notes/v0.12.65.json +0 -27
  91. package/lib/vendor/blamejs/release-notes/v0.12.66.json +0 -18
  92. package/lib/vendor/blamejs/release-notes/v0.12.68.json +0 -27
  93. package/lib/vendor/blamejs/release-notes/v0.12.69.json +0 -27
  94. package/lib/vendor/blamejs/release-notes/v0.12.7.json +0 -86
  95. package/lib/vendor/blamejs/release-notes/v0.12.8.json +0 -81
  96. package/lib/vendor/blamejs/release-notes/v0.12.9.json +0 -61
@@ -89,8 +89,10 @@ The framework bundles the surface a typical Node app reaches for. Every primitiv
89
89
  - **Workflow gates** — break-glass column gates with second-factor + audit (`b.breakGlass`); two-person-rule m-of-n approval with cooling-off lock + cancellation (`b.dualControl`)
90
90
  - **Financial / Open Banking** — FAPI 2.0 Final composite posture (PAR + PKCE-S256 + DPoP-or-mTLS + RFC 9207); runtime enforcement helpers `b.fapi2.assertCallback` (refuses missing iss + bare-param under message-signing) and `b.fapi2.assertAuthzRequest` (refuses non-JAR); CFPB §1033 / FDX 6.0 consumer-financial-data-sharing wrapper (`b.fdx`)
91
91
  - **Data-subject coordination** — cross-table export / rectify / erase / restrict / objection (`b.subject`, `b.subject.eraseHard`); subject-level legal-hold registry consulted by erase + retention paths (FRCP Rule 26/37(e), GDPR Art 17(3)(e), SEC Rule 17a-4, HIPAA §164.530(j)(2)) (`b.legalHold`)
92
+ - **WORM retention** — write-once-read-many records over any backing store (`b.worm.create`): `compliance` / `governance` Object-Lock modes, extend-only `retainUntil`, legal holds, and a tamper-evident SHA3-512 digest verified on read — the store-agnostic application-level companion to `b.objectStore`'s S3 Object Lock, for sealed-DB / filesystem / non-S3 backends (SEC 17a-4(f), CFTC 1.31, FINRA 4511)
92
93
  - **Account safety** — adaptive bot-challenge staircase (`b.authBotChallenge`); session-to-device-posture binding with fail-closed verify (`b.sessionDeviceBinding`)
93
94
  - **Anonymous authorization** — Privacy Pass origin side (RFC 9577/9578 — `b.privacyPass`): issue a `WWW-Authenticate: PrivateToken` challenge and verify a presented Blind-RSA (type 0x0002) token against the issuer public key, with no issuer callback and no client identity
95
+ - **Oblivious PRF** — RFC 9497 OPRF / VOPRF (`b.crypto.oprf.suite`): learn `F(serverKey, input)` without the server seeing the input — the primitive behind password hardening (pepper a password the server never sees), private set intersection, and Privacy Pass; `oprf` (base) + `voprf` (verifiable, DLEQ-proof) modes over ristretto255-SHA512 / P-256 / P-384 / P-521; validated against the RFC 9497 Appendix-A vectors
94
96
  ### Crypto
95
97
 
96
98
  - **At-rest envelope** — envelope-versioned PQC (ML-KEM-1024 + P-384 hybrid, XChaCha20-Poly1305, SHAKE256); vault sealing (`b.crypto`, `b.vault`)
@@ -131,7 +133,7 @@ The framework bundles the surface a typical Node app reaches for. Every primitiv
131
133
  - In-process CIDR fence (`b.middleware.networkAllowlist`)
132
134
  - `Cache-Control: no-store` on every 401 from `requireAuth` / `requireAal` / `requireStepUp` per RFC 9111 §5.2.2.5
133
135
  - **Outbound HTTP client** — HTTP/1.1 + HTTP/2 with SSRF gate (cloud-metadata IPs hard-denied; private / loopback / link-local overridable per call); scheme + userinfo + per-host destination allowlist; redirects, multipart, interceptors, progress, encrypted cookie jar (`b.httpClient`, `b.ssrfGuard`, `b.safeUrl`)
134
- - **Network configurability (`b.network`)** — env-driven NTP / NTS (RFC 8915), IPv4/IPv6 NTP, DNS with IPv6 / DoH / DoT (private-CA pinning) / cache / lookup timeout; local DNSSEC signature verification (RFC 4035 — `b.network.dns.dnssec.verifyRrset` over a canonicalised RRset against RSA / ECDSA P-256·P-384 / Ed25519 DNSKEYs, plus DS-digest + key-tag, plus `verifyDenial` for NSEC / NSEC3 (RFC 5155) NXDOMAIN / NODATA proofs with iteration caps + Opt-Out handling, plus `verifyChain` to validate a full root→TLD→zone delegation chain against the pinned IANA root anchors) so a resolver client can verify both positive and negative answers instead of trusting the upstream AD bit; DANE / TLSA certificate matching (RFC 6698/7671 — `b.network.dns.dane.matchCertificate`) to pin a service's key through DNSSEC instead of a public CA; outbound HTTP proxy (`HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY`); runtime DPI trust-store CA additions; application-level heartbeats; TCP socket defaults
136
+ - **Network configurability (`b.network`)** — env-driven NTP / NTS (RFC 8915), IPv4/IPv6 NTP, DNS with IPv6 / DoH / DoT (private-CA pinning) / cache / lookup timeout; local DNSSEC signature verification (RFC 4035 — `b.network.dns.dnssec.verifyRrset` over a canonicalised RRset against RSA / ECDSA P-256·P-384 / Ed25519 DNSKEYs, plus DS-digest + key-tag, plus `verifyDenial` for NSEC / NSEC3 (RFC 5155) NXDOMAIN / NODATA proofs with iteration caps + Opt-Out handling, plus `verifyChain` to validate a full root→TLD→zone delegation chain against the pinned IANA root anchors) so a resolver client can verify both positive and negative answers instead of trusting the upstream AD bit; DANE / TLSA certificate matching (RFC 6698/7671 — `b.network.dns.dane.matchCertificate`) to pin a service's key through DNSSEC instead of a public CA; TSIG transaction signatures (RFC 8945 — `b.network.dns.tsig.sign` / `verify`) for shared-key HMAC authentication of zone transfers, dynamic updates, and query/response pairs, with constant-time MAC compare + fudge-window check (verified against dnspython); outbound HTTP proxy (`HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY`); runtime DPI trust-store CA additions; application-level heartbeats; TCP socket defaults
135
137
  - **Error pages** — operator-rendered, no app-frame leakage (`b.errorPage`)
136
138
  ### Defensive parsers
137
139
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 1,
3
- "frameworkVersion": "0.12.69",
4
- "createdAt": "2026-05-26T14:58:13.295Z",
3
+ "frameworkVersion": "0.13.1",
4
+ "createdAt": "2026-05-26T20:56:45.702Z",
5
5
  "exports": {
6
6
  "a2a": {
7
7
  "type": "object",
@@ -13951,6 +13951,23 @@
13951
13951
  "type": "function",
13952
13952
  "arity": 3
13953
13953
  },
13954
+ "oprf": {
13955
+ "type": "object",
13956
+ "members": {
13957
+ "OprfError": {
13958
+ "type": "function",
13959
+ "arity": 4
13960
+ },
13961
+ "SUITES": {
13962
+ "type": "instance",
13963
+ "ctorName": "Array"
13964
+ },
13965
+ "suite": {
13966
+ "type": "function",
13967
+ "arity": 1
13968
+ }
13969
+ }
13970
+ },
13954
13971
  "randomInt": {
13955
13972
  "type": "function",
13956
13973
  "arity": 2
@@ -42208,6 +42225,69 @@
42208
42225
  "type": "function",
42209
42226
  "arity": 1
42210
42227
  },
42228
+ "tsig": {
42229
+ "type": "object",
42230
+ "members": {
42231
+ "ALGORITHMS": {
42232
+ "type": "object",
42233
+ "members": {
42234
+ "hmac-sha224": {
42235
+ "type": "primitive",
42236
+ "valueType": "string"
42237
+ },
42238
+ "hmac-sha256": {
42239
+ "type": "primitive",
42240
+ "valueType": "string"
42241
+ },
42242
+ "hmac-sha384": {
42243
+ "type": "primitive",
42244
+ "valueType": "string"
42245
+ },
42246
+ "hmac-sha512": {
42247
+ "type": "primitive",
42248
+ "valueType": "string"
42249
+ }
42250
+ }
42251
+ },
42252
+ "ERROR": {
42253
+ "type": "object",
42254
+ "members": {
42255
+ "BADKEY": {
42256
+ "type": "primitive",
42257
+ "valueType": "number"
42258
+ },
42259
+ "BADSIG": {
42260
+ "type": "primitive",
42261
+ "valueType": "number"
42262
+ },
42263
+ "BADTIME": {
42264
+ "type": "primitive",
42265
+ "valueType": "number"
42266
+ },
42267
+ "BADTRUNC": {
42268
+ "type": "primitive",
42269
+ "valueType": "number"
42270
+ },
42271
+ "NOERROR": {
42272
+ "type": "primitive",
42273
+ "valueType": "number"
42274
+ }
42275
+ }
42276
+ },
42277
+ "TsigError": {
42278
+ "type": "function",
42279
+ "arity": 4
42280
+ },
42281
+ "sign": {
42282
+ "type": "function",
42283
+ "arity": 2
42284
+ },
42285
+ "verify": {
42286
+ "type": "function",
42287
+ "arity": 2
42288
+ }
42289
+ }
42290
+ },
42211
42291
  "useDesignatedResolvers": {
42212
42292
  "type": "function",
42213
42293
  "arity": 1
@@ -50270,6 +50350,23 @@
50270
50350
  }
50271
50351
  }
50272
50352
  },
50353
+ "worm": {
50354
+ "type": "object",
50355
+ "members": {
50356
+ "MODES": {
50357
+ "type": "instance",
50358
+ "ctorName": "Array"
50359
+ },
50360
+ "WormError": {
50361
+ "type": "function",
50362
+ "arity": 4
50363
+ },
50364
+ "create": {
50365
+ "type": "function",
50366
+ "arity": 1
50367
+ }
50368
+ }
50369
+ },
50273
50370
  "wsClient": {
50274
50371
  "type": "object",
50275
50372
  "members": {
@@ -57,6 +57,7 @@ var crypto = require("./lib/crypto");
57
57
  // remembering separate top-level namespaces. Implementations live in
58
58
  // the dedicated lib files; these are thin aliases.
59
59
  crypto.hpke = require("./lib/crypto-hpke");
60
+ crypto.oprf = require("./lib/crypto-oprf");
60
61
  // Both PQ-HPKE drafts behind one opt-in sub-namespace — see
61
62
  // lib/crypto-hpke-pq.js. Operators that need a draft-codepoint
62
63
  // shape reach for b.crypto.hpke.pq.connolly / .wg explicitly; the
@@ -371,6 +372,7 @@ var fileUpload = require("./lib/file-upload");
371
372
  var dualControl = require("./lib/dual-control");
372
373
  var retention = require("./lib/retention");
373
374
  var legalHold = require("./lib/legal-hold");
375
+ var worm = require("./lib/worm");
374
376
  var network = require("./lib/network");
375
377
  var cloudEvents = require("./lib/cloud-events");
376
378
  var dsr = require("./lib/dsr");
@@ -709,6 +711,7 @@ module.exports = {
709
711
  dualControl: dualControl,
710
712
  retention: retention,
711
713
  legalHold: legalHold,
714
+ worm: worm,
712
715
  network: network,
713
716
  cloudEvents: cloudEvents,
714
717
  dsr: dsr,
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ /**
3
+ * @module b.crypto.oprf
4
+ * @nav Crypto
5
+ * @title OPRF
6
+ *
7
+ * @intro
8
+ * Oblivious Pseudorandom Functions per <a
9
+ * href="https://www.rfc-editor.org/rfc/rfc9497">RFC 9497</a>. An OPRF lets
10
+ * a client learn <code>F(serverKey, input)</code> — a keyed pseudorandom
11
+ * value — <em>without</em> the server learning the input and without the
12
+ * client learning the key. It is the primitive behind Privacy Pass
13
+ * tokens, password-breach checks and password hardening (the server can
14
+ * pepper a password without ever seeing it), and private set
15
+ * intersection.
16
+ *
17
+ * Two modes are provided per RFC 9497: <code>oprf</code> (base) and
18
+ * <code>voprf</code> (verifiable — the client can prove the server used
19
+ * the committed key, via a DLEQ proof carried in the evaluation). The
20
+ * partially-oblivious <code>poprf</code> mode is not yet exposed: the
21
+ * vendored <code>@noble/curves</code> does not implement it, so it will
22
+ * be added when upstream ships it rather than stubbed here.
23
+ * The base protocol is: the client <code>blind</code>s its input to a
24
+ * group element, the server <code>blindEvaluate</code>s it with its
25
+ * secret key, and the client <code>finalize</code>s by un-blinding and
26
+ * hashing. Because un-blinding cancels the blind, the output depends only
27
+ * on the key and the input — a server-side <code>evaluate</code> produces
28
+ * the same value directly.
29
+ *
30
+ * <code>suite(name)</code> returns the suite for one of the RFC 9497
31
+ * ciphersuites — <code>ristretto255-sha512</code> (the Privacy Pass
32
+ * default), <code>p256-sha256</code>, <code>p384-sha384</code>, or
33
+ * <code>p521-sha512</code> — each exposing the three modes. Group and
34
+ * hash-to-curve operations come from the vendored <code>@noble/curves</code>.
35
+ * Byte arguments are <code>Uint8Array</code> / <code>Buffer</code>;
36
+ * returned elements and outputs are <code>Uint8Array</code>.
37
+ *
38
+ * @card
39
+ * RFC 9497 Oblivious PRFs — learn <code>F(key, input)</code> without the
40
+ * server seeing the input (oprf / voprf / poprf modes; ristretto255 / P-256
41
+ * / P-384 / P-521 suites). The primitive behind Privacy Pass, password
42
+ * hardening, and private set intersection.
43
+ */
44
+
45
+ var nobleCurves = require("./vendor/noble-curves.cjs");
46
+ var { defineClass } = require("./framework-error");
47
+
48
+ var OprfError = defineClass("OprfError", { alwaysPermanent: true });
49
+
50
+ // RFC 9497 ciphersuite name → vendored @noble/curves OPRF implementation.
51
+ var SUITE_IMPL = {
52
+ "ristretto255-sha512": nobleCurves.ristretto255_oprf,
53
+ "p256-sha256": nobleCurves.p256_oprf,
54
+ "p384-sha384": nobleCurves.p384_oprf,
55
+ "p521-sha512": nobleCurves.p521_oprf,
56
+ };
57
+ var SUITES = Object.keys(SUITE_IMPL);
58
+
59
+ /**
60
+ * @primitive b.crypto.oprf.suite
61
+ * @signature b.crypto.oprf.suite(name)
62
+ * @since 0.13.0
63
+ * @status stable
64
+ *
65
+ * Return the RFC 9497 OPRF suite for <code>name</code> — one of
66
+ * <code>"ristretto255-sha512"</code>, <code>"p256-sha256"</code>,
67
+ * <code>"p384-sha384"</code>, or <code>"p521-sha512"</code> (case
68
+ * insensitive). The result is <code>{ name, oprf, voprf }</code>; each mode
69
+ * object has the protocol functions:
70
+ *
71
+ * <ul>
72
+ * <li><code>deriveKeyPair(seed, info)</code> / <code>generateKeyPair()</code>
73
+ * → <code>{ secretKey, publicKey }</code></li>
74
+ * <li><code>blind(input)</code> → <code>{ blind, blinded }</code> (client)</li>
75
+ * <li><code>oprf.blindEvaluate(secretKey, blinded)</code> → evaluation
76
+ * element; <code>voprf.blindEvaluate(secretKey, publicKey, blinded)</code>
77
+ * → <code>{ evaluated, proof }</code> (server)</li>
78
+ * <li><code>oprf.finalize(input, blind, evaluation)</code> /
79
+ * <code>voprf.finalize(input, blind, evaluated, blinded, publicKey, proof)</code>
80
+ * → output bytes (client; <code>voprf</code> verifies the proof and
81
+ * throws if it does not match <code>publicKey</code>)</li>
82
+ * <li><code>evaluate(secretKey, input)</code> → output bytes (server-side,
83
+ * non-oblivious — equals the client's <code>finalize</code> output)</li>
84
+ * </ul>
85
+ *
86
+ * The partially-oblivious <code>poprf</code> mode is intentionally absent
87
+ * (not implemented by the vendored <code>@noble/curves</code>). Throws
88
+ * <code>OprfError</code> for an unknown suite name.
89
+ *
90
+ * @example
91
+ * var s = b.crypto.oprf.suite("ristretto255-sha512");
92
+ * var kp = s.oprf.deriveKeyPair(seed, Buffer.from("my-app"));
93
+ * var c = s.oprf.blind(Buffer.from("user@example.com")); // client
94
+ * var ev = s.oprf.blindEvaluate(kp.secretKey, c.blinded); // server
95
+ * var out = s.oprf.finalize(Buffer.from("user@example.com"), c.blind, ev);
96
+ * // out === s.oprf.evaluate(kp.secretKey, Buffer.from("user@example.com"))
97
+ */
98
+ function suite(name) {
99
+ var impl = SUITE_IMPL[String(name).toLowerCase()];
100
+ if (!impl) throw new OprfError("oprf/bad-suite", "crypto.oprf.suite: unknown suite '" + name + "'; expected one of " + SUITES.join(", "));
101
+ // Expose only the modes the vendored @noble/curves implements (base +
102
+ // verifiable). poprf is omitted rather than surfaced as an empty stub.
103
+ return { name: impl.name, oprf: impl.oprf, voprf: impl.voprf };
104
+ }
105
+
106
+ module.exports = {
107
+ suite: suite,
108
+ SUITES: SUITES,
109
+ OprfError: OprfError,
110
+ };