]> granicus.if.org Git - php/commitdiff
Correct implementation of joaat hash.
authorEddie Kohler <ekohler@gmail.com>
Sun, 21 Jun 2020 23:54:39 +0000 (19:54 -0400)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Mon, 22 Jun 2020 07:39:29 +0000 (09:39 +0200)
Before this commit, the result produced by a joaat hash depended
on how the input data was chunked. A hash produced by multiple
`hash_update` operations was incorrect. For example, this code,
which should produce three identical lines:

    var_dump(hash("joaat", "abcd"));

    $hash = hash_init("joaat");
    hash_update($hash, "ab");
    hash_update($hash, "cd");
    var_dump(hash_final($hash));

    $hash = hash_init("joaat");
    hash_update($hash, "abc");
    hash_update($hash, "d");
    var_dump(hash_final($hash));

instead produced:

    string(8) "cd8b6206"
    string(8) "e590d137"
    string(8) "2d59d087"

This is because the finalization step, involving shift operations
and adds, was applied on every chunk, rather than once at the end
as is required by the hash definition.

After this commit, the code above produces:

    string(8) "cd8b6206"
    string(8) "cd8b6206"
    string(8) "cd8b6206"

as expected.

Some tests encoded the wrong behavior and were corrected.

Closes GH-5749

ext/hash/hash_joaat.c
ext/hash/tests/hash-clone.phpt
ext/hash/tests/hash_copy_001.phpt

index d6311e81dec6cb3f4471d9bfd1d2c87fd2c8b094..10c3ca2748f5d4adfcb947bdd812099db5189d7f 100644 (file)
@@ -44,17 +44,22 @@ PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *i
 
 PHP_HASH_API void PHP_JOAATFinal(unsigned char digest[4], PHP_JOAAT_CTX * context)
 {
+       uint32_t hval = context->state;
+       hval += (hval << 3);
+       hval ^= (hval >> 11);
+       hval += (hval << 15);
+
 #ifdef WORDS_BIGENDIAN
-       memcpy(digest, &context->state, 4);
+       memcpy(digest, &hval, 4);
 #else
        int i = 0;
-       unsigned char *c = (unsigned char *) &context->state;
+       unsigned char *c = (unsigned char *) &hval;
 
        for (i = 0; i < 4; i++) {
                digest[i] = c[3 - i];
        }
 #endif
-    context->state = 0;
+       context->state = 0;
 }
 
 /*
@@ -79,9 +84,5 @@ joaat_buf(void *buf, size_t len, uint32_t hval)
         hval ^= (hval >> 6);
     }
 
-    hval += (hval << 3);
-    hval ^= (hval >> 11);
-    hval += (hval << 15);
-
     return hval;
 }
index 0ef0df444996384c0b7cef437b277a2eb0a5d5c2..57567c0bc5014f50e02f708ede4ec1dee48a8a58 100644 (file)
@@ -301,7 +301,7 @@ string(16) "bebc746a33b6ab62"
 string(16) "893899e4415a920f"
 string(5) "joaat"
 string(8) "aaebf370"
-string(8) "513479b4"
+string(8) "836fb0e5"
 string(10) "haval128,3"
 string(32) "86362472c8895e68e223ef8b3711d8d9"
 string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"
index 27993b61b054acddd208cb8927cb668179252c54..271326178d5239d6ffdeaf3c62fbaaa6d0a6eada 100644 (file)
@@ -301,7 +301,7 @@ string(16) "bebc746a33b6ab62"
 string(16) "893899e4415a920f"
 string(5) "joaat"
 string(8) "aaebf370"
-string(8) "513479b4"
+string(8) "836fb0e5"
 string(10) "haval128,3"
 string(32) "86362472c8895e68e223ef8b3711d8d9"
 string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"