diff --git a/doc/crypto.dox b/doc/crypto.dox
new file mode 100644
index 00000000..a95d2375
--- /dev/null
+++ b/doc/crypto.dox
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2015 Southern Storm Software, Pty Ltd.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+\file crypto.dox
+\page crypto Cryptographic Library
+
+\section crypto_algorithms Supported Algorithms
+
+\li Block ciphers: AES128, AES192, AES256
+\li Block cipher modes: CTR, CFB, CBC, OFB
+\li Stream ciphers: ChaCha, Arcfour
+\li Hash algorithms: SHA1, SHA256
+
+All cryptographic algorithms have been optimized for 8-bit Arduino platforms
+like the Uno. Memory usage is also reduced, particularly for SHA1 and SHA256
+which save 256 and 192 bytes respectively over traditional implementations.
+
+ChaCha with 20 rounds and 256-bit keys is the recommended
+symmetric encryption algorithm because it is twice as fast as AES128,
+constant-time, and much more secure. AES128, AES192, AES256, and Arcfour
+are provided for use in applications where compatibility with other systems
+is desirable.
+
+\section crypto_examples Examples
+
+TBD
+
+\section crypto_performance Performance
+
+All figures are for the Arduino Uno running at 16 MHz:
+
+
+Algorithm | Encryption / Hashing (per byte) | Decryption (per byte) | Key Setup | State Size (bytes) |
+AES128 (ECB mode) | 32.27us | 65.85us | 158.74us | 208 |
+AES192 (ECB mode) | 43.44us | 79.59us | 165.53us | 240 |
+AES256 (ECB mode) | 50.62us | 92.34us | 225.58us | 272 |
+Arcfour | 2.98us | 2.98us | 601.34us | 258 |
+ChaCha (20 rounds) | 14.87us | 14.88us | 39.88us | 130 |
+ChaCha (12 rounds) | 10.38us | 10.38us | 39.88us | 130 |
+ChaCha (8 rounds) | 8.13us | 8.14us | 39.88us | 130 |
+SHA1 | 21.90us | | | 94 |
+SHA256 | 42.89us | | | 106 |
+
+
+Where a cipher supports more than one key size (such as ChaCha and Arcfour),
+the values are typically almost identical for 128-bit and 256-bit keys so only
+the maximum is shown above.
+
+*/
diff --git a/doc/mainpage.dox b/doc/mainpage.dox
index 78c8b95c..2f984512 100644
--- a/doc/mainpage.dox
+++ b/doc/mainpage.dox
@@ -88,6 +88,15 @@ The default implementation simulates the time and date based on the value of
\li \ref alarm_clock "Alarm Clock" example that uses the DS1307 or DS3232
realtime clock and the LCD library to implement an alarm clock.
+\section main_Crypto Cryptographic Library
+
+\li Block ciphers: AES128, AES192, AES256
+\li Block cipher modes: CTR, CFB, CBC, OFB
+\li Stream ciphers: ChaCha, Arcfour
+\li Hash algorithms: SHA1, SHA256
+
+More information can be found on the \ref crypto "Cryptographic Library" page.
+
\section main_IR Infrared Control Library
\li IRreceiver class that receives incoming RC-5 commands from an
diff --git a/libraries/Crypto/examples/TestChaCha/TestChaCha.ino b/libraries/Crypto/examples/TestChaCha/TestChaCha.ino
index ba0ccd8e..cc48bf9a 100644
--- a/libraries/Crypto/examples/TestChaCha/TestChaCha.ino
+++ b/libraries/Crypto/examples/TestChaCha/TestChaCha.ino
@@ -291,6 +291,39 @@ void testCipher(ChaCha *cipher, const struct TestVector *test)
Serial.println("Failed");
}
+// The data space of this sketch is too big if we try to test the
+// performance of all of setKey(), encrypt(), and decrypt().
+// Since decryption is almost identical to encryption, only test
+// that if the PERF_DECRYPT option is enabled, suppressing setKey().
+//#define PERF_DECRYPT 1
+
+#if !defined(PERF_DECRYPT)
+
+void perfCipherSetKey(ChaCha *cipher, const struct TestVector *test)
+{
+ unsigned long start;
+ unsigned long elapsed;
+ int count;
+
+ Serial.print(test->name);
+ Serial.print(" SetKey ... ");
+
+ cipher->setNumRounds(test->rounds);
+ start = micros();
+ for (count = 0; count < 1000; ++count) {
+ cipher->setKey(test->key, test->keySize);
+ cipher->setIV(test->iv, 8);
+ }
+ elapsed = micros() - start;
+
+ Serial.print(elapsed / 1000.0);
+ Serial.print("us per operation, ");
+ Serial.print((1000.0 * 1000000.0) / elapsed);
+ Serial.println(" per second");
+}
+
+#endif
+
void perfCipherEncrypt(ChaCha *cipher, const struct TestVector *test)
{
unsigned long start;
@@ -315,6 +348,8 @@ void perfCipherEncrypt(ChaCha *cipher, const struct TestVector *test)
Serial.println(" bytes per second");
}
+#if defined(PERF_DECRYPT)
+
void perfCipherDecrypt(ChaCha *cipher, const struct TestVector *test)
{
unsigned long start;
@@ -339,10 +374,17 @@ void perfCipherDecrypt(ChaCha *cipher, const struct TestVector *test)
Serial.println(" bytes per second");
}
+#endif
+
void perfCipher(ChaCha *cipher, const struct TestVector *test)
{
+#if !defined(PERF_DECRYPT)
+ perfCipherSetKey(cipher, test);
+ perfCipherEncrypt(cipher, test);
+#else
perfCipherEncrypt(cipher, test);
perfCipherDecrypt(cipher, test);
+#endif
}
void setup()