NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist · #1429 most downloaded on Packagist
A lightweight PHP library for creating and verifying ALTCHA challenges.
Last release 4 days ago
04 Oct 2026
Release timing varies
gaps range from 8 days to 7 months
Most releases are documented
notes for 17 of 21 stable releases
Nothing withdrawn
no release was ever pulled
2 years old
23 releases · first in 2024
fix: verifySolution rejects every challenge with invalidSignature when no hmacSignatureSecret is configured ( null or '' ). Previously the signature c
Changes:
verifySolution rejects every challenge with invalidSignature when no hmacSignatureSecret is configured (null or ''). Previously the signature check was skipped, so unsigned or tampered challenges (e.g. with a client-chosen keyPrefix or cost) verified. '' now also counts as unset when creating challenges.expiresAt handling matches altcha-lib (JS): 0 means no expiry, fractional timestamps (e.g. Date.now() / 1000 + 600) are accepted and signed as-is, and expiry is checked to the sub-second (no more up to 1 s of grace).altcha-lib (JS) byte-for-byte, so challenges signed by one library verify in the other (JS number formatting, JS key order, empty or list-shaped data encoded as an object, U+2028/U+2029 left unescaped).BREAKING:
verifySolution without a signature secret now always fails. Pass hmacSignatureSecret to new Altcha(...) on every server that verifies solutions.ChallengeParameters::$expiresAt and CreateChallengeOptions::$expiresAt are int|float|null (were ?int).ChallengeParameters::toArray()['data'] is a stdClass when data is empty or list-shaped.createChallenge() and ChallengeParameters::toCanonicalJson() throw JsonException on invalid UTF-8 in data (previously an empty string was signed).data contains floats that PHP formatted differently from JS are signed differently; such challenges issued before upgrading fail verification.Full changelog: CHANGELOG.md · v2.2.0...v2.3.0
One column per month.
verifySolution rejects every challenge with invalidSignature when no hmacSignatureSecret is configured (null or ''). It used to skip the signature check, so unsigned or tampered challenges verified. '' now also counts as unset when creating challenges.expiresAt matches altcha-lib (JS): 0 means no expiry, fractional timestamps (e.g. Date.now() / 1000 + 600) are accepted and signed as-is, and expiry is checked to the sub-second (no more up to 1 s of grace).altcha-lib (JS) byte-for-byte, so challenges signed by one library verify in the other: JS number formatting, JS key order (array-index keys first, UTF-16 order, objects inside lists left unsorted), empty or list-shaped data encoded as an object, U+2028/U+2029 left unescaped.verifySolution without a signature secret now always fails.ChallengeParameters::$expiresAt and CreateChallengeOptions::$expiresAt are int|float|null.ChallengeParameters::toArray()['data'] is a stdClass when data is empty or list-shaped.createChallenge() and ChallengeParameters::toCanonicalJson() throw JsonException on invalid UTF-8 in data, instead of signing an empty string.data that PHP used to format differently from JS are signed differently; such challenges issued before upgrading fail verification.Fix: sign raw derived key bytes in keySignature to match TS altcha-lib [ #25 ]
Changes:
BREAKING: challenges with a keySignature that were minted before this change will be rejected.
keySignature to match altcha-lib (JS) (#25).keyPrefix.keySignature minted before this release are rejected.feat: VerifySolutionOptions::$payload now accepts a raw base64 string or a decoded array directly, in addition to a Payload object [ #24 ]
Changes:
VerifySolutionOptions::$payload now accepts a raw base64 string or a decoded array directly, in addition to a Payload object [#24]Sentinel::verify() for remote payload verification via the ALTCHA Sentinel API (POST /v1/verify/signature), with configurable timeout, retries/backoff, and a pluggable HTTP clientVerifySolutionOptions::$payload accepts a raw base64 string or a decoded array, in addition to a Payload object (#24).Sentinel::verify() for remote payload verification via the ALTCHA Sentinel API (POST /v1/verify/signature), with configurable timeout, retries/backoff, and a pluggable HTTP client.fix: verifySolution - reject missing challenge signature when secret is set
Changes:
verifySolution rejects a missing challenge signature when a secret is set.Removed dead ?? fallbacks on non-nullable int properties.
?? fallbacks on non-nullable int properties.build: lower minimum PHP requirement to 8.1
build: lower minimum PHP requirement to 8.1
This version introduces the new PoW mechanism v2
Breaking changes:
MIGRATION-v1.md and available examplesMIGRATION-v1.md and the examples.Nothing published for this version
Nothing published for this version
Changes: Removed ext-json [ #21 ]
Changes:
Updated PHPUnit; added .gitattributes.
.gitattributes.fix: replace ; with & in salt delimiter for compatibility (this allows for backward-compatible extraction of salt parameters with previous versions of
Changes:
& instead of ; as the salt delimiter. Salt parameters stay extractable by previous library versions while still preventing the salt parameter splicing attack.Fixed a parameter splicing vulnerability in salt handling that enabled replay attacks.
### Added - Obfuscator class (#16).
Obfuscator class (#16).Required PHP version in composer.json (8.2).
composer.json (8.2).### Fixed - README examples.
BREAKING: fixed casing of the maxNumber parameter in Challenge. Compatible only with the ALTCHA widget >= 1.4.0; for older widgets use v1.0.0.
maxNumber parameter in Challenge. Compatible only with the ALTCHA widget >= 1.4.0; for older widgets use v1.0.0.BREAKING: codebase migrated to OOP and PHP 8.1 (#10). See the README for migration; for older PHP versions use v0.1.4.
Handling of invalid payloads (#6).
Earlier 0.1.x releases (from 2024-07-26): see the git history.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →