How to convert an sha3 hash to an big integer in golang

1.4k views Asked by At

I generated a hash value using sha3 and I need to convert it to a big.Int value. Is it possible ? or is there a method to get the integervalue of the hash ?

the following code throws an error that cannot convert type hash.Hash to type int64 :

package main 

import (
"math/big"
"golang.org/x/crypto/sha3"
"fmt"

)
func main(){

  chall := "hello word"
  b := byte[](chall)
  h := sha3.New244()
  h.Write(chall)
  h.Write(b)
  d := make([]byte, 16)
  h.Sum(d)
  val := big.NewInt(int64(h))
  fmt.Println(val)

}


3

There are 3 answers

3
Rob Napier On BEST ANSWER

(See Peter's comment for the simpler version of this.)

Interpreting a series of bytes as a big.Int is the same as interpreting a series of decimal digits as an arbitrarily large number. For example, to convert the digits 1234 into a "number", you'd do this:

  • Start with 0
  • Multiply by 10 = 0
  • Add 1 = 1
  • Multiply by 10 = 10
  • Add 2 = 12
  • Multiply by 10 = 120
  • Add 3 = 123
  • Multiply by 10 = 1230
  • Add 4 = 1234

The same applies to bytes. The "digits" are just base-256 rather than base-10:

val := big.NewInt(0)
for i := 0; i < h.Size(); i++ {
    val.Lsh(val, 8)
    val.Add(val, big.NewInt(int64(d[i])))
}

(Lsh is a left-shift. Left shifting by 8 bits is the same as multiplying by 256.)

Playground

0
colm.anseo On

TL;DR;

sha3.New224() cannot be represented in uint64 type.


There are many hash types - and of differing sizes. Go standard library picks a very generic interface to cover all type of hashes: https://golang.org/pkg/hash/#Hash

type Hash interface {
    io.Writer
    Sum(b []byte) []byte
    Reset()
    Size() int
    BlockSize() int
}

Having said that some Go hash implementations optionally include extra methods like hash.Hash64:

type Hash64 interface {
    Hash
    Sum64() uint64
}

others may implement encoding.BinaryMarshaler:

type BinaryMarshaler interface {
    MarshalBinary() (data []byte, err error)
}

which one can use to preserve a hash state.

sha3.New224() does not implement the above 2 interfaces, but crc64 hash does. To do a runtime check:

h64, ok := h.(hash.Hash64)
if ok {
    fmt.Printf("64-bit: %d\n", h64.Sum64())
}

Working example: https://play.golang.org/p/uLUfw0gMZka

0
Azr On

You can also do the following:

val := new(big.Int).SetBytes(sum)

https://go.dev/play/p/Qrxo5D5uBjm