A quick question. I want to use the last character of a SHA256 hash (blockhash of a bitcoin block) as my random source. Is 100 /16(amount of different chars) = 6.25% true for all characters or are some characters more likely to be the last char of a hash.

  • 3
    $\begingroup$ What are you using these random values for? Hash functions like SHA256 are deterministic, so given the input and the output, they are not random at all. Are you assuming your attacker does not have access to the block you are using as the input? $\endgroup$ – mikeazo Feb 21 '18 at 16:22
  • $\begingroup$ @mikeazo Yes I'm assuming the attacker doesn't have the input, because it wont be mined when he has to guess the last char. $\endgroup$ – Bram Feb 21 '18 at 21:45
  • $\begingroup$ Are you sure you want a PRF instead of say a VRF? A special kind of asymmetric signature that emulates a PRF. The secret key is used to derive the random value, the owner cannot manipulate this. The public key verifies, but cannot otherwise compute the random string. This is used in Algorand to implement a Proof-of-Stake and random sortition based byzantine agreement; which solves the forking problem of blockchains and is cheap for both communication and computation. $\endgroup$ – cypherfox Mar 10 '18 at 15:34

The output of any modern hash is binary. Not all byte values however map to (printable) characters. So what you are looking at is a textual representation of the hash, using an encoding such as hexadecimals (e.g. for sha256sum) or base 64.

You are mentioning the value 16, so lets presume that the output is in hexadecimals. In that case each of the characters 0-9 together with A-F (in upper- or lowercase) is expected with a probability of precisely $1\over{16}$, given that the observer doesn't have any information on the input.

If the input can be guessed and verified then the chance of guessing the output is a perfect 1: the attacker can simply perform the hash calculation himself to calculate the output. You would have to perform HMAC instead of the hash function and keep the key secret.

Depending on your requirements you are probably better off using a known secure PRNG (or DRBG) and seed it using the input.

| improve this answer | |

I suspect your hash output is in hexadecimal. If all the characters in the hash are 0-9 or A-F (ignoring case), then it is almost certainly in hex. Which of those 16 characters will occur last is unpredictable (all should appear with equal frequency), but because of the hex encoding any character other than 0-9 and A-F won't appear.

If the hash as a whole consists of a mixture of digits, uppercase letters, lowercase letters, and an occasional punctuation mark, then base64 is more likely. Again the last character would be unpredictable, but would be within the set of characters used by that encoding. Other ASCII encodings exist, but I would not expect them to be used in this context.

I will also agree with mikeazo's comment - Input and use matter.

| improve this answer | |
  • $\begingroup$ Actually, with base64 the last letter should always be =. $\endgroup$ – SEJPM Feb 21 '18 at 18:31
  • 1
    $\begingroup$ @SEJPM Actually, the output padding will either have one, two, or no = symbols, so it's perfectly normal for base64 to end in another character. For example, the ASCII string crypto is encoded to Y3J5cHRv. $\endgroup$ – forest Feb 22 '18 at 6:29
  • $\begingroup$ A hash output can be represented in hexadecimal. Semantic nitpick, sorry for that, but an output is not in hexadecimal. The output is a string. $\endgroup$ – Ruben De Smet Feb 22 '18 at 15:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.