"how numbers are stored and used in computers"
SHA-512 is a cryptographic hash function that produces a 512-bit (64-byte) hash value, typically expressed as a 128-character hexadecimal number. It is part of the SHA-2 family and is designed to provide a higher level of security than SHA-256.
The SHA-512 algorithm processes input data in 1024-bit blocks and produces a 512-bit hash value. The algorithm can be mathematically defined as:
In this definition, the input space
Padding: The input message is padded to ensure its length is congruent to 896 modulo 1024 bits. This padding process involves appending a single '1' bit to the message, followed by enough '0' bits to make the length congruent to 896 modulo 1024. Finally, a 128-bit representation of the original message length is appended to the end.
Initialization: The algorithm initializes eight 64-bit variables (a, b, c, d, e, f, g, h) with specific values. These variables are set to the following hexadecimal values:
code.js1/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */ 2const initialState = Uint32Array.from([ 3 0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1, 4 0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179, 5]);
code.js1export class SHA512 extends HashMD<SHA512> { 2 // Using an array is avoided here because it permits variable indexing, 3 // which prevents the optimizer/compiler from utilizing registers efficiently. 4 // 'h' represents the high 32 bits, and 'l' represents the low 32 bits. 5 protected Ah: number = SHA512_IV[0] | 0; 6 protected Al: number = SHA512_IV[1] | 0; 7 protected Bh: number = SHA512_IV[2] | 0; 8 protected Bl: number = SHA512_IV[3] | 0; 9 protected Ch: number = SHA512_IV[4] | 0; 10 protected Cl: number = SHA512_IV[5] | 0; 11 protected Dh: number = SHA512_IV[6] | 0; 12 protected Dl: number = SHA512_IV[7] | 0; 13 protected Eh: number = SHA512_IV[8] | 0; 14 protected El: number = SHA512_IV[9] | 0; 15 protected Fh: number = SHA512_IV[10] | 0; 16 protected Fl: number = SHA512_IV[11] | 0; 17 protected Gh: number = SHA512_IV[12] | 0; 18 protected Gl: number = SHA512_IV[13] | 0; 19 protected Hh: number = SHA512_IV[14] | 0; 20 protected Hl: number = SHA512_IV[15] | 0; 21 22 constructor(outputLen: number = 64) { 23 super(128, outputLen, 16, false); 24 } 25 // prettier-ignore 26 protected get(): [ 27 number, number, number, number, number, number, number, number, 28 number, number, number, number, number, number, number, number 29 ] { 30 const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; 31 return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl]; 32 } 33 // prettier-ignore 34 protected set( 35 Ah: number, Al: number, Bh: number, Bl: number, Ch: number, Cl: number, Dh: number, Dl: number, 36 Eh: number, El: number, Fh: number, Fl: number, Gh: number, Gl: number, Hh: number, Hl: number 37 ): void { 38 this.Ah = Ah | 0; 39 this.Al = Al | 0; 40 this.Bh = Bh | 0; 41 this.Bl = Bl | 0; 42 this.Ch = Ch | 0; 43 this.Cl = Cl | 0; 44 this.Dh = Dh | 0; 45 this.Dl = Dl | 0; 46 this.Eh = Eh | 0; 47 this.El = El | 0; 48 this.Fh = Fh | 0; 49 this.Fl = Fl | 0; 50 this.Gh = Gh | 0; 51 this.Gl = Gl | 0; 52 this.Hh = Hh | 0; 53 this.Hl = Hl | 0; 54 } 55 protected process(view: DataView, offset: number): void { 56 // Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array 57 for (let i = 0; i < 16; i++, offset += 4) { 58 SHA512_W_H[i] = view.getUint32(offset); 59 SHA512_W_L[i] = view.getUint32((offset += 4)); 60 } 61 for (let i = 16; i < 80; i++) { 62 // s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7) 63 const W15h = SHA512_W_H[i - 15] | 0; 64 const W15l = SHA512_W_L[i - 15] | 0; 65 const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7); 66 const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7); 67 // s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6) 68 const W2h = SHA512_W_H[i - 2] | 0; 69 const W2l = SHA512_W_L[i - 2] | 0; 70 const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6); 71 const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6); 72 // SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16]; 73 const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]); 74 const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]); 75 SHA512_W_H[i] = SUMh | 0; 76 SHA512_W_L[i] = SUMl | 0; 77 } 78 let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this; 79 // Compression function main loop, 80 rounds 80 for (let i = 0; i < 80; i++) { 81 // S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41) 82 const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41); 83 const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41); 84 //const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0; 85 const CHIh = (Eh & Fh) ^ (~Eh & Gh); 86 const CHIl = (El & Fl) ^ (~El & Gl); 87 // T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i] 88 // prettier-ignore 89 const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]); 90 const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]); 91 const T1l = T1ll | 0; 92 // S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39) 93 const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39); 94 const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39); 95 const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch); 96 const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl); 97 Hh = Gh | 0; 98 Hl = Gl | 0; 99 Gh = Fh | 0; 100 Gl = Fl | 0; 101 Fh = Eh | 0; 102 Fl = El | 0; 103 ({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0)); 104 Dh = Ch | 0; 105 Dl = Cl | 0; 106 Ch = Bh | 0; 107 Cl = Bl | 0; 108 Bh = Ah | 0; 109 Bl = Al | 0; 110 const All = u64.add3L(T1l, sigma0l, MAJl); 111 Ah = u64.add3H(All, T1h, sigma0h, MAJh); 112 Al = All | 0; 113 } 114 // Add the compressed chunk to the current hash value 115 ({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0)); 116 ({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0)); 117 ({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0)); 118 ({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0)); 119 ({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0)); 120 ({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0)); 121 ({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0)); 122 ({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0)); 123 this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl); 124 } 125 protected roundClean(): void { 126 clean(SHA512_W_H, SHA512_W_L); 127 } 128 destroy(): void { 129 clean(this.buffer); 130 this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 131 } 132}
SHA-512 offers strong security guarantees due to its design. It provides collision resistance with a complexity of approximately
The time complexity of the SHA-512 algorithm is
SHA-512 is used in various security-critical applications. It is commonly employed in digital signatures, where the goal is to ensure the authenticity and integrity of a document. SHA-512 is also used for file integrity verification, SSL/TLS security, password hashing (with proper salting), blockchain technology, and high-security applications requiring 512-bit hash outputs.
For an empty string, the SHA-512 hash value is cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e
. For the string "Hello, World!", the hash value is 2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b
. These examples illustrate the fixed-length output of the SHA-512 algorithm, regardless of the input size.
When implementing SHA-512, it is important to consider the algorithm's use of 64-bit words. All operations are performed on these 64-bit words, and the algorithm uses big-endian byte ordering. The output is typically represented as a 128-character hexadecimal string, which is a common format for displaying hash values. The algorithm is designed to be resistant to length extension attacks, providing an additional layer of security. However, SHA-512 requires more computational resources than SHA-256, which should be considered in resource-constrained environments.
Given the strong security guarantees of SHA-512, it is recommended for use in applications requiring the highest level of security. Always use proper salting when hashing passwords to enhance security. Consider using SHA-512 in combination with HMAC for message authentication to provide additional security. Be aware of the algorithm's performance characteristics, and consider the specific security requirements of your application. Use SHA-512 when the longer output length is acceptable and provides additional security benefits