1
$\begingroup$

Wikipedia reports:

A 2011 attack breaks preimage resistance for [...] 52 out of 64 rounds for SHA-256. Pseudo-collision attack against up to 46 rounds of SHA-256.

I am having trouble determining/understanding whether the "Message Expansion" of SHA-256 is the one reduced (splitting the 512-bit message block into 16 words, and expanding them into 64 expanded message words), or the "State Update Transformation" is the one reduced (starting from the previous 256-bit chaining value, which is updated by applying the step functions 64 times).

I have the feeling that both are reduced, but I am not sure...

$\endgroup$
  • $\begingroup$ I don't see how you can reduce the message expansion, let alone by a number of rounds as message expansion is only performed once, not in a number of rounds. $\endgroup$ – Maarten Bodewes Nov 21 '17 at 18:25
1
$\begingroup$

Taken from the OpenBSD implementation of the SHA-2 family at their CVS, where the function SHA256Transform() is used to apply a number of rounds to each block of input. It splits this into the first 16 rounds, and then the remaining ones. A reduced-round implementation of SHA-256 would simply have fewer rounds. This makes the hash significantly weaker.

The transform function:

void
SHA256Transform(u_int32_t *state, const u_int8_t *data)
{
    u_int32_t   a, b, c, d, e, f, g, h, s0, s1;
    u_int32_t   T1, W256[16];
    int     j;

    /* Initialize registers with the prev. intermediate value */
    a = state[0];
    b = state[1];
    c = state[2];
    d = state[3];
    e = state[4];
    f = state[5];
    g = state[6];
    h = state[7];

    j = 0;
    do {
        /* Rounds 0 to 15 (unrolled): */
        ROUND256_0_TO_15(a,b,c,d,e,f,g,h);
        ROUND256_0_TO_15(h,a,b,c,d,e,f,g);
        ROUND256_0_TO_15(g,h,a,b,c,d,e,f);
        ROUND256_0_TO_15(f,g,h,a,b,c,d,e);
        ROUND256_0_TO_15(e,f,g,h,a,b,c,d);
        ROUND256_0_TO_15(d,e,f,g,h,a,b,c);
        ROUND256_0_TO_15(c,d,e,f,g,h,a,b);
        ROUND256_0_TO_15(b,c,d,e,f,g,h,a);
    } while (j < 16);

    /* Now for the remaining rounds to 64: */
    do {
        ROUND256(a,b,c,d,e,f,g,h);
        ROUND256(h,a,b,c,d,e,f,g);
        ROUND256(g,h,a,b,c,d,e,f);
        ROUND256(f,g,h,a,b,c,d,e);
        ROUND256(e,f,g,h,a,b,c,d);
        ROUND256(d,e,f,g,h,a,b,c);
        ROUND256(c,d,e,f,g,h,a,b);
        ROUND256(b,c,d,e,f,g,h,a);
    } while (j < 64);

    /* Compute the current intermediate hash value */
    state[0] += a;
    state[1] += b;
    state[2] += c;
    state[3] += d;
    state[4] += e;
    state[5] += f;
    state[6] += g;
    state[7] += h;

    /* Clean up */
    a = b = c = d = e = f = g = h = T1 = 0;
}

The round macros are declared as follows:

/* Unrolled SHA-256 round macros: */

#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) do {                  \
    W256[j] = (u_int32_t)data[3] | ((u_int32_t)data[2] << 8) |      \
        ((u_int32_t)data[1] << 16) | ((u_int32_t)data[0] << 24);        \
    data += 4;                              \
    T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] + W256[j]; \
    (d) += T1;                              \
    (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));            \
    j++;                                    \
} while(0)

#define ROUND256(a,b,c,d,e,f,g,h) do {                      \
    s0 = W256[(j+1)&0x0f];                          \
    s0 = sigma0_256(s0);                            \
    s1 = W256[(j+14)&0x0f];                         \
    s1 = sigma1_256(s1);                            \
    T1 = (h) + Sigma1_256((e)) + Ch((e), (f), (g)) + K256[j] +      \
         (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);          \
    (d) += T1;                              \
    (h) = T1 + Sigma0_256((a)) + Maj((a), (b), (c));            \
    j++;                                    \
} while(0)
| improve this answer | |
$\endgroup$

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.