1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Remove Arcfour - not secure enough and ChaCha is pretty fast

This commit is contained in:
Rhys Weatherley 2015-01-09 19:30:21 +10:00
parent 91b3aa70e7
commit c86330b40c
6 changed files with 9 additions and 511 deletions

View File

@ -28,7 +28,7 @@
\li Block ciphers: AES128, AES192, AES256 \li Block ciphers: AES128, AES192, AES256
\li Block cipher modes: CTR, CFB, CBC, OFB \li Block cipher modes: CTR, CFB, CBC, OFB
\li Stream ciphers: ChaCha, Arcfour \li Stream ciphers: ChaCha
\li Hash algorithms: SHA1, SHA256, BLAKE2s \li Hash algorithms: SHA1, SHA256, BLAKE2s
All cryptographic algorithms have been optimized for 8-bit Arduino platforms All cryptographic algorithms have been optimized for 8-bit Arduino platforms
@ -39,8 +39,8 @@ program memory to further reduce data memory usage.
ChaCha with 20 rounds and 256-bit keys is the recommended ChaCha with 20 rounds and 256-bit keys is the recommended
symmetric encryption algorithm because it is twice as fast as AES128, symmetric encryption algorithm because it is twice as fast as AES128,
constant-time, and much more secure. AES128, AES192, AES256, and Arcfour constant-time, and much more secure. AES128, AES192, and AES256 are
are provided for use in applications where compatibility with other systems provided for use in applications where compatibility with other systems
is desirable. is desirable.
BLAKE2s is a variation on the ChaCha stream cipher, designed for hashing, BLAKE2s is a variation on the ChaCha stream cipher, designed for hashing,
@ -61,7 +61,6 @@ All figures are for the Arduino Uno running at 16 MHz:
<tr><td>AES128 (ECB mode)</td><td align="right">36.90us</td><td align="right">66.48us</td><td align="right">160.00us</td><td align="right">208</td></tr> <tr><td>AES128 (ECB mode)</td><td align="right">36.90us</td><td align="right">66.48us</td><td align="right">160.00us</td><td align="right">208</td></tr>
<tr><td>AES192 (ECB mode)</td><td align="right">44.20us</td><td align="right">80.35us</td><td align="right">166.54us</td><td align="right">240</td></tr> <tr><td>AES192 (ECB mode)</td><td align="right">44.20us</td><td align="right">80.35us</td><td align="right">166.54us</td><td align="right">240</td></tr>
<tr><td>AES256 (ECB mode)</td><td align="right">51.50us</td><td align="right">94.22us</td><td align="right">227.97us</td><td align="right">272</td></tr> <tr><td>AES256 (ECB mode)</td><td align="right">51.50us</td><td align="right">94.22us</td><td align="right">227.97us</td><td align="right">272</td></tr>
<tr><td>Arcfour</td><td align="right">2.98us</td><td align="right">2.98us</td><td align="right">601.34us</td><td align="right">258</td></tr>
<tr><td>ChaCha (20 rounds)</td><td align="right">14.87us</td><td align="right">14.88us</td><td align="right">43.74us</td><td align="right">130</td></tr> <tr><td>ChaCha (20 rounds)</td><td align="right">14.87us</td><td align="right">14.88us</td><td align="right">43.74us</td><td align="right">130</td></tr>
<tr><td>ChaCha (12 rounds)</td><td align="right">10.38us</td><td align="right">10.38us</td><td align="right">43.74us</td><td align="right">130</td></tr> <tr><td>ChaCha (12 rounds)</td><td align="right">10.38us</td><td align="right">10.38us</td><td align="right">43.74us</td><td align="right">130</td></tr>
<tr><td>ChaCha (8 rounds)</td><td align="right">8.13us</td><td align="right">8.14us</td><td align="right">43.74us</td><td align="right">130</td></tr> <tr><td>ChaCha (8 rounds)</td><td align="right">8.13us</td><td align="right">8.14us</td><td align="right">43.74us</td><td align="right">130</td></tr>
@ -70,8 +69,8 @@ All figures are for the Arduino Uno running at 16 MHz:
<tr><td>BLAKE2s</td><td align="right">18.54us</td><td> </td><td align="right"> </td><td align="right">170</td></tr> <tr><td>BLAKE2s</td><td align="right">18.54us</td><td> </td><td align="right"> </td><td align="right">170</td></tr>
</table> </table>
Where a cipher supports more than one key size (such as ChaCha and Arcfour), Where a cipher supports more than one key size (such as ChaCha), the values
the values are typically almost identical for 128-bit and 256-bit keys so only are typically almost identical for 128-bit and 256-bit keys so only the
the maximum is shown above. maximum is shown above.
*/ */

View File

@ -92,7 +92,7 @@ realtime clock and the LCD library to implement an alarm clock.
\li Block ciphers: AES128, AES192, AES256 \li Block ciphers: AES128, AES192, AES256
\li Block cipher modes: CTR, CFB, CBC, OFB \li Block cipher modes: CTR, CFB, CBC, OFB
\li Stream ciphers: ChaCha, Arcfour \li Stream ciphers: ChaCha
\li Hash algorithms: SHA1, SHA256, BLAKE2s \li Hash algorithms: SHA1, SHA256, BLAKE2s
More information can be found on the \ref crypto "Cryptographic Library" page. More information can be found on the \ref crypto "Cryptographic Library" page.

View File

@ -1,192 +0,0 @@
/*
* 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.
*/
#include "Arcfour.h"
#include "Crypto.h"
/**
* \class Arcfour Arcfour.h <Arcfour.h>
* \brief Implementation of the Arcfour stream cipher.
*
* \note While fast and small on 8-bit platforms, Arcfour is a very weak
* algorithm when used incorrectly. Security can be improved slightly using
* drop() and good key generation. Never reuse the same key with Arcfour.
* ChaCha will almost always be a better option than Arcfour.
*
* The default key size is 128 bits, but any key size between 40 and
* 256 bits (5 to 32 bytes) can be used with setKey().
*
* This implementation supports the "Arcfour-drop[N]" variant of Arcfour via
* the drop() function. This variant is used in many Internet standards
* because the prefix of the Arcfour keystream can reveal information
* about the key.
*
* Reference: http://en.wikipedia.org/wiki/RC4
*
* \sa ChaCha
*/
/**
* \brief Constructs an Arcfour cipher with no initial key.
*
* This constructor must be followed by a call to setKey() before the
* cipher can be used for encryption or decryption.
*/
Arcfour::Arcfour()
{
}
/**
* \brief Destroys this cipher object after clearing sensitive information.
*/
Arcfour::~Arcfour()
{
clean(state);
}
/**
* \brief Default key size for Arcfour in bytes.
*
* \return Always returns 16, indicating the default key length of 128 bits.
*
* Arcfour can use any key size between 40 and 256 bits (5 to 32 bytes)
* with the setKey() function.
*
* \sa setKey()
*/
size_t Arcfour::keySize() const
{
return 16;
}
/**
* \brief Size of the initialization vector for Arcfour.
*
* \return Always returns 0 because Arcfour does not use initialization vectors.
*/
size_t Arcfour::ivSize() const
{
return 0;
}
/**
* \brief Sets the Arcfour key to use for future encryption and decryption
* operations.
*
* \param key The key which must contain between 5 and 32 bytes,
* with at least 16 recommended.
* \param len The length of the key in bytes.
* \return Returns false if the key length is not between 5 and 32;
* or true if the key was set successfully.
*
* It is a good idea to drop() the prefix from the keystream before using
* it to encrypt() or decrypt() because the prefix can reveal information
* about the key.
*
* Reference: http://en.wikipedia.org/wiki/RC4#Key-scheduling_algorithm_.28KSA.29
*
* \sa drop()
*/
bool Arcfour::setKey(const uint8_t *key, size_t len)
{
// Check the key length.
if (len < 5 || len > 32)
return false;
// Set up the key schedule.
size_t i, k;
uint8_t j, t;
uint8_t *s = state.s;
for (i = 0; i < 256; ++i)
s[i] = i;
j = 0;
k = 0;
for (i = 0; i < 256; ++i) {
t = s[i];
j += t + key[k];
s[i] = s[j];
s[j] = t;
if (++k >= len)
k = 0;
}
state.i = 0;
state.j = 0;
return true;
}
bool Arcfour::setIV(const uint8_t *, size_t len)
{
// Initialization vectors are not supported by Arcfour.
return len == 0;
}
void Arcfour::encrypt(uint8_t *output, const uint8_t *input, size_t len)
{
while (len > 0) {
++state.i;
state.j += state.s[state.i];
uint8_t t = state.s[state.i];
uint8_t u = state.s[state.j];
state.s[state.i] = u;
state.s[state.j] = t;
*output++ = *input++ ^ state.s[(u + t) & 0xFF];
--len;
}
}
void Arcfour::decrypt(uint8_t *output, const uint8_t *input, size_t len)
{
encrypt(output, input, len);
}
void Arcfour::clear()
{
clean(state);
}
/**
* \brief Drops the next \a count bytes of keystream data.
*
* \param count The number of bytes to drop.
*
* The initial keystream data that emerges from Arcfour after the key is set
* can reveal information about the key. This function can be used to
* drop bytes from the prefix of the keystream until the predictable part
* has been exhausted. Encryption can then safely use the keystream that
* follows the dropped bytes.
*
* Reference: http://en.wikipedia.org/wiki/RC4#Fluhrer.2C_Mantin_and_Shamir_attack
*
* \sa setKey()
*/
void Arcfour::drop(size_t count)
{
while (count > 0) {
++state.i;
state.j = state.j + state.s[state.i];
uint8_t t = state.s[state.i];
uint8_t u = state.s[state.j];
state.s[state.i] = u;
state.s[state.j] = t;
--count;
}
}

View File

@ -1,54 +0,0 @@
/*
* 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.
*/
#ifndef CRYPTO_Arcfour_h
#define CRYPTO_Arcfour_h
#include "Cipher.h"
class Arcfour : public Cipher
{
public:
Arcfour();
virtual ~Arcfour();
size_t keySize() const;
size_t ivSize() const;
bool setKey(const uint8_t *key, size_t len);
bool setIV(const uint8_t *iv, size_t len);
void encrypt(uint8_t *output, const uint8_t *input, size_t len);
void decrypt(uint8_t *output, const uint8_t *input, size_t len);
void clear();
void drop(size_t count);
private:
struct {
uint8_t i, j;
uint8_t s[256];
} state;
};
#endif

View File

@ -31,9 +31,8 @@
* bytes that are input to encrypt() or decrypt() is exactly the same as * bytes that are input to encrypt() or decrypt() is exactly the same as
* the number of bytes that are output. * the number of bytes that are output.
* *
* All of the stream ciphers such as Arcfour and ChaCha inherit * All of the stream ciphers such as ChaCha inherit directly from this class,
* directly from this class, together with block cipher modes such as * together with block cipher modes such as CTR and CFB.
* CTR and CFB.
*/ */
/** /**

View File

@ -1,254 +0,0 @@
/*
* 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.
*/
/*
This example runs tests on the Arcfour implementation to verify correct behaviour.
*/
#include <Crypto.h>
#include <Arcfour.h>
#include <string.h>
struct ArcfourVector
{
size_t offset;
byte keystream[16];
};
// A small selection of test vectors from RFC 6229.
static ArcfourVector const testArcfour40Key1[] = {
{ 0, {0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27,
0xcc, 0xc3, 0x52, 0x4a, 0x0a, 0x11, 0x18, 0xa8}},
{ 240, {0x28, 0xcb, 0x11, 0x32, 0xc9, 0x6c, 0xe2, 0x86,
0x42, 0x1d, 0xca, 0xad, 0xb8, 0xb6, 0x9e, 0xae}},
{ 768, {0xeb, 0x62, 0x63, 0x8d, 0x4f, 0x0b, 0xa1, 0xfe,
0x9f, 0xca, 0x20, 0xe0, 0x5b, 0xf8, 0xff, 0x2b}},
{2048, {0xcc, 0x58, 0x2f, 0x8b, 0xa9, 0xf2, 0x65, 0xe2,
0xb1, 0xbe, 0x91, 0x12, 0xe9, 0x75, 0xd2, 0xd7}},
{4096, {0xff, 0x25, 0xb5, 0x89, 0x95, 0x99, 0x67, 0x07,
0xe5, 0x1f, 0xbd, 0xf0, 0x8b, 0x34, 0xd8, 0x75}}
};
static ArcfourVector const testArcfour128Key1[] = {
{ 0, {0x9a, 0xc7, 0xcc, 0x9a, 0x60, 0x9d, 0x1e, 0xf7,
0xb2, 0x93, 0x28, 0x99, 0xcd, 0xe4, 0x1b, 0x97}},
{ 240, {0x06, 0x59, 0x02, 0xe4, 0xb6, 0x20, 0xf6, 0xcc,
0x36, 0xc8, 0x58, 0x9f, 0x66, 0x43, 0x2f, 0x2b}},
{ 768, {0xec, 0xcb, 0xe1, 0x3d, 0xe1, 0xfc, 0xc9, 0x1c,
0x11, 0xa0, 0xb2, 0x6c, 0x0b, 0xc8, 0xfa, 0x4d}},
{2048, {0x8a, 0x44, 0x12, 0x64, 0x11, 0xea, 0xa7, 0x8b,
0xd5, 0x1e, 0x8d, 0x87, 0xa8, 0x87, 0x9b, 0xf5}},
{4096, {0xa3, 0x6a, 0x4c, 0x30, 0x1a, 0xe8, 0xac, 0x13,
0x61, 0x0c, 0xcb, 0xc1, 0x22, 0x56, 0xca, 0xcc}}
};
static ArcfourVector const testArcfour256Key1[] = {
{ 0, {0xea, 0xa6, 0xbd, 0x25, 0x88, 0x0b, 0xf9, 0x3d,
0x3f, 0x5d, 0x1e, 0x4c, 0xa2, 0x61, 0x1d, 0x91}},
{ 240, {0x11, 0x4a, 0xe3, 0x44, 0xde, 0xd7, 0x1b, 0x35,
0xf2, 0xe6, 0x0f, 0xeb, 0xad, 0x72, 0x7f, 0xd8}},
{ 768, {0xe7, 0xa7, 0xb9, 0xe9, 0xec, 0x54, 0x0d, 0x5f,
0xf4, 0x3b, 0xdb, 0x12, 0x79, 0x2d, 0x1b, 0x35}},
{2048, {0x18, 0xb6, 0x25, 0x03, 0xbf, 0xbc, 0x07, 0x7f,
0xba, 0xbb, 0x98, 0xf2, 0x0d, 0x98, 0xab, 0x34}},
{4096, {0xf3, 0xe4, 0xc0, 0xa2, 0xe0, 0x2d, 0x1d, 0x01,
0xf7, 0xf0, 0xa7, 0x46, 0x18, 0xaf, 0x2b, 0x48}}
};
static ArcfourVector const testArcfour40Key2[] = {
{ 0, {0x80, 0xad, 0x97, 0xbd, 0xc9, 0x73, 0xdf, 0x8a,
0x2e, 0x87, 0x9e, 0x92, 0xa4, 0x97, 0xef, 0xda}},
{ 240, {0xfa, 0xa1, 0x48, 0xe9, 0x90, 0x46, 0x18, 0x1f,
0xec, 0x6b, 0x20, 0x85, 0xf3, 0xb2, 0x0e, 0xd9}},
{ 768, {0x75, 0xd5, 0xef, 0x26, 0x2b, 0x44, 0xc4, 0x1a,
0x9c, 0xf6, 0x3a, 0xe1, 0x45, 0x68, 0xe1, 0xb9}},
{2048, {0x78, 0x5b, 0x60, 0xfd, 0x7e, 0xc4, 0xe9, 0xfc,
0xb6, 0x54, 0x5f, 0x35, 0x0d, 0x66, 0x0f, 0xab}},
{4096, {0xbf, 0x42, 0xc3, 0x01, 0x8c, 0x2f, 0x7c, 0x66,
0xbf, 0xde, 0x52, 0x49, 0x75, 0x76, 0x81, 0x15}}
};
static ArcfourVector const testArcfour128Key2[] = {
{ 0, {0x72, 0x0c, 0x94, 0xb6, 0x3e, 0xdf, 0x44, 0xe1,
0x31, 0xd9, 0x50, 0xca, 0x21, 0x1a, 0x5a, 0x30}},
{ 240, {0xb3, 0x39, 0x4a, 0x40, 0xaa, 0xbf, 0x75, 0xcb,
0xa4, 0x22, 0x82, 0xef, 0x25, 0xa0, 0x05, 0x9f}},
{ 768, {0xef, 0x2d, 0x67, 0x6f, 0x15, 0x45, 0xc2, 0xc1,
0x3d, 0xc6, 0x80, 0xa0, 0x2f, 0x4a, 0xdb, 0xfe}},
{2048, {0x58, 0x65, 0xfd, 0xbb, 0x5b, 0x48, 0x06, 0x41,
0x04, 0xe8, 0x30, 0xb3, 0x80, 0xf2, 0xae, 0xde}},
{4096, {0x5b, 0xbe, 0xb4, 0x78, 0x7d, 0x59, 0xe5, 0x37,
0x3f, 0xdb, 0xea, 0x6c, 0x6f, 0x75, 0xc2, 0x9b}}
};
static ArcfourVector const testArcfour256Key2[] = {
{ 0, {0xdd, 0x5b, 0xcb, 0x00, 0x18, 0xe9, 0x22, 0xd4,
0x94, 0x75, 0x9d, 0x7c, 0x39, 0x5d, 0x02, 0xd3}},
{ 240, {0xaf, 0x3e, 0x30, 0xf9, 0xc0, 0x95, 0x04, 0x59,
0x38, 0x15, 0x15, 0x75, 0xc3, 0xfb, 0x90, 0x98}},
{ 768, {0x85, 0x14, 0xa5, 0x49, 0x58, 0x58, 0x09, 0x6f,
0x59, 0x6e, 0x4b, 0xcd, 0x66, 0xb1, 0x06, 0x65}},
{2048, {0xdd, 0xd2, 0x78, 0x20, 0x55, 0x01, 0x26, 0x69,
0x8e, 0xfa, 0xad, 0xc6, 0x4b, 0x64, 0xf6, 0x6e}},
{4096, {0x37, 0x0b, 0x1c, 0x1f, 0xe6, 0x55, 0x91, 0x6d,
0x97, 0xfd, 0x0d, 0x47, 0xca, 0x1d, 0x72, 0xb8}}
};
static byte const key1[] = {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20
};
static byte const key2[] = {
0x1a, 0xda, 0x31, 0xd5, 0xcf, 0x68, 0x82, 0x21,
0xc1, 0x09, 0x16, 0x39, 0x08, 0xeb, 0xe5, 0x1d,
0xeb, 0xb4, 0x62, 0x27, 0xc6, 0xcc, 0x8b, 0x37,
0x64, 0x19, 0x10, 0x83, 0x32, 0x22, 0x77, 0x2a
};
#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
Arcfour cipher;
byte buffer[16];
byte buffer2[128];
byte const zeroes[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
void testArcfour(const char *name, const byte *key, size_t keySize, const struct ArcfourVector *vectors, size_t numVectors)
{
bool ok = true;
Serial.print(name);
Serial.print(" ... ");
while (numVectors > 0) {
cipher.setKey(key, keySize);
cipher.drop(vectors->offset);
memset(buffer, 0, sizeof(buffer));
cipher.encrypt(buffer, buffer, sizeof(buffer));
if (memcmp(buffer, vectors->keystream, sizeof(buffer)) != 0)
ok = false;
cipher.setKey(key, keySize);
cipher.drop(vectors->offset);
cipher.decrypt(buffer, buffer, sizeof(buffer));
if (memcmp(buffer, zeroes, sizeof(buffer)) != 0)
ok = false;
++vectors;
--numVectors;
}
Serial.println(ok ? "passed" : "failed");
}
void perfArcfourSetKey(const char *name, const uint8_t *key, size_t size)
{
unsigned long start;
unsigned long elapsed;
int count;
Serial.print(name);
Serial.print(" ... ");
start = micros();
for (count = 0; count < 1000; ++count) {
cipher.setKey(key, size);
}
elapsed = micros() - start;
Serial.print(elapsed / 1000.0);
Serial.print("us per operation, ");
Serial.print((1000.0 * 1000000.0) / elapsed);
Serial.println(" per second");
}
void perfArcfourEncrypt(const char *name, const uint8_t *key, size_t size)
{
unsigned long start;
unsigned long elapsed;
int count;
Serial.print(name);
Serial.print(" ... ");
cipher.setKey(key, size);
start = micros();
for (count = 0; count < 3000; ++count) {
cipher.encrypt(buffer2, buffer2, sizeof(buffer2));
}
elapsed = micros() - start;
Serial.print(elapsed / (sizeof(buffer2) * 3000.0));
Serial.print("us per byte, ");
Serial.print((sizeof(buffer2) * 3000.0 * 1000000.0) / elapsed);
Serial.println(" bytes per second");
}
void perfArcfourDecrypt(const char *name, const uint8_t *key, size_t size)
{
unsigned long start;
unsigned long elapsed;
int count;
Serial.print(name);
Serial.print(" ... ");
cipher.setKey(key, size);
start = micros();
for (count = 0; count < 3000; ++count) {
cipher.decrypt(buffer2, buffer2, sizeof(buffer2));
}
elapsed = micros() - start;
Serial.print(elapsed / (sizeof(buffer2) * 3000.0));
Serial.print("us per byte, ");
Serial.print((sizeof(buffer2) * 3000.0 * 1000000.0) / elapsed);
Serial.println(" bytes per second");
}
void setup()
{
Serial.begin(9600);
Serial.println();
Serial.println("Test Vectors:");
testArcfour("Arcfour Key1 40 bit", key1, 5,
testArcfour40Key1, ArraySize(testArcfour40Key1));
testArcfour("Arcfour Key1 128 bit", key1, 16,
testArcfour128Key1, ArraySize(testArcfour128Key1));
testArcfour("Arcfour Key1 256 bit", key1, 32,
testArcfour256Key1, ArraySize(testArcfour256Key1));
testArcfour("Arcfour Key2 40 bit", key2 + (32 - 5), 5,
testArcfour40Key2, ArraySize(testArcfour40Key2));
testArcfour("Arcfour Key2 128 bit", key2 + 16, 16,
testArcfour128Key2, ArraySize(testArcfour128Key2));
testArcfour("Arcfour Key2 256 bit", key2, 32,
testArcfour256Key2, ArraySize(testArcfour256Key2));
Serial.println();
Serial.println("Performance Tests:");
perfArcfourSetKey("Arcfour SetKey 40 bit", key1, 5);
perfArcfourSetKey("Arcfour SetKey 128 bit", key1, 16);
perfArcfourSetKey("Arcfour SetKey 256 bit", key1, 32);
perfArcfourEncrypt("Arcfour Encrypt", key1, 16);
perfArcfourDecrypt("Arcfour Decrypt", key1, 16);
}
void loop()
{
}