4

In a sample ERC721 contract linked from a loom-network medium post, I saw this code:

bytes4 constant InterfaceSignature_ERC721 =
    bytes4(keccak256('name()')) ^
    bytes4(keccak256('symbol()')) ^
    bytes4(keccak256('totalSupply()')) ^
    bytes4(keccak256('balanceOf(address)')) ^
    bytes4(keccak256('ownerOf(uint256)')) ^
    bytes4(keccak256('approve(address,uint256)')) ^
    bytes4(keccak256('transfer(address,uint256)')) ^
    bytes4(keccak256('transferFrom(address,address,uint256)')) ^
    bytes4(keccak256('tokensOfOwner(address)')) ^
    bytes4(keccak256('tokenMetadata(uint256,string)'));

Why is the bitwise XOR (^) operation used to join these values together?

I understand this is a cheap and efficient way to "mix" all of these hashes together, but I'm not sure if this is "safe" in terms of collisions and other weirdness, is this standard practice or just a simple hack to arrive at a probably-safe "unique" signature?

Code source: Line 481 on https://ethfiddle.com/09YbyJRfiI

fafrd
  • 354
  • 3
  • 8
bee
  • 55
  • 3

2 Answers2

3

Please see Standard Interface Detection in ERC-165. (I'm an author on that.)

https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md

The definition is:

We define the interface identifier as the XOR of all function selectors in the interface.

William Entriken
  • 4,690
  • 15
  • 42
  • Thanks! This is not a danger in any way to have a collision or something like that? – bee Mar 08 '18 at 14:41
  • There WILL be collisions eventually for sure. This is a known problem which standards writers will address when it actually comes up. – William Entriken Mar 08 '18 at 23:13
  • Correction: the actual contract authors will address the problem, the standards writers will merely document the solutions ex post facto :-). I'm getting involved with https://ethereum-magicians.org so I should be more careful when talking about this stuff :-). – William Entriken Mar 22 '18 at 06:29
2

I'm not sure this is a probably-secure method, but after googling around a while, it seems XOR is generally considered "good enough".

This stackoverflow answer has a lot of discussion on the topic: https://stackoverflow.com/questions/5889238/why-is-xor-the-default-way-to-combine-hashes

I'd really like to read an academic paper on strategies for combining hashes, if someone can find one.

fafrd
  • 354
  • 3
  • 8
  • 1
    hash(json(stuff)) is how you actually combine hashes. In other words, you hash combines rather than combining hashes. – William Entriken Mar 22 '18 at 06:25
  • Any XOR combination of hashes will be vulnerable to a quadratic field sieve attack. This was well known when designing ERC-165 (which is the signature technique shown in the question). – William Entriken Mar 22 '18 at 06:26