Analysis of VMAC with N=17 rounds --- Message Schedule: KeyIndex = [ 0, 1, 2, 3, 4, 5, 6, 7, 3, 4, 5, 6, 7, 1, 2, 0] t = 0:15 ki = KeyIndex[t] W[t] = Data[t] XOR ROTR( Key[ki], 3*ki+(t>>3)) t > 15 ki = (63-t)%8 W[t] = (sigma1(W[t-2]) + W[t-7] + sigma0(W[t-15]) + W[t-16]) XOR ROTR( Key[ki], 3*ki+(t>>3)) --- W[16] = ( sigma1( Data[14] XOR ROTR( Key[2], 7) ) + Data[9] XOR ROTR( Key[4], 13) + sigma0( Data[1] XOR ROTR( Key[1], 3) ) + Data[0] XOR ROTR( Key[0], 0) ) XOR ROTR( Key[7], 23) --- See Crack17-bits.txt for bitwise analysis, and Crack17-raw.txt for raw VMAC-DATA.py output --- V = T1 - offset = h + W[16] = h + (((D XOR E) + X) XOR Y) where D = sigma1(Data[14]), E = sigma1(ROTR(Key[2],7)), Y = ROTR(Key[7],23) and X = sum of the Data[9,1,0] and Key[4,1,0] terms If we can determine h then we could unwind the hash one more stage and find all of the key bits using the method presented in the Crack16.py notes. Data[9,1,0] affect h and X, but changes in D do not change h, E, X, or Y, so flipping bit i of D will flip bit i of V. Although the change in bit i provides no information itself, the addition with X may flip carry bits, and bit i+1 of ((D XOR E) + X) will change only if bit i of X is 1. However we can only observe V, and the addition with h may also flip carry bits. So if bit i+1 of V changes then bit i of either h or X is 1, but we don't know which. --- To continue without knowing h, we could run Crack16 for each of the possible 2^32 values of h. Each of those produces 2^8 candidate keys so the overall search space is O(2^40). For each value of h, Crack16 invokes VMAC twice for each of 256-8 = 248 bits, that is 2*248 = 496 invocations. At a scan rate of 100msec, i.e. 10 invocations per second, that would take over 6000 years: 496 * ((2^32)/10) / (60*60*24*365) = 6755.1 Extrapolating to N=20 rounds, there would be 4 unknown h values associated with each candidate key, so the overall search space is 2^8*(2^32)^4 = O(2^136).