diff --git a/Makefile b/Makefile index d7529867..744df992 100644 --- a/Makefile +++ b/Makefile @@ -31,6 +31,10 @@ phpcs: phpstan: @php -d xdebug.mode=off vendor/bin/phpstan analyse --memory-limit=-1 +ifndef PHPBENCH_REPORT +override PHPBENCH_REPORT = aggregate +endif + .PHONY: phpbench phpbench: - @vendor/bin/phpbench run -l dots --report aggregate + @vendor/bin/phpbench run -l dots --report=$(PHPBENCH_REPORT) $(PHPBENCH_FLAGS) diff --git a/tests/Benchmark/AlgorithmsBench.php b/tests/Benchmark/AlgorithmsBench.php new file mode 100644 index 00000000..45762e41 --- /dev/null +++ b/tests/Benchmark/AlgorithmsBench.php @@ -0,0 +1,139 @@ + ['HS256', 'HS384', 'HS512'], + 'rsa' => ['RS256', 'RS384', 'RS512'], + 'ecdsa' => ['ES256', 'ES384', 'ES512'], + 'blake2b' => ['BLAKE2B'], + ]; + + protected const PAYLOAD = "It\xe2\x80\x99s a dangerous business, Frodo, going out your door. You step onto the road" + . ", and if you don't keep your feet, there\xe2\x80\x99s no knowing where you might be swept" + . ' off to.'; + + #[Bench\Subject] + #[Bench\ParamProviders('hmacAlgorithms')] + #[Bench\Groups(['hmac', 'symmetric'])] + public function hmac(): void + { + $this->runBenchmark(); + } + + /** @return iterable */ + public function hmacAlgorithms(): iterable + { + yield from $this->iterateAlgorithms('hmac'); + } + + #[Bench\Subject] + #[Bench\ParamProviders('rsaAlgorithms')] + #[Bench\Groups(['rsa', 'asymmetric'])] + public function rsa(): void + { + $this->runBenchmark(); + } + + /** @return iterable */ + public function rsaAlgorithms(): iterable + { + yield from $this->iterateAlgorithms('rsa'); + } + + #[Bench\Subject] + #[Bench\ParamProviders('ecdsaAlgorithms')] + #[Bench\Groups(['ecdsa', 'asymmetric'])] + public function ecdsa(): void + { + $this->runBenchmark(); + } + + /** @return iterable */ + public function ecdsaAlgorithms(): iterable + { + yield from $this->iterateAlgorithms('ecdsa'); + } + + #[Bench\Subject] + #[Bench\ParamProviders('blake2bAlgorithms')] + #[Bench\Groups(['blake2b', 'symmetric'])] + public function blake2b(): void + { + $this->runBenchmark(); + } + + /** @return iterable */ + public function blake2bAlgorithms(): iterable + { + yield from $this->iterateAlgorithms('blake2b'); + } + + abstract protected function runBenchmark(): void; + + protected function resolveAlgorithm(string $name): Signer + { + return match ($name) { + 'HS256' => new Signer\Hmac\Sha256(), + 'HS384' => new Signer\Hmac\Sha384(), + 'HS512' => new Signer\Hmac\Sha512(), + 'RS256' => new Signer\Rsa\Sha256(), + 'RS384' => new Signer\Rsa\Sha384(), + 'RS512' => new Signer\Rsa\Sha512(), + 'ES256' => new Signer\Ecdsa\Sha256(), + 'ES384' => new Signer\Ecdsa\Sha384(), + 'ES512' => new Signer\Ecdsa\Sha512(), + 'BLAKE2B' => new Signer\Blake2b(), + default => throw new RuntimeException('Unknown algorithm'), + }; + } + + protected function resolveSigningKey(string $name): Key + { + return match ($name) { + 'HS256' => InMemory::base64Encoded('n5p7sBK+dvBmSKNlQIFrsuB1cnmnwsxGyWXPgRSZtWY='), + 'HS384' => InMemory::base64Encoded('kNUb8KvJC+fvhPzIuimwWHleES3AAnUjI+UIWZyor5HT33st9KIjfPkgtfu60UL2'), + 'HS512' => InMemory::base64Encoded( + 'OgXKIs+aZCQgXnDfi8mAFnWVo+Xn3JTR7BvT/j1Q1zP9oRx9xGg4jmpq00RsPPDclYi8+jRl664pu4d0zan2ow==', + ), + 'RS256', 'RS384', 'RS512' => InMemory::file(__DIR__ . '/Rsa/private.key'), + 'ES256' => InMemory::file(__DIR__ . '/Ecdsa/private-256.key'), + 'ES384' => InMemory::file(__DIR__ . '/Ecdsa/private-384.key'), + 'ES512' => InMemory::file(__DIR__ . '/Ecdsa/private-521.key'), + 'BLAKE2B' => InMemory::base64Encoded('b6DNRcX2SFapbICe6lXWYoOZA+JXL/dvkfWiv2hJv3Y='), + default => throw new RuntimeException('Unknown algorithm'), + }; + } + + protected function resolveVerificationKey(string $name): Key + { + return match ($name) { + 'HS256', 'HS384', 'HS512', 'BLAKE2B' => $this->resolveSigningKey($name), + 'RS256', 'RS384', 'RS512' => InMemory::file(__DIR__ . '/Rsa/public.key'), + 'ES256' => InMemory::file(__DIR__ . '/Ecdsa/public-256.key'), + 'ES384' => InMemory::file(__DIR__ . '/Ecdsa/public-384.key'), + 'ES512' => InMemory::file(__DIR__ . '/Ecdsa/public-521.key'), + default => throw new RuntimeException('Unknown algorithm'), + }; + } + + /** @return iterable */ + private function iterateAlgorithms(string $family): iterable + { + foreach (self::SUPPORTED_ALGORITHMS[$family] ?? [] as $algorithm) { + yield $algorithm => ['algorithm' => $algorithm]; + } + } +} diff --git a/tests/Benchmark/Blake2bBench.php b/tests/Benchmark/Blake2bBench.php deleted file mode 100644 index a9feac77..00000000 --- a/tests/Benchmark/Blake2bBench.php +++ /dev/null @@ -1,36 +0,0 @@ -createKey(); - } - - protected function verificationKey(): Key - { - return $this->createKey(); - } - - private function createKey(): Key - { - return InMemory::base64Encoded(self::ENCODED_KEY); - } -} diff --git a/tests/Benchmark/CreateSignatureBench.php b/tests/Benchmark/CreateSignatureBench.php new file mode 100644 index 00000000..83870a70 --- /dev/null +++ b/tests/Benchmark/CreateSignatureBench.php @@ -0,0 +1,27 @@ +algorithm = $this->resolveAlgorithm($params['algorithm']); + $this->key = $this->resolveSigningKey($params['algorithm']); + } + + protected function runBenchmark(): void + { + $this->algorithm->sign(self::PAYLOAD, $this->key); + } +} diff --git a/tests/Benchmark/Ecdsa/Sha256Bench.php b/tests/Benchmark/Ecdsa/Sha256Bench.php deleted file mode 100644 index 33388550..00000000 --- a/tests/Benchmark/Ecdsa/Sha256Bench.php +++ /dev/null @@ -1,29 +0,0 @@ -createKey(); - } - - protected function verificationKey(): Key - { - return $this->createKey(); - } - - abstract protected function createKey(): Key; -} diff --git a/tests/Benchmark/Hmac/Sha256Bench.php b/tests/Benchmark/Hmac/Sha256Bench.php deleted file mode 100644 index 847f2d3e..00000000 --- a/tests/Benchmark/Hmac/Sha256Bench.php +++ /dev/null @@ -1,22 +0,0 @@ -algorithm = $this->resolveAlgorithm($params['algorithm']); + $this->key = $this->resolveSigningKey($params['algorithm']); + } + + protected function runBenchmark(): void + { + (new JwtFacade())->issue( + $this->algorithm, + $this->key, + static fn (Builder $builder): Builder => $builder + ->identifiedBy('token-1') + ->issuedBy('lcobucci.jwt.benchmarks') + ->relatedTo('user-1') + ->permittedFor('lcobucci.jwt'), + ); + } +} diff --git a/tests/Benchmark/ParseTokenBench.php b/tests/Benchmark/ParseTokenBench.php new file mode 100644 index 00000000..f0f943d0 --- /dev/null +++ b/tests/Benchmark/ParseTokenBench.php @@ -0,0 +1,51 @@ +algorithm = $this->resolveAlgorithm($params['algorithm']); + $this->key = $this->resolveVerificationKey($params['algorithm']); + + $this->jwt = (new JwtFacade())->issue( + $this->algorithm, + $this->resolveSigningKey($params['algorithm']), + static fn (Builder $builder): Builder => $builder + ->identifiedBy('token-1') + ->issuedBy('lcobucci.jwt.benchmarks') + ->relatedTo('user-1') + ->permittedFor('lcobucci.jwt'), + )->toString(); + } + + protected function runBenchmark(): void + { + (new JwtFacade())->parse( + $this->jwt, + new Constraint\SignedWith($this->algorithm, $this->key), + new Constraint\StrictValidAt(SystemClock::fromSystemTimezone()), + new Constraint\IssuedBy('lcobucci.jwt.benchmarks'), + new Constraint\RelatedTo('user-1'), + new Constraint\PermittedFor('lcobucci.jwt'), + new Constraint\IdentifiedBy('token-1'), + ); + } +} diff --git a/tests/Benchmark/Rsa/RsaBench.php b/tests/Benchmark/Rsa/RsaBench.php deleted file mode 100644 index 65d1af03..00000000 --- a/tests/Benchmark/Rsa/RsaBench.php +++ /dev/null @@ -1,22 +0,0 @@ -signer = $this->signer(); - $this->signingKey = $this->signingKey(); - $this->verificationKey = $this->verificationKey(); - $this->signature = $this->signer->sign(self::PAYLOAD, $this->signingKey); - } - - final public function benchSignature(): void - { - $this->signer->sign(self::PAYLOAD, $this->signingKey); - } - - final public function benchVerification(): void - { - $this->signer->verify($this->signature, self::PAYLOAD, $this->verificationKey); - } - - abstract protected function signer(): Signer; - - abstract protected function signingKey(): Key; - - abstract protected function verificationKey(): Key; -} diff --git a/tests/Benchmark/VerifySignatureBench.php b/tests/Benchmark/VerifySignatureBench.php new file mode 100644 index 00000000..aff363c6 --- /dev/null +++ b/tests/Benchmark/VerifySignatureBench.php @@ -0,0 +1,34 @@ +algorithm = $this->resolveAlgorithm($params['algorithm']); + $this->key = $this->resolveVerificationKey($params['algorithm']); + + $this->signature = $this->algorithm->sign( + self::PAYLOAD, + $this->resolveSigningKey($params['algorithm']), + ); + } + + protected function runBenchmark(): void + { + $this->algorithm->verify($this->signature, self::PAYLOAD, $this->key); + } +}