diff --git a/.changeset/README.md b/.changeset/README.md deleted file mode 100644 index e5b6d8d..0000000 --- a/.changeset/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Changesets - -Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works -with multi-package repos, or single-package repos to help you version and publish your code. You can -find the full documentation for it [in our repository](https://github.com/changesets/changesets) - -We have a quick list of common questions to get you started engaging with this project in -[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/.changeset/config.json b/.changeset/config.json deleted file mode 100644 index 057d1e7..0000000 --- a/.changeset/config.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://unpkg.com/@changesets/config@3.1.2/schema.json", - "changelog": "@changesets/cli/changelog", - "commit": false, - "fixed": [["@frosts/*"]], - "linked": [], - "access": "public", - "baseBranch": "main", - "updateInternalDependencies": "patch", - "ignore": [] -} diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 236d188..0000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "mode": "pre", - "tag": "alpha", - "initialVersions": { - "@frosts/core": "0.2.2-alpha.2", - "@frosts/ed448": "0.2.2-alpha.2", - "@frosts/ed25519": "0.2.2-alpha.2", - "@frosts/p256": "0.2.2-alpha.2", - "@frosts/rerandomized": "0.2.2-alpha.2", - "@frosts/ristretto255": "0.2.2-alpha.2", - "@frosts/secp256k1": "0.2.2-alpha.2", - "@frosts/secp256k1-tr": "0.2.2-alpha.2", - "@frosts/eslint": "0.2.2-alpha.2", - "@frosts/tsconfig": "0.2.2-alpha.2" - }, - "changesets": [] -} diff --git a/.github/markdown-link-check-config.json b/.github/markdown-link-check-config.json new file mode 100644 index 0000000..7e2d2f2 --- /dev/null +++ b/.github/markdown-link-check-config.json @@ -0,0 +1,10 @@ +{ + "ignorePatterns": [ + { + "pattern": "^https?://(www\\.)?npmjs\\.com/" + }, + { + "pattern": "^https?://eprint\\.iacr\\.org/" + } + ] +} diff --git a/.github/workflows/links.yml b/.github/workflows/links.yml index 294c58d..ef3ec39 100644 --- a/.github/workflows/links.yml +++ b/.github/workflows/links.yml @@ -17,3 +17,4 @@ jobs: uses: gaurav-nelson/github-action-markdown-link-check@v1 with: use-quiet-mode: "yes" + config-file: ".github/markdown-link-check-config.json" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7d5b12..c0a574c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -59,10 +59,16 @@ jobs: run: bun run scripts/replace-workspace-protocols.ts - name: Publish to NPM - run: bun changeset publish --provenance + run: | + for PKG in packages/*; do + if [ -f "$PKG/package.json" ]; then + echo "Publishing $PKG ..." + (cd "$PKG" && npm publish --provenance --access public --tag alpha) + fi + done env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} tag: name: Add NPM Tag (${{ matrix.tag }}) diff --git a/README.md b/README.md index fa089be..67debae 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # frosTS - FROST for TypeScript -[![Version](https://img.shields.io/badge/version-0.2.2--alpha.3-green)](https://github.com/leonardocustodio/bcts/releases) -[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue)](https://www.typescriptlang.org/) +[![Version](https://img.shields.io/badge/version-0.2.2--alpha.4-green)](https://github.com/leonardocustodio/bcts/releases) +[![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue)](https://www.typescriptlang.org/) [![Monorepo](https://img.shields.io/badge/Monorepo-Turborepo-blueviolet)](https://turbo.build/) [![Package Manager](https://img.shields.io/badge/Package%20Manager-Bun-FFD700)](https://bun.sh/) [![RFC 9591](https://img.shields.io/badge/RFC-9591-informational)](https://datatracker.ietf.org/doc/rfc9591/) diff --git a/package.json b/package.json index ae48e0e..ae7a86d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "frosts", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "private": true, "description": "TypeScript implementation of FROST (Flexible Round-Optimized Schnorr Threshold) signatures for threshold cryptography", "author": "Leonardo Custodio (https://github.com/leonardocustodio)", @@ -41,10 +41,9 @@ "bump-version": "bun run scripts/bump-version.ts" }, "devDependencies": { - "@changesets/cli": "^2.29.8", - "prettier": "^3.8.1", - "turbo": "^2.7.6", - "typescript": "^5.9.3" + "prettier": "^3.8.4", + "turbo": "^2.9.18", + "typescript": "^6.0.3" }, "packageManager": "bun@1.3.6", "workspaces": [ diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md new file mode 100644 index 0000000..87acb70 --- /dev/null +++ b/packages/core/CHANGELOG.md @@ -0,0 +1,14 @@ +# @frosts/core + +## 0.2.2-alpha.4 + +### Patch Changes + +- Fixed `@frosts/core` crashing at import time for consumers that do not have `vitest` installed. The generic, parameterized test helpers — and their top-level `vitest` import — are no longer bundled into the public entry points (`dist/index.js`, `dist/index.cjs`, `dist/index.iife.js`). They are now published under the dedicated `@frosts/core/tests` subpath instead. Consumers of the helpers should update their imports: + + ```diff + -import { tests } from "@frosts/core"; + +import * as tests from "@frosts/core/tests"; + ``` + +- Updated all dependencies to their latest versions (TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1, typedoc 0.28.19, @types/node 26). diff --git a/packages/core/package.json b/packages/core/package.json index ab38538..b7756a6 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/core", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "Core types and traits for FROST (Flexible Round-Optimized Schnorr Threshold) signatures", "license": "MIT", @@ -24,12 +24,20 @@ "import": "./dist/index.js", "require": "./dist/index.cjs", "default": "./dist/index.js" - } + }, + "./tests": { + "types": "./dist/tests/index.d.ts", + "import": "./dist/tests/index.js", + "require": "./dist/tests/index.cjs", + "default": "./dist/tests/index.js" + }, + "./package.json": "./package.json" }, "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -56,16 +64,16 @@ }, "dependencies": {}, "devDependencies": { - "@eslint/js": "^9.39.2", + "@eslint/js": "^10.0.1", "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "fast-check": "^4.5.3", - "prettier": "^3.8.1", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "fast-check": "^4.8.0", + "prettier": "^3.8.4", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/core/src/identifier.ts b/packages/core/src/identifier.ts index f7e5a21..c4af12b 100644 --- a/packages/core/src/identifier.ts +++ b/packages/core/src/identifier.ts @@ -76,7 +76,7 @@ export class Identifier { if (scalar === null || scalar === undefined) { throw FrostError.identifierDerivationNotSupported(); } - return Identifier.create(ciphersuite, scalar as Scalar); + return Identifier.create(ciphersuite, scalar); } /** @@ -139,7 +139,7 @@ export class Identifier { } } - return Identifier.create(ciphersuite, sum as Scalar); + return Identifier.create(ciphersuite, sum); } /** diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d0ef476..c2c74e1 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -88,6 +88,12 @@ export * from "./batch.js"; // Signature aggregation export * from "./aggregate.js"; -// Generic test functions for ciphersuite packages -// These are parameterized test functions that can be called with a specific ciphersuite -export * as tests from "./tests/index.js"; +// NOTE: The generic, parameterized test functions for ciphersuite packages are +// intentionally NOT exported from this entry point. They depend on `vitest` +// (a dev-only dependency), so re-exporting them here would force every runtime +// consumer of `@frosts/core` to have `vitest` installed. They are published +// under the dedicated `@frosts/core/tests` subpath instead: +// +// import * as tests from "@frosts/core/tests"; +// +// See ./tests/index.ts. diff --git a/packages/core/src/random.ts b/packages/core/src/random.ts index f22963e..3a4ce66 100644 --- a/packages/core/src/random.ts +++ b/packages/core/src/random.ts @@ -29,7 +29,7 @@ export interface RandomSource { export class WebCryptoRandomSource implements RandomSource { fill(array: Uint8Array): void { if (globalThis.crypto?.getRandomValues !== undefined) { - globalThis.crypto.getRandomValues(array); + globalThis.crypto.getRandomValues(array as Uint8Array); } else { throw new Error("Web Crypto API not available"); } diff --git a/packages/core/src/signing_key.ts b/packages/core/src/signing_key.ts index 4142130..8948e05 100644 --- a/packages/core/src/signing_key.ts +++ b/packages/core/src/signing_key.ts @@ -182,7 +182,7 @@ export class SigningKey { */ zeroize(): void { const field = this._ciphersuite.group.field; - this._scalar = field.zero() as Scalar; + this._scalar = field.zero(); } /** diff --git a/packages/core/src/tests/batch.ts b/packages/core/src/tests/batch.ts index bcb6906..aad257e 100644 --- a/packages/core/src/tests/batch.ts +++ b/packages/core/src/tests/batch.ts @@ -46,7 +46,7 @@ export function checkBatchVerify(ciphersuite: C, rng: Cry batch.queue(item); // Create RNG function that generates random scalars for blinding - const rngFn = (): Scalar => ciphersuite.group.field.random(rng) as Scalar; + const rngFn = (): Scalar => ciphersuite.group.field.random(rng); // Verify the batch - should not throw batch.verify(rngFn); @@ -103,7 +103,7 @@ export function checkBadBatchVerify(ciphersuite: C, rng: } // Create RNG function for batch verification - const rngFn = (): Scalar => ciphersuite.group.field.random(rng) as Scalar; + const rngFn = (): Scalar => ciphersuite.group.field.random(rng); // Batch verification should fail due to the bad signature let batchFailed = false; @@ -162,7 +162,7 @@ export function checkEmptyBatchVerify(ciphersuite: C, rng const batch = new Verifier(ciphersuite); // Create RNG function for batch verification - const rngFn = (): Scalar => ciphersuite.group.field.random(rng) as Scalar; + const rngFn = (): Scalar => ciphersuite.group.field.random(rng); // Empty batch should fail let emptyFailed = false; diff --git a/packages/core/src/tests/helpers.ts b/packages/core/src/tests/helpers.ts index ff07359..7a3c4a2 100644 --- a/packages/core/src/tests/helpers.ts +++ b/packages/core/src/tests/helpers.ts @@ -78,7 +78,7 @@ export function createSecureRng(): CryptoRng { return { fill(buffer: Uint8Array): void { if (globalThis.crypto?.getRandomValues !== undefined) { - globalThis.crypto.getRandomValues(buffer); + globalThis.crypto.getRandomValues(buffer as Uint8Array); } else { // Node.js environment - use crypto.getRandomValues which is available in modern Node throw new Error("No secure random source available - Web Crypto API required"); diff --git a/packages/core/src/tests/index.ts b/packages/core/src/tests/index.ts index 05009c3..dc33279 100644 --- a/packages/core/src/tests/index.ts +++ b/packages/core/src/tests/index.ts @@ -8,7 +8,7 @@ * * Usage in a ciphersuite package: * ```typescript - * import { tests } from "@frosts/core"; + * import * as tests from "@frosts/core/tests"; * import { Ristretto255Sha512 } from "../src/index.js"; * * describe("CoefficientCommitment", () => { diff --git a/packages/core/src/tests/refresh.ts b/packages/core/src/tests/refresh.ts index e38ec08..76786c7 100644 --- a/packages/core/src/tests/refresh.ts +++ b/packages/core/src/tests/refresh.ts @@ -133,7 +133,7 @@ export async function checkRefreshSharesWithDealerFailsWithInvalidSigners { computeRefreshingShares(ciphersuite, pubKeyPackage, identifiers, rng); - }).toThrow(expectedError as Error); + }).toThrow(expectedError); } /** diff --git a/packages/core/src/traits.ts b/packages/core/src/traits.ts index 278a30d..e44106d 100644 --- a/packages/core/src/traits.ts +++ b/packages/core/src/traits.ts @@ -35,7 +35,7 @@ export function randomNonzero(field: F, rng: CryptoRng): Scalar let scalar: ScalarOf; do { scalar = field.random(rng) as ScalarOf; - } while (field.isZero(scalar as never)); + } while (field.isZero(scalar)); return scalar; } @@ -53,8 +53,8 @@ export function defaultGenerateNonce( const group = ciphersuite.group; const field = group.field; const k = randomNonzero(field, rng); - const R = group.scalarBaseMul(k as never); - return [k as Scalar, R as Element]; + const R = group.scalarBaseMul(k); + return [k, R]; } /** diff --git a/packages/core/tests/helpers.ts b/packages/core/tests/helpers.ts index f5b422c..25562ef 100644 --- a/packages/core/tests/helpers.ts +++ b/packages/core/tests/helpers.ts @@ -78,7 +78,7 @@ export function createSecureRng(): CryptoRng { typeof globalThis.crypto !== "undefined" && globalThis.crypto.getRandomValues !== undefined ) { - globalThis.crypto.getRandomValues(buffer); + globalThis.crypto.getRandomValues(buffer as Uint8Array); } else { // Node.js environment - use crypto.getRandomValues which is available in modern Node throw new Error("No secure random source available - Web Crypto API required"); diff --git a/packages/core/tests/helpers/ciphersuite.ts b/packages/core/tests/helpers/ciphersuite.ts index 227863c..30a7ba2 100644 --- a/packages/core/tests/helpers/ciphersuite.ts +++ b/packages/core/tests/helpers/ciphersuite.ts @@ -37,6 +37,7 @@ export async function getTestCiphersuite(): Promise { "Failed to load @frosts/ed25519 for testing. " + "Make sure the ed25519 package is built before running core tests. " + `Original error: ${error}`, + { cause: error }, ); } } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 8a4db53..597da00 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -4,6 +4,13 @@ "lib": ["ES2022", "DOM"], "skipLibCheck": true, "types": ["vitest/globals"], + // The interop tests resolve @frosts/ed25519 to its source (below) so they + // can be type-checked without a prior build of that package. TypeScript 6 + // enforces that every source file in the program lives under `rootDir` + // (TS6059), so widen it to the workspace `packages/` directory to admit the + // pulled-in ed25519 sources. This only affects type-checking — the build is + // produced by tsdown, which derives output paths from its own entries. + "rootDir": "..", "paths": { "@frosts/ed25519": ["../ed25519/src/index.ts"] } diff --git a/packages/core/tsdown.config.ts b/packages/core/tsdown.config.ts index 2af46fe..eb01dab 100644 --- a/packages/core/tsdown.config.ts +++ b/packages/core/tsdown.config.ts @@ -1,33 +1,83 @@ import { defineConfig } from "tsdown"; -export default defineConfig({ - entry: ["src/index.ts"], - format: ["esm", "cjs", "iife"], - dts: true, - clean: true, - treeshake: true, - splitting: false, - sourcemap: true, - minify: false, - target: "es2022", - outDir: "dist", - external: [ - // Test dependencies - not bundled into production - "vitest", - "@vitest/spy", - "@vitest/expect", - "@vitest/utils", - "@vitest/pretty-format", - "tinyrainbow", - "chai", - // Node.js built-ins - /^node:/, - ], - platform: "neutral", - globalName: "frostsCore", - outputOptions: { - globals: { - vitest: "vitest", +// Test dependencies — never bundled into any output. Listing them as external +// guarantees that even the `@frosts/core/tests` subpath references them via a +// bare import instead of inlining them. +const testDependencies = [ + "vitest", + "@vitest/spy", + "@vitest/expect", + "@vitest/utils", + "@vitest/pretty-format", + "tinyrainbow", + "chai", + "fast-check", +]; + +const nodeBuiltins = /^node:/; + +export default defineConfig([ + // Library build. + // + // The public entry (`src/index.ts`) and the generic test-helper entry + // (`src/tests/index.ts`) are built together with code splitting enabled so + // that the shared core runtime (types, keys, errors, …) is emitted into + // shared chunks referenced by BOTH entries. This is what keeps a single copy + // of classes such as `FrostError` at runtime — the test helpers rely on + // `instanceof` checks against errors thrown by `@frosts/core`, so they must + // not get their own duplicate copy of the runtime. + // + // Because `src/index.ts` no longer re-exports the test helpers, `vitest` is + // only ever pulled into the `dist/tests/*` chunk — never into `dist/index.*`. + { + entry: ["src/index.ts", "src/tests/index.ts"], + format: ["esm", "cjs"], + dts: true, + clean: true, + treeshake: true, + splitting: true, + sourcemap: true, + minify: false, + target: "es2022", + outDir: "dist", + deps: { + neverBundle: [...testDependencies, nodeBuiltins], + }, + // `keys.ts` dynamically imports `./identifier` to keep a few public + // functions async while sidestepping a historical circular dependency. + // Under code splitting that module is also statically pulled into the + // shared chunk, so rolldown flags the dynamic import as ineffective for + // chunking. That is expected and harmless here, so silence just that check. + checks: { + ineffectiveDynamicImport: false, + }, + platform: "neutral", + }, + // Browser global (IIFE) build for the public entry only. + // + // IIFE output cannot be code-split, so it is built separately from the entry + // above. It only contains the public API (never the test helpers), so it is + // also free of any `vitest` import. + { + entry: ["src/index.ts"], + format: ["iife"], + dts: false, + clean: false, + treeshake: true, + splitting: false, + sourcemap: true, + minify: false, + target: "es2022", + outDir: "dist", + deps: { + neverBundle: [...testDependencies, nodeBuiltins], + }, + platform: "neutral", + globalName: "frostsCore", + outputOptions: { + globals: { + vitest: "vitest", + }, }, }, -}); +]); diff --git a/packages/ed25519/CHANGELOG.md b/packages/ed25519/CHANGELOG.md new file mode 100644 index 0000000..a8a44ca --- /dev/null +++ b/packages/ed25519/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/ed25519 + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/ed25519` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/ed25519/package.json b/packages/ed25519/package.json index e41f171..c29597c 100644 --- a/packages/ed25519/package.json +++ b/packages/ed25519/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/ed25519", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(Ed25519, SHA-512) - A Schnorr signature scheme over Ed25519 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -58,17 +59,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/ed25519/src/index.ts b/packages/ed25519/src/index.ts index 9ad4a2b..5dfb117 100644 --- a/packages/ed25519/src/index.ts +++ b/packages/ed25519/src/index.ts @@ -882,7 +882,7 @@ class Ed25519Sha512Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { pkBytes = (verifyingKey as VerifyingKey).serialize(); } else { @@ -918,7 +918,7 @@ class Ed25519Sha512Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKey).serialize(); } else { diff --git a/packages/ed25519/tests/coefficient-commitment.test.ts b/packages/ed25519/tests/coefficient-commitment.test.ts index 99c3313..80dc8d7 100644 --- a/packages/ed25519/tests/coefficient-commitment.test.ts +++ b/packages/ed25519/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ed25519Sha512 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ed25519/tests/integration.test.ts b/packages/ed25519/tests/integration.test.ts index a597779..bd79e0a 100644 --- a/packages/ed25519/tests/integration.test.ts +++ b/packages/ed25519/tests/integration.test.ts @@ -7,7 +7,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, Identifier } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { Identifier } from "@frosts/core"; import { Ed25519Sha512 } from "../src/index.js"; import { createSecureRng, diff --git a/packages/ed25519/tests/interoperability.test.ts b/packages/ed25519/tests/interoperability.test.ts index d357006..611c0d2 100644 --- a/packages/ed25519/tests/interoperability.test.ts +++ b/packages/ed25519/tests/interoperability.test.ts @@ -12,7 +12,7 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { createSecureRng, verifySignature, diff --git a/packages/ed25519/tests/vss-commitment.test.ts b/packages/ed25519/tests/vss-commitment.test.ts index 1980a44..824a6ce 100644 --- a/packages/ed25519/tests/vss-commitment.test.ts +++ b/packages/ed25519/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ed25519Sha512 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ed25519/tsdown.config.ts b/packages/ed25519/tsdown.config.ts index 604e711..8f57918 100644 --- a/packages/ed25519/tsdown.config.ts +++ b/packages/ed25519/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha2.js", - "@noble/curves/ed25519.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha2.js", + "@noble/curves/ed25519.js", + ], + }, platform: "neutral", globalName: "frostsEd25519", outputOptions: { diff --git a/packages/ed448/CHANGELOG.md b/packages/ed448/CHANGELOG.md new file mode 100644 index 0000000..3a2fe96 --- /dev/null +++ b/packages/ed448/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/ed448 + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/ed448` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/ed448/package.json b/packages/ed448/package.json index 2fc4202..f68ad06 100644 --- a/packages/ed448/package.json +++ b/packages/ed448/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/ed448", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(Ed448, SHAKE256) - A Schnorr signature scheme over Ed448 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -58,17 +59,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/ed448/src/index.ts b/packages/ed448/src/index.ts index 8324e8a..8818cc5 100644 --- a/packages/ed448/src/index.ts +++ b/packages/ed448/src/index.ts @@ -923,7 +923,7 @@ class Ed448Shake256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { pkBytes = (verifyingKey as VerifyingKey).serialize(); } else { @@ -957,7 +957,7 @@ class Ed448Shake256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKey).serialize(); } else { diff --git a/packages/ed448/tests/coefficient-commitment.test.ts b/packages/ed448/tests/coefficient-commitment.test.ts index 83c3195..6556963 100644 --- a/packages/ed448/tests/coefficient-commitment.test.ts +++ b/packages/ed448/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ed448Shake256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ed448/tests/integration.test.ts b/packages/ed448/tests/integration.test.ts index e0b40f2..739c0df 100644 --- a/packages/ed448/tests/integration.test.ts +++ b/packages/ed448/tests/integration.test.ts @@ -7,7 +7,7 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { createSecureRng, hexToBytes, diff --git a/packages/ed448/tests/vss-commitment.test.ts b/packages/ed448/tests/vss-commitment.test.ts index f94837e..6d3521b 100644 --- a/packages/ed448/tests/vss-commitment.test.ts +++ b/packages/ed448/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ed448Shake256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ed448/tsdown.config.ts b/packages/ed448/tsdown.config.ts index 0ca9e1f..c77588d 100644 --- a/packages/ed448/tsdown.config.ts +++ b/packages/ed448/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha3.js", - "@noble/curves/ed448.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha3.js", + "@noble/curves/ed448.js", + ], + }, platform: "neutral", globalName: "frostsEd448", outputOptions: { diff --git a/packages/p256/CHANGELOG.md b/packages/p256/CHANGELOG.md new file mode 100644 index 0000000..bc7b80f --- /dev/null +++ b/packages/p256/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/p256 + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/p256` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/p256/package.json b/packages/p256/package.json index a22059c..80508c5 100644 --- a/packages/p256/package.json +++ b/packages/p256/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/p256", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(P-256, SHA-256) - A Schnorr signature scheme over P-256 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -60,17 +61,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/p256/src/index.ts b/packages/p256/src/index.ts index 8c5413a..29af593 100644 --- a/packages/p256/src/index.ts +++ b/packages/p256/src/index.ts @@ -1066,7 +1066,7 @@ class P256Sha256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { pkBytes = (verifyingKey as VerifyingKey).serialize(); } else { @@ -1100,7 +1100,7 @@ class P256Sha256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKey).serialize(); } else { diff --git a/packages/p256/tests/coefficient-commitment.test.ts b/packages/p256/tests/coefficient-commitment.test.ts index 6bd7e5b..3bda294 100644 --- a/packages/p256/tests/coefficient-commitment.test.ts +++ b/packages/p256/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { P256Sha256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/p256/tests/integration.test.ts b/packages/p256/tests/integration.test.ts index 5f8bb6e..0bc693c 100644 --- a/packages/p256/tests/integration.test.ts +++ b/packages/p256/tests/integration.test.ts @@ -7,7 +7,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, Identifier } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { Identifier } from "@frosts/core"; import { createSecureRng, hexToBytes, diff --git a/packages/p256/tests/vss-commitment.test.ts b/packages/p256/tests/vss-commitment.test.ts index 93d97eb..928fe4d 100644 --- a/packages/p256/tests/vss-commitment.test.ts +++ b/packages/p256/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { P256Sha256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/p256/tsdown.config.ts b/packages/p256/tsdown.config.ts index c9b1096..41cd335 100644 --- a/packages/p256/tsdown.config.ts +++ b/packages/p256/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha2.js", - "@noble/curves/nist.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha2.js", + "@noble/curves/nist.js", + ], + }, platform: "neutral", globalName: "frostsP256", outputOptions: { diff --git a/packages/rerandomized/CHANGELOG.md b/packages/rerandomized/CHANGELOG.md new file mode 100644 index 0000000..5e5054d --- /dev/null +++ b/packages/rerandomized/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/rerandomized + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/rerandomized` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package re-exports), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated dev dependencies to their latest versions (TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/rerandomized/package.json b/packages/rerandomized/package.json index 71f4c1e..636bf72 100644 --- a/packages/rerandomized/package.json +++ b/packages/rerandomized/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/rerandomized", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "Re-randomized FROST signatures for threshold cryptography with re-randomizable keys", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -61,13 +62,13 @@ "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@eslint/js": "^9.39.2", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "prettier": "^3.8.1", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@eslint/js": "^10.0.1", + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "prettier": "^3.8.4", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/rerandomized/tsdown.config.ts b/packages/rerandomized/tsdown.config.ts index 5c87b85..c907167 100644 --- a/packages/rerandomized/tsdown.config.ts +++ b/packages/rerandomized/tsdown.config.ts @@ -11,7 +11,9 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: ["@frosts/core"], + deps: { + neverBundle: ["@frosts/core"], + }, platform: "neutral", globalName: "frostsRerandomized", outputOptions: { diff --git a/packages/ristretto255/CHANGELOG.md b/packages/ristretto255/CHANGELOG.md new file mode 100644 index 0000000..e169f67 --- /dev/null +++ b/packages/ristretto255/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/ristretto255 + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/ristretto255` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/ristretto255/package.json b/packages/ristretto255/package.json index 9eb93b8..d184308 100644 --- a/packages/ristretto255/package.json +++ b/packages/ristretto255/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/ristretto255", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(ristretto255, SHA-512) - A Schnorr signature scheme over ristretto255 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -58,17 +59,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/ristretto255/src/index.ts b/packages/ristretto255/src/index.ts index c93121a..0251a86 100644 --- a/packages/ristretto255/src/index.ts +++ b/packages/ristretto255/src/index.ts @@ -841,7 +841,7 @@ class Ristretto255Sha512Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { pkBytes = (verifyingKey as VerifyingKey).serialize(); } else { @@ -875,7 +875,7 @@ class Ristretto255Sha512Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKey).serialize(); } else { diff --git a/packages/ristretto255/tests/coefficient-commitment.test.ts b/packages/ristretto255/tests/coefficient-commitment.test.ts index 8c5402d..859f82a 100644 --- a/packages/ristretto255/tests/coefficient-commitment.test.ts +++ b/packages/ristretto255/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ristretto255Sha512 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ristretto255/tests/integration.test.ts b/packages/ristretto255/tests/integration.test.ts index d4cb905..a28fced 100644 --- a/packages/ristretto255/tests/integration.test.ts +++ b/packages/ristretto255/tests/integration.test.ts @@ -7,7 +7,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, Identifier } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { Identifier } from "@frosts/core"; import { createSecureRng, hexToBytes, diff --git a/packages/ristretto255/tests/vss-commitment.test.ts b/packages/ristretto255/tests/vss-commitment.test.ts index 419f6e9..c5ee293 100644 --- a/packages/ristretto255/tests/vss-commitment.test.ts +++ b/packages/ristretto255/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Ristretto255Sha512 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/ristretto255/tsdown.config.ts b/packages/ristretto255/tsdown.config.ts index c8cf20c..a0878fc 100644 --- a/packages/ristretto255/tsdown.config.ts +++ b/packages/ristretto255/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha2.js", - "@noble/curves/ed25519.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha2.js", + "@noble/curves/ed25519.js", + ], + }, platform: "neutral", globalName: "frostsRistretto255", outputOptions: { diff --git a/packages/secp256k1-tr/CHANGELOG.md b/packages/secp256k1-tr/CHANGELOG.md new file mode 100644 index 0000000..16bb19f --- /dev/null +++ b/packages/secp256k1-tr/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/secp256k1-tr + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/secp256k1-tr` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/secp256k1-tr/package.json b/packages/secp256k1-tr/package.json index 5bb4bb1..d02d5b9 100644 --- a/packages/secp256k1-tr/package.json +++ b/packages/secp256k1-tr/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/secp256k1-tr", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(secp256k1, SHA-256) Taproot - A BIP-340 compatible Schnorr signature scheme over secp256k1 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -62,17 +63,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/secp256k1-tr/src/index.ts b/packages/secp256k1-tr/src/index.ts index 533d840..8e6a4bc 100644 --- a/packages/secp256k1-tr/src/index.ts +++ b/packages/secp256k1-tr/src/index.ts @@ -964,7 +964,7 @@ export const Secp256K1Sha256TR: Secp256K1Sha256TRImpl = { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as { serialize(): Uint8Array }).serialize(); } else { @@ -1100,10 +1100,7 @@ export const Secp256K1Sha256TR: Secp256K1Sha256TRImpl = { rng: RandomSource, ): SignatureClass { // Extract scalar from SigningKey object or use directly if already a bigint - const scalar = - typeof signingKey === "bigint" - ? signingKey - : (signingKey as { toScalar(): bigint }).toScalar(); + const scalar = typeof signingKey === "bigint" ? signingKey : signingKey.toScalar(); // Ensure signing key produces even Y public key const publicKey = Secp256K1Group.basePointMul(scalar); @@ -1212,12 +1209,12 @@ export const Secp256K1Sha256TR: Secp256K1Sha256TRImpl = { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKeyClass).serialize(); } else { // It's a raw element, serialize it directly - vkBytes = Secp256K1Group.serialize(verifyingKey as Uint8Array); + vkBytes = Secp256K1Group.serialize(verifyingKey); } // Compute message hash H4(message) @@ -1450,7 +1447,7 @@ export const Secp256K1Sha256TR: Secp256K1Sha256TRImpl = { // Check if we need to negate the signing share (for even Y verifying key) let vkBytes: Uint8Array; if (typeof kp.verifyingKey === "object" && "serialize" in kp.verifyingKey) { - vkBytes = (kp.verifyingKey as { serialize(): Uint8Array }).serialize(); + vkBytes = kp.verifyingKey.serialize(); } else { vkBytes = kp.verifyingKey; } @@ -1460,7 +1457,7 @@ export const Secp256K1Sha256TR: Secp256K1Sha256TRImpl = { if (typeof kp.signingShare === "bigint") { signingShare = kp.signingShare; } else if (typeof kp.signingShare === "object" && "toScalar" in kp.signingShare) { - signingShare = (kp.signingShare as { toScalar(): bigint }).toScalar(); + signingShare = kp.signingShare.toScalar(); } else { throw new Error("signingShare must be a bigint or object with toScalar()"); } @@ -1797,14 +1794,14 @@ export function intoEvenYKeyPackage< verifyingKey: Secp256K1Group.negate(vkBytes), signingShare: Secp256K1ScalarField.negate(signingScalar), verifyingShare: Secp256K1Group.negate(vsBytes), - } as T; + }; } return { ...keyPackage, verifyingKey: vkBytes, signingShare: signingScalar, verifyingShare: vsBytes, - } as T; + }; } /** @@ -1842,7 +1839,7 @@ export function intoEvenYPublicKeyPackage< ...publicKeyPackage, verifyingKey: Secp256K1Group.negate(vkBytes), verifyingShares: newShares, - } as T; + }; } // Convert shares to bytes even if not negating const newShares = new Map(); @@ -1853,7 +1850,7 @@ export function intoEvenYPublicKeyPackage< ...publicKeyPackage, verifyingKey: vkBytes, verifyingShares: newShares, - } as T; + }; } /** @@ -1882,7 +1879,7 @@ export function tweakKeyPackage< verifyingKey: Secp256K1Group.add(vkBytes, tp), signingShare: Secp256K1ScalarField.add(signingScalar, t), verifyingShare: Secp256K1Group.add(vsBytes, tp), - } as T; + }; } /** @@ -1905,14 +1902,14 @@ export function tweakPublicKeyPackage< // Apply tweak to all shares const newShares = new Map(); for (const [id, share] of evenPackage.verifyingShares) { - newShares.set(id, Secp256K1Group.add(share as Uint8Array, tp)); + newShares.set(id, Secp256K1Group.add(share, tp)); } return { ...evenPackage, verifyingKey: Secp256K1Group.add(vkBytes, tp), verifyingShares: newShares, - } as T; + }; } // --------------------------------------------------------------------------- diff --git a/packages/secp256k1-tr/src/keys/index.ts b/packages/secp256k1-tr/src/keys/index.ts index 81452ba..0763bd9 100644 --- a/packages/secp256k1-tr/src/keys/index.ts +++ b/packages/secp256k1-tr/src/keys/index.ts @@ -210,10 +210,10 @@ export function publicKeyPackageIntoEvenY( ): PublicKeyPackage { const evenY = isEven ?? publicKeyPackageHasEvenY(pkg); if (!evenY) { - const verifyingKey = Secp256K1Group.negate(pkg.verifyingKey as Uint8Array); + const verifyingKey = Secp256K1Group.negate(pkg.verifyingKey); const verifyingShares = new Map(); for (const [id, share] of pkg.verifyingShares) { - verifyingShares.set(id, Secp256K1Group.negate(share as Uint8Array)); + verifyingShares.set(id, Secp256K1Group.negate(share)); } return { ...pkg, @@ -239,10 +239,10 @@ export function publicKeyPackageTweak( const tp = Secp256K1Group.basePointMul(t); // Apply tweak to verifying key and all shares - const verifyingKey = Secp256K1Group.add(evenPkg.verifyingKey as Uint8Array, tp); + const verifyingKey = Secp256K1Group.add(evenPkg.verifyingKey, tp); const verifyingShares = new Map(); for (const [id, share] of evenPkg.verifyingShares) { - verifyingShares.set(id, Secp256K1Group.add(share as Uint8Array, tp)); + verifyingShares.set(id, Secp256K1Group.add(share, tp)); } return { @@ -269,9 +269,9 @@ export function keyPackageHasEvenY(pkg: KeyPackage): boolean { export function keyPackageIntoEvenY(pkg: KeyPackage, isEven?: boolean): KeyPackage { const evenY = isEven ?? keyPackageHasEvenY(pkg); if (!evenY) { - const verifyingKey = Secp256K1Group.negate(pkg.verifyingKey as Uint8Array); - const signingShare = Secp256K1ScalarField.negate(pkg.signingShare as bigint); - const verifyingShare = Secp256K1Group.negate(pkg.verifyingShare as Uint8Array); + const verifyingKey = Secp256K1Group.negate(pkg.verifyingKey); + const signingShare = Secp256K1ScalarField.negate(pkg.signingShare); + const verifyingShare = Secp256K1Group.negate(pkg.verifyingShare); return { ...pkg, verifyingKey, @@ -294,9 +294,9 @@ export function keyPackageTweak(pkg: KeyPackage, merkleRoot?: Uint8Array): KeyPa const tp = Secp256K1Group.basePointMul(t); // Apply tweak to all components - const verifyingKey = Secp256K1Group.add(evenPkg.verifyingKey as Uint8Array, tp); - const signingShare = Secp256K1ScalarField.add(evenPkg.signingShare as bigint, t); - const verifyingShare = Secp256K1Group.add(evenPkg.verifyingShare as Uint8Array, tp); + const verifyingKey = Secp256K1Group.add(evenPkg.verifyingKey, tp); + const signingShare = Secp256K1ScalarField.add(evenPkg.signingShare, t); + const verifyingShare = Secp256K1Group.add(evenPkg.verifyingShare, tp); return { ...evenPkg, diff --git a/packages/secp256k1-tr/tests/coefficient-commitment.test.ts b/packages/secp256k1-tr/tests/coefficient-commitment.test.ts index 7d2f491..8b62191 100644 --- a/packages/secp256k1-tr/tests/coefficient-commitment.test.ts +++ b/packages/secp256k1-tr/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Secp256K1Sha256TR } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/secp256k1-tr/tests/integration.test.ts b/packages/secp256k1-tr/tests/integration.test.ts index 72ed6f4..84d0b85 100644 --- a/packages/secp256k1-tr/tests/integration.test.ts +++ b/packages/secp256k1-tr/tests/integration.test.ts @@ -13,7 +13,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, Identifier } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { Identifier } from "@frosts/core"; import { createSecureRng, hexToBytes, diff --git a/packages/secp256k1-tr/tests/interoperability.test.ts b/packages/secp256k1-tr/tests/interoperability.test.ts index 567a3b7..2ebaf14 100644 --- a/packages/secp256k1-tr/tests/interoperability.test.ts +++ b/packages/secp256k1-tr/tests/interoperability.test.ts @@ -10,7 +10,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, VerifyingKey } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { VerifyingKey } from "@frosts/core"; import { createSecureRng, verifySignature, diff --git a/packages/secp256k1-tr/tests/vss-commitment.test.ts b/packages/secp256k1-tr/tests/vss-commitment.test.ts index 67a6023..e72b605 100644 --- a/packages/secp256k1-tr/tests/vss-commitment.test.ts +++ b/packages/secp256k1-tr/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Secp256K1Sha256TR } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/secp256k1-tr/tsdown.config.ts b/packages/secp256k1-tr/tsdown.config.ts index 6ee875a..64a0adc 100644 --- a/packages/secp256k1-tr/tsdown.config.ts +++ b/packages/secp256k1-tr/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha2.js", - "@noble/curves/secp256k1.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha2.js", + "@noble/curves/secp256k1.js", + ], + }, platform: "neutral", globalName: "frostsSecp256k1Tr", outputOptions: { diff --git a/packages/secp256k1/CHANGELOG.md b/packages/secp256k1/CHANGELOG.md new file mode 100644 index 0000000..9bd33c3 --- /dev/null +++ b/packages/secp256k1/CHANGELOG.md @@ -0,0 +1,8 @@ +# @frosts/secp256k1 + +## 0.2.2-alpha.4 + +### Patch Changes + +- Importing `@frosts/secp256k1` no longer crashes for consumers that do not have `vitest` installed. The crash originated in `@frosts/core` (which this package depends on), whose public entry bundled its test helpers and their `vitest` import; those helpers now live under the `@frosts/core/tests` subpath. +- Updated runtime and dev dependencies to their latest versions (`@noble/curves` & `@noble/hashes` 2.2, TypeScript 6, ESLint 10, tsdown 0.22, Vitest 4.1). diff --git a/packages/secp256k1/package.json b/packages/secp256k1/package.json index bfba0ca..9c61ca5 100644 --- a/packages/secp256k1/package.json +++ b/packages/secp256k1/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/secp256k1", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "description": "FROST(secp256k1, SHA-256) - A Schnorr signature scheme over secp256k1 that supports FROST threshold signatures", "license": "MIT", @@ -29,7 +29,8 @@ "files": [ "dist", "src", - "README.md" + "README.md", + "CHANGELOG.md" ], "scripts": { "build": "tsdown", @@ -59,17 +60,17 @@ "dependencies": { "@frosts/core": "workspace:*", "@frosts/rerandomized": "workspace:*", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0" }, "devDependencies": { "@frosts/eslint": "workspace:*", "@frosts/tsconfig": "workspace:*", - "@types/node": "^25.0.10", - "eslint": "^9.39.2", - "tsdown": "^0.20.1", - "typedoc": "^0.28.5", - "typescript": "^5.9.3", - "vitest": "^4.0.18" + "@types/node": "^26.0.0", + "eslint": "^10.5.0", + "tsdown": "^0.22.3", + "typedoc": "^0.28.19", + "typescript": "^6.0.3", + "vitest": "^4.1.9" } } diff --git a/packages/secp256k1/src/index.ts b/packages/secp256k1/src/index.ts index 47fd940..3c96e4e 100644 --- a/packages/secp256k1/src/index.ts +++ b/packages/secp256k1/src/index.ts @@ -1066,7 +1066,7 @@ class Secp256K1Sha256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { pkBytes = (verifyingKey as VerifyingKey).serialize(); } else { @@ -1100,7 +1100,7 @@ class Secp256K1Sha256Impl implements RandomizedCiphersuite { typeof verifyingKey === "object" && verifyingKey !== null && "serialize" in verifyingKey && - typeof (verifyingKey as { serialize: unknown }).serialize === "function" + typeof verifyingKey.serialize === "function" ) { vkBytes = (verifyingKey as VerifyingKey).serialize(); } else { diff --git a/packages/secp256k1/tests/coefficient-commitment.test.ts b/packages/secp256k1/tests/coefficient-commitment.test.ts index 1781eab..db8deb2 100644 --- a/packages/secp256k1/tests/coefficient-commitment.test.ts +++ b/packages/secp256k1/tests/coefficient-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Secp256K1Sha256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/secp256k1/tests/integration.test.ts b/packages/secp256k1/tests/integration.test.ts index e014831..3d8a71d 100644 --- a/packages/secp256k1/tests/integration.test.ts +++ b/packages/secp256k1/tests/integration.test.ts @@ -7,7 +7,8 @@ */ import { describe, it, expect, beforeEach } from "vitest"; -import { tests, Identifier } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; +import { Identifier } from "@frosts/core"; import { createSecureRng, hexToBytes, diff --git a/packages/secp256k1/tests/vss-commitment.test.ts b/packages/secp256k1/tests/vss-commitment.test.ts index ff18150..4ac02b0 100644 --- a/packages/secp256k1/tests/vss-commitment.test.ts +++ b/packages/secp256k1/tests/vss-commitment.test.ts @@ -8,7 +8,7 @@ */ import { describe, it, beforeEach } from "vitest"; -import { tests } from "@frosts/core"; +import * as tests from "@frosts/core/tests"; import { Secp256K1Sha256 } from "../src/index.js"; import { createSecureRng, type CryptoRng } from "./helpers/index.js"; import elementsJson from "./helpers/elements.json"; diff --git a/packages/secp256k1/tsdown.config.ts b/packages/secp256k1/tsdown.config.ts index d4321c4..4f77f26 100644 --- a/packages/secp256k1/tsdown.config.ts +++ b/packages/secp256k1/tsdown.config.ts @@ -11,12 +11,14 @@ export default defineConfig({ minify: false, target: "es2022", outDir: "dist", - external: [ - "@frosts/core", - "@frosts/rerandomized", - "@noble/hashes/sha2.js", - "@noble/curves/secp256k1.js", - ], + deps: { + neverBundle: [ + "@frosts/core", + "@frosts/rerandomized", + "@noble/hashes/sha2.js", + "@noble/curves/secp256k1.js", + ], + }, platform: "neutral", globalName: "frostsSecp256k1", outputOptions: { diff --git a/shared/eslint/package.json b/shared/eslint/package.json index 61490f2..9bc2b66 100644 --- a/shared/eslint/package.json +++ b/shared/eslint/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/eslint", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "type": "module", "private": true, "main": "./library.mjs", @@ -9,16 +9,16 @@ "./cli": "./cli.mjs" }, "dependencies": { - "@eslint/js": "^9.39.2", - "@typescript-eslint/eslint-plugin": "^8.53.1", - "@typescript-eslint/parser": "^8.53.1" + "@eslint/js": "^10.0.1", + "@typescript-eslint/eslint-plugin": "^8.61.1", + "@typescript-eslint/parser": "^8.61.1" }, "devDependencies": { - "eslint-config-turbo": "^2.7.6", - "typescript": "5.9.3" + "eslint-config-turbo": "^2.9.18", + "typescript": "6.0.3" }, "peerDependencies": { - "eslint": "^9.39.2", - "typescript": ">=5.9.3" + "eslint": "^10.0.0", + "typescript": ">=6.0.0" } } diff --git a/shared/tsconfig/library.json b/shared/tsconfig/library.json index 26a54c5..38ff83f 100644 --- a/shared/tsconfig/library.json +++ b/shared/tsconfig/library.json @@ -3,7 +3,7 @@ "extends": "./base.json", "compilerOptions": { "target": "ES2022", - "lib": ["ES2022"], + "lib": ["ES2022", "DOM"], "module": "ESNext", "moduleResolution": "bundler", "resolveJsonModule": true, diff --git a/shared/tsconfig/package.json b/shared/tsconfig/package.json index 2ff5683..8fda041 100644 --- a/shared/tsconfig/package.json +++ b/shared/tsconfig/package.json @@ -1,6 +1,6 @@ { "name": "@frosts/tsconfig", - "version": "0.2.2-alpha.3", + "version": "0.2.2-alpha.4", "private": true, "publishConfig": { "access": "public"