1

This question is similar to this, which is about how the hash digest in the ProtoBuf-based MerkleDag (dag-pb) format is computed. Since the ipfs dag will replace ipfs object, and CBOR will be supported, here I want to ask the similar thing about dag-cbor. I tried to find the answer in IPFS's documentation but did not get much information.

So I did the following.

$ echo '[0,1,2,3]' | ipfs dag put

It gives the CID bafyreidiu4acrauzpzhefghkkom6pbbsvw34o7kc2trpnqd7l62yrxrv2q. In the IPFS webui, the CID is resolved as

bafyreidiu4acrauzpzhefghkkom6pbbsvw34o7kc2trpnqd7l62yrxrv2q
base32 - cidv1 - dag-cbor - sha2-256-256-68a7002882997e4e4298ea5399e78432adb7c77d42d4e2f6c07f5fb588de35d4
BASE - VERSION - CODEC - MULTIHASH
MULTIHASH
0x122068a7002882997e4e4298ea5399e78432
      adb7c77d42d4e2f6c07f5fb588de35d4
HASH DIGEST
0x12 = sha2-256
0x20 = 256 bits

I expect the [0,1,2,3]is first serialized by CBOR as a CBOR-array, then sha256 digested. Therefore I want to reproduce the hash digest (68a700288299...). So I did the following in Python's repl:

>>> from cbor2 import dumps
>>> from hashlib import sha256
>>> from binascii import hexlify
>>> hexlify(sha256(dumps([0,1,2,3])).digest())
b'e3fbd65c4c3f7fdba7b8ae0709da781c3637b13f4a4b920db90d2f9b23d412ff'

So the hash cannot match. But if I do the same thing for a simple string object, i.e.,

$ echo '"Hello World"' | ipfs dag put
bafyreidfq7gnjnpi7hllpwowrphojoy6hgdgrsgitbnbpty6f2yirqhkom

the hash digest, in this case, can be successfully reproduced.

So why it doesn't work for the array object (map objects fails as well)? What else is hiding?

Chen
  • 113
  • 5

2 Answers2

2

I finally found github.com/ipfs/go-ipfs/issues/6549. So that's because go-ipfs parses [0,1,2,3] as float64. So in Python if I change it to [0.0, 1.0, 2.0, 3.0], the two hash values match perfectly! That's also why the simple string works.

Chen
  • 113
  • 5
0

I'm not sure, but it might be a wrong data type representation in Python. Have you tried a tuple instead?

  • Just tried. A tuple `(0,1,2,3)` in Python will be treated as a CBOR array as well by the cbor2 package. So it gives me the same result. I also compared the Python cbor-dumped result with http://cbor.me/. They are the same. – Chen Apr 26 '20 at 13:59