3v4l.org

run code in 300+ PHP versions simultaneously
<?php declare(strict_types=1); namespace ParagonIE\BlogExampleCode; /** * Implements encryption RSA with PKCS1v1.5 padding * using the Anti-BB'98 dance. * * @ref https://paragonie.com/b/_8qH-xPuGPUoSSsc */ class RSAPKCS1v15 { public static function encrypt(string $message, string $publicKey): array { $key = \random_bytes(32); $C = ''; // This defaults to PKCS1v1.5: \openssl_public_encrypt($key, $C, $publicKey); $iv = \random_bytes(16); $cipher = \openssl_encrypt( $message, 'aes-256-ctr', $key, OPENSSL_RAW_DATA, $iv ); $mac = \hash_hmac('sha256', $iv . $cipher, $key, true); $D = $mac . $iv . $cipher; return [\bin2hex($C), \bin2hex($D)]; } public static function decrypt(string $CHex, string $DHex, string $privateKey): string { $kPrime = \random_bytes(32); $C = \hex2bin($CHex); $D = \hex2bin($DHex); $k = ''; $success = \openssl_private_decrypt($C, $k, $privateKey); // Do a constant-time swap: $key = self::cswap32($k, (string) $kPrime, $success); $mac = \mb_substr($D, 0, 32, '8bit'); $iv = \mb_substr($D, 32, 16, '8bit'); $cipher = \mb_substr($D, 48, null, '8bit'); $recalc = \hash_hmac('sha256', $iv . $cipher, $key, true); if (!\hash_equals($recalc, $mac)) { throw new \Exception('Invalid MAC'); } return \openssl_decrypt( $cipher, 'aes-256-ctr', $key, OPENSSL_RAW_DATA, $iv ); } /** * Branch-less, timing safe version of * $A = ($switch === 0 ? $A : $B); * * @param string $A * @param string $B * @param bool $success * @return string */ public static function cswap32(string $A, string $B, bool $success): string { $A .= \str_repeat("\x00", 32); $B .= \str_repeat("\x00", 32); /** @var int $mask 0 if $success is true, otherwise 255 */ $mask = (((int) $success) - 1) & 0xff; $C = ''; for ($i = 0; $i < 32; ++$i) { $C .= self::intToChr( (self::chrToInt($A[$i]) ^ self::chrToInt($B[$i])) & $mask ); } return (string) mb_substr($A ^ $C, 0, 32, '8bit'); } public static function chrToInt(string $chr): int { $chunk = \unpack('C', $chr); return (int) ($chunk[1]); } public static function intToChr(int $int): string { return \pack('C', $int); } } $private_key = '-----BEGIN RSA PRIVATE KEY----- MIIEowIBAAKCAQEAyaTgTt53ph3p5GHgwoGWwz5hRfWXSQA08NCOwe0FEgALWos9 GCjNFCd723nCHxBtN1qd74MSh/uN88JPIbwxKheDp4kxo4YMN5trPaF0e9G6Bj1N 02HnanxFLW+gmLbgYO/SZYfWF/M8yLBcu5Y1Ot0ZxDDDXS9wIQTtBE0ne3YbxgZJ AZTU5XqyQ1DxdzYyC5lF6yBaR5UQtCYTnXAApVRuUI2Sd6L1E2vl9bSBumZ5IpNx kRnAwIMjeTJB/0AIELh0mE5vwdihOCbdV6alUyhKC1+1w/FW6HWcp/JG1kKC8DPI idZ78Bbqv9YFzkAbNni5eSBOsXVBKG78Zsc8owIDAQABAoIBAF22jLDa34yKdns3 qfd7to+C3D5hRzAcMn6Azvf9qc+VybEI6RnjTHxDZWK5EajSP4/sQ15e8ivUk0Jo WdJ53feL+hnQvwsab28gghSghrxM2kGwGA1XgO+SVawqJt8SjvE+Q+//01ZKK0Oy A0cDJjX3L9RoPUN/moMeAPFw0hqkFEhm72GSVCEY1eY+cOXmL3icxnsnlUD//SS9 q33RxF2y5oiW1edqcRqhW/7L1yYMbxHFUcxWh8WUwjn1AAhoCOUzF8ZB+0X/PPh+ 1nYoq6xwqL0ZKDwrQ8SDhW/rNDLeO9gic5rl7EetRQRbFvsZ40AdsX2wU+lWFUkB 42AjuoECgYEA5z/CXqDFfZ8MXCPAOeui8y5HNDtu30aR+HOXsBDnRI8huXsGND04 FfmXR7nkghr08fFVDmE4PeKUk810YJb+IAJo8wrOZ0682n6yEMO58omqKin+iIUV rPXLSLo5CChrqw2J4vgzolzPw3N5I8FJdLomb9FkrV84H+IviPIylyECgYEA3znw AG29QX6ATEfFpGVOcogorHCntd4niaWCq5ne5sFL+EwLeVc1zD9yj1axcDelICDZ xCZynU7kDnrQcFkT0bjH/gC8Jk3v7XT9l1UDDqC1b7rm/X5wFIZ/rmNa1rVZhL1o /tKx5tvM2syJ1q95v7NdygFIEIW+qbIKbc6Wz0MCgYBsUZdQD+qx/xAhELX364I2 epTryHMUrs+tGygQVrqdiJX5dcDgM1TUJkdQV6jLsKjPs4Vt6OgZRMrnuLMsk02R 3M8gGQ25ok4f4nyyEZxGGWnVujn55KzUiYWhGWmhgp18UCkoYa59/Q9ss+gocV9h B9j9Q43vD80QUjiF4z0DQQKBgC7XQX1VibkMim93QAnXGDcAS0ij+w02qKVBjcHk b9mMBhz8GAxGOIu7ZJafYmxhwMyVGB0I1FQeEczYCJUKnBYN6Clsjg6bnBT/z5bJ x/Jx1qCzX3Uh6vLjpjc5sf4L39Tyye1u2NXQmZPwB5x9BdcsFConSq/s4K1LJtUT 3KFxAoGBANGcQ8nObi3m4wROyKrkCWcWxFFMnpwxv0pW727Hn9wuaOs4UbesCnwm pcMTfzGUDuzYXCtAq2pJl64HG6wsdkWmjBTJEpm6b9ibOBN3qFV2zQ0HyyKlMWxI uVSj9gOo61hF7UH9XB6R4HRdlpBOuIbgAWZ46dkj9/HM9ovdP0Iy -----END RSA PRIVATE KEY-----'; $public_key = '-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyaTgTt53ph3p5GHgwoGW wz5hRfWXSQA08NCOwe0FEgALWos9GCjNFCd723nCHxBtN1qd74MSh/uN88JPIbwx KheDp4kxo4YMN5trPaF0e9G6Bj1N02HnanxFLW+gmLbgYO/SZYfWF/M8yLBcu5Y1 Ot0ZxDDDXS9wIQTtBE0ne3YbxgZJAZTU5XqyQ1DxdzYyC5lF6yBaR5UQtCYTnXAA pVRuUI2Sd6L1E2vl9bSBumZ5IpNxkRnAwIMjeTJB/0AIELh0mE5vwdihOCbdV6al UyhKC1+1w/FW6HWcp/JG1kKC8DPIidZ78Bbqv9YFzkAbNni5eSBOsXVBKG78Zsc8 owIDAQAB -----END PUBLIC KEY-----'; $in = 'This is a test message!'; list ($C, $D) = RSAPKCS1v15::encrypt($in, $public_key); $start = $end = microtime(true); $out = RSAPKCS1v15::decrypt($C, $D, $private_key); $end = microtime(true); var_dump($in, $out); var_dump($end - $start); // Flip the bits in one character of C to force an error $Corig = $D; $C = hex2bin($C); $C[0] = RSAPKCS1v15::intToChr( RSAPKCS1v15::chrToInt($C[0]) ^ 0xff ); $C = bin2hex($C); $start = $end = microtime(true); try { $out = RSAPKCS1v15::decrypt($C, $D, $private_key); } catch (\Exception $ex) { $end = microtime(true); var_dump($end - $start); if ($ex->getMessage() === 'Invalid MAC') { echo 'Got the expected error message. No RSA hints given.', PHP_EOL; } } $C = $Corig; // Flip the bits in one character of D to force an error $Dorig = $D; $D = hex2bin($D); $D[0] = RSAPKCS1v15::intToChr( RSAPKCS1v15::chrToInt($D[0]) ^ 0xff ); $D = bin2hex($D); $start = $end = microtime(true); try { $out = RSAPKCS1v15::decrypt($C, $D, $private_key); } catch (\Exception $ex) { $end = microtime(true); var_dump($end - $start); if ($ex->getMessage() === 'Invalid MAC') { echo 'Got the expected error message. No RSA hints given.', PHP_EOL; } } $D = $Dorig;

Here you find the average performance (time & memory) of each version. A grayed out version indicates it didn't complete successfully (based on exit-code).

VersionSystem time (s)User time (s)Memory (MiB)
8.2.50.0170.00019.52
8.2.40.0170.00019.52
8.2.30.0130.00519.52
8.2.20.0110.00519.52
8.2.10.0140.00319.52
8.2.00.0140.00319.52
8.1.180.0090.00919.52
8.1.170.0110.00619.52
8.1.160.0110.00519.52
8.1.150.0110.00519.52
8.1.140.0140.00319.52
8.1.130.0160.00019.52
8.1.120.0050.00718.77
8.1.110.0170.00019.52
8.1.100.0110.01119.52
8.1.90.0150.00319.52
8.1.80.0150.00019.52
8.1.70.0070.00919.52
8.1.60.0120.00619.52
8.1.50.0130.00619.52
8.1.40.0140.00319.52
8.1.30.0150.00319.52
8.1.20.0100.00819.52
8.1.10.0090.00919.52
8.1.00.0130.00519.52
8.0.280.0130.00219.52
8.0.270.0130.00319.52
8.0.260.0170.00319.52
8.0.250.0110.00419.52
8.0.240.0120.00519.52
8.0.230.0140.00319.52
8.0.220.0140.00319.52
8.0.210.0080.00819.52
8.0.200.0110.00719.52
8.0.190.0140.00319.52
8.0.180.0140.00219.52
8.0.170.0120.00519.52
8.0.160.0110.00619.52
8.0.150.0060.01119.52
8.0.140.0140.00319.52
8.0.130.0080.00819.52
8.0.120.0110.00519.52
8.0.110.0160.00019.52
8.0.100.0180.00019.52
8.0.90.0150.00519.52
8.0.80.0190.00019.52
8.0.70.0150.00219.52
8.0.60.0080.00819.52
8.0.50.0090.00519.52
8.0.30.0080.00819.52
8.0.20.0080.00819.52
8.0.10.0120.00719.52
8.0.00.0100.00718.19
7.4.330.0130.00019.52
7.4.320.0040.01319.52
7.4.300.0080.00819.52
7.4.290.0100.00719.52
7.4.280.0110.00519.52
7.4.270.0190.00019.52
7.4.260.0110.00619.52
7.4.250.0060.00415.40
7.4.240.0050.01119.52
7.4.230.0030.01219.52
7.4.220.0050.01019.52
7.4.210.0100.00519.52
7.4.200.0080.00819.52
7.4.190.0090.00619.52
7.4.180.0100.00519.52
7.4.160.0120.00419.52
7.4.150.0120.00419.52
7.4.140.0050.01019.52
7.4.130.0110.00518.12
7.4.120.0090.00818.14
7.4.110.0050.01218.10
7.4.100.0080.00918.03
7.4.90.0080.01118.04
7.4.80.0110.00618.06
7.4.70.0110.00817.98
7.4.60.0120.00718.06
7.4.50.0080.01018.07
7.4.40.0080.01118.03
7.4.30.0100.00918.08
7.4.20.0150.00918.04
7.4.10.0160.00418.00
7.4.00.0180.00218.17
7.3.330.0150.00019.52
7.3.320.0070.00719.52
7.3.310.0110.00419.52
7.3.300.0150.00019.52
7.3.290.0110.00419.52
7.3.280.0140.00019.52
7.3.270.0130.00319.52
7.3.260.0110.00419.52
7.3.250.0070.00717.96
7.3.240.0090.00718.11
7.3.230.0080.00817.99
7.3.220.0130.00518.04
7.3.210.0120.00418.07
7.3.200.0100.00717.99
7.3.190.0060.01117.95
7.3.180.0130.00717.95
7.3.170.0130.00517.96
7.3.160.0120.01018.00
7.3.150.0110.01018.04
7.3.140.0170.00618.09
7.3.130.0150.00718.09
7.3.120.0100.01018.07
7.3.110.0060.01418.03
7.3.100.0090.00916.98
7.3.90.0110.00816.89
7.3.80.0110.01116.98
7.3.70.0100.00816.93
7.3.60.0050.01316.80
7.3.50.0110.00716.71
7.3.40.0120.00616.77
7.3.30.0110.00816.98
7.3.20.0080.01216.88
7.3.10.0140.00516.84
7.3.00.0100.00916.90
7.2.340.0080.00918.03
7.2.330.0130.00518.18
7.2.320.0100.00817.93
7.2.310.0070.01218.17
7.2.300.0120.00718.07
7.2.290.0130.00718.09
7.2.280.0100.00818.04
7.2.270.0060.01618.04
7.2.260.0090.01218.15
7.2.250.0110.01118.02
7.2.240.0080.01217.97
7.2.230.0140.00618.15
7.2.220.0110.00917.14
7.2.210.0150.00617.14
7.2.200.0080.01017.04
7.2.190.0150.00416.93
7.2.180.0080.01217.03
7.2.170.0140.00317.04
7.2.160.0120.00617.03
7.2.150.0090.01017.10
7.2.140.0110.00717.02
7.2.130.0140.00817.09
7.2.120.0090.00917.05
7.2.110.0120.00817.08
7.2.100.0100.00917.05
7.2.90.0250.01116.49
7.2.80.0280.00816.54
7.2.70.0290.00816.12
7.2.60.0260.00715.98
7.2.50.0320.00816.02
7.2.40.0230.00916.07
7.2.30.0290.00916.12
7.2.20.0220.01016.05
7.2.10.0370.00616.04
7.2.00.0190.00915.99
7.1.330.0170.01117.53
7.1.320.0160.01016.47
7.1.310.0300.00816.43
7.1.300.0150.00816.38
7.1.290.0180.00916.38
7.1.280.0140.00916.41
7.1.270.0110.01116.41
7.1.260.0160.00616.39
7.1.250.0150.00916.42
7.1.240.0160.00816.41
7.1.230.0190.00516.31
7.1.220.0170.00816.33
7.1.210.0390.00715.79
7.1.200.0460.00715.79
7.1.190.0360.00415.73
7.1.180.0320.00515.78
7.1.170.0330.01115.06
7.1.160.0270.00615.15
7.1.150.0360.00915.13
7.1.140.0460.00815.13
7.1.130.0300.00815.15
7.1.120.0270.00815.13
7.1.110.0390.00515.14
7.1.100.0180.00915.12
7.1.90.0330.00715.17
7.1.80.0260.01015.19
7.1.70.0200.01015.19
7.1.60.0290.01024.10
7.1.50.0240.00924.11
7.1.40.0400.00724.10
7.1.30.0330.00924.10
7.1.20.0390.00924.11
7.1.10.0170.00715.16
7.1.00.0170.00815.09
7.0.330.0130.01316.20
7.0.320.0220.00617.46
7.0.310.0190.00417.46
7.0.300.0130.01017.44
7.0.290.0180.00517.41
7.0.280.0180.00517.45
7.0.270.0130.01017.36
7.0.260.0170.00917.44
7.0.250.0210.00617.42
7.0.240.0120.00917.46
7.0.230.0160.00617.39
7.0.220.0130.00917.35
7.0.210.0170.00517.46
7.0.200.0170.00517.41
7.0.190.0170.00417.50
7.0.180.0150.00817.46
7.0.170.0120.00917.39
7.0.160.0160.00817.50
7.0.150.0260.00717.51
7.0.140.0190.00817.50
7.0.130.0180.00517.47
7.0.120.0140.01017.42
7.0.110.0190.00617.46
7.0.100.0190.00517.46
7.0.90.0180.00517.38
7.0.80.0180.00317.42
7.0.70.0110.01017.39
7.0.60.0160.00617.41
7.0.50.0170.01117.38
7.0.40.0150.00717.41
7.0.30.0140.00717.44
7.0.20.0150.00617.33
7.0.10.0190.00417.42
7.0.00.0150.00817.41
5.6.400.0170.00716.24
5.6.390.0120.01116.52
5.6.380.0130.01016.38
5.6.370.0220.00417.65
5.6.360.0200.00517.51
5.6.350.0150.00817.71
5.6.340.0120.01317.51
5.6.330.0180.00817.67
5.6.320.0130.00817.57
5.6.310.0190.00517.58
5.6.300.0200.00517.57
5.6.290.0140.00917.57
5.6.280.0110.01117.54
5.6.270.0180.00517.58
5.6.260.0120.01217.62
5.6.250.0150.00917.54
5.6.240.0140.00917.61
5.6.230.0150.00817.59
5.6.220.0140.00917.57
5.6.210.0140.01017.68
5.6.200.0140.00717.66
5.6.190.0130.01217.66
5.6.180.0140.00917.62
5.6.170.0180.00817.55
5.6.160.0200.00317.57
5.6.150.0180.00517.58
5.6.140.0170.00717.61
5.6.130.0180.00317.56
5.6.120.0190.00317.59
5.6.110.0150.00817.64
5.6.100.0200.00217.63
5.6.90.0140.00917.55
5.6.80.0170.00817.53
5.6.70.0170.00417.62
5.6.60.0130.00917.57
5.6.50.0150.00717.41
5.6.40.0100.00817.43
5.6.30.0130.00817.45
5.6.20.0060.01217.40
5.6.10.0140.00817.41
5.6.00.0140.00717.55

preferences:
42.4 ms | 401 KiB | 5 Q