Arm Mbed and Pelion Device Management support forum

Help with a double-SHA512 for crypto address generation

I have the following Python3 code that performs SHA512 twice to transform a public key to a network address:

import hashlib
h = hashlib.sha512()
h.update(pub_key_bytes) # once
h.update(h.digest()) # twice
addr = h.digest() # use first 128-bits of addr

The following mbedtls code is my attempt to duplicate the above:

enum { HASH_SZ = 64 };
mbedtls_sha512_context sha_ctx;
unsigned char hash[HASH_SZ];

// Perform SHA512 hash twice on the public key
mbedtls_sha512_init(&sha_ctx);
mbedtls_sha512_starts_ret(&sha_ctx, 0);
mbedtls_sha512_update_ret(&sha_ctx, pub_key, SECP384R1_KEY_SZ); // once
mbedtls_sha512_finish_ret(&sha_ctx, hash);
mbedtls_sha512_update_ret(&sha_ctx, hash, HASH_SZ); // twice
mbedtls_sha512_finish_ret(&sha_ctx, hash);

// Copy the first 128-bits of the 512-bit hash
memcpy(r_addr, hash, LONG_ADDR_SZ);

I’m not getting the same result and am looking for help. Does the “finish_ret()” damage the ctx in some fashion and I have to call starts_ret() again?

thanks,

!!Dean

I’ve confirmed that both the Python and the mbed code produce the same result after the first SHA512 update operation. So there’s something about the way I’m doing the second update in the mbed code that needs correction.

I was able to solve my problem. My workaround in the code block below shows that cloning my context before the call to finish_ret() and using the cloned context for the second update_ret() solves my issue. Restated, the call to finish_ret() modifies context preventing further updates from being valid. I recommend this behavior be explained in the API docs.

// Perform SHA512 hash twice on the public key
mbedtls_sha512_init(&sha_ctx);
mbedtls_sha512_starts_ret(&sha_ctx, 0);
mbedtls_sha512_update_ret(&sha_ctx, pub_key, SECP384R1_KEY_SZ); // once
mbedtls_sha512_clone(&sha_ctx2, &sha_ctx);
mbedtls_sha512_finish_ret(&sha_ctx, hash);

mbedtls_sha512_update_ret(&sha_ctx2, hash, HASH_SZ); // twice
mbedtls_sha512_finish_ret(&sha_ctx2, hash);
mbedtls_sha512_free(&sha_ctx);
mbedtls_sha512_free(&sha_ctx2);