. Added DateTime::createFromInterface() and
DateTimeImmutable::createFromInterface().
+- Dom:
+ . Introduce DOMParentNode and DOMChildNode with new traversal and
+ manipulation APIs.
+ RFC: https://wiki.php.net/rfc/dom_living_standard_api
+
- Enchant:
. enchant_dict_add()
. enchant_dict_is_added()
. LIBENCHANT_VERSION macro
-- dom:
- . Introduce DOMParentNode and DOMChildNode with new traversal and manipulation APIs
- RFC: https://wiki.php.net/rfc/dom_living_standard_api
+- Hash:
+ . HashContext objects can now be serialized.
- Opcache:
. If the opcache.record_warnings ini setting is enabled, opcache will record
#include "php_hash.h"
#include "ext/standard/info.h"
#include "ext/standard/file.h"
+#include "ext/standard/php_var.h"
+#include "ext/spl/spl_exceptions.h"
#include "zend_interfaces.h"
#include "zend_exceptions.h"
+#include "zend_smart_str.h"
#include "hash_arginfo.h"
+#ifdef PHP_WIN32
+# define __alignof__ __alignof
+#else
+# ifndef HAVE_ALIGNOF
+# include <stddef.h>
+# define __alignof__(type) offsetof (struct { char c; type member;}, member)
+# endif
+#endif
+
HashTable php_hash_hashtable;
zend_class_entry *php_hashcontext_ce;
static zend_object_handlers php_hashcontext_handlers;
}
/* }}} */
+
+static inline size_t align_to(size_t pos, size_t alignment) {
+ size_t offset = pos & (alignment - 1);
+ return pos + (offset ? alignment - offset : 0);
+}
+
+static size_t parse_serialize_spec(
+ const char **specp, size_t *pos, size_t *sz, size_t *max_alignment) {
+ size_t count, alignment;
+ const char *spec = *specp;
+ /* parse size */
+ if (*spec == 's' || *spec == 'S') {
+ *sz = 2;
+ alignment = __alignof__(uint16_t); /* usually 2 */
+ } else if (*spec == 'l' || *spec == 'L') {
+ *sz = 4;
+ alignment = __alignof__(uint32_t); /* usually 4 */
+ } else if (*spec == 'q' || *spec == 'Q') {
+ *sz = 8;
+ alignment = __alignof__(uint64_t); /* usually 8 */
+ } else if (*spec == 'i' || *spec == 'I') {
+ *sz = sizeof(int);
+ alignment = __alignof__(int); /* usually 4 */
+ } else {
+ ZEND_ASSERT(*spec == 'b' || *spec == 'B');
+ *sz = 1;
+ alignment = 1;
+ }
+ /* process alignment */
+ *pos = align_to(*pos, alignment);
+ *max_alignment = *max_alignment < alignment ? alignment : *max_alignment;
+ /* parse count */
+ ++spec;
+ if (isdigit((unsigned char) *spec)) {
+ count = 0;
+ while (isdigit((unsigned char) *spec)) {
+ count = 10 * count + *spec - '0';
+ ++spec;
+ }
+ } else {
+ count = 1;
+ }
+ *specp = spec;
+ return count;
+}
+
+static uint64_t one_from_buffer(size_t sz, const unsigned char *buf) {
+ if (sz == 2) {
+ const uint16_t *x = (const uint16_t *) buf;
+ return *x;
+ } else if (sz == 4) {
+ const uint32_t *x = (const uint32_t *) buf;
+ return *x;
+ } else if (sz == 8) {
+ const uint64_t *x = (const uint64_t *) buf;
+ return *x;
+ } else {
+ ZEND_ASSERT(sz == 1);
+ return *buf;
+ }
+}
+
+static void one_to_buffer(size_t sz, unsigned char *buf, uint64_t val) {
+ if (sz == 2) {
+ uint16_t *x = (uint16_t *) buf;
+ *x = val;
+ } else if (sz == 4) {
+ uint32_t *x = (uint32_t *) buf;
+ *x = val;
+ } else if (sz == 8) {
+ uint64_t *x = (uint64_t *) buf;
+ *x = val;
+ } else {
+ ZEND_ASSERT(sz == 1);
+ *buf = val;
+ }
+}
+
+/* Serialize a hash context according to a `spec` string.
+ Spec contents:
+ b[COUNT] -- serialize COUNT bytes
+ s[COUNT] -- serialize COUNT 16-bit integers
+ l[COUNT] -- serialize COUNT 32-bit integers
+ q[COUNT] -- serialize COUNT 64-bit integers
+ i[COUNT] -- serialize COUNT `int`s
+ B[COUNT] -- skip COUNT bytes
+ S[COUNT], L[COUNT], etc. -- uppercase versions skip instead of read
+ . (must be last character) -- assert that the hash context has exactly
+ this size
+ Example: "llllllb64l16." is the spec for an MD5 context: 6 32-bit
+ integers, followed by 64 bytes, then 16 32-bit integers, and that's
+ exactly the size of the context.
+
+ The serialization result is an array. Each integer is serialized as a
+ 32-bit integer, except that a run of 2 or more bytes is encoded as a
+ string, and each 64-bit integer is serialized as two 32-bit integers, least
+ significant bits first. This allows 32-bit and 64-bit architectures to
+ interchange serialized HashContexts. */
+
+PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *hash, zval *zv, const char *spec) /* {{{ */
+{
+ size_t pos = 0, max_alignment = 1;
+ unsigned char *buf = (unsigned char *) hash->context;
+ zval tmp;
+ array_init(zv);
+ while (*spec != '\0' && *spec != '.') {
+ char spec_ch = *spec;
+ size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment);
+ if (pos + count * sz > hash->ops->context_size) {
+ return FAILURE;
+ }
+ if (isupper((unsigned char) spec_ch)) {
+ pos += count * sz;
+ } else if (sz == 1 && count > 1) {
+ ZVAL_STRINGL(&tmp, (char *) buf + pos, count);
+ zend_hash_next_index_insert(Z_ARRVAL_P(zv), &tmp);
+ pos += count;
+ } else {
+ while (count > 0) {
+ uint64_t val = one_from_buffer(sz, buf + pos);
+ pos += sz;
+ ZVAL_LONG(&tmp, (int32_t) val);
+ zend_hash_next_index_insert(Z_ARRVAL_P(zv), &tmp);
+ if (sz == 8) {
+ ZVAL_LONG(&tmp, (int32_t) (val >> 32));
+ zend_hash_next_index_insert(Z_ARRVAL_P(zv), &tmp);
+ }
+ --count;
+ }
+ }
+ }
+ if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) {
+ return FAILURE;
+ }
+ return SUCCESS;
+}
+/* }}} */
+
+/* Unserialize a hash context serialized by `php_hash_serialize_spec` with `spec`.
+ Returns SUCCESS on success and a negative error code on failure.
+ Codes: FAILURE (-1) == generic failure
+ -999 == spec wrong size for context
+ -1000 - POS == problem at byte offset POS */
+
+PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec) /* {{{ */
+{
+ size_t pos = 0, max_alignment = 1, j = 0;
+ unsigned char *buf = (unsigned char *) hash->context;
+ zval *elt;
+ if (Z_TYPE_P(zv) != IS_ARRAY) {
+ return FAILURE;
+ }
+ while (*spec != '\0' && *spec != '.') {
+ char spec_ch = *spec;
+ size_t sz, count = parse_serialize_spec(&spec, &pos, &sz, &max_alignment);
+ if (pos + count * sz > hash->ops->context_size) {
+ return -999;
+ }
+ if (isupper((unsigned char) spec_ch)) {
+ pos += count * sz;
+ } else if (sz == 1 && count > 1) {
+ elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
+ if (!elt || Z_TYPE_P(elt) != IS_STRING || Z_STRLEN_P(elt) != count) {
+ return -1000 - pos;
+ }
+ ++j;
+ memcpy(buf + pos, Z_STRVAL_P(elt), count);
+ pos += count;
+ } else {
+ while (count > 0) {
+ uint64_t val;
+ elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
+ if (!elt || Z_TYPE_P(elt) != IS_LONG) {
+ return -1000 - pos;
+ }
+ ++j;
+ val = (uint32_t) Z_LVAL_P(elt);
+ if (sz == 8) {
+ elt = zend_hash_index_find(Z_ARRVAL_P(zv), j);
+ if (!elt || Z_TYPE_P(elt) != IS_LONG) {
+ return -1000 - pos;
+ }
+ ++j;
+ val += ((uint64_t) Z_LVAL_P(elt)) << 32;
+ }
+ one_to_buffer(sz, buf + pos, val);
+ pos += sz;
+ --count;
+ }
+ }
+ }
+ if (*spec == '.' && align_to(pos, max_alignment) != hash->ops->context_size) {
+ return -999;
+ }
+ return SUCCESS;
+}
+/* }}} */
+
+PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv) /* {{{ */
+{
+ if (hash->ops->serialize_spec) {
+ *magic = PHP_HASH_SERIALIZE_MAGIC_SPEC;
+ return php_hash_serialize_spec(hash, zv, hash->ops->serialize_spec);
+ } else {
+ return FAILURE;
+ }
+}
+/* }}} */
+
+PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv) /* {{{ */
+{
+ if (hash->ops->serialize_spec
+ && magic == PHP_HASH_SERIALIZE_MAGIC_SPEC) {
+ return php_hash_unserialize_spec(hash, zv, hash->ops->serialize_spec);
+ } else {
+ return FAILURE;
+ }
+}
+/* }}} */
+
/* Userspace */
static void php_hash_do_hash(INTERNAL_FUNCTION_PARAMETERS, int isfilename, zend_bool raw_output_default) /* {{{ */
}
}
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
ops->hash_init(context);
if (isfilename) {
}
}
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
K = emalloc(ops->block_size);
digest = zend_string_alloc(ops->digest_size, 0);
object_init_ex(return_value, php_hashcontext_ce);
hash = php_hashcontext_from_object(Z_OBJ_P(return_value));
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
ops->hash_init(context);
hash->ops = ops;
RETURN_THROWS();
}
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
// Extract
ops->hash_init(context);
RETURN_THROWS();
}
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
ops->hash_init(context);
K1 = emalloc(ops->block_size);
times++;
}
- context = emalloc(ops->context_size);
+ context = php_hash_alloc_context(ops);
ops->hash_init(context);
key = ecalloc(1, times * block_size);
newobj->ops = oldobj->ops;
newobj->options = oldobj->options;
- newobj->context = emalloc(newobj->ops->context_size);
+ newobj->context = php_hash_alloc_context(newobj->ops);
newobj->ops->hash_init(newobj->context);
if (SUCCESS != newobj->ops->hash_copy(newobj->ops, oldobj->context, newobj->context)) {
}
/* }}} */
+/* Serialization format: 5-element array
+ Index 0: hash algorithm (string)
+ Index 1: options (long, 0)
+ Index 2: hash-determined serialization of context state (usually array)
+ Index 3: magic number defining layout of context state (long, usually 2)
+ Index 4: properties (array)
+
+ HashContext serializations are not necessarily portable between architectures or
+ PHP versions. If the format of a serialized hash context changes, that should
+ be reflected in either a different value of `magic` or a different format of
+ the serialized context state. Most context states are unparsed and parsed using
+ a spec string, such as "llb128.", using the format defined by
+ `php_hash_serialize_spec`/`php_hash_unserialize_spec`. Some hash algorithms must
+ also check the unserialized state for validity, to ensure that using an
+ unserialized context is safe from memory errors.
+
+ Currently HASH_HMAC contexts cannot be serialized, because serializing them
+ would require serializing the HMAC key in plaintext. */
+
+/* {{{ proto array HashContext::__serialize()
+ Serialize the object */
+PHP_METHOD(HashContext, __serialize)
+{
+ zval *object = ZEND_THIS;
+ php_hashcontext_object *hash = php_hashcontext_from_object(Z_OBJ_P(object));
+ zend_long magic = 0;
+ zval tmp;
+
+ if (zend_parse_parameters_none() == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ array_init(return_value);
+
+ if (!hash->ops->hash_serialize) {
+ goto serialize_failure;
+ } else if (hash->options & PHP_HASH_HMAC) {
+ zend_throw_exception(NULL, "HashContext with HASH_HMAC option cannot be serialized", 0);
+ RETURN_THROWS();
+ }
+
+ ZVAL_STRING(&tmp, hash->ops->algo);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+
+ ZVAL_LONG(&tmp, hash->options);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+
+ if (hash->ops->hash_serialize(hash, &magic, &tmp) != SUCCESS) {
+ goto serialize_failure;
+ }
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+
+ ZVAL_LONG(&tmp, magic);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+
+ /* members */
+ ZVAL_ARR(&tmp, zend_std_get_properties(&hash->std));
+ Z_TRY_ADDREF(tmp);
+ zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &tmp);
+
+ return;
+
+serialize_failure:
+ zend_throw_exception_ex(NULL, 0, "HashContext for algorithm \"%s\" cannot be serialized", hash->ops->algo);
+ RETURN_THROWS();
+}
+/* }}} */
+
+/* {{{ proto void HashContext::__unserialize(array serialized)
+ * unserialize the object
+ */
+PHP_METHOD(HashContext, __unserialize)
+{
+ zval *object = ZEND_THIS;
+ php_hashcontext_object *hash = php_hashcontext_from_object(Z_OBJ_P(object));
+ HashTable *data;
+ zval *algo_zv, *magic_zv, *options_zv, *hash_zv, *members_zv;
+ zend_long magic, options;
+ int unserialize_result;
+ const php_hash_ops *ops;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "h", &data) == FAILURE) {
+ RETURN_THROWS();
+ }
+
+ if (hash->context) {
+ zend_throw_exception(NULL, "HashContext::__unserialize called on initialized object", 0);
+ RETURN_THROWS();
+ }
+
+ algo_zv = zend_hash_index_find(data, 0);
+ options_zv = zend_hash_index_find(data, 1);
+ hash_zv = zend_hash_index_find(data, 2);
+ magic_zv = zend_hash_index_find(data, 3);
+ members_zv = zend_hash_index_find(data, 4);
+
+ if (!algo_zv || Z_TYPE_P(algo_zv) != IS_STRING
+ || !magic_zv || Z_TYPE_P(magic_zv) != IS_LONG
+ || !options_zv || Z_TYPE_P(options_zv) != IS_LONG
+ || !hash_zv
+ || !members_zv || Z_TYPE_P(members_zv) != IS_ARRAY) {
+ zend_throw_exception(NULL, "Incomplete or ill-formed serialization data", 0);
+ RETURN_THROWS();
+ }
+
+ magic = Z_LVAL_P(magic_zv);
+ options = Z_LVAL_P(options_zv);
+ if (options & PHP_HASH_HMAC) {
+ zend_throw_exception(NULL, "HashContext with HASH_HMAC option cannot be serialized", 0);
+ RETURN_THROWS();
+ }
+
+ ops = php_hash_fetch_ops(Z_STR_P(algo_zv));
+ if (!ops) {
+ zend_throw_exception(NULL, "Unknown hash algorithm", 0);
+ RETURN_THROWS();
+ } else if (!ops->hash_unserialize) {
+ zend_throw_exception_ex(NULL, 0, "Hash algorithm \"%s\" cannot be unserialized", ops->algo);
+ RETURN_THROWS();
+ }
+
+ hash->ops = ops;
+ hash->context = php_hash_alloc_context(ops);
+ ops->hash_init(hash->context);
+ hash->options = options;
+
+ unserialize_result = ops->hash_unserialize(hash, magic, hash_zv);
+ if (unserialize_result != SUCCESS) {
+ zend_throw_exception_ex(NULL, 0, "Incomplete or ill-formed serialization data (\"%s\" code %d)", ops->algo, unserialize_result);
+ /* free context */
+ php_hashcontext_dtor(Z_OBJ_P(object));
+ RETURN_THROWS();
+ }
+
+ object_properties_load(&hash->std, Z_ARRVAL_P(members_zv));
+}
+/* }}} */
+
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(hash)
php_hashcontext_ce = zend_register_internal_class(&ce);
php_hashcontext_ce->ce_flags |= ZEND_ACC_FINAL;
php_hashcontext_ce->create_object = php_hashcontext_create;
- php_hashcontext_ce->serialize = zend_class_serialize_deny;
- php_hashcontext_ce->unserialize = zend_class_unserialize_deny;
memcpy(&php_hashcontext_handlers, &std_object_handlers,
sizeof(zend_object_handlers));
final class HashContext
{
private function __construct() {}
+
+ public function __serialize(): array {}
+
+ public function __unserialize(array $serialized): void {}
}
}
const php_hash_ops php_hash_adler32_ops = {
+ "adler32",
(php_hash_init_func_t) PHP_ADLER32Init,
(php_hash_update_func_t) PHP_ADLER32Update,
(php_hash_final_func_t) PHP_ADLER32Final,
(php_hash_copy_func_t) PHP_ADLER32Copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_ADLER32_SPEC,
4, /* what to say here? */
4,
sizeof(PHP_ADLER32_CTX),
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_HashContext___construct, 0, 0, 0)
ZEND_END_ARG_INFO()
+#define arginfo_class_HashContext___serialize arginfo_hash_algos
+
+ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_HashContext___unserialize, 0, 1, IS_VOID, 0)
+ ZEND_ARG_TYPE_INFO(0, serialized, IS_ARRAY, 0)
+ZEND_END_ARG_INFO()
+
ZEND_FUNCTION(hash);
ZEND_FUNCTION(hash_file);
ZEND_FUNCTION(mhash);
#endif
ZEND_METHOD(HashContext, __construct);
+ZEND_METHOD(HashContext, __serialize);
+ZEND_METHOD(HashContext, __unserialize);
static const zend_function_entry ext_functions[] = {
static const zend_function_entry class_HashContext_methods[] = {
ZEND_ME(HashContext, __construct, arginfo_class_HashContext___construct, ZEND_ACC_PRIVATE)
+ ZEND_ME(HashContext, __serialize, arginfo_class_HashContext___serialize, ZEND_ACC_PUBLIC)
+ ZEND_ME(HashContext, __unserialize, arginfo_class_HashContext___unserialize, ZEND_ACC_PUBLIC)
ZEND_FE_END
};
}
const php_hash_ops php_hash_crc32_ops = {
+ "crc32",
(php_hash_init_func_t) PHP_CRC32Init,
(php_hash_update_func_t) PHP_CRC32Update,
(php_hash_final_func_t) PHP_CRC32LEFinal,
(php_hash_copy_func_t) PHP_CRC32Copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_CRC32_SPEC,
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
};
const php_hash_ops php_hash_crc32b_ops = {
+ "crc32b",
(php_hash_init_func_t) PHP_CRC32Init,
(php_hash_update_func_t) PHP_CRC32BUpdate,
(php_hash_final_func_t) PHP_CRC32BEFinal,
(php_hash_copy_func_t) PHP_CRC32Copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_CRC32_SPEC,
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
};
const php_hash_ops php_hash_crc32c_ops = {
+ "crc32c",
(php_hash_init_func_t) PHP_CRC32Init,
(php_hash_update_func_t) PHP_CRC32CUpdate,
(php_hash_final_func_t) PHP_CRC32BEFinal,
(php_hash_copy_func_t) PHP_CRC32Copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_CRC32_SPEC,
4, /* what to say here? */
4,
sizeof(PHP_CRC32_CTX),
#include "php_hash_fnv.h"
const php_hash_ops php_hash_fnv132_ops = {
+ "fnv132",
(php_hash_init_func_t) PHP_FNV132Init,
(php_hash_update_func_t) PHP_FNV132Update,
(php_hash_final_func_t) PHP_FNV132Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_FNV132_SPEC,
4,
4,
sizeof(PHP_FNV132_CTX),
};
const php_hash_ops php_hash_fnv1a32_ops = {
+ "fnv1a32",
(php_hash_init_func_t) PHP_FNV132Init,
(php_hash_update_func_t) PHP_FNV1a32Update,
- (php_hash_final_func_t) PHP_FNV132Final,
- (php_hash_copy_func_t) php_hash_copy,
+ (php_hash_final_func_t) PHP_FNV132Final,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_FNV132_SPEC,
4,
4,
sizeof(PHP_FNV132_CTX),
};
const php_hash_ops php_hash_fnv164_ops = {
+ "fnv164",
(php_hash_init_func_t) PHP_FNV164Init,
(php_hash_update_func_t) PHP_FNV164Update,
(php_hash_final_func_t) PHP_FNV164Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_FNV164_SPEC,
8,
4,
sizeof(PHP_FNV164_CTX),
};
const php_hash_ops php_hash_fnv1a64_ops = {
+ "fnv1a64",
(php_hash_init_func_t) PHP_FNV164Init,
(php_hash_update_func_t) PHP_FNV1a64Update,
- (php_hash_final_func_t) PHP_FNV164Final,
- (php_hash_copy_func_t) php_hash_copy,
+ (php_hash_final_func_t) PHP_FNV164Final,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_FNV164_SPEC,
8,
4,
sizeof(PHP_FNV164_CTX),
ZEND_SECURE_ZERO(context, sizeof(*context));
}
+static int php_gost_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ PHP_GOST_CTX *ctx = (PHP_GOST_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_GOST_SPEC)) == SUCCESS
+ && ctx->length < sizeof(ctx->buffer)) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
+
const php_hash_ops php_hash_gost_ops = {
+ "gost",
(php_hash_init_func_t) PHP_GOSTInit,
(php_hash_update_func_t) PHP_GOSTUpdate,
(php_hash_final_func_t) PHP_GOSTFinal,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_gost_unserialize,
+ PHP_GOST_SPEC,
32,
32,
sizeof(PHP_GOST_CTX),
};
const php_hash_ops php_hash_gost_crypto_ops = {
+ "gost-crypto",
(php_hash_init_func_t) PHP_GOSTInitCrypto,
(php_hash_update_func_t) PHP_GOSTUpdate,
(php_hash_final_func_t) PHP_GOSTFinal,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_gost_unserialize,
+ PHP_GOST_SPEC,
32,
32,
sizeof(PHP_GOST_CTX),
#define PHP_HASH_HAVAL_INIT(p,b) \
const php_hash_ops php_hash_##p##haval##b##_ops = { \
+ "haval" #b "," #p, \
(php_hash_init_func_t) PHP_##p##HAVAL##b##Init, \
(php_hash_update_func_t) PHP_HAVALUpdate, \
(php_hash_final_func_t) PHP_HAVAL##b##Final, \
- (php_hash_copy_func_t) php_hash_copy, \
+ php_hash_copy, \
+ php_hash_serialize, \
+ php_hash_unserialize, \
+ PHP_HAVAL_SPEC, \
((b) / 8), 128, sizeof(PHP_HAVAL_CTX), 1 }; \
PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *context) \
{ int i; context->count[0] = context->count[1] = 0; \
#include "php_hash_joaat.h"
const php_hash_ops php_hash_joaat_ops = {
+ "joaat",
(php_hash_init_func_t) PHP_JOAATInit,
(php_hash_update_func_t) PHP_JOAATUpdate,
(php_hash_final_func_t) PHP_JOAATFinal,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_JOAAT_SPEC,
4,
4,
sizeof(PHP_JOAAT_CTX),
#include "php_hash_md.h"
const php_hash_ops php_hash_md5_ops = {
+ "md5",
(php_hash_init_func_t) PHP_MD5Init,
(php_hash_update_func_t) PHP_MD5Update,
(php_hash_final_func_t) PHP_MD5Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_MD5_SPEC,
16,
64,
sizeof(PHP_MD5_CTX),
};
const php_hash_ops php_hash_md4_ops = {
+ "md4",
(php_hash_init_func_t) PHP_MD4Init,
(php_hash_update_func_t) PHP_MD4Update,
(php_hash_final_func_t) PHP_MD4Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_MD4_SPEC,
16,
64,
sizeof(PHP_MD4_CTX),
1
};
+static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv);
+
const php_hash_ops php_hash_md2_ops = {
+ "md2",
(php_hash_init_func_t) PHP_MD2Init,
(php_hash_update_func_t) PHP_MD2Update,
(php_hash_final_func_t) PHP_MD2Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_md2_unserialize,
+ PHP_MD2_SPEC,
16,
16,
sizeof(PHP_MD2_CTX),
memcpy(output, context->state, 16);
}
+
+static int php_md2_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ PHP_MD2_CTX *ctx = (PHP_MD2_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_MD2_SPEC)) == SUCCESS
+ && (unsigned char) ctx->in_buffer < sizeof(ctx->buffer)) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
#include "php_hash_ripemd.h"
const php_hash_ops php_hash_ripemd128_ops = {
+ "ripemd128",
(php_hash_init_func_t) PHP_RIPEMD128Init,
(php_hash_update_func_t) PHP_RIPEMD128Update,
(php_hash_final_func_t) PHP_RIPEMD128Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_RIPEMD128_SPEC,
16,
64,
sizeof(PHP_RIPEMD128_CTX),
};
const php_hash_ops php_hash_ripemd160_ops = {
+ "ripemd160",
(php_hash_init_func_t) PHP_RIPEMD160Init,
(php_hash_update_func_t) PHP_RIPEMD160Update,
(php_hash_final_func_t) PHP_RIPEMD160Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_RIPEMD160_SPEC,
20,
64,
sizeof(PHP_RIPEMD160_CTX),
};
const php_hash_ops php_hash_ripemd256_ops = {
+ "ripemd256",
(php_hash_init_func_t) PHP_RIPEMD256Init,
(php_hash_update_func_t) PHP_RIPEMD256Update,
(php_hash_final_func_t) PHP_RIPEMD256Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_RIPEMD256_SPEC,
32,
64,
sizeof(PHP_RIPEMD256_CTX),
};
const php_hash_ops php_hash_ripemd320_ops = {
+ "ripemd320",
(php_hash_init_func_t) PHP_RIPEMD320Init,
(php_hash_update_func_t) PHP_RIPEMD320Update,
(php_hash_final_func_t) PHP_RIPEMD320Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_RIPEMD320_SPEC,
40,
64,
sizeof(PHP_RIPEMD320_CTX),
/* }}} */
const php_hash_ops php_hash_sha1_ops = {
+ "sha1",
(php_hash_init_func_t) PHP_SHA1Init,
(php_hash_update_func_t) PHP_SHA1Update,
(php_hash_final_func_t) PHP_SHA1Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA1_SPEC,
20,
64,
sizeof(PHP_SHA1_CTX),
/* sha224/sha256 */
const php_hash_ops php_hash_sha256_ops = {
+ "sha256",
(php_hash_init_func_t) PHP_SHA256Init,
(php_hash_update_func_t) PHP_SHA256Update,
(php_hash_final_func_t) PHP_SHA256Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA256_SPEC,
32,
64,
sizeof(PHP_SHA256_CTX),
};
const php_hash_ops php_hash_sha224_ops = {
+ "sha224",
(php_hash_init_func_t) PHP_SHA224Init,
(php_hash_update_func_t) PHP_SHA224Update,
(php_hash_final_func_t) PHP_SHA224Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA224_SPEC,
28,
64,
sizeof(PHP_SHA224_CTX),
/* }}} */
const php_hash_ops php_hash_sha384_ops = {
+ "sha384",
(php_hash_init_func_t) PHP_SHA384Init,
(php_hash_update_func_t) PHP_SHA384Update,
(php_hash_final_func_t) PHP_SHA384Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA384_SPEC,
48,
128,
sizeof(PHP_SHA384_CTX),
/* }}} */
const php_hash_ops php_hash_sha512_ops = {
+ "sha512",
(php_hash_init_func_t) PHP_SHA512Init,
(php_hash_update_func_t) PHP_SHA512Update,
(php_hash_final_func_t) PHP_SHA512Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA512_SPEC,
64,
128,
sizeof(PHP_SHA512_CTX),
};
const php_hash_ops php_hash_sha512_256_ops = {
+ "sha512/256",
(php_hash_init_func_t) PHP_SHA512_256Init,
(php_hash_update_func_t) PHP_SHA512_256Update,
(php_hash_final_func_t) PHP_SHA512_256Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA512_SPEC,
32,
128,
sizeof(PHP_SHA512_CTX),
};
const php_hash_ops php_hash_sha512_224_ops = {
+ "sha512/224",
(php_hash_init_func_t) PHP_SHA512_224Init,
(php_hash_update_func_t) PHP_SHA512_224Update,
(php_hash_final_func_t) PHP_SHA512_224Final,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_hash_unserialize,
+ PHP_SHA512_SPEC,
28,
128,
sizeof(PHP_SHA512_CTX),
ZEND_SECURE_ZERO(ctx, sizeof(PHP_SHA3_CTX));
}
+static int php_sha3_unserialize(php_hashcontext_object *hash,
+ zend_long magic,
+ const zval *zv,
+ size_t block_size)
+{
+ PHP_SHA3_CTX *ctx = (PHP_SHA3_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_SHA3_SPEC)) == SUCCESS
+ && ctx->pos < block_size) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
+
// ==========================================================================
#define DECLARE_SHA3_OPS(bits) \
(1600 - (2 * bits)) >> 3, \
bits >> 3); \
} \
+static int php_sha3##bits##_unserialize(php_hashcontext_object *hash, \
+ zend_long magic, \
+ const zval *zv) { \
+ return php_sha3_unserialize(hash, magic, zv, (1600 - (2 * bits)) >> 3); \
+} \
const php_hash_ops php_hash_sha3_##bits##_ops = { \
+ "sha3-" #bits, \
(php_hash_init_func_t) PHP_SHA3##bits##Init, \
(php_hash_update_func_t) PHP_SHA3##bits##Update, \
(php_hash_final_func_t) PHP_SHA3##bits##Final, \
php_hash_copy, \
+ php_hash_serialize, \
+ php_sha3##bits##_unserialize, \
+ PHP_SHA3_SPEC, \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_##bits##_CTX), \
#define SUCCESS SHA3_SUCCESS /* Avoid conflict between KeccacHash.h and zend_types.h */
#include "KeccakHash.h"
+/* KECCAK SERIALIZATION
+
+ Keccak_HashInstance consists of:
+ KeccakWidth1600_SpongeInstance {
+ unsigned char state[200];
+ unsigned int rate; -- fixed for digest size
+ unsigned int byteIOIndex; -- in range [0, rate/8)
+ int squeezing; -- 0 normally, 1 only during finalize
+ } sponge;
+ unsigned int fixedOutputLength; -- fixed for digest size
+ unsigned char delimitedSuffix; -- fixed for digest size
+
+ NB If the external sha3/ library is updated, the serialization code
+ may need to be updated.
+
+ The simpler SHA3 code's serialization states are not interchangeable with
+ Keccak. Furthermore, the Keccak sponge state is sensitive to architecture
+ -- 32-bit and 64-bit implementations produce different states. It does not
+ appear that the state is sensitive to endianness. */
+
+#if Keccak_HashInstance_ImplType == 64
+/* corresponds to sha3/generic64lc */
+# define PHP_HASH_SERIALIZE_MAGIC_KECCAK 100
+#elif Keccak_HashInstance_ImplType == 32
+/* corresponds to sha3/generic32lc */
+# define PHP_HASH_SERIALIZE_MAGIC_KECCAK 101
+#else
+# error "Unknown Keccak_HashInstance_ImplType"
+#endif
+#define PHP_KECCAK_SPEC "b200IiIIB"
+
+static int php_keccak_serialize(const php_hashcontext_object *hash, zend_long *magic, zval *zv)
+{
+ *magic = PHP_HASH_SERIALIZE_MAGIC_KECCAK;
+ return php_hash_serialize_spec(hash, zv, PHP_KECCAK_SPEC);
+}
+
+static int php_keccak_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ Keccak_HashInstance *ctx = (Keccak_HashInstance *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_KECCAK
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_KECCAK_SPEC)) == SUCCESS
+ && ctx->sponge.byteIOIndex < ctx->sponge.rate / 8) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
// ==========================================================================
Keccak_HashFinal((Keccak_HashInstance *)ctx, digest); \
} \
const php_hash_ops php_hash_sha3_##bits##_ops = { \
+ "sha3-" #bits, \
(php_hash_init_func_t) PHP_SHA3##bits##Init, \
(php_hash_update_func_t) PHP_SHA3##bits##Update, \
(php_hash_final_func_t) PHP_SHA3##bits##Final, \
php_hash_copy, \
+ php_keccak_serialize, \
+ php_keccak_unserialize, \
+ PHP_KECCAK_SPEC, \
bits >> 3, \
(1600 - (2 * bits)) >> 3, \
sizeof(PHP_SHA3_CTX), \
ZEND_SECURE_ZERO(context, sizeof(*context));
}
+static int php_snefru_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ PHP_SNEFRU_CTX *ctx = (PHP_SNEFRU_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_SNEFRU_SPEC)) == SUCCESS
+ && ctx->length < sizeof(ctx->buffer)) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
+
const php_hash_ops php_hash_snefru_ops = {
+ "snefru",
(php_hash_init_func_t) PHP_SNEFRUInit,
(php_hash_update_func_t) PHP_SNEFRUUpdate,
(php_hash_final_func_t) PHP_SNEFRUFinal,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_snefru_unserialize,
+ PHP_SNEFRU_SPEC,
32,
32,
sizeof(PHP_SNEFRU_CTX),
ZEND_SECURE_ZERO(context, sizeof(*context));
}
+static int php_tiger_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ PHP_TIGER_CTX *ctx = (PHP_TIGER_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_TIGER_SPEC)) == SUCCESS
+ && ctx->length < sizeof(ctx->buffer)) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
+
#define PHP_HASH_TIGER_OPS(p, b) \
const php_hash_ops php_hash_##p##tiger##b##_ops = { \
+ "tiger" #b "," #p, \
(php_hash_init_func_t) PHP_##p##TIGERInit, \
(php_hash_update_func_t) PHP_TIGERUpdate, \
(php_hash_final_func_t) PHP_TIGER##b##Final, \
- (php_hash_copy_func_t) php_hash_copy, \
+ php_hash_copy, \
+ php_hash_serialize, \
+ php_tiger_unserialize, \
+ PHP_TIGER_SPEC, \
b/8, \
64, \
sizeof(PHP_TIGER_CTX), \
ZEND_SECURE_ZERO(context, sizeof(*context));
}
+static int php_whirlpool_unserialize(php_hashcontext_object *hash, zend_long magic, const zval *zv)
+{
+ PHP_WHIRLPOOL_CTX *ctx = (PHP_WHIRLPOOL_CTX *) hash->context;
+ int r = FAILURE;
+ if (magic == PHP_HASH_SERIALIZE_MAGIC_SPEC
+ && (r = php_hash_unserialize_spec(hash, zv, PHP_WHIRLPOOL_SPEC)) == SUCCESS
+ && ctx->buffer.pos >= 0
+ && ctx->buffer.pos < (int) sizeof(ctx->buffer.data)
+ && ctx->buffer.bits >= ctx->buffer.pos * 8
+ && ctx->buffer.bits < ctx->buffer.pos * 8 + 8) {
+ return SUCCESS;
+ } else {
+ return r != SUCCESS ? r : -2000;
+ }
+}
+
const php_hash_ops php_hash_whirlpool_ops = {
+ "whirlpool",
(php_hash_init_func_t) PHP_WHIRLPOOLInit,
(php_hash_update_func_t) PHP_WHIRLPOOLUpdate,
(php_hash_final_func_t) PHP_WHIRLPOOLFinal,
- (php_hash_copy_func_t) php_hash_copy,
+ php_hash_copy,
+ php_hash_serialize,
+ php_whirlpool_unserialize,
+ PHP_WHIRLPOOL_SPEC,
64,
64,
sizeof(PHP_WHIRLPOOL_CTX),
#define PHP_HASH_HMAC 0x0001
+#define PHP_HASH_SERIALIZE_MAGIC_SPEC 2
+
#define L64 INT64_C
+typedef struct _php_hashcontext_object php_hashcontext_object;
+
typedef void (*php_hash_init_func_t)(void *context);
typedef void (*php_hash_update_func_t)(void *context, const unsigned char *buf, size_t count);
typedef void (*php_hash_final_func_t)(unsigned char *digest, void *context);
typedef int (*php_hash_copy_func_t)(const void *ops, void *orig_context, void *dest_context);
+typedef int (*php_hash_serialize_func_t)(const php_hashcontext_object *hash, zend_long *magic, zval *zv);
+typedef int (*php_hash_unserialize_func_t)(php_hashcontext_object *hash, zend_long magic, const zval *zv);
typedef struct _php_hash_ops {
+ const char *algo;
php_hash_init_func_t hash_init;
php_hash_update_func_t hash_update;
php_hash_final_func_t hash_final;
php_hash_copy_func_t hash_copy;
+ php_hash_serialize_func_t hash_serialize;
+ php_hash_unserialize_func_t hash_unserialize;
+ const char *serialize_spec;
size_t digest_size;
size_t block_size;
unsigned is_crypto: 1;
} php_hash_ops;
-typedef struct _php_hashcontext_object {
+struct _php_hashcontext_object {
const php_hash_ops *ops;
void *context;
unsigned char *key;
zend_object std;
-} php_hashcontext_object;
+};
static inline php_hashcontext_object *php_hashcontext_from_object(zend_object *obj) {
return ((php_hashcontext_object*)(obj + 1)) - 1;
PHP_HASH_API const php_hash_ops *php_hash_fetch_ops(zend_string *algo);
PHP_HASH_API void php_hash_register_algo(const char *algo, const php_hash_ops *ops);
PHP_HASH_API int php_hash_copy(const void *ops, void *orig_context, void *dest_context);
+PHP_HASH_API int php_hash_serialize(const php_hashcontext_object *context, zend_long *magic, zval *zv);
+PHP_HASH_API int php_hash_unserialize(php_hashcontext_object *context, zend_long magic, const zval *zv);
+PHP_HASH_API int php_hash_serialize_spec(const php_hashcontext_object *context, zval *zv, const char *spec);
+PHP_HASH_API int php_hash_unserialize_spec(php_hashcontext_object *hash, const zval *zv, const char *spec);
+
+static inline void *php_hash_alloc_context(const php_hash_ops *ops) {
+ /* Zero out context memory so serialization doesn't expose internals */
+ return ecalloc(1, ops->context_size);
+}
static inline void php_hash_bin2hex(char *out, const unsigned char *in, size_t in_len)
{
typedef struct {
uint32_t state;
} PHP_ADLER32_CTX;
+#define PHP_ADLER32_SPEC "l."
PHP_HASH_API void PHP_ADLER32Init(PHP_ADLER32_CTX *context);
PHP_HASH_API void PHP_ADLER32Update(PHP_ADLER32_CTX *context, const unsigned char *input, size_t len);
typedef struct {
uint32_t state;
} PHP_CRC32_CTX;
+#define PHP_CRC32_SPEC "l."
PHP_HASH_API void PHP_CRC32Init(PHP_CRC32_CTX *context);
PHP_HASH_API void PHP_CRC32Update(PHP_CRC32_CTX *context, const unsigned char *input, size_t len);
typedef struct {
uint32_t state;
} PHP_FNV132_CTX;
+#define PHP_FNV132_SPEC "l."
typedef struct {
uint64_t state;
} PHP_FNV164_CTX;
+#define PHP_FNV164_SPEC "q."
PHP_HASH_API void PHP_FNV132Init(PHP_FNV132_CTX *context);
unsigned char buffer[32];
const uint32_t (*tables)[4][256];
} PHP_GOST_CTX;
+#define PHP_GOST_SPEC "l16l2bb32"
PHP_HASH_API void PHP_GOSTInit(PHP_GOST_CTX *);
PHP_HASH_API void PHP_GOSTUpdate(PHP_GOST_CTX *, const unsigned char *, size_t);
short output;
void (*Transform)(uint32_t state[8], const unsigned char block[128]);
} PHP_HAVAL_CTX;
+#define PHP_HAVAL_SPEC "l8l2b128"
#define PHP_HASH_HAVAL_INIT_DECL(p,b) PHP_HASH_API void PHP_##p##HAVAL##b##Init(PHP_HAVAL_CTX *); \
PHP_HASH_API void PHP_HAVAL##b##Final(unsigned char*, PHP_HAVAL_CTX *);
typedef struct {
uint32_t state;
} PHP_JOAAT_CTX;
+#define PHP_JOAAT_SPEC "l."
PHP_HASH_API void PHP_JOAATInit(PHP_JOAAT_CTX *context);
PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *input, size_t inputLen);
uint32_t count[2];
unsigned char buffer[64];
} PHP_MD4_CTX;
+#define PHP_MD4_SPEC "l4l2b64."
PHP_HASH_API void PHP_MD4Init(PHP_MD4_CTX *);
PHP_HASH_API void PHP_MD4Update(PHP_MD4_CTX *context, const unsigned char *, size_t);
unsigned char state[48];
unsigned char checksum[16];
unsigned char buffer[16];
- char in_buffer;
+ unsigned char in_buffer;
} PHP_MD2_CTX;
+#define PHP_MD2_SPEC "b48b16b16b."
PHP_HASH_API void PHP_MD2Init(PHP_MD2_CTX *context);
PHP_HASH_API void PHP_MD2Update(PHP_MD2_CTX *context, const unsigned char *, size_t);
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} PHP_RIPEMD128_CTX;
+#define PHP_RIPEMD128_SPEC "l4l2b64."
typedef struct {
uint32_t state[5]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} PHP_RIPEMD160_CTX;
+#define PHP_RIPEMD160_SPEC "l5l2b64."
typedef struct {
uint32_t state[8]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} PHP_RIPEMD256_CTX;
+#define PHP_RIPEMD256_SPEC "l8l2b64."
typedef struct {
uint32_t state[10]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} PHP_RIPEMD320_CTX;
+#define PHP_RIPEMD320_SPEC "l10l2b64."
PHP_HASH_API void PHP_RIPEMD128Init(PHP_RIPEMD128_CTX *);
PHP_HASH_API void PHP_RIPEMD128Update(PHP_RIPEMD128_CTX *, const unsigned char *, size_t);
uint32_t count[2]; /* number of bits, modulo 2^64 */
unsigned char buffer[64]; /* input buffer */
} PHP_SHA224_CTX;
+#define PHP_SHA224_SPEC "l8l2b64."
PHP_HASH_API void PHP_SHA224Init(PHP_SHA224_CTX *);
PHP_HASH_API void PHP_SHA224Update(PHP_SHA224_CTX *, const unsigned char *, size_t);
uint32_t count[2]; /* number of bits, modulo 2^64 */
unsigned char buffer[64]; /* input buffer */
} PHP_SHA256_CTX;
+#define PHP_SHA256_SPEC "l8l2b64."
PHP_HASH_API void PHP_SHA256Init(PHP_SHA256_CTX *);
PHP_HASH_API void PHP_SHA256Update(PHP_SHA256_CTX *, const unsigned char *, size_t);
uint64_t count[2]; /* number of bits, modulo 2^128 */
unsigned char buffer[128]; /* input buffer */
} PHP_SHA384_CTX;
+#define PHP_SHA384_SPEC "q8q2b128."
PHP_HASH_API void PHP_SHA384Init(PHP_SHA384_CTX *);
PHP_HASH_API void PHP_SHA384Update(PHP_SHA384_CTX *, const unsigned char *, size_t);
uint64_t count[2]; /* number of bits, modulo 2^128 */
unsigned char buffer[128]; /* input buffer */
} PHP_SHA512_CTX;
+#define PHP_SHA512_SPEC "q8q2b128."
PHP_HASH_API void PHP_SHA512Init(PHP_SHA512_CTX *);
PHP_HASH_API void PHP_SHA512Update(PHP_SHA512_CTX *, const unsigned char *, size_t);
unsigned char state[224]; // this must fit a Keccak_HashInstance
#endif
} PHP_SHA3_CTX;
+#ifdef HAVE_SLOW_HASH3
+#define PHP_SHA3_SPEC "b200l."
+#endif
typedef PHP_SHA3_CTX PHP_SHA3_224_CTX;
typedef PHP_SHA3_CTX PHP_SHA3_256_CTX;
unsigned char length;
unsigned char buffer[32];
} PHP_SNEFRU_CTX;
+#define PHP_SNEFRU_SPEC "l16l2bb32"
PHP_HASH_API void PHP_SNEFRUInit(PHP_SNEFRU_CTX *);
PHP_HASH_API void PHP_SNEFRUUpdate(PHP_SNEFRU_CTX *, const unsigned char *, size_t);
uint64_t state[3];
uint64_t passed;
unsigned char buffer[64];
+ uint32_t length;
unsigned int passes:1;
- size_t length;
} PHP_TIGER_CTX;
+#define PHP_TIGER_SPEC "q3qb64l"
PHP_HASH_API void PHP_3TIGERInit(PHP_TIGER_CTX *context);
PHP_HASH_API void PHP_4TIGERInit(PHP_TIGER_CTX *context);
unsigned char data[64];
} buffer;
} PHP_WHIRLPOOL_CTX;
+#define PHP_WHIRLPOOL_SPEC "q8b32iib64."
PHP_HASH_API void PHP_WHIRLPOOLInit(PHP_WHIRLPOOL_CTX *);
PHP_HASH_API void PHP_WHIRLPOOLUpdate(PHP_WHIRLPOOL_CTX *, const unsigned char *, size_t);
*/
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen);
+#define Keccak_HashInstance_ImplType 32
+
#endif
#endif
*/
HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, DataLength databitlen);
+#define Keccak_HashInstance_ImplType 64
+
#endif
#endif
--- /dev/null
+--TEST--
+Hash: serialize()/unserialize()
+--FILE--
+<?php
+
+$algos = hash_algos();
+
+foreach ($algos as $algo) {
+ var_dump($algo);
+ $ctx0 = hash_init($algo);
+ $serial = serialize($ctx0);
+ assert(is_string($serial));
+
+ $ctx1 = unserialize($serial);
+ hash_update($ctx1, "I can't remember anything");
+ $serial = serialize($ctx1);
+ assert(is_string($serial));
+ var_dump(hash_final($ctx1));
+
+ $ctx2 = unserialize($serial);
+ var_dump(hash_final($ctx2));
+}
+
+// serialize/unserialize produces same results as all-on-one
+foreach ($algos as $algo) {
+ var_dump($algo);
+ $orig = hash_init($algo);
+ hash_update($orig, "I can't remember anything");
+ $serial = serialize($orig);
+
+ $fresh = hash_init($algo);
+ hash_update($fresh, "I can't remember anythingCan’t tell if this is true or dream");
+ var_dump(hash_final($fresh));
+
+ $copy = unserialize($serial);
+ hash_update($copy, "Can’t tell if this is true or dream");
+ var_dump(hash_final($copy));
+}
+
+echo "Done\n";
+?>
+--EXPECT--
+string(3) "md2"
+string(32) "d5ac4ffd08f6a57b9bd402b8068392ff"
+string(32) "d5ac4ffd08f6a57b9bd402b8068392ff"
+string(3) "md4"
+string(32) "302c45586b53a984bd3a1237cb81c15f"
+string(32) "302c45586b53a984bd3a1237cb81c15f"
+string(3) "md5"
+string(32) "e35759f6ea35db254e415b5332269435"
+string(32) "e35759f6ea35db254e415b5332269435"
+string(4) "sha1"
+string(40) "29f62a228f726cd728efa7a0ac6a2aba318baf15"
+string(40) "29f62a228f726cd728efa7a0ac6a2aba318baf15"
+string(6) "sha224"
+string(56) "51fd0aa76a00b4a86103895cad5c7c2651ec7da9f4fc1e50c43ede29"
+string(56) "51fd0aa76a00b4a86103895cad5c7c2651ec7da9f4fc1e50c43ede29"
+string(6) "sha256"
+string(64) "d3a13cf52af8e9390caed78b77b6b1e06e102204e3555d111dfd149bc5d54dba"
+string(64) "d3a13cf52af8e9390caed78b77b6b1e06e102204e3555d111dfd149bc5d54dba"
+string(6) "sha384"
+string(96) "6950d861ace4102b803ab8b3779d2f471968233010d2608974ab89804cef6f76162b4433d6e554e11e40a7cdcf510ea3"
+string(96) "6950d861ace4102b803ab8b3779d2f471968233010d2608974ab89804cef6f76162b4433d6e554e11e40a7cdcf510ea3"
+string(10) "sha512/224"
+string(56) "a2573d0e3f6c3e2d174c935a35a8ea31032f04e9e83499ac3ceda568"
+string(56) "a2573d0e3f6c3e2d174c935a35a8ea31032f04e9e83499ac3ceda568"
+string(10) "sha512/256"
+string(64) "fddacab80b3a610ba024c9d75a5fe0cafe5ae7c789f829b3c5fbea8ef11ccc1a"
+string(64) "fddacab80b3a610ba024c9d75a5fe0cafe5ae7c789f829b3c5fbea8ef11ccc1a"
+string(6) "sha512"
+string(128) "caced3db8e9e3a5543d5b933bcbe9e7834e6667545c3f5d4087b58ec8d78b4c8a4a5500c9b88f65f7368810ba9905e51f1cff3b25a5dccf76634108fb4e7ce13"
+string(128) "caced3db8e9e3a5543d5b933bcbe9e7834e6667545c3f5d4087b58ec8d78b4c8a4a5500c9b88f65f7368810ba9905e51f1cff3b25a5dccf76634108fb4e7ce13"
+string(8) "sha3-224"
+string(56) "7e1126cffee98e5c4b0e9dd5c6efabd5c9356d668e9a2d3cfab724d4"
+string(56) "7e1126cffee98e5c4b0e9dd5c6efabd5c9356d668e9a2d3cfab724d4"
+string(8) "sha3-256"
+string(64) "834abfed9197af09cbe66b7748c65a050a3755ef7a556d6764eb6eabc93b4c7a"
+string(64) "834abfed9197af09cbe66b7748c65a050a3755ef7a556d6764eb6eabc93b4c7a"
+string(8) "sha3-384"
+string(96) "c9016992586f7a8663c5379ed892349c1140ad258f7c44ee82f61f0b8cb75c675012ea94dc1314e06699be2d1465f67b"
+string(96) "c9016992586f7a8663c5379ed892349c1140ad258f7c44ee82f61f0b8cb75c675012ea94dc1314e06699be2d1465f67b"
+string(8) "sha3-512"
+string(128) "5f85341bc9c6621406bf1841c4ce01727ea8759fdf2927106c3e70a75ad9fffd095b87f995aeee844e1a2c287e1195ce809b9bdb1c31258f7fc098175b6de0b4"
+string(128) "5f85341bc9c6621406bf1841c4ce01727ea8759fdf2927106c3e70a75ad9fffd095b87f995aeee844e1a2c287e1195ce809b9bdb1c31258f7fc098175b6de0b4"
+string(9) "ripemd128"
+string(32) "5f1bc5f5aeaf747574dd34a6535cd94a"
+string(32) "5f1bc5f5aeaf747574dd34a6535cd94a"
+string(9) "ripemd160"
+string(40) "02a2a535ee10404c6b5cf9acb178a04fbed67269"
+string(40) "02a2a535ee10404c6b5cf9acb178a04fbed67269"
+string(9) "ripemd256"
+string(64) "547d2ed85ca0a0e3208b5ecf4fc6a7fc1e64db8ff13493e4beaf11e4d71648e2"
+string(64) "547d2ed85ca0a0e3208b5ecf4fc6a7fc1e64db8ff13493e4beaf11e4d71648e2"
+string(9) "ripemd320"
+string(80) "785a7df56858f550966cddfd59ce14b13bf4b18e7892c4c1ad91bf23bf67639bd2c96749ba29cfa6"
+string(80) "785a7df56858f550966cddfd59ce14b13bf4b18e7892c4c1ad91bf23bf67639bd2c96749ba29cfa6"
+string(9) "whirlpool"
+string(128) "6e60597340640e621e25f975cef2b000b0c4c09a7af7d240a52d193002b0a8426fa7da7acc5b37ed9608016d4f396db834a0ea2f2c35f900461c9ac7e5604082"
+string(128) "6e60597340640e621e25f975cef2b000b0c4c09a7af7d240a52d193002b0a8426fa7da7acc5b37ed9608016d4f396db834a0ea2f2c35f900461c9ac7e5604082"
+string(10) "tiger128,3"
+string(32) "8d68e78bc5e62ba925a67aa48595cfc6"
+string(32) "8d68e78bc5e62ba925a67aa48595cfc6"
+string(10) "tiger160,3"
+string(40) "8d68e78bc5e62ba925a67aa48595cfc62cd1e5e0"
+string(40) "8d68e78bc5e62ba925a67aa48595cfc62cd1e5e0"
+string(10) "tiger192,3"
+string(48) "8d68e78bc5e62ba925a67aa48595cfc62cd1e5e08224fc35"
+string(48) "8d68e78bc5e62ba925a67aa48595cfc62cd1e5e08224fc35"
+string(10) "tiger128,4"
+string(32) "a26ca3f58e74fb32ee44b099cb1b5122"
+string(32) "a26ca3f58e74fb32ee44b099cb1b5122"
+string(10) "tiger160,4"
+string(40) "a26ca3f58e74fb32ee44b099cb1b512203375900"
+string(40) "a26ca3f58e74fb32ee44b099cb1b512203375900"
+string(10) "tiger192,4"
+string(48) "a26ca3f58e74fb32ee44b099cb1b512203375900f30b741d"
+string(48) "a26ca3f58e74fb32ee44b099cb1b512203375900f30b741d"
+string(6) "snefru"
+string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26"
+string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26"
+string(9) "snefru256"
+string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26"
+string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26"
+string(4) "gost"
+string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5"
+string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5"
+string(11) "gost-crypto"
+string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043"
+string(64) "f7c4e35548d66aabe2b106f20515d289fde90969225d3d7b83f6dd12d694f043"
+string(7) "adler32"
+string(8) "6f7c0928"
+string(8) "6f7c0928"
+string(5) "crc32"
+string(8) "e5cfc160"
+string(8) "e5cfc160"
+string(6) "crc32b"
+string(8) "69147a4e"
+string(8) "69147a4e"
+string(6) "crc32c"
+string(8) "5e405e93"
+string(8) "5e405e93"
+string(6) "fnv132"
+string(8) "98139504"
+string(8) "98139504"
+string(7) "fnv1a32"
+string(8) "aae4e042"
+string(8) "aae4e042"
+string(6) "fnv164"
+string(16) "14522659f8138684"
+string(16) "14522659f8138684"
+string(7) "fnv1a64"
+string(16) "bebc746a33b6ab62"
+string(16) "bebc746a33b6ab62"
+string(5) "joaat"
+string(8) "aaebf370"
+string(8) "aaebf370"
+string(10) "haval128,3"
+string(32) "86362472c8895e68e223ef8b3711d8d9"
+string(32) "86362472c8895e68e223ef8b3711d8d9"
+string(10) "haval160,3"
+string(40) "fabdf6905f3ba18a3c93d6a16b91e31f7222a7a4"
+string(40) "fabdf6905f3ba18a3c93d6a16b91e31f7222a7a4"
+string(10) "haval192,3"
+string(48) "e05d0ff5723028bd5494f32c0c2494cd0b9ccf7540af7b47"
+string(48) "e05d0ff5723028bd5494f32c0c2494cd0b9ccf7540af7b47"
+string(10) "haval224,3"
+string(56) "56b196289d8de8a22296588cf90e5b09cb6fa1b01ce8e92bca40cae2"
+string(56) "56b196289d8de8a22296588cf90e5b09cb6fa1b01ce8e92bca40cae2"
+string(10) "haval256,3"
+string(64) "ff4d7ab0fac2ca437b945461f9b62fd16e71e9103524d5d140445a00e3d49239"
+string(64) "ff4d7ab0fac2ca437b945461f9b62fd16e71e9103524d5d140445a00e3d49239"
+string(10) "haval128,4"
+string(32) "ee44418e0195a0c4a35d112722919a9c"
+string(32) "ee44418e0195a0c4a35d112722919a9c"
+string(10) "haval160,4"
+string(40) "f320cce982d5201a1ccacc1c5ff835a258a97eb1"
+string(40) "f320cce982d5201a1ccacc1c5ff835a258a97eb1"
+string(10) "haval192,4"
+string(48) "a96600107463e8e97a7fe6f260d9bf4f4587a281caafa6db"
+string(48) "a96600107463e8e97a7fe6f260d9bf4f4587a281caafa6db"
+string(10) "haval224,4"
+string(56) "7147c9e1c1e67b942da3229f59a1ab18f121f5d7f5765ca88bc9f200"
+string(56) "7147c9e1c1e67b942da3229f59a1ab18f121f5d7f5765ca88bc9f200"
+string(10) "haval256,4"
+string(64) "82fec42679ed5a77a841962827b88a9cddf7d677736e50bc81f1a14b99f06061"
+string(64) "82fec42679ed5a77a841962827b88a9cddf7d677736e50bc81f1a14b99f06061"
+string(10) "haval128,5"
+string(32) "8d0b157828328ae7d34d60b4b60c1dab"
+string(32) "8d0b157828328ae7d34d60b4b60c1dab"
+string(10) "haval160,5"
+string(40) "54dab5e10dc41503f9b8aa32ffe3bab7cf1da8a3"
+string(40) "54dab5e10dc41503f9b8aa32ffe3bab7cf1da8a3"
+string(10) "haval192,5"
+string(48) "7d91265a1b27698279d8d95a5ee0a20014528070bf6415e7"
+string(48) "7d91265a1b27698279d8d95a5ee0a20014528070bf6415e7"
+string(10) "haval224,5"
+string(56) "7772b2e22f2a3bce917e08cf57ebece46bb33168619a776c6f2f7234"
+string(56) "7772b2e22f2a3bce917e08cf57ebece46bb33168619a776c6f2f7234"
+string(10) "haval256,5"
+string(64) "438a602cb1a761f7bd0a633b7bd8b3ccd0577b524d05174ca1ae1f559b9a2c2a"
+string(64) "438a602cb1a761f7bd0a633b7bd8b3ccd0577b524d05174ca1ae1f559b9a2c2a"
+string(3) "md2"
+string(32) "5c36f61062d091a8324991132c5e8dbd"
+string(32) "5c36f61062d091a8324991132c5e8dbd"
+string(3) "md4"
+string(32) "1d4196526aada3506efb4c7425651584"
+string(32) "1d4196526aada3506efb4c7425651584"
+string(3) "md5"
+string(32) "f255c114bd6ce94aad092b5141c00d46"
+string(32) "f255c114bd6ce94aad092b5141c00d46"
+string(4) "sha1"
+string(40) "a273396f056554dcd491b5dea1e7baa3b89b802b"
+string(40) "a273396f056554dcd491b5dea1e7baa3b89b802b"
+string(6) "sha224"
+string(56) "1aee028400c56ceb5539625dc2f395abf491409336ca0f3e177a50e2"
+string(56) "1aee028400c56ceb5539625dc2f395abf491409336ca0f3e177a50e2"
+string(6) "sha256"
+string(64) "268e7f4cf88504a53fd77136c4c4748169f46ff7150b376569ada9c374836944"
+string(64) "268e7f4cf88504a53fd77136c4c4748169f46ff7150b376569ada9c374836944"
+string(6) "sha384"
+string(96) "0d44981d04bb11b1ef75d5c2932bd0aa2785e7bc454daac954d77e2ca10047879b58997533fc99650b20049c6cb9a6cc"
+string(96) "0d44981d04bb11b1ef75d5c2932bd0aa2785e7bc454daac954d77e2ca10047879b58997533fc99650b20049c6cb9a6cc"
+string(10) "sha512/224"
+string(56) "cbc2bbf0028ed803af785b0f264962c84ec48d8ee0908322ef995ddb"
+string(56) "cbc2bbf0028ed803af785b0f264962c84ec48d8ee0908322ef995ddb"
+string(10) "sha512/256"
+string(64) "2cec704878ffa7128e0c4a61eef87d1f3c823184d364dfa3fed73beb00499b00"
+string(64) "2cec704878ffa7128e0c4a61eef87d1f3c823184d364dfa3fed73beb00499b00"
+string(6) "sha512"
+string(128) "28d7c721433782a880f840af0c3f3ea2cad4ef55de2114dda9d504cedeb110e1cf2519c49e4b5da3da4484bb6ba4fd1621ceadc6408f4410b2ebe9d83a4202c2"
+string(128) "28d7c721433782a880f840af0c3f3ea2cad4ef55de2114dda9d504cedeb110e1cf2519c49e4b5da3da4484bb6ba4fd1621ceadc6408f4410b2ebe9d83a4202c2"
+string(8) "sha3-224"
+string(56) "9a21a5464794c2c9784df50cf89cf72234e11941bddaee93f912753e"
+string(56) "9a21a5464794c2c9784df50cf89cf72234e11941bddaee93f912753e"
+string(8) "sha3-256"
+string(64) "57aa7a90f29b5ab66592760592780da247fd39b4c911773687450f9df8cc8ed0"
+string(64) "57aa7a90f29b5ab66592760592780da247fd39b4c911773687450f9df8cc8ed0"
+string(8) "sha3-384"
+string(96) "5d6d7e42b241288bc707b74c50f90a37d69a4afa854ca72021a22cb379356e53b6233aea1be2f33d393d6effa9b5e36c"
+string(96) "5d6d7e42b241288bc707b74c50f90a37d69a4afa854ca72021a22cb379356e53b6233aea1be2f33d393d6effa9b5e36c"
+string(8) "sha3-512"
+string(128) "9b88c689bc13a36e6983b32e8ee9464d63b619f246ca451d1fe2a6c9670f01e71d0c8eb245f3204d27d27c056f2a0fef76a1e3bc30fb74cccbc984dbd4883ae6"
+string(128) "9b88c689bc13a36e6983b32e8ee9464d63b619f246ca451d1fe2a6c9670f01e71d0c8eb245f3204d27d27c056f2a0fef76a1e3bc30fb74cccbc984dbd4883ae6"
+string(9) "ripemd128"
+string(32) "f95f5e22b8875ee0c48219ae97f0674b"
+string(32) "f95f5e22b8875ee0c48219ae97f0674b"
+string(9) "ripemd160"
+string(40) "900d615c1abe714e340f4ecd6a3d65599fd30ff4"
+string(40) "900d615c1abe714e340f4ecd6a3d65599fd30ff4"
+string(9) "ripemd256"
+string(64) "b9799db40d1af5614118c329169cdcd2c718db6af03bf945ea7f7ba72b8e14f4"
+string(64) "b9799db40d1af5614118c329169cdcd2c718db6af03bf945ea7f7ba72b8e14f4"
+string(9) "ripemd320"
+string(80) "d6d12c1fca7a9c4a59c1be4f40188e92a746a035219e0a6ca1ee53b36a8282527187f7dffaa57ecc"
+string(80) "d6d12c1fca7a9c4a59c1be4f40188e92a746a035219e0a6ca1ee53b36a8282527187f7dffaa57ecc"
+string(9) "whirlpool"
+string(128) "e8c6a921e7d8eac2fd21d4df6054bb27a02321b2beb5b01b6f88c40706164e64d67ec97519bf76c8af8df896745478b78d42a0159f1a0db16777771fd9d420dc"
+string(128) "e8c6a921e7d8eac2fd21d4df6054bb27a02321b2beb5b01b6f88c40706164e64d67ec97519bf76c8af8df896745478b78d42a0159f1a0db16777771fd9d420dc"
+string(10) "tiger128,3"
+string(32) "a99d2c0348d480dc0f3c35852926e0f1"
+string(32) "a99d2c0348d480dc0f3c35852926e0f1"
+string(10) "tiger160,3"
+string(40) "a99d2c0348d480dc0f3c35852926e0f1e1825c16"
+string(40) "a99d2c0348d480dc0f3c35852926e0f1e1825c16"
+string(10) "tiger192,3"
+string(48) "a99d2c0348d480dc0f3c35852926e0f1e1825c1651957ee3"
+string(48) "a99d2c0348d480dc0f3c35852926e0f1e1825c1651957ee3"
+string(10) "tiger128,4"
+string(32) "66e2c0322421c4e5a9208e6aeed481e5"
+string(32) "66e2c0322421c4e5a9208e6aeed481e5"
+string(10) "tiger160,4"
+string(40) "66e2c0322421c4e5a9208e6aeed481e5c4b00448"
+string(40) "66e2c0322421c4e5a9208e6aeed481e5c4b00448"
+string(10) "tiger192,4"
+string(48) "66e2c0322421c4e5a9208e6aeed481e5c4b00448e344d9d0"
+string(48) "66e2c0322421c4e5a9208e6aeed481e5c4b00448e344d9d0"
+string(6) "snefru"
+string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0"
+string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0"
+string(9) "snefru256"
+string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0"
+string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0"
+string(4) "gost"
+string(64) "a00961e371287c71c527a41c14564f13b6ed12ac7cd9d5f5dfb3542a25e28d3b"
+string(64) "a00961e371287c71c527a41c14564f13b6ed12ac7cd9d5f5dfb3542a25e28d3b"
+string(11) "gost-crypto"
+string(64) "68ca9aea6729dc07d995fbe071a4b5c6490bb27fc4dc65ec0e96200d5e082996"
+string(64) "68ca9aea6729dc07d995fbe071a4b5c6490bb27fc4dc65ec0e96200d5e082996"
+string(7) "adler32"
+string(8) "d9141747"
+string(8) "d9141747"
+string(5) "crc32"
+string(8) "59f8d3d2"
+string(8) "59f8d3d2"
+string(6) "crc32b"
+string(8) "3ee63999"
+string(8) "3ee63999"
+string(6) "crc32c"
+string(8) "516ad412"
+string(8) "516ad412"
+string(6) "fnv132"
+string(8) "59ad036f"
+string(8) "59ad036f"
+string(7) "fnv1a32"
+string(8) "fadc2cef"
+string(8) "fadc2cef"
+string(6) "fnv164"
+string(16) "5e8c64fba6a5ffcf"
+string(16) "5e8c64fba6a5ffcf"
+string(7) "fnv1a64"
+string(16) "893899e4415a920f"
+string(16) "893899e4415a920f"
+string(5) "joaat"
+string(8) "836fb0e5"
+string(8) "836fb0e5"
+string(10) "haval128,3"
+string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"
+string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"
+string(10) "haval160,3"
+string(40) "f1a2c9604fb40899ad502abe0dfcec65115c8a9a"
+string(40) "f1a2c9604fb40899ad502abe0dfcec65115c8a9a"
+string(10) "haval192,3"
+string(48) "d3a7315773a326678208650ed02510ed96cd488d74cd5231"
+string(48) "d3a7315773a326678208650ed02510ed96cd488d74cd5231"
+string(10) "haval224,3"
+string(56) "6d7132fabc83c9ab7913748b79ecf10e25409569d3ed144177f46731"
+string(56) "6d7132fabc83c9ab7913748b79ecf10e25409569d3ed144177f46731"
+string(10) "haval256,3"
+string(64) "7a469868ad4b92891a3a44524c58a2b8d0f3bebb92b4cf47d19bc6aba973eb95"
+string(64) "7a469868ad4b92891a3a44524c58a2b8d0f3bebb92b4cf47d19bc6aba973eb95"
+string(10) "haval128,4"
+string(32) "6ecddb39615f43fd211839287ff38461"
+string(32) "6ecddb39615f43fd211839287ff38461"
+string(10) "haval160,4"
+string(40) "bcd2e7821723ac22e122b8b7cbbd2daaa9a862df"
+string(40) "bcd2e7821723ac22e122b8b7cbbd2daaa9a862df"
+string(10) "haval192,4"
+string(48) "ae74619a88dcec1fbecde28e27f009a65ecc12170824d2cd"
+string(48) "ae74619a88dcec1fbecde28e27f009a65ecc12170824d2cd"
+string(10) "haval224,4"
+string(56) "fdaba6563f1334d40de24e311f14b324577f97c3b78b9439c408cdca"
+string(56) "fdaba6563f1334d40de24e311f14b324577f97c3b78b9439c408cdca"
+string(10) "haval256,4"
+string(64) "289a2ba4820218bdb25a6534fbdf693f9de101362584fdd41e32244c719caa37"
+string(64) "289a2ba4820218bdb25a6534fbdf693f9de101362584fdd41e32244c719caa37"
+string(10) "haval128,5"
+string(32) "ffa7993a4e183b245263fb1f63e27343"
+string(32) "ffa7993a4e183b245263fb1f63e27343"
+string(10) "haval160,5"
+string(40) "375ee5ab3a9bd07a1dbe5d071e07b2afb3165e3b"
+string(40) "375ee5ab3a9bd07a1dbe5d071e07b2afb3165e3b"
+string(10) "haval192,5"
+string(48) "c650585f93c6e041e835caedc621f8c42d8bc6829fb76789"
+string(48) "c650585f93c6e041e835caedc621f8c42d8bc6829fb76789"
+string(10) "haval224,5"
+string(56) "bc674d465a822817d939f19b38edde083fe5668759836c203c56e3e4"
+string(56) "bc674d465a822817d939f19b38edde083fe5668759836c203c56e3e4"
+string(10) "haval256,5"
+string(64) "da70ad9bd09ed7c9675329ea2b5279d57761807c7aeac6340d94b5d494809457"
+string(64) "da70ad9bd09ed7c9675329ea2b5279d57761807c7aeac6340d94b5d494809457"
+Done
--- /dev/null
+--TEST--
+Hash: serialize()/unserialize() with HASH_HMAC
+--FILE--
+<?php
+
+$algos = hash_algos();
+$non_crypto = ["adler32", "crc32", "crc32b", "crc32c", "fnv132", "fnv1a32", "fnv164", "fnv1a64", "joaat"];
+$key = "This is the key that I have";
+
+foreach ($algos as $algo) {
+ if (in_array($algo, $non_crypto)) {
+ continue;
+ }
+
+ var_dump($algo);
+ $ctx0 = hash_init($algo, HASH_HMAC, $key);
+ try {
+ $serial = serialize($ctx0);
+ assert(is_string($serial));
+ } catch (Throwable $e) {
+ echo $e->getMessage(), "\n";
+ }
+}
+
+echo "Done\n";
+?>
+--EXPECT--
+string(3) "md2"
+HashContext with HASH_HMAC option cannot be serialized
+string(3) "md4"
+HashContext with HASH_HMAC option cannot be serialized
+string(3) "md5"
+HashContext with HASH_HMAC option cannot be serialized
+string(4) "sha1"
+HashContext with HASH_HMAC option cannot be serialized
+string(6) "sha224"
+HashContext with HASH_HMAC option cannot be serialized
+string(6) "sha256"
+HashContext with HASH_HMAC option cannot be serialized
+string(6) "sha384"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "sha512/224"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "sha512/256"
+HashContext with HASH_HMAC option cannot be serialized
+string(6) "sha512"
+HashContext with HASH_HMAC option cannot be serialized
+string(8) "sha3-224"
+HashContext with HASH_HMAC option cannot be serialized
+string(8) "sha3-256"
+HashContext with HASH_HMAC option cannot be serialized
+string(8) "sha3-384"
+HashContext with HASH_HMAC option cannot be serialized
+string(8) "sha3-512"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "ripemd128"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "ripemd160"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "ripemd256"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "ripemd320"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "whirlpool"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger128,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger160,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger192,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger128,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger160,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "tiger192,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(6) "snefru"
+HashContext with HASH_HMAC option cannot be serialized
+string(9) "snefru256"
+HashContext with HASH_HMAC option cannot be serialized
+string(4) "gost"
+HashContext with HASH_HMAC option cannot be serialized
+string(11) "gost-crypto"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval128,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval160,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval192,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval224,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval256,3"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval128,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval160,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval192,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval224,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval256,4"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval128,5"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval160,5"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval192,5"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval224,5"
+HashContext with HASH_HMAC option cannot be serialized
+string(10) "haval256,5"
+HashContext with HASH_HMAC option cannot be serialized
+Done
--- /dev/null
+--TEST--
+Hash: serialization formats
+--FILE--
+<?php
+
+$serializations = [
+ [
+ "md2",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjM6Im1kMiI7aToxO2k6MDtpOjI7YTo0OntpOjA7czo0ODoiuyJG48A1rdYMPXAiWBDcbOrPsUaDg8lhMXhr/DQfjaN7dOqrImXTxBykKAln5L8sIjtpOjE7czoxNjoiwrfjcIJR1I8RljMyAxmcSyI7aToyO3M6MTY6IiBhbnl0aGluZwAAAAAAAAAiO2k6MztpOjk7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "md4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjM6Im1kNCI7aToxO2k6MDtpOjI7YTo3OntpOjA7aToxNzMyNTg0MTkzO2k6MTtpOi0yNzE3MzM4Nzk7aToyO2k6LTE3MzI1ODQxOTQ7aTozO2k6MjcxNzMzODc4O2k6NDtpOjIwMDtpOjU7aTowO2k6NjtzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "md5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjM6Im1kNSI7aToxO2k6MDtpOjI7YToyMzp7aTowO2k6MjU7aToxO2k6MDtpOjI7aToxNzMyNTg0MTkzO2k6MztpOi0yNzE3MzM4Nzk7aTo0O2k6LTE3MzI1ODQxOTQ7aTo1O2k6MjcxNzMzODc4O2k6NjtzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjtpOjc7aTowO2k6ODtpOjA7aTo5O2k6MDtpOjEwO2k6MDtpOjExO2k6MDtpOjEyO2k6MDtpOjEzO2k6MDtpOjE0O2k6MDtpOjE1O2k6MDtpOjE2O2k6MDtpOjE3O2k6MDtpOjE4O2k6MDtpOjE5O2k6MDtpOjIwO2k6MDtpOjIxO2k6MDtpOjIyO2k6MDt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "sha1",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtpOjA7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O2k6MDtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "sha224",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNoYTIyNCI7aToxO2k6MDtpOjI7YToxMTp7aTowO2k6LTEwNTY1OTYyNjQ7aToxO2k6OTE0MTUwNjYzO2k6MjtpOjgxMjcwMjk5OTtpOjM7aTotMTUwMDU0NTk5O2k6NDtpOi00MTkxNDM5O2k6NTtpOjE3NTA2MDMwMjU7aTo2O2k6MTY5NDA3NjgzOTtpOjc7aTotMTA5MDg5MTg2ODtpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6NjQ6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "sha256",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNoYTI1NiI7aToxO2k6MDtpOjI7YToxMTp7aTowO2k6MTc3OTAzMzcwMztpOjE7aTotMTE1MDgzMzAxOTtpOjI7aToxMDEzOTA0MjQyO2k6MztpOi0xNTIxNDg2NTM0O2k6NDtpOjEzNTk4OTMxMTk7aTo1O2k6LTE2OTQxNDQzNzI7aTo2O2k6NTI4NzM0NjM1O2k6NztpOjE1NDE0NTkyMjU7aTo4O2k6MjAwO2k6OTtpOjA7aToxMDtzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "sha384",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNoYTM4NCI7aToxO2k6MDtpOjI7YToyMTp7aTowO2k6LTEwNTY1OTYyNjQ7aToxO2k6LTg3Njg5NjkzMTtpOjI7aTo5MTQxNTA2NjM7aTozO2k6MTY1NDI3MDI1MDtpOjQ7aTo4MTI3MDI5OTk7aTo1O2k6LTE4NTY0Mzc5MjY7aTo2O2k6LTE1MDA1NDU5OTtpOjc7aTozNTU0NjIzNjA7aTo4O2k6LTQxOTE0Mzk7aTo5O2k6MTczMTQwNTQxNTtpOjEwO2k6MTc1MDYwMzAyNTtpOjExO2k6LTE5MDA3ODcwNjU7aToxMjtpOjE2OTQwNzY4Mzk7aToxMztpOi02MTk5NTg3NzE7aToxNDtpOi0xMDkwODkxODY4O2k6MTU7aToxMjAzMDYyODEzO2k6MTY7aToyMDA7aToxNztpOjA7aToxODtpOjA7aToxOTtpOjA7aToyMDtzOjEyODoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "sha512/224",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJzaGE1MTIvMjI0IjtpOjE7aTowO2k6MjthOjIxOntpOjA7aTo0MjQ5NTUyOTg7aToxO2k6LTE5NDIxNDUwODA7aToyO2k6LTE5ODIwMTYyOTg7aTozO2k6MTk0NDE2NDcxMDtpOjQ7aTo4NTU2MTI1NDY7aTo1O2k6NTAyOTcwMjg2O2k6NjtpOjE0Nzk1MTYxMTE7aTo3O2k6MTczODM5Njk0ODtpOjg7aToyMDc3NTExMDgwO2k6OTtpOjI1ODgxMjc3NztpOjEwO2k6Nzk5ODkwNTg7aToxMTtpOjIwMTEzOTM5MDc7aToxMjtpOjE3ODAyOTk0NjQ7aToxMztpOjEwNjcyODc5NzY7aToxNDtpOi0xODQ4MjA4NzM1O2k6MTU7aToyODY0NTEzNzM7aToxNjtpOjIwMDtpOjE3O2k6MDtpOjE4O2k6MDtpOjE5O2k6MDtpOjIwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "sha512/256",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJzaGE1MTIvMjU2IjtpOjE7aTowO2k6MjthOjIxOntpOjA7aTotNjQyMjc1NDA7aToxO2k6NTczNjQ1MjA0O2k6MjtpOi05MzQ1MTc1NjY7aTozO2k6LTE2MjE3OTQ5MDk7aTo0O2k6MTg2Nzc1NTg1NztpOjU7aTo1OTY4ODM1NjM7aTo2O2k6MTQ5NzQyNjYyMTtpOjc7aTotMTc3NDY4NDM5MTtpOjg7aTotMTQ2NzAyMzM4OTtpOjk7aTotMTc3NTc0NzM1ODtpOjEwO2k6MTQwMTMwNTQ5MDtpOjExO2k6LTExMDExMjgxNTU7aToxMjtpOjc0Njk2MTA2NjtpOjEzO2k6NzIxNTI1MjQ0O2k6MTQ7aTotMjExNzc4NDQxNDtpOjE1O2k6MjQ2ODg1ODUyO2k6MTY7aToyMDA7aToxNztpOjA7aToxODtpOjA7aToxOTtpOjA7aToyMDtzOjEyODoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "sha512",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNoYTUxMiI7aToxO2k6MDtpOjI7YToyMTp7aTowO2k6LTIwNTczMTU3NjtpOjE7aToxNzc5MDMzNzAzO2k6MjtpOi0yMDY3MDkzNzAxO2k6MztpOi0xMTUwODMzMDE5O2k6NDtpOi0yMzc5MTU3MztpOjU7aToxMDEzOTA0MjQyO2k6NjtpOjE1OTU3NTAxMjk7aTo3O2k6LTE1MjE0ODY1MzQ7aTo4O2k6LTEzNzc0MDIxNTk7aTo5O2k6MTM1OTg5MzExOTtpOjEwO2k6NzI1NTExMTk5O2k6MTE7aTotMTY5NDE0NDM3MjtpOjEyO2k6LTc5NTc3NzQ5O2k6MTM7aTo1Mjg3MzQ2MzU7aToxNDtpOjMyNzAzMzIwOTtpOjE1O2k6MTU0MTQ1OTIyNTtpOjE2O2k6MjAwO2k6MTc7aTowO2k6MTg7aTowO2k6MTk7aTowO2k6MjA7czoxMjg6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "ripemd128",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjk6InJpcGVtZDEyOCI7aToxO2k6MDtpOjI7YTo3OntpOjA7aToxNzMyNTg0MTkzO2k6MTtpOi0yNzE3MzM4Nzk7aToyO2k6LTE3MzI1ODQxOTQ7aTozO2k6MjcxNzMzODc4O2k6NDtpOjIwMDtpOjU7aTowO2k6NjtzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "ripemd160",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjk6InJpcGVtZDE2MCI7aToxO2k6MDtpOjI7YTo4OntpOjA7aToxNzMyNTg0MTkzO2k6MTtpOi0yNzE3MzM4Nzk7aToyO2k6LTE3MzI1ODQxOTQ7aTozO2k6MjcxNzMzODc4O2k6NDtpOi0xMDA5NTg5Nzc2O2k6NTtpOjIwMDtpOjY7aTowO2k6NztzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "ripemd256",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjk6InJpcGVtZDI1NiI7aToxO2k6MDtpOjI7YToxMTp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aToxOTg1MjI5MzI4O2k6NTtpOi0xOTA4ODc0NDtpOjY7aTotMTk4NTIyOTMyOTtpOjc7aToxOTA4ODc0MztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6NjQ6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "ripemd320",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjk6InJpcGVtZDMyMCI7aToxO2k6MDtpOjI7YToxMzp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToxOTg1MjI5MzI4O2k6NjtpOi0xOTA4ODc0NDtpOjc7aTotMTk4NTIyOTMyOTtpOjg7aToxOTA4ODc0MztpOjk7aToxMDA5NTg5Nzc1O2k6MTA7aToyMDA7aToxMTtpOjA7aToxMjtzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "whirlpool",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjk6IndoaXJscG9vbCI7aToxO2k6MDtpOjI7YToyMDp7aTowO2k6MDtpOjE7aTowO2k6MjtpOjA7aTozO2k6MDtpOjQ7aTowO2k6NTtpOjA7aTo2O2k6MDtpOjc7aTowO2k6ODtpOjA7aTo5O2k6MDtpOjEwO2k6MDtpOjExO2k6MDtpOjEyO2k6MDtpOjEzO2k6MDtpOjE0O2k6MDtpOjE1O2k6MDtpOjE2O3M6MzI6IgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIIjtpOjE3O2k6MjU7aToxODtpOjIwMDtpOjE5O3M6NjQ6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "tiger128,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjEyOCwzIjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "tiger160,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjE2MCwzIjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "tiger192,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjE5MiwzIjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "tiger128,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjEyOCw0IjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "tiger160,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjE2MCw0IjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "tiger192,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJ0aWdlcjE5Miw0IjtpOjE7aTowO2k6MjthOjEwOntpOjA7aTotMTk4NTIyOTMyOTtpOjE7aToxOTA4ODc0MztpOjI7aToxOTg1MjI5MzI4O2k6MztpOi0xOTA4ODc0NDtpOjQ7aTotMTAxMTY4NzAzMztpOjU7aTotMjU4NTYyNjM2O2k6NjtpOjA7aTo3O2k6MDtpOjg7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7aTo5O2k6MjU7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "snefru",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNuZWZydSI7aToxO2k6MDtpOjI7YToyMDp7aTowO2k6MDtpOjE7aTowO2k6MjtpOjA7aTozO2k6MDtpOjQ7aTowO2k6NTtpOjA7aTo2O2k6MDtpOjc7aTowO2k6ODtpOjA7aTo5O2k6MDtpOjEwO2k6MDtpOjExO2k6MDtpOjEyO2k6MDtpOjEzO2k6MDtpOjE0O2k6MDtpOjE1O2k6MDtpOjE2O2k6MDtpOjE3O2k6MjAwO2k6MTg7aToyNTtpOjE5O3M6MzI6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "snefru256",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6InNuZWZydSI7aToxO2k6MDtpOjI7YToyMDp7aTowO2k6MDtpOjE7aTowO2k6MjtpOjA7aTozO2k6MDtpOjQ7aTowO2k6NTtpOjA7aTo2O2k6MDtpOjc7aTowO2k6ODtpOjA7aTo5O2k6MDtpOjEwO2k6MDtpOjExO2k6MDtpOjEyO2k6MDtpOjEzO2k6MDtpOjE0O2k6MDtpOjE1O2k6MDtpOjE2O2k6MDtpOjE3O2k6MjAwO2k6MTg7aToyNTtpOjE5O3M6MzI6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "gost",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6Imdvc3QiO2k6MTtpOjA7aToyO2E6MjA6e2k6MDtpOjA7aToxO2k6MDtpOjI7aTowO2k6MztpOjA7aTo0O2k6MDtpOjU7aTowO2k6NjtpOjA7aTo3O2k6MDtpOjg7aTowO2k6OTtpOjA7aToxMDtpOjA7aToxMTtpOjA7aToxMjtpOjA7aToxMztpOjA7aToxNDtpOjA7aToxNTtpOjA7aToxNjtpOjIwMDtpOjE3O2k6MDtpOjE4O2k6MjU7aToxOTtzOjMyOiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "gost-crypto",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjExOiJnb3N0LWNyeXB0byI7aToxO2k6MDtpOjI7YToyMDp7aTowO2k6MDtpOjE7aTowO2k6MjtpOjA7aTozO2k6MDtpOjQ7aTowO2k6NTtpOjA7aTo2O2k6MDtpOjc7aTowO2k6ODtpOjA7aTo5O2k6MDtpOjEwO2k6MDtpOjExO2k6MDtpOjEyO2k6MDtpOjEzO2k6MDtpOjE0O2k6MDtpOjE1O2k6MDtpOjE2O2k6MjAwO2k6MTc7aTowO2k6MTg7aToyNTtpOjE5O3M6MzI6IkkgY2FuJ3QgcmVtZW1iZXIgYW55dGhpbmcAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "adler32",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjc6ImFkbGVyMzIiO2k6MTtpOjA7aToyO2E6MTp7aTowO2k6MTg3MDM5OTc4NDt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "crc32",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjU6ImNyYzMyIjtpOjE7aTowO2k6MjthOjE6e2k6MDtpOi0xNjIzMzE0NDA2O31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "crc32b",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6ImNyYzMyYiI7aToxO2k6MDtpOjI7YToxOntpOjA7aTotMTc2Mjk0OTcxMTt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "crc32c",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6ImNyYzMyYyI7aToxO2k6MDtpOjI7YToxOntpOjA7aTotMTU4MTI3NjgyMDt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "fnv132",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6ImZudjEzMiI7aToxO2k6MDtpOjI7YToxOntpOjA7aTotMTc0MzU0NzEzMjt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "fnv1a32",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjc6ImZudjFhMzIiO2k6MTtpOjA7aToyO2E6MTp7aTowO2k6LTE0Mjc4NDA5NTg7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "fnv164",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjY6ImZudjE2NCI7aToxO2k6MDtpOjI7YToyOntpOjA7aTotMTMyOTM4MTA4O2k6MTtpOjM0MDkyODA4OTt9aTozO2k6MjtpOjQ7YTowOnt9fQ=="
+ ],
+ [
+ "fnv1a64",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjc6ImZudjFhNjQiO2k6MTtpOjA7aToyO2E6Mjp7aTowO2k6ODY3NjA5NDQyO2k6MTtpOi0xMDk0OTQ1Njg2O31pOjM7aToyO2k6NDthOjA6e319"
+ ],
+ [
+ "joaat",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjU6ImpvYWF0IjtpOjE7aTowO2k6MjthOjE6e2k6MDtpOi0xNDY5OTExMTA7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval128,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDEyOCwzIjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval160,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE2MCwzIjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval192,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE5MiwzIjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval224,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDIyNCwzIjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval256,3",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDI1NiwzIjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval128,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDEyOCw0IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval160,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE2MCw0IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval192,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE5Miw0IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval224,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDIyNCw0IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval256,4",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDI1Niw0IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval128,5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDEyOCw1IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval160,5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE2MCw1IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval192,5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDE5Miw1IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval224,5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDIyNCw1IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "haval256,5",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjEwOiJoYXZhbDI1Niw1IjtpOjE7aTowO2k6MjthOjExOntpOjA7aTo2MDgxMzU4MTY7aToxO2k6LTIwNTI5MTI5NDE7aToyO2k6MzIwNDQwODc4O2k6MztpOjU3NzAxMTg4O2k6NDtpOi0xNTQyODk5Njc4O2k6NTtpOjY5ODI5ODgzMjtpOjY7aToxMzcyOTY1MzY7aTo3O2k6LTMzMDQwNDcyNztpOjg7aToyMDA7aTo5O2k6MDtpOjEwO3M6MTI4OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0="
+ ],
+ [
+ "sha3-224",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjI0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCCNmpKakp2ajd+ekYaLl5aRZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDA7aTo0O2E6MDp7fX0=", /* 64-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjI0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiCZk6DkJFV0S8u4vLRUZWVJDajqlEZ2R2CwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDE7aTo0O2E6MDp7fX0=", /* 32-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjI0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToyO2k6NDthOjA6e319" /* slow */
+ ],
+ [
+ "sha3-256",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjU2IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCCNmpKakp2ajd+ekYaLl5aRZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDA7aTo0O2E6MDp7fX0=", /* 64-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjU2IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiCZk6DkJFV0S8u4vLRUZWVJDajqlEZ2R2CwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDE7aTo0O2E6MDp7fX0=", /* 32-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMjU2IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToyO2k6NDthOjA6e319" /* slow */
+ ],
+ [
+ "sha3-384",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMzg0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCCNmpKakp2ajd+ekYaLl5aRZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDA7aTo0O2E6MDp7fX0=", /* 64-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMzg0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiCZk6DkJFV0S8u4vLRUZWVJDajqlEZ2R2CwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDE7aTo0O2E6MDp7fX0=", /* 32-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtMzg0IjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToyO2k6NDthOjA6e319" /* slow */
+ ],
+ [
+ "sha3-512",
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtNTEyIjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCCNmpKakp2ajd+ekYaLl5aRZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAP//////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDA7aTo0O2E6MDp7fX0=", /* 64-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtNTEyIjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiCZk6DkJFV0S8u4vLRUZWVJDajqlEZ2R2CwAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToxMDE7aTo0O2E6MDp7fX0=", /* 32-bit fast LE */
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjg6InNoYTMtNTEyIjtpOjE7aTowO2k6MjthOjI6e2k6MDtzOjIwMDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAiO2k6MTtpOjI1O31pOjM7aToyO2k6NDthOjA6e319" /* slow */
+ ]
+];
+
+
+function test_serialization($serial, $hash, $algo) {
+ try {
+ $ctx = unserialize(base64_decode($serial));
+ hash_update($ctx, "Can’t tell if this is true or dream");
+ $hash2 = hash_final($ctx);
+ if ($hash !== $hash2) {
+ echo "$algo: unexpected hash $hash2 for serialization {$serial}\n";
+ }
+ } catch (Throwable $e) {
+ echo "$algo: problem with serialization {$serial}\n";
+ echo " ", $e->getMessage(), "\n", $e->getTraceAsString();
+ }
+}
+
+foreach ($serializations as $slist) {
+ $algo = $slist[0];
+ $hash = hash($algo, "I can't remember anythingCan’t tell if this is true or dream");
+
+ $ctx = hash_init($algo);
+ hash_update($ctx, "I can't remember anything");
+ $serial = base64_encode(serialize($ctx));
+ if (!in_array($serial, $slist)) {
+ echo "$algo: unexpected serialization $serial\n";
+ }
+
+ test_serialization($serial, $hash, $algo);
+}
+
+echo "Done\n";
+?>
+--EXPECT--
+Done
--- /dev/null
+--TEST--
+Hash: serialization errors
+--FILE--
+<?php
+
+// cannot unserialize onto an already-initialized object
+$ctx = hash_init("sha256");
+try {
+ $ctx->__unserialize($ctx->__serialize());
+} catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+}
+
+// bad formats
+foreach ([
+ "TzoxMToiSGFzaENvbnRleHQiOjA6e30=", // no contents
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtpOjE7aToxO2k6MDtpOjI7YTo4OntpOjA7aToxNzMyNTg0MTkzO2k6MTtpOi0yNzE3MzM4Nzk7aToyO2k6LTE3MzI1ODQxOTQ7aTozO2k6MjcxNzMzODc4O2k6NDtpOi0xMDA5NTg5Nzc2O2k6NTtpOjIwMDtpOjY7aTowO2k6NztzOjY0OiJJIGNhbid0IHJlbWVtYmVyIGFueXRoaW5nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIjt9aTozO2k6MjtpOjQ7YTowOnt9fQ==", // algorithm is int
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtzOjA6IiI7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O2k6MDtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0=", // flags are string
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtpOjE7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O2k6MDtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0=", // flags indicate HASH_HMAC
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtpOjI7aToyO3M6MTA6ImFiY2RlZmdoaWoiO2k6MztpOjI7aTo0O2E6MDp7fX0=", // serialization format wrong
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtpOjA7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O3M6MDoiIjtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0=", // serialization internals wrong
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6InNoYTEiO2k6MTtpOjA7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O2k6MDtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjA7aTo0O2E6MDp7fX0=", // bad magic number
+ "TzoxMToiSGFzaENvbnRleHQiOjU6e2k6MDtzOjQ6Inh4eDEiO2k6MTtpOjA7aToyO2E6ODp7aTowO2k6MTczMjU4NDE5MztpOjE7aTotMjcxNzMzODc5O2k6MjtpOi0xNzMyNTg0MTk0O2k6MztpOjI3MTczMzg3ODtpOjQ7aTotMTAwOTU4OTc3NjtpOjU7aToyMDA7aTo2O2k6MDtpOjc7czo2NDoiSSBjYW4ndCByZW1lbWJlciBhbnl0aGluZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI7fWk6MztpOjI7aTo0O2E6MDp7fX0=" // bad algorithm
+] as $serial) {
+ try {
+ $ctx = unserialize(base64_decode($serial));
+ echo "Unexpected success\n";
+ } catch (Exception $e) {
+ echo $e->getMessage(), "\n";
+ }
+}
+
+echo "Done\n";
+?>
+--EXPECT--
+HashContext::__unserialize called on initialized object
+Incomplete or ill-formed serialization data
+Incomplete or ill-formed serialization data
+Incomplete or ill-formed serialization data
+HashContext with HASH_HMAC option cannot be serialized
+Incomplete or ill-formed serialization data ("sha1" code -1)
+Incomplete or ill-formed serialization data ("sha1" code -1024)
+Incomplete or ill-formed serialization data ("sha1" code -1)
+Unknown hash algorithm
+Done
+++ /dev/null
---TEST--
-Hash: Context serialization
---FILE--
-<?php
-
-$h = hash_init('md5');
-try {
- var_dump(serialize($h));
-} catch (Exception $e) {
- echo "Exception: {$e->getMessage()}\n";
-}
---EXPECT--
-Exception: Serialization of 'HashContext' is not allowed
unsigned char buffer[64];
uint32_t block[16];
} PHP_MD5_CTX;
+#define PHP_MD5_SPEC "llllllb64l16."
PHPAPI void PHP_MD5Init(PHP_MD5_CTX *ctx);
PHPAPI void PHP_MD5Update(PHP_MD5_CTX *ctx, const void *data, size_t size);
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} PHP_SHA1_CTX;
+#define PHP_SHA1_SPEC "l5l2b64."
PHPAPI void PHP_SHA1Init(PHP_SHA1_CTX *);
PHPAPI void PHP_SHA1Update(PHP_SHA1_CTX *, const unsigned char *, size_t);