Channels ▼
RSS

Database

Keccak: The New SHA-3 Encryption Standard


Listing One shows how to add SHA-3 support to the NSString class. Here, the category SHA3String declares two method prototypes (lines 8-9). The category method sha3AsCstring extracts the raw message bytes with the instance method cStringUsingEncoding: (line 25). It specifies standard ASCII as the desired text encoding. The method counts the number of message bytes and creates the hash variable tHash (lines 29-30). It passes the count, message text, and hash variable to the entry function Hash() (line 33). Hash() returns the 512-bit message hash, and sha3AsCstring recasts the hash into a constant character string (line 36). BitSequence, by the way, is Keccak's custom typedef for char.

Lisitng One

// -- File:SHA3Category.h
//
#import <Cocoa/Cocoa.h>
#import <string.h>
#import "KeccakNISTInterface.h"

@interface NSString (SHA3String)
- (const char *)sha3AsCstring;
- (NSData *)sha3AsData;
//...
@end

// -- File: SHA3Category.m
//
@implementation NSString (SHA3String)
// Return the SHA-3 hash as a C-string
- (const char *)sha3AsCstring
{
	const char *tTemp;
	const BitSequence *tData;
	BitSequence *tHash;
	NSUInteger tLen;
	
	// extract the message data
    tTemp = [self cStringUsingEncoding:NSASCIIStringEncoding];
	tData = (const BitSequence *)tTemp;
	
	// prepare the hash variable
	tLen = strlen(tTemp);
	tHash = malloc(sizeof(BitSequence) * 32);
	
	// hash the message data
	Hash(512, tData, tLen, tHash);
	
	// return the hash result
	tTemp = (const char *)tHash;
	return (tTemp);
}

// Return the SHA-3 hash as an NSData object
- (NSData *)sha3AsData
{
	const char *tHash;
	NSUInteger tLen;
	NSData *tData;
	
	// generate the SHA-3 hash
	tHash = [self sha3AsCstring];
	
	// prepare the hash object
	tLen = strlen(tHash);
	tData = [NSData dataWithBytes:tHash 
		length:tLen];
	
	// return the hash object
	return (tData);
}

//...
@end

The category method sha3AsData returns the message hash as an NSData object. It relies on sha3AsCstring to process the message bytes (line 48). Then it uses the factory method dataWithBytes:length: to create the object (lines 52-53).

Listing Two shows SHA-3 as a singleton class. A singleton provides a common global access point to the SHA-3 algorithm. It handles its own memory management, and as such, does not require explicit disposal.

Listing Two

// -- File:SHA3Single.h
//
#import <Cocoa/Cocoa.h>
#import "KeccakNISTInterface.h"

// Define the enum constants
typedef enum _SHA3_SIZE 
	{SIZE_224 = 224, SIZE_256 = 256, 
		SIZE_384 = 384, SIZE_512 = 512} 
	SHA3_SIZE;


// Declare the class interface
@interface SHA3Single : NSObject 
{
	@private
		NSUInteger pSize;
}
@property (readwrite) NSUInteger hashSize;

+ (id)defaultGenerator;
+ (id)generatorForSize:(NSUInteger)aSize;

- (void)hashMessage:(const char *)aMesg 
	into:(BitSequence *)aHash;
- (void)hashObject:(id)aMesg 
	into:(BitSequence *)aHash;
@end

// -- File: SHA3Single.m
//
// Declare the static global
static SHA3Single *gHash;

// Define the singleton class
@implementation SHA3Single
@synthesize hashSize = pSize;

// Create the default SHA3 generator
+ (id)defaultGenerator
{
	@synchronized(self)
	{
		// check the static global
		if (gHash == nil)
		{
			// create the instance
			gHash = [[super alloc] init];
			
			// set the output hash size
			gHash.hashSize = SIZE_512;
		}
	}
	
	// return the singleton instance
	return (gHash);
}

// Create a "custom" SHA3 generator
+ (id)generatorForSize:(NSUInteger)aSize
{
	@synchronized(self)
	{
		// check the static global
		if (gHash == nil)
		{
			// create the instance
			gHash = [[super alloc] init];
			
			// set the output hash size
			gHash.hashSize = aSize;
		}
	}
	
	// return the singleton instance
	return (gHash);
}

- (void)hashMessage:(const char *)aMesg 
	into:(BitSequence *)aHash
{
	NSUInteger tLen;
	
	// generate the SHA-3 hash
	tLen = strlen(aMesg);
	Hash(self.hashSize, 
		(const BitSequence *)aMesg, tLen
		, aHash);
}

- (void)hashObject:(id)aMesg 
	into:(BitSequence *)aHash
{
	const char *tData;
	NSUInteger tLen;
	
	// parametre check
	if ((aMesg != nil) && (aHash != nil))
	{
		// identify the message object
		if ([aMesg 
			isKindOfClass:[NSString class]])
			// -- object:NSString
			tData = [aMesg cStringUsingEncoding:NSASCIIStringEncoding];
		else if ([aMesg 
			isKindOfClass:[NSData class]])
		{
			// -- object:NSData
			tLen = [aMesg length];
			tData = malloc(tLen * sizeof(char));
			
			[aMesg getBytes:(void *)tData];
		}
		else 
		{
			// handle other Cocoa objects
			// -- RESERVED
		}
		
		// hash the raw message bytes
		tLen = strlen(tData);
		Hash(self.hashSize, 
			(const BitSequence *)tData, tLen
			, aHash);
	}
}

@end

The singleton class SHA3Single starts by declaring a private property pSize (line 17). This property holds the desired hash size in bits. The class also declares the property accessor hashSize and four method prototypes, two of which are factory methods (lines 19-27).

Next, the class define the static global gHash to hold the singleton instance (line 33). It then defines the hashSize accessor, the two factory and two instance methods. The factory method defaultGenerator checks the gHash global (line 45) and creates an instance of SHA3Single (line 48). It also sets the pSize property to the default hash size of 512 bits (line 51).

The factory method generatorForSize: gets a hash size as input. It, too, checks the gHash global and creates the SHA3Single instance. But it updates the pSize property to the specified size (line 71).

The instance method hashMessage:into: gets a message text (aMesg) and a hash variable (aHash) as input. It counts the number of message bytes, and passes both message text, byte count, and hash variable to the entry function Hash() (lines 85-88). Hash() then stores the message hash into the variable aHash.

The instance method hashObject:into: gets a generic Cocoa object (aMesg) as one of its inputs. It uses the instance method isKindOfClass: (lines 101-102, 105-106) to identify the object. Once it has the object type, hashObject:into: uses the correct code to extract the raw message text (lines 104, 112). Here, too, it counts the message bytes and generates the message hash with Hash() (line 121-124). Then it stores the resulting hash in aHash.

To use the SHA-3 singleton, create the instance with the appropriate factory method. The snippet below creates the 512-bit variant of SHA-3.

  SHA3Single *tSHA3;
  tSHA3 = [SHA3Single defaultGenerator];

Then use the appropriate instance method to process the message. This next snippet, for instance, uses the method hashMessage:into: to process an NSString object.

  NSString *tMesg;
  const char *tHash;
  //...
  tMesg = [NSString stringWithString:@"foobar"];
[tSHA3 hashMessage:tMesg into:(BitSequence *)tHash];

The Xcode project for the SHA3 framework is available for reference.

Conclusion

Overall, Keccak is a good choice for the SHA-3 standard. It is fast, it has a uniform bit distribution, and it resists collisions well. But the digital arms race is far from over. Years from now perhaps, there will be successful attacks against Keccak. When that happens, NIST shall have to prepare a new hash standard. That, however, is a topic for another time.


José Cruz is a freelance engineering writer based in British Columbia. He frequently contributes articles to Dr. Dobb's.

Related Reading

Testing the Final SHA-3 Hashing Algorithms


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 

Video