Unpacking ripemd160 result in python

Question:

I am working on a program which does a lot of hashing, and in one of the steps I take a result of hashlib’s ripemd160 hash and convert it into an integer. The lines are:

ripe_fruit = new('ripemd160', sha256(key.to_der()).digest())
key_hash160 = struct.unpack("<Q", ripe_fruit.digest())[0]

It gives me the error:

struct.error: unpack requires a buffer of 8 bytes

I tried changing the value to L and other things, but they didn’t work. How do I fix this?

Asked By: purple_dot

||

Answers:

RIPEMD-160 returns 160 bits, or 20 bytes. struct doesn’t know how to unpack integers larger than 8 bytes. You have two options and the right one depends on what exactly you’re trying to do.

  1. If your algorithm is looking for just some of the bytes of the hash, you can take the first or last 8 bytes and unpack those.

     key_hash160 = struct.unpack("<Q", ripe_fruit.digest()[:8])[0]
    
  2. If you need a 160 bytes integer, you first have to decide how that’s represented. Is it little endian or big endian or something in between? Then you can break the array into 20 bytes and then calculate one number from them. Assuming little endian based on the < in your question, you can then do something like:

     key_parts = struct.unpack("B" * 20, ripe_fruit.digest())
     key_hash160 = 0
     for b in key_parts[::-1]:
       key_hash160 <<= 8
       key_hash160 |= b
    
Answered By: kichik
Categories: questions Tags: , , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.