Closed paragonie-security closed 2 years ago
Here's a dumb benchmarking script:
<?php
require_once __DIR__ . '/autoload-phpunit.php';
ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
$stop = $start = 0.0;
$i = 0;
$start = microtime(true);
while ($i < 1000) {
$p = sodium_crypto_core_ristretto255_scalar_random();
$q = sodium_crypto_core_ristretto255_scalar_random();
$r = sodium_crypto_core_ristretto255_scalar_add($p, $q);
$p = sodium_crypto_core_ristretto255_scalar_sub($r, $q);
$z = sodium_crypto_core_ristretto255_scalar_mul($p, $q);
$comp = sodium_crypto_core_ristretto255_scalar_complement($p);
$inv = sodium_crypto_core_ristretto255_scalar_invert($p);
$neg1 = sodium_crypto_core_ristretto255_scalar_negate($p);
$bytes = random_bytes(ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES);
$red = sodium_crypto_core_ristretto255_scalar_reduce($bytes);
$alice = sodium_crypto_box_keypair();
$alice_s = sodium_crypto_box_secretkey($alice);
$alice_p = sodium_crypto_box_publickey($alice);
$bob = sodium_crypto_box_keypair();
$bob_s = sodium_crypto_box_secretkey($bob);
$bob_p = sodium_crypto_box_publickey($bob);
$a2b = sodium_crypto_scalarmult($alice_s, $bob_p);
$b2a = sodium_crypto_scalarmult($bob_s, $alice_p);
++$i;
}
$stop = microtime(true);
var_dump($stop - $start);
PS> php .\bench.php
float(0.2294149398803711)
PS> php .\bench.php
float(0.22782397270202637)
PS> php .\bench.php
float(0.22809386253356934)
PS> php .\bench.php
float(0.2278280258178711)
PS> php .\bench.php
float(0.2308211326599121)
PS> php .\bench.php
float(0.23272085189819336)
For this test, I added declare(strict_types=1);
to all the .php files in scope
PS> php .\bench.php
float(0.22864103317260742)
PS> php .\bench.php
float(0.22912812232971191)
PS> php .\bench.php
float(0.22997093200683594)
Test | Trial 1 | Trial 2 | Trial 3 | Average |
---|---|---|---|---|
master | 0.2294149399 | 0.2278239727 | 0.2280938625 | 0.2284442584 |
v2.x | 0.2278280258 | 0.2308211327 | 0.2327208519 | 0.2304566701 |
v2.x-strict | 0.2286410332 | 0.2291281223 | 0.229970932 | 0.2292466958 |
It seems that any performance penalty incurred by strict types is negligible at best.
I forgot to disable ext-sodium, so here's a better benchmarking script.
<?php
declare(strict_types=1);
require_once __DIR__ . '/autoload-phpunit.php';
ParagonIE_Sodium_Compat::$disableFallbackForUnitTests = true;
$stop = $start = 0.0;
$i = 0;
$start = microtime(true);
while ($i < 5) {
$p = ParagonIE_Sodium_Compat::ristretto255_scalar_random();
$q = ParagonIE_Sodium_Compat::ristretto255_scalar_random();
$r = ParagonIE_Sodium_Compat::ristretto255_scalar_add($p, $q);
$p = ParagonIE_Sodium_Compat::ristretto255_scalar_sub($r, $q);
$z = ParagonIE_Sodium_Compat::ristretto255_scalar_mul($p, $q);
$comp = ParagonIE_Sodium_Compat::ristretto255_scalar_complement($p);
$inv = ParagonIE_Sodium_Compat::ristretto255_scalar_invert($p);
$neg = ParagonIE_Sodium_Compat::ristretto255_scalar_negate($p);
$bytes = random_bytes(ParagonIE_Sodium_Compat::CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES);
$red = ParagonIE_Sodium_Compat::ristretto255_scalar_reduce($bytes);
$alice = ParagonIE_Sodium_Compat::crypto_box_keypair();
$alice_s = ParagonIE_Sodium_Compat::crypto_box_secretkey($alice);
$alice_p = ParagonIE_Sodium_Compat::crypto_box_publickey($alice);
$bob = ParagonIE_Sodium_Compat::crypto_box_keypair();
$bob_s = ParagonIE_Sodium_Compat::crypto_box_secretkey($bob);
$bob_p = ParagonIE_Sodium_Compat::crypto_box_publickey($bob);
$a2b = ParagonIE_Sodium_Compat::crypto_scalarmult($alice_s, $bob_p);
$b2a = ParagonIE_Sodium_Compat::crypto_scalarmult($bob_s, $alice_p);
++$i;
}
$stop = microtime(true);
var_dump($stop - $start);
Test | Trial 1 | Trial 2 | Trial 3 | Average |
---|---|---|---|---|
master | 4.158897877 | 4.164984941 | 4.245276928 | 4.189719915 |
v2.x | 3.994076967 | 3.92305994 | 3.975117922 | 3.964084943 |
v2.x-strict | 4.012229204 | 4.049883127 | 4.064672947 | 4.042261759 |
From v2's perspective, there is a small (1.97%) performance hit for using strict_types. However, the savings from dev-master are still larger (3.64% slower).
If we anchor on dev-master, the total run1time is 94.61% (v2) and 96.48% (v2-strict) what we were seeing before.
Overall, performance is improved with v2.x.
I'm closing this pull request. If we decide to continue work on v2.x, the current branch will serve as the basis for this work.
See #137 for background
This PoC exists to answer the following questions:
I may follow up with another branch that pins the minimum to 8.1 and uses FFI for scrypt/Argon2 support.
Note: This will never be merged into the
master
branch (indefinite PHP 5 support is a goal of that branch). Additionally, no tags/releases will be issued from this branch until we're settled on what the minimum version constraint for a sodium_compat v2.x should even be.What's Been Removed?
\Sodium\*()
APIWhat's Been Changed?
Not much else, really. You should be able to test these changes against your own code without modifying anything since v1.19.0.
How Do These Changes Affect PHP 8.2?
dev-master
This Branch
Some tests were removed (due to removed support).