From fbcb29501ad98397e23f654347aad20eea2faf7e Mon Sep 17 00:00:00 2001 From: Paragon Initiative Enterprises Date: Wed, 28 Apr 2021 04:04:04 -0400 Subject: [PATCH 1/3] Expose libsodium's Ristretto255 API --- ext/sodium/libsodium.c | 397 ++++++++++++++++++ ext/sodium/libsodium.stub.php | 34 ++ ext/sodium/libsodium_arginfo.h | 168 +++++++- ext/sodium/php_libsodium.h | 15 + .../tests/crypto_core_ristretto255.phpt | 114 +++++ .../tests/crypto_scalarmult_ristretto255.phpt | 27 ++ 6 files changed, 754 insertions(+), 1 deletion(-) create mode 100644 ext/sodium/tests/crypto_core_ristretto255.phpt create mode 100644 ext/sodium/tests/crypto_scalarmult_ristretto255.phpt diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 79c725729aa4e..1237fe281295d 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -365,6 +365,20 @@ PHP_MINIT_FUNCTION(sodium) REGISTER_LONG_CONSTANT("SODIUM_BASE64_VARIANT_URLSAFE_NO_PADDING", sodium_base64_VARIANT_URLSAFE_NO_PADDING, CONST_CS | CONST_PERSISTENT); #endif +#ifdef crypto_core_ristretto255_HASHBYTES + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES", + crypto_scalarmult_ristretto255_BYTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES", + crypto_scalarmult_ristretto255_SCALARBYTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES", + crypto_core_ristretto255_BYTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES", + crypto_core_ristretto255_HASHBYTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES", + crypto_core_ristretto255_SCALARBYTES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES", + crypto_core_ristretto255_NONREDUCEDSCALARBYTES, CONST_CS | CONST_PERSISTENT); +#endif #if SODIUM_LIBRARY_VERSION_MAJOR > 9 || (SODIUM_LIBRARY_VERSION_MAJOR == 9 && SODIUM_LIBRARY_VERSION_MINOR >= 6) if (FAILURE == PHP_MINIT(sodium_password_hash)(INIT_FUNC_ARGS_PASSTHRU)) { @@ -2544,6 +2558,69 @@ PHP_FUNCTION(sodium_crypto_scalarmult) RETURN_NEW_STR(q); } +#ifdef crypto_core_ristretto255_HASHBYTES +PHP_FUNCTION(sodium_crypto_scalarmult_ristretto255) +{ + zend_string *q; + unsigned char *n; + unsigned char *p; + size_t n_len; + size_t p_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &n, &n_len, &p, &p_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (n_len != crypto_scalarmult_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + if (p_len != crypto_scalarmult_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + q = zend_string_alloc(crypto_scalarmult_ristretto255_BYTES, 0); + if (crypto_scalarmult_ristretto255((unsigned char *) ZSTR_VAL(q), n, p) != 0) { + zend_string_efree(q); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(q)[crypto_scalarmult_BYTES] = 0; + + RETURN_NEW_STR(q); +} + +PHP_FUNCTION(sodium_crypto_scalarmult_ristretto255_base) +{ + zend_string *q; + unsigned char *n; + size_t n_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &n, &n_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (n_len != crypto_scalarmult_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_SCALARMULT_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + q = zend_string_alloc(crypto_scalarmult_ristretto255_BYTES, 0); + if (crypto_scalarmult_ristretto255_base((unsigned char *) ZSTR_VAL(q), n) != 0) { + zend_string_efree(q); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(q)[crypto_scalarmult_BYTES] = 0; + + RETURN_NEW_STR(q); +} +#endif + PHP_FUNCTION(sodium_crypto_kx_seed_keypair) { unsigned char *sk; @@ -3428,3 +3505,323 @@ PHP_FUNCTION(sodium_crypto_secretstream_xchacha20poly1305_rekey) crypto_secretstream_xchacha20poly1305_rekey((void *) state); } #endif + +#ifdef crypto_core_ristretto255_HASHBYTES +PHP_FUNCTION(sodium_crypto_core_ristretto255_add) +{ + zend_string *r; + unsigned char *p; + unsigned char *q; + size_t p_len; + size_t q_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &p, &p_len, &q, &q_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (p_len != crypto_core_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + if (q_len != crypto_core_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + if (crypto_core_ristretto255_add((unsigned char *) ZSTR_VAL(r), p, q) != 0) { + zend_string_efree(r); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_from_hash) +{ + zend_string *r; + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_HASHBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_HASHBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + if (crypto_core_ristretto255_from_hash((unsigned char *) ZSTR_VAL(r), s) != 0) { + zend_string_efree(r); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_is_valid_point) +{ + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + if (crypto_core_ristretto255_is_valid_point(s) != 1) { + RETURN_FALSE; + } + RETURN_TRUE; +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_random) +{ + zend_string *r; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + crypto_core_ristretto255_random((unsigned char *) ZSTR_VAL(r)); + ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_add) +{ + zend_string *r; + unsigned char *p; + unsigned char *q; + size_t p_len; + size_t q_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &p, &p_len, &q, &q_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (p_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + if (q_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + crypto_core_ristretto255_scalar_add((unsigned char *) ZSTR_VAL(r), p, q); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_complement) +{ + zend_string *r; + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + crypto_core_ristretto255_scalar_complement((unsigned char *) ZSTR_VAL(r), s); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_invert) +{ + zend_string *r; + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + if (crypto_core_ristretto255_scalar_invert((unsigned char *) ZSTR_VAL(r), s) != 0) { + zend_string_efree(r); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_mul) +{ + zend_string *r; + unsigned char *x; + unsigned char *y; + size_t x_len; + size_t y_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &x, &x_len, &y, &y_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (x_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + if (y_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + crypto_core_ristretto255_scalar_mul((unsigned char *) ZSTR_VAL(r), x, y); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_negate) +{ + zend_string *r; + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + crypto_core_ristretto255_scalar_negate((unsigned char *) ZSTR_VAL(r), s); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_random) +{ + zend_string *r; + + if (zend_parse_parameters_none() == FAILURE) { + RETURN_THROWS(); + }; + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + crypto_core_ristretto255_scalar_random((unsigned char *) ZSTR_VAL(r)); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_reduce) +{ + zend_string *r; + unsigned char *s; + size_t s_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", + &s, &s_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (s_len != crypto_core_ristretto255_NONREDUCEDSCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_NONREDUCEDSCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_SCALARBYTES, 0); + crypto_core_ristretto255_scalar_reduce((unsigned char *) ZSTR_VAL(r), s); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_sub) +{ + zend_string *r; + unsigned char *p; + unsigned char *q; + size_t p_len; + size_t q_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &p, &p_len, &q, &q_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (p_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + if (q_len != crypto_core_ristretto255_SCALARBYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_SCALARBYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + crypto_core_ristretto255_scalar_sub((unsigned char *) ZSTR_VAL(r), p, q); + ZSTR_VAL(r)[crypto_core_ristretto255_SCALARBYTES] = 0; + RETURN_NEW_STR(r); +} + +PHP_FUNCTION(sodium_crypto_core_ristretto255_sub) +{ + zend_string *r; + unsigned char *p; + unsigned char *q; + size_t p_len; + size_t q_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "ss", + &p, &p_len, &q, &q_len) == FAILURE) { + sodium_remove_param_values_from_backtrace(EG(exception)); + RETURN_THROWS(); + } + if (p_len != crypto_core_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 1, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + if (q_len != crypto_core_ristretto255_BYTES) { + zend_argument_error(sodium_exception_ce, 2, + "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); + RETURN_THROWS(); + } + r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); + if (crypto_core_ristretto255_sub((unsigned char *) ZSTR_VAL(r), p, q) != 0) { + zend_string_efree(r); + zend_throw_exception(sodium_exception_ce, "internal error", 0); + RETURN_THROWS(); + } + ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; + RETURN_NEW_STR(r); +} +#endif diff --git a/ext/sodium/libsodium.stub.php b/ext/sodium/libsodium.stub.php index c6388eca87781..cb47255bcbfc5 100644 --- a/ext/sodium/libsodium.stub.php +++ b/ext/sodium/libsodium.stub.php @@ -58,6 +58,34 @@ function sodium_crypto_box_seal_open(string $ciphertext, string $key_pair): stri function sodium_crypto_box_secretkey(string $key_pair): string {} +#ifdef crypto_core_ristretto255_HASHBYTES +function sodium_crypto_core_ristretto255_add(string $p, string $q): string {} + +function sodium_crypto_core_ristretto255_from_hash(string $s): string {} + +function sodium_crypto_core_ristretto255_is_valid_point(string $s): bool {} + +function sodium_crypto_core_ristretto255_random(): string {} + +function sodium_crypto_core_ristretto255_scalar_add(string $p, string $q): string {} + +function sodium_crypto_core_ristretto255_scalar_complement(string $s): string {} + +function sodium_crypto_core_ristretto255_scalar_invert(string $s): string {} + +function sodium_crypto_core_ristretto255_scalar_mul(string $x, string $y): string {} + +function sodium_crypto_core_ristretto255_scalar_negate(string $s): string {} + +function sodium_crypto_core_ristretto255_scalar_random(): string {} + +function sodium_crypto_core_ristretto255_scalar_reduce(string $s): string {} + +function sodium_crypto_core_ristretto255_scalar_sub(string $p, string $q): string {} + +function sodium_crypto_core_ristretto255_sub(string $p, string $q): string {} +#endif + function sodium_crypto_kx_keypair(): string {} function sodium_crypto_kx_publickey(string $key_pair): string {} @@ -106,6 +134,12 @@ function sodium_crypto_pwhash_scryptsalsa208sha256_str_verify(string $hash, stri function sodium_crypto_scalarmult(string $n, string $p): string {} +#ifdef crypto_core_ristretto255_HASHBYTES +function sodium_crypto_scalarmult_ristretto255(string $n, string $p): string {} + +function sodium_crypto_scalarmult_ristretto255_base(string $n): string {} +#endif + function sodium_crypto_secretbox(string $message, string $nonce, string $key): string {} function sodium_crypto_secretbox_keygen(): string {} diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index 1f9069f1c51c8..f1eb74a15e959 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 55ce0e93db5fac4311ba90693668a92001167573 */ + * Stub hash: 84584a76aa7f397e0c23a4612f5132f6088ecb28 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -129,6 +129,69 @@ ZEND_END_ARG_INFO() #define arginfo_sodium_crypto_box_secretkey arginfo_sodium_crypto_box_publickey +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_add, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, p, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, q, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_from_hash, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, s, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_is_valid_point, 0, 1, _IS_BOOL, 0) + ZEND_ARG_TYPE_INFO(0, s, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_random, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_add arginfo_sodium_crypto_core_ristretto255_add +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_complement arginfo_sodium_crypto_core_ristretto255_from_hash +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_invert arginfo_sodium_crypto_core_ristretto255_from_hash +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_scalar_mul, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, x, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, y, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_negate arginfo_sodium_crypto_core_ristretto255_from_hash +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_random arginfo_sodium_crypto_core_ristretto255_random +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_reduce arginfo_sodium_crypto_core_ristretto255_from_hash +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_scalar_sub arginfo_sodium_crypto_core_ristretto255_add +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +#define arginfo_sodium_crypto_core_ristretto255_sub arginfo_sodium_crypto_core_ristretto255_add +#endif + #define arginfo_sodium_crypto_kx_keypair arginfo_sodium_crypto_aead_chacha20poly1305_keygen #define arginfo_sodium_crypto_kx_publickey arginfo_sodium_crypto_box_publickey @@ -243,6 +306,19 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_scalarmult, 0, 2, ZEND_ARG_TYPE_INFO(0, p, IS_STRING, 0) ZEND_END_ARG_INFO() +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_scalarmult_ristretto255, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, n, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, p, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_scalarmult_ristretto255_base, 0, 1, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, n, IS_STRING, 0) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_secretbox, 0, 3, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, nonce, IS_STRING, 0) @@ -462,6 +538,45 @@ ZEND_FUNCTION(sodium_crypto_box_publickey_from_secretkey); ZEND_FUNCTION(sodium_crypto_box_seal); ZEND_FUNCTION(sodium_crypto_box_seal_open); ZEND_FUNCTION(sodium_crypto_box_secretkey); +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_add); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_from_hash); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_is_valid_point); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_random); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_add); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_complement); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_invert); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_mul); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_negate); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_random); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_reduce); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_scalar_sub); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_core_ristretto255_sub); +#endif ZEND_FUNCTION(sodium_crypto_kx_keypair); ZEND_FUNCTION(sodium_crypto_kx_publickey); ZEND_FUNCTION(sodium_crypto_kx_secretkey); @@ -497,6 +612,12 @@ ZEND_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str); ZEND_FUNCTION(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify); #endif ZEND_FUNCTION(sodium_crypto_scalarmult); +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_scalarmult_ristretto255); +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) +ZEND_FUNCTION(sodium_crypto_scalarmult_ristretto255_base); +#endif ZEND_FUNCTION(sodium_crypto_secretbox); ZEND_FUNCTION(sodium_crypto_secretbox_keygen); ZEND_FUNCTION(sodium_crypto_secretbox_open); @@ -600,6 +721,45 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_crypto_box_seal, arginfo_sodium_crypto_box_seal) ZEND_FE(sodium_crypto_box_seal_open, arginfo_sodium_crypto_box_seal_open) ZEND_FE(sodium_crypto_box_secretkey, arginfo_sodium_crypto_box_secretkey) +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_add, arginfo_sodium_crypto_core_ristretto255_add) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_from_hash, arginfo_sodium_crypto_core_ristretto255_from_hash) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_is_valid_point, arginfo_sodium_crypto_core_ristretto255_is_valid_point) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_random, arginfo_sodium_crypto_core_ristretto255_random) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_add, arginfo_sodium_crypto_core_ristretto255_scalar_add) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_complement, arginfo_sodium_crypto_core_ristretto255_scalar_complement) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_invert, arginfo_sodium_crypto_core_ristretto255_scalar_invert) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_mul, arginfo_sodium_crypto_core_ristretto255_scalar_mul) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_negate, arginfo_sodium_crypto_core_ristretto255_scalar_negate) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_random, arginfo_sodium_crypto_core_ristretto255_scalar_random) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_reduce, arginfo_sodium_crypto_core_ristretto255_scalar_reduce) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_scalar_sub, arginfo_sodium_crypto_core_ristretto255_scalar_sub) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_core_ristretto255_sub, arginfo_sodium_crypto_core_ristretto255_sub) +#endif ZEND_FE(sodium_crypto_kx_keypair, arginfo_sodium_crypto_kx_keypair) ZEND_FE(sodium_crypto_kx_publickey, arginfo_sodium_crypto_kx_publickey) ZEND_FE(sodium_crypto_kx_secretkey, arginfo_sodium_crypto_kx_secretkey) @@ -635,6 +795,12 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(sodium_crypto_pwhash_scryptsalsa208sha256_str_verify, arginfo_sodium_crypto_pwhash_scryptsalsa208sha256_str_verify) #endif ZEND_FE(sodium_crypto_scalarmult, arginfo_sodium_crypto_scalarmult) +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_scalarmult_ristretto255, arginfo_sodium_crypto_scalarmult_ristretto255) +#endif +#if defined(crypto_core_ristretto255_HASHBYTES) + ZEND_FE(sodium_crypto_scalarmult_ristretto255_base, arginfo_sodium_crypto_scalarmult_ristretto255_base) +#endif ZEND_FE(sodium_crypto_secretbox, arginfo_sodium_crypto_secretbox) ZEND_FE(sodium_crypto_secretbox_keygen, arginfo_sodium_crypto_secretbox_keygen) ZEND_FE(sodium_crypto_secretbox_open, arginfo_sodium_crypto_secretbox_open) diff --git a/ext/sodium/php_libsodium.h b/ext/sodium/php_libsodium.h index d9db3d17e9048..a9b6622663179 100644 --- a/ext/sodium/php_libsodium.h +++ b/ext/sodium/php_libsodium.h @@ -64,6 +64,19 @@ PHP_FUNCTION(sodium_crypto_box_seal); PHP_FUNCTION(sodium_crypto_box_seal_open); PHP_FUNCTION(sodium_crypto_box_secretkey); PHP_FUNCTION(sodium_crypto_box_seed_keypair); +PHP_FUNCTION(sodium_crypto_core_ristretto255_add); +PHP_FUNCTION(sodium_crypto_core_ristretto255_from_hash); +PHP_FUNCTION(sodium_crypto_core_ristretto255_is_valid_point); +PHP_FUNCTION(sodium_crypto_core_ristretto255_random); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_add); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_complement); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_invert); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_mul); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_negate); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_random); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_reduce); +PHP_FUNCTION(sodium_crypto_core_ristretto255_scalar_sub); +PHP_FUNCTION(sodium_crypto_core_ristretto255_sub); PHP_FUNCTION(sodium_crypto_generichash); PHP_FUNCTION(sodium_crypto_generichash_final); PHP_FUNCTION(sodium_crypto_generichash_init); @@ -86,6 +99,8 @@ PHP_FUNCTION(sodium_crypto_pwhash_str_needs_rehash); PHP_FUNCTION(sodium_crypto_pwhash_str_verify); PHP_FUNCTION(sodium_crypto_scalarmult); PHP_FUNCTION(sodium_crypto_scalarmult_base); +PHP_FUNCTION(sodium_crypto_scalarmult_ristretto255); +PHP_FUNCTION(sodium_crypto_scalarmult_ristretto255_base); PHP_FUNCTION(sodium_crypto_secretbox); PHP_FUNCTION(sodium_crypto_secretbox_keygen); PHP_FUNCTION(sodium_crypto_secretbox_open); diff --git a/ext/sodium/tests/crypto_core_ristretto255.phpt b/ext/sodium/tests/crypto_core_ristretto255.phpt new file mode 100644 index 0000000000000..b58c7e69bebc8 --- /dev/null +++ b/ext/sodium/tests/crypto_core_ristretto255.phpt @@ -0,0 +1,114 @@ +--TEST-- +Check for libsodium scalarmult ristretto255 +--EXTENSIONS-- +sodium +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +string(64) "3066f82a1a747d45120d1740f14358531a8f04bbffe6a819f86dfe50f44a0a46" +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) diff --git a/ext/sodium/tests/crypto_scalarmult_ristretto255.phpt b/ext/sodium/tests/crypto_scalarmult_ristretto255.phpt new file mode 100644 index 0000000000000..f18287de0ff6b --- /dev/null +++ b/ext/sodium/tests/crypto_scalarmult_ristretto255.phpt @@ -0,0 +1,27 @@ +--TEST-- +Check for libsodium scalarmult ristretto255 +--EXTENSIONS-- +sodium +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(64) "2a684afd8de19c6964fffd28509294e2752fdbb79e13a58dec3aff51de65505e" +string(64) "e08ec8d22c0901c1746da3844857e9bc25b77cfe14a412e7bcd2b4017aff0556" +bool(true) From 1ada95db77979621a44fb029add7b1df812c3884 Mon Sep 17 00:00:00 2001 From: Paragon Initiative Enterprises Date: Fri, 7 May 2021 16:50:47 -0400 Subject: [PATCH 2/3] Update UPGRADING to document sodium changes Also includes the UPGRADING changes for #6868 --- UPGRADING | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/UPGRADING b/UPGRADING index a69170a1a63a6..d22ef195cc458 100644 --- a/UPGRADING +++ b/UPGRADING @@ -298,6 +298,34 @@ PHP 8.1 UPGRADE NOTES flush its buffers to physical storage. RFC: https://wiki.php.net/rfc/fsync_function +- Sodium: + . Added the XChaCha20 stream cipher interface functions: + + - sodium_crypto_stream_xchacha20() + - sodium_crypto_stream_xchacha20_keygen() + - sodium_crypto_stream_xchacha20_xor() + + . Added the Ristretto255 functions, which are available in libsodium 1.0.18. + + Ristretto is a technique for constructing prime order elliptic curve groups with non-malleable encodings. + Ristretto255 implements Ristretto atop Curve25519. + + - sodium_crypto_core_ristretto255_add() + - sodium_crypto_core_ristretto255_from_hash() + - sodium_crypto_core_ristretto255_is_valid_point() + - sodium_crypto_core_ristretto255_random() + - sodium_crypto_core_ristretto255_scalar_add() + - sodium_crypto_core_ristretto255_scalar_complement() + - sodium_crypto_core_ristretto255_scalar_invert() + - sodium_crypto_core_ristretto255_scalar_mul() + - sodium_crypto_core_ristretto255_scalar_negate() + - sodium_crypto_core_ristretto255_scalar_random() + - sodium_crypto_core_ristretto255_scalar_reduce() + - sodium_crypto_core_ristretto255_scalar_sub() + - sodium_crypto_core_ristretto255_sub() + - sodium_crypto_scalarmult_ristretto255() + - sodium_crypto_scalarmult_ristretto255_base() + ======================================== 7. New Classes and Interfaces ======================================== From b7a6613b72151b017fa3cb9436b3cdebb89492c2 Mon Sep 17 00:00:00 2001 From: Paragon Initiative Enterprises Date: Fri, 7 May 2021 16:54:28 -0400 Subject: [PATCH 3/3] Implement suggested changes from Nikita's code review --- ext/sodium/libsodium.c | 7 ++----- ext/sodium/libsodium.stub.php | 4 ++-- ext/sodium/libsodium_arginfo.h | 14 +++++++------- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/ext/sodium/libsodium.c b/ext/sodium/libsodium.c index 1237fe281295d..37faf06aba66d 100644 --- a/ext/sodium/libsodium.c +++ b/ext/sodium/libsodium.c @@ -3581,10 +3581,7 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_is_valid_point) "must be SODIUM_CRYPTO_CORE_RISTRETTO255_BYTES bytes long"); RETURN_THROWS(); } - if (crypto_core_ristretto255_is_valid_point(s) != 1) { - RETURN_FALSE; - } - RETURN_TRUE; + RETURN_BOOL(crypto_core_ristretto255_is_valid_point(s)); } PHP_FUNCTION(sodium_crypto_core_ristretto255_random) @@ -3595,7 +3592,7 @@ PHP_FUNCTION(sodium_crypto_core_ristretto255_random) RETURN_THROWS(); } r = zend_string_alloc(crypto_core_ristretto255_BYTES, 0); - crypto_core_ristretto255_random((unsigned char *) ZSTR_VAL(r)); + crypto_core_ristretto255_random((unsigned char *) ZSTR_VAL(r)); ZSTR_VAL(r)[crypto_core_ristretto255_BYTES] = 0; RETURN_NEW_STR(r); } diff --git a/ext/sodium/libsodium.stub.php b/ext/sodium/libsodium.stub.php index cb47255bcbfc5..5a49889e35ea6 100644 --- a/ext/sodium/libsodium.stub.php +++ b/ext/sodium/libsodium.stub.php @@ -67,7 +67,7 @@ function sodium_crypto_core_ristretto255_is_valid_point(string $s): bool {} function sodium_crypto_core_ristretto255_random(): string {} -function sodium_crypto_core_ristretto255_scalar_add(string $p, string $q): string {} +function sodium_crypto_core_ristretto255_scalar_add(string $x, string $y): string {} function sodium_crypto_core_ristretto255_scalar_complement(string $s): string {} @@ -81,7 +81,7 @@ function sodium_crypto_core_ristretto255_scalar_random(): string {} function sodium_crypto_core_ristretto255_scalar_reduce(string $s): string {} -function sodium_crypto_core_ristretto255_scalar_sub(string $p, string $q): string {} +function sodium_crypto_core_ristretto255_scalar_sub(string $x, string $y): string {} function sodium_crypto_core_ristretto255_sub(string $p, string $q): string {} #endif diff --git a/ext/sodium/libsodium_arginfo.h b/ext/sodium/libsodium_arginfo.h index f1eb74a15e959..7453650b39f81 100644 --- a/ext/sodium/libsodium_arginfo.h +++ b/ext/sodium/libsodium_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 84584a76aa7f397e0c23a4612f5132f6088ecb28 */ + * Stub hash: 286436656e37c5d71de69ed6365b5202e0965f19 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_aead_aes256gcm_is_available, 0, 0, _IS_BOOL, 0) ZEND_END_ARG_INFO() @@ -154,7 +154,10 @@ ZEND_END_ARG_INFO() #endif #if defined(crypto_core_ristretto255_HASHBYTES) -#define arginfo_sodium_crypto_core_ristretto255_scalar_add arginfo_sodium_crypto_core_ristretto255_add +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_scalar_add, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, x, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, y, IS_STRING, 0) +ZEND_END_ARG_INFO() #endif #if defined(crypto_core_ristretto255_HASHBYTES) @@ -166,10 +169,7 @@ ZEND_END_ARG_INFO() #endif #if defined(crypto_core_ristretto255_HASHBYTES) -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_sodium_crypto_core_ristretto255_scalar_mul, 0, 2, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, x, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, y, IS_STRING, 0) -ZEND_END_ARG_INFO() +#define arginfo_sodium_crypto_core_ristretto255_scalar_mul arginfo_sodium_crypto_core_ristretto255_scalar_add #endif #if defined(crypto_core_ristretto255_HASHBYTES) @@ -185,7 +185,7 @@ ZEND_END_ARG_INFO() #endif #if defined(crypto_core_ristretto255_HASHBYTES) -#define arginfo_sodium_crypto_core_ristretto255_scalar_sub arginfo_sodium_crypto_core_ristretto255_add +#define arginfo_sodium_crypto_core_ristretto255_scalar_sub arginfo_sodium_crypto_core_ristretto255_scalar_add #endif #if defined(crypto_core_ristretto255_HASHBYTES)