summaryrefslogtreecommitdiff
path: root/ext/sodium/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ext/sodium/tests')
-rw-r--r--ext/sodium/tests/crypto_aead.phpt135
-rw-r--r--ext/sodium/tests/crypto_auth.phpt47
-rw-r--r--ext/sodium/tests/crypto_box.phpt150
-rw-r--r--ext/sodium/tests/crypto_generichash.phpt61
-rw-r--r--ext/sodium/tests/crypto_hex.phpt21
-rw-r--r--ext/sodium/tests/crypto_kx.phpt37
-rw-r--r--ext/sodium/tests/crypto_scalarmult.phpt20
-rw-r--r--ext/sodium/tests/crypto_secretbox.phpt26
-rw-r--r--ext/sodium/tests/crypto_shorthash.phpt28
-rw-r--r--ext/sodium/tests/crypto_sign.phpt81
-rw-r--r--ext/sodium/tests/crypto_stream.phpt52
-rw-r--r--ext/sodium/tests/exception_trace_without_args.phpt22
-rw-r--r--ext/sodium/tests/inc_add.phpt55
-rw-r--r--ext/sodium/tests/installed.phpt21
-rw-r--r--ext/sodium/tests/pwhash_argon2i.phpt44
-rw-r--r--ext/sodium/tests/pwhash_scrypt.phpt33
-rw-r--r--ext/sodium/tests/utils.phpt62
-rw-r--r--ext/sodium/tests/version.phpt17
18 files changed, 912 insertions, 0 deletions
diff --git a/ext/sodium/tests/crypto_aead.phpt b/ext/sodium/tests/crypto_aead.phpt
new file mode 100644
index 0000000000..5c4a51d32c
--- /dev/null
+++ b/ext/sodium/tests/crypto_aead.phpt
@@ -0,0 +1,135 @@
+--TEST--
+Check for libsodium AEAD
+--SKIPIF--
+<?php
+if (!extension_loaded("sodium")) print "skip extension not loaded";
+if (!defined('SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES')) print "skip libsodium without AESGCM";
+?>
+--FILE--
+<?php
+echo "aead_chacha20poly1305:\n";
+
+$msg = random_bytes(random_int(1, 1000));
+$nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_NPUBBYTES);
+$key = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_KEYBYTES);
+$ad = random_bytes(random_int(1, 1000));
+
+$ciphertext = sodium_crypto_aead_chacha20poly1305_encrypt($msg, $ad, $nonce, $key);
+$msg2 = sodium_crypto_aead_chacha20poly1305_decrypt($ciphertext, $ad, $nonce, $key);
+var_dump($ciphertext !== $msg);
+var_dump($msg === $msg2);
+var_dump(sodium_crypto_aead_chacha20poly1305_decrypt($ciphertext, 'x' . $ad, $nonce, $key));
+try {
+ // Switched order
+ $msg2 = sodium_crypto_aead_chacha20poly1305_decrypt($ciphertext, $ad, $key, $nonce);
+ var_dump(false);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+
+echo "aead_chacha20poly1305_ietf:\n";
+
+if (SODIUM_LIBRARY_MAJOR_VERSION > 7 ||
+ (SODIUM_LIBRARY_MAJOR_VERSION == 7 &&
+ SODIUM_LIBRARY_MINOR_VERSION >= 6)) {
+ $msg = random_bytes(random_int(1, 1000));
+ $nonce = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_NPUBBYTES);
+ $key = random_bytes(SODIUM_CRYPTO_AEAD_CHACHA20POLY1305_IETF_KEYBYTES);
+ $ad = random_bytes(random_int(1, 1000));
+
+ $ciphertext = sodium_crypto_aead_chacha20poly1305_ietf_encrypt($msg, $ad, $nonce, $key);
+ $msg2 = sodium_crypto_aead_chacha20poly1305_ietf_decrypt($ciphertext, $ad, $nonce, $key);
+ var_dump($ciphertext !== $msg);
+ var_dump($msg === $msg2);
+ var_dump(sodium_crypto_aead_chacha20poly1305_ietf_decrypt($ciphertext, 'x' . $ad, $nonce, $key));
+ try {
+ // Switched order
+ $msg2 = sodium_crypto_aead_chacha20poly1305_ietf_decrypt($ciphertext, $ad, $key, $nonce);
+ var_dump(false);
+ } catch (SodiumException $ex) {
+ var_dump(true);
+ }
+} else {
+ var_dump(true);
+ var_dump(true);
+ var_dump(false);
+ var_dump(true);
+}
+
+echo "aead_xchacha20poly1305_ietf:\n";
+
+if (SODIUM_LIBRARY_MAJOR_VERSION > 9 ||
+ (SODIUM_LIBRARY_MAJOR_VERSION == 9 &&
+ SODIUM_LIBRARY_MINOR_VERSION >= 4)) {
+ $msg = random_bytes(random_int(1, 1000));
+ $nonce = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_NPUBBYTES);
+ $key = random_bytes(SODIUM_CRYPTO_AEAD_XCHACHA20POLY1305_IETF_KEYBYTES);
+ $ad = random_bytes(random_int(1, 1000));
+
+ $ciphertext = sodium_crypto_aead_xchacha20poly1305_ietf_encrypt($msg, $ad, $nonce, $key);
+ $msg2 = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, $ad, $nonce, $key);
+ var_dump($ciphertext !== $msg);
+ var_dump($msg === $msg2);
+ var_dump(sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, 'x' . $ad, $nonce, $key));
+ try {
+ // Switched order
+ $msg2 = sodium_crypto_aead_xchacha20poly1305_ietf_decrypt($ciphertext, $ad, $key, $nonce);
+ var_dump(false);
+ } catch (SodiumException $ex) {
+ var_dump(true);
+ }
+} else {
+ var_dump(true);
+ var_dump(true);
+ var_dump(false);
+ var_dump(true);
+}
+
+echo "aead_aes256gcm:\n";
+
+$msg = random_bytes(random_int(1, 1000));
+$nonce = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_NPUBBYTES);
+$key = random_bytes(SODIUM_CRYPTO_AEAD_AES256GCM_KEYBYTES);
+$ad = random_bytes(random_int(1, 1000));
+
+if (sodium_crypto_aead_aes256gcm_is_available()) {
+ $ciphertext = sodium_crypto_aead_aes256gcm_encrypt($msg, $ad, $nonce, $key);
+ $msg2 = sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $ad, $nonce, $key);
+ var_dump($ciphertext !== $msg);
+ var_dump($msg === $msg2);
+ var_dump(sodium_crypto_aead_aes256gcm_decrypt($ciphertext, 'x' . $ad, $nonce, $key));
+ try {
+ // Switched order
+ $msg2 = sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $ad, $key, $nonce);
+ var_dump(false);
+ } catch (SodiumException $ex) {
+ var_dump(true);
+ }
+} else {
+ var_dump(true);
+ var_dump(true);
+ var_dump(false);
+ var_dump(true);
+}
+?>
+--EXPECT--
+aead_chacha20poly1305:
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+aead_chacha20poly1305_ietf:
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+aead_xchacha20poly1305_ietf:
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+aead_aes256gcm:
+bool(true)
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/sodium/tests/crypto_auth.phpt b/ext/sodium/tests/crypto_auth.phpt
new file mode 100644
index 0000000000..25ddff540f
--- /dev/null
+++ b/ext/sodium/tests/crypto_auth.phpt
@@ -0,0 +1,47 @@
+--TEST--
+Check for libsodium auth
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$msg = random_bytes(1000);
+$key = random_bytes(SODIUM_CRYPTO_AUTH_KEYBYTES);
+$mac = sodium_crypto_auth($msg, $key);
+
+// This should validate
+var_dump(sodium_crypto_auth_verify($mac, $msg, $key));
+
+$bad_key = random_bytes(SODIUM_CRYPTO_AUTH_KEYBYTES - 1);
+try {
+ $mac = sodium_crypto_auth($msg, $bad_key);
+ echo 'Fail!', PHP_EOL;
+} catch (SodiumException $ex) {
+ echo $ex->getMessage(), PHP_EOL;
+}
+
+// Flip the first bit
+$badmsg = $msg;
+$badmsg[0] = \chr(\ord($badmsg[0]) ^ 0x80);
+var_dump(sodium_crypto_auth_verify($mac, $badmsg, $key));
+
+// Let's flip a bit pseudo-randomly
+$badmsg = $msg;
+$badmsg[$i=mt_rand(0, 999)] = \chr(
+ \ord($msg[$i]) ^ (
+ 1 << mt_rand(0, 7)
+ )
+);
+
+var_dump(sodium_crypto_auth_verify($mac, $badmsg, $key));
+
+// Now let's change a bit in the MAC
+$badmac = $mac;
+$badmac[0] = \chr(\ord($badmac[0]) ^ 0x80);
+var_dump(sodium_crypto_auth_verify($badmac, $msg, $key));
+?>
+--EXPECT--
+bool(true)
+crypto_auth(): key must be CRYPTO_AUTH_KEYBYTES bytes
+bool(false)
+bool(false)
+bool(false)
diff --git a/ext/sodium/tests/crypto_box.phpt b/ext/sodium/tests/crypto_box.phpt
new file mode 100644
index 0000000000..ef35714714
--- /dev/null
+++ b/ext/sodium/tests/crypto_box.phpt
@@ -0,0 +1,150 @@
+--TEST--
+Check for libsodium box
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$keypair = sodium_crypto_box_keypair();
+var_dump(strlen($keypair) === SODIUM_CRYPTO_BOX_KEYPAIRBYTES);
+$sk = sodium_crypto_box_secretkey($keypair);
+var_dump(strlen($sk) === SODIUM_CRYPTO_BOX_SECRETKEYBYTES);
+$pk = sodium_crypto_box_publickey($keypair);
+var_dump(strlen($pk) === SODIUM_CRYPTO_BOX_PUBLICKEYBYTES);
+var_dump($pk !== $sk);
+$pk2 = sodium_crypto_box_publickey_from_secretkey($sk);
+var_dump($pk === $pk2);
+$pk2 = sodium_crypto_scalarmult_base($sk);
+var_dump($pk === $pk2);
+$keypair2 = sodium_crypto_box_keypair_from_secretkey_and_publickey($sk, $pk);
+var_dump($keypair === $keypair2);
+
+$seed_x = str_repeat('x', SODIUM_CRYPTO_BOX_SEEDBYTES);
+$seed_y = str_repeat('y', SODIUM_CRYPTO_BOX_SEEDBYTES);
+$alice_box_kp = sodium_crypto_box_seed_keypair($seed_x);
+$bob_box_kp = sodium_crypto_box_seed_keypair($seed_y);
+$message_nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
+
+$alice_box_secretkey = sodium_crypto_box_secretkey($alice_box_kp);
+$bob_box_publickey = sodium_crypto_box_publickey($bob_box_kp);
+
+$alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
+ $alice_box_secretkey,
+ $bob_box_publickey
+);
+
+$msg = "Here is another message, to be signed using Alice's secret key, and " .
+ "to be encrypted using Bob's public key. The keys will always be the same " .
+ "since they are derived from a fixed seeds";
+
+$ciphertext = sodium_crypto_box(
+ $msg,
+ $message_nonce,
+ $alice_to_bob_kp
+);
+
+try {
+ $ciphertext = sodium_crypto_box(
+ $msg,
+ $message_nonce,
+ substr($alice_to_bob_kp, 1)
+ );
+} catch (SodiumException $ex) {
+ echo $ex->getMessage(), PHP_EOL;
+}
+
+sodium_memzero($alice_box_kp);
+sodium_memzero($bob_box_kp);
+
+$alice_box_kp = sodium_crypto_box_seed_keypair($seed_x);
+$bob_box_kp = sodium_crypto_box_seed_keypair($seed_y);
+
+$alice_box_publickey = sodium_crypto_box_publickey($alice_box_kp);
+$bob_box_secretkey = sodium_crypto_box_secretkey($bob_box_kp);
+
+$bob_to_alice_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey(
+ $bob_box_secretkey,
+ $alice_box_publickey
+);
+
+$plaintext = sodium_crypto_box_open(
+ $ciphertext,
+ $message_nonce,
+ $bob_to_alice_kp
+);
+
+var_dump($msg === $plaintext);
+
+$alice_kp = sodium_crypto_box_keypair();
+$alice_secretkey = sodium_crypto_box_secretkey($alice_kp);
+$alice_publickey = sodium_crypto_box_publickey($alice_kp);
+
+$bob_kp = sodium_crypto_box_keypair();
+$bob_secretkey = sodium_crypto_box_secretkey($bob_kp);
+$bob_publickey = sodium_crypto_box_publickey($bob_kp);
+
+$alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey
+ ($alice_secretkey, $bob_publickey);
+
+$bob_to_alice_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey
+ ($bob_secretkey, $alice_publickey);
+
+$alice_to_bob_message_nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
+
+$alice_to_bob_ciphertext = sodium_crypto_box('Hi, this is Alice',
+ $alice_to_bob_message_nonce,
+ $alice_to_bob_kp);
+
+$alice_message_decrypted_by_bob = sodium_crypto_box_open($alice_to_bob_ciphertext,
+ $alice_to_bob_message_nonce,
+ $bob_to_alice_kp);
+
+$bob_to_alice_message_nonce = random_bytes(SODIUM_CRYPTO_BOX_NONCEBYTES);
+
+$bob_to_alice_ciphertext = sodium_crypto_box('Hi Alice! This is Bob',
+ $bob_to_alice_message_nonce,
+ $bob_to_alice_kp);
+
+$bob_message_decrypted_by_alice = sodium_crypto_box_open($bob_to_alice_ciphertext,
+ $bob_to_alice_message_nonce,
+ $alice_to_bob_kp);
+
+var_dump($alice_message_decrypted_by_bob);
+var_dump($bob_message_decrypted_by_alice);
+
+if (SODIUM_LIBRARY_MAJOR_VERSION > 7 ||
+ (SODIUM_LIBRARY_MAJOR_VERSION == 7 &&
+ SODIUM_LIBRARY_MINOR_VERSION >= 5)) {
+ $anonymous_message_to_alice = sodium_crypto_box_seal('Anonymous message',
+ $alice_publickey);
+
+ $decrypted_message = sodium_crypto_box_seal_open($anonymous_message_to_alice,
+ $alice_kp);
+} else {
+ $decrypted_message = 'Anonymous message';
+}
+var_dump($decrypted_message);
+
+$msg = sodium_hex2bin(
+ '7375f4094f1151640bd853cb13dbc1a0ee9e13b0287a89d34fa2f6732be9de13f88457553d'.
+ '768347116522d6d32c9cb353ef07aa7c83bd129b2bb5db35b28334c935b24f2639405a0604'
+);
+$kp = sodium_hex2bin(
+ '36a6c2b96a650d80bf7e025e0f58f3d636339575defb370801a54213bd54582d'.
+ '5aecbcf7866e7a4d58a6c1317e2b955f54ecbe2fcbbf7d262c10636ed524480c'
+);
+var_dump(sodium_crypto_box_seal_open($msg, $kp));
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+crypto_box(): keypair size should be CRYPTO_BOX_KEYPAIRBYTES bytes
+bool(true)
+string(17) "Hi, this is Alice"
+string(21) "Hi Alice! This is Bob"
+string(17) "Anonymous message"
+string(26) "This is for your eyes only"
diff --git a/ext/sodium/tests/crypto_generichash.phpt b/ext/sodium/tests/crypto_generichash.phpt
new file mode 100644
index 0000000000..364c5dc5ec
--- /dev/null
+++ b/ext/sodium/tests/crypto_generichash.phpt
@@ -0,0 +1,61 @@
+--TEST--
+Check for libsodium generichash
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$q = sodium_crypto_generichash('msg');
+var_dump(bin2hex($q));
+$q = sodium_crypto_generichash('msg', '0123456789abcdef');
+var_dump(bin2hex($q));
+$q = sodium_crypto_generichash('msg', '0123456789abcdef', 64);
+var_dump(bin2hex($q));
+$q = sodium_crypto_generichash('msg', '0123456789abcdef0123456789abcdef', 64);
+var_dump(bin2hex($q));
+$state = sodium_crypto_generichash_init();
+$q = sodium_crypto_generichash_final($state);
+var_dump(bin2hex($q));
+$state = sodium_crypto_generichash_init();
+sodium_crypto_generichash_update($state, 'm');
+sodium_crypto_generichash_update($state, 'sg');
+$q = sodium_crypto_generichash_final($state);
+var_dump(bin2hex($q));
+$state = sodium_crypto_generichash_init('0123456789abcdef');
+sodium_crypto_generichash_update($state, 'm');
+sodium_crypto_generichash_update($state, 'sg');
+$q = sodium_crypto_generichash_final($state);
+var_dump(bin2hex($q));
+$state = sodium_crypto_generichash_init('0123456789abcdef', 64);
+sodium_crypto_generichash_update($state, 'm');
+sodium_crypto_generichash_update($state, 'sg');
+$state2 = '' . $state;
+$q = sodium_crypto_generichash_final($state, 64);
+var_dump(bin2hex($q));
+sodium_crypto_generichash_update($state2, '2');
+$q = sodium_crypto_generichash_final($state2, 64);
+$exp = bin2hex($q);
+var_dump($exp);
+$act = bin2hex(
+ sodium_crypto_generichash('msg2', '0123456789abcdef', 64)
+);
+var_dump($act);
+var_dump($exp === $act);
+try {
+ $hash = sodium_crypto_generichash('test', '', 128);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+?>
+--EXPECT--
+string(64) "96a7ed8861db0abc006f473f9e64687875f3d9df8e723adae9f53a02b2aec378"
+string(64) "ba03e32a94ece425a77b350f029e0a3d37e6383158aa7cefa2b1b9470a7fcb7a"
+string(128) "8ccd640462e7380010c5722d7f3c2354781d1360430197ff233509c27353fd2597c8d689bfe769467056a0655b3faba6af4e4ade248558f7c53538c4d5b94806"
+string(128) "30f0e5f1e3beb7e0340976ac05a94043cce082d870e28e03c906e8fe9a88786271c6ba141eee2885e7444a870fac498cc78a13b0c53aefaec01bf38ebfe73b3f"
+string(64) "0e5751c026e543b2e8ab2eb06099daa1d1e5df47778f7787faab45cdf12fe3a8"
+string(64) "96a7ed8861db0abc006f473f9e64687875f3d9df8e723adae9f53a02b2aec378"
+string(64) "ba03e32a94ece425a77b350f029e0a3d37e6383158aa7cefa2b1b9470a7fcb7a"
+string(128) "8ccd640462e7380010c5722d7f3c2354781d1360430197ff233509c27353fd2597c8d689bfe769467056a0655b3faba6af4e4ade248558f7c53538c4d5b94806"
+string(128) "9ef702f51114c9dc2cc7521746e8beebe0a3ca9bb29ec729e16682ca982e7f69ff70235a46659a9a6c28f92fbd990288301b9a6b5517f1f2ba6518074af19a5a"
+string(128) "9ef702f51114c9dc2cc7521746e8beebe0a3ca9bb29ec729e16682ca982e7f69ff70235a46659a9a6c28f92fbd990288301b9a6b5517f1f2ba6518074af19a5a"
+bool(true)
+bool(true)
diff --git a/ext/sodium/tests/crypto_hex.phpt b/ext/sodium/tests/crypto_hex.phpt
new file mode 100644
index 0000000000..0f872ee867
--- /dev/null
+++ b/ext/sodium/tests/crypto_hex.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Check for libsodium bin2hex
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$bin = random_bytes(random_int(1, 1000));
+$hex = sodium_bin2hex($bin);
+$phphex = bin2hex($bin);
+var_dump(strcasecmp($hex, $phphex));
+
+$bin2 = sodium_hex2bin($hex);
+var_dump($bin2 === $bin);
+
+$bin2 = sodium_hex2bin('[' . $hex .']', '[]');
+var_dump($bin2 === $bin);
+?>
+--EXPECT--
+int(0)
+bool(true)
+bool(true)
diff --git a/ext/sodium/tests/crypto_kx.phpt b/ext/sodium/tests/crypto_kx.phpt
new file mode 100644
index 0000000000..ef8c5f7a63
--- /dev/null
+++ b/ext/sodium/tests/crypto_kx.phpt
@@ -0,0 +1,37 @@
+--TEST--
+Check for libsodium-based key exchange
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$client_secretkey = sodium_hex2bin("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a");
+$client_publickey = sodium_crypto_box_publickey_from_secretkey($client_secretkey);
+
+$server_secretkey = sodium_hex2bin("948f00e90a246fb5909f8648c2ac6f21515771235523266439e0d775ba0c3671");
+$server_publickey = sodium_crypto_box_publickey_from_secretkey($server_secretkey);
+
+$shared_key_computed_by_client =
+ sodium_crypto_kx($client_secretkey, $server_publickey,
+ $client_publickey, $server_publickey);
+
+$shared_key_computed_by_server =
+ sodium_crypto_kx($server_secretkey, $client_publickey,
+ $client_publickey, $server_publickey);
+
+var_dump(sodium_bin2hex($shared_key_computed_by_client));
+var_dump(sodium_bin2hex($shared_key_computed_by_server));
+try {
+ sodium_crypto_kx(
+ substr($client_secretkey, 1),
+ $server_publickey,
+ $client_publickey,
+ $server_publickey
+ );
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+?>
+--EXPECT--
+string(64) "509a1580c2ee30c565317e29e0fea0b1c232e0ef3a7871d91dc64814b19a3bd2"
+string(64) "509a1580c2ee30c565317e29e0fea0b1c232e0ef3a7871d91dc64814b19a3bd2"
+bool(true)
diff --git a/ext/sodium/tests/crypto_scalarmult.phpt b/ext/sodium/tests/crypto_scalarmult.phpt
new file mode 100644
index 0000000000..22496cd669
--- /dev/null
+++ b/ext/sodium/tests/crypto_scalarmult.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Check for libsodium scalarmult
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$n = sodium_hex2bin("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb");
+$p = sodium_hex2bin("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a");
+$q = sodium_crypto_scalarmult($n, $p);
+
+var_dump(sodium_bin2hex($q));
+try {
+ sodium_crypto_scalarmult(substr($n, 1), $p);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+?>
+--EXPECT--
+string(64) "4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742"
+bool(true)
diff --git a/ext/sodium/tests/crypto_secretbox.phpt b/ext/sodium/tests/crypto_secretbox.phpt
new file mode 100644
index 0000000000..f4bf53ec61
--- /dev/null
+++ b/ext/sodium/tests/crypto_secretbox.phpt
@@ -0,0 +1,26 @@
+--TEST--
+Check for libsodium secretbox
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES);
+$key = random_bytes(SODIUM_CRYPTO_SECRETBOX_KEYBYTES);
+
+$a = sodium_crypto_secretbox('test', $nonce, $key);
+$x = sodium_crypto_secretbox_open($a, $nonce, $key);
+var_dump(bin2hex($x));
+$y = sodium_crypto_secretbox_open("\0" . $a, $nonce, $key);
+var_dump($y);
+
+try {
+ sodium_crypto_secretbox('test', substr($nonce, 1), $key);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+
+?>
+--EXPECT--
+string(8) "74657374"
+bool(false)
+bool(true)
diff --git a/ext/sodium/tests/crypto_shorthash.phpt b/ext/sodium/tests/crypto_shorthash.phpt
new file mode 100644
index 0000000000..3398def06e
--- /dev/null
+++ b/ext/sodium/tests/crypto_shorthash.phpt
@@ -0,0 +1,28 @@
+--TEST--
+Check for libsodium shorthash
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$m1 = 'message';
+$k1 = '0123456789ABCDEF';
+$h1 = sodium_crypto_shorthash($m1, $k1);
+echo bin2hex($h1) . "\n";
+$k2 = '0123456789abcdef';
+$h2 = sodium_crypto_shorthash($m1, $k2);
+echo bin2hex($h2) . "\n";
+$m2 = 'msg';
+$h3 = sodium_crypto_shorthash($m2, $k2);
+echo bin2hex($h3) . "\n";
+
+try {
+ sodium_crypto_shorthash($m1, $k1 . $k2);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+?>
+--EXPECT--
+e0ad6fdbf8b9a191
+c667b37af201a2d9
+d27fa3fc70b45b72
+bool(true)
diff --git a/ext/sodium/tests/crypto_sign.phpt b/ext/sodium/tests/crypto_sign.phpt
new file mode 100644
index 0000000000..55fe8920bf
--- /dev/null
+++ b/ext/sodium/tests/crypto_sign.phpt
@@ -0,0 +1,81 @@
+--TEST--
+Check for libsodium ed25519 signatures
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$keypair = sodium_crypto_sign_keypair();
+var_dump(strlen($keypair) === SODIUM_CRYPTO_SIGN_KEYPAIRBYTES);
+$sk = sodium_crypto_sign_secretkey($keypair);
+var_dump(strlen($sk) === SODIUM_CRYPTO_SIGN_SECRETKEYBYTES);
+$pk = sodium_crypto_sign_publickey($keypair);
+var_dump(strlen($pk) === SODIUM_CRYPTO_SIGN_PUBLICKEYBYTES);
+var_dump($pk !== $sk);
+$keypair2 = sodium_crypto_sign_keypair_from_secretkey_and_publickey($sk, $pk);
+var_dump($keypair === $keypair2);
+
+$alice_kp = sodium_crypto_sign_keypair();
+$alice_secretkey = sodium_crypto_sign_secretkey($alice_kp);
+$alice_publickey = sodium_crypto_sign_publickey($alice_kp);
+
+$msg = "Here is the message, to be signed using Alice's secret key, and " .
+ "to be verified using Alice's public key";
+
+$msg_signed = sodium_crypto_sign($msg, $alice_secretkey);
+var_dump(strlen($msg_signed) - strlen($msg) === SODIUM_CRYPTO_SIGN_BYTES);
+
+$msg_orig = sodium_crypto_sign_open($msg_signed, $alice_publickey);
+var_dump($msg_orig === $msg);
+
+$seed = str_repeat('x', SODIUM_CRYPTO_SIGN_SEEDBYTES);
+$alice_kp = sodium_crypto_sign_seed_keypair($seed);
+
+$alice_secretkey = sodium_crypto_sign_secretkey($alice_kp);
+$alice_publickey = sodium_crypto_sign_publickey($alice_kp);
+
+$msg = "Here is another message, to be signed using Alice's secret key, and " .
+ "to be verified using Alice's public key, which will be always the same " .
+ "since they are derived from a fixed seed";
+
+$msg_signed = sodium_crypto_sign($msg, $alice_secretkey);
+var_dump(strlen($msg_signed) - strlen($msg) === SODIUM_CRYPTO_SIGN_BYTES);
+
+$msg_orig = sodium_crypto_sign_open($msg_signed, $alice_publickey);
+var_dump($msg_orig === $msg);
+
+$signature = sodium_crypto_sign_detached($msg, $alice_secretkey);
+var_dump(strlen($signature) === SODIUM_CRYPTO_SIGN_BYTES);
+var_dump(sodium_crypto_sign_verify_detached($signature,
+ $msg, $alice_publickey));
+var_dump(sodium_crypto_sign_verify_detached($signature,
+ $msg . "\0", $alice_publickey));
+
+$calc_pubkey = sodium_crypto_sign_publickey_from_secretkey($alice_secretkey);
+var_dump(sodium_memcmp($calc_pubkey, $alice_publickey) === 0);
+
+$ed25519key = sodium_hex2bin("55b62f664bf1c359f58a6b91b89556f97284273510573055b9237d17f5a20564607f0626f49e63c2c8f814ed6d955bf8b005b33fd5fd56eaca93073d8eb99165");
+$curve25519key = sodium_crypto_sign_ed25519_sk_to_curve25519($ed25519key);
+var_dump($curve25519key === sodium_hex2bin("381b2be5e3d38820deb1243fb58b4be654da30dd3ccde492cb88f937eb489363"));
+
+try {
+ sodium_crypto_sign($msg, substr($alice_secretkey, 1));
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/sodium/tests/crypto_stream.phpt b/ext/sodium/tests/crypto_stream.phpt
new file mode 100644
index 0000000000..7439e289b8
--- /dev/null
+++ b/ext/sodium/tests/crypto_stream.phpt
@@ -0,0 +1,52 @@
+--TEST--
+Check for libsodium stream
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);
+$key = random_bytes(SODIUM_CRYPTO_STREAM_KEYBYTES);
+
+$len = 100;
+$stream = sodium_crypto_stream($len, $nonce, $key);
+var_dump(strlen($stream));
+
+$stream2 = sodium_crypto_stream($len, $nonce, $key);
+
+$nonce = random_bytes(SODIUM_CRYPTO_STREAM_NONCEBYTES);
+$stream3 = sodium_crypto_stream($len, $nonce, $key);
+
+$key = random_bytes(SODIUM_CRYPTO_STREAM_KEYBYTES);
+$stream4 = sodium_crypto_stream($len, $nonce, $key);
+
+var_dump($stream === $stream2);
+var_dump($stream !== $stream3);
+var_dump($stream !== $stream4);
+var_dump($stream2 !== $stream3);
+var_dump($stream2 !== $stream4);
+var_dump($stream3 !== $stream4);
+
+$stream5 = sodium_crypto_stream_xor($stream, $nonce, $key);
+var_dump($stream5 !== $stream);
+$stream6 = sodium_crypto_stream_xor($stream5, $nonce, $key);
+
+var_dump($stream6 === $stream);
+
+try {
+ sodium_crypto_stream($len, substr($nonce, 1), $key);
+} catch (SodiumException $ex) {
+ var_dump(true);
+}
+
+?>
+--EXPECT--
+int(100)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
+bool(true)
diff --git a/ext/sodium/tests/exception_trace_without_args.phpt b/ext/sodium/tests/exception_trace_without_args.phpt
new file mode 100644
index 0000000000..c821df0eb5
--- /dev/null
+++ b/ext/sodium/tests/exception_trace_without_args.phpt
@@ -0,0 +1,22 @@
+--TEST--
+SodiumException backtraces do not contain function arguments
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+
+function do_memzero($x) {
+ sodium_memzero($x);
+}
+
+$x = 42;
+do_memzero($x);
+
+?>
+--EXPECTF--
+Fatal error: Uncaught SodiumException: memzero: a PHP string is required in %s:%d
+Stack trace:
+#0 %s(%d): sodium_memzero()
+#1 %s(%d): do_memzero()
+#2 {main}
+ thrown in %s on line %d
diff --git a/ext/sodium/tests/inc_add.phpt b/ext/sodium/tests/inc_add.phpt
new file mode 100644
index 0000000000..2ab9b92696
--- /dev/null
+++ b/ext/sodium/tests/inc_add.phpt
@@ -0,0 +1,55 @@
+--TEST--
+increment and add edge cases
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+
+$notStr = 123;
+try {
+ sodium_increment($notStr);
+} catch (SodiumException $e) {
+ echo $e->getMessage(), "\n";
+}
+
+$str = "abc";
+$str2 = $str;
+sodium_increment($str);
+var_dump($str, $str2);
+
+$str = "ab" . ($x = "c");
+$str2 = $str;
+sodium_increment($str);
+var_dump($str, $str2);
+
+$addStr = "\2\0\0";
+
+$notStr = 123;
+try {
+ sodium_add($notStr, $addStr);
+} catch (SodiumException $e) {
+ echo $e->getMessage(), "\n";
+}
+
+$str = "abc";
+$str2 = $str;
+sodium_add($str, $addStr);
+var_dump($str, $str2);
+
+$str = "ab" . ($x = "c");
+$str2 = $str;
+sodium_add($str, $addStr);
+var_dump($str, $str2);
+
+?>
+--EXPECT--
+increment(): a PHP string is required
+string(3) "bbc"
+string(3) "abc"
+string(3) "bbc"
+string(3) "abc"
+add(): PHP strings are required
+string(3) "cbc"
+string(3) "abc"
+string(3) "cbc"
+string(3) "abc"
diff --git a/ext/sodium/tests/installed.phpt b/ext/sodium/tests/installed.phpt
new file mode 100644
index 0000000000..43ad4fdd86
--- /dev/null
+++ b/ext/sodium/tests/installed.phpt
@@ -0,0 +1,21 @@
+--TEST--
+Check for libsodium presence
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+echo "libsodium extension is available";
+/*
+ you can add regression tests for your extension here
+
+ the output of your test code has to be equal to the
+ text in the --EXPECT-- section below for the tests
+ to pass, differences between the output and the
+ expected text are interpreted as failure
+
+ see php5/README.TESTING for further information on
+ writing regression tests
+*/
+?>
+--EXPECT--
+libsodium extension is available
diff --git a/ext/sodium/tests/pwhash_argon2i.phpt b/ext/sodium/tests/pwhash_argon2i.phpt
new file mode 100644
index 0000000000..eb36223b87
--- /dev/null
+++ b/ext/sodium/tests/pwhash_argon2i.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Check for libsodium utils
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip";
+if (!defined('SODIUM_CRYPTO_PWHASH_SALTBYTES')) print "skip libsodium without argon2i"; ?>
+--FILE--
+<?php
+$passwd = 'password';
+
+$hash = sodium_crypto_pwhash_str
+ ($passwd, SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
+ SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
+var_dump(substr($hash, 0, 9) ===
+ SODIUM_CRYPTO_PWHASH_STRPREFIX);
+
+$testHash = '$argon2i$v=19$m=4096,t=3,p=1$MzE4ODFiZWFlMjAzOWUAAA$FWUV6tsyJ32qThiLi1cCsLIbf3dIOG/RwXcTzt536KY';
+$c = sodium_crypto_pwhash_str_verify($testHash, $passwd);
+var_dump($c);
+
+$testHash = '$argon2i$v=19$m=4096,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA$JTBozgKQiCn5yKAm3Hz0vUSX/XgfqhZloNCxDWmeDr0';
+$c = sodium_crypto_pwhash_str_verify($testHash, $passwd);
+var_dump($c);
+
+$c = sodium_crypto_pwhash_str_verify($hash, $passwd);
+var_dump($c);
+
+$c = sodium_crypto_pwhash_str_verify($hash, 'passwd');
+var_dump($c);
+
+$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SALTBYTES);
+$out_len = 100;
+$key = sodium_crypto_pwhash
+ ($out_len, $passwd, $salt,
+ SODIUM_CRYPTO_PWHASH_OPSLIMIT_INTERACTIVE,
+ SODIUM_CRYPTO_PWHASH_MEMLIMIT_INTERACTIVE);
+var_dump(strlen($key) === $out_len);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(false)
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/sodium/tests/pwhash_scrypt.phpt b/ext/sodium/tests/pwhash_scrypt.phpt
new file mode 100644
index 0000000000..e5a204926c
--- /dev/null
+++ b/ext/sodium/tests/pwhash_scrypt.phpt
@@ -0,0 +1,33 @@
+--TEST--
+Check for libsodium utils
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$passwd = 'test';
+
+$hash = sodium_crypto_pwhash_scryptsalsa208sha256_str
+ ($passwd, SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE,
+ SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE);
+var_dump(substr($hash, 0, 3) ===
+ SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_STRPREFIX);
+
+$c = sodium_crypto_pwhash_scryptsalsa208sha256_str_verify($hash, $passwd);
+var_dump($c);
+
+$c = sodium_crypto_pwhash_scryptsalsa208sha256_str_verify($hash, 'passwd');
+var_dump($c);
+
+$salt = random_bytes(SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_SALTBYTES);
+$out_len = 100;
+$key = sodium_crypto_pwhash_scryptsalsa208sha256
+ ($out_len, $passwd, $salt,
+ SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_OPSLIMIT_INTERACTIVE,
+ SODIUM_CRYPTO_PWHASH_SCRYPTSALSA208SHA256_MEMLIMIT_INTERACTIVE);
+var_dump(strlen($key) === $out_len);
+?>
+--EXPECT--
+bool(true)
+bool(true)
+bool(false)
+bool(true)
diff --git a/ext/sodium/tests/utils.phpt b/ext/sodium/tests/utils.phpt
new file mode 100644
index 0000000000..c413e01a81
--- /dev/null
+++ b/ext/sodium/tests/utils.phpt
@@ -0,0 +1,62 @@
+--TEST--
+Check for libsodium utils
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+$a = 'test';
+sodium_memzero($a);
+if ($a !== 'test') {
+ echo strlen($a);
+} else {
+ echo $a;
+}
+echo "\n";
+$b = 'string';
+$c = 'string';
+var_dump(!sodium_memcmp($b, $c));
+var_dump(!sodium_memcmp($b, 'String'));
+$v = "\xFF\xFF\x80\x01\x02\x03\x04\x05\x06\x07";
+$v .= "\x08";
+sodium_increment($v);
+var_dump(bin2hex($v));
+
+$w = "\x01\x02\x03\x04\x05\x06\x07\x08\xFA\xFB";
+$w .= "\xFC";
+sodium_add($v, $w);
+var_dump(bin2hex($v));
+
+if (SODIUM_LIBRARY_MAJOR_VERSION > 7 ||
+ (SODIUM_LIBRARY_MAJOR_VERSION == 7 &&
+ SODIUM_LIBRARY_MINOR_VERSION >= 6)) {
+ $v_1 = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+ $v_2 = ""."\x02\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F";
+ $v_1 .= '';
+ var_dump(sodium_compare($v_1, $v_2));
+ sodium_increment($v_1);
+ var_dump(sodium_compare($v_1, $v_2));
+ sodium_increment($v_1);
+ var_dump(sodium_compare($v_1, $v_2));
+} else {
+ // Dummy test results for libsodium < 1.0.4
+ var_dump(-1, 0, 1);
+}
+
+$str = 'stdClass';
+sodium_memzero($str);
+$obj = (object)array('foo' => 'bar');
+var_dump($obj);
+?>
+--EXPECT--
+0
+bool(true)
+bool(false)
+string(22) "0000810102030405060708"
+string(22) "0102840507090b0d000305"
+int(-1)
+int(0)
+int(1)
+object(stdClass)#1 (1) {
+ ["foo"]=>
+ string(3) "bar"
+}
diff --git a/ext/sodium/tests/version.phpt b/ext/sodium/tests/version.phpt
new file mode 100644
index 0000000000..f13345ea07
--- /dev/null
+++ b/ext/sodium/tests/version.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Check for libsodium version
+--SKIPIF--
+<?php if (!extension_loaded("sodium")) print "skip"; ?>
+--FILE--
+<?php
+echo strlen(SODIUM_LIBRARY_VERSION) >= 5;
+echo "\n";
+echo SODIUM_LIBRARY_MAJOR_VERSION >= 4;
+echo "\n";
+echo SODIUM_LIBRARY_MINOR_VERSION >= 0;
+?>
+--EXPECT--
+1
+1
+1
+