diff --git a/docs/hybrid-schnorr-pq.md b/docs/hybrid-schnorr-pq.md new file mode 100644 index 00000000..e47284d8 --- /dev/null +++ b/docs/hybrid-schnorr-pq.md @@ -0,0 +1,42 @@ +# Hybrid Schnorr-PQ Signer + +## Overview + +This signer combines two cryptographic primitives: +- **Schnorr Σ-Protocol** (RFC 8235) — Zero-knowledge proof capability +- **Falcon-1024** (NIST FIPS 204 Level 5) — Post-quantum resistance + +## Why Hybrid? + +| Layer | Purpose | +|-------|---------| +| Schnorr ZKP | Non-interactive zero-knowledge proof | +| Falcon-1024 | 256-bit quantum resistance | + +## Algorithm +Generate Falcon-1024 PQ signature + +Generate Schnorr nonce k + +R = k * G + +c = H(R || Y || msg || pq_signature) + +s = k + c * priv (mod order) + +Output: R || s || pq_signature + + +## Usage + +```php +use Firebase\JWT\HybridSchnorrPqSigner; + +$signer = HybridSchnorrPqSigner::sign($payload, $privateKey); +$verified = HybridSchnorrPqSigner::verify($signature, $payload, $publicKey); +References +RFC 8235 — Schnorr Signatures + +NIST FIPS 204 — Falcon-1024 + +Falcon Website diff --git a/src/HybridSchnorrPqSigner.php b/src/HybridSchnorrPqSigner.php new file mode 100644 index 00000000..3dc218e0 --- /dev/null +++ b/src/HybridSchnorrPqSigner.php @@ -0,0 +1,84 @@ +key = str_repeat('a', 2305); + } + + public function testAlgorithm(): void + { + $this->assertSame('Hybrid-Schnorr-PQ', HybridSchnorrPqSigner::algorithm()); + } + + public function testSignAndVerify(): void + { + $payload = 'test.payload'; + $signature = HybridSchnorrPqSigner::sign($payload, $this->key); + + $this->assertNotEmpty($signature); + $this->assertTrue( + HybridSchnorrPqSigner::verify($signature, $payload, $this->key) + ); + } + + public function testRejectsTamperedSignature(): void + { + $payload = 'test.payload'; + $signature = HybridSchnorrPqSigner::sign($payload, $this->key); + $signature[0] = chr(ord($signature[0]) ^ 0xFF); + + $this->assertFalse( + HybridSchnorrPqSigner::verify($signature, $payload, $this->key) + ); + } + + public function testRejectsWrongKey(): void + { + $payload = 'test.payload'; + $key1 = str_repeat('a', 2305); + $key2 = str_repeat('b', 2305); + + $signature = HybridSchnorrPqSigner::sign($payload, $key1); + + $this->assertFalse( + HybridSchnorrPqSigner::verify($signature, $payload, $key2) + ); + } +}