From Wikipedia, the free encyclopedia

CubeHash[1] is a cryptographic hash function submitted to the NIST hash function competition by Daniel J. Bernstein. CubeHash has a 128 byte state, uses wide pipe construction, and is ARX based. Message blocks are XORed into the initial bits of a 128-byte state, which then goes through an r-round bijective transformation between blocks. The initial NIST proposal ("Cubehash8/1") required about 200 cycles per byte.[2] After clarifications from NIST, the author changed the proposal to Cubehash16/32, which "is approximately 16 times faster than CubeHash8/1, easily catching up to both SHA-256 and SHA-512 on the reference platform" while still maintaining a "comfortable security margin".[3]

CubeHash advanced to the second round of the competition, but was not chosen as one of the 5 finalists. Bernstein has since tuned the parameters further and his main recommendation is CubeHash512, defined as CubeHash16+16/32+32–512.[4]


This description refers to the latest specification, and not the NIST submission.[4]

CubeHash has 5 parameters, a certain instance is denoted by CubeHashi+r/b+f-h.

  • i is the number of initial rounds
  • r is the number of rounds per block
  • b is the block size in bytes, defined for {1, 2, 3, ... 128}
  • f is the number of final rounds
  • h is the size of the hash output in bits, defined for {8, 16, 24, 32, ... 512}

In the original NIST submission, i and f was fixed to 10r. The obsolete notation CubeHashr/b-h indicates i and f being implicitly 10r.

The internal state is defined as a five-dimensional array of words (four-byte integers), 0-1 in both dimensions. The words are referred to with their coordinates [00000] to [11111]. The words are treated as little-endian.

The internal state is initialized by setting the first three words ([00000], [00001], [00010]) to h/8, b, and r respectively, all other words to zero. The state is then run through i rounds, and the initialization stage is complete. The state is now the Initialization Vector (IV). The IV can be saved and reused for a given combination of h, b, r.

The message is padded and split to b-byte blocks. The padding appends a 1 bit, followed by as many 0 bits as necessary to make a complete block.

Each block is inputted by XORing to the first b bytes of the state, and then performing r rounds of transformation.

Finally, 1 is XORed to the state word [11111], and then f rounds of transformation are performed.

The output hash is now contained in the first h/8 bytes of this final state.

Round function[edit]

Illustration of mixing function
The ten steps of the mixing function. Two of the five dimensions are unrolled.

CubeHash round function consists of the following ten steps:

  1. Add x[0jklm] into x[1jklm] modulo 232, for each (j,k,l,m).
  2. Rotate x[0jklm] upwards by 7 bits, for each (j,k,l,m).
  3. Swap x[00klm] with x[01klm], for each (k,l,m).
  4. Xor x[1jklm] into x[0jklm], for each (j,k,l,m).
  5. Swap x[1jk0m] with x[1jk1m], for each (j,k,m).
  6. Add x[0jklm] into x[1jklm] modulo 232, for each (j,k,l,m).
  7. Rotate x[0jklm] upwards by 11 bits, for each (j,k,l,m).
  8. Swap x[0j0lm] with x[0j1lm], for each (j,l,m).
  9. Xor x[1jklm] into x[0jklm], for each (j,k,l,m).
  10. Swap x[1jkl0] with x[1jkl1], for each (j,k,l).

Example hashes[edit]

This example uses CubeHash80+8/1+80-512. The initialization vector is the same for all 80+8/1+f-512 hashes, and is as follows:


Hashing the ASCII message "Hello" (hex: 0x48, 0x65, 0x6c, 0x6c, 0x6f) uses 6 message blocks. There are 5 blocks from the message, and since this is a byte-aligned input, there is 1 block for padding. The 512 bit hash value is:


A small change in the message, such as flipping a single bit, will wildly change the hash output, due to the avalanche effect. Hashing the message "hello" (which only differs from "Hello" in 1 bit position) gives the following hash value:


Parameter changes[edit]

CubeHash allows for many different parameters to be used to determine the hash output. It is up to the user to decide which parameters they wish to use. Here are several example hashes of different messages, using different parameters. The messages are all in ASCII.

message: ""  (the zero-length string)
CubeHash160+16/32+160-512: 4a1d00bbcfcb5a9562fb981e7f7db3350fe2658639d948b9d57452c22328bb32\

CubeHash80+8/1+80-512: 90bc3f2948f7374065a811f1e47a208a53b1a2f3be1c0072759ed49c9c6c7f28\

CubeHash10+1/1+10-512: 3f917707df9acd9b94244681b3812880e267d204f1fdf795d398799b584fa8f1\

CubeHash160+16/32+160-256: 44c6de3ac6c73c391bf0906cb7482600ec06b216c7c54a2a8688a6a42676577d

CubeHash80+8/1+80-256: 38d1e8a22d7baac6fd5262d83de89cacf784a02caa866335299987722aeabc59

CubeHash10+1/1+10-256: 80f72e07d04ddadb44a78823e0af2ea9f72ef3bf366fd773aa1fa33fc030e5cb
message: "Hello"
CubeHash160+16/32+160-512: dcc0503aae279a3c8c95fa1181d37c418783204e2e3048a081392fd61bace883\

CubeHash80+8/1+80-512: 7ce309a25e2e1603ca0fc369267b4d43f0b1b744ac45d6213ca08e7567566444\

CubeHash10+1/1+10-512: 13cf99c1a71e40b135f5535bee02e151eb4897e4de410b9cb6d7179c677074eb\

CubeHash160+16/32+160-256: e712139e3b892f2f5fe52d0f30d78a0cb16b51b217da0e4acb103dd0856f2db0

CubeHash80+8/1+80-256: 692638db57760867326f851bd2376533f37b640bd47a0ddc607a9456b692f70f

CubeHash10+1/1+10-256: f63041a946aa98bd47f3175e6009dcb2ccf597b2718617ba46d56f27ffe35d49
message: "The quick brown fox jumps over the lazy dog"
CubeHash160+16/32+160-512: bdba44a28cd16b774bdf3c9511def1a2baf39d4ef98b92c27cf5e37beb8990b7\

CubeHash80+8/1+80-512: ca942b088ed9103726af1fa87b4deb59e50cf3b5c6dcfbcebf5bba22fb39a6be\

CubeHash10+1/1+10-512: eb7f5f80706e8668c61186c3c710ce57f9094fbfa1dbdc7554842cdbb4d10ce4\

CubeHash160+16/32+160-256: 5151e251e348cbbfee46538651c06b138b10eeb71cf6ea6054d7ca5fec82eb79

CubeHash80+8/1+80-256: 94e0c958d85cdfaf554919980f0f50b945b88ad08413e0762d6ff0219aff3e55

CubeHash10+1/1+10-256: 217a4876f2b24cec489c9171f85d53395cc979156ea0254938c4c2c59dfdf8a4

The Initialization Vectors for the four variants shown are all different as well. For example, the Initialization Vector for CubeHash80+8/1+80-512 can be seen above, and the IV for CubeHash80+8/1+80-256 is:



The strength of this function increases as b decreases towards 1, and as r increases. So CubeHash 8/1-512 is stronger (more secure) than CubeHash 1/1-512, and CubeHash 1/1-512 is stronger than CubeHash 1/2-512. The weakest possible version of this algorithm is CubeHash 1/128-h. However, there is a security versus time tradeoff. A more secure version will take longer to compute a hash value than a weakened version.


  1. ^ Daniel J. Bernstein (2009-09-14). "CubeHash specification (2.B.1)" (PDF).
  2. ^ Daniel J. Bernstein (2008-10-28). "CubeHash efficiency estimates (2.B.2)" (PDF).
  3. ^ Daniel J. Bernstein (2009-07-15). "CubeHash parameter tweak: 16 times faster" (PDF).
  4. ^ a b Daniel J. Bernstein. "Introduction to CubeHash".

External links[edit]