2
$\begingroup$

I am using the Stampery API to anchor hashes into different Blockchains. I wanted to independently verify that my hash with the given Merkle Proof from Stampery. I tried to follow their Whitepaper but with no success.

What I've tried so far is the following:

Hash:
265D0E134C56080CBD9049427C39C5B6425FDC909FC16072FC4AA0D6957B7264

Merkle proof:
R 4C83C6F2C253CD8B44A3EDEB076B65877BEBA0DCA2B85497C3B7E74785EC5618 
R 9F016BF9C9CD4C4F55D171C211666B214C38C7FBDDCED9BC5D2D4239E6C7CE19
L 5461D61A21A6EF783737F328DA8BB8BF5D24804B8574F0E6CBEC076D026C2FBE
R FD894CD6289981AEEC0CE250C841257276FE56D2A003BFE482B2E669BA4A93AC

Merkle root:
16DA7D280DC9B527985F8749636DFB5E3C6B3856A4C7F7CB3E8BA6AEC9F33EB7

Code:

var mP = [
    "4C83C6F2C253CD8B44A3EDEB076B65877BEBA0DCA2B85497C3B7E74785EC5618",
    "9F016BF9C9CD4C4F55D171C211666B214C38C7FBDDCED9BC5D2D4239E6C7CE19",
    "5461D61A21A6EF783737F328DA8BB8BF5D24804B8574F0E6CBEC076D026C2FBE",
    "FD894CD6289981AEEC0CE250C841257276FE56D2A003BFE482B2E669BA4A93AC"
];

r = SHA3( SHA3( mP[2]+SHA3( SHA3(hash+mP[0]) +mP[1])) +mP[3] );

with $r \neq merkleRoot $. Here I simply applied the SHA3 (Keccak) algorithm (as mentioned in the paper) successive, taking into account the L and R from the Merkle Proof. I guess, that the Ls and Rs decide the order of the operands of the SHA3 function.

I am not sure what I am doing wrong and would be happy for any help!


Edit: With the help aesedepece I got a minimal node version running:

var crypto = require('crypto');

function SHA256(x) {
    var buf = new Buffer(x, 'hex');
    return crypto.createHash('sha256').update(buf).digest('hex');
}

var hash = "265D0E134C56080CBD9049427C39C5B6425FDC909FC16072FC4AA0D6957B7264";
var mP = [
    "4C83C6F2C253CD8B44A3EDEB076B65877BEBA0DCA2B85497C3B7E74785EC5618",
    "9F016BF9C9CD4C4F55D171C211666B214C38C7FBDDCED9BC5D2D4239E6C7CE19",
    "5461D61A21A6EF783737F328DA8BB8BF5D24804B8574F0E6CBEC076D026C2FBE",
    "FD894CD6289981AEEC0CE250C841257276FE56D2A003BFE482B2E669BA4A93AC"
];

var merkleRoot = "265D0E134C56080CBD9049427C39C5B6425FDC909FC16072FC4AA0D6957B7264";

var r = SHA256(SHA256(mP[2]+SHA256(SHA256(hash+mP[0])+mP[1]))+mP[3]);
console.log(r);
$\endgroup$
3
  • $\begingroup$ I would expect you hash to be the left leaf joined with mP[3] which then is the right leaf joined with mP[2] etc. $\endgroup$
    – eckes
    Mar 19 '18 at 0:25
  • $\begingroup$ @eckes following your comment I tried: SHA3(SHA3(SHA3(mP[2]+SHA3(hash+mP[3]))+mP[1])+mP[0]), which still does not give me the merkle root. $\endgroup$
    – Knowledge
    Mar 19 '18 at 7:24
  • 1
    $\begingroup$ The whitepaper is not defining what L/R is, so the answer below that you used the wrong version looks likely. $\endgroup$
    – eckes
    Mar 19 '18 at 16:39
1
$\begingroup$

You seem to be doing everything right. The problem here is that you are using the verification process from BTA v5 on a proof generated by BTA v6 (the LTS version of our API). The v6 whitepaper is here.

Put simply: you'll need to use SHA256 instead of SHA3:

r = SHA256(SHA256(mP[2]+SHA256(SHA256(hash+mP[0])+mP[1]))+mP[3]);

Also make sure your hash functions operate on a byte level, not on the hexadecimal representation of the hash digests.

Please don't hesitate to ask for clarification!

$\endgroup$
1
  • $\begingroup$ Finally got it! Thx. The byte-level is a very important detail to have in mind! $\endgroup$
    – Knowledge
    Mar 19 '18 at 18:40

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.