Jump to content

Talk:SHA-2

Page contents not supported in other languages.
From Wikipedia, the free encyclopedia

This is an old revision of this page, as edited by 107.1.64.82 (talk) at 19:26, 24 February 2014 (Picture of data flow is flawed.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

Fix SHA-2 page

[Discussion moved from Wikipedia talk:WikiProject Cryptography -- intgr [talk] 17:28, 6 January 2011 (UTC)][reply]

The formula beneath the graphic on the SHA-2 page differs from the pseudocode given beneath in the calculation of Ch and Ma(j). ORs in the formula are ANDs in the pseudocode, and the second F (which is NOT-ed) in the formula is E in the pseudocode. I don't know which is correct, so I can't fix this myself. Everything else appears to be consistent between the two. —Preceding unsigned comment added by 70.176.109.171 (talk) 06:48, 20 December 2010 (UTC)[reply]

You are right. I added the formulas beneath the graphic. They were adopted from the following paper: Yu Sasaki, Lei Wang, and Kazumaro Aoki (2008-11-25). "Preimage Attacks on 41-Step SHA-256 and 46-Step SHA-512" (PDF). {{cite journal}}: Cite journal requires |journal= (help)CS1 maint: multiple names: authors list (link), formula (6) on page 4. This paper is the first reference on the SHA-2 page. I do not know which of these formulas is correct, but I have checked that they produce different results. Nielsduif (talk) 13:57, 5 January 2011 (UTC)[reply]
I have replaced the second F (which is NOT-ed) in the formula by E. This part is now the same as in the pseudocode. The difference between the use of AND and OR remains unresolved.Nielsduif (talk) 14:06, 5 January 2011 (UTC)[reply]
According to the document FIPS PUB 180-3, linked from the same article, AND should be correct in both functions.--193.40.16.60 (talk) 11:42, 15 January 2011 (UTC)[reply]

The Note 1 in SHA-256 algorithme header is unclear. "Calculating" doesn't mean much - the specific calculation (rotate, add) that wrap module 2^32 shall be explicitely described, as well as those which not wrap (shift). Emmanuel Deloget (talk) 16:24, 6 January 2011 (UTC)[reply]

I have changed the note to clarify that addition is modulo 2^32, and removed the word "wrap", as the use of that word is not correct to describe the overflow of the calculation when exceeding the 32-bit limit. Richieframe (talk) 06:44, 11 June 2013 (UTC)[reply]

Substitutes for formulas

ch := (e and f) xor ((not e) and g) can be substituded by ch := (e and f) or ((not e) and g) which again can be substituded by ch := g xor (e and (f xor g)) --213.178.64.5 (talk) 06:48, 17 February 2011 (UTC)[reply]

SHA-2 Variants

NIST has recently announced that a draft for FIPS180-4 that will add 224- and 256-bit variants of SHA-512 (since this should be faster than SHA-256 on a 64-bit computer), with designations SHA-512/224 and SHA-512/256. The current "Comparison of SHA functions" table is fairly unambiguous for the existing functions but it's not clear how to list the two new variants without significantly expanding the content of that column.

One approach would be to have one line per variant (2 for SHA-256 and 4 for SHA-512) but this would seem to overly bulk up the table (and it's not clear which variant was measured for the Example Performance column).

--PeterJeremy (talk) 20:10, 15 March 2011 (UTC)[reply]

Square root initialization constants

The pseudocode section talks about initializing the array using the "first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19". For fun, I wrote a little piece of code that actually calculated the square roots of the first 8 primes and looked at the hexadecimal representation of them (using printf ("%a", sqrt(X));). The list of constants in the page is correct for the first two primes, but then is completely wrong. For reference, here's what I show as output from my code:

Square root of 2 is: 0x1.6a09e667f3bcdp+0
Square root of 3 is: 0x1.bb67ae8584caap+0
Square root of 5 is: 0x1.1e3779b97f4a8p+1
Square root of 7 is: 0x1.52a7fa9d2f8eap+1
Square root of 11 is: 0x1.a887293fd6f34p+1
Square root of 13 is: 0x1.cd82b446159f3p+1
Square root of 17 is: 0x1.07e0f66afed07p+2
Square root of 19 is: 0x1.16f8334644df9p+2

And here's what the pseudocode lists:

0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19

You can see that the first two match (0x6a90e667 and 0xbb67ae85), but after that they aren't even close. I did not edit the article because I don't know if I did something wrong in my program. But I wanted to point it out here so that others can verify if I'm right and decide what to do about it.

--Markkawika (talk) 01:58, 5 April 2011 (UTC)[reply]

Upon further review, I believe the table of cube roots is also incorrect. The first four match my calculations, but all of the rest appear to be wrong. --Markkawika (talk) 02:01, 5 April 2011 (UTC)[reply]
And upon still further review, I found out that there's many ways to represent a floating point number internally. I just was looking at the wrong representation. Sorry, my bad. The values are, in fact, correct. --Markkawika (talk) 02:19, 5 April 2011 (UTC)[reply]

addition with no carry v standard addition

I think also that the red [+] are standard additions, with carry propagation. However they don't overflow past 2^32.

 Fixed. RFC 6234 is pretty clear: You are right. So I changed the caption from "addition with no carry" (which usually means "XOR") to "addition modulo 232". --DavidCary (talk) 12:14, 12 July 2011 (UTC)[reply]

C implementation

I have created a C implementation of sha256 using contents of the article. I've tested it on x86 and x86_64 gnu/linux (latest Ubuntu). IMHO, that would be a good addition to the pseudocode.

A MediaWiki command, that hides text unless pressed, would be good here =) Bu I couldn't find it. — Preceding unsigned comment added by Ivze (talkcontribs) 18:15, 4 August 2011 (UTC)[reply]

Thanks for collapse command :) --Ivze (talk) 18:31, 4 August 2011 (UTC)[reply]
Extended content
/**
 * This program implements SHA256 hash function for streams of bits.
 * 
 * SHA 256 operates on streams of bits. After padding, a bit stream is 
 * packed into bytes, for each byte the first bit comes to bit 7, and 
 * the last comes to 0. This complies with Big-Endian phylosophy of
 * those people, who created SHA256.
 * 
 * In practice SHA256 is rarely applied to bit streams: byte sequencies
 * are the target. A byte sequence is concieved to be a stream of bits,
 * produced by concatenating 8 bit blocks, where first bit of every 
 * block comes from the most significant bit of the respective byte.
 */

#include <stdint.h>
#include <string.h>

struct sha256state {
	uint32_t h[8];
};

void sha256state_init(struct sha256state * S){
	S -> h[0] = 0x6A09E667;
	S -> h[1] = 0xBB67AE85;
	S -> h[2] = 0x3C6EF372;
	S -> h[3] = 0xA54FF53A;
	S -> h[4] = 0x510E527F;
	S -> h[5] = 0x9B05688C;
	S -> h[6] = 0x1F83D9AB;
	S -> h[7] = 0x5BE0CD19;
}

/**
 * Standart constants, needed in processing
 **/
const uint32_t 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
};

/**
 * Implements right cyclic shift
 * @param w - integer to shift
 * @param N - shift value
 * @return shifted value
 */
uint32_t rightrotate(uint32_t w, uint8_t N){
	return (w >> N) | (w << (32 - N));
}

/**
 * Processes one 512 bit block
 * @param state - hash sate structure
 * @param data - array of 64 bytes, containing bits to be processed
 */
void sha256state_apply64bytes(struct sha256state * state, 
	const uint8_t * data)
{
	uint8_t i; /* loop variable */
	/* Make first 16 32-bit integers from data bytes considering
	 * Big-Endian rules */
	uint32_t w[64];
	for (i = 0; i < 16; i += 1) {
		uint8_t of;
		of = i * 4;
		w[i] = 
			((uint32_t)data[of] << 24) |
			((uint32_t)data[of + 1] << 16) |
			((uint32_t)data[of + 2] << 8) |
			((uint32_t)data[of + 3]);
	}
	
	/* Uncompress first 16 integers into 64 ones */
	for(i = 16; i < 64; i += 1){
		uint32_t s0, s1;
		s0 = rightrotate(w[i-15], 7) ^ 
			rightrotate(w[i-15], 18) ^ (w[i-15] >> 3);
		s1 = rightrotate(w[i-2], 17) ^
			rightrotate(w[i-2], 19) ^ (w[i-2] >> 10);
		w[i] = w[i-16] + s0 + w[i-7] + s1;
	}
	
	/* Copy state */
	uint32_t a,b,c,d,e,f,g,h;
	a = state -> h[0];
	b = state -> h[1];
	c = state -> h[2];
	d = state -> h[3];
	e = state -> h[4];
	f = state -> h[5];
	g = state -> h[6];
	h = state -> h[7];
	
	/* Main ciphering loop */
	for(i = 0; i < 64; i += 1){
		uint32_t Sigma0, Ma, t2, Sigma1, Ch, t1;
		Sigma0 = rightrotate(a, 2) ^
			rightrotate(a, 13) ^ rightrotate(a, 22);
		Ma = (a & b) ^ (a & c) ^ (b & c);
		t2 = Sigma0 + Ma;
		Sigma1 = rightrotate(e, 6) ^
			rightrotate(e, 11) ^ rightrotate(e, 25);
		Ch = (e & f) ^ ((~ e) & g);
		t1 = h + Sigma1 + Ch + k[i] + w[i];
		
		h = g;
		g = f;
		f = e;
		e = d + t1;
		d = c;
		c = b;
		b = a;
		a = t1 + t2;
	}
	
	/* Push values back to state */
	state -> h[0] += a;
	state -> h[1] += b;
	state -> h[2] += c;
	state -> h[3] += d;
	state -> h[4] += e;
	state -> h[5] += f;
	state -> h[6] += g;
	state -> h[7] += h;
}

/**
 * High-level data structure for processing data in blocks of variable 
 * length.
 */
struct sha256hash {
	struct sha256state state;
	uint8_t inbuf; /* bytes waiting in buf[] */
	uint8_t buf[63];
	uint64_t message_bits; /* Number of message bits,
		allready processed */
};

void sha256hash_init(struct sha256hash * hash){
	sha256state_init(& hash -> state);
	hash -> inbuf = 0;
	hash -> message_bits = 0;
}
/**
 * Pushes len message bytes into hasher. To process bit stream, bits 
 * shall be packed in bytes in Big-Endian manner.
 * @param hash - highlevel hash object
 * @param buf - data buffer
 * @param len - number of bytes in buffer, 32 bit unsigned for code
 * stability
 **/
void sha256hash_process_bytes(struct sha256hash * hash,
	const uint8_t * buf, uint32_t len)
{
	uint64_t all_len = (uint64_t)len + hash -> inbuf;
	uint64_t full_blocks = all_len / 64;
	uint8_t trailing_bytes = all_len % 64;
	uint64_t i;
	for(i = 0; i < full_blocks; i += 1){
		if(i == 0){
			/* concatination with (hash -> buf) is possible */
			if(hash -> inbuf == 0){
				/* no concatenation here */
				sha256state_apply64bytes( &hash -> state, buf );
			}else{
				uint8_t mem[64];
				memcpy( mem, hash -> buf, hash -> inbuf );
				memcpy( mem + hash -> inbuf, buf, 64 - hash -> inbuf );
				sha256state_apply64bytes( &hash -> state, mem );
			}
		}else{
			/* all data taken directly from buf */
			sha256state_apply64bytes( &hash -> state,
				buf + (i*64 - hash -> inbuf) );
		}
	}
	
	/* copying trailing bytes to buf */	
	if(full_blocks == 0){
		/*Couldn't get enough data for a block, add new data to bufer*/
		memcpy(hash -> buf + hash -> inbuf, buf, len);
		hash -> inbuf += len;
	}else{
		/* Have had at least one full block, all hash -> buf data
		 * gone there */
		memcpy(hash -> buf, buf + (full_blocks*64 - hash -> inbuf),
			trailing_bytes);
		hash -> inbuf = trailing_bytes;
	}
	
	/* incrementing message bit length */
	uint64_t new_bits = full_blocks * 512;
	hash -> message_bits += new_bits;
}

/**
 * Called before end of hashing. Applies bits, not fitted into last byte.
 * @param hash - hash object
 * @param bits - one byte, containing 0 to 7 bits, that are last bits of
 * the message in Big-Endian order. Zero bits shall be used for hashing
 * sterams of bytes.
 * @param len - number of bits
 */
void sha256hash_process_trailing_bits(struct sha256hash * hash,
	uint8_t bits, uint8_t len)
{
	uint8_t mem[128]; /* From 1 to 2 last blocks
		are going to be generated */
	uint16_t bits_left = (uint16_t)hash -> inbuf * 8 + len;/* So many
		message bits left unprocessed */
		
	/* Writing first block */
	uint8_t mempos = 0;
	memcpy(mem, hash -> buf, hash -> inbuf);
	mempos += hash -> inbuf; /* at most 63 */
	mem[mempos] = ( bits & (0xff << (8-len)) ) |
		( 0x01 << (7-len) ); /* '1' bit with some zero bits according
		to padding standart */
	mempos += 1; /* at most we've filled the whole first block */
	uint8_t bytes_except_padding = hash -> inbuf + 1 + 8; /* This + N
		zero bytes => one or two 512 bit blocks */
	
	uint8_t write_zero_bytes;
	uint8_t twoblocks = bytes_except_padding <= 64 ? 0 : 1; /* One or
		two blocks will be produced */
	if( !twoblocks ){
		/* one block is enough */
		write_zero_bytes = 64 - bytes_except_padding;
	}else{
		write_zero_bytes = 128 - bytes_except_padding;
	}
	/* applying zero bytes */
	memset(mem + mempos, 0, write_zero_bytes);
	mempos += write_zero_bytes;
	/* appending message length in bits */
	hash -> message_bits += bits_left;
	uint8_t i;
	for(i = 0; i < 8; i += 1){
		mem[mempos + i] = hash -> message_bits >> 8*(7-i) & 0xff ;
	}
	/* push the block or blocks through hasher */
	sha256state_apply64bytes(&hash -> state, mem);
	if(twoblocks)
		sha256state_apply64bytes(&hash -> state, mem + 64);
	/* Done! Quk-ik */
}

/**
 * Outputs hash value as a sequence of bytes.
 * @param hash - high-level hash object
 * @param mem - array of 32 bytes to put data to
 */
void sha256hash_get_result(const struct sha256hash * hash,
	uint8_t * mem)
{
	uint8_t ksi, eta;
	for(ksi = 0; ksi < 8; ksi += 1){
		for(eta = 0; eta < 4; eta += 1){
			mem[ksi * 4 + eta] = hash -> state . h [ksi] 
				>> (8*(3 - eta)) & 0xff;
		}
	}
}

/* Below is a sample program, that hashes sequences of bytes from
 * a file */

#include <stdio.h>
#include <stdlib.h>
/**
 * Prints mem in hex
 */
void print_beautiful(uint8_t * mem, uint8_t len){
	uint8_t i;
	for(i = 0; i < len; i += 1){
		printf("%.2x", mem[i]);
	}
	printf("\n");
}

int main(int argc, char ** argv){
	if(argc < 2){
		fprintf(stderr, "Specify a file to calculate hash for\n");
		fprintf(stderr, "usage: ./a.out file [buffer_size]\n");
		fprintf(stderr, "file - file to open and read data from\n");
		fprintf(stderr, "buffer_size - read buffer length in bytes \
from diapason [100-65535]\n");
		
		return 0;
	}
	uint16_t buffer_size;
	if(argc >= 3){
		int buffer_size_i = atoi(argv[2]);
		if(buffer_size_i < 100 || buffer_size_i > 65535){
			fprintf(stderr, "Wrong buffer size\n");
			return 1;
		}
		buffer_size = (uint16_t)buffer_size_i;
	}else{
		buffer_size = 8192;
	}
	
	struct sha256hash hash;
	sha256hash_init(&hash);
	
	FILE * file = fopen(argv[1], "r");
	if(file == NULL){
		fprintf(stderr, "Can't open file\n");
		return 2;
	}
	uint8_t mem[buffer_size];
	uint16_t nread;
	do{
		nread = (uint16_t)fread(mem, 1, buffer_size, file);
		sha256hash_process_bytes(&hash, mem, nread);
	}while(nread == buffer_size); /* end of data or IO error */
	if(ferror(file)) fprintf(stderr, "Error reading file\n");
	fclose(file);
	
	sha256hash_process_trailing_bits(&hash, 0, 0); /* No trailing bits,
		just finish the digest */
	
	uint8_t out[32];
	sha256hash_get_result(&hash, out);
	print_beautiful(out, 32);
	return 0;
}

sha2 and rsa 2048

What is the difference between SHA2 and RSA2048? — Preceding unsigned comment added by 115.242.166.67 (talk) 08:36, 25 October 2011 (UTC)[reply]

Removal of recommendations of outdated FIPS180-1

In the applications section, saying that FIPS180-1 recommends that non-government organizations use SHA-1 is outdated, as FIPS180-3, which replaces FIPS180-1 and FIPS180-2, states that "The adoption and use of this Standard is available to private and commercial organizations," which Standard recommends SHA-2. Should this line be removed, or changed? Derekstucki (talk) 04:02, 4 December 2011 (UTC)[reply]

Big-endian vs. Little-endian

From the article: 'Note 2: All constants in this pseudo code are in big endian'

I believe Note 2 at the beginning of the SHA-256 pseudo code is massively confusing. FIPS180-2 specifies, 'Throughout this specification, the “big-endian” convention is used when expressing both 32- and 64-bit words, so that within each word, the most significant bit is stored in the left-most bit position.' This statement concerns left-to-right natural language representation in the text of the standard and not the architecture of the machine executing the code.

All compilers I am familiar with use left-to-right notation for constants in their source code. This may not be true for compilers in natural languages other than English, but the article is in English; thus one should expect the pseudo code to be read by someone who understands English conventions.

There is no need to modify pseudo code constants when translating pseudo code to source code. Only when binary code is transferred between big-endian/little-endian computers is conversion needed. I believe Note 2 should be removed.

17:49, 12 December 2011 (UTC) — Preceding unsigned comment added by 76.18.184.9 (talk)

It was confusing, the main issue with endianness in FIPS180 is regarding how input bytes of the message are converted to words of the message schedule, I have edited the note in such a way to hopefully avoid future confusion. Richieframe (talk) 06:37, 11 June 2013 (UTC)[reply]

Zappos

A blog post on ZDNET says Zappos was using SHA-2 for their passwords: "Zappos Thursday said it was using a SHA-2 cryptographic hash but would not disclose any details about its “cryptographically scrambled” password format in the wake of a breach that forced the company to reset 24 million passwords."

Is that appropriate to add here? http://www.zdnet.com/blog/identity/zappos-was-using-sha-2-hash-now-working-with-fbi/162 — Preceding unsigned comment added by 67.87.231.208 (talk) 04:01, 20 January 2012 (UTC)[reply]

Definitely not here, nor would it go in the Internet article since that was probably the breach avenue. The information may be suitable for the Zappos article though. —EncMstr (talk) 08:16, 20 January 2012 (UTC)[reply]

Secret backdoor

If I was a government, and had to design a hash, I would almost certainly want a back door in it. If I was a mathematician, and I had to put a back door in something, I would head straight to prime numbers. It's beautifully easy to use prime moduloarithmetic to "scramble" one number into some other number, in a way that cannot be reversed easily. It's even got a name: asymmetric cryptography. Of course, if you know the secret key, then you *can* reverse it: so there's your back door. If you look into how RSA gets programmed, it boils down to simply a stack of binary operations, carried out in some order determined by the keys. If you look at how SHA gets programmed, it boils down to simply a stack of binary operations, carried out in some interesting order. So the challenge for the mathematician: how to write the SHA algorithm so that nobody suspects it's really an alternative representation of a particular pre-chosen public key hard coded into an asymmetric cipher.

The dead giveaway here is "prime numbers". SHA is initialized with a whole stack of carefully chosen constants that are all derived from prime numbers. This smells to me like it was designed from the start to have a secret inverse. — Preceding unsigned comment added by 120.151.160.158 (talk) 04:12, 31 August 2012 (UTC)[reply]

The SHA hash algorithms have been and are continuously analyzed by cryptographers all over the world. If there really was a basis for backdoor concerns, you would have something more concrete to rely on than "if I was a government"
I disagree. The financial value of exploiting a backdoor may well outweigh the esteem value of publishing the find, and, this is an arms race: for as long as the government was better than researchers, nobody's going to find it - and lets face it - they *have* got more resources ($28bn, 20 years ago[1]).120.151.160.158 (talk) 22:00, 5 October 2012 (UTC)[reply]
Look at Dual EC DRBG for an example how a certain government tried to push a backdoored algorithm and how the cryptography community reacted -- the backdoor was uncovered and researchers complained very loudly.
It is also incorrect to call RSA "simply a stack of binary operations". RSA and other asymmetric algorithms have simple and neat mathematical descriptions. In RSA that's -- basically describes the whole algorithm.
I disagree. I have hand-coded RSA in assembly language from first principals. If you were to use a fixed key, you could optimise the code into something that looks similar to a hash with preconceived constants.120.151.160.158 (talk) 22:00, 5 October 2012 (UTC)[reply]
In contrast, symmetric algorithms such as SHA, AES etc, do not have a simple mathematical form -- they are indeed just binary operations (Confusion and diffusion).
About the "prime numbers" argument, see nothing up my sleeve number. SHA-2 doesn't use plain prime numbers, it uses square roots of very small prime numbers (and nowhere in the algorithm are these numbers squared up again). For these numbers to be useful for asymmetric cryptography, they would have to be very large primes (e.g. which are used for RSA). -- intgr [talk] 08:39, 31 August 2012 (UTC)[reply]
This only fuels my suspicion - picking constants that are deliberately non-random numbers with interesting potential mathematical properties? They should have announced their intention in advance to pick the results of unpredictable events in future, and used those (eg: lotto, weather, exchange data, whatever).120.151.160.158 (talk) 22:00, 5 October 2012 (UTC)[reply]

'too technical' template

Anyone want to propose changes we could make to be able to take that 'too technical' box off? It seems like nontechnical readers should go follow the "cryptographic hash algorithm" link and learn what those are, and that once you know what a hash is there's very little nontechnical additional info about SHA-2 that's interesting--maybe there's a paragraph or so more to be written about history/security/applications. It's like how the pages on chess openings don't make sense if you haven't learned a little about chess. Perhaps we could nudge people towards reading the more basic articles if they're lost, but I'm not sure what we'd change to do that.

What thinkst all y'all? — Preceding unsigned comment added by 24.7.67.251 (talk) 00:36, 29 November 2012 (UTC)[reply]

Fips 180-4 and SHA-512/t

The updated standard from March 2012 introduced SHA-512/224 and SHA-512/256 and generally SHA-512/t. I've updated some of the sections to mention this. This moves things around a bit, since we can't say "SHA-224/256" anymore for two different hash functions, that would be confusing. SHA-512/224 and SHA-512/256 are in the info table because it is in the standard as well. 81.186.243.41 (talk) 15:13, 14 January 2013 (UTC)[reply]

 Done. Several of the revisions made in the last year should have cleared up any confusion and misnomers regarding truncated SHA-512 variants. --Richieframe 08:21, 20 December 2013 (UTC)[reply]

Pseudocode is broken

A bug was recently introduced into the pseudocode: [1] It is pretty obvious that the h variable is inadvertently overwritten. --87.144.116.61 (talk) 00:51, 7 February 2013 (UTC)[reply]

 Done. Pseudocode rewrite and some prior modifications no longer have this problem. Richie Frame (talk) 08:27, 20 December 2013 (UTC)[reply]

SHA-256 pseudocode problem (or lack of clarity, at best)

The psuedocode for SHA-256 contains the following three lines:

break message into 512-bit chunks
for each chunk
    break chunk into sixteen 32-bit big-endian words w[0..15]

This sounds like it is declaring a word array of 16 words, each 32 bits in length, which is incorrect. The very next loop of code iterates with i as an index, from 16 to 63, and accesses w[i], which implies that array w must be sized as a word array of 64 words, each 32 bits in length. If the array is defined as w[0..15] as is implied, the loop would run off the end of the array.

I downloaded FIPS PUB 180-4 and checked the formulas listed there, which appears to confirm that the message schedule w is comprised of 64 words (see page 22) and also indicates that the first 16 words of the message schedule are copied directly from the original message block, while the remaining 48 words are computed using the formulas described in that doc (and likewise in the rest of the pseudocode).

I think those three lines would be more accurate and more descriptive if they read:

break message into 512-bit chunks
for each chunk
    copy chunk into first 16 words of 64-word array w[0..63], where each word is 32 bits in length

I considered making the change myself, but I'd appreciate another pair of eyeballs on the NIST doc to confirm the change first. JonathanSomers (talk) 20:48, 26 March 2013 (UTC)[reply]


I have made multiple changes to the pseudocode to clarify this as best as I could for both non-experts and programmers. Richieframe (talk) 06:39, 11 June 2013 (UTC)[reply]
 Done. The pseudocode now explicitly states "a 64-entry message schedule array w[0..63] of 32-bit words" which seems pretty clear to me. I agree with JonathanSomers and Richieframe that the FIPS publication actually does call for a 64-entry array, and the old pseudocode we used to have in this Wikipedia article was unclear on this point. --DavidCary (talk) 12:37, 14 October 2013 (UTC)[reply]

Security of a Hash function is too generic to deserve a paragraph in the abstract

Hi guys, great article! Still, I would suggest removing or moving below the following paragraph: """The security provided by a hashing algorithm is entirely dependent upon its ability to produce a unique value for any specific set of data. When a hash function produces the same hash value for two different sets of data then a collision is said to occur. Collision raises the possibility that an attacker may be able to computationally craft sets of data which provide access to information secured by the hashed values of pass codes or to alter computer data files in a fashion that would not change the resulting hash value and would thereby escape detection. A strong hash function is one that is resistant to such computational attacks. A weak hash function is one where a computational approach to producing collisions is believed to be possible. A broken hash function is one where a computational method for producing collisions is known to exist."""

Whereas it is true, this applies to a Hash function, and I can't see anything specific for SHA-2. I would personally remove it, but I'm perfectly ok with just moving it below, or reducing the number of lines.

Carlesso (talk) 14:17, 16 December 2013 (UTC)[reply]

I agree. How about cut-and-pasting this to Cryptographic hash function, section #Properties or #Cryptographic hash algorithms? --Claw of Slime (talk) 16:56, 16 December 2013 (UTC)[reply]
I have been looking over that paragraph as well, as it is incorrect. That is saying collision resistance is the only important thing, and completely forgetting about preimage resistance. I plan on making a lot more edits to this page and will work on that section eventually. --Richieframe 08:52, 19 December 2013 (UTC)[reply]
After further review, I am removing those 2 paragraphs, similar paragraphs do not exist on the SHA-1 page, and there are too many issues with its content. I will adjust the cryptanalysis section to compensate for this plus the recent edit by Dionyziz. The Cryptographic hash function article has a more comprehensive and accurate description already. --Richie Frame (talk) 09:28, 21 December 2013 (UTC)[reply]

Picture of data flow is flawed.

If I had more authority, I would remove the data flow picture. (Or if I had time I would replace it).

  • It contains symbols without explanation
  • the >>> symbol is not in agreement with the explicit description later.
  • I've a mathematical background and recognize ^ as a logical and(never as a *bitwise and*.) In a context like this almost everybody expects it to be xor.

Even so it is illustrative, so it is much better to replace it than just remove. 80.100.243.19 (talk) 11:23, 21 December 2013 (UTC)[reply]

Actually, >>> stands for a right rotate (no carry bit) and is common notation for an equivilent ror in ASM. I do fully agree with the ^, as it is not used for AND in any style of pseudocode I am aware of (other than for c style XOR), and will make the appropriate change. -Richie Frame (talk) 09:58, 28 December 2013 (UTC)[reply]
It is the standard notation for boolean algebras. 83.77.191.161 (talk) 12:17, 28 December 2013 (UTC)[reply]

It doesn't seem to add much value as the Ch(), Ma(), and sum functions just reach a cold trail from there and aren't explained further. Anyone coming here (like me) to just learn a high-level overview of how SHA works just gets this figure and that's it. That doesn't add value in my opinion.

  1. ^ [2]