### Complete Server Example - PHP Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt A minimal PHP built-in server that handles challenge issuance and solution verification. It auto-detects client solutions versus Sentinel server-signature payloads. Ensure you have the ALTCHA library installed via Composer. ```php createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 10000, expiresAt: time() + 120, )); header('Content-Type: application/json'); echo $challenge->toJson(); return; } if ($method === 'POST' && $path === '/submit') { $raw = $_POST['altcha'] ?? ''; $decoded = json_decode(base64_decode($raw, true) ?: '{}', true); if (isset($decoded['verificationData'])) { // Sentinel / server-signature payload $result = ServerSignature::verifyServerSignature($decoded, $hmacSecret); $verified = $result->verified; } elseif (isset($decoded['challenge'], $decoded['solution'])) { // Client-solved payload $challenge = new Challenge( ChallengeParameters::fromArray($decoded['challenge']['parameters']), $decoded['challenge']['signature'] ?? null, ); $solution = new Solution( counter: (int) $decoded['solution']['counter'], derivedKey: (string) $decoded['solution']['derivedKey'], ); $result = $altcha->verifySolution(new VerifySolutionOptions( payload: new Payload($challenge, $solution), algorithm: $pbkdf2, )); $verified = $result->verified; } else { http_response_code(400); echo json_encode(['error' => 'Unrecognized payload']); return; } http_response_code($verified ? 200 : 403); header('Content-Type: application/json'); echo json_encode(['verified' => $verified, 'details' => $result]); return; } http_response_code(404); echo json_encode(['error' => 'Not found']); ``` -------------------------------- ### Install ALTCHA PHP Library Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Use Composer to install the ALTCHA PHP library. This is the standard method for managing PHP dependencies. ```sh composer require altcha-org/altcha ``` -------------------------------- ### Basic ALTCHA Usage Example Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Demonstrates the core workflow of the ALTCHA library: creating a challenge, solving it (typically client-side), and verifying the solution on the server. Ensure vendor autoload is included. The cost and counter values should be adjusted based on the chosen algorithm for appropriate security. ```php createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 5000, counter: random_int(5000, 10000), expiresAt: time() + 600, )); // Solve the challenge (client-side in production) $solution = $altcha->solveChallenge(new SolveChallengeOptions( algorithm: $pbkdf2, challenge: $challenge, )); // Verify the solution (server-side) if ($solution !== null) { $payload = new Payload($challenge, $solution); $result = $altcha->verifySolution(new VerifySolutionOptions( algorithm: $pbkdf2, payload: $payload, )); if ($result->verified) { echo "Solution verified!\n"; } } ``` -------------------------------- ### Custom Algorithm Implementation Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Provides an example of implementing a custom algorithm by extending `DeriveKeyInterface`. ```APIDOC ## Custom Algorithm ### Description Allows users to define and use their own custom algorithms for key derivation by implementing the `DeriveKeyInterface`. ### Implementation Example ```php use AltchaOrg\Altcha\Algorithm\DeriveKeyInterface; use AltchaOrg\Altcha\Algorithm\DeriveKeyResult; use AltchaOrg\Altcha\ChallengeParameters; class MyAlgorithm implements DeriveKeyInterface { public function getAlgorithmName(): string { return 'MY-ALGO'; } public function deriveKey(ChallengeParameters $parameters, string $salt, string $password): DeriveKeyResult { $key = hash_pbkdf2('sha256', $password, $salt, $parameters->cost, $parameters->keyLength, true); return new DeriveKeyResult($key); } } ``` ### Methods - `getAlgorithmName()`: Returns the string name of the custom algorithm. - `deriveKey(ChallengeParameters $parameters, string $salt, string $password)`: Derives the key using the provided parameters, salt, and password. ``` -------------------------------- ### Run PHPUnit Tests Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Execute the project's tests using the PHPUnit framework. Ensure you have the necessary dependencies installed via Composer. ```sh vendor/bin/phpunit tests ``` -------------------------------- ### Argon2id Key Derivation Algorithm Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Use the `Argon2id` class for key derivation, which requires the `ext-sodium` PHP extension. Configure `cost` and `memoryCost` parameters for security and performance tuning. This example shows creating a challenge with Argon2id. ```php use AltchaOrg\Altcha\Algorithm\Argon2id; $argon2id = new Argon2id(); // Uses: cost (time iterations), memoryCost (KiB, default 32768 = 32 MiB) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $argon2id, cost: 3, memoryCost: 32768, // 32 MiB expiresAt: time() + 300, )); ``` -------------------------------- ### Issue Challenge and Submit Payload - Bash Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Examples of using curl to interact with the PHP server for issuing a challenge and submitting a payload. The first command fetches a challenge, and the second submits a base64-encoded payload for verification. ```bash # Issue a challenge curl http://localhost:8080/challenge # {"parameters":{"algorithm":"PBKDF2/SHA-256","cost":10000,...},"signature":"..."} # Submit a verified Sentinel payload curl -X POST http://localhost:8080/submit \ -d "altcha=" # {"verified":true,"details":{"verified":true,...}} ``` -------------------------------- ### Solve Altcha Challenge Client-Side Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Use this method to solve a challenge by iterating through counter values until a derived key matches the required prefix. This is a CPU-bound operation suitable for client-side execution. Adjust `start`, `step`, and `timeout` as needed. ```php use AltchaOrg\Altcha\SolveChallengeOptions; $solution = $altcha->solveChallenge(new SolveChallengeOptions( challenge: $challenge, algorithm: $pbkdf2, start: 0, // initial counter (default 0) step: 1, // counter increment per iteration (default 1) timeout: 30.0, // max seconds before giving up (default 30.0) )); if ($solution === null) { echo "No solution found within timeout.\n"; } else { echo "Counter: {$solution->counter}\n"; echo "Derived key (hex): {$solution->derivedKey}\n"; echo "Time taken: {$solution->time}s\n"; // Counter: 7341 // Derived key (hex): a3f1c9... // Time taken: 0.843s } ``` -------------------------------- ### Initialize Scrypt Algorithm Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Instantiate the Scrypt algorithm. Requires the `ext-scrypt` PHP extension. Uses default memoryCost (r=8) and parallelism (p=1) if not specified in challenge options. ```php use AltchaOrg\Altcha\Algorithm\Scrypt; new Scrypt(); ``` -------------------------------- ### Scrypt Algorithm Usage Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Demonstrates how to use the Scrypt algorithm for creating challenges, specifying cost, memory cost, and parallelism parameters. ```APIDOC ## `Scrypt` Algorithm Requires `ext-scrypt`. ### Description Used for creating challenges with Scrypt as the hashing algorithm. Allows configuration of cost (N), memoryCost (r), and parallelism (p). ### Usage ```php use AltchaOrg\Altcha\Algorithm\Scrypt; $scrypt = new Scrypt(); $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $scrypt, cost: 16384, // N memoryCost: 8, // r parallelism: 1, // p expiresAt: time() + 300, )); ``` ### Parameters - `algorithm`: An instance of the Scrypt algorithm class. - `cost` (N): CPU/memory iterations for Scrypt. - `memoryCost` (r): Memory cost factor for Scrypt (default 8). - `parallelism` (p): Parallelism factor for Scrypt (default 1). - `expiresAt`: Unix timestamp for challenge expiration. ``` -------------------------------- ### Scrypt Algorithm Initialization Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Initializes the Scrypt algorithm. Requires the `ext-scrypt` PHP extension. Configuration for `memoryCost` and `parallelism` can be passed via challenge options. ```APIDOC ## Scrypt Algorithm ### Description Initializes the Scrypt algorithm, which is used for key derivation. This requires the `ext-scrypt` PHP extension to be installed. ### Usage ```php use AltchaOrg\Altcha\Algorithm\Scrypt; // Initialize Scrypt with default options $scrypt = new Scrypt(); // Initialization with custom challenge options (example) // $challengeOptions = ['r' => 16, 'p' => 2]; // Example values for memoryCost and parallelism // $scrypt = new Scrypt($challengeOptions); ``` ### Configuration - `memoryCost` (r): Default is 8. Controls the memory usage. - `parallelism` (p): Default is 1. Controls the number of parallel threads. ``` -------------------------------- ### Create Challenge with Scrypt Algorithm Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Demonstrates creating a challenge using the Scrypt algorithm. Requires the `ext-scrypt` PHP extension. ```php use AltchaOrg\Altcha\Algorithm\Scrypt; $scrypt = new Scrypt(); // Uses: cost (N, CPU/memory iterations), memoryCost (r, default 8), parallelism (p, default 1) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $scrypt, cost: 16384, // N memoryCost: 8, // r parallelism: 1, // p expiresAt: time() + 300, )); ``` -------------------------------- ### Initialize Altcha Class Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Instantiate the main Altcha class. You can initialize it with just the HMAC signature secret, or with both signature and key secrets for an optional fast verification path. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\HmacAlgorithm; // Minimal: only challenge signature $altcha = new Altcha( hmacSignatureSecret: 'my-hmac-secret' ); // Full: adds fast verification path via keySignature $altcha = new Altcha( hmacSignatureSecret: 'my-hmac-secret', hmacKeySignatureSecret: 'my-key-secret', // optional — enables fast path hmacAlgorithm: HmacAlgorithm::SHA256, // default; also SHA384, SHA512 ); ``` -------------------------------- ### Configure Argon2id Algorithm Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Instantiate the Argon2id algorithm. This requires the `ext-sodium` PHP extension to be enabled. The `memoryCost` parameter should be configured within the `CreateChallengeOptions` when using this algorithm. ```php use AltchaOrg\Altcha\Algorithm\Argon2id; new Argon2id(); ``` -------------------------------- ### Implement a Custom DeriveKey Algorithm Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Shows how to create a custom hashing algorithm by implementing the `DeriveKeyInterface`. This allows for unique hashing methods beyond the standard ones. ```php use AltchaOrg\Altcha\Algorithm\DeriveKeyInterface; use AltchaOrg\Altcha\Algorithm\DeriveKeyResult; use AltchaOrg\Altcha\ChallengeParameters; class MyAlgorithm implements DeriveKeyInterface { public function getAlgorithmName(): string { return 'MY-ALGO'; } public function deriveKey(ChallengeParameters $parameters, string $salt, string $password): DeriveKeyResult { $key = hash_pbkdf2('sha256', $password, $salt, $parameters->cost, $parameters->keyLength, true); return new DeriveKeyResult($key); } } ``` -------------------------------- ### Verify Altcha Solution Server-Side Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt This method verifies a submitted Altcha solution on the server. It checks for expiry, validates the challenge signature, and either uses a fast path with a pre-submitted derived key or re-derives the key to check its prefix. The `VerifySolutionOptions` should be constructed from client-submitted data. ```php use AltchaOrg\Altcha\Payload; use AltchaOrg\Altcha\Challenge; use AltchaOrg\Altcha\Solution; use AltchaOrg\Altcha\ChallengeParameters; use AltchaOrg\Altcha\VerifySolutionOptions; // --- Typically reconstructed from client-submitted base64 payload --- $decoded = json_decode(base64_decode($_POST['altcha']), true); $challenge = new Challenge( ChallengeParameters::fromArray($decoded['challenge']['parameters']), $decoded['challenge']['signature'] ?? null, ); $solution = new Solution( counter: (int) $decoded['solution']['counter'], derivedKey: (string) $decoded['solution']['derivedKey'], ); $result = $altcha->verifySolution(new VerifySolutionOptions( payload: new Payload($challenge, $solution), algorithm: $pbkdf2, )); if ($result->verified) { echo "Challenge verified in {$result->time}s\n"; } else { if ($result->expired) echo "Challenge has expired.\n"; if ($result->invalidSignature) echo "Challenge signature is invalid.\n"; if ($result->invalidSolution) echo "Derived key does not match.\n"; } ``` -------------------------------- ### Configure HMAC Algorithm for Altcha Instance Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Illustrates how to set the HMAC algorithm for signing ALTCHA instances and for PBKDF2 hashing. Defaults to SHA256. ```php use AltchaOrg\Altcha\HmacAlgorithm; HmacAlgorithm::SHA256; // 'SHA-256' → sha256 (default) HmacAlgorithm::SHA384; // 'SHA-384' → sha384 HmacAlgorithm::SHA512; // 'SHA-512' → sha512 $altcha = new Altcha( hmacSignatureSecret: 'secret', hmacAlgorithm: HmacAlgorithm::SHA512, ); ``` -------------------------------- ### Altcha Constructor Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Initializes the Altcha client with secrets for HMAC signature generation and optional key signature generation. ```APIDOC ## Altcha::__construct ### Description Initializes the Altcha client with secrets for HMAC signature generation and optional key signature generation. ### Parameters - **hmacSignatureSecret** (string) - Required - The secret key for HMAC signature generation. - **hmacKeySignatureSecret** (string) - Optional - The secret key for fast verification path using key signatures. - **hmacAlgorithm** (HmacAlgorithm) - Optional - The HMAC algorithm to use (defaults to SHA256). ``` -------------------------------- ### Create Standard ALTCHA Challenge Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Generate a standard ALTCHA challenge using PBKDF2. This challenge has a random prefix and an expiry time. Ensure the `algorithm` and `cost` parameters are provided. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\CreateChallengeOptions; use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\Algorithm\Argon2id; use AltchaOrg\Altcha\HmacAlgorithm; $altcha = new Altcha(hmacSignatureSecret: 'secret', hmacKeySignatureSecret: 'key-secret'); $pbkdf2 = new Pbkdf2(); // Standard challenge (random prefix, expires in 10 minutes) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 10000, expiresAt: time() + 600, // or new \DateTimeImmutable('+10 minutes') )); ``` -------------------------------- ### Configure PBKDF2 Algorithm Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Instantiate the PBKDF2 algorithm. By default, it uses SHA-256. You can specify SHA-384 or SHA-512 by passing the corresponding HmacAlgorithm constant. ```php use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\HmacAlgorithm; new Pbkdf2(); // PBKDF2/SHA-256 new Pbkdf2(HmacAlgorithm::SHA384); // PBKDF2/SHA-384 new Pbkdf2(HmacAlgorithm::SHA512); // PBKDF2/SHA-512 ``` -------------------------------- ### Altcha Class Instantiation Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Instantiate the `Altcha` class, providing HMAC secrets for challenge signing and optionally for fast verification. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\HmacAlgorithm; // Minimal: only challenge signature $altcha = new Altcha( hmacSignatureSecret: 'my-hmac-secret', ); // Full: adds fast verification path via keySignature $altcha = new Altcha( hmacSignatureSecret: 'my-hmac-secret', hmacKeySignatureSecret: 'my-key-secret', // optional — enables fast path hmacAlgorithm: HmacAlgorithm::SHA256, // default; also SHA384, SHA512 ); ``` -------------------------------- ### Key Derivation Algorithms Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Information on the supported key derivation algorithms, including PBKDF2 and Argon2id. ```APIDOC ## Key Derivation Algorithms All algorithms used by ALTCHA must implement the `DeriveKeyInterface`. ### PBKDF2 Instantiate PBKDF2 with an optional HMAC algorithm. ```php use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\HmacAlgorithm; // Default: PBKDF2 with SHA-256 $pbkdf2_sha256 = new Pbkdf2(); // PBKDF2 with SHA-384 $pbkdf2_sha384 = new Pbkdf2(HmacAlgorithm::SHA384); // PBKDF2 with SHA-512 $pbkdf2_sha512 = new Pbkdf2(HmacAlgorithm::SHA512); ``` ### Argon2id Requires the `ext-sodium` PHP extension. ```php use AltchaOrg\Altcha\Algorithm\Argon2id; $argon2id = new Argon2id(); ``` Note: The `memoryCost` parameter for Argon2id should be provided within the `CreateChallengeOptions`. ``` -------------------------------- ### Altcha::verifySolution Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Verifies if a given solution correctly solves an ALTCHA challenge. ```APIDOC ## Altcha::verifySolution ### Description Verifies a provided solution against its corresponding challenge. This method is typically used server-side to validate user input. ### Parameters #### Request Body - **options** (VerifySolutionOptions) - Required - Options containing the challenge and solution payload. ##### `VerifySolutionOptions` - **algorithm** (DeriveKeyInterface) - Required - The key derivation algorithm used. - **payload** (Payload) - Required - A `Payload` object containing the original challenge and the user's solution. ### Returns - **VerifySolutionResult** - An object indicating whether the solution was verified, and providing details on expiration and specific verification failures. ``` -------------------------------- ### Create Deterministic ALTCHA Challenge Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Generate a deterministic challenge with a known counter, enabling `keySignature` for fast server-side verification. Custom metadata can be embedded using the `data` parameter. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\CreateChallengeOptions; use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\Algorithm\Argon2id; use AltchaOrg\Altcha\HmacAlgorithm; $altcha = new Altcha(hmacSignatureSecret: 'secret', hmacKeySignatureSecret: 'key-secret'); $pbkdf2 = new Pbkdf2(); // Deterministic challenge (known counter → keySignature for fast verification) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 5000, counter: random_int(5000, 10000), // enables keySignature expiresAt: new \DateTimeImmutable('+2 minutes'), data: ['userId' => 42], // optional custom metadata )); // Send to client as JSON header('Content-Type: application/json'); echo $challenge->toJson(); // {"parameters":{"algorithm":"PBKDF2/SHA-256","cost":5000,"keyLength":32, // "keyPrefix":"a3f1...","nonce":"...","salt":"...","expiresAt":..., // "keySignature":"...","data":{"userId":42}},"signature":"..."} ``` -------------------------------- ### PBKDF2 Key Derivation Algorithms Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Instantiate PBKDF2 with different SHA variants (SHA-256, SHA-384, SHA-512) to create different key derivation algorithms. SHA-256 is the default and requires no additional extensions. ```php use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\HmacAlgorithm; $pbkdf2_256 = new Pbkdf2(); // PBKDF2/SHA-256 (default) $pbkdf2_384 = new Pbkdf2(HmacAlgorithm::SHA384); // PBKDF2/SHA-384 $pbkdf2_512 = new Pbkdf2(HmacAlgorithm::SHA512); // PBKDF2/SHA-512 echo $pbkdf2_256->getAlgorithmName(); // "PBKDF2/SHA-256" ``` -------------------------------- ### Verify Solution Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Verifies a submitted Altcha solution on the server-side. It checks for expiry, validates the challenge HMAC signature, and either uses a fast key signature path or re-derives the key to check the prefix. Returns detailed diagnostic results. ```APIDOC ## `Altcha::verifySolution(VerifySolutionOptions $options): VerifySolutionResult` Server-side solution verification. Checks expiry, validates the challenge HMAC signature, then either uses the fast `keySignature` path (HMAC of the submitted derived key) or fully re-derives the key and checks the prefix. Returns a `VerifySolutionResult` with detailed diagnostics. ```php use AltchaOrg\Altcha\Payload; use AltchaOrg\Altcha\Challenge; use AltchaOrg\Altcha\Solution; use AltchaOrg\Altcha\ChallengeParameters; use AltchaOrg\Altcha\VerifySolutionOptions; // --- Typically reconstructed from client-submitted base64 payload --- $decoded = json_decode(base64_decode($_POST['altcha']), true); $challenge = new Challenge( ChallengeParameters::fromArray($decoded['challenge']['parameters']), $decoded['challenge']['signature'] ?? null, ); $solution = new Solution( counter: (int) $decoded['solution']['counter'], derivedKey: (string) $decoded['solution']['derivedKey'], ); $result = $altcha->verifySolution(new VerifySolutionOptions( payload: new Payload($challenge, $solution), algorithm: $pbkdf2, )); if ($result->verified) { echo "Challenge verified in {$result->time}s\n"; } else { if ($result->expired) echo "Challenge has expired.\n"; if ($result->invalidSignature) echo "Challenge signature is invalid.\n"; if ($result->invalidSolution) echo "Derived key does not match.\n"; } ``` **`VerifySolutionResult` properties:** | Property | Type | Description | |---|---|---| | `verified` | `bool` | `true` if solution is valid, not expired, and signature is correct | | `expired` | `?bool` | Challenge expiry timestamp has passed | | `invalidSignature` | `?bool` | Challenge HMAC signature mismatch | | `invalidSolution` | `?bool` | Derived key does not match prefix or submitted value | | `time` | `float` | Verification wall-clock time in seconds | ``` -------------------------------- ### Initialize Altcha with HMAC Secrets Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Instantiate the Altcha class, providing secrets for HMAC signature generation. The `hmacKeySignatureSecret` enables a faster verification path by allowing pre-computation of a key signature. ```php $altcha = new Altcha( hmacSignatureSecret: 'secret', hmacKeySignatureSecret: 'key-secret', // enables fast verification path hmacAlgorithm: HmacAlgorithm::SHA256, // default ); ``` -------------------------------- ### CreateChallengeOptions Parameters Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Details of the parameters available for the `CreateChallengeOptions` class. ```APIDOC ## `CreateChallengeOptions` Parameters | Parameter | Type | Default | Description | |---|---|---|---| | `algorithm` | `DeriveKeyInterface` | required | Key derivation algorithm instance | | `cost` | `int` | required | Iterations / time cost | | `counter` | `?int` | `null` | Known counter for deterministic mode | | `data` | `?array` | `null` | Custom metadata embedded in parameters | | `expiresAt` | `DateTimeInterface|int|null` | `null` | Expiry as timestamp or `DateTimeInterface` | | `keyLength` | `int` | `32` | Derived key length in bytes | | `keyPrefix` | `string` | `'00'` | Fixed key prefix (overridden when `counter` is set) | | `keyPrefixLength` | `?int` | `keyLength / 2` | Prefix length when counter-derived | | `memoryCost` | `?int` | `null` | Memory cost for Argon2id (KiB) / Scrypt (r) | | `nonce` | `?string` | `null` | Custom nonce (hex); random if omitted | | `parallelism` | `?int` | `null` | Parallelism factor for Scrypt (p) | | `salt` | `?string` | `null` | Custom salt (hex); random if omitted | ``` -------------------------------- ### Create Argon2id ALTCHA Challenge Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Generate an ALTCHA challenge using the Argon2id algorithm. This requires the `ext-sodium` PHP extension. Adjust `cost`, `memoryCost`, and `expiresAt` as needed. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\CreateChallengeOptions; use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\Algorithm\Argon2id; use AltchaOrg\Altcha\HmacAlgorithm; $altcha = new Altcha(hmacSignatureSecret: 'secret', hmacKeySignatureSecret: 'key-secret'); // Argon2id variant (requires ext-sodium) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: new Argon2id(), cost: 3, // Argon2id time cost (iterations) memoryCost: 65536, // memory in KiB expiresAt: time() + 300, )); ``` -------------------------------- ### createChallenge Method Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Generates a new ALTCHA challenge with optional parameters for algorithm, cost, expiry, and deterministic modes. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\CreateChallengeOptions; use AltchaOrg\Altcha\Algorithm\Pbkdf2; use AltchaOrg\Altcha\Algorithm\Argon2id; use AltchaOrg\Altcha\HmacAlgorithm; $altcha = new Altcha(hmacSignatureSecret: 'secret', hmacKeySignatureSecret: 'key-secret'); $pbkdf2 = new Pbkdf2(); // Standard challenge (random prefix, expires in 10 minutes) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 10000, expiresAt: time() + 600, // or new \DateTimeImmutable('+10 minutes') )); // Deterministic challenge (known counter → keySignature for fast verification) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: $pbkdf2, cost: 5000, counter: random_int(5000, 10000), // enables keySignature expiresAt: new \DateTimeImmutable('+2 minutes'), data: ['userId' => 42], // optional custom metadata )); // Send to client as JSON header('Content-Type: application/json'); echo $challenge->toJson(); // {"parameters":{"algorithm":"PBKDF2/SHA-256","cost":5000,"keyLength":32, // "keyPrefix":"a3f1...","nonce":"...","salt":"...","expiresAt":... , // "keySignature":"...","data":{"userId":42}},"signature":"..."} // Argon2id variant (requires ext-sodium) $challenge = $altcha->createChallenge(new CreateChallengeOptions( algorithm: new Argon2id(), cost: 3, // Argon2id time cost (iterations) memoryCost: 65536, // memory in KiB expiresAt: time() + 300, )); ``` -------------------------------- ### Altcha::createChallenge Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Creates a new ALTCHA challenge with specified parameters, including the key derivation algorithm, cost, and expiration. ```APIDOC ## Altcha::createChallenge ### Description Creates a new ALTCHA challenge. This method allows customization of the challenge parameters, including the key derivation algorithm, cost, and expiration time. If `counter` is provided and `hmacKeySignatureSecret` is set, the challenge will include a `keySignature` for faster verification. ### Parameters #### Request Body - **options** (CreateChallengeOptions) - Required - Options for creating the challenge. ##### `CreateChallengeOptions` - **algorithm** (DeriveKeyInterface) - Required - The key derivation algorithm to use (e.g., `Pbkdf2`, `Argon2id`). - **cost** (int) - Required - The computational cost (e.g., iterations for PBKDF2). - **counter** (int) - Optional - A counter for deterministic mode, used with `hmacKeySignatureSecret` for fast verification. - **data** (array) - Optional - Custom metadata to include in the challenge. - **expiresAt** (int) - Optional - Unix timestamp indicating when the challenge expires. - **keyLength** (int) - Optional - The desired length of the derived key in bytes (default: 32). - **keyPrefixLength** (int) - Optional - The length of the key prefix to check (default: `keyLength / 2`). - **memoryCost** (int) - Optional - Memory cost for Argon2id/Scrypt algorithms. - **nonce** (string) - Optional - A custom nonce in hexadecimal format. - **parallelism** (int) - Optional - Parallelism factor for Scrypt algorithm. - **salt** (string) - Optional - A custom salt in hexadecimal format. ### Returns - **Challenge** - An object containing the challenge parameters and signature. ``` -------------------------------- ### Create Payload Object Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Wraps a Challenge and Solution pair into a Payload object. Provides methods to serialize the payload into an array, JSON string, or base64-encoded JSON. ```php $payload = new Payload($challenge, $solution); $payload->toArray(); // array $payload->toJson(); // JSON string $payload->toBase64(); // base64-encoded JSON ``` -------------------------------- ### HmacAlgorithm Enum Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Configuration for HMAC signing and PBKDF2 hash function using the HmacAlgorithm enum. ```APIDOC ## `HmacAlgorithm` Enum ### Description Used to configure the HMAC signing algorithm for ALTCHA instances and the hash function for `Pbkdf2`. ### Enum Values - `HmacAlgorithm::SHA256`: Uses 'SHA-256' (default). - `HmacAlgorithm::SHA384`: Uses 'SHA-384'. - `HmacAlgorithm::SHA512`: Uses 'SHA-512'. ### Usage Example ```php use AltchaOrg\Altcha\HmacAlgorithm; $altcha = new Altcha( hmacSignatureSecret: 'secret', hmacAlgorithm: HmacAlgorithm::SHA512, ); ``` ``` -------------------------------- ### Obfuscate and Deobfuscate Data with AES-256-GCM in PHP Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Encrypts arbitrary string data using AES-256-GCM, keyed from a derived key of an ALTCHA challenge. Decryption is tied to proof-of-work. Includes error handling for invalid formats or solve/decrypt failures. ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\Obfuscator; use AltchaOrg\Altcha\Algorithm\Pbkdf2; $altcha = new Altcha(hmacSignatureSecret: 'secret'); $obfuscator = new Obfuscator( altcha: $altcha, algorithm: new Pbkdf2(), // default ); $secret = json_encode(['apiKey' => 'sk-live-abc123', 'userId' => 99]); // Encrypt: creates a challenge, derives the AES key, encrypts with AES-256-GCM $blob = $obfuscator->obfuscate( data: $secret, cost: 5000, // PBKDF2 iterations (default 5000) counterMin: 20, // min counter range (default 20) counterMax: 200, // max counter range (default 200) keyPrefixLength: 32, // full 32-byte AES key prefix (default 32) ); // $blob is a base64 string containing parameters + AES ciphertext // Decrypt: solves the challenge to re-derive the AES key, then decrypts $plain = $obfuscator->deobfuscate( obfuscatedData: $blob, timeout: 30.0, // max solve time (default 30.0s) ); echo $plain; // {"apiKey":"sk-live-abc123","userId":99} // Error handling try { $plain = $obfuscator->deobfuscate($blob); } catch (\InvalidArgumentException $e) { echo "Invalid format: {$e->getMessage()}\n"; } catch (\RuntimeException $e) { echo "Solve/decrypt failed: {$e->getMessage()}\n"; } ``` -------------------------------- ### Altcha::solveChallenge Source: https://github.com/altcha-org/altcha-lib-php/blob/main/README.md Attempts to solve an ALTCHA challenge by iterating through counter values until a valid derived key prefix is found. ```APIDOC ## Altcha::solveChallenge ### Description Solves an ALTCHA challenge by finding a counter value that produces a derived key matching the challenge's prefix. This is typically performed client-side. ### Parameters #### Request Body - **options** (SolveChallengeOptions) - Required - Options for solving the challenge. ##### `SolveChallengeOptions` - **algorithm** (DeriveKeyInterface) - Required - The key derivation algorithm used in the challenge. - **challenge** (Challenge) - Required - The challenge object to solve. - **start** (int) - Optional - The initial counter value to start searching from (default: 0). - **step** (int) - Optional - The increment step for the counter (default: 1). - **timeout** (float) - Optional - The maximum time in seconds to spend solving the challenge (default: 30.0). ### Returns - **Solution** - An object containing the `counter`, `derivedKey` (hex), and `time` taken, or `null` if the challenge could not be solved within the timeout. ``` -------------------------------- ### Altcha Payload Serialization Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt The `Payload` class bundles `Challenge` and `Solution` objects and provides methods for serialization to array, JSON, and base64 formats. The base64-encoded string is typically submitted as the `altcha` form field. ```php use AltchaOrg\Altcha\Payload; $payload = new Payload($challenge, $solution); $payload->toArray(); // ['challenge' => [...], 'solution' => [...]] $payload->toJson(); // '{"challenge":{...},"solution":{...}}' $payload->toBase64(); // base64-encoded JSON string → sent as "altcha" form field // Typical form submission hidden field: // ``` -------------------------------- ### Solve Challenge Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Solves a given Altcha challenge by iterating through counter values and deriving keys until a match is found or a timeout is reached. This operation is CPU-bound and typically runs client-side. ```APIDOC ## `Altcha::solveChallenge(SolveChallengeOptions $options): ?Solution` Iterates counter values starting from `start`, derives a key for each, and returns the first `Solution` whose derived key begins with the challenge's `keyPrefix`. Returns `null` if no match is found within `timeout` seconds. This is a CPU-bound operation — in production it runs client-side in the browser. ```php use AltchaOrg\Altcha\SolveChallengeOptions; $solution = $altcha->solveChallenge(new SolveChallengeOptions( challenge: $challenge, algorithm: $pbkdf2, start: 0, // initial counter (default 0) step: 1, // counter increment per iteration (default 1) timeout: 30.0, // max seconds before giving up (default 30.0) )); if ($solution === null) { echo "No solution found within timeout.\n"; } else { echo "Counter: {$solution->counter}\n"; echo "Derived key (hex): {$solution->derivedKey}\n"; echo "Time taken: {$solution->time}s\n"; // Counter: 7341 // Derived key (hex): a3f1c9... // Time taken: 0.843s } ``` ``` -------------------------------- ### Parse Server Signature Verification Data in PHP Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt Parses raw URL-encoded verification data. Automatic type coercion is applied. Useful for manual handling of server signature payloads. ```php use AltchaOrg\Altcha\ServerSignature; $raw = 'verified=true&expire=1720000000&score=0.05&classification=GOOD' . '&fields=name%2Cemail&reasons=&email=jane%40example.com'; $data = ServerSignature::parseVerificationData($raw); var_dump($data->verified); // bool(true) var_dump($data->expire); // int(1720000000) var_dump($data->score); // float(0.05) var_dump($data->classification); // string(4) "GOOD" var_dump($data->fields); // array(2) { [0]=> "name" [1]=> "email" } var_dump($data->reasons); // array(0) {} var_dump($data->email); // string(16) "jane@example.com" var_dump($data['verified']); // bool(true) — array access also works ``` -------------------------------- ### Payload Serialization Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt The `Payload` class acts as a wrapper for `Challenge` and `Solution` objects, providing methods for serialization into various formats, including JSON and base64, which is commonly used for client-submitted form data. ```APIDOC ## `Payload` — Serialization wrapper Bundles a `Challenge` and `Solution` together and provides serialization helpers. The base64-encoded form is what clients submit in the `altcha` form field. ```php use AltchaOrg\Altcha\Payload; $payload = new Payload($challenge, $solution); $payload->toArray(); // ['challenge' => [...], 'solution' => [...]] $payload->toJson(); // '{"challenge":{...},"solution":{...}}' $payload->toBase64(); // base64-encoded JSON string → sent as "altcha" form field // Typical form submission hidden field: // ``` ``` -------------------------------- ### Obfuscator Source: https://context7.com/altcha-org/altcha-lib-php/llms.txt AES-256-GCM data obfuscation. Encrypts arbitrary string data using AES-256-GCM, keyed from the derived key of an ALTCHA challenge. The client must solve the challenge to recover the AES key and decrypt the data. ```APIDOC ## `Obfuscator` — AES-256-GCM data obfuscation ### Description Encrypts arbitrary string data using AES-256-GCM, keyed from the derived key of an ALTCHA challenge. The client must solve the challenge to recover the AES key and decrypt the data. This ties decryption to proof-of-work, making brute-force extraction expensive. ### Methods #### `obfuscate(string $data, int $cost = 5000, int $counterMin = 20, int $counterMax = 200, int $keyPrefixLength = 32): string` Encrypts the provided data. #### `deobfuscate(string $obfuscatedData, float $timeout = 30.0): string` Decrypts the obfuscated data by first solving the associated challenge. ### Parameters #### `obfuscate` Method Parameters * **data** (string) - Required - The arbitrary string data to encrypt. * **cost** (int) - Optional - PBKDF2 iterations (default 5000). * **counterMin** (int) - Optional - Minimum counter range for challenge generation (default 20). * **counterMax** (int) - Optional - Maximum counter range for challenge generation (default 200). * **keyPrefixLength** (int) - Optional - The length of the AES key prefix (default 32). #### `deobfuscate` Method Parameters * **obfuscatedData** (string) - Required - The base64 encoded string containing parameters and AES ciphertext. * **timeout** (float) - Optional - Maximum time allowed to solve the challenge in seconds (default 30.0). ### Request Example ```php use AltchaOrg\Altcha\Altcha; use AltchaOrg\Altcha\Obfuscator; use AltchaOrg\Altcha\Algorithm\Pbkdf2; $altcha = new Altcha(hmacSignatureSecret: 'secret'); $obfuscator = new Obfuscator( altcha: $altcha, algorithm: new Pbkdf2(), // default ); $secret = json_encode(['apiKey' => 'sk-live-abc123', 'userId' => 99]); // Encrypt $blob = $obfuscator->obfuscate( data: $secret, cost: 5000, counterMin: 20, counterMax: 200, keyPrefixLength: 32, ); // Decrypt $plain = $obfuscator->deobfuscate( obfuscatedData: $blob, timeout: 30.0, ); echo $plain; ``` ### Response #### Success Response (200) * **`obfuscate`**: Returns a base64 encoded string containing parameters and AES ciphertext. * **`deobfuscate`**: Returns the original, decrypted string data. #### Response Example ```php // Output of echo $plain; // {"apiKey":"sk-live-abc123","userId":99} ``` ### Error Handling ```php try { $plain = $obfuscator->deobfuscate($blob); } catch (\InvalidArgumentException $e) { echo "Invalid format: {$e->getMessage()}\n"; } catch (\RuntimeException $e) { echo "Solve/decrypt failed: {$e->getMessage()}\n"; } ``` ```