Skip to content

Commit 1642f2e

Browse files
committed
Correct implementation of joaat hash.
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.
1 parent 56aebbe commit 1642f2e

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

ext/hash/hash_joaat.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,22 @@ PHP_HASH_API void PHP_JOAATUpdate(PHP_JOAAT_CTX *context, const unsigned char *i
4444

4545
PHP_HASH_API void PHP_JOAATFinal(unsigned char digest[4], PHP_JOAAT_CTX * context)
4646
{
47+
uint32_t hval = context->state;
48+
hval += (hval << 3);
49+
hval ^= (hval >> 11);
50+
hval += (hval << 15);
51+
4752
#ifdef WORDS_BIGENDIAN
48-
memcpy(digest, &context->state, 4);
53+
memcpy(digest, &hval, 4);
4954
#else
5055
int i = 0;
51-
unsigned char *c = (unsigned char *) &context->state;
56+
unsigned char *c = (unsigned char *) &hval;
5257

5358
for (i = 0; i < 4; i++) {
5459
digest[i] = c[3 - i];
5560
}
5661
#endif
57-
context->state = 0;
62+
context->state = 0;
5863
}
5964

6065
/*
@@ -79,9 +84,5 @@ joaat_buf(void *buf, size_t len, uint32_t hval)
7984
hval ^= (hval >> 6);
8085
}
8186

82-
hval += (hval << 3);
83-
hval ^= (hval >> 11);
84-
hval += (hval << 15);
85-
8687
return hval;
8788
}

ext/hash/tests/hash-clone.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ string(16) "bebc746a33b6ab62"
301301
string(16) "893899e4415a920f"
302302
string(5) "joaat"
303303
string(8) "aaebf370"
304-
string(8) "513479b4"
304+
string(8) "836fb0e5"
305305
string(10) "haval128,3"
306306
string(32) "86362472c8895e68e223ef8b3711d8d9"
307307
string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"

ext/hash/tests/hash_copy_001.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ string(16) "bebc746a33b6ab62"
301301
string(16) "893899e4415a920f"
302302
string(5) "joaat"
303303
string(8) "aaebf370"
304-
string(8) "513479b4"
304+
string(8) "836fb0e5"
305305
string(10) "haval128,3"
306306
string(32) "86362472c8895e68e223ef8b3711d8d9"
307307
string(32) "ebeeeb05c18af1e53d2d127b561d5e0d"

0 commit comments

Comments
 (0)