Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .changeset/README.md

This file was deleted.

11 changes: 0 additions & 11 deletions .changeset/config.json

This file was deleted.

17 changes: 0 additions & 17 deletions .changeset/pre.json

This file was deleted.

10 changes: 10 additions & 0 deletions .github/markdown-link-check-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"ignorePatterns": [
{
"pattern": "^https?://(www\\.)?npmjs\\.com/"
},
{
"pattern": "^https?://eprint\\.iacr\\.org/"
}
]
}
1 change: 1 addition & 0 deletions .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
10 changes: 8 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }})
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -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/)
Expand Down
9 changes: 4 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -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 <leonardo.custodio@parity.io> (https://github.com/leonardocustodio)",
Expand Down Expand Up @@ -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": [
Expand Down
14 changes: 14 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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).
32 changes: 20 additions & 12 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand All @@ -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",
Expand All @@ -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"
}
}
4 changes: 2 additions & 2 deletions packages/core/src/identifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export class Identifier<C extends Ciphersuite> {
if (scalar === null || scalar === undefined) {
throw FrostError.identifierDerivationNotSupported();
}
return Identifier.create(ciphersuite, scalar as Scalar<C>);
return Identifier.create(ciphersuite, scalar);
}

/**
Expand Down Expand Up @@ -139,7 +139,7 @@ export class Identifier<C extends Ciphersuite> {
}
}

return Identifier.create(ciphersuite, sum as Scalar<C>);
return Identifier.create(ciphersuite, sum);
}

/**
Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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.
2 changes: 1 addition & 1 deletion packages/core/src/random.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArrayBuffer>);
} else {
throw new Error("Web Crypto API not available");
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/signing_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ export class SigningKey<C extends Ciphersuite> {
*/
zeroize(): void {
const field = this._ciphersuite.group.field;
this._scalar = field.zero() as Scalar<C>;
this._scalar = field.zero();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/tests/batch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export function checkBatchVerify<C extends Ciphersuite>(ciphersuite: C, rng: Cry
batch.queue(item);

// Create RNG function that generates random scalars for blinding
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng) as Scalar<C>;
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng);

// Verify the batch - should not throw
batch.verify(rngFn);
Expand Down Expand Up @@ -103,7 +103,7 @@ export function checkBadBatchVerify<C extends Ciphersuite>(ciphersuite: C, rng:
}

// Create RNG function for batch verification
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng) as Scalar<C>;
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng);

// Batch verification should fail due to the bad signature
let batchFailed = false;
Expand Down Expand Up @@ -162,7 +162,7 @@ export function checkEmptyBatchVerify<C extends Ciphersuite>(ciphersuite: C, rng
const batch = new Verifier(ciphersuite);

// Create RNG function for batch verification
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng) as Scalar<C>;
const rngFn = (): Scalar<C> => ciphersuite.group.field.random(rng);

// Empty batch should fail
let emptyFailed = false;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArrayBuffer>);
} 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");
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/tests/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/tests/refresh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export async function checkRefreshSharesWithDealerFailsWithInvalidSigners<C exte

expect(() => {
computeRefreshingShares(ciphersuite, pubKeyPackage, identifiers, rng);
}).toThrow(expectedError as Error);
}).toThrow(expectedError);
}

/**
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/traits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function randomNonzero<F extends Field>(field: F, rng: CryptoRng): Scalar
let scalar: ScalarOf<F>;
do {
scalar = field.random(rng) as ScalarOf<F>;
} while (field.isZero(scalar as never));
} while (field.isZero(scalar));
return scalar;
}

Expand All @@ -53,8 +53,8 @@ export function defaultGenerateNonce<C extends Ciphersuite>(
const group = ciphersuite.group;
const field = group.field;
const k = randomNonzero(field, rng);
const R = group.scalarBaseMul(k as never);
return [k as Scalar<C>, R as Element<C>];
const R = group.scalarBaseMul(k);
return [k, R];
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/core/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ArrayBuffer>);
} 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");
Expand Down
1 change: 1 addition & 0 deletions packages/core/tests/helpers/ciphersuite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export async function getTestCiphersuite(): Promise<Ciphersuite> {
"Failed to load @frosts/ed25519 for testing. " +
"Make sure the ed25519 package is built before running core tests. " +
`Original error: ${error}`,
{ cause: error },
);
}
}
Expand Down
7 changes: 7 additions & 0 deletions packages/core/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
}
Expand Down
Loading