Home | pfodApps/pfodDevices | WebStringTemplates | Java/J2EE | Unix | Torches | Superannuation | | About Us
 

Forward Logo (image)      

SipHash Library
for Arduino

by Matthew Ford 15th August 2013 (original 9th June 2013) – corrected example include, corrected keywords.txt, added initialization from RAM, renamed finalize() to finish()
© Forward Computing and Control Pty. Ltd. NSW Australia
All rights reserved.

SipHash Library for Arduino.

Update: Version 2 of the SipHash library replaces the Atmel assembler code with standard C code methods so that the library will compile with all boards supported by the Arduino IDE and most other microprocessors.

This page describes a small library that implements SipHash for Arduino. It adds about 1500 bytes to the code size and uses about 42 bytes of RAM. There is also a complementary SipHash Java library available here.

SipHash is a family of pseudorandom functions (a.k.a. keyed hash functions) optimized for speed on short messages.
SipHash is secure, fast, and simple (for real):
SipHash is simpler and faster than previous cryptographic algorithms (e.g. MACs based on universal hashing)
SipHash is competitive in performance with insecure non-cryptographic algorithms (e.g. MurmurHash)
” – https://131002.net/siphash

I am using SipHash as a MAC (http://en.wikipedia.org/wiki/Message_authentication_code) to provide a secure messaging system for controlling pfodDevices via the internet. Adding the SipHash of the message to the end of each message makes it very hard for hackers to forge a message.

The key is 128bits i.e. 16 bytes, all bits are used. For security this key MUST BE RANDOM. See the "Generating the Password" section towards the bottom of SipHash Secure Challenge and Response for micro-devices (AVR / Arduino) for the details and how to create a 'random' secret key.

The message size in unlimited (by SipHash). You call SipHash.updateHash((byte)c); for each byte in the message. SipHash internally accumulates 8 bytes and then adds them to the hash and then discards them. In finish() SipHash adds the msg length % 256. The code assigns one byte to keep this value and updates it each time updateHash() is called so the message length is unlimited.

Installation:

Delete any existing SipHash directory in your Arduino library path.

Download the SipHash.zip file copy it to a directory where you can find it and install it using the Arduino IDE Sketch → Import Libary → Add Library.
Under File->Examples you should now see SipHash.
Run the SipHashTest example to test out the hash function.

Library Reference: SipHash_2_4

SipHash_2_4 class includes an instance, sipHash, which you can just use directly.

SipHash_2_4 produces a 64bit number which is the hash of all the input and the secret key. This 64bit number can be stored as bytes in two different ways, Big Endian and Little Endian. See http://en.wikipedia.org/wiki/Endianness for the details. This library returns the hash in an 8 byte array, sipHash.result, with the bytes stored in BigEndian format. The example program, SipHashTest.ino , reverse this byte array (using reverse64()) to LittleEndian format output so that the test results can be directly compared to the results of the reference C implementation. You can choose which ever format suits your purpose as long as users of the hash know which it is.

Note: This SipHash library only uses byte manipulations and so this one library runs correctly on both BigEndian and LittleEndian processors with 8bit, 16bit, 32bit or 64bit words.

Usage:

 // Define your 'secret' 16 byte key in program memory (flash memory)
 const uint8_t key[] PROGMEM = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                                0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
 // to start hashing initialize with your key
 sipHash.initFromPROGMEM(key);
 // for each byte in the message call updateHash()
 for (int i=0; i<msgLen;i++) {
   sipHash.updateHash((byte)c); // update hash with each byte of msg
 }
 // at the end of the message call finalize to calculate the result
 sipHash.finish(); // finish
 // the uint8_t[8] variable, sipHash.result, then contains the 8 bytes of the hash in BigEndian format

If your key is in RAM, initialize using SipHash.initFromRAM instead. e.g.

  // Define your 'secret' 16 byte key in RAM
 uint8_t key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                        0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
 // to start hashing initialize with your key
 sipHash.initFromRAM(key);
 // for each byte in the message call updateHash()
 for (int i=0; i<msgLen;i++) {
   sipHash.updateHash((byte)c); // update hash with each byte of msg
 }
 // at the end of the message call finalize to calculate the result
 sipHash.finish(); // finish
 // the uint8_t[8] variable, sipHash.result, then contains the 8 bytes of the hash in BigEndian format


Methods

SipHash_2_4no argument constructor, instance sipHash is pre-defined in the library, see example code

To initialize the hash call one of these two methods before the start of the message you want to hash.
The key
MUST BE 16 bytes long.
void initFromPROGMEM(const uint8_t* keyPrgPtr)initialize the hash with your secret key stored in FLASH (program memory)
void initFromRAM(const uint8_t* keyInRam)initialize the hash with your secret key in RAM

For each byte of the message call this method
void updateHash(uint8_t c)add the byte to the hash.

Finally, at the end of the message, call this method to get the hash in result
void finish()
after you have added all the bytes of your msg, call this method to finish the hash calculation. The hash is in result.

unsigned char *resultafter calling finish() this variable points to the unsigned char[8] array that contains the hash in BigEndian format.

Example

The example SipHashTest.ino illustrates its use and produces the reference results shown in https://131002.net/siphash/siphash24.c.

For use of the Arduino name see http://arduino.cc/en/Main/FAQ


pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.


Forward home page link (image)

Contact Forward Computing and Control by
©Copyright 1996-2012 Forward Computing and Control Pty. Ltd. ACN 003 669 994