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
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: CI

on:
push:
branches: [master]
pull_request:

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node: [16, 18, 20, 22, 24]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: corepack enable
- run: yarn install --immutable
- run: yarn test
47 changes: 47 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Publish

# Cut a release with `npm version patch|minor|major` on master. That runs the
# tests, dates the CHANGELOG entry, commits, tags `vX.Y.Z` and pushes. This
# workflow then publishes to npm with provenance and creates the GitHub release.
#
# Needs one repository secret: NPM_TOKEN, a granular npm access token with
# read/write on @provableio/provable-core and bypass 2FA for automation.

on:
push:
tags: ["v[0-9]+.[0-9]+.[0-9]+"]

permissions:
contents: write
id-token: write

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: https://registry.npmjs.org
- run: corepack enable
- run: yarn install --immutable
- run: yarn test

- name: Tag must match package.json
run: |
version="v$(node -p "require('./package.json').version")"
test "$version" = "$GITHUB_REF_NAME" || { echo "tag $GITHUB_REF_NAME != package.json $version"; exit 1; }

- name: Release notes from CHANGELOG.md
run: node scripts/release-changelog.js notes "$GITHUB_REF_NAME" > release-notes.md

- name: Publish to npm
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: GitHub release
run: gh release create "$GITHUB_REF_NAME" --title "$GITHUB_REF_NAME" --notes-file release-notes.md
env:
GH_TOKEN: ${{ github.token }}
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
node_modules
.env
*.log
dist
dist
.yarn/
.pnp.*
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
message=v%s
3 changes: 3 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nodeLinker: node-modules
enableGlobalCache: true
enableTelemetry: false
79 changes: 79 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Changelog

All notable changes to this project are documented here. The format follows
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

Because this library exists to make results reproducible, **any change to the
bytes, floats or integers produced for a given input is a breaking change and
requires a major version**, however small it looks.

## [Unreleased]

### Breaking

- Inputs are validated. Seeds must be non-empty strings; `nonce`, `cursor`,
`count`, `max`, `min`, hash-chain `count`/`index` and hash-series `nonce`
must be safe integers or their canonical decimal string form (`"400"`).
Calls that previously coerced or ignored bad input (`ints()` returned `[]`,
a `NaN` nonce was hashed as the text `NaN`) now throw.
- `serverHash` is always derived from `serverSeed`. A supplied value is
replaced rather than trusted.
- `Provable(...)(config)` no longer mutates `config`; `state()` and the
emitted state are copies.
- `next(salt)` requires a non-empty `salt`.
- `HashChain` rejects `index` outside `[0, count - 1]` and non-integer `count`
with clear errors instead of `RangeError: Invalid array length` or silent
`undefined`.
- Requires Node.js 14.17 or later (`crypto.randomUUID`).

### Fixed

- A long-lived `Provable` instance reused its first nonce for every draw, so
the emitted state did not reproduce the outcome it was recorded against.
Each draw now opens a fresh byte stream for the current nonce, then advances
it. Instances that were re-created from persisted state before every draw
produce identical results before and after this fix.
- The nonce guard runs before state changes, so a failed draw leaves the
instance untouched.
- `HashChain` count assertion checked the seed (copy-paste).
- `HashChain()` with no argument threw `TypeError`.
- LICENSE copyright holder was blank.

### Changed

- README rewritten to describe the actual algorithm (HMAC-SHA256, the
`[min, min + max - 1]` range of `ints`, immutable `HashSeries`, no `new` on
generator functions) and to add a verification recipe.
- Test suite pins the byte stream, float and integer conversions and the
rotation formula with fixed vectors.
- Releases are cut with `npm version` and published from GitHub Actions on
`v*` tags with npm provenance.

### Added

- `HashChain.generateHashChain(count, seed)`.
- `utils.toInteger`, `utils.assertSeed`, `utils.randomUUID`.
- `files` field so the published tarball ships only the library.

### Removed

- Runtime dependencies `lodash` and `uuid`.
- The `release` npm script.

## [1.0.1] - 2025-09-27

### Changed

- Nonce advances eagerly and is capped at `Number.MAX_SAFE_INTEGER`.
- Documentation and typo fixes.

## [1.0.0] - 2024-05-03

### Added

- `Provable`, `HashSeries`, `HashChain` and `utils`.

[Unreleased]: https://github.com/provableio/provable-core/compare/v1.0.1...HEAD
[1.0.1]: https://github.com/provableio/provable-core/compare/v1.0.0...v1.0.1
[1.0.0]: https://github.com/provableio/provable-core/releases/tag/v1.0.0
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c)
Copyright (c) 2012-2026 Provable.io

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
Loading
Loading