Home
| pfodApps/pfodDevices
| WebStringTemplates
| Java/J2EE
| Unix
| Torches
| Superannuation
|
| About
Us
|
SipHash Library
|
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.
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.
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.
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_4 – no 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 *result – after calling finish() this variable points to the unsigned char[8] array that contains the hash in BigEndian format.
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
The General Purpose Android/Arduino Control App.
pfodDevice™ and pfodApp™ are trade marks of Forward Computing and Control Pty. Ltd.
Contact Forward Computing and Control by
©Copyright 1996-2020 Forward Computing and Control Pty. Ltd.
ACN 003 669 994