From 47ab405e7f6c01b6e5015114a6a1361c8522f4c3 Mon Sep 17 00:00:00 2001 From: Rhys Weatherley Date: Thu, 2 Apr 2015 16:33:47 +1000 Subject: [PATCH] Finalization and key setup figures for hash/auth algorithms --- doc/crypto.dox | 39 ++++++------ .../examples/TestBLAKE2b/TestBLAKE2b.ino | 23 +++++++ .../examples/TestBLAKE2s/TestBLAKE2s.ino | 62 +++++++++++++++++++ .../Crypto/examples/TestGHASH/TestGHASH.ino | 44 +++++++++++++ .../examples/TestPoly1305/TestPoly1305.ino | 44 +++++++++++++ .../Crypto/examples/TestSHA1/TestSHA1.ino | 62 +++++++++++++++++++ .../Crypto/examples/TestSHA256/TestSHA256.ino | 62 +++++++++++++++++++ .../examples/TestSHA3_256/TestSHA3_256.ino | 27 ++++++++ .../examples/TestSHA3_512/TestSHA3_512.ino | 25 ++++++++ .../Crypto/examples/TestSHA512/TestSHA512.ino | 23 +++++++ 10 files changed, 392 insertions(+), 19 deletions(-) diff --git a/doc/crypto.dox b/doc/crypto.dox index 8292b576..093e87b0 100644 --- a/doc/crypto.dox +++ b/doc/crypto.dox @@ -76,29 +76,30 @@ Ardunino Mega 2560 running at 16 MHz are similar: GCM<AES192>194.17us193.72us1628.67us348 GCM<AES256>201.47us201.02us1923.78us380 -Hash AlgorithmHashing (per byte)FinalizationKey SetupState Size (bytes) -SHA121.90us 95 -SHA25643.85us 107 -SHA512123.24us 211 -SHA3_256121.69us 405 -SHA3_512229.12us 405 -BLAKE2s18.54us 171 -BLAKE2b50.58us 339 -Poly130526.29us 87 -GHASH148.14us 33 +Hash AlgorithmHashing (per byte)Finalization State Size (bytes) +SHA121.90us1423.28us 95 +SHA25643.85us2841.04us 107 +SHA512122.82us15953.42us 211 +SHA3_256121.69us16486.33us 405 +SHA3_512229.12us16502.34us 405 +BLAKE2s18.54us1200.06us 171 +BLAKE2b50.70us6515.87us 339 + +Authentication AlgorithmHashing (per byte)FinalizationKey SetupState Size (bytes) +SHA1 (HMAC mode)21.90us4296.33us1420.24us95 +SHA256 (HMAC mode)43.85us8552.61us2836.49us107 +BLAKE2s (HMAC mode)18.54us3649.98us1214.81us171 +Poly130526.29us486.15us17.26us87 +GHASH148.14us17.09us21.87us33 + +Public Key OperationTime (per operation)Comment +Curve25519::eval()3738msRaw curve evaluation +Curve25519::dh1()3740msFirst half of Diffie-Hellman key agreement +Curve25519::dh2()3738msSecond half of Diffie-Hellman key agreement Where a cipher supports more than one key size (such as ChaCha), the values are typically almost identical for 128-bit and 256-bit keys so only the maximum is shown above. -Public key algorithms have the following results on an Arduino Uno: - - - - - - -
AlgorithmOperationTimeComment
Curve25519\link Curve25519::eval() eval()\endlink3738 msRaw curve evaluation
Curve25519\link Curve25519::dh1() dh1()\endlink3740 msFirst half of Diffie-Hellman key agreement
Curve25519\link Curve25519::dh2() dh2()\endlink3738 msSecond half of Diffie-Hellman key agreement
- */ diff --git a/libraries/Crypto/examples/TestBLAKE2b/TestBLAKE2b.ino b/libraries/Crypto/examples/TestBLAKE2b/TestBLAKE2b.ino index c824339a..a21b4a1c 100644 --- a/libraries/Crypto/examples/TestBLAKE2b/TestBLAKE2b.ino +++ b/libraries/Crypto/examples/TestBLAKE2b/TestBLAKE2b.ino @@ -224,6 +224,28 @@ void testHMAC(Hash *hash, size_t keyLen) Serial.println("Failed"); } +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -250,6 +272,7 @@ void setup() Serial.println("Performance Tests:"); perfHash(&blake2b); + perfFinalize(&blake2b); } void loop() diff --git a/libraries/Crypto/examples/TestBLAKE2s/TestBLAKE2s.ino b/libraries/Crypto/examples/TestBLAKE2s/TestBLAKE2s.ino index b7217150..1c06d7cb 100644 --- a/libraries/Crypto/examples/TestBLAKE2s/TestBLAKE2s.ino +++ b/libraries/Crypto/examples/TestBLAKE2s/TestBLAKE2s.ino @@ -208,6 +208,66 @@ void testHMAC(Hash *hash, size_t keyLen) Serial.println("Failed"); } +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + +void perfHMAC(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("HMAC Reset ... "); + + for (size_t posn = 0; posn < sizeof(buffer); ++posn) + buffer[posn] = (uint8_t)posn; + + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->resetHMAC(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); + + Serial.print("HMAC Finalize ... "); + + hash->resetHMAC(buffer, hash->hashSize()); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalizeHMAC(buffer, hash->hashSize(), buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -234,6 +294,8 @@ void setup() Serial.println("Performance Tests:"); perfHash(&blake2s); + perfFinalize(&blake2s); + perfHMAC(&blake2s); } void loop() diff --git a/libraries/Crypto/examples/TestGHASH/TestGHASH.ino b/libraries/Crypto/examples/TestGHASH/TestGHASH.ino index 66b69454..70305d25 100644 --- a/libraries/Crypto/examples/TestGHASH/TestGHASH.ino +++ b/libraries/Crypto/examples/TestGHASH/TestGHASH.ino @@ -174,6 +174,48 @@ void perfGHASH(GHASH *hash) Serial.println(" bytes per second"); } +void perfGHASHSetKey(GHASH *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Set Key ... "); + + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->reset(testVectorGHASH_1.key); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + +void perfGHASHFinalize(GHASH *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalize ... "); + + hash->reset(testVectorGHASH_1.key); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, 16); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -194,6 +236,8 @@ void setup() Serial.println("Performance Tests:"); perfGHASH(&ghash); + perfGHASHSetKey(&ghash); + perfGHASHFinalize(&ghash); } void loop() diff --git a/libraries/Crypto/examples/TestPoly1305/TestPoly1305.ino b/libraries/Crypto/examples/TestPoly1305/TestPoly1305.ino index cd727ab1..55660e97 100644 --- a/libraries/Crypto/examples/TestPoly1305/TestPoly1305.ino +++ b/libraries/Crypto/examples/TestPoly1305/TestPoly1305.ino @@ -167,6 +167,48 @@ void perfPoly1305(Poly1305 *hash) Serial.println(" bytes per second"); } +void perfPoly1305SetKey(Poly1305 *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Set Key ... "); + + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->reset(testVectorPoly1305_1.key); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + +void perfPoly1305Finalize(Poly1305 *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalize ... "); + + hash->reset(testVectorPoly1305_1.key); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(testVectorPoly1305_1.nonce, buffer, 16); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -187,6 +229,8 @@ void setup() Serial.println("Performance Tests:"); perfPoly1305(&poly1305); + perfPoly1305SetKey(&poly1305); + perfPoly1305Finalize(&poly1305); } void loop() diff --git a/libraries/Crypto/examples/TestSHA1/TestSHA1.ino b/libraries/Crypto/examples/TestSHA1/TestSHA1.ino index 22890f2f..3a4d6640 100644 --- a/libraries/Crypto/examples/TestSHA1/TestSHA1.ino +++ b/libraries/Crypto/examples/TestSHA1/TestSHA1.ino @@ -224,6 +224,66 @@ void perfHash(Hash *hash) Serial.println(" bytes per second"); } +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + +void perfHMAC(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("HMAC Reset ... "); + + for (size_t posn = 0; posn < sizeof(buffer); ++posn) + buffer[posn] = (uint8_t)posn; + + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->resetHMAC(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); + + Serial.print("HMAC Finalize ... "); + + hash->resetHMAC(buffer, hash->hashSize()); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalizeHMAC(buffer, hash->hashSize(), buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -250,6 +310,8 @@ void setup() Serial.println("Performance Tests:"); perfHash(&sha1); + perfFinalize(&sha1); + perfHMAC(&sha1); } void loop() diff --git a/libraries/Crypto/examples/TestSHA256/TestSHA256.ino b/libraries/Crypto/examples/TestSHA256/TestSHA256.ino index 63f7436e..87f78cd7 100644 --- a/libraries/Crypto/examples/TestSHA256/TestSHA256.ino +++ b/libraries/Crypto/examples/TestSHA256/TestSHA256.ino @@ -228,6 +228,66 @@ void perfHash(Hash *hash) Serial.println(" bytes per second"); } +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + +void perfHMAC(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("HMAC Reset ... "); + + for (size_t posn = 0; posn < sizeof(buffer); ++posn) + buffer[posn] = (uint8_t)posn; + + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->resetHMAC(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); + + Serial.print("HMAC Finalize ... "); + + hash->resetHMAC(buffer, hash->hashSize()); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalizeHMAC(buffer, hash->hashSize(), buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -254,6 +314,8 @@ void setup() Serial.println("Performance Tests:"); perfHash(&sha256); + perfFinalize(&sha256); + perfHMAC(&sha256); } void loop() diff --git a/libraries/Crypto/examples/TestSHA3_256/TestSHA3_256.ino b/libraries/Crypto/examples/TestSHA3_256/TestSHA3_256.ino index 7fa610a4..71d17c4b 100644 --- a/libraries/Crypto/examples/TestSHA3_256/TestSHA3_256.ino +++ b/libraries/Crypto/examples/TestSHA3_256/TestSHA3_256.ino @@ -261,6 +261,32 @@ void testHMAC(Hash *hash, size_t keyLen) Serial.println("Failed"); } +/* +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + // Reuse one of the test vectors as a large temporary buffer. + uint8_t *buffer = (uint8_t *)&testVectorSHA3_256_5; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} +*/ + void setup() { Serial.begin(9600); @@ -288,6 +314,7 @@ void setup() Serial.println("Performance Tests:"); perfHash(&sha3_256); + //perfFinalize(&sha3_256); } void loop() diff --git a/libraries/Crypto/examples/TestSHA3_512/TestSHA3_512.ino b/libraries/Crypto/examples/TestSHA3_512/TestSHA3_512.ino index 896ef728..3e77ff0d 100644 --- a/libraries/Crypto/examples/TestSHA3_512/TestSHA3_512.ino +++ b/libraries/Crypto/examples/TestSHA3_512/TestSHA3_512.ino @@ -263,6 +263,30 @@ void testHMAC(Hash *hash, size_t keyLen) Serial.println("Failed"); } +/* +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} +*/ + void setup() { Serial.begin(9600); @@ -290,6 +314,7 @@ void setup() Serial.println("Performance Tests:"); perfHash(&sha3_512); + //perfFinalize(&sha3_512); } void loop() diff --git a/libraries/Crypto/examples/TestSHA512/TestSHA512.ino b/libraries/Crypto/examples/TestSHA512/TestSHA512.ino index 3a7e20c0..4a8b1007 100644 --- a/libraries/Crypto/examples/TestSHA512/TestSHA512.ino +++ b/libraries/Crypto/examples/TestSHA512/TestSHA512.ino @@ -211,6 +211,28 @@ void testHMAC(Hash *hash, size_t keyLen) Serial.println("Failed"); } +void perfFinalize(Hash *hash) +{ + unsigned long start; + unsigned long elapsed; + int count; + + Serial.print("Finalizing ... "); + + hash->reset(); + hash->update("abc", 3); + start = micros(); + for (count = 0; count < 1000; ++count) { + hash->finalize(buffer, hash->hashSize()); + } + elapsed = micros() - start; + + Serial.print(elapsed / 1000.0); + Serial.print("us per op, "); + Serial.print((1000.0 * 1000000.0) / elapsed); + Serial.println(" ops per second"); +} + void setup() { Serial.begin(9600); @@ -236,6 +258,7 @@ void setup() Serial.println("Performance Tests:"); perfHash(&sha512); + perfFinalize(&sha512); } void loop()