3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types=1); define('SODIUM_CRYPTO_RSIGN_SIGBYTES', 96); function sodium_crypto_rsign(string $message, string $sk): string { return sodium_crypto_sign(random_bytes(32) . $message, $sk); } function sodium_crypto_rsign_open(string $sm, string $pk): string { $opened = sodium_crypto_sign_open($sm, $pk); return mb_substr($opened, 32, null, '8bit'); } function sodium_crypto_rsign_detached(string $message, string $sk): string { $random = random_bytes(32); return sodium_crypto_sign_detached($random . $message, $sk) . $random; } function sodium_crypto_rsign_verify_detached(string $signature, string $message, string $pk): bool { $sig = mb_substr($signature, 0, 64, '8bit'); $random = mb_substr($signature, 64, 32, '8bit'); return sodium_crypto_sign_verify_detached($sig, $random . $message, $pk); } /*** TESTS ***/ $kp = sodium_crypto_sign_keypair(); $sk = sodium_crypto_sign_secretkey($kp); $pk = sodium_crypto_sign_publickey($kp); # First test: Does it work? $message = 'This is a test message.'; $signed = sodium_crypto_rsign($message, $sk); $ropen = sodium_crypto_rsign_open($signed, $pk); if (!hash_equals($message, $ropen)) { echo bin2hex($signed), PHP_EOL; echo bin2hex($ropen), PHP_EOL; exit(255); } # Second test: Is it backwards compatible? $random = mb_substr($signed, 64, 32, '8bit'); $open = sodium_crypto_sign_open($signed, $pk); if (!hash_equals($random . $message, $open)) { echo bin2hex($signed), PHP_EOL; echo bin2hex($open), PHP_EOL; exit(255); } # Third test: Detached API $msg2 = 'Cryptography nerds in the kitchen have too much thyme on their hands.'; // Do you feel timing attacked? $sig = sodium_crypto_rsign_detached($msg2, $sk); $len = mb_strlen($sig, '8bit'); if ($len !== SODIUM_CRYPTO_RSIGN_SIGBYTES) { echo 'Expected ', SODIUM_CRYPTO_RSIGN_SIGBYTES, '; got ', $len, '.', PHP_EOL; exit(255); } if (!sodium_crypto_rsign_verify_detached($sig, $msg2, $pk)) { echo 'Invalid signature.', PHP_EOL; exit(255); } $sig2 = sodium_crypto_rsign_detached($msg2, $sk); if (hash_equals($sig, $sig2)) { echo 'RNG Failure.', PHP_EOL; echo bin2hex($sig), PHP_EOL; echo bin2hex($sig2), PHP_EOL; exit(255); } $sigLeft = mb_substr($sig, 0, 64, '8bit'); $sigRight = mb_substr($sig, 64, 32, '8bit'); if (!sodium_crypto_rsign_verify_detached($sigLeft, $sigRight . $msg2, $pk)) { echo 'Invalid signature.', PHP_EOL; exit(255); } echo 'All tests pass!', PHP_EOL; // Two signatures of the same message: var_dump(bin2hex($sig), bin2hex($sig2));

preferences:
48.39 ms | 402 KiB | 5 Q