tromp / cuckoo

a memory-bound graph-theoretic proof-of-work system
Other
822 stars 173 forks source link

Inconsistency between C++ and Java miners. #38

Closed Rupsbant closed 6 years ago

Rupsbant commented 6 years ago

I'm seeing an inconsistency between the Java and C++ miners: In C++ the nodes are shifted by 1 bit and or'ed bit (cuckoo.h):

node_t sipnode(siphash_keys *keys, edge_t nonce, u32 uorv) {
  return _sipnode(keys, nonce, uorv) << 1 | uorv;
}

In Java they aren't (Cuckoo.java):

  // generate edge in cuckoo graph
  public int sipnode(int nonce, int uorv) {
    return (int)siphash24(2*nonce + uorv) & EDGEMASK;
  }
  // generate edge in cuckoo graph
  public Edge sipedge(int nonce) {
    return new Edge(sipnode(nonce,0), sipnode(nonce,1));
  }

Is it a trivial choice, is it by design? Am I overlooking something? The Java cycle verification is more accepting than the C++ one, though all miners produce equal results.

tromp commented 6 years ago

dear Rupsbant,

I'm seeing an inconsistency between the Java and C++ miners: In C++ the nodes are shifted by 1 bit and or'ed bit (cuckoo.h):

node_t sipnode(siphash_keys *keys, edge_t nonce, u32 uorv) { return _sipnode(keys, nonce, uorv) << 1 | uorv; }

In Java they aren't (Cuckoo.java):

They are.

// generate edge in cuckoo graph public int sipnode(int nonce, int uorv) { return (int)siphash24(2*nonce + uorv) & EDGEMASK; }

Shifting is same as doubling and adding a bit same as or-ing, i.e.: 2*nonce + uorv == (nonce << 1) | uorv

regards, -John

Rupsbant commented 6 years ago

Dear John

Thank you for the swift response. I am aware of bitshifts. I'm talking about line 48 instead of line 43 however. If you inline the C++ function _sipnode you get:

return (siphash24(keys, 2*nonce + uorv) & EDGEMASK) << 1 | uorv;

Which contains both a multiplication of the nonce but also a bitshift of the hash.

The Java function has the following:

return (int)siphash24(2*nonce + uorv) & EDGEMASK;

I see the same pattern in SimpleMiner.java at lines 46, 48 and 76. Where you use a high bit to mark the from and to node by adding/subtracting NEDGES.

However I don't see this pattern for the Java verification: 131,132

Reading more it's however clear that you mean to explicitly create a bipartite graph, something I seem to forget again and again. edit maybe it's not even a bug, us/vs probably encode a bipartite graph I seem to have found a just bug in the Java verifier.

Kind regards Rupsbant