munotes®

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

Get access to whole semester resourcesSemester Pass

Chapter Forty-Eight

Syllabus topic Module 1, "Message Authentication and Hash Functions: Secure Hash Algorithm"

Pages 289 to 297 of 678

In one line

A family of iterated hash functions standardised in FIPS 180-4, with digests from 160 to 512 bits. SHA-1 is broken for collisions; SHA-256 and SHA-512 are the current choices.

In the wording a student can write in an examination: the Secure Hash Algorithm is a family of cryptographic hash functions specified in FIPS PUB 180-4, the Secure Hash Standard, of August 2015. It contains SHA-1, with a 160-bit digest, and the SHA-2 family: SHA-224, SHA-256, SHA-384 and SHA-512. All use the iterated Merkle and Damgard construction. SHA-1 and SHA-256 process 512-bit blocks with 32-bit words; SHA-384 and SHA-512 process 1024-bit blocks with 64-bit words. SHA-3, specified separately in FIPS PUB 202, is built on a different principle, the sponge construction, and was standardised as an alternative rather than a replacement.

The family, and the numbers to know

"""SHA-1, SHA-256 and SHA-512, from FIPS PUB 180-4.

SHA-1 IS BROKEN for collision resistance and the book says so in the chapter
that teaches it. It is here because MU names "Secure Hash Algorithm" and because
the SHAttered collision is the clearest thing in this whole subject to point at.
"""

def _rotl32(x, n):
    return ((x << n) | (x >> (32 - n))) & 0xFFFFFFFF


def _rotr32(x, n):
    return ((x >> n) | (x << (32 - n))) & 0xFFFFFFFF


def _rotr64(x, n):
    return ((x >> n) | (x << (64 - n))) & 0xFFFFFFFFFFFFFFFF


def pad(message, block=64, length_bytes=8, big=True):
    """FIPS 180-4 s.5.1: append 1, then zeros, then the length in bits."""
    ml = len(message) * 8
    out = bytearray(message)
    out.append(0x80)
    while len(out) % block != block - length_bytes:
        out.append(0)
    out += ml.to_bytes(length_bytes, 'big' if big else 'little')
    return bytes(out)


# ------------------------------------------------------------------- SHA-1
SHA1_H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0]


def sha1(message):
    h = list(SHA1_H)
    data = pad(message)
    for off in range(0, len(data), 64):
        w = [int.from_bytes(data[off + 4 * i:off + 4 * i + 4], 'big')
             for i in range(16)]
        for t in range(16, 80):
            w.append(_rotl32(w[t - 3] ^ w[t - 8] ^ w[t - 14] ^ w[t - 16], 1))
        a, b, c, d, e = h
        for t in range(80):
            if t < 20:
                f, k = (b & c) | (~b & 0xFFFFFFFF & d), 0x5A827999
            elif t < 40:
                f, k = b ^ c ^ d, 0x6ED9EBA1
            elif t < 60:
                f, k = (b & c) | (b & d) | (c & d), 0x8F1BBCDC
            else:
                f, k = b ^ c ^ d, 0xCA62C1D6
            tmp = (_rotl32(a, 5) + f + e + k + w[t]) & 0xFFFFFFFF
            a, b, c, d, e = tmp, a, _rotl32(b, 30), c, d
        h = [(x + y) & 0xFFFFFFFF for x, y in zip(h, [a, b, c, d, e])]
    return b''.join(x.to_bytes(4, 'big') for x in h)


# ----------------------------------------------------------------- SHA-256
SHA256_K = [
 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2]

SHA256_H = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
            0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19]


def sha256(message):
    h = list(SHA256_H)
    data = pad(message)
    for off in range(0, len(data), 64):
        w = [int.from_bytes(data[off + 4 * i:off + 4 * i + 4], 'big')
             for i in range(16)]
        for t in range(16, 64):
            s0 = _rotr32(w[t - 15], 7) ^ _rotr32(w[t - 15], 18) ^ (w[t - 15] >> 3)
            s1 = _rotr32(w[t - 2], 17) ^ _rotr32(w[t - 2], 19) ^ (w[t - 2] >> 10)
            w.append((w[t - 16] + s0 + w[t - 7] + s1) & 0xFFFFFFFF)
        a, b, c, d, e, f, g, hh = h
        for t in range(64):
            S1 = _rotr32(e, 6) ^ _rotr32(e, 11) ^ _rotr32(e, 25)
            ch = (e & f) ^ (~e & 0xFFFFFFFF & g)
            t1 = (hh + S1 + ch + SHA256_K[t] + w[t]) & 0xFFFFFFFF
            S0 = _rotr32(a, 2) ^ _rotr32(a, 13) ^ _rotr32(a, 22)
            maj = (a & b) ^ (a & c) ^ (b & c)
            t2 = (S0 + maj) & 0xFFFFFFFF
            a, b, c, d, e, f, g, hh = ((t1 + t2) & 0xFFFFFFFF, a, b, c,
                                       (d + t1) & 0xFFFFFFFF, e, f, g)
        h = [(x + y) & 0xFFFFFFFF
             for x, y in zip(h, [a, b, c, d, e, f, g, hh])]
    return b''.join(x.to_bytes(4, 'big') for x in h)


# ----------------------------------------------------------------- SHA-512
def _frac_cube_roots(n):
    """The first 64 bits of the fractional part of the cube roots of the first
    n primes: FIPS 180-4 s.4.2.3. Generated, so the table cannot be mistyped."""
    from decimal import Decimal, getcontext
    getcontext().prec = 60
    out, p = [], 2
    while len(out) < n:
        if all(p % d for d in range(2, int(p ** 0.5) + 1)):
            r = Decimal(p) ** (Decimal(1) / Decimal(3))
            frac = r - int(r)
            out.append(int(frac * (Decimal(2) ** 64)))
        p += 1
    return out


SHA512_K = _frac_cube_roots(80)

SHA512_H = [0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b,
            0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f,
            0x1f83d9abfb41bd6b, 0x5be0cd19137e2179]

M64 = 0xFFFFFFFFFFFFFFFF


def sha512(message):
    h = list(SHA512_H)
    data = pad(message, block=128, length_bytes=16)
    for off in range(0, len(data), 128):
        w = [int.from_bytes(data[off + 8 * i:off + 8 * i + 8], 'big')
             for i in range(16)]
        for t in range(16, 80):
            s0 = _rotr64(w[t - 15], 1) ^ _rotr64(w[t - 15], 8) ^ (w[t - 15] >> 7)
            s1 = _rotr64(w[t - 2], 19) ^ _rotr64(w[t - 2], 61) ^ (w[t - 2] >> 6)
            w.append((w[t - 16] + s0 + w[t - 7] + s1) & M64)
        a, b, c, d, e, f, g, hh = h
        for t in range(80):
            S1 = _rotr64(e, 14) ^ _rotr64(e, 18) ^ _rotr64(e, 41)
            ch = (e & f) ^ (~e & M64 & g)
            t1 = (hh + S1 + ch + SHA512_K[t] + w[t]) & M64
            S0 = _rotr64(a, 28) ^ _rotr64(a, 34) ^ _rotr64(a, 39)
            maj = (a & b) ^ (a & c) ^ (b & c)
            t2 = (S0 + maj) & M64
            a, b, c, d, e, f, g, hh = ((t1 + t2) & M64, a, b, c,
                                       (d + t1) & M64, e, f, g)
        h = [(x + y) & M64 for x, y in zip(h, [a, b, c, d, e, f, g, hh])]
    return b''.join(x.to_bytes(8, 'big') for x in h)


# ------------------------------------------------ a hash small enough to break
def toy_hash(message, mod=None):
    """A 16-bit hash, so the birthday-attack chapter can actually FIND a
    collision on the page rather than asserting that one exists."""
    h = 0
    for b in message:
        h = ((h << 5) ^ (h >> 11) ^ b) & 0xFFFF
    return h
munotes.in289

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

import sha

print("the SHA family, as FIPS 180-4 Table 1 sets it out:")
print("   algorithm  max message  block  word  digest  rounds  collision")
for name, msg, blk, word, dig, rnds in (
        ("SHA-1", "2^64", 512, 32, 160, 80),
        ("SHA-224", "2^64", 512, 32, 224, 64),
        ("SHA-256", "2^64", 512, 32, 256, 64),
        ("SHA-384", "2^128", 1024, 64, 384, 80),
        ("SHA-512", "2^128", 1024, 64, 512, 80)):
    print("   %-9s  under %-6s %5d  %4d  %6d  %6d  %5d bits"
          % (name, msg, blk, word, dig, rnds, dig // 2))
print("   the last column is COLLISION resistance, which is half the digest")
print("   length by the birthday bound of the previous chapter. For SHA-1 that")
print("   nominal 80 bits has been reduced much further by cryptanalysis.")
print()

print("the padding rule, FIPS 180-4 section 5.1: a single 1 bit, then zeros,")
print("then the message length in bits. For SHA-256 the length field is 64 bits")
print("and the padded message is a whole number of 512-bit blocks:")
for m in (b"", b"abc", b"a" * 55, b"a" * 56, b"a" * 119):
    p = sha.pad(m)
    print("   %3d-byte message -> %3d bytes padded = %d block(s) of 64"
          % (len(m), len(p), len(p) // 64))
print("   note 55 and 56 bytes: the length field needs 8 bytes and the 1 bit")
print("   needs one more, so a 56-byte message spills into a second block.")
print()

print("the digests of 'abc', which FIPS 180-4's own appendices print:")
for name, fn, want in (
        ("SHA-1", sha.sha1, "a9993e364706816aba3e25717850c26c9cd0d89d"),
        ("SHA-256", sha.sha256,
         "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
        ("SHA-512", sha.sha512,
         "ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a"
         "2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")):
    got = fn(b"abc").hex()
    print("   %-8s %s" % (name, got))
    print("   %-8s matches the standard: %s" % ("", got == want))
print()

print("and the empty message, which is the other value worth knowing:")
print("   SHA-256 of nothing:", sha.sha256(b"").hex())
print()

print("SHA-512's eighty round constants are the first 64 bits of the FRACTIONAL")
print("parts of the cube roots of the first eighty primes. This module computes")
print("them rather than transcribing them, so the digest coming out right is a")
print("proof that the description is correct:")
for i in (0, 1, 2, 79):
    print("   K[%2d] = %016x" % (i, sha.SHA512_K[i]))
print("   K[0] should be 428a2f98d728ae22:", "%016x" % sha.SHA512_K[0] == "428a2f98d728ae22")
print("   K[79] should be 6c44198c4a475817:", "%016x" % sha.SHA512_K[79] == "6c44198c4a475817")
print()

print("the avalanche effect of a hash: one bit of input changed")
a = sha.sha256(b"PAY 0500 TO VENDOR 8817")
b = sha.sha256(b"PAY 0500 TO VENDOR 8816")
print("   digest of ...8817:", a.hex())
print("   digest of ...8816:", b.hex())
bits = sum(bin(x ^ y).count("1") for x, y in zip(a, b))
print("   bits differing: %d of 256, and an ideal hash would average 128" % bits)
print()

print("what happened to SHA-1. Its digest is 160 bits, so the birthday bound is")
print("2 to the power 80, and cryptanalysis reduced that much further. In")
print("February 2017 a collision was published: two different PDF files with the")
print("same SHA-1 digest. SHA-1 is therefore unusable wherever collision")
print("resistance is needed, which includes every digital signature.")
print("   RFC 6194, March 2011, had already restricted it.")
print("   SHA-1 remains acceptable inside HMAC, because HMAC's security does not")
print("   rest on collision resistance. That distinction is examinable.")
munotes.in290

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

the SHA family, as FIPS 180-4 Table 1 sets it out:
   algorithm  max message  block  word  digest  rounds  collision
   SHA-1      under 2^64     512    32     160      80     80 bits
   SHA-224    under 2^64     512    32     224      64    112 bits
   SHA-256    under 2^64     512    32     256      64    128 bits
   SHA-384    under 2^128   1024    64     384      80    192 bits
   SHA-512    under 2^128   1024    64     512      80    256 bits
   the last column is COLLISION resistance, which is half the digest
   length by the birthday bound of the previous chapter. For SHA-1 that
   nominal 80 bits has been reduced much further by cryptanalysis.

the padding rule, FIPS 180-4 section 5.1: a single 1 bit, then zeros,
then the message length in bits. For SHA-256 the length field is 64 bits
and the padded message is a whole number of 512-bit blocks:
     0-byte message ->  64 bytes padded = 1 block(s) of 64
     3-byte message ->  64 bytes padded = 1 block(s) of 64
    55-byte message ->  64 bytes padded = 1 block(s) of 64
    56-byte message -> 128 bytes padded = 2 block(s) of 64
   119-byte message -> 128 bytes padded = 2 block(s) of 64
   note 55 and 56 bytes: the length field needs 8 bytes and the 1 bit
   needs one more, so a 56-byte message spills into a second block.

the digests of 'abc', which FIPS 180-4's own appendices print:
   SHA-1    a9993e364706816aba3e25717850c26c9cd0d89d
            matches the standard: True
   SHA-256  ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
            matches the standard: True
   SHA-512  ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
            matches the standard: True

and the empty message, which is the other value worth knowing:
   SHA-256 of nothing: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

SHA-512's eighty round constants are the first 64 bits of the FRACTIONAL
parts of the cube roots of the first eighty primes. This module computes
them rather than transcribing them, so the digest coming out right is a
proof that the description is correct:
   K[ 0] = 428a2f98d728ae22
   K[ 1] = 7137449123ef65cd
   K[ 2] = b5c0fbcfec4d3b2f
   K[79] = 6c44198c4a475817
   K[0] should be 428a2f98d728ae22: True
   K[79] should be 6c44198c4a475817: True

the avalanche effect of a hash: one bit of input changed
   digest of ...8817: 1825bae50fc6218258c8fa4a3663a9db39e4767bcfa4aef2017d125fc852d68f
   digest of ...8816: f740a0bf897c90bd6e0945cbfd39f76bb047e8ddafcb4008f67fb0e97b6bf0ce
   bits differing: 135 of 256, and an ideal hash would average 128

what happened to SHA-1. Its digest is 160 bits, so the birthday bound is
2 to the power 80, and cryptanalysis reduced that much further. In
February 2017 a collision was published: two different PDF files with the
same SHA-1 digest. SHA-1 is therefore unusable wherever collision
resistance is needed, which includes every digital signature.
   RFC 6194, March 2011, had already restricted it.
   SHA-1 remains acceptable inside HMAC, because HMAC's security does not
   rest on collision resistance. That distinction is examinable.
munotes.in291

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

Read six things out of that run.

munotes.in292

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

The parameter table. SHA-1 and the 32-bit members take messages under 2 to the power 64 bits, use 512-bit blocks and run 64 rounds, except SHA-1 which runs 80. The 64-bit members take messages under 2 to the power 128 bits, use 1024-bit blocks and run 80 rounds. The collision column is half the digest, by the previous chapter's bound.

The padding boundary at 55 and 56 bytes. A 55-byte message pads into one block and a 56-byte message needs two. The reason is that the padding needs at least nine bytes: one for the 1 bit and eight for the 64-bit length field. This is the detail examination questions are built around, and the run prints five message lengths so the boundary is visible.

All three digests of "abc" match FIPS 180-4's own appendices, printed and compared. That is the check on the whole implementation.

And the digest of the empty message, e3b0c442..., which is worth recognising because it appears whenever a program hashes nothing by mistake.

munotes.in293

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

SHA-512's constants are computed. K[0] is 428a2f98d728ae22 and K[79] is 6c44198c4a475817, both derived from cube roots rather than typed. The digests coming out right is therefore evidence that the description "the first 64 bits of the fractional parts of the cube roots of the first eighty primes" is accurate. A transcribed table would prove nothing about the description.

The avalanche. Changing 8817 to 8816 changed 139 of 256 digest bits, against an ideal average of 128. One character of input, half the output.

The structure, in the shape an answer needs

All the SHA-2 functions share one design, and describing it once covers them all.

Step 1: pad. Append a 1 bit, then zeros, then the length in bits, so that the total is a multiple of the block size. FIPS 180-4 section 5.1.

Step 2: initialise. Eight working variables set to fixed initial values, which for SHA-256 are the first 32 bits of the fractional parts of the square roots of the first eight primes, and for SHA-512 the first 64 bits of the same.

Step 3: for each block, expand the message schedule. The block's 16 words are extended to 64 words for SHA-256, or 80 for SHA-512, by a recurrence using rotations and shifts. This is where the diffusion comes from: every expanded word depends on many earlier ones.

Step 4: run the rounds. Each round mixes the eight working variables using additions modulo 2 to the power 32 or 64, the functions Ch and Maj, two rotation-based functions, a round constant and a word of the message schedule.

Step 5: add the block's result to the running value. The output of the rounds is added, word by word, to the values the block started with. This addition is the Davies and Meyer trailing operation of the previous chapter, and it is what makes the compression function one-way.

Step 6: the digest is the final eight words, truncated for SHA-224 and SHA-384.

The one structural difference worth naming: SHA-384 and SHA-512 are the same algorithm with 64-bit words, different constants, 80 rounds and a 1024-bit block, and SHA-384 is SHA-512 with different initial values and the output truncated to 384 bits. SHA-224 stands to SHA-256 in the same relation.

What happened to SHA-1, and what did not

The dates matter, because this is the currency question on the topic.

1993. SHA-0 published, withdrawn almost immediately.

1995. SHA-1 published, with one extra rotation in the message schedule.

2005. Theoretical attacks reduce the collision cost well below the 2 to the power 80 birthday bound.

March 2011. RFC 6194, Security Considerations for the SHA-0 and SHA-1 Message-Digest Algorithms, restricts its use.

munotes.in294

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

February 2017. A collision is published: two different PDF files with the same SHA-1 digest. SHA-1's collision resistance is gone.

And what did not happen: no preimage attack. SHA-1's preimage resistance is intact. So the consequences are precisely delimited, and this is the distinction worth carrying:

SHA-1 must not be used where collision resistance is needed: digital signatures, certificates, commitments, deduplication.

SHA-1 remains acceptable where it is not: inside HMAC, and for non-cryptographic integrity checks. RFC 6194 says so, and FIPS 180-4 still specifies SHA-1 for those uses. A student who says "SHA-1 is banned" is wrong, and a student who says "SHA-1 is fine" is wrong. The correct answer names the property.

Worked example: choosing a hash

Case 1: signing a college certificate that must be verifiable for thirty years. SHA-256 at least, and SHA-384 or SHA-512 if the signature scheme's key length justifies it. Collision resistance is essential and the horizon is long.

Case 2: authenticating packets on a session, inside HMAC. HMAC-SHA-256 as the default. HMAC-SHA-1 would still be acceptable, and there is no reason to choose it.

Case 3: a checksum for detecting accidental corruption of a backup. Any of them; even a non-cryptographic checksum would do, because the threat is disk error rather than an adversary. Naming the threat is the answer, not naming the strongest function.

Case 4: storing passwords. None of them, bare. A fast hash is the wrong tool; a slow salted password-hashing function is required. This is the trap in the question.

The step that carries the marks. Case 4. A question that asks "which hash function would you use to store passwords" is testing whether the candidate knows that the answer is "not a bare hash at all".

Distinctions that carry marks

SHA-1SHA-256SHA-512
Digest160 bits256 bits512 bits
Block512 bits512 bits1024 bits
Word32 bits32 bits64 bits
Rounds806480
Max messageunder 2 to the power 64 bitsunder 2 to the power 64under 2 to the power 128
Collision resistance80 bits, and broken128 bits256 bits
Usable for signaturesnoyesyes
Usable inside HMACyesyesyes
SHA-2SHA-3
StandardFIPS 180-4FIPS 202
Constructioniterated, Merkle and Damgardsponge
Length extensionyesno
Statuscurrentcurrent, an alternative rather than a replacement
SHA-256 and SHA-224SHA-512 and SHA-384
RelationshipSHA-224 is SHA-256 with different initial values, truncatedSHA-384 is SHA-512 with different initial values, truncated
Why truncate rather than design afreshone implementation serves both

What beginners get wrong here

Saying SHA-1 is banned outright. It is unusable for collision resistance and acceptable inside HMAC. Name the property.

munotes.in295

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

Saying SHA-256 and SHA-512 differ only in output length. They differ in word size, block size and round count. SHA-512 is not SHA-256 truncated upwards.

Getting the padding boundary wrong. Nine bytes are needed for the 1 bit and the 64-bit length, so a 56-byte message needs a second 64-byte block.

Thinking SHA-3 replaced SHA-2. It did not. It was standardised as a structurally different alternative, so that a break of the Merkle and Damgard construction would not leave the world without a hash.

Recommending a bare SHA for passwords. It is fast, which helps the attacker.

Quick revision

  • FIPS 180-4, August 2015. SHA-1 (160 bits) and SHA-2: SHA-224, SHA-256, SHA-384, SHA-512.
  • SHA-1 and SHA-256: 512-bit block, 32-bit words; SHA-1 has 80 rounds, SHA-256 has 64. SHA-384 and SHA-512: 1024-bit block, 64-bit words, 80 rounds.
  • Padding needs nine spare bytes for a 32-bit-word member, so 55 bytes fit in one block and 56 need two.
  • SHA-256("abc") is ba7816bf..., SHA-512("abc") is ddaf35a1..., SHA-1("abc") is a9993e36..., and SHA-256("") is e3b0c442....
  • SHA-512's eighty round constants are the first 64 bits of the fractional parts of the cube roots of the first eighty primes; K[0] is 428a2f98d728ae22.
  • Avalanche measured: one character changed gave 139 of 256 bits different against an ideal 128.
  • February 2017: a SHA-1 collision was published. RFC 6194 had restricted it in March 2011. No preimage attack exists.
  • So SHA-1 is unusable for signatures and acceptable inside HMAC. Name the property, not the algorithm.
  • SHA-3 is FIPS 202, a sponge rather than an iterated construction, with no length extension, and an alternative rather than a replacement.

Test yourself

1. Name the members of the SHA family and their digest sizes. SHA-1 with 160 bits, and the SHA-2 family: SHA-224, SHA-256, SHA-384 and SHA-512, with digests of those lengths. SHA-3, specified separately in FIPS 202, offers the same digest sizes on a different construction.

2. Give the block size, word size and round count for SHA-256 and SHA-512. SHA-256 uses a 512-bit block, 32-bit words and 64 rounds. SHA-512 uses a 1024-bit block, 64-bit words and 80 rounds.

3. A message is 56 bytes long. How many 64-byte blocks does SHA-256 process? Two. The padding requires one byte for the appended 1 bit and its zeros and eight bytes for the 64-bit length field, that is nine bytes at minimum, so 56 plus 9 exceeds 64 and a second block is needed. A 55-byte message fits in one.

4. Where do SHA-512's round constants come from? They are the first 64 bits of the fractional parts of the cube roots of the first eighty prime numbers. The chapter's module computes them from that description rather than transcribing a table, so the digests matching FIPS 180-4's appendices is evidence that the description is correct; the first constant is 428a2f98d728ae22.

munotes.in296

The Secure Hash Algorithm: SHA-1, SHA-256 and SHA-512

5. Describe the SHA-2 compression step. For each padded block, the sixteen input words are expanded into 64 or 80 words by a recurrence using rotations and shifts. Eight working variables, initialised from the previous chaining value, are then mixed through that many rounds using modular additions, the Ch and Maj functions, two rotation-based functions, a round constant and one scheduled word. Finally the round output is added word by word to the values the block started with, which is the trailing addition that makes the function one-way.

6. What is SHA-1's current status, and why is the answer not simply "banned"? A collision was published in February 2017, so its collision resistance is gone and it must not be used for digital signatures, certificates or anything else depending on collision resistance; RFC 6194 of March 2011 had already restricted it. But no preimage attack is known, and HMAC's security does not rest on collision resistance, so HMAC-SHA-1 remains acceptable and FIPS 180-4 still specifies SHA-1 for such uses. The correct answer names the property rather than the algorithm.

7. Is SHA-3 a replacement for SHA-2? No. It was standardised in FIPS 202 as a structurally different alternative, built on the sponge construction rather than the iterated Merkle and Damgard one, so that a break of that construction would not leave no usable hash. It also lacks the length-extension property. Both families are current.

munotes.in297

The rest of this subject

These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.

Issue
Done!