diff --git a/AES128_8cpp_source.html b/AES128_8cpp_source.html index 9fe100e4..da98104e 100644 --- a/AES128_8cpp_source.html +++ b/AES128_8cpp_source.html @@ -175,7 +175,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AES192_8cpp_source.html b/AES192_8cpp_source.html index 2d904d7e..c4a81e60 100644 --- a/AES192_8cpp_source.html +++ b/AES192_8cpp_source.html @@ -175,7 +175,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AES256_8cpp_source.html b/AES256_8cpp_source.html index b9682fb4..b7891243 100644 --- a/AES256_8cpp_source.html +++ b/AES256_8cpp_source.html @@ -182,7 +182,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AESCommon_8cpp_source.html b/AESCommon_8cpp_source.html index 6daa18a7..b5c24406 100644 --- a/AESCommon_8cpp_source.html +++ b/AESCommon_8cpp_source.html @@ -415,7 +415,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AES_8h_source.html b/AES_8h_source.html index c328d957..7042c63b 100644 --- a/AES_8h_source.html +++ b/AES_8h_source.html @@ -203,7 +203,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AuthenticatedCipher_8cpp_source.html b/AuthenticatedCipher_8cpp_source.html index dd0ccde5..f06625b8 100644 --- a/AuthenticatedCipher_8cpp_source.html +++ b/AuthenticatedCipher_8cpp_source.html @@ -125,7 +125,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/AuthenticatedCipher_8h_source.html b/AuthenticatedCipher_8h_source.html index 5b9092a3..a4e33026 100644 --- a/AuthenticatedCipher_8h_source.html +++ b/AuthenticatedCipher_8h_source.html @@ -141,7 +141,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BLAKE2b_8cpp_source.html b/BLAKE2b_8cpp_source.html index 3fcac93b..00ca5f6a 100644 --- a/BLAKE2b_8cpp_source.html +++ b/BLAKE2b_8cpp_source.html @@ -365,7 +365,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BLAKE2b_8h_source.html b/BLAKE2b_8h_source.html index e1a37e22..52e2f7e8 100644 --- a/BLAKE2b_8h_source.html +++ b/BLAKE2b_8h_source.html @@ -164,7 +164,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BLAKE2s_8cpp_source.html b/BLAKE2s_8cpp_source.html index a0dde02c..3f3626d3 100644 --- a/BLAKE2s_8cpp_source.html +++ b/BLAKE2s_8cpp_source.html @@ -356,7 +356,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BLAKE2s_8h_source.html b/BLAKE2s_8h_source.html index 479b8919..52af2cec 100644 --- a/BLAKE2s_8h_source.html +++ b/BLAKE2s_8h_source.html @@ -163,7 +163,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BigNumberUtil_8cpp_source.html b/BigNumberUtil_8cpp_source.html index 39169912..defeb172 100644 --- a/BigNumberUtil_8cpp_source.html +++ b/BigNumberUtil_8cpp_source.html @@ -682,7 +682,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BigNumberUtil_8h_source.html b/BigNumberUtil_8h_source.html index 5027270f..b163dd26 100644 --- a/BigNumberUtil_8h_source.html +++ b/BigNumberUtil_8h_source.html @@ -117,92 +117,93 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
27 #include <stddef.h>
28 
29 // Define exactly one of these to 1 to set the size of the basic limb type.
-
30 #if defined(__AVR__)
+
30 #if defined(__AVR__) || defined(ESP8266)
31 // 16-bit limbs seem to give the best performance on 8-bit AVR micros.
-
32 #define BIGNUMBER_LIMB_8BIT 0
-
33 #define BIGNUMBER_LIMB_16BIT 1
-
34 #define BIGNUMBER_LIMB_32BIT 0
-
35 #define BIGNUMBER_LIMB_64BIT 0
-
36 #elif defined(__GNUC__) && __WORDSIZE == 64
-
37 // 64-bit system with 128-bit double limbs.
-
38 #define BIGNUMBER_LIMB_8BIT 0
-
39 #define BIGNUMBER_LIMB_16BIT 0
-
40 #define BIGNUMBER_LIMB_32BIT 0
-
41 #define BIGNUMBER_LIMB_64BIT 1
-
42 #else
-
43 // On all other platforms, assume 32-bit is best.
-
44 #define BIGNUMBER_LIMB_8BIT 0
-
45 #define BIGNUMBER_LIMB_16BIT 0
-
46 #define BIGNUMBER_LIMB_32BIT 1
-
47 #define BIGNUMBER_LIMB_64BIT 0
-
48 #endif
-
49 
-
50 // Define the limb types to use on this platform.
-
51 #if BIGNUMBER_LIMB_8BIT
-
52 typedef uint8_t limb_t;
-
53 typedef int8_t slimb_t;
-
54 typedef uint16_t dlimb_t;
-
55 #elif BIGNUMBER_LIMB_16BIT
-
56 typedef uint16_t limb_t;
-
57 typedef int16_t slimb_t;
-
58 typedef uint32_t dlimb_t;
-
59 #elif BIGNUMBER_LIMB_32BIT
-
60 typedef uint32_t limb_t;
-
61 typedef int32_t slimb_t;
-
62 typedef uint64_t dlimb_t;
-
63 #elif BIGNUMBER_LIMB_64BIT
-
64 typedef uint64_t limb_t;
-
65 typedef int64_t slimb_t;
-
66 typedef unsigned __int128 dlimb_t;
-
67 #else
-
68 #error "limb_t must be 8, 16, 32, or 64 bits in size"
-
69 #endif
-
70 
-
71 class BigNumberUtil
-
72 {
-
73 public:
-
74  static void unpackLE(limb_t *limbs, size_t count,
-
75  const uint8_t *bytes, size_t len);
-
76  static void unpackBE(limb_t *limbs, size_t count,
-
77  const uint8_t *bytes, size_t len);
-
78  static void packLE(uint8_t *bytes, size_t len,
-
79  const limb_t *limbs, size_t count);
-
80  static void packBE(uint8_t *bytes, size_t len,
-
81  const limb_t *limbs, size_t count);
-
82 
-
83  static limb_t add(limb_t *result, const limb_t *x,
-
84  const limb_t *y, size_t size);
-
85  static limb_t sub(limb_t *result, const limb_t *x,
-
86  const limb_t *y, size_t size);
-
87  static void mul(limb_t *result, const limb_t *x, size_t xcount,
-
88  const limb_t *y, size_t ycount);
-
89  static void reduceQuick(limb_t *result, const limb_t *x,
-
90  const limb_t *y, size_t size);
-
91 
-
92  static limb_t add_P(limb_t *result, const limb_t *x,
-
93  const limb_t *y, size_t size);
-
94  static limb_t sub_P(limb_t *result, const limb_t *x,
-
95  const limb_t *y, size_t size);
-
96  static void mul_P(limb_t *result, const limb_t *x, size_t xcount,
-
97  const limb_t *y, size_t ycount);
-
98  static void reduceQuick_P(limb_t *result, const limb_t *x,
-
99  const limb_t *y, size_t size);
-
100 
-
101  static limb_t isZero(const limb_t *x, size_t size);
-
102 
-
103 private:
-
104  // Constructor and destructor are private - cannot instantiate this class.
-
105  BigNumberUtil() {}
-
106  ~BigNumberUtil() {}
-
107 };
-
108 
-
109 #endif
+
32 // They also seem to give better performance on ESP8266 as well.
+
33 #define BIGNUMBER_LIMB_8BIT 0
+
34 #define BIGNUMBER_LIMB_16BIT 1
+
35 #define BIGNUMBER_LIMB_32BIT 0
+
36 #define BIGNUMBER_LIMB_64BIT 0
+
37 #elif defined(__GNUC__) && __WORDSIZE == 64
+
38 // 64-bit system with 128-bit double limbs.
+
39 #define BIGNUMBER_LIMB_8BIT 0
+
40 #define BIGNUMBER_LIMB_16BIT 0
+
41 #define BIGNUMBER_LIMB_32BIT 0
+
42 #define BIGNUMBER_LIMB_64BIT 1
+
43 #else
+
44 // On all other platforms, assume 32-bit is best.
+
45 #define BIGNUMBER_LIMB_8BIT 0
+
46 #define BIGNUMBER_LIMB_16BIT 0
+
47 #define BIGNUMBER_LIMB_32BIT 1
+
48 #define BIGNUMBER_LIMB_64BIT 0
+
49 #endif
+
50 
+
51 // Define the limb types to use on this platform.
+
52 #if BIGNUMBER_LIMB_8BIT
+
53 typedef uint8_t limb_t;
+
54 typedef int8_t slimb_t;
+
55 typedef uint16_t dlimb_t;
+
56 #elif BIGNUMBER_LIMB_16BIT
+
57 typedef uint16_t limb_t;
+
58 typedef int16_t slimb_t;
+
59 typedef uint32_t dlimb_t;
+
60 #elif BIGNUMBER_LIMB_32BIT
+
61 typedef uint32_t limb_t;
+
62 typedef int32_t slimb_t;
+
63 typedef uint64_t dlimb_t;
+
64 #elif BIGNUMBER_LIMB_64BIT
+
65 typedef uint64_t limb_t;
+
66 typedef int64_t slimb_t;
+
67 typedef unsigned __int128 dlimb_t;
+
68 #else
+
69 #error "limb_t must be 8, 16, 32, or 64 bits in size"
+
70 #endif
+
71 
+
72 class BigNumberUtil
+
73 {
+
74 public:
+
75  static void unpackLE(limb_t *limbs, size_t count,
+
76  const uint8_t *bytes, size_t len);
+
77  static void unpackBE(limb_t *limbs, size_t count,
+
78  const uint8_t *bytes, size_t len);
+
79  static void packLE(uint8_t *bytes, size_t len,
+
80  const limb_t *limbs, size_t count);
+
81  static void packBE(uint8_t *bytes, size_t len,
+
82  const limb_t *limbs, size_t count);
+
83 
+
84  static limb_t add(limb_t *result, const limb_t *x,
+
85  const limb_t *y, size_t size);
+
86  static limb_t sub(limb_t *result, const limb_t *x,
+
87  const limb_t *y, size_t size);
+
88  static void mul(limb_t *result, const limb_t *x, size_t xcount,
+
89  const limb_t *y, size_t ycount);
+
90  static void reduceQuick(limb_t *result, const limb_t *x,
+
91  const limb_t *y, size_t size);
+
92 
+
93  static limb_t add_P(limb_t *result, const limb_t *x,
+
94  const limb_t *y, size_t size);
+
95  static limb_t sub_P(limb_t *result, const limb_t *x,
+
96  const limb_t *y, size_t size);
+
97  static void mul_P(limb_t *result, const limb_t *x, size_t xcount,
+
98  const limb_t *y, size_t ycount);
+
99  static void reduceQuick_P(limb_t *result, const limb_t *x,
+
100  const limb_t *y, size_t size);
+
101 
+
102  static limb_t isZero(const limb_t *x, size_t size);
+
103 
+
104 private:
+
105  // Constructor and destructor are private - cannot instantiate this class.
+
106  BigNumberUtil() {}
+
107  ~BigNumberUtil() {}
+
108 };
+
109 
+
110 #endif
BigNumberUtil::reduceQuick_P
static void reduceQuick_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction where y is in program memory.
Definition: BigNumberUtil.cpp:734
BigNumberUtil::add
static limb_t add(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers.
Definition: BigNumberUtil.cpp:495
BigNumberUtil::sub_P
static limb_t sub_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Subtracts one big number from another where one is in program memory.
Definition: BigNumberUtil.cpp:655
BigNumberUtil::reduceQuick
static void reduceQuick(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction.
Definition: BigNumberUtil.cpp:598
BigNumberUtil::sub
static limb_t sub(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Subtracts one big number from another.
Definition: BigNumberUtil.cpp:522
-
BigNumberUtil
Utilities to assist with implementing big number arithmetic.
Definition: BigNumberUtil.h:71
+
BigNumberUtil
Utilities to assist with implementing big number arithmetic.
Definition: BigNumberUtil.h:72
BigNumberUtil::mul_P
static void mul_P(limb_t *result, const limb_t *x, size_t xcount, const limb_t *y, size_t ycount)
Multiplies two big numbers where one is in program memory.
Definition: BigNumberUtil.cpp:680
BigNumberUtil::packBE
static void packBE(uint8_t *bytes, size_t len, const limb_t *limbs, size_t count)
Packs the big-endian byte representation of a big number into a byte array.
Definition: BigNumberUtil.cpp:375
BigNumberUtil::unpackLE
static void unpackLE(limb_t *limbs, size_t count, const uint8_t *bytes, size_t len)
Unpacks the little-endian byte representation of a big number into a limb array.
Definition: BigNumberUtil.cpp:55
@@ -214,7 +215,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Bitmap_8cpp_source.html b/Bitmap_8cpp_source.html index cf88b529..f54ce9b0 100644 --- a/Bitmap_8cpp_source.html +++ b/Bitmap_8cpp_source.html @@ -694,7 +694,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Bitmap_8h_source.html b/Bitmap_8h_source.html index ed576d28..c694ab6c 100644 --- a/Bitmap_8h_source.html +++ b/Bitmap_8h_source.html @@ -271,7 +271,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BlinkLED_8cpp_source.html b/BlinkLED_8cpp_source.html index 04ea742e..ec4af19c 100644 --- a/BlinkLED_8cpp_source.html +++ b/BlinkLED_8cpp_source.html @@ -196,7 +196,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BlinkLED_8h_source.html b/BlinkLED_8h_source.html index acf2bb93..dbc5b070 100644 --- a/BlinkLED_8h_source.html +++ b/BlinkLED_8h_source.html @@ -157,7 +157,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BlockCipher_8cpp_source.html b/BlockCipher_8cpp_source.html index cf240d21..f863adcb 100644 --- a/BlockCipher_8cpp_source.html +++ b/BlockCipher_8cpp_source.html @@ -125,7 +125,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BlockCipher_8h_source.html b/BlockCipher_8h_source.html index b2931f55..fe012ca1 100644 --- a/BlockCipher_8h_source.html +++ b/BlockCipher_8h_source.html @@ -146,7 +146,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BoolField_8cpp_source.html b/BoolField_8cpp_source.html index c1ac3839..25697491 100644 --- a/BoolField_8cpp_source.html +++ b/BoolField_8cpp_source.html @@ -202,7 +202,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/BoolField_8h_source.html b/BoolField_8h_source.html index 68dd35d0..b1f173b5 100644 --- a/BoolField_8h_source.html +++ b/BoolField_8h_source.html @@ -160,7 +160,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CBC_8cpp_source.html b/CBC_8cpp_source.html index fb314670..a45d3395 100644 --- a/CBC_8cpp_source.html +++ b/CBC_8cpp_source.html @@ -208,7 +208,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CBC_8h_source.html b/CBC_8h_source.html index 4d2fa619..6234b2ff 100644 --- a/CBC_8h_source.html +++ b/CBC_8h_source.html @@ -172,7 +172,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CFB_8cpp_source.html b/CFB_8cpp_source.html index 8cdddcd9..785615b7 100644 --- a/CFB_8cpp_source.html +++ b/CFB_8cpp_source.html @@ -233,7 +233,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CFB_8h_source.html b/CFB_8h_source.html index 30802f45..8a226264 100644 --- a/CFB_8h_source.html +++ b/CFB_8h_source.html @@ -171,7 +171,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CTR_8cpp_source.html b/CTR_8cpp_source.html index 57e92125..f8709137 100644 --- a/CTR_8cpp_source.html +++ b/CTR_8cpp_source.html @@ -228,7 +228,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/CTR_8h_source.html b/CTR_8h_source.html index 04c82148..d9c03420 100644 --- a/CTR_8h_source.html +++ b/CTR_8h_source.html @@ -175,7 +175,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaChaPoly_8cpp_source.html b/ChaChaPoly_8cpp_source.html index 66f131db..a122ef54 100644 --- a/ChaChaPoly_8cpp_source.html +++ b/ChaChaPoly_8cpp_source.html @@ -263,7 +263,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaChaPoly_8h_source.html b/ChaChaPoly_8h_source.html index ae5339c4..82105910 100644 --- a/ChaChaPoly_8h_source.html +++ b/ChaChaPoly_8h_source.html @@ -173,7 +173,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaCha_8cpp_source.html b/ChaCha_8cpp_source.html index 4b8768f5..d43b4971 100644 --- a/ChaCha_8cpp_source.html +++ b/ChaCha_8cpp_source.html @@ -311,7 +311,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaCha_8h_source.html b/ChaCha_8h_source.html index b89912a6..54353d37 100644 --- a/ChaCha_8h_source.html +++ b/ChaCha_8h_source.html @@ -170,7 +170,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Charlieplex_8cpp_source.html b/Charlieplex_8cpp_source.html index e3f23e4e..8901810d 100644 --- a/Charlieplex_8cpp_source.html +++ b/Charlieplex_8cpp_source.html @@ -232,7 +232,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Charlieplex_8h_source.html b/Charlieplex_8h_source.html index b605fd31..29044ecb 100644 --- a/Charlieplex_8h_source.html +++ b/Charlieplex_8h_source.html @@ -162,7 +162,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaseLEDs_8cpp_source.html b/ChaseLEDs_8cpp_source.html index b495579e..5a5eed4a 100644 --- a/ChaseLEDs_8cpp_source.html +++ b/ChaseLEDs_8cpp_source.html @@ -160,7 +160,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ChaseLEDs_8h_source.html b/ChaseLEDs_8h_source.html index 74fcf0b0..eb5090f4 100644 --- a/ChaseLEDs_8h_source.html +++ b/ChaseLEDs_8h_source.html @@ -149,7 +149,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Cipher_8cpp_source.html b/Cipher_8cpp_source.html index 5abf8077..b9d92279 100644 --- a/Cipher_8cpp_source.html +++ b/Cipher_8cpp_source.html @@ -125,7 +125,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Cipher_8h_source.html b/Cipher_8h_source.html index 763bffc2..6d7f6447 100644 --- a/Cipher_8h_source.html +++ b/Cipher_8h_source.html @@ -148,7 +148,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Crypto_8cpp_source.html b/Crypto_8cpp_source.html index f1b86534..4f888e41 100644 --- a/Crypto_8cpp_source.html +++ b/Crypto_8cpp_source.html @@ -158,7 +158,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Crypto_8h_source.html b/Crypto_8h_source.html index c13b0beb..6e1cc261 100644 --- a/Crypto_8h_source.html +++ b/Crypto_8h_source.html @@ -126,11 +126,18 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
36 
37 bool secure_compare(const void *data1, const void *data2, size_t len);
38 
-
39 #endif
+
39 #if defined(ESP8266)
+
40 extern "C" void system_soft_wdt_feed(void);
+
41 #define crypto_feed_watchdog() system_soft_wdt_feed()
+
42 #else
+
43 #define crypto_feed_watchdog() do { ; } while (0)
+
44 #endif
+
45 
+
46 #endif
diff --git a/Curve25519_8cpp_source.html b/Curve25519_8cpp_source.html index 38a87321..2bd9d15e 100644 --- a/Curve25519_8cpp_source.html +++ b/Curve25519_8cpp_source.html @@ -878,578 +878,579 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
934  mulNoReduce(temp, x, y);
935  reduce(result, temp, NUM_LIMBS_256BIT);
936  strict_clean(temp);
-
937 }
-
938 
-
958 void Curve25519::mulA24(limb_t *result, const limb_t *x)
-
959 {
-
960 #if !defined(CURVE25519_ASM_AVR)
-
961  // The constant a24 = 121665 (0x1DB41) as a limb array.
-
962 #if BIGNUMBER_LIMB_8BIT
-
963  static limb_t const a24[3] PROGMEM = {0x41, 0xDB, 0x01};
-
964 #elif BIGNUMBER_LIMB_16BIT
-
965  static limb_t const a24[2] PROGMEM = {0xDB41, 0x0001};
-
966 #elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
-
967  static limb_t const a24[1] PROGMEM = {0x0001DB41};
-
968 #else
-
969  #error "limb_t must be 8, 16, 32, or 64 bits in size"
-
970 #endif
-
971  #define NUM_A24_LIMBS (sizeof(a24) / sizeof(limb_t))
-
972 
-
973  // Multiply the lowest limb of a24 by x and zero-extend into the result.
-
974  limb_t temp[NUM_LIMBS_512BIT];
-
975  uint8_t i, j;
-
976  dlimb_t carry = 0;
-
977  limb_t word = pgm_read_limb(&(a24[0]));
-
978  const limb_t *xx = x;
-
979  limb_t *tt = temp;
-
980  for (i = 0; i < NUM_LIMBS_256BIT; ++i) {
-
981  carry += ((dlimb_t)(*xx++)) * word;
-
982  *tt++ = (limb_t)carry;
-
983  carry >>= LIMB_BITS;
-
984  }
-
985  *tt = (limb_t)carry;
-
986 
-
987  // Multiply and add the remaining limbs of a24.
-
988  for (i = 1; i < NUM_A24_LIMBS; ++i) {
-
989  word = pgm_read_limb(&(a24[i]));
-
990  carry = 0;
-
991  xx = x;
-
992  tt = temp + i;
-
993  for (j = 0; j < NUM_LIMBS_256BIT; ++j) {
-
994  carry += ((dlimb_t)(*xx++)) * word;
-
995  carry += *tt;
-
996  *tt++ = (limb_t)carry;
-
997  carry >>= LIMB_BITS;
-
998  }
-
999  *tt = (limb_t)carry;
-
1000  }
-
1001 #else
-
1002  limb_t temp[NUM_LIMBS_512BIT];
-
1003  #define NUM_A24_LIMBS ((3 + sizeof(limb_t) - 1) / sizeof(limb_t))
-
1004  __asm__ __volatile__ (
-
1005  // Load the two low bytes of a24 into r16 and r17.
-
1006  // The third byte is 0x01 which we can deal with implicitly.
-
1007  "ldi r16,0x41\n"
-
1008  "ldi r17,0xDB\n"
-
1009 
-
1010  // Iterate over the bytes of "x" and multiply each with a24.
-
1011  "ldi r25,32\n" // 32 bytes in "x"
-
1012  "clr r22\n" // r22 = 0
-
1013  "clr r18\n" // r18:r19:r11 = 0 (carry)
-
1014  "clr r19\n"
-
1015  "clr r11\n"
-
1016  "1:\n"
-
1017  "ld r21,X+\n" // r21 = *x++
-
1018  "mul r21,r16\n" // r8:r9 = r21 * a24[0]
-
1019  "movw r8,r0\n"
-
1020  "mul r21,r17\n" // r9:r1 += r21 * a24[1]
-
1021  "add r9,r0\n"
-
1022  "adc r1,r21\n" // r1:r10 += r21 * a24[2] (implicitly 1)
-
1023  "mov r10,r22\n"
-
1024  "adc r10,r22\n"
-
1025  "add r8,r18\n" // r8:r9:r1:r10 += carry
-
1026  "adc r9,r19\n"
-
1027  "adc r1,r11\n"
-
1028  "adc r10,r22\n"
-
1029  "st Z+,r8\n" // *tt++ = r8
-
1030  "mov r18,r9\n" // carry = r9:r1:r10
-
1031  "mov r19,r1\n"
-
1032  "mov r11,r10\n"
-
1033  "dec r25\n"
-
1034  "brne 1b\n"
-
1035  "st Z,r18\n" // *tt = carry
-
1036  "std Z+1,r19\n"
-
1037  "std Z+2,r11\n"
-
1038 #if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT
-
1039  "std Z+3,r22\n" // Zero pad to a limb boundary
-
1040 #endif
-
1041 
-
1042  // Restore __zero_reg__
-
1043  "clr __zero_reg__\n"
-
1044 
-
1045  : : "x"(x), "z"(temp)
-
1046  : "r8", "r9", "r10", "r11", "r16", "r17", "r18", "r19",
-
1047  "r20", "r21", "r22", "r25"
-
1048  );
-
1049 #endif
-
1050 
-
1051  // Reduce the intermediate result modulo 2^255 - 19.
-
1052  reduce(result, temp, NUM_A24_LIMBS);
-
1053  strict_clean(temp);
-
1054 }
-
1055 
-
1067 void Curve25519::mul_P(limb_t *result, const limb_t *x, const limb_t *y)
-
1068 {
-
1069  limb_t temp[NUM_LIMBS_512BIT];
-
1070  uint8_t i, j;
-
1071  dlimb_t carry;
-
1072  limb_t word;
-
1073  const limb_t *xx;
-
1074  limb_t *tt;
-
1075 
-
1076  // Multiply the lowest word of y by x.
-
1077  carry = 0;
-
1078  word = pgm_read_limb(&(y[0]));
-
1079  xx = x;
-
1080  tt = temp;
-
1081  for (i = 0; i < NUM_LIMBS_256BIT; ++i) {
-
1082  carry += ((dlimb_t)(*xx++)) * word;
-
1083  *tt++ = (limb_t)carry;
-
1084  carry >>= LIMB_BITS;
-
1085  }
-
1086  *tt = (limb_t)carry;
-
1087 
-
1088  // Multiply and add the remaining words of y by x.
-
1089  for (i = 1; i < NUM_LIMBS_256BIT; ++i) {
-
1090  word = pgm_read_limb(&(y[i]));
-
1091  carry = 0;
-
1092  xx = x;
-
1093  tt = temp + i;
-
1094  for (j = 0; j < NUM_LIMBS_256BIT; ++j) {
-
1095  carry += ((dlimb_t)(*xx++)) * word;
-
1096  carry += *tt;
-
1097  *tt++ = (limb_t)carry;
-
1098  carry >>= LIMB_BITS;
-
1099  }
-
1100  *tt = (limb_t)carry;
-
1101  }
-
1102 
-
1103  // Reduce the intermediate result modulo 2^255 - 19.
-
1104  reduce(result, temp, NUM_LIMBS_256BIT);
-
1105  strict_clean(temp);
-
1106 }
-
1107 
-
1118 void Curve25519::add(limb_t *result, const limb_t *x, const limb_t *y)
-
1119 {
-
1120 #if !defined(CURVE25519_ASM_AVR)
-
1121  dlimb_t carry = 0;
-
1122  uint8_t posn;
-
1123  limb_t *rr = result;
-
1124 
-
1125  // Add the two arrays to obtain the intermediate result.
-
1126  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
-
1127  carry += *x++;
-
1128  carry += *y++;
-
1129  *rr++ = (limb_t)carry;
-
1130  carry >>= LIMB_BITS;
-
1131  }
-
1132 #else // CURVE25519_ASM_AVR
-
1133  __asm__ __volatile__ (
-
1134  // Save Y and copy the "result" pointer into it.
-
1135  "push r28\n"
-
1136  "push r29\n"
-
1137  "mov r28,%A2\n"
-
1138  "mov r29,%B2\n"
-
1139 
-
1140  // Unroll the loop to operate on 4 bytes at a time (8 iterations).
-
1141  "ldi r24,8\n" // Loop counter.
-
1142  "clr r25\n" // carry = 0
-
1143  "1:\n"
-
1144  "ld r16,X+\n" // r16:r19 = *x++
-
1145  "ld r17,X+\n"
-
1146  "ld r18,X+\n"
-
1147  "ld r19,X+\n"
-
1148  "ld r20,Z+\n" // r20:r23 = *y++
-
1149  "ld r21,Z+\n"
-
1150  "ld r22,Z+\n"
-
1151  "ld r23,Z+\n"
-
1152  "add r16,r25\n" // r16:r19:carry += carry
-
1153  "adc r17,__zero_reg__\n"
-
1154  "adc r18,__zero_reg__\n"
-
1155  "adc r19,__zero_reg__\n"
-
1156  "mov r25,__zero_reg__\n"
-
1157  "adc r25,r25\n"
-
1158  "add r16,r20\n" // r16:r19:carry += r20:r23
-
1159  "adc r17,r21\n"
-
1160  "adc r18,r22\n"
-
1161  "adc r19,r23\n"
-
1162  "adc r25,__zero_reg__\n"
-
1163  "st Y+,r16\n" // *rr++ = r16:r23
-
1164  "st Y+,r17\n"
-
1165  "st Y+,r18\n"
-
1166  "st Y+,r19\n"
-
1167  "dec r24\n"
-
1168  "brne 1b\n"
-
1169 
-
1170  // Restore Y.
-
1171  "pop r29\n"
-
1172  "pop r28\n"
-
1173  : : "x"(x), "z"(y), "r"(result)
-
1174  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-
1175  "r24", "r25"
-
1176  );
-
1177 #endif // CURVE25519_ASM_AVR
-
1178 
-
1179  // Reduce the result using the quick trial subtraction method.
-
1180  reduceQuick(result);
-
1181 }
-
1182 
-
1193 void Curve25519::sub(limb_t *result, const limb_t *x, const limb_t *y)
-
1194 {
-
1195 #if !defined(CURVE25519_ASM_AVR)
-
1196  dlimb_t borrow;
-
1197  uint8_t posn;
-
1198  limb_t *rr = result;
-
1199 
-
1200  // Subtract y from x to generate the intermediate result.
-
1201  borrow = 0;
-
1202  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
-
1203  borrow = ((dlimb_t)(*x++)) - (*y++) - ((borrow >> LIMB_BITS) & 0x01);
-
1204  *rr++ = (limb_t)borrow;
-
1205  }
-
1206 
-
1207  // If we had a borrow, then the result has gone negative and we
-
1208  // have to add 2^255 - 19 to the result to make it positive again.
-
1209  // The top bits of "borrow" will be all 1's if there is a borrow
-
1210  // or it will be all 0's if there was no borrow. Easiest is to
-
1211  // conditionally subtract 19 and then mask off the high bit.
-
1212  rr = result;
-
1213  borrow = (borrow >> LIMB_BITS) & 19U;
-
1214  borrow = ((dlimb_t)(*rr)) - borrow;
-
1215  *rr++ = (limb_t)borrow;
-
1216  for (posn = 1; posn < NUM_LIMBS_256BIT; ++posn) {
-
1217  borrow = ((dlimb_t)(*rr)) - ((borrow >> LIMB_BITS) & 0x01);
-
1218  *rr++ = (limb_t)borrow;
-
1219  }
-
1220  *(--rr) &= ((((limb_t)1) << (LIMB_BITS - 1)) - 1);
-
1221 #else // CURVE25519_ASM_AVR
-
1222  __asm__ __volatile__ (
-
1223  // Save Y and copy the "result" pointer into it.
-
1224  "push r28\n"
-
1225  "push r29\n"
-
1226  "mov r28,%A2\n"
-
1227  "mov r29,%B2\n"
-
1228 
-
1229  // Unroll the sub loop to operate on 4 bytes at a time (8 iterations).
-
1230  "ldi r24,8\n" // Loop counter.
-
1231  "clr r25\n" // borrow = 0
-
1232  "1:\n"
-
1233  "ld r16,X+\n" // r16:r19 = *x++
-
1234  "ld r17,X+\n"
-
1235  "ld r18,X+\n"
-
1236  "ld r19,X+\n"
-
1237  "ld r20,Z+\n" // r20:r23 = *y++
-
1238  "ld r21,Z+\n"
-
1239  "ld r22,Z+\n"
-
1240  "ld r23,Z+\n"
-
1241  "sub r16,r25\n" // r16:r19:borrow -= borrow
-
1242  "sbc r17,__zero_reg__\n"
-
1243  "sbc r18,__zero_reg__\n"
-
1244  "sbc r19,__zero_reg__\n"
-
1245  "mov r25,__zero_reg__\n"
-
1246  "sbc r25,__zero_reg__\n"
-
1247  "sub r16,r20\n" // r16:r19:borrow -= r20:r23
-
1248  "sbc r17,r21\n"
-
1249  "sbc r18,r22\n"
-
1250  "sbc r19,r23\n"
-
1251  "sbc r25,__zero_reg__\n"
-
1252  "st Y+,r16\n" // *rr++ = r16:r23
-
1253  "st Y+,r17\n"
-
1254  "st Y+,r18\n"
-
1255  "st Y+,r19\n"
-
1256  "andi r25,1\n" // Only need the bottom bit of the borrow
-
1257  "dec r24\n"
-
1258  "brne 1b\n"
-
1259 
-
1260  // If there was a borrow, then we need to add 2^255 - 19 back.
-
1261  // We conditionally subtract 19 and then mask off the high bit.
-
1262  "neg r25\n" // borrow = mask(borrow) & 19
-
1263  "andi r25,19\n"
-
1264  "sbiw r28,32\n" // Point Y back to the start of "result"
-
1265  "ldi r24,8\n"
-
1266  "2:\n"
-
1267  "ld r16,Y\n" // r16:r19 = *rr
-
1268  "ldd r17,Y+1\n"
-
1269  "ldd r18,Y+2\n"
-
1270  "ldd r19,Y+3\n"
-
1271  "sub r16,r25\n"
-
1272  "sbc r17,__zero_reg__\n" // r16:r19:borrow -= borrow
-
1273  "sbc r18,__zero_reg__\n"
-
1274  "sbc r19,__zero_reg__\n"
-
1275  "mov r25,__zero_reg__\n"
-
1276  "sbc r25,__zero_reg__\n"
-
1277  "andi r25,1\n"
-
1278  "st Y+,r16\n" // *r++ = r16:r19
-
1279  "st Y+,r17\n"
-
1280  "st Y+,r18\n"
-
1281  "st Y+,r19\n"
-
1282  "dec r24\n"
-
1283  "brne 2b\n"
-
1284  "andi r19,0x7F\n" // Mask off the high bit in the last byte
-
1285  "sbiw r28,1\n"
-
1286  "st Y,r19\n"
-
1287 
-
1288  // Restore Y.
-
1289  "pop r29\n"
-
1290  "pop r28\n"
-
1291  : : "x"(x), "z"(y), "r"(result)
-
1292  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-
1293  "r24", "r25"
-
1294  );
-
1295 #endif // CURVE25519_ASM_AVR
-
1296 }
-
1297 
-
1310 void Curve25519::cswap(limb_t select, limb_t *x, limb_t *y)
-
1311 {
-
1312 #if !defined(CURVE25519_ASM_AVR)
-
1313  uint8_t posn;
-
1314  limb_t dummy;
-
1315  limb_t sel;
-
1316 
-
1317  // Turn "select" into an all-zeroes or all-ones mask. We don't care
-
1318  // which bit or bits is set in the original "select" value.
-
1319  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
-
1320  --sel;
-
1321 
-
1322  // Swap the two values based on "select". Algorithm from:
-
1323  // http://tools.ietf.org/html/rfc7748
-
1324  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
-
1325  dummy = sel & (x[posn] ^ y[posn]);
-
1326  x[posn] ^= dummy;
-
1327  y[posn] ^= dummy;
-
1328  }
-
1329 #else // CURVE25519_ASM_AVR
-
1330  __asm__ __volatile__ (
-
1331  // Combine all bytes from "select" into one and then turn
-
1332  // that byte into the "sel" mask in r24.
-
1333  "clr r24\n"
-
1334 #if BIGNUMBER_LIMB_8BIT
-
1335  "sub r24,%2\n"
-
1336 #elif BIGNUMBER_LIMB_16BIT
-
1337  "or %A2,%B2\n"
-
1338  "sub r24,%A2\n"
-
1339 #elif BIGNUMBER_LIMB_32BIT
-
1340  "or %A2,%B2\n"
-
1341  "or %A2,%C2\n"
-
1342  "or %A2,%D2\n"
-
1343  "sub r24,%A2\n"
-
1344 #endif
-
1345  "mov r24,__zero_reg__\n"
-
1346  "sbc r24,r24\n"
-
1347 
-
1348  // Perform the conditional swap 4 bytes at a time.
-
1349  "ldi r25,8\n"
-
1350  "1:\n"
-
1351  "ld r16,X+\n" // r16:r19 = *x
-
1352  "ld r17,X+\n"
-
1353  "ld r18,X+\n"
-
1354  "ld r19,X\n"
-
1355  "ld r20,Z\n" // r20:r23 = *y
-
1356  "ldd r21,Z+1\n"
-
1357  "ldd r22,Z+2\n"
-
1358  "ldd r23,Z+3\n"
-
1359  "mov r12,r16\n" // r12:r15 = (r16:r19 ^ r20:r23) & sel
-
1360  "mov r13,r17\n"
-
1361  "mov r14,r18\n"
-
1362  "mov r15,r19\n"
-
1363  "eor r12,r20\n"
-
1364  "eor r13,r21\n"
-
1365  "eor r14,r22\n"
-
1366  "eor r15,r23\n"
-
1367  "and r12,r24\n"
-
1368  "and r13,r24\n"
-
1369  "and r14,r24\n"
-
1370  "and r15,r24\n"
-
1371  "eor r16,r12\n" // r16:r19 ^= r12:r15
-
1372  "eor r17,r13\n"
-
1373  "eor r18,r14\n"
-
1374  "eor r19,r15\n"
-
1375  "eor r20,r12\n" // r20:r23 ^= r12:r15
-
1376  "eor r21,r13\n"
-
1377  "eor r22,r14\n"
-
1378  "eor r23,r15\n"
-
1379  "st X,r19\n" // *x++ = r16:r19
-
1380  "st -X,r18\n"
-
1381  "st -X,r17\n"
-
1382  "st -X,r16\n"
-
1383  "adiw r26,4\n"
-
1384  "st Z+,r20\n" // *y++ = r20:r23
-
1385  "st Z+,r21\n"
-
1386  "st Z+,r22\n"
-
1387  "st Z+,r23\n"
-
1388  "dec r25\n"
-
1389  "brne 1b\n"
-
1390 
-
1391  : : "x"(x), "z"(y), "r"(select)
-
1392  : "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
-
1393  "r20", "r21", "r22", "r23", "r24", "r25"
-
1394  );
-
1395 #endif // CURVE25519_ASM_AVR
-
1396 }
-
1397 
-
1410 void Curve25519::cmove(limb_t select, limb_t *x, const limb_t *y)
-
1411 {
-
1412 #if !defined(CURVE25519_ASM_AVR)
-
1413  uint8_t posn;
-
1414  limb_t dummy;
-
1415  limb_t sel;
-
1416 
-
1417  // Turn "select" into an all-zeroes or all-ones mask. We don't care
-
1418  // which bit or bits is set in the original "select" value.
-
1419  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
-
1420  --sel;
-
1421 
-
1422  // Move y into x based on "select". Similar to conditional swap above.
-
1423  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
-
1424  dummy = sel & (x[posn] ^ y[posn]);
-
1425  x[posn] ^= dummy;
-
1426  }
-
1427 #else // CURVE25519_ASM_AVR
-
1428  __asm__ __volatile__ (
-
1429  // Combine all bytes from "select" into one and then turn
-
1430  // that byte into the "sel" mask in r24.
-
1431  "clr r24\n"
-
1432 #if BIGNUMBER_LIMB_8BIT
-
1433  "sub r24,%2\n"
-
1434 #elif BIGNUMBER_LIMB_16BIT
-
1435  "or %A2,%B2\n"
-
1436  "sub r24,%A2\n"
-
1437 #elif BIGNUMBER_LIMB_32BIT
-
1438  "or %A2,%B2\n"
-
1439  "or %A2,%C2\n"
-
1440  "or %A2,%D2\n"
-
1441  "sub r24,%A2\n"
-
1442 #endif
-
1443  "mov r24,__zero_reg__\n"
-
1444  "sbc r24,r24\n"
-
1445 
-
1446  // Perform the conditional move 4 bytes at a time.
-
1447  "ldi r25,8\n"
-
1448  "1:\n"
-
1449  "ld r16,X+\n" // r16:r19 = *x
-
1450  "ld r17,X+\n"
-
1451  "ld r18,X+\n"
-
1452  "ld r19,X\n"
-
1453  "ld r20,Z+\n" // r20:r23 = *y++
-
1454  "ld r21,Z+\n"
-
1455  "ld r22,Z+\n"
-
1456  "ld r23,Z+\n"
-
1457  "eor r20,r16\n" // r20:r23 = (r16:r19 ^ r20:r23) & sel
-
1458  "eor r21,r17\n"
-
1459  "eor r22,r18\n"
-
1460  "eor r23,r19\n"
-
1461  "and r20,r24\n"
-
1462  "and r21,r24\n"
-
1463  "and r22,r24\n"
-
1464  "and r23,r24\n"
-
1465  "eor r16,r20\n" // r16:r19 ^= r20:r23
-
1466  "eor r17,r21\n"
-
1467  "eor r18,r22\n"
-
1468  "eor r19,r23\n"
-
1469  "st X,r19\n" // *x++ = r16:r19
-
1470  "st -X,r18\n"
-
1471  "st -X,r17\n"
-
1472  "st -X,r16\n"
-
1473  "adiw r26,4\n"
-
1474  "dec r25\n"
-
1475  "brne 1b\n"
-
1476 
-
1477  : : "x"(x), "z"(y), "r"(select)
-
1478  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
-
1479  "r24", "r25"
-
1480  );
-
1481 #endif // CURVE25519_ASM_AVR
-
1482 }
-
1483 
-
1490 void Curve25519::pow250(limb_t *result, const limb_t *x)
-
1491 {
-
1492  limb_t t1[NUM_LIMBS_256BIT];
-
1493  uint8_t i, j;
-
1494 
-
1495  // The big-endian hexadecimal expansion of (2^250 - 1) is:
-
1496  // 03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
-
1497  //
-
1498  // The naive implementation needs to do 2 multiplications per 1 bit and
-
1499  // 1 multiplication per 0 bit. We can improve upon this by creating a
-
1500  // pattern 0000000001 ... 0000000001. If we square and multiply the
-
1501  // pattern by itself we can turn the pattern into the partial results
-
1502  // 0000000011 ... 0000000011, 0000000111 ... 0000000111, etc.
-
1503  // This averages out to about 1.1 multiplications per 1 bit instead of 2.
-
1504 
-
1505  // Build a pattern of 250 bits in length of repeated copies of 0000000001.
-
1506  #define RECIP_GROUP_SIZE 10
-
1507  #define RECIP_GROUP_BITS 250 // Must be a multiple of RECIP_GROUP_SIZE.
-
1508  square(t1, x);
-
1509  for (j = 0; j < (RECIP_GROUP_SIZE - 1); ++j)
-
1510  square(t1, t1);
-
1511  mul(result, t1, x);
-
1512  for (i = 0; i < ((RECIP_GROUP_BITS / RECIP_GROUP_SIZE) - 2); ++i) {
-
1513  for (j = 0; j < RECIP_GROUP_SIZE; ++j)
-
1514  square(t1, t1);
-
1515  mul(result, result, t1);
-
1516  }
-
1517 
-
1518  // Multiply bit-shifted versions of the 0000000001 pattern into
-
1519  // the result to "fill in" the gaps in the pattern.
-
1520  square(t1, result);
-
1521  mul(result, result, t1);
-
1522  for (j = 0; j < (RECIP_GROUP_SIZE - 2); ++j) {
-
1523  square(t1, t1);
-
1524  mul(result, result, t1);
-
1525  }
-
1526 
-
1527  // Clean up and exit.
-
1528  clean(t1);
-
1529 }
-
1530 
-
1538 void Curve25519::recip(limb_t *result, const limb_t *x)
-
1539 {
-
1540  // The reciprocal is the same as x ^ (p - 2) where p = 2^255 - 19.
-
1541  // The big-endian hexadecimal expansion of (p - 2) is:
-
1542  // 7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFEB
-
1543  // Start with the 250 upper bits of the expansion of (p - 2).
-
1544  pow250(result, x);
-
1545 
-
1546  // Deal with the 5 lowest bits of (p - 2), 01011, from highest to lowest.
-
1547  square(result, result);
+
937  crypto_feed_watchdog();
+
938 }
+
939 
+
959 void Curve25519::mulA24(limb_t *result, const limb_t *x)
+
960 {
+
961 #if !defined(CURVE25519_ASM_AVR)
+
962  // The constant a24 = 121665 (0x1DB41) as a limb array.
+
963 #if BIGNUMBER_LIMB_8BIT
+
964  static limb_t const a24[3] PROGMEM = {0x41, 0xDB, 0x01};
+
965 #elif BIGNUMBER_LIMB_16BIT
+
966  static limb_t const a24[2] PROGMEM = {0xDB41, 0x0001};
+
967 #elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
+
968  static limb_t const a24[1] PROGMEM = {0x0001DB41};
+
969 #else
+
970  #error "limb_t must be 8, 16, 32, or 64 bits in size"
+
971 #endif
+
972  #define NUM_A24_LIMBS (sizeof(a24) / sizeof(limb_t))
+
973 
+
974  // Multiply the lowest limb of a24 by x and zero-extend into the result.
+
975  limb_t temp[NUM_LIMBS_512BIT];
+
976  uint8_t i, j;
+
977  dlimb_t carry = 0;
+
978  limb_t word = pgm_read_limb(&(a24[0]));
+
979  const limb_t *xx = x;
+
980  limb_t *tt = temp;
+
981  for (i = 0; i < NUM_LIMBS_256BIT; ++i) {
+
982  carry += ((dlimb_t)(*xx++)) * word;
+
983  *tt++ = (limb_t)carry;
+
984  carry >>= LIMB_BITS;
+
985  }
+
986  *tt = (limb_t)carry;
+
987 
+
988  // Multiply and add the remaining limbs of a24.
+
989  for (i = 1; i < NUM_A24_LIMBS; ++i) {
+
990  word = pgm_read_limb(&(a24[i]));
+
991  carry = 0;
+
992  xx = x;
+
993  tt = temp + i;
+
994  for (j = 0; j < NUM_LIMBS_256BIT; ++j) {
+
995  carry += ((dlimb_t)(*xx++)) * word;
+
996  carry += *tt;
+
997  *tt++ = (limb_t)carry;
+
998  carry >>= LIMB_BITS;
+
999  }
+
1000  *tt = (limb_t)carry;
+
1001  }
+
1002 #else
+
1003  limb_t temp[NUM_LIMBS_512BIT];
+
1004  #define NUM_A24_LIMBS ((3 + sizeof(limb_t) - 1) / sizeof(limb_t))
+
1005  __asm__ __volatile__ (
+
1006  // Load the two low bytes of a24 into r16 and r17.
+
1007  // The third byte is 0x01 which we can deal with implicitly.
+
1008  "ldi r16,0x41\n"
+
1009  "ldi r17,0xDB\n"
+
1010 
+
1011  // Iterate over the bytes of "x" and multiply each with a24.
+
1012  "ldi r25,32\n" // 32 bytes in "x"
+
1013  "clr r22\n" // r22 = 0
+
1014  "clr r18\n" // r18:r19:r11 = 0 (carry)
+
1015  "clr r19\n"
+
1016  "clr r11\n"
+
1017  "1:\n"
+
1018  "ld r21,X+\n" // r21 = *x++
+
1019  "mul r21,r16\n" // r8:r9 = r21 * a24[0]
+
1020  "movw r8,r0\n"
+
1021  "mul r21,r17\n" // r9:r1 += r21 * a24[1]
+
1022  "add r9,r0\n"
+
1023  "adc r1,r21\n" // r1:r10 += r21 * a24[2] (implicitly 1)
+
1024  "mov r10,r22\n"
+
1025  "adc r10,r22\n"
+
1026  "add r8,r18\n" // r8:r9:r1:r10 += carry
+
1027  "adc r9,r19\n"
+
1028  "adc r1,r11\n"
+
1029  "adc r10,r22\n"
+
1030  "st Z+,r8\n" // *tt++ = r8
+
1031  "mov r18,r9\n" // carry = r9:r1:r10
+
1032  "mov r19,r1\n"
+
1033  "mov r11,r10\n"
+
1034  "dec r25\n"
+
1035  "brne 1b\n"
+
1036  "st Z,r18\n" // *tt = carry
+
1037  "std Z+1,r19\n"
+
1038  "std Z+2,r11\n"
+
1039 #if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT
+
1040  "std Z+3,r22\n" // Zero pad to a limb boundary
+
1041 #endif
+
1042 
+
1043  // Restore __zero_reg__
+
1044  "clr __zero_reg__\n"
+
1045 
+
1046  : : "x"(x), "z"(temp)
+
1047  : "r8", "r9", "r10", "r11", "r16", "r17", "r18", "r19",
+
1048  "r20", "r21", "r22", "r25"
+
1049  );
+
1050 #endif
+
1051 
+
1052  // Reduce the intermediate result modulo 2^255 - 19.
+
1053  reduce(result, temp, NUM_A24_LIMBS);
+
1054  strict_clean(temp);
+
1055 }
+
1056 
+
1068 void Curve25519::mul_P(limb_t *result, const limb_t *x, const limb_t *y)
+
1069 {
+
1070  limb_t temp[NUM_LIMBS_512BIT];
+
1071  uint8_t i, j;
+
1072  dlimb_t carry;
+
1073  limb_t word;
+
1074  const limb_t *xx;
+
1075  limb_t *tt;
+
1076 
+
1077  // Multiply the lowest word of y by x.
+
1078  carry = 0;
+
1079  word = pgm_read_limb(&(y[0]));
+
1080  xx = x;
+
1081  tt = temp;
+
1082  for (i = 0; i < NUM_LIMBS_256BIT; ++i) {
+
1083  carry += ((dlimb_t)(*xx++)) * word;
+
1084  *tt++ = (limb_t)carry;
+
1085  carry >>= LIMB_BITS;
+
1086  }
+
1087  *tt = (limb_t)carry;
+
1088 
+
1089  // Multiply and add the remaining words of y by x.
+
1090  for (i = 1; i < NUM_LIMBS_256BIT; ++i) {
+
1091  word = pgm_read_limb(&(y[i]));
+
1092  carry = 0;
+
1093  xx = x;
+
1094  tt = temp + i;
+
1095  for (j = 0; j < NUM_LIMBS_256BIT; ++j) {
+
1096  carry += ((dlimb_t)(*xx++)) * word;
+
1097  carry += *tt;
+
1098  *tt++ = (limb_t)carry;
+
1099  carry >>= LIMB_BITS;
+
1100  }
+
1101  *tt = (limb_t)carry;
+
1102  }
+
1103 
+
1104  // Reduce the intermediate result modulo 2^255 - 19.
+
1105  reduce(result, temp, NUM_LIMBS_256BIT);
+
1106  strict_clean(temp);
+
1107 }
+
1108 
+
1119 void Curve25519::add(limb_t *result, const limb_t *x, const limb_t *y)
+
1120 {
+
1121 #if !defined(CURVE25519_ASM_AVR)
+
1122  dlimb_t carry = 0;
+
1123  uint8_t posn;
+
1124  limb_t *rr = result;
+
1125 
+
1126  // Add the two arrays to obtain the intermediate result.
+
1127  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
+
1128  carry += *x++;
+
1129  carry += *y++;
+
1130  *rr++ = (limb_t)carry;
+
1131  carry >>= LIMB_BITS;
+
1132  }
+
1133 #else // CURVE25519_ASM_AVR
+
1134  __asm__ __volatile__ (
+
1135  // Save Y and copy the "result" pointer into it.
+
1136  "push r28\n"
+
1137  "push r29\n"
+
1138  "mov r28,%A2\n"
+
1139  "mov r29,%B2\n"
+
1140 
+
1141  // Unroll the loop to operate on 4 bytes at a time (8 iterations).
+
1142  "ldi r24,8\n" // Loop counter.
+
1143  "clr r25\n" // carry = 0
+
1144  "1:\n"
+
1145  "ld r16,X+\n" // r16:r19 = *x++
+
1146  "ld r17,X+\n"
+
1147  "ld r18,X+\n"
+
1148  "ld r19,X+\n"
+
1149  "ld r20,Z+\n" // r20:r23 = *y++
+
1150  "ld r21,Z+\n"
+
1151  "ld r22,Z+\n"
+
1152  "ld r23,Z+\n"
+
1153  "add r16,r25\n" // r16:r19:carry += carry
+
1154  "adc r17,__zero_reg__\n"
+
1155  "adc r18,__zero_reg__\n"
+
1156  "adc r19,__zero_reg__\n"
+
1157  "mov r25,__zero_reg__\n"
+
1158  "adc r25,r25\n"
+
1159  "add r16,r20\n" // r16:r19:carry += r20:r23
+
1160  "adc r17,r21\n"
+
1161  "adc r18,r22\n"
+
1162  "adc r19,r23\n"
+
1163  "adc r25,__zero_reg__\n"
+
1164  "st Y+,r16\n" // *rr++ = r16:r23
+
1165  "st Y+,r17\n"
+
1166  "st Y+,r18\n"
+
1167  "st Y+,r19\n"
+
1168  "dec r24\n"
+
1169  "brne 1b\n"
+
1170 
+
1171  // Restore Y.
+
1172  "pop r29\n"
+
1173  "pop r28\n"
+
1174  : : "x"(x), "z"(y), "r"(result)
+
1175  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+
1176  "r24", "r25"
+
1177  );
+
1178 #endif // CURVE25519_ASM_AVR
+
1179 
+
1180  // Reduce the result using the quick trial subtraction method.
+
1181  reduceQuick(result);
+
1182 }
+
1183 
+
1194 void Curve25519::sub(limb_t *result, const limb_t *x, const limb_t *y)
+
1195 {
+
1196 #if !defined(CURVE25519_ASM_AVR)
+
1197  dlimb_t borrow;
+
1198  uint8_t posn;
+
1199  limb_t *rr = result;
+
1200 
+
1201  // Subtract y from x to generate the intermediate result.
+
1202  borrow = 0;
+
1203  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
+
1204  borrow = ((dlimb_t)(*x++)) - (*y++) - ((borrow >> LIMB_BITS) & 0x01);
+
1205  *rr++ = (limb_t)borrow;
+
1206  }
+
1207 
+
1208  // If we had a borrow, then the result has gone negative and we
+
1209  // have to add 2^255 - 19 to the result to make it positive again.
+
1210  // The top bits of "borrow" will be all 1's if there is a borrow
+
1211  // or it will be all 0's if there was no borrow. Easiest is to
+
1212  // conditionally subtract 19 and then mask off the high bit.
+
1213  rr = result;
+
1214  borrow = (borrow >> LIMB_BITS) & 19U;
+
1215  borrow = ((dlimb_t)(*rr)) - borrow;
+
1216  *rr++ = (limb_t)borrow;
+
1217  for (posn = 1; posn < NUM_LIMBS_256BIT; ++posn) {
+
1218  borrow = ((dlimb_t)(*rr)) - ((borrow >> LIMB_BITS) & 0x01);
+
1219  *rr++ = (limb_t)borrow;
+
1220  }
+
1221  *(--rr) &= ((((limb_t)1) << (LIMB_BITS - 1)) - 1);
+
1222 #else // CURVE25519_ASM_AVR
+
1223  __asm__ __volatile__ (
+
1224  // Save Y and copy the "result" pointer into it.
+
1225  "push r28\n"
+
1226  "push r29\n"
+
1227  "mov r28,%A2\n"
+
1228  "mov r29,%B2\n"
+
1229 
+
1230  // Unroll the sub loop to operate on 4 bytes at a time (8 iterations).
+
1231  "ldi r24,8\n" // Loop counter.
+
1232  "clr r25\n" // borrow = 0
+
1233  "1:\n"
+
1234  "ld r16,X+\n" // r16:r19 = *x++
+
1235  "ld r17,X+\n"
+
1236  "ld r18,X+\n"
+
1237  "ld r19,X+\n"
+
1238  "ld r20,Z+\n" // r20:r23 = *y++
+
1239  "ld r21,Z+\n"
+
1240  "ld r22,Z+\n"
+
1241  "ld r23,Z+\n"
+
1242  "sub r16,r25\n" // r16:r19:borrow -= borrow
+
1243  "sbc r17,__zero_reg__\n"
+
1244  "sbc r18,__zero_reg__\n"
+
1245  "sbc r19,__zero_reg__\n"
+
1246  "mov r25,__zero_reg__\n"
+
1247  "sbc r25,__zero_reg__\n"
+
1248  "sub r16,r20\n" // r16:r19:borrow -= r20:r23
+
1249  "sbc r17,r21\n"
+
1250  "sbc r18,r22\n"
+
1251  "sbc r19,r23\n"
+
1252  "sbc r25,__zero_reg__\n"
+
1253  "st Y+,r16\n" // *rr++ = r16:r23
+
1254  "st Y+,r17\n"
+
1255  "st Y+,r18\n"
+
1256  "st Y+,r19\n"
+
1257  "andi r25,1\n" // Only need the bottom bit of the borrow
+
1258  "dec r24\n"
+
1259  "brne 1b\n"
+
1260 
+
1261  // If there was a borrow, then we need to add 2^255 - 19 back.
+
1262  // We conditionally subtract 19 and then mask off the high bit.
+
1263  "neg r25\n" // borrow = mask(borrow) & 19
+
1264  "andi r25,19\n"
+
1265  "sbiw r28,32\n" // Point Y back to the start of "result"
+
1266  "ldi r24,8\n"
+
1267  "2:\n"
+
1268  "ld r16,Y\n" // r16:r19 = *rr
+
1269  "ldd r17,Y+1\n"
+
1270  "ldd r18,Y+2\n"
+
1271  "ldd r19,Y+3\n"
+
1272  "sub r16,r25\n"
+
1273  "sbc r17,__zero_reg__\n" // r16:r19:borrow -= borrow
+
1274  "sbc r18,__zero_reg__\n"
+
1275  "sbc r19,__zero_reg__\n"
+
1276  "mov r25,__zero_reg__\n"
+
1277  "sbc r25,__zero_reg__\n"
+
1278  "andi r25,1\n"
+
1279  "st Y+,r16\n" // *r++ = r16:r19
+
1280  "st Y+,r17\n"
+
1281  "st Y+,r18\n"
+
1282  "st Y+,r19\n"
+
1283  "dec r24\n"
+
1284  "brne 2b\n"
+
1285  "andi r19,0x7F\n" // Mask off the high bit in the last byte
+
1286  "sbiw r28,1\n"
+
1287  "st Y,r19\n"
+
1288 
+
1289  // Restore Y.
+
1290  "pop r29\n"
+
1291  "pop r28\n"
+
1292  : : "x"(x), "z"(y), "r"(result)
+
1293  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+
1294  "r24", "r25"
+
1295  );
+
1296 #endif // CURVE25519_ASM_AVR
+
1297 }
+
1298 
+
1311 void Curve25519::cswap(limb_t select, limb_t *x, limb_t *y)
+
1312 {
+
1313 #if !defined(CURVE25519_ASM_AVR)
+
1314  uint8_t posn;
+
1315  limb_t dummy;
+
1316  limb_t sel;
+
1317 
+
1318  // Turn "select" into an all-zeroes or all-ones mask. We don't care
+
1319  // which bit or bits is set in the original "select" value.
+
1320  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
+
1321  --sel;
+
1322 
+
1323  // Swap the two values based on "select". Algorithm from:
+
1324  // http://tools.ietf.org/html/rfc7748
+
1325  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
+
1326  dummy = sel & (x[posn] ^ y[posn]);
+
1327  x[posn] ^= dummy;
+
1328  y[posn] ^= dummy;
+
1329  }
+
1330 #else // CURVE25519_ASM_AVR
+
1331  __asm__ __volatile__ (
+
1332  // Combine all bytes from "select" into one and then turn
+
1333  // that byte into the "sel" mask in r24.
+
1334  "clr r24\n"
+
1335 #if BIGNUMBER_LIMB_8BIT
+
1336  "sub r24,%2\n"
+
1337 #elif BIGNUMBER_LIMB_16BIT
+
1338  "or %A2,%B2\n"
+
1339  "sub r24,%A2\n"
+
1340 #elif BIGNUMBER_LIMB_32BIT
+
1341  "or %A2,%B2\n"
+
1342  "or %A2,%C2\n"
+
1343  "or %A2,%D2\n"
+
1344  "sub r24,%A2\n"
+
1345 #endif
+
1346  "mov r24,__zero_reg__\n"
+
1347  "sbc r24,r24\n"
+
1348 
+
1349  // Perform the conditional swap 4 bytes at a time.
+
1350  "ldi r25,8\n"
+
1351  "1:\n"
+
1352  "ld r16,X+\n" // r16:r19 = *x
+
1353  "ld r17,X+\n"
+
1354  "ld r18,X+\n"
+
1355  "ld r19,X\n"
+
1356  "ld r20,Z\n" // r20:r23 = *y
+
1357  "ldd r21,Z+1\n"
+
1358  "ldd r22,Z+2\n"
+
1359  "ldd r23,Z+3\n"
+
1360  "mov r12,r16\n" // r12:r15 = (r16:r19 ^ r20:r23) & sel
+
1361  "mov r13,r17\n"
+
1362  "mov r14,r18\n"
+
1363  "mov r15,r19\n"
+
1364  "eor r12,r20\n"
+
1365  "eor r13,r21\n"
+
1366  "eor r14,r22\n"
+
1367  "eor r15,r23\n"
+
1368  "and r12,r24\n"
+
1369  "and r13,r24\n"
+
1370  "and r14,r24\n"
+
1371  "and r15,r24\n"
+
1372  "eor r16,r12\n" // r16:r19 ^= r12:r15
+
1373  "eor r17,r13\n"
+
1374  "eor r18,r14\n"
+
1375  "eor r19,r15\n"
+
1376  "eor r20,r12\n" // r20:r23 ^= r12:r15
+
1377  "eor r21,r13\n"
+
1378  "eor r22,r14\n"
+
1379  "eor r23,r15\n"
+
1380  "st X,r19\n" // *x++ = r16:r19
+
1381  "st -X,r18\n"
+
1382  "st -X,r17\n"
+
1383  "st -X,r16\n"
+
1384  "adiw r26,4\n"
+
1385  "st Z+,r20\n" // *y++ = r20:r23
+
1386  "st Z+,r21\n"
+
1387  "st Z+,r22\n"
+
1388  "st Z+,r23\n"
+
1389  "dec r25\n"
+
1390  "brne 1b\n"
+
1391 
+
1392  : : "x"(x), "z"(y), "r"(select)
+
1393  : "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
+
1394  "r20", "r21", "r22", "r23", "r24", "r25"
+
1395  );
+
1396 #endif // CURVE25519_ASM_AVR
+
1397 }
+
1398 
+
1411 void Curve25519::cmove(limb_t select, limb_t *x, const limb_t *y)
+
1412 {
+
1413 #if !defined(CURVE25519_ASM_AVR)
+
1414  uint8_t posn;
+
1415  limb_t dummy;
+
1416  limb_t sel;
+
1417 
+
1418  // Turn "select" into an all-zeroes or all-ones mask. We don't care
+
1419  // which bit or bits is set in the original "select" value.
+
1420  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
+
1421  --sel;
+
1422 
+
1423  // Move y into x based on "select". Similar to conditional swap above.
+
1424  for (posn = 0; posn < NUM_LIMBS_256BIT; ++posn) {
+
1425  dummy = sel & (x[posn] ^ y[posn]);
+
1426  x[posn] ^= dummy;
+
1427  }
+
1428 #else // CURVE25519_ASM_AVR
+
1429  __asm__ __volatile__ (
+
1430  // Combine all bytes from "select" into one and then turn
+
1431  // that byte into the "sel" mask in r24.
+
1432  "clr r24\n"
+
1433 #if BIGNUMBER_LIMB_8BIT
+
1434  "sub r24,%2\n"
+
1435 #elif BIGNUMBER_LIMB_16BIT
+
1436  "or %A2,%B2\n"
+
1437  "sub r24,%A2\n"
+
1438 #elif BIGNUMBER_LIMB_32BIT
+
1439  "or %A2,%B2\n"
+
1440  "or %A2,%C2\n"
+
1441  "or %A2,%D2\n"
+
1442  "sub r24,%A2\n"
+
1443 #endif
+
1444  "mov r24,__zero_reg__\n"
+
1445  "sbc r24,r24\n"
+
1446 
+
1447  // Perform the conditional move 4 bytes at a time.
+
1448  "ldi r25,8\n"
+
1449  "1:\n"
+
1450  "ld r16,X+\n" // r16:r19 = *x
+
1451  "ld r17,X+\n"
+
1452  "ld r18,X+\n"
+
1453  "ld r19,X\n"
+
1454  "ld r20,Z+\n" // r20:r23 = *y++
+
1455  "ld r21,Z+\n"
+
1456  "ld r22,Z+\n"
+
1457  "ld r23,Z+\n"
+
1458  "eor r20,r16\n" // r20:r23 = (r16:r19 ^ r20:r23) & sel
+
1459  "eor r21,r17\n"
+
1460  "eor r22,r18\n"
+
1461  "eor r23,r19\n"
+
1462  "and r20,r24\n"
+
1463  "and r21,r24\n"
+
1464  "and r22,r24\n"
+
1465  "and r23,r24\n"
+
1466  "eor r16,r20\n" // r16:r19 ^= r20:r23
+
1467  "eor r17,r21\n"
+
1468  "eor r18,r22\n"
+
1469  "eor r19,r23\n"
+
1470  "st X,r19\n" // *x++ = r16:r19
+
1471  "st -X,r18\n"
+
1472  "st -X,r17\n"
+
1473  "st -X,r16\n"
+
1474  "adiw r26,4\n"
+
1475  "dec r25\n"
+
1476  "brne 1b\n"
+
1477 
+
1478  : : "x"(x), "z"(y), "r"(select)
+
1479  : "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+
1480  "r24", "r25"
+
1481  );
+
1482 #endif // CURVE25519_ASM_AVR
+
1483 }
+
1484 
+
1491 void Curve25519::pow250(limb_t *result, const limb_t *x)
+
1492 {
+
1493  limb_t t1[NUM_LIMBS_256BIT];
+
1494  uint8_t i, j;
+
1495 
+
1496  // The big-endian hexadecimal expansion of (2^250 - 1) is:
+
1497  // 03FFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF
+
1498  //
+
1499  // The naive implementation needs to do 2 multiplications per 1 bit and
+
1500  // 1 multiplication per 0 bit. We can improve upon this by creating a
+
1501  // pattern 0000000001 ... 0000000001. If we square and multiply the
+
1502  // pattern by itself we can turn the pattern into the partial results
+
1503  // 0000000011 ... 0000000011, 0000000111 ... 0000000111, etc.
+
1504  // This averages out to about 1.1 multiplications per 1 bit instead of 2.
+
1505 
+
1506  // Build a pattern of 250 bits in length of repeated copies of 0000000001.
+
1507  #define RECIP_GROUP_SIZE 10
+
1508  #define RECIP_GROUP_BITS 250 // Must be a multiple of RECIP_GROUP_SIZE.
+
1509  square(t1, x);
+
1510  for (j = 0; j < (RECIP_GROUP_SIZE - 1); ++j)
+
1511  square(t1, t1);
+
1512  mul(result, t1, x);
+
1513  for (i = 0; i < ((RECIP_GROUP_BITS / RECIP_GROUP_SIZE) - 2); ++i) {
+
1514  for (j = 0; j < RECIP_GROUP_SIZE; ++j)
+
1515  square(t1, t1);
+
1516  mul(result, result, t1);
+
1517  }
+
1518 
+
1519  // Multiply bit-shifted versions of the 0000000001 pattern into
+
1520  // the result to "fill in" the gaps in the pattern.
+
1521  square(t1, result);
+
1522  mul(result, result, t1);
+
1523  for (j = 0; j < (RECIP_GROUP_SIZE - 2); ++j) {
+
1524  square(t1, t1);
+
1525  mul(result, result, t1);
+
1526  }
+
1527 
+
1528  // Clean up and exit.
+
1529  clean(t1);
+
1530 }
+
1531 
+
1539 void Curve25519::recip(limb_t *result, const limb_t *x)
+
1540 {
+
1541  // The reciprocal is the same as x ^ (p - 2) where p = 2^255 - 19.
+
1542  // The big-endian hexadecimal expansion of (p - 2) is:
+
1543  // 7FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFEB
+
1544  // Start with the 250 upper bits of the expansion of (p - 2).
+
1545  pow250(result, x);
+
1546 
+
1547  // Deal with the 5 lowest bits of (p - 2), 01011, from highest to lowest.
1548  square(result, result);
-
1549  mul(result, result, x);
-
1550  square(result, result);
+
1549  square(result, result);
+
1550  mul(result, result, x);
1551  square(result, result);
-
1552  mul(result, result, x);
-
1553  square(result, result);
-
1554  mul(result, result, x);
-
1555 }
-
1556 
-
1572 bool Curve25519::sqrt(limb_t *result, const limb_t *x)
-
1573 {
-
1574  // sqrt(-1) mod (2^255 - 19).
-
1575  static limb_t const numSqrtM1[NUM_LIMBS_256BIT] PROGMEM = {
-
1576  LIMB_PAIR(0x4A0EA0B0, 0xC4EE1B27), LIMB_PAIR(0xAD2FE478, 0x2F431806),
-
1577  LIMB_PAIR(0x3DFBD7A7, 0x2B4D0099), LIMB_PAIR(0x4FC1DF0B, 0x2B832480)
-
1578  };
-
1579  limb_t y[NUM_LIMBS_256BIT];
-
1580 
-
1581  // Algorithm from: http://tools.ietf.org/html/rfc7748
-
1582 
-
1583  // Compute a candidate root: result = x^((p + 3) / 8) mod p.
-
1584  // (p + 3) / 8 = (2^252 - 2) which is 251 one bits followed by a zero:
-
1585  // 0FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE
-
1586  pow250(result, x);
-
1587  square(result, result);
-
1588  mul(result, result, x);
-
1589  square(result, result);
-
1590 
-
1591  // Did we get the square root immediately?
-
1592  square(y, result);
-
1593  if (memcmp(x, y, sizeof(y)) == 0) {
-
1594  clean(y);
-
1595  return true;
-
1596  }
-
1597 
-
1598  // Multiply the result by sqrt(-1) and check again.
-
1599  mul_P(result, result, numSqrtM1);
-
1600  square(y, result);
-
1601  if (memcmp(x, y, sizeof(y)) == 0) {
-
1602  clean(y);
-
1603  return true;
-
1604  }
-
1605 
-
1606  // The number does not have a square root.
-
1607  clean(y);
-
1608  return false;
-
1609 }
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
+
1552  square(result, result);
+
1553  mul(result, result, x);
+
1554  square(result, result);
+
1555  mul(result, result, x);
+
1556 }
+
1557 
+
1573 bool Curve25519::sqrt(limb_t *result, const limb_t *x)
+
1574 {
+
1575  // sqrt(-1) mod (2^255 - 19).
+
1576  static limb_t const numSqrtM1[NUM_LIMBS_256BIT] PROGMEM = {
+
1577  LIMB_PAIR(0x4A0EA0B0, 0xC4EE1B27), LIMB_PAIR(0xAD2FE478, 0x2F431806),
+
1578  LIMB_PAIR(0x3DFBD7A7, 0x2B4D0099), LIMB_PAIR(0x4FC1DF0B, 0x2B832480)
+
1579  };
+
1580  limb_t y[NUM_LIMBS_256BIT];
+
1581 
+
1582  // Algorithm from: http://tools.ietf.org/html/rfc7748
+
1583 
+
1584  // Compute a candidate root: result = x^((p + 3) / 8) mod p.
+
1585  // (p + 3) / 8 = (2^252 - 2) which is 251 one bits followed by a zero:
+
1586  // 0FFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE
+
1587  pow250(result, x);
+
1588  square(result, result);
+
1589  mul(result, result, x);
+
1590  square(result, result);
+
1591 
+
1592  // Did we get the square root immediately?
+
1593  square(y, result);
+
1594  if (memcmp(x, y, sizeof(y)) == 0) {
+
1595  clean(y);
+
1596  return true;
+
1597  }
+
1598 
+
1599  // Multiply the result by sqrt(-1) and check again.
+
1600  mul_P(result, result, numSqrtM1);
+
1601  square(y, result);
+
1602  if (memcmp(x, y, sizeof(y)) == 0) {
+
1603  clean(y);
+
1604  return true;
+
1605  }
+
1606 
+
1607  // The number does not have a square root.
+
1608  clean(y);
+
1609  return false;
+
1610 }
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
Curve25519::eval
static bool eval(uint8_t result[32], const uint8_t s[32], const uint8_t x[32])
Evaluates the raw Curve25519 function.
Definition: Curve25519.cpp:80
BigNumberUtil::unpackLE
static void unpackLE(limb_t *limbs, size_t count, const uint8_t *bytes, size_t len)
Unpacks the little-endian byte representation of a big number into a limb array.
Definition: BigNumberUtil.cpp:55
BigNumberUtil::packLE
static void packLE(uint8_t *bytes, size_t len, const limb_t *limbs, size_t count)
Packs the little-endian byte representation of a big number into a byte array.
Definition: BigNumberUtil.cpp:264
@@ -1458,7 +1459,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Curve25519_8h_source.html b/Curve25519_8h_source.html index 68d40359..c1c3724b 100644 --- a/Curve25519_8h_source.html +++ b/Curve25519_8h_source.html @@ -173,7 +173,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DMD_8cpp_source.html b/DMD_8cpp_source.html index f3b28cc3..a5a6dd3b 100644 --- a/DMD_8cpp_source.html +++ b/DMD_8cpp_source.html @@ -456,7 +456,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DMD_8h_source.html b/DMD_8h_source.html index f9536c25..03de4960 100644 --- a/DMD_8h_source.html +++ b/DMD_8h_source.html @@ -170,7 +170,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS1307RTC_8cpp_source.html b/DS1307RTC_8cpp_source.html index 6ad9b49d..657010ee 100644 --- a/DS1307RTC_8cpp_source.html +++ b/DS1307RTC_8cpp_source.html @@ -415,7 +415,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS1307RTC_8h_source.html b/DS1307RTC_8h_source.html index b36f28bd..4f79a0bb 100644 --- a/DS1307RTC_8h_source.html +++ b/DS1307RTC_8h_source.html @@ -172,7 +172,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS3231RTC_8cpp_source.html b/DS3231RTC_8cpp_source.html index bbbd8b40..ef77b84c 100644 --- a/DS3231RTC_8cpp_source.html +++ b/DS3231RTC_8cpp_source.html @@ -657,7 +657,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS3231RTC_8h_source.html b/DS3231RTC_8h_source.html index c6813829..14ccf9fa 100644 --- a/DS3231RTC_8h_source.html +++ b/DS3231RTC_8h_source.html @@ -202,7 +202,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS3232RTC_8cpp_source.html b/DS3232RTC_8cpp_source.html index c37c99db..0410ec18 100644 --- a/DS3232RTC_8cpp_source.html +++ b/DS3232RTC_8cpp_source.html @@ -575,7 +575,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DS3232RTC_8h_source.html b/DS3232RTC_8h_source.html index 56af5709..e93a2605 100644 --- a/DS3232RTC_8h_source.html +++ b/DS3232RTC_8h_source.html @@ -190,7 +190,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DejaVuSans9_8h_source.html b/DejaVuSans9_8h_source.html index dd571f91..659af806 100644 --- a/DejaVuSans9_8h_source.html +++ b/DejaVuSans9_8h_source.html @@ -257,7 +257,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DejaVuSansBold9_8h_source.html b/DejaVuSansBold9_8h_source.html index 65fcf746..54bfdf2c 100644 --- a/DejaVuSansBold9_8h_source.html +++ b/DejaVuSansBold9_8h_source.html @@ -257,7 +257,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/DejaVuSansItalic9_8h_source.html b/DejaVuSansItalic9_8h_source.html index c6ed0eac..dcae79df 100644 --- a/DejaVuSansItalic9_8h_source.html +++ b/DejaVuSansItalic9_8h_source.html @@ -257,7 +257,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/EAX_8cpp_source.html b/EAX_8cpp_source.html index a229d61d..917bfa15 100644 --- a/EAX_8cpp_source.html +++ b/EAX_8cpp_source.html @@ -301,7 +301,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/EAX_8h_source.html b/EAX_8h_source.html index f406e17f..d4af0d6b 100644 --- a/EAX_8h_source.html +++ b/EAX_8h_source.html @@ -196,7 +196,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/EEPROM24_8cpp_source.html b/EEPROM24_8cpp_source.html index 48aaeeb4..4866cc9f 100644 --- a/EEPROM24_8cpp_source.html +++ b/EEPROM24_8cpp_source.html @@ -282,7 +282,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/EEPROM24_8h_source.html b/EEPROM24_8h_source.html index a9d06731..507c9ccf 100644 --- a/EEPROM24_8h_source.html +++ b/EEPROM24_8h_source.html @@ -186,7 +186,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Ed25519_8cpp_source.html b/Ed25519_8cpp_source.html index 6fae433c..dd17b7fe 100644 --- a/Ed25519_8cpp_source.html +++ b/Ed25519_8cpp_source.html @@ -556,7 +556,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
BigNumberUtil::reduceQuick_P
static void reduceQuick_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction where y is in program memory.
Definition: BigNumberUtil.cpp:734
Ed25519::generatePrivateKey
static void generatePrivateKey(uint8_t privateKey[32])
Generates a private key for Ed25519 signing operations.
Definition: Ed25519.cpp:243
BigNumberUtil::add
static limb_t add(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers.
Definition: BigNumberUtil.cpp:495
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
Ed25519::verify
static bool verify(const uint8_t signature[64], const uint8_t publicKey[32], const void *message, size_t len)
Verifies a signature using a specific Ed25519 public key.
Definition: Ed25519.cpp:189
SHA512
SHA-512 hash algorithm.
Definition: SHA512.h:30
SHA512::reset
void reset()
Resets the hash ready for a new hashing process.
Definition: SHA512.cpp:66
@@ -571,7 +571,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Ed25519_8h_source.html b/Ed25519_8h_source.html index 695e89d6..532aa66d 100644 --- a/Ed25519_8h_source.html +++ b/Ed25519_8h_source.html @@ -168,7 +168,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Field_8cpp_source.html b/Field_8cpp_source.html index 7b38ee20..71937208 100644 --- a/Field_8cpp_source.html +++ b/Field_8cpp_source.html @@ -196,7 +196,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Field_8h_source.html b/Field_8h_source.html index c6be444c..e3d22a44 100644 --- a/Field_8h_source.html +++ b/Field_8h_source.html @@ -164,7 +164,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Form_8cpp_source.html b/Form_8cpp_source.html index c951d1b0..fda140e6 100644 --- a/Form_8cpp_source.html +++ b/Form_8cpp_source.html @@ -278,7 +278,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Form_8h_source.html b/Form_8h_source.html index 09f5a97e..019475ea 100644 --- a/Form_8h_source.html +++ b/Form_8h_source.html @@ -172,7 +172,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GCM_8cpp_source.html b/GCM_8cpp_source.html index 92ac4b4e..c52b4bc4 100644 --- a/GCM_8cpp_source.html +++ b/GCM_8cpp_source.html @@ -353,7 +353,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GCM_8h_source.html b/GCM_8h_source.html index c4c977b4..1df82dde 100644 --- a/GCM_8h_source.html +++ b/GCM_8h_source.html @@ -191,7 +191,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GF128_8cpp_source.html b/GF128_8cpp_source.html index e5e83768..50189e4d 100644 --- a/GF128_8cpp_source.html +++ b/GF128_8cpp_source.html @@ -578,7 +578,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GF128_8h_source.html b/GF128_8h_source.html index ed2da754..bf894e1f 100644 --- a/GF128_8h_source.html +++ b/GF128_8h_source.html @@ -139,7 +139,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GHASH_8cpp_source.html b/GHASH_8cpp_source.html index dee96fe8..27fb9517 100644 --- a/GHASH_8cpp_source.html +++ b/GHASH_8cpp_source.html @@ -190,7 +190,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/GHASH_8h_source.html b/GHASH_8h_source.html index 6bc6edd9..57571265 100644 --- a/GHASH_8h_source.html +++ b/GHASH_8h_source.html @@ -150,7 +150,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Hash_8cpp_source.html b/Hash_8cpp_source.html index f60b8eb7..3eba28b7 100644 --- a/Hash_8cpp_source.html +++ b/Hash_8cpp_source.html @@ -151,7 +151,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Hash_8h_source.html b/Hash_8h_source.html index ca0017cd..f0bfe0ee 100644 --- a/Hash_8h_source.html +++ b/Hash_8h_source.html @@ -154,7 +154,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/I2CMaster_8cpp_source.html b/I2CMaster_8cpp_source.html index 14242c5a..fa77744a 100644 --- a/I2CMaster_8cpp_source.html +++ b/I2CMaster_8cpp_source.html @@ -115,7 +115,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/I2CMaster_8h_source.html b/I2CMaster_8h_source.html index 4ff994dc..b115c92e 100644 --- a/I2CMaster_8h_source.html +++ b/I2CMaster_8h_source.html @@ -140,7 +140,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/IRreceiver_8cpp_source.html b/IRreceiver_8cpp_source.html index 6303f572..163fcfac 100644 --- a/IRreceiver_8cpp_source.html +++ b/IRreceiver_8cpp_source.html @@ -261,7 +261,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/IRreceiver_8h_source.html b/IRreceiver_8h_source.html index 20a5d8ee..ce07a28e 100644 --- a/IRreceiver_8h_source.html +++ b/IRreceiver_8h_source.html @@ -157,7 +157,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/IntField_8cpp_source.html b/IntField_8cpp_source.html index 0914e883..2ba99c02 100644 --- a/IntField_8cpp_source.html +++ b/IntField_8cpp_source.html @@ -208,7 +208,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/IntField_8h_source.html b/IntField_8h_source.html index aaa8ee5c..eeead3ea 100644 --- a/IntField_8h_source.html +++ b/IntField_8h_source.html @@ -173,7 +173,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/KeccakCore_8cpp_source.html b/KeccakCore_8cpp_source.html index 11e46130..85f6e443 100644 --- a/KeccakCore_8cpp_source.html +++ b/KeccakCore_8cpp_source.html @@ -1991,7 +1991,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/KeccakCore_8h_source.html b/KeccakCore_8h_source.html index f6d332dd..6a270556 100644 --- a/KeccakCore_8h_source.html +++ b/KeccakCore_8h_source.html @@ -167,7 +167,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/LCD_8cpp_source.html b/LCD_8cpp_source.html index d33a3d1b..4250ff61 100644 --- a/LCD_8cpp_source.html +++ b/LCD_8cpp_source.html @@ -290,7 +290,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/LCD_8h_source.html b/LCD_8h_source.html index cc9baaa8..e95c5498 100644 --- a/LCD_8h_source.html +++ b/LCD_8h_source.html @@ -202,7 +202,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ListField_8cpp_source.html b/ListField_8cpp_source.html index e05c3172..9f678357 100644 --- a/ListField_8cpp_source.html +++ b/ListField_8cpp_source.html @@ -221,7 +221,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ListField_8h_source.html b/ListField_8h_source.html index f73c0d18..edd3ccc0 100644 --- a/ListField_8h_source.html +++ b/ListField_8h_source.html @@ -159,7 +159,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/LoginShell_8cpp_source.html b/LoginShell_8cpp_source.html index db618d37..2dde2549 100644 --- a/LoginShell_8cpp_source.html +++ b/LoginShell_8cpp_source.html @@ -126,7 +126,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/LoginShell_8h_source.html b/LoginShell_8h_source.html index 4fa4fd03..00f8b79a 100644 --- a/LoginShell_8h_source.html +++ b/LoginShell_8h_source.html @@ -155,7 +155,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Melody_8cpp_source.html b/Melody_8cpp_source.html index 03d4392a..0608d6fb 100644 --- a/Melody_8cpp_source.html +++ b/Melody_8cpp_source.html @@ -215,7 +215,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Melody_8h_source.html b/Melody_8h_source.html index c312eb04..fe9c34fd 100644 --- a/Melody_8h_source.html +++ b/Melody_8h_source.html @@ -258,7 +258,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Mono5x7_8h_source.html b/Mono5x7_8h_source.html index 64f89109..ebf08716 100644 --- a/Mono5x7_8h_source.html +++ b/Mono5x7_8h_source.html @@ -246,7 +246,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/NewHope_8cpp_source.html b/NewHope_8cpp_source.html index 28c268bb..9de4e753 100644 --- a/NewHope_8cpp_source.html +++ b/NewHope_8cpp_source.html @@ -124,1127 +124,1168 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
36  return ptr;
37 }
38 
-
39 #if defined(__AVR__)
-
40 #include <avr/pgmspace.h>
+
39 #if defined(ESP8266)
+
40 #include <pgmspace.h>
41 #define table_read(name, index) (pgm_read_word(&((name)[(index)])))
-
42 #else
-
43 #define PROGMEM
-
44 #define table_read(name, index) ((name)[(index)])
-
45 #endif
-
46 
-
158 typedef struct
-
159 {
-
160  uint32_t input[16];
-
161  uint32_t output[16];
-
162 
-
163 } NewHopeChaChaState;
-
164 
-
165 // The following is public domain code from the reference C version of
-
166 // New Hope at https://cryptojedi.org/crypto/#newhope. This part of
-
167 // the Arduino port remains public domain. Original authors:
-
168 // Erdem Alkim, Léo Ducas, Thomas Pöppelmann, Peter Schwabe
-
169 
-
170 #define PARAM_N 1024
-
171 #define PARAM_K 16
-
172 #define PARAM_Q ((int32_t)12289)
-
173 #define POLY_BYTES 1792
-
174 #define NEWHOPE_SEEDBYTES 32
-
175 #define NEWHOPE_RECBYTES 256
-
176 
-
177 static uint16_t const omegas_montgomery[PARAM_N/2] PROGMEM = {
-
178  4075,6974,7373,7965,3262,5079,522,2169,6364,1018,1041,8775,2344,
-
179  11011,5574,1973,4536,1050,6844,3860,3818,6118,2683,1190,4789,7822,
-
180  7540,6752,5456,4449,3789,12142,11973,382,3988,468,6843,5339,6196,
-
181  3710,11316,1254,5435,10930,3998,10256,10367,3879,11889,1728,6137,
-
182  4948,5862,6136,3643,6874,8724,654,10302,1702,7083,6760,56,3199,9987,
-
183  605,11785,8076,5594,9260,6403,4782,6212,4624,9026,8689,4080,11868,
-
184  6221,3602,975,8077,8851,9445,5681,3477,1105,142,241,12231,1003,
-
185  3532,5009,1956,6008,11404,7377,2049,10968,12097,7591,5057,3445,
-
186  4780,2920,7048,3127,8120,11279,6821,11502,8807,12138,2127,2839,
-
187  3957,431,1579,6383,9784,5874,677,3336,6234,2766,1323,9115,12237,
-
188  2031,6956,6413,2281,3969,3991,12133,9522,4737,10996,4774,5429,11871,
-
189  3772,453,5908,2882,1805,2051,1954,11713,3963,2447,6142,8174,3030,
-
190  1843,2361,12071,2908,3529,3434,3202,7796,2057,5369,11939,1512,6906,
-
191  10474,11026,49,10806,5915,1489,9789,5942,10706,10431,7535,426,8974,
-
192  3757,10314,9364,347,5868,9551,9634,6554,10596,9280,11566,174,2948,
-
193  2503,6507,10723,11606,2459,64,3656,8455,5257,5919,7856,1747,9166,
-
194  5486,9235,6065,835,3570,4240,11580,4046,10970,9139,1058,8210,11848,
-
195  922,7967,1958,10211,1112,3728,4049,11130,5990,1404,325,948,11143,
-
196  6190,295,11637,5766,8212,8273,2919,8527,6119,6992,8333,1360,2555,
-
197  6167,1200,7105,7991,3329,9597,12121,5106,5961,10695,10327,3051,9923,
-
198  4896,9326,81,3091,1000,7969,4611,726,1853,12149,4255,11112,2768,
-
199  10654,1062,2294,3553,4805,2747,4846,8577,9154,1170,2319,790,11334,
-
200  9275,9088,1326,5086,9094,6429,11077,10643,3504,3542,8668,9744,1479,
-
201  1,8246,7143,11567,10984,4134,5736,4978,10938,5777,8961,4591,5728,
-
202  6461,5023,9650,7468,949,9664,2975,11726,2744,9283,10092,5067,12171,
-
203  2476,3748,11336,6522,827,9452,5374,12159,7935,3296,3949,9893,4452,
-
204  10908,2525,3584,8112,8011,10616,4989,6958,11809,9447,12280,1022,
-
205  11950,9821,11745,5791,5092,2089,9005,2881,3289,2013,9048,729,7901,
-
206  1260,5755,4632,11955,2426,10593,1428,4890,5911,3932,9558,8830,3637,
-
207  5542,145,5179,8595,3707,10530,355,3382,4231,9741,1207,9041,7012,1168,
-
208  10146,11224,4645,11885,10911,10377,435,7952,4096,493,9908,6845,6039,
-
209  2422,2187,9723,8643,9852,9302,6022,7278,1002,4284,5088,1607,7313,
-
210  875,8509,9430,1045,2481,5012,7428,354,6591,9377,11847,2401,1067,
-
211  7188,11516,390,8511,8456,7270,545,8585,9611,12047,1537,4143,4714,
-
212  4885,1017,5084,1632,3066,27,1440,8526,9273,12046,11618,9289,3400,
-
213  9890,3136,7098,8758,11813,7384,3985,11869,6730,10745,10111,2249,
-
214  4048,2884,11136,2126,1630,9103,5407,2686,9042,2969,8311,9424,
-
215  9919,8779,5332,10626,1777,4654,10863,7351,3636,9585,5291,8374,
-
216  2166,4919,12176,9140,12129,7852,12286,4895,10805,2780,5195,2305,
-
217  7247,9644,4053,10600,3364,3271,4057,4414,9442,7917,2174
-
218 };
-
219 
-
220 static uint16_t const omegas_inv_montgomery[PARAM_N/2] PROGMEM = {
-
221  4075,5315,4324,4916,10120,11767,7210,9027,10316,6715,1278,9945,
-
222  3514,11248,11271,5925,147,8500,7840,6833,5537,4749,4467,7500,11099,
-
223  9606,6171,8471,8429,5445,11239,7753,9090,12233,5529,5206,10587,
-
224  1987,11635,3565,5415,8646,6153,6427,7341,6152,10561,400,8410,1922,
-
225  2033,8291,1359,6854,11035,973,8579,6093,6950,5446,11821,8301,11907,
-
226  316,52,3174,10966,9523,6055,8953,11612,6415,2505,5906,10710,11858,
-
227  8332,9450,10162,151,3482,787,5468,1010,4169,9162,5241,9369,7509,
-
228  8844,7232,4698,192,1321,10240,4912,885,6281,10333,7280,8757,11286,
-
229  58,12048,12147,11184,8812,6608,2844,3438,4212,11314,8687,6068,421,
-
230  8209,3600,3263,7665,6077,7507,5886,3029,6695,4213,504,11684,2302,
-
231  1962,1594,6328,7183,168,2692,8960,4298,5184,11089,6122,9734,10929,
-
232  3956,5297,6170,3762,9370,4016,4077,6523,652,11994,6099,1146,11341,
-
233  11964,10885,6299,1159,8240,8561,11177,2078,10331,4322,11367,441,
-
234  4079,11231,3150,1319,8243,709,8049,8719,11454,6224,3054,6803,3123,
-
235  10542,4433,6370,7032,3834,8633,12225,9830,683,1566,5782,9786,9341,
-
236  12115,723,3009,1693,5735,2655,2738,6421,11942,2925,1975,8532,3315,
-
237  11863,4754,1858,1583,6347,2500,10800,6374,1483,12240,1263,1815,
-
238  5383,10777,350,6920,10232,4493,9087,8855,8760,9381,218,9928,10446,
-
239  9259,4115,6147,9842,8326,576,10335,10238,10484,9407,6381,11836,8517,
-
240  418,6860,7515,1293,7552,2767,156,8298,8320,10008,5876,5333,10258,
-
241  10115,4372,2847,7875,8232,9018,8925,1689,8236,2645,5042,9984,7094,
-
242  9509,1484,7394,3,4437,160,3149,113,7370,10123,3915,6998,2704,8653,
-
243  4938,1426,7635,10512,1663,6957,3510,2370,2865,3978,9320,3247,9603,
-
244  6882,3186,10659,10163,1153,9405,8241,10040,2178,1544,5559,420,8304,
-
245  4905,476,3531,5191,9153,2399,8889,3000,671,243,3016,3763,10849,12262,
-
246  9223,10657,7205,11272,7404,7575,8146,10752,242,2678,3704,11744,
-
247  5019,3833,3778,11899,773,5101,11222,9888,442,2912,5698,11935,4861,
-
248  7277,9808,11244,2859,3780,11414,4976,10682,7201,8005,11287,5011,
-
249  6267,2987,2437,3646,2566,10102,9867,6250,5444,2381,11796,8193,4337,
-
250  11854,1912,1378,404,7644,1065,2143,11121,5277,3248,11082,2548,8058,
-
251  8907,11934,1759,8582,3694,7110,12144,6747,8652,3459,2731,8357,6378,
-
252  7399,10861,1696,9863,334,7657,6534,11029,4388,11560,3241,10276,9000,
-
253  9408,3284,10200,7197,6498,544,2468,339,11267,9,2842,480,5331,7300,
-
254  1673,4278,4177,8705,9764,1381,7837,2396,8340,8993,4354,130,6915,
-
255  2837,11462,5767,953,8541,9813,118,7222,2197,3006,9545,563,9314,
-
256  2625,11340,4821,2639,7266,5828,6561,7698,3328,6512,1351,7311,6553,
-
257  8155,1305,722,5146,4043,12288,10810,2545,3621,8747,8785,1646,1212,
-
258  5860,3195,7203,10963,3201,3014,955,11499,9970,11119,3135,3712,7443,
-
259  9542,7484,8736,9995,11227,1635,9521,1177,8034,140,10436,11563,7678,
-
260  4320,11289,9198,12208,2963,7393,2366,9238
-
261 };
-
262 
-
263 static uint16_t const psis_bitrev_montgomery[PARAM_N] PROGMEM = {
-
264  4075,6974,7373,7965,3262,5079,522,2169,6364,1018,1041,8775,2344,
-
265  11011,5574,1973,4536,1050,6844,3860,3818,6118,2683,1190,4789,7822,
-
266  7540,6752,5456,4449,3789,12142,11973,382,3988,468,6843,5339,6196,3710,
-
267  11316,1254,5435,10930,3998,10256,10367,3879,11889,1728,6137,4948,
-
268  5862,6136,3643,6874,8724,654,10302,1702,7083,6760,56,3199,9987,605,
-
269  11785,8076,5594,9260,6403,4782,6212,4624,9026,8689,4080,11868,6221,
-
270  3602,975,8077,8851,9445,5681,3477,1105,142,241,12231,1003,3532,5009,
-
271  1956,6008,11404,7377,2049,10968,12097,7591,5057,3445,4780,2920,
-
272  7048,3127,8120,11279,6821,11502,8807,12138,2127,2839,3957,431,1579,
-
273  6383,9784,5874,677,3336,6234,2766,1323,9115,12237,2031,6956,6413,
-
274  2281,3969,3991,12133,9522,4737,10996,4774,5429,11871,3772,453,
-
275  5908,2882,1805,2051,1954,11713,3963,2447,6142,8174,3030,1843,2361,
-
276  12071,2908,3529,3434,3202,7796,2057,5369,11939,1512,6906,10474,
-
277  11026,49,10806,5915,1489,9789,5942,10706,10431,7535,426,8974,3757,
-
278  10314,9364,347,5868,9551,9634,6554,10596,9280,11566,174,2948,2503,
-
279  6507,10723,11606,2459,64,3656,8455,5257,5919,7856,1747,9166,5486,
-
280  9235,6065,835,3570,4240,11580,4046,10970,9139,1058,8210,11848,922,
-
281  7967,1958,10211,1112,3728,4049,11130,5990,1404,325,948,11143,6190,
-
282  295,11637,5766,8212,8273,2919,8527,6119,6992,8333,1360,2555,6167,
-
283  1200,7105,7991,3329,9597,12121,5106,5961,10695,10327,3051,9923,
-
284  4896,9326,81,3091,1000,7969,4611,726,1853,12149,4255,11112,2768,
-
285  10654,1062,2294,3553,4805,2747,4846,8577,9154,1170,2319,790,11334,
-
286  9275,9088,1326,5086,9094,6429,11077,10643,3504,3542,8668,9744,1479,
-
287  1,8246,7143,11567,10984,4134,5736,4978,10938,5777,8961,4591,5728,
-
288  6461,5023,9650,7468,949,9664,2975,11726,2744,9283,10092,5067,12171,
-
289  2476,3748,11336,6522,827,9452,5374,12159,7935,3296,3949,9893,4452,
-
290  10908,2525,3584,8112,8011,10616,4989,6958,11809,9447,12280,1022,
-
291  11950,9821,11745,5791,5092,2089,9005,2881,3289,2013,9048,729,7901,
-
292  1260,5755,4632,11955,2426,10593,1428,4890,5911,3932,9558,8830,3637,
-
293  5542,145,5179,8595,3707,10530,355,3382,4231,9741,1207,9041,7012,
-
294  1168,10146,11224,4645,11885,10911,10377,435,7952,4096,493,9908,6845,
-
295  6039,2422,2187,9723,8643,9852,9302,6022,7278,1002,4284,5088,1607,
-
296  7313,875,8509,9430,1045,2481,5012,7428,354,6591,9377,11847,2401,
-
297  1067,7188,11516,390,8511,8456,7270,545,8585,9611,12047,1537,4143,
-
298  4714,4885,1017,5084,1632,3066,27,1440,8526,9273,12046,11618,9289,
-
299  3400,9890,3136,7098,8758,11813,7384,3985,11869,6730,10745,10111,
-
300  2249,4048,2884,11136,2126,1630,9103,5407,2686,9042,2969,8311,9424,
-
301  9919,8779,5332,10626,1777,4654,10863,7351,3636,9585,5291,8374,
-
302  2166,4919,12176,9140,12129,7852,12286,4895,10805,2780,5195,2305,
-
303  7247,9644,4053,10600,3364,3271,4057,4414,9442,7917,2174,3947,
-
304  11951,2455,6599,10545,10975,3654,2894,7681,7126,7287,12269,4119,
-
305  3343,2151,1522,7174,7350,11041,2442,2148,5959,6492,8330,8945,5598,
-
306  3624,10397,1325,6565,1945,11260,10077,2674,3338,3276,11034,506,
-
307  6505,1392,5478,8778,1178,2776,3408,10347,11124,2575,9489,12096,
-
308  6092,10058,4167,6085,923,11251,11912,4578,10669,11914,425,10453,
-
309  392,10104,8464,4235,8761,7376,2291,3375,7954,8896,6617,7790,1737,
-
310  11667,3982,9342,6680,636,6825,7383,512,4670,2900,12050,7735,994,
-
311  1687,11883,7021,146,10485,1403,5189,6094,2483,2054,3042,10945,
-
312  3981,10821,11826,8882,8151,180,9600,7684,5219,10880,6780,204,
-
313  11232,2600,7584,3121,3017,11053,7814,7043,4251,4739,11063,6771,
-
314  7073,9261,2360,11925,1928,11825,8024,3678,3205,3359,11197,5209,
-
315  8581,3238,8840,1136,9363,1826,3171,4489,7885,346,2068,1389,8257,
-
316  3163,4840,6127,8062,8921,612,4238,10763,8067,125,11749,10125,5416,
-
317  2110,716,9839,10584,11475,11873,3448,343,1908,4538,10423,7078,
-
318  4727,1208,11572,3589,2982,1373,1721,10753,4103,2429,4209,5412,
-
319  5993,9011,438,3515,7228,1218,8347,5232,8682,1327,7508,4924,448,
-
320  1014,10029,12221,4566,5836,12229,2717,1535,3200,5588,5845,412,
-
321  5102,7326,3744,3056,2528,7406,8314,9202,6454,6613,1417,10032,7784,
-
322  1518,3765,4176,5063,9828,2275,6636,4267,6463,2065,7725,3495,8328,
-
323  8755,8144,10533,5966,12077,9175,9520,5596,6302,8400,579,6781,11014,
-
324  5734,11113,11164,4860,1131,10844,9068,8016,9694,3837,567,9348,7000,
-
325  6627,7699,5082,682,11309,5207,4050,7087,844,7434,3769,293,9057,
-
326  6940,9344,10883,2633,8190,3944,5530,5604,3480,2171,9282,11024,2213,
-
327  8136,3805,767,12239,216,11520,6763,10353,7,8566,845,7235,3154,4360,
-
328  3285,10268,2832,3572,1282,7559,3229,8360,10583,6105,3120,6643,6203,
-
329  8536,8348,6919,3536,9199,10891,11463,5043,1658,5618,8787,5789,4719,
-
330  751,11379,6389,10783,3065,7806,6586,2622,5386,510,7628,6921,578,
-
331  10345,11839,8929,4684,12226,7154,9916,7302,8481,3670,11066,2334,
-
332  1590,7878,10734,1802,1891,5103,6151,8820,3418,7846,9951,4693,417,
-
333  9996,9652,4510,2946,5461,365,881,1927,1015,11675,11009,1371,12265,
-
334  2485,11385,5039,6742,8449,1842,12217,8176,9577,4834,7937,9461,2643,
-
335  11194,3045,6508,4094,3451,7911,11048,5406,4665,3020,6616,11345,
-
336  7519,3669,5287,1790,7014,5410,11038,11249,2035,6125,10407,4565,
-
337  7315,5078,10506,2840,2478,9270,4194,9195,4518,7469,1160,6878,2730,
-
338  10421,10036,1734,3815,10939,5832,10595,10759,4423,8420,9617,7119,
-
339  11010,11424,9173,189,10080,10526,3466,10588,7592,3578,11511,7785,
-
340  9663,530,12150,8957,2532,3317,9349,10243,1481,9332,3454,3758,7899,
-
341  4218,2593,11410,2276,982,6513,1849,8494,9021,4523,7988,8,457,648,
-
342  150,8000,2307,2301,874,5650,170,9462,2873,9855,11498,2535,11169,
-
343  5808,12268,9687,1901,7171,11787,3846,1573,6063,3793,466,11259,
-
344  10608,3821,6320,4649,6263,2929
-
345 };
-
346 
-
347 static uint16_t const psis_inv_montgomery[PARAM_N] PROGMEM = {
-
348  256,10570,1510,7238,1034,7170,6291,7921,11665,3422,4000,2327,
-
349  2088,5565,795,10647,1521,5484,2539,7385,1055,7173,8047,11683,
-
350  1669,1994,3796,5809,4341,9398,11876,12230,10525,12037,12253,
-
351  3506,4012,9351,4847,2448,7372,9831,3160,2207,5582,2553,7387,6322,
-
352  9681,1383,10731,1533,219,5298,4268,7632,6357,9686,8406,4712,9451,
-
353  10128,4958,5975,11387,8649,11769,6948,11526,12180,1740,10782,
-
354  6807,2728,7412,4570,4164,4106,11120,12122,8754,11784,3439,5758,
-
355  11356,6889,9762,11928,1704,1999,10819,12079,12259,7018,11536,
-
356  1648,1991,2040,2047,2048,10826,12080,8748,8272,8204,1172,1923,
-
357  7297,2798,7422,6327,4415,7653,6360,11442,12168,7005,8023,9924,
-
358  8440,8228,2931,7441,1063,3663,5790,9605,10150,1450,8985,11817,
-
359  10466,10273,12001,3470,7518,1074,1909,7295,9820,4914,702,5367,
-
360  7789,8135,9940,1420,3714,11064,12114,12264,1752,5517,9566,11900,
-
361  1700,3754,5803,829,1874,7290,2797,10933,5073,7747,8129,6428,
-
362  6185,11417,1631,233,5300,9535,10140,11982,8734,8270,2937,10953,
-
363  8587,8249,2934,9197,4825,5956,4362,9401,1343,3703,529,10609,
-
364  12049,6988,6265,895,3639,4031,4087,4095,585,10617,8539,4731,
-
365  4187,9376,3095,9220,10095,10220,1460,10742,12068,1724,5513,
-
366  11321,6884,2739,5658,6075,4379,11159,10372,8504,4726,9453,3106,
-
367  7466,11600,10435,8513,9994,8450,9985,3182,10988,8592,2983,9204,
-
368  4826,2445,5616,6069,867,3635,5786,11360,5134,2489,10889,12089,
-
369  1727,7269,2794,9177,1311,5454,9557,6632,2703,9164,10087,1441,
-
370  3717,531,3587,2268,324,5313,759,1864,5533,2546,7386,9833,8427,
-
371  4715,11207,1601,7251,4547,11183,12131,1733,10781,10318,1474,
-
372  10744,5046,4232,11138,10369,6748,964,7160,4534,7670,8118,8182,
-
373  4680,11202,6867,981,8918,1274,182,26,7026,8026,11680,12202,
-
374  10521,1503,7237,4545,5916,9623,8397,11733,10454,3249,9242,6587,
-
375  941,1890,270,10572,6777,9746,6659,6218,6155,6146,878,1881,7291,
-
376  11575,12187,1741,7271,8061,11685,6936,4502,9421,4857,4205,7623,
-
377  1089,10689,1527,8996,10063,11971,10488,6765,2722,3900,9335,11867,
-
378  6962,11528,5158,4248,4118,5855,2592,5637,6072,2623,7397,8079,
-
379  9932,4930,5971,853,3633,519,8852,11798,3441,11025,1575,225,8810,
-
380  11792,12218,3501,9278,3081,9218,4828,7712,8124,11694,12204,3499,
-
381  4011,573,3593,5780,7848,9899,10192,1456,208,7052,2763,7417,11593,
-
382  10434,12024,8740,11782,10461,3250,5731,7841,9898,1414,202,3540,
-
383  7528,2831,2160,10842,5060,4234,4116,588,84,12,7024,2759,9172,6577,
-
384  11473,1639,9012,3043,7457,6332,11438,1634,1989,9062,11828,8712,
-
385  11778,12216,10523,6770,9745,10170,4964,9487,6622,946,8913,6540,
-
386  6201,4397,9406,8366,9973,8447,8229,11709,8695,10020,3187,5722,
-
387  2573,10901,6824,4486,4152,9371,8361,2950,2177,311,1800,9035,
-
388  8313,11721,3430,490,70,10,1757,251,3547,7529,11609,3414,7510,
-
389  4584,4166,9373,1339,5458,7802,11648,1664,7260,9815,10180,6721,
-
390  9738,10169,8475,8233,9954,1422,8981,1283,5450,11312,1616,3742,
-
391  11068,10359,4991,713,3613,9294,8350,4704,672,96,7036,9783,11931,
-
392  3460,5761,823,10651,12055,10500,1500,5481,783,3623,11051,8601,
-
393  8251,8201,11705,10450,5004,4226,7626,2845,2162,3820,7568,9859,
-
394  3164,452,10598,1514,5483,6050,6131,4387,7649,8115,6426,918,8909,
-
395  8295,1185,5436,11310,8638,1234,5443,11311,5127,2488,2111,10835,
-
396  5059,7745,2862,3920,560,80,1767,2008,3798,11076,6849,2734,10924,
-
397  12094,8750,1250,10712,6797,971,7161,1023,8924,4786,7706,4612,4170,
-
398  7618,6355,4419,5898,11376,10403,10264,6733,4473,639,5358,2521,
-
399  9138,3061,5704,4326,618,5355,765,5376,768,7132,4530,9425,3102,
-
400  9221,6584,11474,10417,10266,12000,6981,6264,4406,2385,7363,4563,
-
401  4163,7617,9866,3165,9230,11852,10471,5007,5982,11388,5138,734,
-
402  3616,11050,12112,6997,11533,12181,10518,12036,3475,2252,7344,
-
403  9827,4915,9480,6621,4457,7659,9872,6677,4465,4149,7615,4599,657,
-
404  3605,515,10607,6782,4480,640,1847,3775,5806,2585,5636,9583,1369,
-
405  10729,8555,10000,11962,5220,7768,8132,8184,9947,1421,203,29,8782,
-
406  11788,1684,10774,10317,4985,9490,8378,4708,11206,5112,5997,7879,
-
407  11659,12199,8765,10030,4944,5973,6120,6141,6144,7900,11662,1666,
-
408  238,34,3516,5769,9602,8394,9977,6692,956,10670,6791,9748,11926,
-
409  8726,11780,5194,742,106,8793,10034,3189,10989,5081,4237,5872,4350,
-
410  2377,10873,6820,6241,11425,10410,10265,3222,5727,9596,4882,2453,
-
411  2106,3812,11078,12116,5242,4260,11142,8614,11764,12214,5256,4262,
-
412  4120,11122,5100,11262,5120,2487,5622,9581,8391,8221,2930,10952,
-
413  12098,6995,6266,9673,4893,699,3611,4027,5842,11368,1624,232,8811,
-
414  8281,1183,169,8802,3013,2186,5579,797,3625,4029,11109,1587,7249,
-
415  11569,8675,6506,2685,10917,12093,12261,12285,1755,7273,1039,1904,
-
416  272,3550,9285,3082,5707,6082,4380,7648,11626,5172,4250,9385,8363,
-
417  8217,4685,5936,848,8899,6538,934,1889,3781,9318,10109,10222,6727,
-
418  961,5404,772,5377,9546,8386,1198,8949,3034,2189,7335,4559,5918,2601,
-
419  10905,5069,9502,3113,7467,8089,11689,5181,9518,8382,2953,3933,4073,
-
420  4093,7607,8109,2914,5683,4323,11151,1593,10761,6804,972,3650,2277,
-
421  5592,4310,7638,9869,4921,703,1856,9043,4803,9464,1352,8971,11815,
-
422  5199,7765,6376,4422,7654,2849,407,8836,6529,7955,2892,9191,1313,
-
423  10721,12065,12257,1751,9028,8312,2943,2176,3822,546,78,8789,11789,
-
424  10462,12028,6985,4509,9422,1346,5459,4291,613,10621,6784,9747,3148,
-
425  7472,2823,5670,810,7138,8042,4660,7688,6365,6176,6149,2634,5643,
-
426  9584,10147,11983,5223,9524,11894,10477,8519,1217,3685,2282,326,
-
427  10580,3267,7489,4581,2410,5611,11335,6886,8006,8166,11700,3427,
-
428  11023,8597,10006,3185,455,65,5276,7776,4622,5927,7869,9902,11948,
-
429  5218,2501,5624,2559,10899,1557,1978,10816,10323,8497,4725,675,1852,
-
430  10798,12076,10503,3256,9243,3076,2195,10847,12083,10504,12034,10497
-
431 };
-
432 
-
433 static uint16_t const bitrev_table[PARAM_N] PROGMEM = {
-
434  0,512,256,768,128,640,384,896,64,576,320,832,192,704,448,960,32,544,288,800,160,672,416,928,96,608,352,864,224,736,480,992,
-
435  16,528,272,784,144,656,400,912,80,592,336,848,208,720,464,976,48,560,304,816,176,688,432,944,112,624,368,880,240,752,496,1008,
-
436  8,520,264,776,136,648,392,904,72,584,328,840,200,712,456,968,40,552,296,808,168,680,424,936,104,616,360,872,232,744,488,1000,
-
437  24,536,280,792,152,664,408,920,88,600,344,856,216,728,472,984,56,568,312,824,184,696,440,952,120,632,376,888,248,760,504,1016,
-
438  4,516,260,772,132,644,388,900,68,580,324,836,196,708,452,964,36,548,292,804,164,676,420,932,100,612,356,868,228,740,484,996,
-
439  20,532,276,788,148,660,404,916,84,596,340,852,212,724,468,980,52,564,308,820,180,692,436,948,116,628,372,884,244,756,500,1012,
-
440  12,524,268,780,140,652,396,908,76,588,332,844,204,716,460,972,44,556,300,812,172,684,428,940,108,620,364,876,236,748,492,1004,
-
441  28,540,284,796,156,668,412,924,92,604,348,860,220,732,476,988,60,572,316,828,188,700,444,956,124,636,380,892,252,764,508,1020,
-
442  2,514,258,770,130,642,386,898,66,578,322,834,194,706,450,962,34,546,290,802,162,674,418,930,98,610,354,866,226,738,482,994,
-
443  18,530,274,786,146,658,402,914,82,594,338,850,210,722,466,978,50,562,306,818,178,690,434,946,114,626,370,882,242,754,498,1010,
-
444  10,522,266,778,138,650,394,906,74,586,330,842,202,714,458,970,42,554,298,810,170,682,426,938,106,618,362,874,234,746,490,1002,
-
445  26,538,282,794,154,666,410,922,90,602,346,858,218,730,474,986,58,570,314,826,186,698,442,954,122,634,378,890,250,762,506,1018,
-
446  6,518,262,774,134,646,390,902,70,582,326,838,198,710,454,966,38,550,294,806,166,678,422,934,102,614,358,870,230,742,486,998,
-
447  22,534,278,790,150,662,406,918,86,598,342,854,214,726,470,982,54,566,310,822,182,694,438,950,118,630,374,886,246,758,502,1014,
-
448  14,526,270,782,142,654,398,910,78,590,334,846,206,718,462,974,46,558,302,814,174,686,430,942,110,622,366,878,238,750,494,1006,
-
449  30,542,286,798,158,670,414,926,94,606,350,862,222,734,478,990,62,574,318,830,190,702,446,958,126,638,382,894,254,766,510,1022,
-
450  1,513,257,769,129,641,385,897,65,577,321,833,193,705,449,961,33,545,289,801,161,673,417,929,97,609,353,865,225,737,481,993,
-
451  17,529,273,785,145,657,401,913,81,593,337,849,209,721,465,977,49,561,305,817,177,689,433,945,113,625,369,881,241,753,497,1009,
-
452  9,521,265,777,137,649,393,905,73,585,329,841,201,713,457,969,41,553,297,809,169,681,425,937,105,617,361,873,233,745,489,1001,
-
453  25,537,281,793,153,665,409,921,89,601,345,857,217,729,473,985,57,569,313,825,185,697,441,953,121,633,377,889,249,761,505,1017,
-
454  5,517,261,773,133,645,389,901,69,581,325,837,197,709,453,965,37,549,293,805,165,677,421,933,101,613,357,869,229,741,485,997,
-
455  21,533,277,789,149,661,405,917,85,597,341,853,213,725,469,981,53,565,309,821,181,693,437,949,117,629,373,885,245,757,501,1013,
-
456  13,525,269,781,141,653,397,909,77,589,333,845,205,717,461,973,45,557,301,813,173,685,429,941,109,621,365,877,237,749,493,1005,
-
457  29,541,285,797,157,669,413,925,93,605,349,861,221,733,477,989,61,573,317,829,189,701,445,957,125,637,381,893,253,765,509,1021,
-
458  3,515,259,771,131,643,387,899,67,579,323,835,195,707,451,963,35,547,291,803,163,675,419,931,99,611,355,867,227,739,483,995,
-
459  19,531,275,787,147,659,403,915,83,595,339,851,211,723,467,979,51,563,307,819,179,691,435,947,115,627,371,883,243,755,499,1011,
-
460  11,523,267,779,139,651,395,907,75,587,331,843,203,715,459,971,43,555,299,811,171,683,427,939,107,619,363,875,235,747,491,1003,
-
461  27,539,283,795,155,667,411,923,91,603,347,859,219,731,475,987,59,571,315,827,187,699,443,955,123,635,379,891,251,763,507,1019,
-
462  7,519,263,775,135,647,391,903,71,583,327,839,199,711,455,967,39,551,295,807,167,679,423,935,103,615,359,871,231,743,487,999,
-
463  23,535,279,791,151,663,407,919,87,599,343,855,215,727,471,983,55,567,311,823,183,695,439,951,119,631,375,887,247,759,503,1015,
-
464  15,527,271,783,143,655,399,911,79,591,335,847,207,719,463,975,47,559,303,815,175,687,431,943,111,623,367,879,239,751,495,1007,
-
465  31,543,287,799,159,671,415,927,95,607,351,863,223,735,479,991,63,575,319,831,191,703,447,959,127,639,383,895,255,767,511,1023
-
466 };
-
467 
-
468 /* Incomplete-reduction routines; for details on allowed input ranges
-
469  * and produced output ranges, see the description in the paper:
-
470  * https://cryptojedi.org/papers/#newhope */
-
471 
-
472 #define qinv 12287 // -inverse_mod(p,2^18)
-
473 #define rlog 18
-
474 
-
475 inline uint16_t montgomery_reduce(uint32_t a)
-
476 {
-
477  uint32_t u;
-
478 
-
479  u = (a * qinv);
-
480  u &= ((((uint32_t)1)<<rlog)-1);
-
481  u *= PARAM_Q;
-
482  a = a + u;
-
483  return a >> 18;
-
484 }
-
485 
-
486 inline uint16_t barrett_reduce(uint16_t a)
-
487 {
-
488  uint32_t u;
-
489 
-
490  u = ((uint32_t) a * 5) >> 16;
-
491  u *= PARAM_Q;
-
492  a -= u;
-
493  return a;
-
494 }
-
495 
-
496 static void bitrev_vector(uint16_t* poly)
-
497 {
-
498  unsigned int i,r;
-
499  uint16_t tmp;
-
500 
-
501  for(i = 0; i < PARAM_N; i++)
-
502  {
-
503  r = table_read(bitrev_table,i);
-
504  if (i < r)
-
505  {
-
506  tmp = poly[i];
-
507  poly[i] = poly[r];
-
508  poly[r] = tmp;
-
509  }
-
510  }
-
511 }
-
512 
-
513 static void mul_coefficients(uint16_t* poly, const uint16_t* factors)
-
514 {
-
515  unsigned int i;
-
516 
-
517  for(i = 0; i < PARAM_N; i++)
-
518  poly[i] = montgomery_reduce((poly[i] * (uint32_t)table_read(factors,i)));
-
519 }
-
520 
-
521 /* GS_bo_to_no; omegas need to be in Montgomery domain */
-
522 static void ntt(uint16_t * a, const uint16_t* omega)
-
523 {
-
524  int i, start, j, jTwiddle, distance;
-
525  uint16_t temp, W;
-
526 
-
527 
-
528  for(i=0;i<10;i+=2)
-
529  {
-
530  // Even level
-
531  distance = (1<<i);
-
532  for(start = 0; start < distance;start++)
-
533  {
-
534  jTwiddle = 0;
-
535  for(j=start;j<PARAM_N-1;j+=2*distance)
-
536  {
-
537  W = table_read(omega,jTwiddle++);
-
538  temp = a[j];
-
539  a[j] = (temp + a[j + distance]); // Omit reduction (be lazy)
-
540  a[j + distance] = montgomery_reduce((W * ((uint32_t)temp + 3*PARAM_Q - a[j + distance])));
-
541  }
-
542  }
-
543 
-
544  // Odd level
-
545  distance <<= 1;
-
546  for(start = 0; start < distance;start++)
-
547  {
-
548  jTwiddle = 0;
-
549  for(j=start;j<PARAM_N-1;j+=2*distance)
-
550  {
-
551  W = table_read(omega,jTwiddle++);
-
552  temp = a[j];
-
553  a[j] = barrett_reduce((temp + a[j + distance]));
-
554  a[j + distance] = montgomery_reduce((W * ((uint32_t)temp + 3*PARAM_Q - a[j + distance])));
-
555  }
-
556  }
-
557  }
-
558 }
-
559 
-
560 static int32_t abs(int32_t v)
-
561 {
-
562  int32_t mask = v >> 31;
-
563  return (v ^ mask) - mask;
-
564 }
-
565 
-
566 static int32_t f(int32_t *v0, int32_t *v1, uint32_t x)
-
567 {
-
568  int32_t xit, t, r, b;
-
569 
-
570  // Next 6 lines compute t = x/PARAM_Q;
-
571  b = x*2730;
-
572  t = b >> 25;
-
573  b = x - t*12289;
-
574  b = 12288 - b;
-
575  b >>= 31;
-
576  t -= b;
-
577 
-
578  r = t & 1;
-
579  xit = (t>>1);
-
580  *v0 = xit+r; // v0 = round(x/(2*PARAM_Q))
-
581 
-
582  t -= 1;
-
583  r = t & 1;
-
584  *v1 = (t>>1)+r;
-
585 
-
586  return abs(x-((*v0)*2*PARAM_Q));
-
587 }
+
42 #elif defined(__AVR__)
+
43 #include <avr/pgmspace.h>
+
44 #define table_read(name, index) (pgm_read_word(&((name)[(index)])))
+
45 #else
+
46 #define PROGMEM
+
47 #define table_read(name, index) ((name)[(index)])
+
48 #endif
+
49 
+
161 typedef struct
+
162 {
+
163  uint32_t input[16];
+
164  uint32_t output[16];
+
165 
+
166 } NewHopeChaChaState;
+
167 
+
168 // The following is public domain code from the reference C version of
+
169 // New Hope at https://cryptojedi.org/crypto/#newhope. This part of
+
170 // the Arduino port remains public domain. Original authors:
+
171 // Erdem Alkim, Léo Ducas, Thomas Pöppelmann, Peter Schwabe
+
172 
+
173 #define PARAM_N 1024
+
174 #define PARAM_K 16
+
175 #define PARAM_Q ((int32_t)12289)
+
176 #define POLY_BYTES 1792
+
177 #define NEWHOPE_SEEDBYTES 32
+
178 #define NEWHOPE_RECBYTES 256
+
179 
+
180 static uint16_t const omegas_montgomery[PARAM_N/2] PROGMEM = {
+
181  4075,6974,7373,7965,3262,5079,522,2169,6364,1018,1041,8775,2344,
+
182  11011,5574,1973,4536,1050,6844,3860,3818,6118,2683,1190,4789,7822,
+
183  7540,6752,5456,4449,3789,12142,11973,382,3988,468,6843,5339,6196,
+
184  3710,11316,1254,5435,10930,3998,10256,10367,3879,11889,1728,6137,
+
185  4948,5862,6136,3643,6874,8724,654,10302,1702,7083,6760,56,3199,9987,
+
186  605,11785,8076,5594,9260,6403,4782,6212,4624,9026,8689,4080,11868,
+
187  6221,3602,975,8077,8851,9445,5681,3477,1105,142,241,12231,1003,
+
188  3532,5009,1956,6008,11404,7377,2049,10968,12097,7591,5057,3445,
+
189  4780,2920,7048,3127,8120,11279,6821,11502,8807,12138,2127,2839,
+
190  3957,431,1579,6383,9784,5874,677,3336,6234,2766,1323,9115,12237,
+
191  2031,6956,6413,2281,3969,3991,12133,9522,4737,10996,4774,5429,11871,
+
192  3772,453,5908,2882,1805,2051,1954,11713,3963,2447,6142,8174,3030,
+
193  1843,2361,12071,2908,3529,3434,3202,7796,2057,5369,11939,1512,6906,
+
194  10474,11026,49,10806,5915,1489,9789,5942,10706,10431,7535,426,8974,
+
195  3757,10314,9364,347,5868,9551,9634,6554,10596,9280,11566,174,2948,
+
196  2503,6507,10723,11606,2459,64,3656,8455,5257,5919,7856,1747,9166,
+
197  5486,9235,6065,835,3570,4240,11580,4046,10970,9139,1058,8210,11848,
+
198  922,7967,1958,10211,1112,3728,4049,11130,5990,1404,325,948,11143,
+
199  6190,295,11637,5766,8212,8273,2919,8527,6119,6992,8333,1360,2555,
+
200  6167,1200,7105,7991,3329,9597,12121,5106,5961,10695,10327,3051,9923,
+
201  4896,9326,81,3091,1000,7969,4611,726,1853,12149,4255,11112,2768,
+
202  10654,1062,2294,3553,4805,2747,4846,8577,9154,1170,2319,790,11334,
+
203  9275,9088,1326,5086,9094,6429,11077,10643,3504,3542,8668,9744,1479,
+
204  1,8246,7143,11567,10984,4134,5736,4978,10938,5777,8961,4591,5728,
+
205  6461,5023,9650,7468,949,9664,2975,11726,2744,9283,10092,5067,12171,
+
206  2476,3748,11336,6522,827,9452,5374,12159,7935,3296,3949,9893,4452,
+
207  10908,2525,3584,8112,8011,10616,4989,6958,11809,9447,12280,1022,
+
208  11950,9821,11745,5791,5092,2089,9005,2881,3289,2013,9048,729,7901,
+
209  1260,5755,4632,11955,2426,10593,1428,4890,5911,3932,9558,8830,3637,
+
210  5542,145,5179,8595,3707,10530,355,3382,4231,9741,1207,9041,7012,1168,
+
211  10146,11224,4645,11885,10911,10377,435,7952,4096,493,9908,6845,6039,
+
212  2422,2187,9723,8643,9852,9302,6022,7278,1002,4284,5088,1607,7313,
+
213  875,8509,9430,1045,2481,5012,7428,354,6591,9377,11847,2401,1067,
+
214  7188,11516,390,8511,8456,7270,545,8585,9611,12047,1537,4143,4714,
+
215  4885,1017,5084,1632,3066,27,1440,8526,9273,12046,11618,9289,3400,
+
216  9890,3136,7098,8758,11813,7384,3985,11869,6730,10745,10111,2249,
+
217  4048,2884,11136,2126,1630,9103,5407,2686,9042,2969,8311,9424,
+
218  9919,8779,5332,10626,1777,4654,10863,7351,3636,9585,5291,8374,
+
219  2166,4919,12176,9140,12129,7852,12286,4895,10805,2780,5195,2305,
+
220  7247,9644,4053,10600,3364,3271,4057,4414,9442,7917,2174
+
221 };
+
222 
+
223 static uint16_t const omegas_inv_montgomery[PARAM_N/2] PROGMEM = {
+
224  4075,5315,4324,4916,10120,11767,7210,9027,10316,6715,1278,9945,
+
225  3514,11248,11271,5925,147,8500,7840,6833,5537,4749,4467,7500,11099,
+
226  9606,6171,8471,8429,5445,11239,7753,9090,12233,5529,5206,10587,
+
227  1987,11635,3565,5415,8646,6153,6427,7341,6152,10561,400,8410,1922,
+
228  2033,8291,1359,6854,11035,973,8579,6093,6950,5446,11821,8301,11907,
+
229  316,52,3174,10966,9523,6055,8953,11612,6415,2505,5906,10710,11858,
+
230  8332,9450,10162,151,3482,787,5468,1010,4169,9162,5241,9369,7509,
+
231  8844,7232,4698,192,1321,10240,4912,885,6281,10333,7280,8757,11286,
+
232  58,12048,12147,11184,8812,6608,2844,3438,4212,11314,8687,6068,421,
+
233  8209,3600,3263,7665,6077,7507,5886,3029,6695,4213,504,11684,2302,
+
234  1962,1594,6328,7183,168,2692,8960,4298,5184,11089,6122,9734,10929,
+
235  3956,5297,6170,3762,9370,4016,4077,6523,652,11994,6099,1146,11341,
+
236  11964,10885,6299,1159,8240,8561,11177,2078,10331,4322,11367,441,
+
237  4079,11231,3150,1319,8243,709,8049,8719,11454,6224,3054,6803,3123,
+
238  10542,4433,6370,7032,3834,8633,12225,9830,683,1566,5782,9786,9341,
+
239  12115,723,3009,1693,5735,2655,2738,6421,11942,2925,1975,8532,3315,
+
240  11863,4754,1858,1583,6347,2500,10800,6374,1483,12240,1263,1815,
+
241  5383,10777,350,6920,10232,4493,9087,8855,8760,9381,218,9928,10446,
+
242  9259,4115,6147,9842,8326,576,10335,10238,10484,9407,6381,11836,8517,
+
243  418,6860,7515,1293,7552,2767,156,8298,8320,10008,5876,5333,10258,
+
244  10115,4372,2847,7875,8232,9018,8925,1689,8236,2645,5042,9984,7094,
+
245  9509,1484,7394,3,4437,160,3149,113,7370,10123,3915,6998,2704,8653,
+
246  4938,1426,7635,10512,1663,6957,3510,2370,2865,3978,9320,3247,9603,
+
247  6882,3186,10659,10163,1153,9405,8241,10040,2178,1544,5559,420,8304,
+
248  4905,476,3531,5191,9153,2399,8889,3000,671,243,3016,3763,10849,12262,
+
249  9223,10657,7205,11272,7404,7575,8146,10752,242,2678,3704,11744,
+
250  5019,3833,3778,11899,773,5101,11222,9888,442,2912,5698,11935,4861,
+
251  7277,9808,11244,2859,3780,11414,4976,10682,7201,8005,11287,5011,
+
252  6267,2987,2437,3646,2566,10102,9867,6250,5444,2381,11796,8193,4337,
+
253  11854,1912,1378,404,7644,1065,2143,11121,5277,3248,11082,2548,8058,
+
254  8907,11934,1759,8582,3694,7110,12144,6747,8652,3459,2731,8357,6378,
+
255  7399,10861,1696,9863,334,7657,6534,11029,4388,11560,3241,10276,9000,
+
256  9408,3284,10200,7197,6498,544,2468,339,11267,9,2842,480,5331,7300,
+
257  1673,4278,4177,8705,9764,1381,7837,2396,8340,8993,4354,130,6915,
+
258  2837,11462,5767,953,8541,9813,118,7222,2197,3006,9545,563,9314,
+
259  2625,11340,4821,2639,7266,5828,6561,7698,3328,6512,1351,7311,6553,
+
260  8155,1305,722,5146,4043,12288,10810,2545,3621,8747,8785,1646,1212,
+
261  5860,3195,7203,10963,3201,3014,955,11499,9970,11119,3135,3712,7443,
+
262  9542,7484,8736,9995,11227,1635,9521,1177,8034,140,10436,11563,7678,
+
263  4320,11289,9198,12208,2963,7393,2366,9238
+
264 };
+
265 
+
266 static uint16_t const psis_bitrev_montgomery[PARAM_N] PROGMEM = {
+
267  4075,6974,7373,7965,3262,5079,522,2169,6364,1018,1041,8775,2344,
+
268  11011,5574,1973,4536,1050,6844,3860,3818,6118,2683,1190,4789,7822,
+
269  7540,6752,5456,4449,3789,12142,11973,382,3988,468,6843,5339,6196,3710,
+
270  11316,1254,5435,10930,3998,10256,10367,3879,11889,1728,6137,4948,
+
271  5862,6136,3643,6874,8724,654,10302,1702,7083,6760,56,3199,9987,605,
+
272  11785,8076,5594,9260,6403,4782,6212,4624,9026,8689,4080,11868,6221,
+
273  3602,975,8077,8851,9445,5681,3477,1105,142,241,12231,1003,3532,5009,
+
274  1956,6008,11404,7377,2049,10968,12097,7591,5057,3445,4780,2920,
+
275  7048,3127,8120,11279,6821,11502,8807,12138,2127,2839,3957,431,1579,
+
276  6383,9784,5874,677,3336,6234,2766,1323,9115,12237,2031,6956,6413,
+
277  2281,3969,3991,12133,9522,4737,10996,4774,5429,11871,3772,453,
+
278  5908,2882,1805,2051,1954,11713,3963,2447,6142,8174,3030,1843,2361,
+
279  12071,2908,3529,3434,3202,7796,2057,5369,11939,1512,6906,10474,
+
280  11026,49,10806,5915,1489,9789,5942,10706,10431,7535,426,8974,3757,
+
281  10314,9364,347,5868,9551,9634,6554,10596,9280,11566,174,2948,2503,
+
282  6507,10723,11606,2459,64,3656,8455,5257,5919,7856,1747,9166,5486,
+
283  9235,6065,835,3570,4240,11580,4046,10970,9139,1058,8210,11848,922,
+
284  7967,1958,10211,1112,3728,4049,11130,5990,1404,325,948,11143,6190,
+
285  295,11637,5766,8212,8273,2919,8527,6119,6992,8333,1360,2555,6167,
+
286  1200,7105,7991,3329,9597,12121,5106,5961,10695,10327,3051,9923,
+
287  4896,9326,81,3091,1000,7969,4611,726,1853,12149,4255,11112,2768,
+
288  10654,1062,2294,3553,4805,2747,4846,8577,9154,1170,2319,790,11334,
+
289  9275,9088,1326,5086,9094,6429,11077,10643,3504,3542,8668,9744,1479,
+
290  1,8246,7143,11567,10984,4134,5736,4978,10938,5777,8961,4591,5728,
+
291  6461,5023,9650,7468,949,9664,2975,11726,2744,9283,10092,5067,12171,
+
292  2476,3748,11336,6522,827,9452,5374,12159,7935,3296,3949,9893,4452,
+
293  10908,2525,3584,8112,8011,10616,4989,6958,11809,9447,12280,1022,
+
294  11950,9821,11745,5791,5092,2089,9005,2881,3289,2013,9048,729,7901,
+
295  1260,5755,4632,11955,2426,10593,1428,4890,5911,3932,9558,8830,3637,
+
296  5542,145,5179,8595,3707,10530,355,3382,4231,9741,1207,9041,7012,
+
297  1168,10146,11224,4645,11885,10911,10377,435,7952,4096,493,9908,6845,
+
298  6039,2422,2187,9723,8643,9852,9302,6022,7278,1002,4284,5088,1607,
+
299  7313,875,8509,9430,1045,2481,5012,7428,354,6591,9377,11847,2401,
+
300  1067,7188,11516,390,8511,8456,7270,545,8585,9611,12047,1537,4143,
+
301  4714,4885,1017,5084,1632,3066,27,1440,8526,9273,12046,11618,9289,
+
302  3400,9890,3136,7098,8758,11813,7384,3985,11869,6730,10745,10111,
+
303  2249,4048,2884,11136,2126,1630,9103,5407,2686,9042,2969,8311,9424,
+
304  9919,8779,5332,10626,1777,4654,10863,7351,3636,9585,5291,8374,
+
305  2166,4919,12176,9140,12129,7852,12286,4895,10805,2780,5195,2305,
+
306  7247,9644,4053,10600,3364,3271,4057,4414,9442,7917,2174,3947,
+
307  11951,2455,6599,10545,10975,3654,2894,7681,7126,7287,12269,4119,
+
308  3343,2151,1522,7174,7350,11041,2442,2148,5959,6492,8330,8945,5598,
+
309  3624,10397,1325,6565,1945,11260,10077,2674,3338,3276,11034,506,
+
310  6505,1392,5478,8778,1178,2776,3408,10347,11124,2575,9489,12096,
+
311  6092,10058,4167,6085,923,11251,11912,4578,10669,11914,425,10453,
+
312  392,10104,8464,4235,8761,7376,2291,3375,7954,8896,6617,7790,1737,
+
313  11667,3982,9342,6680,636,6825,7383,512,4670,2900,12050,7735,994,
+
314  1687,11883,7021,146,10485,1403,5189,6094,2483,2054,3042,10945,
+
315  3981,10821,11826,8882,8151,180,9600,7684,5219,10880,6780,204,
+
316  11232,2600,7584,3121,3017,11053,7814,7043,4251,4739,11063,6771,
+
317  7073,9261,2360,11925,1928,11825,8024,3678,3205,3359,11197,5209,
+
318  8581,3238,8840,1136,9363,1826,3171,4489,7885,346,2068,1389,8257,
+
319  3163,4840,6127,8062,8921,612,4238,10763,8067,125,11749,10125,5416,
+
320  2110,716,9839,10584,11475,11873,3448,343,1908,4538,10423,7078,
+
321  4727,1208,11572,3589,2982,1373,1721,10753,4103,2429,4209,5412,
+
322  5993,9011,438,3515,7228,1218,8347,5232,8682,1327,7508,4924,448,
+
323  1014,10029,12221,4566,5836,12229,2717,1535,3200,5588,5845,412,
+
324  5102,7326,3744,3056,2528,7406,8314,9202,6454,6613,1417,10032,7784,
+
325  1518,3765,4176,5063,9828,2275,6636,4267,6463,2065,7725,3495,8328,
+
326  8755,8144,10533,5966,12077,9175,9520,5596,6302,8400,579,6781,11014,
+
327  5734,11113,11164,4860,1131,10844,9068,8016,9694,3837,567,9348,7000,
+
328  6627,7699,5082,682,11309,5207,4050,7087,844,7434,3769,293,9057,
+
329  6940,9344,10883,2633,8190,3944,5530,5604,3480,2171,9282,11024,2213,
+
330  8136,3805,767,12239,216,11520,6763,10353,7,8566,845,7235,3154,4360,
+
331  3285,10268,2832,3572,1282,7559,3229,8360,10583,6105,3120,6643,6203,
+
332  8536,8348,6919,3536,9199,10891,11463,5043,1658,5618,8787,5789,4719,
+
333  751,11379,6389,10783,3065,7806,6586,2622,5386,510,7628,6921,578,
+
334  10345,11839,8929,4684,12226,7154,9916,7302,8481,3670,11066,2334,
+
335  1590,7878,10734,1802,1891,5103,6151,8820,3418,7846,9951,4693,417,
+
336  9996,9652,4510,2946,5461,365,881,1927,1015,11675,11009,1371,12265,
+
337  2485,11385,5039,6742,8449,1842,12217,8176,9577,4834,7937,9461,2643,
+
338  11194,3045,6508,4094,3451,7911,11048,5406,4665,3020,6616,11345,
+
339  7519,3669,5287,1790,7014,5410,11038,11249,2035,6125,10407,4565,
+
340  7315,5078,10506,2840,2478,9270,4194,9195,4518,7469,1160,6878,2730,
+
341  10421,10036,1734,3815,10939,5832,10595,10759,4423,8420,9617,7119,
+
342  11010,11424,9173,189,10080,10526,3466,10588,7592,3578,11511,7785,
+
343  9663,530,12150,8957,2532,3317,9349,10243,1481,9332,3454,3758,7899,
+
344  4218,2593,11410,2276,982,6513,1849,8494,9021,4523,7988,8,457,648,
+
345  150,8000,2307,2301,874,5650,170,9462,2873,9855,11498,2535,11169,
+
346  5808,12268,9687,1901,7171,11787,3846,1573,6063,3793,466,11259,
+
347  10608,3821,6320,4649,6263,2929
+
348 };
+
349 
+
350 static uint16_t const psis_inv_montgomery[PARAM_N] PROGMEM = {
+
351  256,10570,1510,7238,1034,7170,6291,7921,11665,3422,4000,2327,
+
352  2088,5565,795,10647,1521,5484,2539,7385,1055,7173,8047,11683,
+
353  1669,1994,3796,5809,4341,9398,11876,12230,10525,12037,12253,
+
354  3506,4012,9351,4847,2448,7372,9831,3160,2207,5582,2553,7387,6322,
+
355  9681,1383,10731,1533,219,5298,4268,7632,6357,9686,8406,4712,9451,
+
356  10128,4958,5975,11387,8649,11769,6948,11526,12180,1740,10782,
+
357  6807,2728,7412,4570,4164,4106,11120,12122,8754,11784,3439,5758,
+
358  11356,6889,9762,11928,1704,1999,10819,12079,12259,7018,11536,
+
359  1648,1991,2040,2047,2048,10826,12080,8748,8272,8204,1172,1923,
+
360  7297,2798,7422,6327,4415,7653,6360,11442,12168,7005,8023,9924,
+
361  8440,8228,2931,7441,1063,3663,5790,9605,10150,1450,8985,11817,
+
362  10466,10273,12001,3470,7518,1074,1909,7295,9820,4914,702,5367,
+
363  7789,8135,9940,1420,3714,11064,12114,12264,1752,5517,9566,11900,
+
364  1700,3754,5803,829,1874,7290,2797,10933,5073,7747,8129,6428,
+
365  6185,11417,1631,233,5300,9535,10140,11982,8734,8270,2937,10953,
+
366  8587,8249,2934,9197,4825,5956,4362,9401,1343,3703,529,10609,
+
367  12049,6988,6265,895,3639,4031,4087,4095,585,10617,8539,4731,
+
368  4187,9376,3095,9220,10095,10220,1460,10742,12068,1724,5513,
+
369  11321,6884,2739,5658,6075,4379,11159,10372,8504,4726,9453,3106,
+
370  7466,11600,10435,8513,9994,8450,9985,3182,10988,8592,2983,9204,
+
371  4826,2445,5616,6069,867,3635,5786,11360,5134,2489,10889,12089,
+
372  1727,7269,2794,9177,1311,5454,9557,6632,2703,9164,10087,1441,
+
373  3717,531,3587,2268,324,5313,759,1864,5533,2546,7386,9833,8427,
+
374  4715,11207,1601,7251,4547,11183,12131,1733,10781,10318,1474,
+
375  10744,5046,4232,11138,10369,6748,964,7160,4534,7670,8118,8182,
+
376  4680,11202,6867,981,8918,1274,182,26,7026,8026,11680,12202,
+
377  10521,1503,7237,4545,5916,9623,8397,11733,10454,3249,9242,6587,
+
378  941,1890,270,10572,6777,9746,6659,6218,6155,6146,878,1881,7291,
+
379  11575,12187,1741,7271,8061,11685,6936,4502,9421,4857,4205,7623,
+
380  1089,10689,1527,8996,10063,11971,10488,6765,2722,3900,9335,11867,
+
381  6962,11528,5158,4248,4118,5855,2592,5637,6072,2623,7397,8079,
+
382  9932,4930,5971,853,3633,519,8852,11798,3441,11025,1575,225,8810,
+
383  11792,12218,3501,9278,3081,9218,4828,7712,8124,11694,12204,3499,
+
384  4011,573,3593,5780,7848,9899,10192,1456,208,7052,2763,7417,11593,
+
385  10434,12024,8740,11782,10461,3250,5731,7841,9898,1414,202,3540,
+
386  7528,2831,2160,10842,5060,4234,4116,588,84,12,7024,2759,9172,6577,
+
387  11473,1639,9012,3043,7457,6332,11438,1634,1989,9062,11828,8712,
+
388  11778,12216,10523,6770,9745,10170,4964,9487,6622,946,8913,6540,
+
389  6201,4397,9406,8366,9973,8447,8229,11709,8695,10020,3187,5722,
+
390  2573,10901,6824,4486,4152,9371,8361,2950,2177,311,1800,9035,
+
391  8313,11721,3430,490,70,10,1757,251,3547,7529,11609,3414,7510,
+
392  4584,4166,9373,1339,5458,7802,11648,1664,7260,9815,10180,6721,
+
393  9738,10169,8475,8233,9954,1422,8981,1283,5450,11312,1616,3742,
+
394  11068,10359,4991,713,3613,9294,8350,4704,672,96,7036,9783,11931,
+
395  3460,5761,823,10651,12055,10500,1500,5481,783,3623,11051,8601,
+
396  8251,8201,11705,10450,5004,4226,7626,2845,2162,3820,7568,9859,
+
397  3164,452,10598,1514,5483,6050,6131,4387,7649,8115,6426,918,8909,
+
398  8295,1185,5436,11310,8638,1234,5443,11311,5127,2488,2111,10835,
+
399  5059,7745,2862,3920,560,80,1767,2008,3798,11076,6849,2734,10924,
+
400  12094,8750,1250,10712,6797,971,7161,1023,8924,4786,7706,4612,4170,
+
401  7618,6355,4419,5898,11376,10403,10264,6733,4473,639,5358,2521,
+
402  9138,3061,5704,4326,618,5355,765,5376,768,7132,4530,9425,3102,
+
403  9221,6584,11474,10417,10266,12000,6981,6264,4406,2385,7363,4563,
+
404  4163,7617,9866,3165,9230,11852,10471,5007,5982,11388,5138,734,
+
405  3616,11050,12112,6997,11533,12181,10518,12036,3475,2252,7344,
+
406  9827,4915,9480,6621,4457,7659,9872,6677,4465,4149,7615,4599,657,
+
407  3605,515,10607,6782,4480,640,1847,3775,5806,2585,5636,9583,1369,
+
408  10729,8555,10000,11962,5220,7768,8132,8184,9947,1421,203,29,8782,
+
409  11788,1684,10774,10317,4985,9490,8378,4708,11206,5112,5997,7879,
+
410  11659,12199,8765,10030,4944,5973,6120,6141,6144,7900,11662,1666,
+
411  238,34,3516,5769,9602,8394,9977,6692,956,10670,6791,9748,11926,
+
412  8726,11780,5194,742,106,8793,10034,3189,10989,5081,4237,5872,4350,
+
413  2377,10873,6820,6241,11425,10410,10265,3222,5727,9596,4882,2453,
+
414  2106,3812,11078,12116,5242,4260,11142,8614,11764,12214,5256,4262,
+
415  4120,11122,5100,11262,5120,2487,5622,9581,8391,8221,2930,10952,
+
416  12098,6995,6266,9673,4893,699,3611,4027,5842,11368,1624,232,8811,
+
417  8281,1183,169,8802,3013,2186,5579,797,3625,4029,11109,1587,7249,
+
418  11569,8675,6506,2685,10917,12093,12261,12285,1755,7273,1039,1904,
+
419  272,3550,9285,3082,5707,6082,4380,7648,11626,5172,4250,9385,8363,
+
420  8217,4685,5936,848,8899,6538,934,1889,3781,9318,10109,10222,6727,
+
421  961,5404,772,5377,9546,8386,1198,8949,3034,2189,7335,4559,5918,2601,
+
422  10905,5069,9502,3113,7467,8089,11689,5181,9518,8382,2953,3933,4073,
+
423  4093,7607,8109,2914,5683,4323,11151,1593,10761,6804,972,3650,2277,
+
424  5592,4310,7638,9869,4921,703,1856,9043,4803,9464,1352,8971,11815,
+
425  5199,7765,6376,4422,7654,2849,407,8836,6529,7955,2892,9191,1313,
+
426  10721,12065,12257,1751,9028,8312,2943,2176,3822,546,78,8789,11789,
+
427  10462,12028,6985,4509,9422,1346,5459,4291,613,10621,6784,9747,3148,
+
428  7472,2823,5670,810,7138,8042,4660,7688,6365,6176,6149,2634,5643,
+
429  9584,10147,11983,5223,9524,11894,10477,8519,1217,3685,2282,326,
+
430  10580,3267,7489,4581,2410,5611,11335,6886,8006,8166,11700,3427,
+
431  11023,8597,10006,3185,455,65,5276,7776,4622,5927,7869,9902,11948,
+
432  5218,2501,5624,2559,10899,1557,1978,10816,10323,8497,4725,675,1852,
+
433  10798,12076,10503,3256,9243,3076,2195,10847,12083,10504,12034,10497
+
434 };
+
435 
+
436 static uint16_t const bitrev_table[PARAM_N] PROGMEM = {
+
437  0,512,256,768,128,640,384,896,64,576,320,832,192,704,448,960,32,544,288,800,160,672,416,928,96,608,352,864,224,736,480,992,
+
438  16,528,272,784,144,656,400,912,80,592,336,848,208,720,464,976,48,560,304,816,176,688,432,944,112,624,368,880,240,752,496,1008,
+
439  8,520,264,776,136,648,392,904,72,584,328,840,200,712,456,968,40,552,296,808,168,680,424,936,104,616,360,872,232,744,488,1000,
+
440  24,536,280,792,152,664,408,920,88,600,344,856,216,728,472,984,56,568,312,824,184,696,440,952,120,632,376,888,248,760,504,1016,
+
441  4,516,260,772,132,644,388,900,68,580,324,836,196,708,452,964,36,548,292,804,164,676,420,932,100,612,356,868,228,740,484,996,
+
442  20,532,276,788,148,660,404,916,84,596,340,852,212,724,468,980,52,564,308,820,180,692,436,948,116,628,372,884,244,756,500,1012,
+
443  12,524,268,780,140,652,396,908,76,588,332,844,204,716,460,972,44,556,300,812,172,684,428,940,108,620,364,876,236,748,492,1004,
+
444  28,540,284,796,156,668,412,924,92,604,348,860,220,732,476,988,60,572,316,828,188,700,444,956,124,636,380,892,252,764,508,1020,
+
445  2,514,258,770,130,642,386,898,66,578,322,834,194,706,450,962,34,546,290,802,162,674,418,930,98,610,354,866,226,738,482,994,
+
446  18,530,274,786,146,658,402,914,82,594,338,850,210,722,466,978,50,562,306,818,178,690,434,946,114,626,370,882,242,754,498,1010,
+
447  10,522,266,778,138,650,394,906,74,586,330,842,202,714,458,970,42,554,298,810,170,682,426,938,106,618,362,874,234,746,490,1002,
+
448  26,538,282,794,154,666,410,922,90,602,346,858,218,730,474,986,58,570,314,826,186,698,442,954,122,634,378,890,250,762,506,1018,
+
449  6,518,262,774,134,646,390,902,70,582,326,838,198,710,454,966,38,550,294,806,166,678,422,934,102,614,358,870,230,742,486,998,
+
450  22,534,278,790,150,662,406,918,86,598,342,854,214,726,470,982,54,566,310,822,182,694,438,950,118,630,374,886,246,758,502,1014,
+
451  14,526,270,782,142,654,398,910,78,590,334,846,206,718,462,974,46,558,302,814,174,686,430,942,110,622,366,878,238,750,494,1006,
+
452  30,542,286,798,158,670,414,926,94,606,350,862,222,734,478,990,62,574,318,830,190,702,446,958,126,638,382,894,254,766,510,1022,
+
453  1,513,257,769,129,641,385,897,65,577,321,833,193,705,449,961,33,545,289,801,161,673,417,929,97,609,353,865,225,737,481,993,
+
454  17,529,273,785,145,657,401,913,81,593,337,849,209,721,465,977,49,561,305,817,177,689,433,945,113,625,369,881,241,753,497,1009,
+
455  9,521,265,777,137,649,393,905,73,585,329,841,201,713,457,969,41,553,297,809,169,681,425,937,105,617,361,873,233,745,489,1001,
+
456  25,537,281,793,153,665,409,921,89,601,345,857,217,729,473,985,57,569,313,825,185,697,441,953,121,633,377,889,249,761,505,1017,
+
457  5,517,261,773,133,645,389,901,69,581,325,837,197,709,453,965,37,549,293,805,165,677,421,933,101,613,357,869,229,741,485,997,
+
458  21,533,277,789,149,661,405,917,85,597,341,853,213,725,469,981,53,565,309,821,181,693,437,949,117,629,373,885,245,757,501,1013,
+
459  13,525,269,781,141,653,397,909,77,589,333,845,205,717,461,973,45,557,301,813,173,685,429,941,109,621,365,877,237,749,493,1005,
+
460  29,541,285,797,157,669,413,925,93,605,349,861,221,733,477,989,61,573,317,829,189,701,445,957,125,637,381,893,253,765,509,1021,
+
461  3,515,259,771,131,643,387,899,67,579,323,835,195,707,451,963,35,547,291,803,163,675,419,931,99,611,355,867,227,739,483,995,
+
462  19,531,275,787,147,659,403,915,83,595,339,851,211,723,467,979,51,563,307,819,179,691,435,947,115,627,371,883,243,755,499,1011,
+
463  11,523,267,779,139,651,395,907,75,587,331,843,203,715,459,971,43,555,299,811,171,683,427,939,107,619,363,875,235,747,491,1003,
+
464  27,539,283,795,155,667,411,923,91,603,347,859,219,731,475,987,59,571,315,827,187,699,443,955,123,635,379,891,251,763,507,1019,
+
465  7,519,263,775,135,647,391,903,71,583,327,839,199,711,455,967,39,551,295,807,167,679,423,935,103,615,359,871,231,743,487,999,
+
466  23,535,279,791,151,663,407,919,87,599,343,855,215,727,471,983,55,567,311,823,183,695,439,951,119,631,375,887,247,759,503,1015,
+
467  15,527,271,783,143,655,399,911,79,591,335,847,207,719,463,975,47,559,303,815,175,687,431,943,111,623,367,879,239,751,495,1007,
+
468  31,543,287,799,159,671,415,927,95,607,351,863,223,735,479,991,63,575,319,831,191,703,447,959,127,639,383,895,255,767,511,1023
+
469 };
+
470 
+
471 /* Incomplete-reduction routines; for details on allowed input ranges
+
472  * and produced output ranges, see the description in the paper:
+
473  * https://cryptojedi.org/papers/#newhope */
+
474 
+
475 #define qinv 12287 // -inverse_mod(p,2^18)
+
476 #define rlog 18
+
477 
+
478 inline uint16_t montgomery_reduce(uint32_t a)
+
479 {
+
480  uint32_t u;
+
481 
+
482  u = (a * qinv);
+
483  u &= ((((uint32_t)1)<<rlog)-1);
+
484  u *= PARAM_Q;
+
485  a = a + u;
+
486  return a >> 18;
+
487 }
+
488 
+
489 inline uint16_t barrett_reduce(uint16_t a)
+
490 {
+
491  uint32_t u;
+
492 
+
493  u = ((uint32_t) a * 5) >> 16;
+
494  u *= PARAM_Q;
+
495  a -= u;
+
496  return a;
+
497 }
+
498 
+
499 static void bitrev_vector(uint16_t* poly)
+
500 {
+
501  unsigned int i,r;
+
502  uint16_t tmp;
+
503 
+
504  for(i = 0; i < PARAM_N; i++)
+
505  {
+
506  r = table_read(bitrev_table,i);
+
507  if (i < r)
+
508  {
+
509  tmp = poly[i];
+
510  poly[i] = poly[r];
+
511  poly[r] = tmp;
+
512  }
+
513  }
+
514 }
+
515 
+
516 static void mul_coefficients(uint16_t* poly, const uint16_t* factors)
+
517 {
+
518  unsigned int i;
+
519 
+
520  for(i = 0; i < PARAM_N; i++)
+
521  poly[i] = montgomery_reduce((poly[i] * (uint32_t)table_read(factors,i)));
+
522 }
+
523 
+
524 /* GS_bo_to_no; omegas need to be in Montgomery domain */
+
525 static void ntt(uint16_t * a, const uint16_t* omega)
+
526 {
+
527  int i, start, j, jTwiddle, distance;
+
528  uint16_t temp, W;
+
529 
+
530 
+
531  for(i=0;i<10;i+=2)
+
532  {
+
533  // Even level
+
534  distance = (1<<i);
+
535  for(start = 0; start < distance;start++)
+
536  {
+
537  jTwiddle = 0;
+
538  for(j=start;j<PARAM_N-1;j+=2*distance)
+
539  {
+
540  W = table_read(omega,jTwiddle++);
+
541  temp = a[j];
+
542  a[j] = (temp + a[j + distance]); // Omit reduction (be lazy)
+
543  a[j + distance] = montgomery_reduce((W * ((uint32_t)temp + 3*PARAM_Q - a[j + distance])));
+
544  }
+
545  }
+
546 
+
547  // Odd level
+
548  distance <<= 1;
+
549  for(start = 0; start < distance;start++)
+
550  {
+
551  jTwiddle = 0;
+
552  for(j=start;j<PARAM_N-1;j+=2*distance)
+
553  {
+
554  W = table_read(omega,jTwiddle++);
+
555  temp = a[j];
+
556  a[j] = barrett_reduce((temp + a[j + distance]));
+
557  a[j + distance] = montgomery_reduce((W * ((uint32_t)temp + 3*PARAM_Q - a[j + distance])));
+
558  }
+
559  }
+
560  }
+
561 }
+
562 
+
563 static int32_t abs(int32_t v)
+
564 {
+
565  int32_t mask = v >> 31;
+
566  return (v ^ mask) - mask;
+
567 }
+
568 
+
569 static int32_t f(int32_t *v0, int32_t *v1, uint32_t x)
+
570 {
+
571  int32_t xit, t, r, b;
+
572 
+
573  // Next 6 lines compute t = x/PARAM_Q;
+
574  b = x*2730;
+
575  t = b >> 25;
+
576  b = x - t*12289;
+
577  b = 12288 - b;
+
578  b >>= 31;
+
579  t -= b;
+
580 
+
581  r = t & 1;
+
582  xit = (t>>1);
+
583  *v0 = xit+r; // v0 = round(x/(2*PARAM_Q))
+
584 
+
585  t -= 1;
+
586  r = t & 1;
+
587  *v1 = (t>>1)+r;
588 
-
589 static int32_t g(int32_t x)
-
590 {
-
591  int32_t t,c,b;
-
592 
-
593  // Next 6 lines compute t = x/(4*PARAM_Q);
-
594  b = x*2730;
-
595  t = b >> 27;
-
596  b = x - t*49156;
-
597  b = 49155 - b;
-
598  b >>= 31;
-
599  t -= b;
-
600 
-
601  c = t & 1;
-
602  t = (t >> 1) + c; // t = round(x/(8*PARAM_Q))
+
589  return abs(x-((*v0)*2*PARAM_Q));
+
590 }
+
591 
+
592 static int32_t g(int32_t x)
+
593 {
+
594  int32_t t,c,b;
+
595 
+
596  // Next 6 lines compute t = x/(4*PARAM_Q);
+
597  b = x*2730;
+
598  t = b >> 27;
+
599  b = x - t*49156;
+
600  b = 49155 - b;
+
601  b >>= 31;
+
602  t -= b;
603 
-
604  t *= 8*PARAM_Q;
-
605 
-
606  return abs(t - x);
-
607 }
+
604  c = t & 1;
+
605  t = (t >> 1) + c; // t = round(x/(8*PARAM_Q))
+
606 
+
607  t *= 8*PARAM_Q;
608 
-
609 static int16_t LDDecode(int32_t xi0, int32_t xi1, int32_t xi2, int32_t xi3)
-
610 {
-
611  int32_t t;
-
612 
-
613  t = g(xi0);
-
614  t += g(xi1);
-
615  t += g(xi2);
-
616  t += g(xi3);
-
617 
-
618  t -= 8*PARAM_Q;
-
619  t >>= 31;
-
620  return t&1;
-
621 }
-
622 
-
623 static void helprec(NewHopeChaChaState *chacha, uint16_t *c, const uint16_t *v, unsigned char nonce)
-
624 {
-
625  int32_t v0[4], v1[4], v_tmp[4], k;
-
626  unsigned char rbit;
-
627  unsigned char *rand;
-
628  int i;
-
629 
-
630  chacha->input[12] = 0;
-
631  chacha->input[13] = 0;
-
632  chacha->input[14] = 0;
-
633  chacha->input[15] = (((uint32_t)nonce) << 24); // Assumes little-endian.
-
634  ChaCha::hashCore(chacha->output, chacha->input, 20);
-
635  rand = (unsigned char *)chacha->output;
-
636 
-
637  for(i=0; i<256; i++)
-
638  {
-
639  rbit = (rand[i>>3] >> (i&7)) & 1;
-
640 
-
641  k = f(v0+0, v1+0, 8*(int32_t)v[ 0+i] + 4*rbit);
-
642  k += f(v0+1, v1+1, 8*(int32_t)v[256+i] + 4*rbit);
-
643  k += f(v0+2, v1+2, 8*(int32_t)v[512+i] + 4*rbit);
-
644  k += f(v0+3, v1+3, 8*(int32_t)v[768+i] + 4*rbit);
-
645 
-
646  k = (2*PARAM_Q-1-k) >> 31;
-
647 
-
648  v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
-
649  v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
-
650  v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
-
651  v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
-
652 
-
653  c[ 0+i] = (v_tmp[0] - v_tmp[3]) & 3;
-
654  c[256+i] = (v_tmp[1] - v_tmp[3]) & 3;
-
655  c[512+i] = (v_tmp[2] - v_tmp[3]) & 3;
-
656  c[768+i] = ( -k + 2*v_tmp[3]) & 3;
-
657  }
-
658 
-
659  clean(&chacha, sizeof(chacha));
-
660 }
+
609  return abs(t - x);
+
610 }
+
611 
+
612 static int16_t LDDecode(int32_t xi0, int32_t xi1, int32_t xi2, int32_t xi3)
+
613 {
+
614  int32_t t;
+
615 
+
616  t = g(xi0);
+
617  t += g(xi1);
+
618  t += g(xi2);
+
619  t += g(xi3);
+
620 
+
621  t -= 8*PARAM_Q;
+
622  t >>= 31;
+
623  return t&1;
+
624 }
+
625 
+
626 static void helprec(NewHopeChaChaState *chacha, uint16_t *c, const uint16_t *v, unsigned char nonce)
+
627 {
+
628  int32_t v0[4], v1[4], v_tmp[4], k;
+
629  unsigned char rbit;
+
630  unsigned char *rand;
+
631  int i;
+
632 
+
633  chacha->input[12] = 0;
+
634  chacha->input[13] = 0;
+
635  chacha->input[14] = 0;
+
636  chacha->input[15] = (((uint32_t)nonce) << 24); // Assumes little-endian.
+
637  ChaCha::hashCore(chacha->output, chacha->input, 20);
+
638  rand = (unsigned char *)chacha->output;
+
639 
+
640  for(i=0; i<256; i++)
+
641  {
+
642  rbit = (rand[i>>3] >> (i&7)) & 1;
+
643 
+
644  k = f(v0+0, v1+0, 8*(int32_t)v[ 0+i] + 4*rbit);
+
645  k += f(v0+1, v1+1, 8*(int32_t)v[256+i] + 4*rbit);
+
646  k += f(v0+2, v1+2, 8*(int32_t)v[512+i] + 4*rbit);
+
647  k += f(v0+3, v1+3, 8*(int32_t)v[768+i] + 4*rbit);
+
648 
+
649  k = (2*PARAM_Q-1-k) >> 31;
+
650 
+
651  v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
+
652  v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
+
653  v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
+
654  v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
+
655 
+
656  c[ 0+i] = (v_tmp[0] - v_tmp[3]) & 3;
+
657  c[256+i] = (v_tmp[1] - v_tmp[3]) & 3;
+
658  c[512+i] = (v_tmp[2] - v_tmp[3]) & 3;
+
659  c[768+i] = ( -k + 2*v_tmp[3]) & 3;
+
660  }
661 
-
662 static void rec(unsigned char *key, const uint16_t *v, const uint16_t *c)
-
663 {
-
664  int i;
-
665  int32_t tmp[4];
-
666 
-
667  for(i=0;i<32;i++)
-
668  key[i] = 0;
+
662  clean(&chacha, sizeof(chacha));
+
663 }
+
664 
+
665 static void rec(unsigned char *key, const uint16_t *v, const uint16_t *c)
+
666 {
+
667  int i;
+
668  int32_t tmp[4];
669 
-
670  for(i=0; i<256; i++)
-
671  {
-
672  tmp[0] = 16*PARAM_Q + 8*(int32_t)v[ 0+i] - PARAM_Q * (2*(int32_t)c[ 0+i]+c[768+i]);
-
673  tmp[1] = 16*PARAM_Q + 8*(int32_t)v[256+i] - PARAM_Q * (2*(int32_t)c[256+i]+c[768+i]);
-
674  tmp[2] = 16*PARAM_Q + 8*(int32_t)v[512+i] - PARAM_Q * (2*(int32_t)c[512+i]+c[768+i]);
-
675  tmp[3] = 16*PARAM_Q + 8*(int32_t)v[768+i] - PARAM_Q * ( c[768+i]);
-
676 
-
677  key[i>>3] |= LDDecode(tmp[0], tmp[1], tmp[2], tmp[3]) << (i & 7);
-
678  }
-
679 }
-
680 
-
681 static void poly_frombytes(uint16_t *r, const unsigned char *a)
-
682 {
-
683  int i;
-
684  for(i=0;i<PARAM_N/4;i++)
-
685  {
-
686  r[4*i+0] = a[7*i+0] | (((uint16_t)a[7*i+1] & 0x3f) << 8);
-
687  r[4*i+1] = (a[7*i+1] >> 6) | (((uint16_t)a[7*i+2]) << 2) | (((uint16_t)a[7*i+3] & 0x0f) << 10);
-
688  r[4*i+2] = (a[7*i+3] >> 4) | (((uint16_t)a[7*i+4]) << 4) | (((uint16_t)a[7*i+5] & 0x03) << 12);
-
689  r[4*i+3] = (a[7*i+5] >> 2) | (((uint16_t)a[7*i+6]) << 6);
-
690  }
-
691 }
-
692 
-
693 static void poly_tobytes(unsigned char *r, const uint16_t *p)
-
694 {
-
695  int i;
-
696  uint16_t t0,t1,t2,t3,m;
-
697  int16_t c;
-
698  for(i=0;i<PARAM_N/4;i++)
-
699  {
-
700  t0 = barrett_reduce(p[4*i+0]); //Make sure that coefficients have only 14 bits
-
701  t1 = barrett_reduce(p[4*i+1]);
-
702  t2 = barrett_reduce(p[4*i+2]);
-
703  t3 = barrett_reduce(p[4*i+3]);
-
704 
-
705  m = t0 - PARAM_Q;
-
706  c = m;
-
707  c >>= 15;
-
708  t0 = m ^ ((t0^m)&c); // <Make sure that coefficients are in [0,q]
-
709 
-
710  m = t1 - PARAM_Q;
-
711  c = m;
-
712  c >>= 15;
-
713  t1 = m ^ ((t1^m)&c); // <Make sure that coefficients are in [0,q]
-
714 
-
715  m = t2 - PARAM_Q;
-
716  c = m;
-
717  c >>= 15;
-
718  t2 = m ^ ((t2^m)&c); // <Make sure that coefficients are in [0,q]
-
719 
-
720  m = t3 - PARAM_Q;
-
721  c = m;
-
722  c >>= 15;
-
723  t3 = m ^ ((t3^m)&c); // <Make sure that coefficients are in [0,q]
-
724 
-
725  r[7*i+0] = t0 & 0xff;
-
726  r[7*i+1] = (t0 >> 8) | (t1 << 6);
-
727  r[7*i+2] = (t1 >> 2);
-
728  r[7*i+3] = (t1 >> 10) | (t2 << 4);
-
729  r[7*i+4] = (t2 >> 4);
-
730  r[7*i+5] = (t2 >> 12) | (t3 << 2);
-
731  r[7*i+6] = (t3 >> 6);
-
732  }
-
733 }
-
734 
-
735 static void poly_pointwise(uint16_t *r, const uint16_t *a, const uint16_t *b)
-
736 {
-
737  int i;
-
738  uint16_t t;
-
739  for(i=0;i<PARAM_N;i++)
-
740  {
-
741  t = montgomery_reduce(3186*(uint32_t)b[i]); /* t is now in Montgomery domain */
-
742  r[i] = montgomery_reduce(a[i] * (uint32_t)t); /* r->coeffs[i] is back in normal domain */
-
743  }
-
744 }
-
745 
-
746 static void poly_add(uint16_t *r, const uint16_t *a, const uint16_t *b)
-
747 {
-
748  int i;
-
749  for(i=0;i<PARAM_N;i++)
-
750  r[i] = barrett_reduce(a[i] + (uint32_t)b[i]);
-
751 }
-
752 
-
753 static void poly_ntt(uint16_t *r)
-
754 {
-
755  mul_coefficients(r, psis_bitrev_montgomery);
-
756  ntt(r, omegas_montgomery);
-
757 }
-
758 
-
759 static void poly_invntt(uint16_t *r)
-
760 {
-
761  bitrev_vector(r);
-
762  ntt(r, omegas_inv_montgomery);
-
763  mul_coefficients(r, psis_inv_montgomery);
-
764 }
-
765 
-
766 static void encode_b_2nd_half(unsigned char *r, const uint16_t *c)
-
767 {
-
768  int i;
-
769  for(i=0;i<PARAM_N/4;i++)
-
770  r[POLY_BYTES+i] = c[4*i] | (c[4*i+1] << 2) | (c[4*i+2] << 4) | (c[4*i+3] << 6);
-
771 }
-
772 
-
773 static void decode_b_2nd_half(uint16_t *c, const unsigned char *r)
-
774 {
-
775  int i;
-
776  for(i=0;i<PARAM_N/4;i++)
-
777  {
-
778  c[4*i+0] = r[POLY_BYTES+i] & 0x03;
-
779  c[4*i+1] = (r[POLY_BYTES+i] >> 2) & 0x03;
-
780  c[4*i+2] = (r[POLY_BYTES+i] >> 4) & 0x03;
-
781  c[4*i+3] = (r[POLY_BYTES+i] >> 6);
-
782  }
-
783 }
-
784 
-
785 #define _5q (5*PARAM_Q)
-
786 
-
787 #define compare_and_swap(x,i,j) \
-
788  c = _5q - 1 - x[16*(i)];\
-
789  c >>= 31;\
-
790  t = x[16*(i)] ^ x[16*(j)];\
-
791  t &= c;\
-
792  x[16*(i)] ^= t;\
-
793  x[16*(j)] ^= t;
-
794 
-
795 static void batcher84(uint16_t *x);
-
796 
-
797 static int discardtopoly(uint16_t *x)
-
798 {
-
799  int32_t i, r=0;
-
800 
-
801  for(i=0;i<16;i++)
-
802  batcher84(x+i);
+
670  for(i=0;i<32;i++)
+
671  key[i] = 0;
+
672 
+
673  for(i=0; i<256; i++)
+
674  {
+
675  tmp[0] = 16*PARAM_Q + 8*(int32_t)v[ 0+i] - PARAM_Q * (2*(int32_t)c[ 0+i]+c[768+i]);
+
676  tmp[1] = 16*PARAM_Q + 8*(int32_t)v[256+i] - PARAM_Q * (2*(int32_t)c[256+i]+c[768+i]);
+
677  tmp[2] = 16*PARAM_Q + 8*(int32_t)v[512+i] - PARAM_Q * (2*(int32_t)c[512+i]+c[768+i]);
+
678  tmp[3] = 16*PARAM_Q + 8*(int32_t)v[768+i] - PARAM_Q * ( c[768+i]);
+
679 
+
680  key[i>>3] |= LDDecode(tmp[0], tmp[1], tmp[2], tmp[3]) << (i & 7);
+
681  }
+
682 }
+
683 
+
684 static void poly_frombytes(uint16_t *r, const unsigned char *a)
+
685 {
+
686  int i;
+
687  for(i=0;i<PARAM_N/4;i++)
+
688  {
+
689  r[4*i+0] = a[7*i+0] | (((uint16_t)a[7*i+1] & 0x3f) << 8);
+
690  r[4*i+1] = (a[7*i+1] >> 6) | (((uint16_t)a[7*i+2]) << 2) | (((uint16_t)a[7*i+3] & 0x0f) << 10);
+
691  r[4*i+2] = (a[7*i+3] >> 4) | (((uint16_t)a[7*i+4]) << 4) | (((uint16_t)a[7*i+5] & 0x03) << 12);
+
692  r[4*i+3] = (a[7*i+5] >> 2) | (((uint16_t)a[7*i+6]) << 6);
+
693  }
+
694 }
+
695 
+
696 static void poly_tobytes(unsigned char *r, const uint16_t *p)
+
697 {
+
698  int i;
+
699  uint16_t t0,t1,t2,t3,m;
+
700  int16_t c;
+
701  for(i=0;i<PARAM_N/4;i++)
+
702  {
+
703  t0 = barrett_reduce(p[4*i+0]); //Make sure that coefficients have only 14 bits
+
704  t1 = barrett_reduce(p[4*i+1]);
+
705  t2 = barrett_reduce(p[4*i+2]);
+
706  t3 = barrett_reduce(p[4*i+3]);
+
707 
+
708  m = t0 - PARAM_Q;
+
709  c = m;
+
710  c >>= 15;
+
711  t0 = m ^ ((t0^m)&c); // <Make sure that coefficients are in [0,q]
+
712 
+
713  m = t1 - PARAM_Q;
+
714  c = m;
+
715  c >>= 15;
+
716  t1 = m ^ ((t1^m)&c); // <Make sure that coefficients are in [0,q]
+
717 
+
718  m = t2 - PARAM_Q;
+
719  c = m;
+
720  c >>= 15;
+
721  t2 = m ^ ((t2^m)&c); // <Make sure that coefficients are in [0,q]
+
722 
+
723  m = t3 - PARAM_Q;
+
724  c = m;
+
725  c >>= 15;
+
726  t3 = m ^ ((t3^m)&c); // <Make sure that coefficients are in [0,q]
+
727 
+
728  r[7*i+0] = t0 & 0xff;
+
729  r[7*i+1] = (t0 >> 8) | (t1 << 6);
+
730  r[7*i+2] = (t1 >> 2);
+
731  r[7*i+3] = (t1 >> 10) | (t2 << 4);
+
732  r[7*i+4] = (t2 >> 4);
+
733  r[7*i+5] = (t2 >> 12) | (t3 << 2);
+
734  r[7*i+6] = (t3 >> 6);
+
735  }
+
736 }
+
737 
+
738 static void poly_pointwise(uint16_t *r, const uint16_t *a, const uint16_t *b)
+
739 {
+
740  int i;
+
741  uint16_t t;
+
742  for(i=0;i<PARAM_N;i++)
+
743  {
+
744  t = montgomery_reduce(3186*(uint32_t)b[i]); /* t is now in Montgomery domain */
+
745  r[i] = montgomery_reduce(a[i] * (uint32_t)t); /* r->coeffs[i] is back in normal domain */
+
746  }
+
747 }
+
748 
+
749 static void poly_add(uint16_t *r, const uint16_t *a, const uint16_t *b)
+
750 {
+
751  int i;
+
752  for(i=0;i<PARAM_N;i++)
+
753  r[i] = barrett_reduce(a[i] + (uint32_t)b[i]);
+
754 }
+
755 
+
756 static void poly_ntt(uint16_t *r)
+
757 {
+
758  mul_coefficients(r, psis_bitrev_montgomery);
+
759  ntt(r, omegas_montgomery);
+
760 }
+
761 
+
762 static void poly_invntt(uint16_t *r)
+
763 {
+
764  bitrev_vector(r);
+
765  ntt(r, omegas_inv_montgomery);
+
766  mul_coefficients(r, psis_inv_montgomery);
+
767 }
+
768 
+
769 static void encode_b_2nd_half(unsigned char *r, const uint16_t *c)
+
770 {
+
771  int i;
+
772  for(i=0;i<PARAM_N/4;i++)
+
773  r[POLY_BYTES+i] = c[4*i] | (c[4*i+1] << 2) | (c[4*i+2] << 4) | (c[4*i+3] << 6);
+
774 }
+
775 
+
776 static void decode_b_2nd_half(uint16_t *c, const unsigned char *r)
+
777 {
+
778  int i;
+
779  for(i=0;i<PARAM_N/4;i++)
+
780  {
+
781  c[4*i+0] = r[POLY_BYTES+i] & 0x03;
+
782  c[4*i+1] = (r[POLY_BYTES+i] >> 2) & 0x03;
+
783  c[4*i+2] = (r[POLY_BYTES+i] >> 4) & 0x03;
+
784  c[4*i+3] = (r[POLY_BYTES+i] >> 6);
+
785  }
+
786 }
+
787 
+
788 #define _5q (5*PARAM_Q)
+
789 
+
790 #define compare_and_swap(x,i,j) \
+
791  c = _5q - 1 - x[16*(i)];\
+
792  c >>= 31;\
+
793  t = x[16*(i)] ^ x[16*(j)];\
+
794  t &= c;\
+
795  x[16*(i)] ^= t;\
+
796  x[16*(j)] ^= t;
+
797 
+
798 static void batcher84(uint16_t *x);
+
799 
+
800 static int discardtopoly(uint16_t *x)
+
801 {
+
802  int32_t i, r=0;
803 
-
804  // Check whether we're safe:
-
805  for(i=1008;i<1024;i++)
-
806  r |= 61444 - x[i];
-
807  if(r >>= 31) return -1;
-
808 
-
809  return 0;
-
810 }
+
804  for(i=0;i<16;i++)
+
805  batcher84(x+i);
+
806 
+
807  // Check whether we're safe:
+
808  for(i=1008;i<1024;i++)
+
809  r |= 61444 - x[i];
+
810  if(r >>= 31) return -1;
811 
-
812 // End of public domain code imported from the C reference code.
-
813 
-
814 // Code size efficient (but slower) version of the Batcher sort.
-
815 // https://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort
-
816 static void oddeven_merge(uint16_t *x, unsigned lo, unsigned hi, unsigned r)
-
817 {
-
818  unsigned step = r * 2;
-
819  unsigned i;
-
820  int32_t c;
-
821  uint16_t t;
-
822  if (lo >= 84)
-
823  return;
-
824  if (step < (hi - lo)) {
-
825  if ((step * 2) >= (hi - lo) && hi < 84) {
-
826  // The next recursion down is a leaf, so unroll a little.
-
827  compare_and_swap(x, lo, lo + step);
-
828  compare_and_swap(x, lo + r, lo + r + step);
-
829  compare_and_swap(x, lo + r, lo + step);
-
830  return;
-
831  }
-
832  oddeven_merge(x, lo, hi, step);
-
833  oddeven_merge(x, lo + r, hi, step);
-
834  for (i = lo + r; i < (hi - r) && (i + r) < 84; i += step) {
-
835  compare_and_swap(x, i, i + r);
-
836  }
-
837  } else if ((lo + r) < 84) {
-
838  compare_and_swap(x, lo, lo + r);
-
839  }
-
840 }
-
841 static void oddeven_merge_sort_range(uint16_t *x, unsigned lo, unsigned hi)
-
842 {
-
843  if (lo == hi || lo >= 84)
-
844  return;
-
845  unsigned mid = lo + ((hi - lo) / 2);
-
846  if ((hi - lo) == 3 && hi < 84) {
-
847  // Optimization for sub lists of size 4. Unroll the comparisons.
-
848  int32_t c;
-
849  uint16_t t;
-
850  compare_and_swap(x, lo , lo + 1);
-
851  compare_and_swap(x, lo + 2, lo + 3);
-
852  compare_and_swap(x, lo , lo + 2);
-
853  compare_and_swap(x, lo + 1, lo + 3);
-
854  compare_and_swap(x, lo + 1, lo + 2);
-
855  return;
-
856  }
-
857  oddeven_merge_sort_range(x, lo, mid);
-
858  oddeven_merge_sort_range(x, mid + 1, hi);
-
859  oddeven_merge(x, lo, hi, 1);
-
860 }
-
861 static void batcher84(uint16_t *x)
-
862 {
-
863  // Batcher sort is defined over a power of two list size but 84
-
864  // is not a power of two. Round up to the next power of two and
-
865  // then ignore any swap with an index that is out of range.
-
866  oddeven_merge_sort_range(x, 0, 127);
-
867 }
-
868 
-
869 // Formats the ChaCha20 input block using a key.
-
870 static void crypto_chacha20_set_key(uint32_t *block, const unsigned char *k)
-
871 {
-
872  static const char tag256[] PROGMEM = "expand 32-byte k";
-
873 #if defined(__AVR__)
-
874  memcpy_P(block, tag256, 16);
-
875 #else
-
876  memcpy(block, tag256, 16);
-
877 #endif
-
878  memcpy(block + 4, k, 32);
-
879  memset(block + 12, 0, 8);
-
880 }
-
881 
-
882 static void poly_uniform(SHAKE128 *shake, uint16_t *a, const unsigned char *seed)
-
883 {
-
884  int ctr = 0;
-
885  int posn = PARAM_N;
-
886  uint16_t val;
-
887 
-
888  // Absorb the seed material into the SHAKE128 object.
-
889  shake->update(seed, NEWHOPE_SEEDBYTES);
+
812  return 0;
+
813 }
+
814 
+
815 // End of public domain code imported from the C reference code.
+
816 
+
817 // Code size efficient (but slower) version of the Batcher sort.
+
818 // https://en.wikipedia.org/wiki/Batcher_odd%E2%80%93even_mergesort
+
819 static void oddeven_merge(uint16_t *x, unsigned lo, unsigned hi, unsigned r)
+
820 {
+
821  unsigned step = r * 2;
+
822  unsigned i;
+
823  int32_t c;
+
824  uint16_t t;
+
825  if (lo >= 84)
+
826  return;
+
827  if (step < (hi - lo)) {
+
828  if ((step * 2) >= (hi - lo) && hi < 84) {
+
829  // The next recursion down is a leaf, so unroll a little.
+
830  compare_and_swap(x, lo, lo + step);
+
831  compare_and_swap(x, lo + r, lo + r + step);
+
832  compare_and_swap(x, lo + r, lo + step);
+
833  return;
+
834  }
+
835  oddeven_merge(x, lo, hi, step);
+
836  oddeven_merge(x, lo + r, hi, step);
+
837  for (i = lo + r; i < (hi - r) && (i + r) < 84; i += step) {
+
838  compare_and_swap(x, i, i + r);
+
839  }
+
840  } else if ((lo + r) < 84) {
+
841  compare_and_swap(x, lo, lo + r);
+
842  }
+
843 }
+
844 static void oddeven_merge_sort_range(uint16_t *x, unsigned lo, unsigned hi)
+
845 {
+
846  if (lo == hi || lo >= 84)
+
847  return;
+
848  unsigned mid = lo + ((hi - lo) / 2);
+
849  if ((hi - lo) == 3 && hi < 84) {
+
850  // Optimization for sub lists of size 4. Unroll the comparisons.
+
851  int32_t c;
+
852  uint16_t t;
+
853  compare_and_swap(x, lo , lo + 1);
+
854  compare_and_swap(x, lo + 2, lo + 3);
+
855  compare_and_swap(x, lo , lo + 2);
+
856  compare_and_swap(x, lo + 1, lo + 3);
+
857  compare_and_swap(x, lo + 1, lo + 2);
+
858  return;
+
859  }
+
860  oddeven_merge_sort_range(x, lo, mid);
+
861  oddeven_merge_sort_range(x, mid + 1, hi);
+
862  oddeven_merge(x, lo, hi, 1);
+
863 }
+
864 static void batcher84(uint16_t *x)
+
865 {
+
866  // Batcher sort is defined over a power of two list size but 84
+
867  // is not a power of two. Round up to the next power of two and
+
868  // then ignore any swap with an index that is out of range.
+
869  oddeven_merge_sort_range(x, 0, 127);
+
870 }
+
871 
+
872 // Formats the ChaCha20 input block using a key.
+
873 static void crypto_chacha20_set_key(uint32_t *block, const unsigned char *k)
+
874 {
+
875  static const char tag256[] PROGMEM = "expand 32-byte k";
+
876 #if defined(__AVR__)
+
877  memcpy_P(block, tag256, 16);
+
878 #else
+
879  memcpy(block, tag256, 16);
+
880 #endif
+
881  memcpy(block + 4, k, 32);
+
882  memset(block + 12, 0, 8);
+
883 }
+
884 
+
885 static void poly_uniform(SHAKE128 *shake, uint16_t *a, const unsigned char *seed)
+
886 {
+
887  int ctr = 0;
+
888  int posn = PARAM_N;
+
889  uint16_t val;
890 
-
891  while (ctr < PARAM_N) {
-
892  // Extract data from the SHAKE128 object directly into "a".
-
893  if (posn >= PARAM_N) {
-
894  shake->extend((uint8_t *)(a + ctr),
-
895  (PARAM_N - ctr) * sizeof(uint16_t));
-
896  posn = ctr;
-
897  }
-
898 
-
899  // Process as much of the data as we can, discarding values
-
900  // that are greater than or equal to 5 * PARAM_Q.
-
901  while (posn < PARAM_N) {
-
902  val = a[posn++];
-
903  if (val < (5 * PARAM_Q))
-
904  a[ctr++] = val;
-
905  }
-
906  }
-
907 }
-
908 
-
909 static void poly_uniform_torref(SHAKE128 *shake, uint16_t *a, const unsigned char *seed)
-
910 {
-
911  shake->update(seed, 32);
-
912  do {
-
913  shake->extend((uint8_t *)a, 84 * 16 * sizeof(uint16_t));
-
914  } while (discardtopoly(a));
-
915 }
-
916 
-
917 static void poly_getnoise(uint16_t *r, NewHopeChaChaState *chacha, unsigned char nonce)
-
918 {
-
919  int i, j;
-
920  uint32_t a, b;
-
921 
-
922  // Note: The rest of this function assumes that we are running on a
-
923  // little-endian CPU. Since we're generating random noise from a
-
924  // random seed, it doesn't actually matter what the endian-ness is
-
925  // as it will be just as random in both directions. It's only a
-
926  // problem for verifying fixed test vectors.
-
927 
-
928  chacha->input[12] = 0;
-
929  chacha->input[13] = 0;
-
930  chacha->input[14] = nonce; // Assumes little-endian.
-
931  chacha->input[15] = 0;
-
932 
-
933  for (i = 0; i < PARAM_N; ++i) {
-
934  // Generate a new block of random data if necessary.
-
935  j = i % 16;
-
936  if (j == 0) {
-
937  ChaCha::hashCore(chacha->output, chacha->input, 20);
-
938  ++(chacha->input[12]); // Assumes little-endian.
-
939  }
-
940 
-
941  // This is a slightly more efficient way to count bits than in
-
942  // the reference C implementation. The technique is from:
-
943  // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
-
944  a = chacha->output[j] & 0xFFFF; // Assumes little-endian.
-
945  a = a - ((a >> 1) & 0x5555);
-
946  a = (a & 0x3333) + ((a >> 2) & 0x3333);
-
947  a = ((a >> 4) + a) & 0x0F0F;
-
948  a = ((a >> 8) + a) & 0x00FF;
-
949 
-
950  b = (chacha->output[j] >> 16) & 0xFFFF; // Assumes little-endian.
-
951  b = b - ((b >> 1) & 0x5555);
-
952  b = (b & 0x3333) + ((b >> 2) & 0x3333);
-
953  b = ((b >> 4) + b) & 0x0F0F;
-
954  b = ((b >> 8) + b) & 0x00FF;
-
955 
-
956  r[i] = a + PARAM_Q - b;
-
957  }
+
891  // Absorb the seed material into the SHAKE128 object.
+
892  shake->update(seed, NEWHOPE_SEEDBYTES);
+
893 
+
894  while (ctr < PARAM_N) {
+
895  // Extract data from the SHAKE128 object directly into "a".
+
896  if (posn >= PARAM_N) {
+
897  shake->extend((uint8_t *)(a + ctr),
+
898  (PARAM_N - ctr) * sizeof(uint16_t));
+
899  posn = ctr;
+
900  }
+
901 
+
902  // Process as much of the data as we can, discarding values
+
903  // that are greater than or equal to 5 * PARAM_Q.
+
904  while (posn < PARAM_N) {
+
905  val = a[posn++];
+
906  if (val < (5 * PARAM_Q))
+
907  a[ctr++] = val;
+
908  }
+
909  }
+
910 }
+
911 
+
912 static void poly_uniform_torref(SHAKE128 *shake, uint16_t *a, const unsigned char *seed)
+
913 {
+
914  shake->update(seed, 32);
+
915  do {
+
916  shake->extend((uint8_t *)a, 84 * 16 * sizeof(uint16_t));
+
917  } while (discardtopoly(a));
+
918 }
+
919 
+
920 static void poly_getnoise(uint16_t *r, NewHopeChaChaState *chacha, unsigned char nonce)
+
921 {
+
922  int i, j;
+
923  uint32_t a, b;
+
924 
+
925  // Note: The rest of this function assumes that we are running on a
+
926  // little-endian CPU. Since we're generating random noise from a
+
927  // random seed, it doesn't actually matter what the endian-ness is
+
928  // as it will be just as random in both directions. It's only a
+
929  // problem for verifying fixed test vectors.
+
930 
+
931  chacha->input[12] = 0;
+
932  chacha->input[13] = 0;
+
933  chacha->input[14] = nonce; // Assumes little-endian.
+
934  chacha->input[15] = 0;
+
935 
+
936  for (i = 0; i < PARAM_N; ++i) {
+
937  // Generate a new block of random data if necessary.
+
938  j = i % 16;
+
939  if (j == 0) {
+
940  ChaCha::hashCore(chacha->output, chacha->input, 20);
+
941  ++(chacha->input[12]); // Assumes little-endian.
+
942  }
+
943 
+
944  // This is a slightly more efficient way to count bits than in
+
945  // the reference C implementation. The technique is from:
+
946  // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
+
947  a = chacha->output[j] & 0xFFFF; // Assumes little-endian.
+
948  a = a - ((a >> 1) & 0x5555);
+
949  a = (a & 0x3333) + ((a >> 2) & 0x3333);
+
950  a = ((a >> 4) + a) & 0x0F0F;
+
951  a = ((a >> 8) + a) & 0x00FF;
+
952 
+
953  b = (chacha->output[j] >> 16) & 0xFFFF; // Assumes little-endian.
+
954  b = b - ((b >> 1) & 0x5555);
+
955  b = (b & 0x3333) + ((b >> 2) & 0x3333);
+
956  b = ((b >> 4) + b) & 0x0F0F;
+
957  b = ((b >> 8) + b) & 0x00FF;
958 
-
959  clean(&chacha, sizeof(chacha));
-
960 }
+
959  r[i] = a + PARAM_Q - b;
+
960  }
961 
-
984 #define ALLOC_OBJ(type, name) \
-
985  uint64_t name##_x[(sizeof(type) + sizeof(uint64_t) - 1) / sizeof(uint64_t)]
-
986 
-
987 #define INIT_OBJ(type, name) \
-
988  type *name = new (state.name##_x) type
+
962  clean(&chacha, sizeof(chacha));
+
963 }
+
964 
+
987 #define ALLOC_OBJ(type, name) \
+
988  uint64_t name##_x[(sizeof(type) + sizeof(uint64_t) - 1) / sizeof(uint64_t)]
989 
-
990 #if defined(__AVR__)
-
991 #define NEWHOPE_BYTE_ALIGNED 1
-
992 #else
-
993 #define NEWHOPE_BYTE_ALIGNED 0
-
994 #endif
-
995 
-
1014 void NewHope::keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk,
-
1015  Variant variant, const uint8_t *random_seed)
-
1016 {
-
1017  // The order of calls is rearranged compared to the reference C version.
-
1018  // This allows us to get away with two temporary poly objects (a, pk)
-
1019  // instead of four (a, e, r, pk). This saves 4k of stack space.
-
1020  //
-
1021  // We also combine most of the state into a single union, which allows
-
1022  // us to overlap some of the larger objects and reuse the stack space
-
1023  // at different points within this function.
-
1024  union {
-
1025  struct {
-
1026  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
-
1027  uint16_t pk[PARAM_N]; // Value of "pk" as a "poly" object.
-
1028  };
-
1029  struct {
-
1030  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
-
1031  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
-
1032  };
-
1033  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the seed.
-
1034  } state;
-
1035 
-
1036  // Hide the ChaCha state and the noise seed inside "send".
-
1037 #if NEWHOPE_BYTE_ALIGNED
-
1038  #define chacha (*((NewHopeChaChaState *)send))
-
1039 #else
-
1040  NewHopeChaChaState chacha;
-
1041 #endif
-
1042 #if NEWHOPE_SMALL_FOOTPRINT
-
1043  #define noiseseed (sk.seed)
-
1044 #else
-
1045  #define noiseseed (send + sizeof(NewHopeChaChaState))
-
1046 #endif
-
1047 
-
1048  if (!random_seed) {
-
1049  RNG.rand(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
-
1050  RNG.rand(noiseseed, 32);
-
1051  } else {
-
1052  memcpy(send + POLY_BYTES, random_seed, NEWHOPE_SEEDBYTES);
-
1053  memcpy(noiseseed, random_seed + NEWHOPE_SEEDBYTES, 32);
-
1054  }
-
1055  INIT_OBJ(SHA3_256, sha3);
-
1056  sha3->update(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
-
1057  sha3->finalize(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
-
1058 
-
1059  INIT_OBJ(SHAKE128, shake);
-
1060  if (variant == Ref)
-
1061  poly_uniform(shake, state.a, send + POLY_BYTES);
-
1062  else
-
1063  poly_uniform_torref(shake, state.a_ext, send + POLY_BYTES);
-
1064 
-
1065  crypto_chacha20_set_key(chacha.input, noiseseed);
-
1066 
-
1067 #if NEWHOPE_SMALL_FOOTPRINT
-
1068  poly_getnoise(state.pk, &chacha, 0);
-
1069  poly_ntt(state.pk);
-
1070  poly_pointwise(state.pk, state.pk, state.a);
-
1071 #else
-
1072  poly_getnoise(sk.coeffs, &chacha, 0);
-
1073  poly_ntt(sk.coeffs);
-
1074  poly_pointwise(state.pk, sk.coeffs, state.a);
-
1075 #endif
-
1076 
-
1077  poly_getnoise(state.a, &chacha, 1);
-
1078  poly_ntt(state.a);
-
1079 
-
1080  poly_add(state.pk, state.a, state.pk);
+
990 #define INIT_OBJ(type, name) \
+
991  type *name = new (state.name##_x) type
+
992 
+
993 #if defined(ESP8266)
+
994 // If we try to put the state on the stack, then it causes a stack smash.
+
995 // Possibly a system stack size limitation. Allocate the NewHope state on
+
996 // the heap instead for ESP8266.
+
997 #define NEWHOPE_HEAP_STATE 1
+
998 #define NEWHOPE_BYTE_ALIGNED 0
+
999 #elif defined(__AVR__)
+
1000 #define NEWHOPE_HEAP_STATE 0
+
1001 #define NEWHOPE_BYTE_ALIGNED 1
+
1002 #else
+
1003 #define NEWHOPE_HEAP_STATE 0
+
1004 #define NEWHOPE_BYTE_ALIGNED 0
+
1005 #endif
+
1006 
+
1025 void NewHope::keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk,
+
1026  Variant variant, const uint8_t *random_seed)
+
1027 {
+
1028  // The order of calls is rearranged compared to the reference C version.
+
1029  // This allows us to get away with two temporary poly objects (a, pk)
+
1030  // instead of four (a, e, r, pk). This saves 4k of stack space.
+
1031  //
+
1032  // We also combine most of the state into a single union, which allows
+
1033  // us to overlap some of the larger objects and reuse the stack space
+
1034  // at different points within this function.
+
1035  typedef union {
+
1036  struct {
+
1037  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
+
1038  uint16_t pk[PARAM_N]; // Value of "pk" as a "poly" object.
+
1039  };
+
1040  struct {
+
1041  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
+
1042  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
+
1043  };
+
1044  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the seed.
+
1045  } NewHopeKeygenState;
+
1046 #if NEWHOPE_HEAP_STATE
+
1047  NewHopeKeygenState *heapState = new NewHopeKeygenState();
+
1048  #define state (*heapState)
+
1049 #else
+
1050  NewHopeKeygenState state;
+
1051 #endif
+
1052 
+
1053  // Hide the ChaCha state and the noise seed inside "send".
+
1054 #if NEWHOPE_BYTE_ALIGNED
+
1055  #define chacha (*((NewHopeChaChaState *)send))
+
1056 #else
+
1057  NewHopeChaChaState chacha;
+
1058 #endif
+
1059 #if NEWHOPE_SMALL_FOOTPRINT
+
1060  #define noiseseed (sk.seed)
+
1061 #else
+
1062  #define noiseseed (send + sizeof(NewHopeChaChaState))
+
1063 #endif
+
1064 
+
1065  if (!random_seed) {
+
1066  RNG.rand(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
+
1067  RNG.rand(noiseseed, 32);
+
1068  } else {
+
1069  memcpy(send + POLY_BYTES, random_seed, NEWHOPE_SEEDBYTES);
+
1070  memcpy(noiseseed, random_seed + NEWHOPE_SEEDBYTES, 32);
+
1071  }
+
1072  INIT_OBJ(SHA3_256, sha3);
+
1073  sha3->update(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
+
1074  sha3->finalize(send + POLY_BYTES, NEWHOPE_SEEDBYTES);
+
1075 
+
1076  INIT_OBJ(SHAKE128, shake);
+
1077  if (variant == Ref)
+
1078  poly_uniform(shake, state.a, send + POLY_BYTES);
+
1079  else
+
1080  poly_uniform_torref(shake, state.a_ext, send + POLY_BYTES);
1081 
-
1082  poly_tobytes(send, state.pk);
+
1082  crypto_chacha20_set_key(chacha.input, noiseseed);
1083 
-
1084  clean(&state, sizeof(state));
-
1085 #if !NEWHOPE_BYTE_ALIGNED
-
1086  clean(&chacha, sizeof(chacha));
-
1087 #endif
-
1088  #undef noiseseed
-
1089  #undef chacha
-
1090 }
-
1091 
-
1116 void NewHope::sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES],
-
1117  uint8_t send[NEWHOPE_SENDBBYTES],
-
1118  uint8_t received[NEWHOPE_SENDABYTES],
-
1119  Variant variant, const uint8_t *random_seed)
-
1120 {
-
1121 #if NEWHOPE_SMALL_FOOTPRINT && NEWHOPE_BYTE_ALIGNED
-
1122  // The order of calls is rearranged compared to the reference C version.
-
1123  // This allows us to get away with 2 temporary poly objects (v, a)
-
1124  // instead of 8 (sp, ep, v, a, pka, c, epp, bp). Saves 12k of stack space.
-
1125  // To achieve this, we reuse "send" as the third temporary poly object bp.
-
1126  //
-
1127  // We also combine most of the state into a single union, which allows
-
1128  // us to overlap some of the larger objects and reuse the stack space
-
1129  // at different points within this function.
-
1130  union {
-
1131  struct {
-
1132  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
-
1133  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
-
1134  };
-
1135  struct {
-
1136  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
-
1137  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
-
1138  };
-
1139  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
-
1140  } state;
-
1141  uint8_t seed[32];
-
1142  NewHopeChaChaState chacha;
-
1143  #define bp ((uint16_t *)send)
-
1144 
-
1145  if (!random_seed) {
-
1146  RNG.rand(seed, 32);
-
1147  crypto_chacha20_set_key(chacha.input, seed);
-
1148  } else {
-
1149  crypto_chacha20_set_key(chacha.input, random_seed);
-
1150  }
-
1151 
-
1152  poly_frombytes(state.a, received);
-
1153  memcpy(seed, received + POLY_BYTES, 32);
-
1154 
-
1155  poly_getnoise(bp, &chacha, 0);
-
1156  poly_ntt(bp);
-
1157 
-
1158  poly_pointwise(state.v, state.a, bp);
-
1159  poly_invntt(state.v);
-
1160 
-
1161  poly_getnoise(bp, &chacha, 2);
-
1162 
-
1163  poly_add(state.v, state.v, bp);
-
1164 
-
1165  helprec(&chacha, state.a, state.v, 3);
-
1166 
-
1167  encode_b_2nd_half(send, state.a);
-
1168 
-
1169  rec(shared_key, state.v, state.a);
-
1170 
-
1171  INIT_OBJ(SHA3_256, sha3);
-
1172  sha3->update(shared_key, 32);
-
1173  sha3->finalize(shared_key, 32);
-
1174 
-
1175  INIT_OBJ(SHAKE128, shake);
-
1176  if (variant == Ref)
-
1177  poly_uniform(shake, state.a, seed);
-
1178  else
-
1179  poly_uniform_torref(shake, state.a_ext, seed);
-
1180 
-
1181  poly_getnoise(state.v, &chacha, 0);
-
1182  poly_ntt(state.v);
+
1084 #if NEWHOPE_SMALL_FOOTPRINT
+
1085  poly_getnoise(state.pk, &chacha, 0);
+
1086  poly_ntt(state.pk);
+
1087  poly_pointwise(state.pk, state.pk, state.a);
+
1088 #else
+
1089  poly_getnoise(sk.coeffs, &chacha, 0);
+
1090  poly_ntt(sk.coeffs);
+
1091  poly_pointwise(state.pk, sk.coeffs, state.a);
+
1092 #endif
+
1093 
+
1094  poly_getnoise(state.a, &chacha, 1);
+
1095  poly_ntt(state.a);
+
1096 
+
1097  poly_add(state.pk, state.a, state.pk);
+
1098 
+
1099  poly_tobytes(send, state.pk);
+
1100 
+
1101  clean(&state, sizeof(state));
+
1102 #if !NEWHOPE_BYTE_ALIGNED
+
1103  clean(&chacha, sizeof(chacha));
+
1104 #endif
+
1105  #undef noiseseed
+
1106  #undef chacha
+
1107 #if NEWHOPE_HEAP_STATE
+
1108  delete heapState;
+
1109  #undef state
+
1110 #endif
+
1111 }
+
1112 
+
1137 void NewHope::sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES],
+
1138  uint8_t send[NEWHOPE_SENDBBYTES],
+
1139  uint8_t received[NEWHOPE_SENDABYTES],
+
1140  Variant variant, const uint8_t *random_seed)
+
1141 {
+
1142 #if NEWHOPE_SMALL_FOOTPRINT && NEWHOPE_BYTE_ALIGNED
+
1143  // The order of calls is rearranged compared to the reference C version.
+
1144  // This allows us to get away with 2 temporary poly objects (v, a)
+
1145  // instead of 8 (sp, ep, v, a, pka, c, epp, bp). Saves 12k of stack space.
+
1146  // To achieve this, we reuse "send" as the third temporary poly object bp.
+
1147  //
+
1148  // We also combine most of the state into a single union, which allows
+
1149  // us to overlap some of the larger objects and reuse the stack space
+
1150  // at different points within this function.
+
1151  union {
+
1152  struct {
+
1153  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
+
1154  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
+
1155  };
+
1156  struct {
+
1157  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
+
1158  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
+
1159  };
+
1160  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
+
1161  } state;
+
1162  uint8_t seed[32];
+
1163  NewHopeChaChaState chacha;
+
1164  #define bp ((uint16_t *)send)
+
1165 
+
1166  if (!random_seed) {
+
1167  RNG.rand(seed, 32);
+
1168  crypto_chacha20_set_key(chacha.input, seed);
+
1169  } else {
+
1170  crypto_chacha20_set_key(chacha.input, random_seed);
+
1171  }
+
1172 
+
1173  poly_frombytes(state.a, received);
+
1174  memcpy(seed, received + POLY_BYTES, 32);
+
1175 
+
1176  poly_getnoise(bp, &chacha, 0);
+
1177  poly_ntt(bp);
+
1178 
+
1179  poly_pointwise(state.v, state.a, bp);
+
1180  poly_invntt(state.v);
+
1181 
+
1182  poly_getnoise(bp, &chacha, 2);
1183 
-
1184  poly_pointwise(state.a, state.a, state.v);
+
1184  poly_add(state.v, state.v, bp);
1185 
-
1186  poly_getnoise(state.v, &chacha, 1);
-
1187  poly_ntt(state.v);
-
1188 
-
1189  poly_add(state.a, state.a, state.v);
-
1190 
-
1191  poly_tobytes(send, state.a);
-
1192 
-
1193  clean(&state, sizeof(state));
-
1194  clean(&chacha, sizeof(chacha));
-
1195  clean(seed, sizeof(seed));
-
1196  #undef bp
-
1197 #else
-
1198  // The order of calls is rearranged compared to the reference C version.
-
1199  // This allows us to get away with 3 temporary poly objects (v, a, bp)
-
1200  // instead of 8 (sp, ep, v, a, pka, c, epp, bp). Saves 10k of stack space.
-
1201  //
-
1202  // We also combine most of the state into a single union, which allows
-
1203  // us to overlap some of the larger objects and reuse the stack space
-
1204  // at different points within this function.
-
1205  union {
-
1206  struct {
-
1207  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
-
1208  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
-
1209  uint16_t bp[PARAM_N]; // Value of "bp" as a "poly" object.
-
1210  };
-
1211  struct {
-
1212  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
-
1213  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
-
1214  };
-
1215  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
-
1216  } state;
-
1217 
-
1218  // Hide the ChaCha state and the noise seed inside "send".
-
1219  // Put them at the end of the "send" buffer in case "received"
-
1220  // overlaps with the start of "send".
-
1221 #if NEWHOPE_BYTE_ALIGNED
-
1222  #define chacha (*((NewHopeChaChaState *)(send + NEWHOPE_SENDABYTES)))
-
1223 #else
-
1224  NewHopeChaChaState chacha;
-
1225 #endif
-
1226  #define noiseseed (send + NEWHOPE_SENDABYTES + sizeof(NewHopeChaChaState))
-
1227 
-
1228  if (!random_seed)
-
1229  RNG.rand(noiseseed, 32);
-
1230  else
-
1231  memcpy(noiseseed, random_seed, 32);
-
1232 
-
1233  INIT_OBJ(SHAKE128, shake);
-
1234  if (variant == Ref)
-
1235  poly_uniform(shake, state.a, received + POLY_BYTES);
-
1236  else
-
1237  poly_uniform_torref(shake, state.a_ext, received + POLY_BYTES);
-
1238 
-
1239  crypto_chacha20_set_key(chacha.input, noiseseed);
-
1240 
-
1241  poly_getnoise(state.v, &chacha, 0);
-
1242  poly_ntt(state.v);
-
1243 
-
1244  poly_pointwise(state.bp, state.a, state.v);
-
1245 
-
1246  poly_getnoise(state.a, &chacha, 1);
-
1247  poly_ntt(state.a);
-
1248 
-
1249  poly_add(state.bp, state.bp, state.a);
-
1250 
-
1251  poly_frombytes(state.a, received);
-
1252 
-
1253  poly_pointwise(state.v, state.a, state.v);
-
1254  poly_invntt(state.v);
-
1255 
-
1256  poly_getnoise(state.a, &chacha, 2);
-
1257  poly_add(state.v, state.v, state.a);
-
1258 
-
1259  helprec(&chacha, state.a, state.v, 3);
-
1260 
-
1261  poly_tobytes(send, state.bp);
-
1262  encode_b_2nd_half(send, state.a);
-
1263 
-
1264  rec(shared_key, state.v, state.a);
+
1186  helprec(&chacha, state.a, state.v, 3);
+
1187 
+
1188  encode_b_2nd_half(send, state.a);
+
1189 
+
1190  rec(shared_key, state.v, state.a);
+
1191 
+
1192  INIT_OBJ(SHA3_256, sha3);
+
1193  sha3->update(shared_key, 32);
+
1194  sha3->finalize(shared_key, 32);
+
1195 
+
1196  INIT_OBJ(SHAKE128, shake);
+
1197  if (variant == Ref)
+
1198  poly_uniform(shake, state.a, seed);
+
1199  else
+
1200  poly_uniform_torref(shake, state.a_ext, seed);
+
1201 
+
1202  poly_getnoise(state.v, &chacha, 0);
+
1203  poly_ntt(state.v);
+
1204 
+
1205  poly_pointwise(state.a, state.a, state.v);
+
1206 
+
1207  poly_getnoise(state.v, &chacha, 1);
+
1208  poly_ntt(state.v);
+
1209 
+
1210  poly_add(state.a, state.a, state.v);
+
1211 
+
1212  poly_tobytes(send, state.a);
+
1213 
+
1214  clean(&state, sizeof(state));
+
1215  clean(&chacha, sizeof(chacha));
+
1216  clean(seed, sizeof(seed));
+
1217  #undef bp
+
1218 #else
+
1219  // The order of calls is rearranged compared to the reference C version.
+
1220  // This allows us to get away with 3 temporary poly objects (v, a, bp)
+
1221  // instead of 8 (sp, ep, v, a, pka, c, epp, bp). Saves 10k of stack space.
+
1222  //
+
1223  // We also combine most of the state into a single union, which allows
+
1224  // us to overlap some of the larger objects and reuse the stack space
+
1225  // at different points within this function.
+
1226  typedef union {
+
1227  struct {
+
1228  uint16_t a[PARAM_N]; // Value of "a" as a "poly" object.
+
1229  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
+
1230  uint16_t bp[PARAM_N]; // Value of "bp" as a "poly" object.
+
1231  };
+
1232  struct {
+
1233  uint16_t a_ext[84 * 16]; // Value of "a" for torref uniform.
+
1234  ALLOC_OBJ(SHAKE128, shake); // SHAKE128 object for poly_uniform().
+
1235  };
+
1236  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
+
1237  } NewHopeSharedBState;
+
1238 #if NEWHOPE_HEAP_STATE
+
1239  NewHopeSharedBState *heapState = new NewHopeSharedBState();
+
1240  #define state (*heapState)
+
1241 #else
+
1242  NewHopeSharedBState state;
+
1243 #endif
+
1244 
+
1245  // Hide the ChaCha state and the noise seed inside "send".
+
1246  // Put them at the end of the "send" buffer in case "received"
+
1247  // overlaps with the start of "send".
+
1248 #if NEWHOPE_BYTE_ALIGNED
+
1249  #define chacha (*((NewHopeChaChaState *)(send + NEWHOPE_SENDABYTES)))
+
1250 #else
+
1251  NewHopeChaChaState chacha;
+
1252 #endif
+
1253  #define noiseseed (send + NEWHOPE_SENDABYTES + sizeof(NewHopeChaChaState))
+
1254 
+
1255  if (!random_seed)
+
1256  RNG.rand(noiseseed, 32);
+
1257  else
+
1258  memcpy(noiseseed, random_seed, 32);
+
1259 
+
1260  INIT_OBJ(SHAKE128, shake);
+
1261  if (variant == Ref)
+
1262  poly_uniform(shake, state.a, received + POLY_BYTES);
+
1263  else
+
1264  poly_uniform_torref(shake, state.a_ext, received + POLY_BYTES);
1265 
-
1266  INIT_OBJ(SHA3_256, sha3);
-
1267  sha3->update(shared_key, 32);
-
1268  sha3->finalize(shared_key, 32);
-
1269 
-
1270  clean(&state, sizeof(state));
-
1271 #if !NEWHOPE_BYTE_ALIGNED
-
1272  clean(&chacha, sizeof(chacha));
-
1273 #endif
-
1274 #undef noiseseed
-
1275 #undef chacha
-
1276 #endif
-
1277 }
-
1278 
-
1288 void NewHope::shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES],
-
1289  const NewHopePrivateKey &sk,
-
1290  uint8_t received[NEWHOPE_SENDBBYTES])
-
1291 {
-
1292  // The order of calls is rearranged compared to the reference C version.
-
1293  // This allows us to get away with two temporary poly objects (v, bp)
-
1294  // instead of three (v, bp, c). This saves 2k of stack space.
-
1295  //
-
1296  // We also combine most of the state into a single union, which allows
-
1297  // us to overlap some of the larger objects and reuse the stack space
-
1298  // at different points within this function.
-
1299  union {
-
1300  struct {
-
1301  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
-
1302  uint16_t bp[PARAM_N]; // Value of "bp" as a "poly" object.
-
1303  };
-
1304  struct {
-
1305  uint16_t v_alt[PARAM_N];
-
1306  ALLOC_OBJ(NewHopeChaChaState, chacha);
-
1307  };
-
1308  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
-
1309  } state;
-
1310 
-
1311 #if NEWHOPE_SMALL_FOOTPRINT
-
1312  // Re-create the full private key for Alice from the seed.
-
1313  INIT_OBJ(NewHopeChaChaState, chacha);
-
1314  crypto_chacha20_set_key(chacha->input, sk.seed);
-
1315  poly_getnoise(state.v, chacha, 0);
-
1316  poly_ntt(state.v);
-
1317  poly_frombytes(state.bp, received);
-
1318  poly_pointwise(state.v, state.v, state.bp);
-
1319  poly_invntt(state.v);
-
1320 #else
-
1321  // Alice's full private key was supplied.
-
1322  poly_frombytes(state.bp, received);
-
1323  poly_pointwise(state.v, sk.coeffs, state.bp);
-
1324  poly_invntt(state.v);
-
1325 #endif
-
1326 
-
1327  decode_b_2nd_half(state.bp, received);
-
1328 
-
1329  rec(shared_key, state.v, state.bp);
-
1330 
-
1331  INIT_OBJ(SHA3_256, sha3);
-
1332  sha3->update(shared_key, 32);
-
1333  sha3->finalize(shared_key, 32);
-
1334 
-
1335  clean(&state, sizeof(state));
-
1336 }
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
+
1266  crypto_chacha20_set_key(chacha.input, noiseseed);
+
1267 
+
1268  poly_getnoise(state.v, &chacha, 0);
+
1269  poly_ntt(state.v);
+
1270 
+
1271  poly_pointwise(state.bp, state.a, state.v);
+
1272 
+
1273  poly_getnoise(state.a, &chacha, 1);
+
1274  poly_ntt(state.a);
+
1275 
+
1276  poly_add(state.bp, state.bp, state.a);
+
1277 
+
1278  poly_frombytes(state.a, received);
+
1279 
+
1280  poly_pointwise(state.v, state.a, state.v);
+
1281  poly_invntt(state.v);
+
1282 
+
1283  poly_getnoise(state.a, &chacha, 2);
+
1284  poly_add(state.v, state.v, state.a);
+
1285 
+
1286  helprec(&chacha, state.a, state.v, 3);
+
1287 
+
1288  poly_tobytes(send, state.bp);
+
1289  encode_b_2nd_half(send, state.a);
+
1290 
+
1291  rec(shared_key, state.v, state.a);
+
1292 
+
1293  INIT_OBJ(SHA3_256, sha3);
+
1294  sha3->update(shared_key, 32);
+
1295  sha3->finalize(shared_key, 32);
+
1296 
+
1297  clean(&state, sizeof(state));
+
1298 #if !NEWHOPE_BYTE_ALIGNED
+
1299  clean(&chacha, sizeof(chacha));
+
1300 #endif
+
1301 #undef noiseseed
+
1302 #undef chacha
+
1303 #endif
+
1304 #if NEWHOPE_HEAP_STATE
+
1305  delete heapState;
+
1306  #undef state
+
1307 #endif
+
1308 }
+
1309 
+
1319 void NewHope::shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES],
+
1320  const NewHopePrivateKey &sk,
+
1321  uint8_t received[NEWHOPE_SENDBBYTES])
+
1322 {
+
1323  // The order of calls is rearranged compared to the reference C version.
+
1324  // This allows us to get away with two temporary poly objects (v, bp)
+
1325  // instead of three (v, bp, c). This saves 2k of stack space.
+
1326  //
+
1327  // We also combine most of the state into a single union, which allows
+
1328  // us to overlap some of the larger objects and reuse the stack space
+
1329  // at different points within this function.
+
1330  typedef union {
+
1331  struct {
+
1332  uint16_t v[PARAM_N]; // Value of "v" as a "poly" object.
+
1333  uint16_t bp[PARAM_N]; // Value of "bp" as a "poly" object.
+
1334  };
+
1335  struct {
+
1336  uint16_t v_alt[PARAM_N];
+
1337  ALLOC_OBJ(NewHopeChaChaState, chacha);
+
1338  };
+
1339  ALLOC_OBJ(SHA3_256, sha3); // SHA3 object for hashing the result.
+
1340  } NewHopeSharedAState;
+
1341 #if NEWHOPE_HEAP_STATE
+
1342  NewHopeSharedAState *heapState = new NewHopeSharedAState();
+
1343  #define state (*heapState)
+
1344 #else
+
1345  NewHopeSharedAState state;
+
1346 #endif
+
1347 
+
1348 #if NEWHOPE_SMALL_FOOTPRINT
+
1349  // Re-create the full private key for Alice from the seed.
+
1350  INIT_OBJ(NewHopeChaChaState, chacha);
+
1351  crypto_chacha20_set_key(chacha->input, sk.seed);
+
1352  poly_getnoise(state.v, chacha, 0);
+
1353  poly_ntt(state.v);
+
1354  poly_frombytes(state.bp, received);
+
1355  poly_pointwise(state.v, state.v, state.bp);
+
1356  poly_invntt(state.v);
+
1357 #else
+
1358  // Alice's full private key was supplied.
+
1359  poly_frombytes(state.bp, received);
+
1360  poly_pointwise(state.v, sk.coeffs, state.bp);
+
1361  poly_invntt(state.v);
+
1362 #endif
+
1363 
+
1364  decode_b_2nd_half(state.bp, received);
+
1365 
+
1366  rec(shared_key, state.v, state.bp);
+
1367 
+
1368  INIT_OBJ(SHA3_256, sha3);
+
1369  sha3->update(shared_key, 32);
+
1370  sha3->finalize(shared_key, 32);
+
1371 
+
1372  clean(&state, sizeof(state));
+
1373 #if NEWHOPE_HEAP_STATE
+
1374  delete heapState;
+
1375  #undef state
+
1376 #endif
+
1377 }
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
NewHope::Variant
Variant
Describes the variant of the New Hope algorithm to implement.
Definition: NewHope.h:57
SHAKE128
SHAKE Extendable-Output Function (XOF) with 128-bit security.
Definition: SHAKE.h:52
-
NewHope::keygen
static void keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk, Variant variant=Ref, const uint8_t *random_seed=0)
Generates the key pair for Alice in a New Hope key exchange.
Definition: NewHope.cpp:1014
-
NewHope::shareda
static void shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES], const NewHopePrivateKey &sk, uint8_t received[NEWHOPE_SENDBBYTES])
Generates the shared secret for Alice.
Definition: NewHope.cpp:1288
+
NewHope::keygen
static void keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk, Variant variant=Ref, const uint8_t *random_seed=0)
Generates the key pair for Alice in a New Hope key exchange.
Definition: NewHope.cpp:1025
+
NewHope::shareda
static void shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES], const NewHopePrivateKey &sk, uint8_t received[NEWHOPE_SENDBBYTES])
Generates the shared secret for Alice.
Definition: NewHope.cpp:1319
NewHopePrivateKey
NewHope private key representation.
Definition: NewHope.h:38
-
NewHope::sharedb
static void sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES], uint8_t send[NEWHOPE_SENDBBYTES], uint8_t received[NEWHOPE_SENDABYTES], Variant variant=Ref, const uint8_t *random_seed=0)
Generates the public key and shared secret for Bob.
Definition: NewHope.cpp:1116
+
NewHope::sharedb
static void sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES], uint8_t send[NEWHOPE_SENDBBYTES], uint8_t received[NEWHOPE_SENDABYTES], Variant variant=Ref, const uint8_t *random_seed=0)
Generates the public key and shared secret for Bob.
Definition: NewHope.cpp:1137
SHAKE::update
void update(const void *data, size_t len)
Updates the XOF with more data.
Definition: SHAKE.cpp:64
ChaCha::hashCore
static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds)
Executes the ChaCha hash core on an input memory block.
Definition: ChaCha.cpp:253
SHA3_256
SHA3-256 hash algorithm.
Definition: SHA3.h:29
@@ -1253,7 +1294,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/NewHope_8h_source.html b/NewHope_8h_source.html index e267d98a..3d388b28 100644 --- a/NewHope_8h_source.html +++ b/NewHope_8h_source.html @@ -163,15 +163,15 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
NewHope::Torref
The alternative "torref" version of the New Hope algorithm.
Definition: NewHope.h:60
NewHope::Variant
Variant
Describes the variant of the New Hope algorithm to implement.
Definition: NewHope.h:57
NewHope
NewHope post-quantum key exchange algorithm.
Definition: NewHope.h:50
-
NewHope::keygen
static void keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk, Variant variant=Ref, const uint8_t *random_seed=0)
Generates the key pair for Alice in a New Hope key exchange.
Definition: NewHope.cpp:1014
-
NewHope::shareda
static void shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES], const NewHopePrivateKey &sk, uint8_t received[NEWHOPE_SENDBBYTES])
Generates the shared secret for Alice.
Definition: NewHope.cpp:1288
+
NewHope::keygen
static void keygen(uint8_t send[NEWHOPE_SENDABYTES], NewHopePrivateKey &sk, Variant variant=Ref, const uint8_t *random_seed=0)
Generates the key pair for Alice in a New Hope key exchange.
Definition: NewHope.cpp:1025
+
NewHope::shareda
static void shareda(uint8_t shared_key[NEWHOPE_SHAREDBYTES], const NewHopePrivateKey &sk, uint8_t received[NEWHOPE_SENDBBYTES])
Generates the shared secret for Alice.
Definition: NewHope.cpp:1319
NewHopePrivateKey
NewHope private key representation.
Definition: NewHope.h:38
-
NewHope::sharedb
static void sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES], uint8_t send[NEWHOPE_SENDBBYTES], uint8_t received[NEWHOPE_SENDABYTES], Variant variant=Ref, const uint8_t *random_seed=0)
Generates the public key and shared secret for Bob.
Definition: NewHope.cpp:1116
+
NewHope::sharedb
static void sharedb(uint8_t shared_key[NEWHOPE_SHAREDBYTES], uint8_t send[NEWHOPE_SENDBBYTES], uint8_t received[NEWHOPE_SENDABYTES], Variant variant=Ref, const uint8_t *random_seed=0)
Generates the public key and shared secret for Bob.
Definition: NewHope.cpp:1137
NewHope::Ref
The standard "reference" version of the New Hope algorithm.
Definition: NewHope.h:59
diff --git a/NoiseSource_8cpp_source.html b/NoiseSource_8cpp_source.html index 775bdece..6189ed3f 100644 --- a/NoiseSource_8cpp_source.html +++ b/NoiseSource_8cpp_source.html @@ -134,11 +134,11 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
NoiseSource::added
virtual void added()
Called when the noise source is added to RNG with RNG.addNoiseSource().
Definition: NoiseSource.cpp:95
NoiseSource::output
virtual void output(const uint8_t *data, size_t len, unsigned int credit)
Called from subclasses to output noise to the global random number pool.
Definition: NoiseSource.cpp:117
NoiseSource::~NoiseSource
virtual ~NoiseSource()
Destroys this random noise source.
Definition: NoiseSource.cpp:43
-
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:626
+
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:693
diff --git a/NoiseSource_8h_source.html b/NoiseSource_8h_source.html index e3c7c9e7..086a9232 100644 --- a/NoiseSource_8h_source.html +++ b/NoiseSource_8h_source.html @@ -142,7 +142,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/OFB_8cpp_source.html b/OFB_8cpp_source.html index 838fe362..6b047bf4 100644 --- a/OFB_8cpp_source.html +++ b/OFB_8cpp_source.html @@ -206,7 +206,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/OFB_8h_source.html b/OFB_8h_source.html index 1421ffc9..c69ee1d5 100644 --- a/OFB_8h_source.html +++ b/OFB_8h_source.html @@ -171,7 +171,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/OMAC_8cpp_source.html b/OMAC_8cpp_source.html index 8f5d117c..d1c35239 100644 --- a/OMAC_8cpp_source.html +++ b/OMAC_8cpp_source.html @@ -208,7 +208,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/OMAC_8h_source.html b/OMAC_8h_source.html index c1e07b76..5751faeb 100644 --- a/OMAC_8h_source.html +++ b/OMAC_8h_source.html @@ -152,7 +152,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/P521_8cpp_source.html b/P521_8cpp_source.html index c67de49d..006d14e0 100644 --- a/P521_8cpp_source.html +++ b/P521_8cpp_source.html @@ -782,534 +782,535 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
965  mulNoReduce(temp, x, y);
966  reduce(result, temp);
967  strict_clean(temp);
-
968 }
-
969 
-
989 void P521::mulLiteral(limb_t *result, const limb_t *x, limb_t y)
-
990 {
-
991  uint8_t index;
-
992  dlimb_t carry = 0;
-
993  const limb_t *xx = x;
-
994  limb_t *rr = result;
-
995 
-
996  // Multiply x by the literal and put it into the result array.
-
997  // We assume that y is small enough that overflow from the
-
998  // highest limb will not occur during this process.
-
999  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
-
1000  carry += ((dlimb_t)(*xx++)) * y;
-
1001  *rr++ = (limb_t)carry;
-
1002  carry >>= LIMB_BITS;
-
1003  }
-
1004 
-
1005  // Reduce the value modulo 2^521 - 1. The high half is only a
-
1006  // single limb, so we can short-cut some of reduce() here.
-
1007 #if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
-
1008  limb_t word = result[NUM_LIMBS_521BIT - 1];
-
1009  carry = (word >> 9) + 1;
-
1010  word &= 0x1FF;
-
1011  rr = result;
-
1012  for (index = 0; index < (NUM_LIMBS_521BIT - 1); ++index) {
-
1013  carry += *rr;
-
1014  *rr++ = (limb_t)carry;
-
1015  carry >>= LIMB_BITS;
-
1016  }
-
1017  carry += word;
-
1018  word = (limb_t)carry;
-
1019  *rr = word;
-
1020 
-
1021  // If the carry out was 1, then mask it off and we have the answer.
-
1022  // If the carry out was 0, then we need to add 2^521 - 1 back again.
-
1023  // To preserve the timing we perform a conditional subtract of 1 and
-
1024  // then mask off the high bits.
-
1025  carry = ((word >> 9) ^ 0x01) & 0x01;
-
1026  rr = result;
-
1027  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
-
1028  carry = ((dlimb_t)(*rr)) - carry;
-
1029  *rr++ = (limb_t)carry;
-
1030  carry = (carry >> LIMB_BITS) & 0x01;
-
1031  }
-
1032  *(--rr) &= 0x1FF;
-
1033 #elif BIGNUMBER_LIMB_8BIT
-
1034  // Same as above, but for 8-bit limbs.
-
1035  limb_t word = result[NUM_LIMBS_521BIT - 1];
-
1036  carry = (word >> 1) + 1;
-
1037  word &= 0x01;
-
1038  rr = result;
-
1039  for (index = 0; index < (NUM_LIMBS_521BIT - 1); ++index) {
-
1040  carry += *rr;
-
1041  *rr++ = (limb_t)carry;
-
1042  carry >>= LIMB_BITS;
-
1043  }
-
1044  carry += word;
-
1045  word = (limb_t)carry;
-
1046  *rr = word;
-
1047  carry = ((word >> 1) ^ 0x01) & 0x01;
-
1048  rr = result;
-
1049  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
-
1050  carry = ((dlimb_t)(*rr)) - carry;
-
1051  *rr++ = (limb_t)carry;
-
1052  carry = (carry >> LIMB_BITS) & 0x01;
-
1053  }
-
1054  *(--rr) &= 0x01;
-
1055 #endif
-
1056 }
-
1057 
-
1068 void P521::add(limb_t *result, const limb_t *x, const limb_t *y)
-
1069 {
-
1070  dlimb_t carry = 0;
-
1071  limb_t *rr = result;
-
1072  for (uint8_t posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
-
1073  carry += *x++;
-
1074  carry += *y++;
-
1075  *rr++ = (limb_t)carry;
-
1076  carry >>= LIMB_BITS;
-
1077  }
-
1078  reduceQuick(result);
-
1079 }
-
1080 
-
1091 void P521::sub(limb_t *result, const limb_t *x, const limb_t *y)
-
1092 {
-
1093  dlimb_t borrow;
-
1094  uint8_t posn;
-
1095  limb_t *rr = result;
-
1096 
-
1097  // Subtract y from x to generate the intermediate result.
-
1098  borrow = 0;
-
1099  for (posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
-
1100  borrow = ((dlimb_t)(*x++)) - (*y++) - ((borrow >> LIMB_BITS) & 0x01);
-
1101  *rr++ = (limb_t)borrow;
-
1102  }
-
1103 
-
1104  // If we had a borrow, then the result has gone negative and we
-
1105  // have to add 2^521 - 1 to the result to make it positive again.
-
1106  // The top bits of "borrow" will be all 1's if there is a borrow
-
1107  // or it will be all 0's if there was no borrow. Easiest is to
-
1108  // conditionally subtract 1 and then mask off the high bits.
-
1109  rr = result;
-
1110  borrow = (borrow >> LIMB_BITS) & 1U;
-
1111  borrow = ((dlimb_t)(*rr)) - borrow;
-
1112  *rr++ = (limb_t)borrow;
-
1113  for (posn = 1; posn < NUM_LIMBS_521BIT; ++posn) {
-
1114  borrow = ((dlimb_t)(*rr)) - ((borrow >> LIMB_BITS) & 0x01);
-
1115  *rr++ = (limb_t)borrow;
-
1116  }
-
1117 #if BIGNUMBER_LIMB_8BIT
-
1118  *(--rr) &= 0x01;
-
1119 #else
-
1120  *(--rr) &= 0x1FF;
-
1121 #endif
-
1122 }
-
1123 
-
1139 void P521::dblPoint(limb_t *xout, limb_t *yout, limb_t *zout,
-
1140  const limb_t *xin, const limb_t *yin,
-
1141  const limb_t *zin)
-
1142 {
-
1143  limb_t alpha[NUM_LIMBS_521BIT];
-
1144  limb_t beta[NUM_LIMBS_521BIT];
-
1145  limb_t gamma[NUM_LIMBS_521BIT];
-
1146  limb_t delta[NUM_LIMBS_521BIT];
-
1147  limb_t tmp[NUM_LIMBS_521BIT];
-
1148 
-
1149  // Double the point. If it is the point at infinity (z = 0),
-
1150  // then zout will still be zero at the end of this process so
-
1151  // we don't need any special handling for that case.
-
1152  square(delta, zin); // delta = z^2
-
1153  square(gamma, yin); // gamma = y^2
-
1154  mul(beta, xin, gamma); // beta = x * gamma
-
1155  sub(tmp, xin, delta); // alpha = 3 * (x - delta) * (x + delta)
-
1156  mulLiteral(alpha, tmp, 3);
-
1157  add(tmp, xin, delta);
-
1158  mul(alpha, alpha, tmp);
-
1159  square(xout, alpha); // xout = alpha^2 - 8 * beta
-
1160  mulLiteral(tmp, beta, 8);
-
1161  sub(xout, xout, tmp);
-
1162  add(zout, yin, zin); // zout = (y + z)^2 - gamma - delta
-
1163  square(zout, zout);
-
1164  sub(zout, zout, gamma);
-
1165  sub(zout, zout, delta);
-
1166  mulLiteral(yout, beta, 4);// yout = alpha * (4 * beta - xout) - 8 * gamma^2
-
1167  sub(yout, yout, xout);
-
1168  mul(yout, alpha, yout);
-
1169  square(gamma, gamma);
-
1170  mulLiteral(gamma, gamma, 8);
-
1171  sub(yout, yout, gamma);
-
1172 
-
1173  // Clean up.
-
1174  strict_clean(alpha);
-
1175  strict_clean(beta);
-
1176  strict_clean(gamma);
-
1177  strict_clean(delta);
-
1178  strict_clean(tmp);
-
1179 }
-
1180 
-
1200 void P521::addPoint(limb_t *xout, limb_t *yout, limb_t *zout,
-
1201  const limb_t *x1, const limb_t *y1,
-
1202  const limb_t *z1, const limb_t *x2,
-
1203  const limb_t *y2)
-
1204 {
-
1205  limb_t z1z1[NUM_LIMBS_521BIT];
-
1206  limb_t u2[NUM_LIMBS_521BIT];
-
1207  limb_t s2[NUM_LIMBS_521BIT];
-
1208  limb_t h[NUM_LIMBS_521BIT];
-
1209  limb_t i[NUM_LIMBS_521BIT];
-
1210  limb_t j[NUM_LIMBS_521BIT];
-
1211  limb_t r[NUM_LIMBS_521BIT];
-
1212  limb_t v[NUM_LIMBS_521BIT];
-
1213 
-
1214  // Determine if the first value is the point-at-infinity identity element.
-
1215  // The second z value is always 1 so it cannot be the point-at-infinity.
-
1216  limb_t p1IsIdentity = BigNumberUtil::isZero(z1, NUM_LIMBS_521BIT);
-
1217 
-
1218  // Multiply the points, assuming that z2 = 1.
-
1219  square(z1z1, z1); // z1z1 = z1^2
-
1220  mul(u2, x2, z1z1); // u2 = x2 * z1z1
-
1221  mul(s2, y2, z1); // s2 = y2 * z1 * z1z1
-
1222  mul(s2, s2, z1z1);
-
1223  sub(h, u2, x1); // h = u2 - x1
-
1224  mulLiteral(i, h, 2); // i = (2 * h)^2
-
1225  square(i, i);
-
1226  sub(r, s2, y1); // r = 2 * (s2 - y1)
-
1227  add(r, r, r);
-
1228  mul(j, h, i); // j = h * i
-
1229  mul(v, x1, i); // v = x1 * i
-
1230  square(xout, r); // xout = r^2 - j - 2 * v
-
1231  sub(xout, xout, j);
-
1232  sub(xout, xout, v);
+
968  crypto_feed_watchdog();
+
969 }
+
970 
+
990 void P521::mulLiteral(limb_t *result, const limb_t *x, limb_t y)
+
991 {
+
992  uint8_t index;
+
993  dlimb_t carry = 0;
+
994  const limb_t *xx = x;
+
995  limb_t *rr = result;
+
996 
+
997  // Multiply x by the literal and put it into the result array.
+
998  // We assume that y is small enough that overflow from the
+
999  // highest limb will not occur during this process.
+
1000  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
+
1001  carry += ((dlimb_t)(*xx++)) * y;
+
1002  *rr++ = (limb_t)carry;
+
1003  carry >>= LIMB_BITS;
+
1004  }
+
1005 
+
1006  // Reduce the value modulo 2^521 - 1. The high half is only a
+
1007  // single limb, so we can short-cut some of reduce() here.
+
1008 #if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
+
1009  limb_t word = result[NUM_LIMBS_521BIT - 1];
+
1010  carry = (word >> 9) + 1;
+
1011  word &= 0x1FF;
+
1012  rr = result;
+
1013  for (index = 0; index < (NUM_LIMBS_521BIT - 1); ++index) {
+
1014  carry += *rr;
+
1015  *rr++ = (limb_t)carry;
+
1016  carry >>= LIMB_BITS;
+
1017  }
+
1018  carry += word;
+
1019  word = (limb_t)carry;
+
1020  *rr = word;
+
1021 
+
1022  // If the carry out was 1, then mask it off and we have the answer.
+
1023  // If the carry out was 0, then we need to add 2^521 - 1 back again.
+
1024  // To preserve the timing we perform a conditional subtract of 1 and
+
1025  // then mask off the high bits.
+
1026  carry = ((word >> 9) ^ 0x01) & 0x01;
+
1027  rr = result;
+
1028  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
+
1029  carry = ((dlimb_t)(*rr)) - carry;
+
1030  *rr++ = (limb_t)carry;
+
1031  carry = (carry >> LIMB_BITS) & 0x01;
+
1032  }
+
1033  *(--rr) &= 0x1FF;
+
1034 #elif BIGNUMBER_LIMB_8BIT
+
1035  // Same as above, but for 8-bit limbs.
+
1036  limb_t word = result[NUM_LIMBS_521BIT - 1];
+
1037  carry = (word >> 1) + 1;
+
1038  word &= 0x01;
+
1039  rr = result;
+
1040  for (index = 0; index < (NUM_LIMBS_521BIT - 1); ++index) {
+
1041  carry += *rr;
+
1042  *rr++ = (limb_t)carry;
+
1043  carry >>= LIMB_BITS;
+
1044  }
+
1045  carry += word;
+
1046  word = (limb_t)carry;
+
1047  *rr = word;
+
1048  carry = ((word >> 1) ^ 0x01) & 0x01;
+
1049  rr = result;
+
1050  for (index = 0; index < NUM_LIMBS_521BIT; ++index) {
+
1051  carry = ((dlimb_t)(*rr)) - carry;
+
1052  *rr++ = (limb_t)carry;
+
1053  carry = (carry >> LIMB_BITS) & 0x01;
+
1054  }
+
1055  *(--rr) &= 0x01;
+
1056 #endif
+
1057 }
+
1058 
+
1069 void P521::add(limb_t *result, const limb_t *x, const limb_t *y)
+
1070 {
+
1071  dlimb_t carry = 0;
+
1072  limb_t *rr = result;
+
1073  for (uint8_t posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
+
1074  carry += *x++;
+
1075  carry += *y++;
+
1076  *rr++ = (limb_t)carry;
+
1077  carry >>= LIMB_BITS;
+
1078  }
+
1079  reduceQuick(result);
+
1080 }
+
1081 
+
1092 void P521::sub(limb_t *result, const limb_t *x, const limb_t *y)
+
1093 {
+
1094  dlimb_t borrow;
+
1095  uint8_t posn;
+
1096  limb_t *rr = result;
+
1097 
+
1098  // Subtract y from x to generate the intermediate result.
+
1099  borrow = 0;
+
1100  for (posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
+
1101  borrow = ((dlimb_t)(*x++)) - (*y++) - ((borrow >> LIMB_BITS) & 0x01);
+
1102  *rr++ = (limb_t)borrow;
+
1103  }
+
1104 
+
1105  // If we had a borrow, then the result has gone negative and we
+
1106  // have to add 2^521 - 1 to the result to make it positive again.
+
1107  // The top bits of "borrow" will be all 1's if there is a borrow
+
1108  // or it will be all 0's if there was no borrow. Easiest is to
+
1109  // conditionally subtract 1 and then mask off the high bits.
+
1110  rr = result;
+
1111  borrow = (borrow >> LIMB_BITS) & 1U;
+
1112  borrow = ((dlimb_t)(*rr)) - borrow;
+
1113  *rr++ = (limb_t)borrow;
+
1114  for (posn = 1; posn < NUM_LIMBS_521BIT; ++posn) {
+
1115  borrow = ((dlimb_t)(*rr)) - ((borrow >> LIMB_BITS) & 0x01);
+
1116  *rr++ = (limb_t)borrow;
+
1117  }
+
1118 #if BIGNUMBER_LIMB_8BIT
+
1119  *(--rr) &= 0x01;
+
1120 #else
+
1121  *(--rr) &= 0x1FF;
+
1122 #endif
+
1123 }
+
1124 
+
1140 void P521::dblPoint(limb_t *xout, limb_t *yout, limb_t *zout,
+
1141  const limb_t *xin, const limb_t *yin,
+
1142  const limb_t *zin)
+
1143 {
+
1144  limb_t alpha[NUM_LIMBS_521BIT];
+
1145  limb_t beta[NUM_LIMBS_521BIT];
+
1146  limb_t gamma[NUM_LIMBS_521BIT];
+
1147  limb_t delta[NUM_LIMBS_521BIT];
+
1148  limb_t tmp[NUM_LIMBS_521BIT];
+
1149 
+
1150  // Double the point. If it is the point at infinity (z = 0),
+
1151  // then zout will still be zero at the end of this process so
+
1152  // we don't need any special handling for that case.
+
1153  square(delta, zin); // delta = z^2
+
1154  square(gamma, yin); // gamma = y^2
+
1155  mul(beta, xin, gamma); // beta = x * gamma
+
1156  sub(tmp, xin, delta); // alpha = 3 * (x - delta) * (x + delta)
+
1157  mulLiteral(alpha, tmp, 3);
+
1158  add(tmp, xin, delta);
+
1159  mul(alpha, alpha, tmp);
+
1160  square(xout, alpha); // xout = alpha^2 - 8 * beta
+
1161  mulLiteral(tmp, beta, 8);
+
1162  sub(xout, xout, tmp);
+
1163  add(zout, yin, zin); // zout = (y + z)^2 - gamma - delta
+
1164  square(zout, zout);
+
1165  sub(zout, zout, gamma);
+
1166  sub(zout, zout, delta);
+
1167  mulLiteral(yout, beta, 4);// yout = alpha * (4 * beta - xout) - 8 * gamma^2
+
1168  sub(yout, yout, xout);
+
1169  mul(yout, alpha, yout);
+
1170  square(gamma, gamma);
+
1171  mulLiteral(gamma, gamma, 8);
+
1172  sub(yout, yout, gamma);
+
1173 
+
1174  // Clean up.
+
1175  strict_clean(alpha);
+
1176  strict_clean(beta);
+
1177  strict_clean(gamma);
+
1178  strict_clean(delta);
+
1179  strict_clean(tmp);
+
1180 }
+
1181 
+
1201 void P521::addPoint(limb_t *xout, limb_t *yout, limb_t *zout,
+
1202  const limb_t *x1, const limb_t *y1,
+
1203  const limb_t *z1, const limb_t *x2,
+
1204  const limb_t *y2)
+
1205 {
+
1206  limb_t z1z1[NUM_LIMBS_521BIT];
+
1207  limb_t u2[NUM_LIMBS_521BIT];
+
1208  limb_t s2[NUM_LIMBS_521BIT];
+
1209  limb_t h[NUM_LIMBS_521BIT];
+
1210  limb_t i[NUM_LIMBS_521BIT];
+
1211  limb_t j[NUM_LIMBS_521BIT];
+
1212  limb_t r[NUM_LIMBS_521BIT];
+
1213  limb_t v[NUM_LIMBS_521BIT];
+
1214 
+
1215  // Determine if the first value is the point-at-infinity identity element.
+
1216  // The second z value is always 1 so it cannot be the point-at-infinity.
+
1217  limb_t p1IsIdentity = BigNumberUtil::isZero(z1, NUM_LIMBS_521BIT);
+
1218 
+
1219  // Multiply the points, assuming that z2 = 1.
+
1220  square(z1z1, z1); // z1z1 = z1^2
+
1221  mul(u2, x2, z1z1); // u2 = x2 * z1z1
+
1222  mul(s2, y2, z1); // s2 = y2 * z1 * z1z1
+
1223  mul(s2, s2, z1z1);
+
1224  sub(h, u2, x1); // h = u2 - x1
+
1225  mulLiteral(i, h, 2); // i = (2 * h)^2
+
1226  square(i, i);
+
1227  sub(r, s2, y1); // r = 2 * (s2 - y1)
+
1228  add(r, r, r);
+
1229  mul(j, h, i); // j = h * i
+
1230  mul(v, x1, i); // v = x1 * i
+
1231  square(xout, r); // xout = r^2 - j - 2 * v
+
1232  sub(xout, xout, j);
1233  sub(xout, xout, v);
-
1234  sub(yout, v, xout); // yout = r * (v - xout) - 2 * y1 * j
-
1235  mul(yout, r, yout);
-
1236  mul(j, y1, j);
-
1237  sub(yout, yout, j);
+
1234  sub(xout, xout, v);
+
1235  sub(yout, v, xout); // yout = r * (v - xout) - 2 * y1 * j
+
1236  mul(yout, r, yout);
+
1237  mul(j, y1, j);
1238  sub(yout, yout, j);
-
1239  mul(zout, z1, h); // zout = 2 * z1 * h
-
1240  add(zout, zout, zout);
-
1241 
-
1242  // Select the answer to return. If (x1, y1, z1) was the identity,
-
1243  // then the answer is (x2, y2, z2). Otherwise it is (xout, yout, zout).
-
1244  // Conditionally move the second argument over the output if necessary.
-
1245  cmove(p1IsIdentity, xout, x2);
-
1246  cmove(p1IsIdentity, yout, y2);
-
1247  cmove1(p1IsIdentity, zout); // z2 = 1
-
1248 
-
1249  // Clean up.
-
1250  strict_clean(z1z1);
-
1251  strict_clean(u2);
-
1252  strict_clean(s2);
-
1253  strict_clean(h);
-
1254  strict_clean(i);
-
1255  strict_clean(j);
-
1256  strict_clean(r);
-
1257  strict_clean(v);
-
1258 }
-
1259 
-
1272 void P521::cmove(limb_t select, limb_t *x, const limb_t *y)
-
1273 {
-
1274  uint8_t posn;
-
1275  limb_t dummy;
-
1276  limb_t sel;
-
1277 
-
1278  // Turn "select" into an all-zeroes or all-ones mask. We don't care
-
1279  // which bit or bits is set in the original "select" value.
-
1280  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
-
1281  --sel;
-
1282 
-
1283  // Move y into x based on "select".
-
1284  for (posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
-
1285  dummy = sel & (*x ^ *y++);
-
1286  *x++ ^= dummy;
-
1287  }
-
1288 }
-
1289 
-
1301 void P521::cmove1(limb_t select, limb_t *x)
-
1302 {
-
1303  uint8_t posn;
-
1304  limb_t dummy;
-
1305  limb_t sel;
-
1306 
-
1307  // Turn "select" into an all-zeroes or all-ones mask. We don't care
-
1308  // which bit or bits is set in the original "select" value.
-
1309  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
-
1310  --sel;
-
1311 
-
1312  // Move 1 into x based on "select".
-
1313  dummy = sel & (*x ^ 1);
-
1314  *x++ ^= dummy;
-
1315  for (posn = 1; posn < NUM_LIMBS_521BIT; ++posn) {
-
1316  dummy = sel & *x;
-
1317  *x++ ^= dummy;
-
1318  }
-
1319 }
-
1320 
-
1329 void P521::recip(limb_t *result, const limb_t *x)
-
1330 {
-
1331  limb_t t1[NUM_LIMBS_521BIT];
-
1332 
-
1333  // The reciprocal is the same as x ^ (p - 2) where p = 2^521 - 1.
-
1334  // The big-endian hexadecimal expansion of (p - 2) is:
-
1335  // 01FF FFFFFFF FFFFFFFF ... FFFFFFFF FFFFFFFD
-
1336  //
-
1337  // The naive implementation needs to do 2 multiplications per 1 bit and
-
1338  // 1 multiplication per 0 bit. We can improve upon this by creating a
-
1339  // pattern 1111 and then shifting and multiplying to create 11111111,
-
1340  // and then 1111111111111111, and so on for the top 512-bits.
-
1341 
-
1342  // Build a 4-bit pattern 1111 in the result.
-
1343  square(result, x);
-
1344  mul(result, result, x);
-
1345  square(result, result);
-
1346  mul(result, result, x);
-
1347  square(result, result);
-
1348  mul(result, result, x);
-
1349 
-
1350  // Shift and multiply by increasing powers of two. This turns
-
1351  // 1111 into 11111111, and then 1111111111111111, and so on.
-
1352  for (size_t power = 4; power <= 256; power <<= 1) {
-
1353  square(t1, result);
-
1354  for (size_t temp = 1; temp < power; ++temp)
-
1355  square(t1, t1);
-
1356  mul(result, result, t1);
-
1357  }
-
1358 
-
1359  // Handle the 9 lowest bits of (p - 2), 111111101, from highest to lowest.
-
1360  for (uint8_t index = 0; index < 7; ++index) {
-
1361  square(result, result);
-
1362  mul(result, result, x);
-
1363  }
-
1364  square(result, result);
+
1239  sub(yout, yout, j);
+
1240  mul(zout, z1, h); // zout = 2 * z1 * h
+
1241  add(zout, zout, zout);
+
1242 
+
1243  // Select the answer to return. If (x1, y1, z1) was the identity,
+
1244  // then the answer is (x2, y2, z2). Otherwise it is (xout, yout, zout).
+
1245  // Conditionally move the second argument over the output if necessary.
+
1246  cmove(p1IsIdentity, xout, x2);
+
1247  cmove(p1IsIdentity, yout, y2);
+
1248  cmove1(p1IsIdentity, zout); // z2 = 1
+
1249 
+
1250  // Clean up.
+
1251  strict_clean(z1z1);
+
1252  strict_clean(u2);
+
1253  strict_clean(s2);
+
1254  strict_clean(h);
+
1255  strict_clean(i);
+
1256  strict_clean(j);
+
1257  strict_clean(r);
+
1258  strict_clean(v);
+
1259 }
+
1260 
+
1273 void P521::cmove(limb_t select, limb_t *x, const limb_t *y)
+
1274 {
+
1275  uint8_t posn;
+
1276  limb_t dummy;
+
1277  limb_t sel;
+
1278 
+
1279  // Turn "select" into an all-zeroes or all-ones mask. We don't care
+
1280  // which bit or bits is set in the original "select" value.
+
1281  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
+
1282  --sel;
+
1283 
+
1284  // Move y into x based on "select".
+
1285  for (posn = 0; posn < NUM_LIMBS_521BIT; ++posn) {
+
1286  dummy = sel & (*x ^ *y++);
+
1287  *x++ ^= dummy;
+
1288  }
+
1289 }
+
1290 
+
1302 void P521::cmove1(limb_t select, limb_t *x)
+
1303 {
+
1304  uint8_t posn;
+
1305  limb_t dummy;
+
1306  limb_t sel;
+
1307 
+
1308  // Turn "select" into an all-zeroes or all-ones mask. We don't care
+
1309  // which bit or bits is set in the original "select" value.
+
1310  sel = (limb_t)(((((dlimb_t)1) << LIMB_BITS) - select) >> LIMB_BITS);
+
1311  --sel;
+
1312 
+
1313  // Move 1 into x based on "select".
+
1314  dummy = sel & (*x ^ 1);
+
1315  *x++ ^= dummy;
+
1316  for (posn = 1; posn < NUM_LIMBS_521BIT; ++posn) {
+
1317  dummy = sel & *x;
+
1318  *x++ ^= dummy;
+
1319  }
+
1320 }
+
1321 
+
1330 void P521::recip(limb_t *result, const limb_t *x)
+
1331 {
+
1332  limb_t t1[NUM_LIMBS_521BIT];
+
1333 
+
1334  // The reciprocal is the same as x ^ (p - 2) where p = 2^521 - 1.
+
1335  // The big-endian hexadecimal expansion of (p - 2) is:
+
1336  // 01FF FFFFFFF FFFFFFFF ... FFFFFFFF FFFFFFFD
+
1337  //
+
1338  // The naive implementation needs to do 2 multiplications per 1 bit and
+
1339  // 1 multiplication per 0 bit. We can improve upon this by creating a
+
1340  // pattern 1111 and then shifting and multiplying to create 11111111,
+
1341  // and then 1111111111111111, and so on for the top 512-bits.
+
1342 
+
1343  // Build a 4-bit pattern 1111 in the result.
+
1344  square(result, x);
+
1345  mul(result, result, x);
+
1346  square(result, result);
+
1347  mul(result, result, x);
+
1348  square(result, result);
+
1349  mul(result, result, x);
+
1350 
+
1351  // Shift and multiply by increasing powers of two. This turns
+
1352  // 1111 into 11111111, and then 1111111111111111, and so on.
+
1353  for (size_t power = 4; power <= 256; power <<= 1) {
+
1354  square(t1, result);
+
1355  for (size_t temp = 1; temp < power; ++temp)
+
1356  square(t1, t1);
+
1357  mul(result, result, t1);
+
1358  }
+
1359 
+
1360  // Handle the 9 lowest bits of (p - 2), 111111101, from highest to lowest.
+
1361  for (uint8_t index = 0; index < 7; ++index) {
+
1362  square(result, result);
+
1363  mul(result, result, x);
+
1364  }
1365  square(result, result);
-
1366  mul(result, result, x);
-
1367 
-
1368  // Clean up.
-
1369  clean(t1);
-
1370 }
-
1371 
-
1380 void P521::reduceQ(limb_t *result, const limb_t *r)
-
1381 {
-
1382  // Algorithm from: http://en.wikipedia.org/wiki/Barrett_reduction
-
1383  //
-
1384  // We assume that r is less than or equal to (q - 1)^2.
-
1385  //
-
1386  // We want to compute result = r mod q. Find the smallest k such
-
1387  // that 2^k > q. In our case, k = 521. Then set m = floor(4^k / q)
-
1388  // and let r = r - q * floor(m * r / 4^k). This will be the result
-
1389  // or it will be at most one subtraction of q away from the result.
-
1390  //
-
1391  // Note: m is a 522-bit number, which fits in the same number of limbs
-
1392  // as a 521-bit number assuming that limbs are 8 bits or more in size.
-
1393  static limb_t const numM[NUM_LIMBS_521BIT] PROGMEM = {
-
1394  LIMB_PAIR(0x6EC79BF7, 0x449048E1), LIMB_PAIR(0x7663B851, 0xC44A3647),
-
1395  LIMB_PAIR(0x08F65A2F, 0x8033FEB7), LIMB_PAIR(0x40D06994, 0xAE79787C),
-
1396  LIMB_PAIR(0x00000005, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000),
-
1397  LIMB_PAIR(0x00000000, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000),
-
1398  LIMB_PARTIAL(0x200)
-
1399  };
-
1400  limb_t temp[NUM_LIMBS_1042BIT + NUM_LIMBS_521BIT];
-
1401  limb_t temp2[NUM_LIMBS_521BIT];
-
1402 
-
1403  // Multiply r by m.
-
1404  BigNumberUtil::mul_P(temp, r, NUM_LIMBS_1042BIT, numM, NUM_LIMBS_521BIT);
-
1405 
-
1406  // Compute (m * r / 4^521) = (m * r / 2^1042).
-
1407 #if BIGNUMBER_LIMB_8BIT || BIGNUMBER_LIMB_16BIT
-
1408  dlimb_t carry = temp[NUM_LIMBS_BITS(1040)] >> 2;
-
1409  for (uint8_t index = 0; index < NUM_LIMBS_521BIT; ++index) {
-
1410  carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1040) + index + 1])) << (LIMB_BITS - 2);
-
1411  temp2[index] = (limb_t)carry;
-
1412  carry >>= LIMB_BITS;
-
1413  }
-
1414 #elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
-
1415  dlimb_t carry = temp[NUM_LIMBS_BITS(1024)] >> 18;
-
1416  for (uint8_t index = 0; index < NUM_LIMBS_521BIT; ++index) {
-
1417  carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1024) + index + 1])) << (LIMB_BITS - 18);
-
1418  temp2[index] = (limb_t)carry;
-
1419  carry >>= LIMB_BITS;
-
1420  }
-
1421 #endif
-
1422 
-
1423  // Multiply (m * r) / 2^1042 by q and subtract it from r.
-
1424  // We can ignore the high words of the subtraction result
-
1425  // because they will all turn into zero after the subtraction.
-
1426  BigNumberUtil::mul_P(temp, temp2, NUM_LIMBS_521BIT,
-
1427  P521_q, NUM_LIMBS_521BIT);
-
1428  BigNumberUtil::sub(result, r, temp, NUM_LIMBS_521BIT);
-
1429 
-
1430  // Perform a trial subtraction of q from the result to reduce it.
-
1431  BigNumberUtil::reduceQuick_P(result, result, P521_q, NUM_LIMBS_521BIT);
-
1432 
-
1433  // Clean up and exit.
-
1434  clean(temp);
-
1435  clean(temp2);
-
1436 }
-
1437 
-
1448 void P521::mulQ(limb_t *result, const limb_t *x, const limb_t *y)
-
1449 {
-
1450  limb_t temp[NUM_LIMBS_1042BIT];
-
1451  mulNoReduce(temp, x, y);
-
1452  reduceQ(result, temp);
-
1453  strict_clean(temp);
-
1454 }
-
1455 
-
1464 void P521::recipQ(limb_t *result, const limb_t *x)
-
1465 {
-
1466  // Bottom 265 bits of q - 2. The top 256 bits are all-1's.
-
1467  static limb_t const P521_q_m2[] PROGMEM = {
-
1468  LIMB_PAIR(0x91386407, 0xbb6fb71e), LIMB_PAIR(0x899c47ae, 0x3bb5c9b8),
-
1469  LIMB_PAIR(0xf709a5d0, 0x7fcc0148), LIMB_PAIR(0xbf2f966b, 0x51868783),
-
1470  LIMB_PARTIAL(0x1fa)
-
1471  };
-
1472 
-
1473  // Raise x to the power of q - 2, mod q. We start with the top
-
1474  // 256 bits which are all-1's, using a similar technique to recip().
-
1475  limb_t t1[NUM_LIMBS_521BIT];
-
1476  mulQ(result, x, x);
-
1477  mulQ(result, result, x);
-
1478  mulQ(result, result, result);
-
1479  mulQ(result, result, x);
-
1480  mulQ(result, result, result);
-
1481  mulQ(result, result, x);
-
1482  for (size_t power = 4; power <= 128; power <<= 1) {
-
1483  mulQ(t1, result, result);
-
1484  for (size_t temp = 1; temp < power; ++temp)
-
1485  mulQ(t1, t1, t1);
-
1486  mulQ(result, result, t1);
-
1487  }
-
1488  clean(t1);
-
1489 
-
1490  // Deal with the bottom 265 bits from highest to lowest. Square for
-
1491  // each bit and multiply in x whenever there is a 1 bit. The timing
-
1492  // is based on the publicly-known constant q - 2, not on the value of x.
-
1493  size_t bit = 265;
-
1494  while (bit > 0) {
-
1495  --bit;
-
1496  mulQ(result, result, result);
-
1497  if (pgm_read_limb(&(P521_q_m2[bit / LIMB_BITS])) &
-
1498  (((limb_t)1) << (bit % LIMB_BITS))) {
-
1499  mulQ(result, result, x);
-
1500  }
-
1501  }
-
1502 }
-
1503 
-
1514 void P521::generateK(uint8_t k[66], const uint8_t hm[66],
-
1515  const uint8_t x[66], Hash *hash, uint64_t count)
-
1516 {
-
1517  size_t hlen = hash->hashSize();
-
1518  uint8_t V[64];
-
1519  uint8_t K[64];
-
1520  uint8_t marker;
-
1521 
-
1522  // If for some reason a hash function was supplied with more than
-
1523  // 512 bits of output, truncate hash values to the first 512 bits.
-
1524  // We cannot support more than this yet.
-
1525  if (hlen > 64)
-
1526  hlen = 64;
-
1527 
-
1528  // RFC 6979, Section 3.2, Step a. Hash the message, reduce modulo q,
-
1529  // and produce an octet string the same length as q, bits2octets(H(m)).
-
1530  // We support hashes up to 512 bits and q is a 521-bit number, so "hm"
-
1531  // is already the bits2octets(H(m)) value that we need.
-
1532 
-
1533  // Steps b and c. Set V to all-ones and K to all-zeroes.
-
1534  memset(V, 0x01, hlen);
-
1535  memset(K, 0x00, hlen);
-
1536 
-
1537  // Step d. K = HMAC_K(V || 0x00 || x || hm). We make a small
-
1538  // modification here to append the count value if it is non-zero.
-
1539  // We use this to generate a new k if we have to re-enter this
-
1540  // function because the previous one was rejected by sign().
-
1541  // This is slightly different to RFC 6979 which says that the
-
1542  // loop in step h below should be continued. That code path is
-
1543  // difficult to access, so instead modify K and V in steps d and f.
-
1544  // This alternative construction is compatible with the second
-
1545  // variant described in section 3.6 of RFC 6979.
-
1546  hash->resetHMAC(K, hlen);
-
1547  hash->update(V, hlen);
-
1548  marker = 0x00;
-
1549  hash->update(&marker, 1);
-
1550  hash->update(x, 66);
-
1551  hash->update(hm, 66);
-
1552  if (count)
-
1553  hash->update(&count, sizeof(count));
-
1554  hash->finalizeHMAC(K, hlen, K, hlen);
-
1555 
-
1556  // Step e. V = HMAC_K(V)
-
1557  hash->resetHMAC(K, hlen);
-
1558  hash->update(V, hlen);
-
1559  hash->finalizeHMAC(K, hlen, V, hlen);
-
1560 
-
1561  // Step f. K = HMAC_K(V || 0x01 || x || hm)
-
1562  hash->resetHMAC(K, hlen);
-
1563  hash->update(V, hlen);
-
1564  marker = 0x01;
-
1565  hash->update(&marker, 1);
-
1566  hash->update(x, 66);
-
1567  hash->update(hm, 66);
-
1568  if (count)
-
1569  hash->update(&count, sizeof(count));
-
1570  hash->finalizeHMAC(K, hlen, K, hlen);
-
1571 
-
1572  // Step g. V = HMAC_K(V)
-
1573  hash->resetHMAC(K, hlen);
-
1574  hash->update(V, hlen);
-
1575  hash->finalizeHMAC(K, hlen, V, hlen);
-
1576 
-
1577  // Step h. Generate candidate k values until we find what we want.
-
1578  for (;;) {
-
1579  // Step h.1 and h.2. Generate a string of 66 bytes in length.
-
1580  // T = empty
-
1581  // while (len(T) < 66)
-
1582  // V = HMAC_K(V)
-
1583  // T = T || V
-
1584  size_t posn = 0;
-
1585  while (posn < 66) {
-
1586  size_t temp = 66 - posn;
-
1587  if (temp > hlen)
-
1588  temp = hlen;
-
1589  hash->resetHMAC(K, hlen);
-
1590  hash->update(V, hlen);
-
1591  hash->finalizeHMAC(K, hlen, V, hlen);
-
1592  memcpy(k + posn, V, temp);
-
1593  posn += temp;
-
1594  }
-
1595 
-
1596  // Step h.3. k = bits2int(T) and exit the loop if k is not in
-
1597  // the range 1 to q - 1. Note: We have to extract the 521 most
-
1598  // significant bits of T, which means shifting it right by seven
-
1599  // bits to put it into the correct form.
-
1600  for (posn = 65; posn > 0; --posn)
-
1601  k[posn] = (k[posn - 1] << 1) | (k[posn] >> 7);
-
1602  k[0] >>= 7;
-
1603  if (isValidPrivateKey(k))
-
1604  break;
-
1605 
-
1606  // Generate new K and V values and try again.
-
1607  // K = HMAC_K(V || 0x00)
-
1608  // V = HMAC_K(V)
-
1609  hash->resetHMAC(K, hlen);
-
1610  hash->update(V, hlen);
-
1611  marker = 0x00;
-
1612  hash->update(&marker, 1);
-
1613  hash->finalizeHMAC(K, hlen, K, hlen);
-
1614  hash->resetHMAC(K, hlen);
-
1615  hash->update(V, hlen);
-
1616  hash->finalizeHMAC(K, hlen, V, hlen);
-
1617  }
-
1618 
-
1619  // Clean up.
-
1620  clean(V);
-
1621  clean(K);
-
1622 }
-
1623 
-
1636 void P521::generateK(uint8_t k[66], const uint8_t hm[66],
-
1637  const uint8_t x[66], uint64_t count)
-
1638 {
-
1639  SHA512 hash;
-
1640  generateK(k, hm, x, &hash, count);
-
1641 }
+
1366  square(result, result);
+
1367  mul(result, result, x);
+
1368 
+
1369  // Clean up.
+
1370  clean(t1);
+
1371 }
+
1372 
+
1381 void P521::reduceQ(limb_t *result, const limb_t *r)
+
1382 {
+
1383  // Algorithm from: http://en.wikipedia.org/wiki/Barrett_reduction
+
1384  //
+
1385  // We assume that r is less than or equal to (q - 1)^2.
+
1386  //
+
1387  // We want to compute result = r mod q. Find the smallest k such
+
1388  // that 2^k > q. In our case, k = 521. Then set m = floor(4^k / q)
+
1389  // and let r = r - q * floor(m * r / 4^k). This will be the result
+
1390  // or it will be at most one subtraction of q away from the result.
+
1391  //
+
1392  // Note: m is a 522-bit number, which fits in the same number of limbs
+
1393  // as a 521-bit number assuming that limbs are 8 bits or more in size.
+
1394  static limb_t const numM[NUM_LIMBS_521BIT] PROGMEM = {
+
1395  LIMB_PAIR(0x6EC79BF7, 0x449048E1), LIMB_PAIR(0x7663B851, 0xC44A3647),
+
1396  LIMB_PAIR(0x08F65A2F, 0x8033FEB7), LIMB_PAIR(0x40D06994, 0xAE79787C),
+
1397  LIMB_PAIR(0x00000005, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000),
+
1398  LIMB_PAIR(0x00000000, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000),
+
1399  LIMB_PARTIAL(0x200)
+
1400  };
+
1401  limb_t temp[NUM_LIMBS_1042BIT + NUM_LIMBS_521BIT];
+
1402  limb_t temp2[NUM_LIMBS_521BIT];
+
1403 
+
1404  // Multiply r by m.
+
1405  BigNumberUtil::mul_P(temp, r, NUM_LIMBS_1042BIT, numM, NUM_LIMBS_521BIT);
+
1406 
+
1407  // Compute (m * r / 4^521) = (m * r / 2^1042).
+
1408 #if BIGNUMBER_LIMB_8BIT || BIGNUMBER_LIMB_16BIT
+
1409  dlimb_t carry = temp[NUM_LIMBS_BITS(1040)] >> 2;
+
1410  for (uint8_t index = 0; index < NUM_LIMBS_521BIT; ++index) {
+
1411  carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1040) + index + 1])) << (LIMB_BITS - 2);
+
1412  temp2[index] = (limb_t)carry;
+
1413  carry >>= LIMB_BITS;
+
1414  }
+
1415 #elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT
+
1416  dlimb_t carry = temp[NUM_LIMBS_BITS(1024)] >> 18;
+
1417  for (uint8_t index = 0; index < NUM_LIMBS_521BIT; ++index) {
+
1418  carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1024) + index + 1])) << (LIMB_BITS - 18);
+
1419  temp2[index] = (limb_t)carry;
+
1420  carry >>= LIMB_BITS;
+
1421  }
+
1422 #endif
+
1423 
+
1424  // Multiply (m * r) / 2^1042 by q and subtract it from r.
+
1425  // We can ignore the high words of the subtraction result
+
1426  // because they will all turn into zero after the subtraction.
+
1427  BigNumberUtil::mul_P(temp, temp2, NUM_LIMBS_521BIT,
+
1428  P521_q, NUM_LIMBS_521BIT);
+
1429  BigNumberUtil::sub(result, r, temp, NUM_LIMBS_521BIT);
+
1430 
+
1431  // Perform a trial subtraction of q from the result to reduce it.
+
1432  BigNumberUtil::reduceQuick_P(result, result, P521_q, NUM_LIMBS_521BIT);
+
1433 
+
1434  // Clean up and exit.
+
1435  clean(temp);
+
1436  clean(temp2);
+
1437 }
+
1438 
+
1449 void P521::mulQ(limb_t *result, const limb_t *x, const limb_t *y)
+
1450 {
+
1451  limb_t temp[NUM_LIMBS_1042BIT];
+
1452  mulNoReduce(temp, x, y);
+
1453  reduceQ(result, temp);
+
1454  strict_clean(temp);
+
1455 }
+
1456 
+
1465 void P521::recipQ(limb_t *result, const limb_t *x)
+
1466 {
+
1467  // Bottom 265 bits of q - 2. The top 256 bits are all-1's.
+
1468  static limb_t const P521_q_m2[] PROGMEM = {
+
1469  LIMB_PAIR(0x91386407, 0xbb6fb71e), LIMB_PAIR(0x899c47ae, 0x3bb5c9b8),
+
1470  LIMB_PAIR(0xf709a5d0, 0x7fcc0148), LIMB_PAIR(0xbf2f966b, 0x51868783),
+
1471  LIMB_PARTIAL(0x1fa)
+
1472  };
+
1473 
+
1474  // Raise x to the power of q - 2, mod q. We start with the top
+
1475  // 256 bits which are all-1's, using a similar technique to recip().
+
1476  limb_t t1[NUM_LIMBS_521BIT];
+
1477  mulQ(result, x, x);
+
1478  mulQ(result, result, x);
+
1479  mulQ(result, result, result);
+
1480  mulQ(result, result, x);
+
1481  mulQ(result, result, result);
+
1482  mulQ(result, result, x);
+
1483  for (size_t power = 4; power <= 128; power <<= 1) {
+
1484  mulQ(t1, result, result);
+
1485  for (size_t temp = 1; temp < power; ++temp)
+
1486  mulQ(t1, t1, t1);
+
1487  mulQ(result, result, t1);
+
1488  }
+
1489  clean(t1);
+
1490 
+
1491  // Deal with the bottom 265 bits from highest to lowest. Square for
+
1492  // each bit and multiply in x whenever there is a 1 bit. The timing
+
1493  // is based on the publicly-known constant q - 2, not on the value of x.
+
1494  size_t bit = 265;
+
1495  while (bit > 0) {
+
1496  --bit;
+
1497  mulQ(result, result, result);
+
1498  if (pgm_read_limb(&(P521_q_m2[bit / LIMB_BITS])) &
+
1499  (((limb_t)1) << (bit % LIMB_BITS))) {
+
1500  mulQ(result, result, x);
+
1501  }
+
1502  }
+
1503 }
+
1504 
+
1515 void P521::generateK(uint8_t k[66], const uint8_t hm[66],
+
1516  const uint8_t x[66], Hash *hash, uint64_t count)
+
1517 {
+
1518  size_t hlen = hash->hashSize();
+
1519  uint8_t V[64];
+
1520  uint8_t K[64];
+
1521  uint8_t marker;
+
1522 
+
1523  // If for some reason a hash function was supplied with more than
+
1524  // 512 bits of output, truncate hash values to the first 512 bits.
+
1525  // We cannot support more than this yet.
+
1526  if (hlen > 64)
+
1527  hlen = 64;
+
1528 
+
1529  // RFC 6979, Section 3.2, Step a. Hash the message, reduce modulo q,
+
1530  // and produce an octet string the same length as q, bits2octets(H(m)).
+
1531  // We support hashes up to 512 bits and q is a 521-bit number, so "hm"
+
1532  // is already the bits2octets(H(m)) value that we need.
+
1533 
+
1534  // Steps b and c. Set V to all-ones and K to all-zeroes.
+
1535  memset(V, 0x01, hlen);
+
1536  memset(K, 0x00, hlen);
+
1537 
+
1538  // Step d. K = HMAC_K(V || 0x00 || x || hm). We make a small
+
1539  // modification here to append the count value if it is non-zero.
+
1540  // We use this to generate a new k if we have to re-enter this
+
1541  // function because the previous one was rejected by sign().
+
1542  // This is slightly different to RFC 6979 which says that the
+
1543  // loop in step h below should be continued. That code path is
+
1544  // difficult to access, so instead modify K and V in steps d and f.
+
1545  // This alternative construction is compatible with the second
+
1546  // variant described in section 3.6 of RFC 6979.
+
1547  hash->resetHMAC(K, hlen);
+
1548  hash->update(V, hlen);
+
1549  marker = 0x00;
+
1550  hash->update(&marker, 1);
+
1551  hash->update(x, 66);
+
1552  hash->update(hm, 66);
+
1553  if (count)
+
1554  hash->update(&count, sizeof(count));
+
1555  hash->finalizeHMAC(K, hlen, K, hlen);
+
1556 
+
1557  // Step e. V = HMAC_K(V)
+
1558  hash->resetHMAC(K, hlen);
+
1559  hash->update(V, hlen);
+
1560  hash->finalizeHMAC(K, hlen, V, hlen);
+
1561 
+
1562  // Step f. K = HMAC_K(V || 0x01 || x || hm)
+
1563  hash->resetHMAC(K, hlen);
+
1564  hash->update(V, hlen);
+
1565  marker = 0x01;
+
1566  hash->update(&marker, 1);
+
1567  hash->update(x, 66);
+
1568  hash->update(hm, 66);
+
1569  if (count)
+
1570  hash->update(&count, sizeof(count));
+
1571  hash->finalizeHMAC(K, hlen, K, hlen);
+
1572 
+
1573  // Step g. V = HMAC_K(V)
+
1574  hash->resetHMAC(K, hlen);
+
1575  hash->update(V, hlen);
+
1576  hash->finalizeHMAC(K, hlen, V, hlen);
+
1577 
+
1578  // Step h. Generate candidate k values until we find what we want.
+
1579  for (;;) {
+
1580  // Step h.1 and h.2. Generate a string of 66 bytes in length.
+
1581  // T = empty
+
1582  // while (len(T) < 66)
+
1583  // V = HMAC_K(V)
+
1584  // T = T || V
+
1585  size_t posn = 0;
+
1586  while (posn < 66) {
+
1587  size_t temp = 66 - posn;
+
1588  if (temp > hlen)
+
1589  temp = hlen;
+
1590  hash->resetHMAC(K, hlen);
+
1591  hash->update(V, hlen);
+
1592  hash->finalizeHMAC(K, hlen, V, hlen);
+
1593  memcpy(k + posn, V, temp);
+
1594  posn += temp;
+
1595  }
+
1596 
+
1597  // Step h.3. k = bits2int(T) and exit the loop if k is not in
+
1598  // the range 1 to q - 1. Note: We have to extract the 521 most
+
1599  // significant bits of T, which means shifting it right by seven
+
1600  // bits to put it into the correct form.
+
1601  for (posn = 65; posn > 0; --posn)
+
1602  k[posn] = (k[posn - 1] << 1) | (k[posn] >> 7);
+
1603  k[0] >>= 7;
+
1604  if (isValidPrivateKey(k))
+
1605  break;
+
1606 
+
1607  // Generate new K and V values and try again.
+
1608  // K = HMAC_K(V || 0x00)
+
1609  // V = HMAC_K(V)
+
1610  hash->resetHMAC(K, hlen);
+
1611  hash->update(V, hlen);
+
1612  marker = 0x00;
+
1613  hash->update(&marker, 1);
+
1614  hash->finalizeHMAC(K, hlen, K, hlen);
+
1615  hash->resetHMAC(K, hlen);
+
1616  hash->update(V, hlen);
+
1617  hash->finalizeHMAC(K, hlen, V, hlen);
+
1618  }
+
1619 
+
1620  // Clean up.
+
1621  clean(V);
+
1622  clean(K);
+
1623 }
+
1624 
+
1637 void P521::generateK(uint8_t k[66], const uint8_t hm[66],
+
1638  const uint8_t x[66], uint64_t count)
+
1639 {
+
1640  SHA512 hash;
+
1641  generateK(k, hm, x, &hash, count);
+
1642 }
BigNumberUtil::reduceQuick_P
static void reduceQuick_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction where y is in program memory.
Definition: BigNumberUtil.cpp:734
P521::eval
static bool eval(uint8_t result[132], const uint8_t f[66], const uint8_t point[132])
Evaluates the curve function.
Definition: P521.cpp:135
BigNumberUtil::add
static limb_t add(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers.
Definition: BigNumberUtil.cpp:495
P521::generatePrivateKey
static void generatePrivateKey(uint8_t privateKey[66])
Generates a private key for P-521 signing operations.
Definition: P521.cpp:466
BigNumberUtil::sub_P
static limb_t sub_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Subtracts one big number from another where one is in program memory.
Definition: BigNumberUtil.cpp:655
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
P521::dh2
static bool dh2(const uint8_t k[132], uint8_t f[66])
Performs phase 2 of an ECDH key exchange using P-521.
Definition: P521.cpp:229
Hash
Abstract base class for cryptographic hash algorithms.
Definition: Hash.h:29
Hash::finalizeHMAC
virtual void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)=0
Finalizes the HMAC hashing process and returns the hash.
@@ -1333,7 +1334,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/P521_8h_source.html b/P521_8h_source.html index f11f71a7..12e36250 100644 --- a/P521_8h_source.html +++ b/P521_8h_source.html @@ -215,7 +215,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Poly1305_8cpp_source.html b/Poly1305_8cpp_source.html index c686cc7d..be36a73e 100644 --- a/Poly1305_8cpp_source.html +++ b/Poly1305_8cpp_source.html @@ -358,7 +358,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Poly1305_8h_source.html b/Poly1305_8h_source.html index 9fe6fd32..bfcf940a 100644 --- a/Poly1305_8h_source.html +++ b/Poly1305_8h_source.html @@ -153,7 +153,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/PowerSave_8cpp_source.html b/PowerSave_8cpp_source.html index 370ea20e..12272f5d 100644 --- a/PowerSave_8cpp_source.html +++ b/PowerSave_8cpp_source.html @@ -155,7 +155,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/PowerSave_8h_source.html b/PowerSave_8h_source.html index c1279921..bd1b1f53 100644 --- a/PowerSave_8h_source.html +++ b/PowerSave_8h_source.html @@ -158,7 +158,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/RC5_8h_source.html b/RC5_8h_source.html index c5e8db50..8c70e5e9 100644 --- a/RC5_8h_source.html +++ b/RC5_8h_source.html @@ -435,7 +435,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/RNG_8cpp_source.html b/RNG_8cpp_source.html index 7ea2b855..ad6ecdd4 100644 --- a/RNG_8cpp_source.html +++ b/RNG_8cpp_source.html @@ -127,548 +127,696 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
37 #include <avr/wdt.h>
38 #include <avr/io.h>
39 #define RNG_EEPROM_ADDRESS (E2END + 1 - RNGClass::SEED_SIZE)
-
40 #endif
-
41 #include <string.h>
-
42 
-
136 RNGClass RNG;
-
137 
-
146 // Number of ChaCha hash rounds to use for random number generation.
-
147 #define RNG_ROUNDS 20
-
148 
-
149 // Force a rekey after this many blocks of random data.
-
150 #define RNG_REKEY_BLOCKS 16
-
151 
-
152 // Maximum entropy credit that can be contained in the pool.
-
153 #define RNG_MAX_CREDITS 384
-
154 
-
157 // Imported from Crypto.cpp.
-
158 extern uint8_t crypto_crc8(uint8_t tag, const void *data, unsigned size);
-
159 
-
160 // Tag for 256-bit ChaCha20 keys. This will always appear in the
-
161 // first 16 bytes of the block. The remaining 48 bytes are the seed.
-
162 static const char tagRNG[16] PROGMEM = {
-
163  'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
-
164  '2', '-', 'b', 'y', 't', 'e', ' ', 'k'
-
165 };
-
166 
-
167 // Initialization seed. This is the ChaCha20 output of hashing
-
168 // "expand 32-byte k" followed by 48 bytes set to the numbers 1 to 48.
-
169 // The ChaCha20 output block is then truncated to the first 48 bytes.
-
170 //
-
171 // This value is intended to start the RNG in a semi-chaotic state if
-
172 // we don't have a previously saved seed in EEPROM.
-
173 static const uint8_t initRNG[48] PROGMEM = {
-
174  0xB0, 0x2A, 0xAE, 0x7D, 0xEE, 0xCB, 0xBB, 0xB1,
-
175  0xFC, 0x03, 0x6F, 0xDD, 0xDC, 0x7D, 0x76, 0x67,
-
176  0x0C, 0xE8, 0x1F, 0x0D, 0xA3, 0xA0, 0xAA, 0x1E,
-
177  0xB0, 0xBD, 0x72, 0x6B, 0x2B, 0x4C, 0x8A, 0x7E,
-
178  0x34, 0xFC, 0x37, 0x60, 0xF4, 0x1E, 0x22, 0xA0,
-
179  0x0B, 0xFB, 0x18, 0x84, 0x60, 0xA5, 0x77, 0x72
-
180 };
-
181 
-
182 #if defined(RNG_WATCHDOG)
-
183 
-
184 // Use jitter between the watchdog timer and the main CPU clock to
-
185 // harvest some entropy on AVR-based systems. This technique comes from:
-
186 //
-
187 // https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library
-
188 //
-
189 // The watchdog generates entropy very slowly - it can take around 32 seconds
-
190 // to generate 256 bits of entropy credit. This is a "better than nothing"
-
191 // entropy source but a real noise source is definitely recommended.
-
192 
-
193 // Helper macros for specific 32-bit shift counts.
-
194 #define leftShift3(value) ((value) << 3)
-
195 #define leftShift10(value) ((value) << 10)
-
196 #define leftShift15(value) ((value) << 15)
-
197 #define rightShift6(value) ((value) >> 6)
-
198 #define rightShift11(value) ((value) >> 11)
-
199 
-
200 static uint32_t volatile hash = 0;
-
201 static uint8_t volatile outBits = 0;
-
202 
-
203 // Watchdog interrupt handler. This fires off every 16ms. We collect
-
204 // 32 bits and then pass them off onto RNGClass::loop().
-
205 ISR(WDT_vect)
-
206 {
-
207  // Read the low byte of Timer 1. We assume that the timer was
-
208  // initialized by the Arduino startup code for PWM use or that the
-
209  // application is free-running Timer 1 for its own purposes.
-
210  // Timer 0 is used on systems that don't have a Timer 1.
-
211 #if defined(TCNT1L)
-
212  unsigned char value = TCNT1L;
-
213 #elif defined(TCNT0L)
-
214  unsigned char value = TCNT0L;
-
215 #else
-
216  unsigned char value = TCNT0;
-
217 #endif
-
218  // Use Jenkin's one-at-a-time hash function to scatter the entropy a bit.
-
219  // https://en.wikipedia.org/wiki/Jenkins_hash_function
-
220  hash += value;
-
221  hash += leftShift10(hash);
-
222  hash ^= rightShift6(hash);
-
223  ++outBits;
-
224 }
+
40 #elif defined(ESP8266)
+
41 // ESP8266 does not have EEPROM but it does have SPI flash memory.
+
42 // It also has a TRNG register for generating "true" random numbers.
+
43 // For now we use the TRNG but don't save the seed in flash memory.
+
44 #define RNG_WORD_TRNG 1
+
45 #define RNG_WORD_TRNG_GET() (ESP8266_DREG(0x20E44))
+
46 #elif defined(ESP32)
+
47 // ESP32 has a word-based TRNG and an API for Non-Volatile Storage (NVS).
+
48 #define RNG_WORD_TRNG 1
+
49 #define RNG_WORD_TRNG_GET() (esp_random())
+
50 #define RNG_ESP_NVS 1
+
51 #include <nvs.h>
+
52 #endif
+
53 #include <string.h>
+
54 
+
55 // Throw an error if there is no built-in hardware random number source.
+
56 // If this happens, then you need to do one of two things:
+
57 // 1. Edit RNG.cpp to add your platform's hardware TRNG.
+
58 // 2. Provide a proper noise source like TransistorNoiseSource
+
59 // in your sketch and then comment out the #error line below.
+
60 #if !defined(RNG_DUE_TRNG) && \
+
61  !defined(RNG_WATCHDOG) && \
+
62  !defined(RNG_WORD_TRNG)
+
63 #error "no hardware random number source detected for this platform"
+
64 #endif
+
65 
+
159 RNGClass RNG;
+
160 
+
169 // Number of ChaCha hash rounds to use for random number generation.
+
170 #define RNG_ROUNDS 20
+
171 
+
172 // Force a rekey after this many blocks of random data.
+
173 #define RNG_REKEY_BLOCKS 16
+
174 
+
175 // Maximum entropy credit that can be contained in the pool.
+
176 #define RNG_MAX_CREDITS 384
+
177 
+
180 // Imported from Crypto.cpp.
+
181 extern uint8_t crypto_crc8(uint8_t tag, const void *data, unsigned size);
+
182 
+
183 // Tag for 256-bit ChaCha20 keys. This will always appear in the
+
184 // first 16 bytes of the block. The remaining 48 bytes are the seed.
+
185 static const char tagRNG[16] PROGMEM = {
+
186  'e', 'x', 'p', 'a', 'n', 'd', ' ', '3',
+
187  '2', '-', 'b', 'y', 't', 'e', ' ', 'k'
+
188 };
+
189 
+
190 // Initialization seed. This is the ChaCha20 output of hashing
+
191 // "expand 32-byte k" followed by 48 bytes set to the numbers 1 to 48.
+
192 // The ChaCha20 output block is then truncated to the first 48 bytes.
+
193 //
+
194 // This value is intended to start the RNG in a semi-chaotic state if
+
195 // we don't have a previously saved seed in EEPROM.
+
196 static const uint8_t initRNG[48] PROGMEM = {
+
197  0xB0, 0x2A, 0xAE, 0x7D, 0xEE, 0xCB, 0xBB, 0xB1,
+
198  0xFC, 0x03, 0x6F, 0xDD, 0xDC, 0x7D, 0x76, 0x67,
+
199  0x0C, 0xE8, 0x1F, 0x0D, 0xA3, 0xA0, 0xAA, 0x1E,
+
200  0xB0, 0xBD, 0x72, 0x6B, 0x2B, 0x4C, 0x8A, 0x7E,
+
201  0x34, 0xFC, 0x37, 0x60, 0xF4, 0x1E, 0x22, 0xA0,
+
202  0x0B, 0xFB, 0x18, 0x84, 0x60, 0xA5, 0x77, 0x72
+
203 };
+
204 
+
205 #if defined(RNG_WATCHDOG)
+
206 
+
207 // Use jitter between the watchdog timer and the main CPU clock to
+
208 // harvest some entropy on AVR-based systems. This technique comes from:
+
209 //
+
210 // https://sites.google.com/site/astudyofentropy/project-definition/timer-jitter-entropy-sources/entropy-library
+
211 //
+
212 // The watchdog generates entropy very slowly - it can take around 32 seconds
+
213 // to generate 256 bits of entropy credit. This is a "better than nothing"
+
214 // entropy source but a real noise source is definitely recommended.
+
215 
+
216 // Helper macros for specific 32-bit shift counts.
+
217 #define leftShift3(value) ((value) << 3)
+
218 #define leftShift10(value) ((value) << 10)
+
219 #define leftShift15(value) ((value) << 15)
+
220 #define rightShift6(value) ((value) >> 6)
+
221 #define rightShift11(value) ((value) >> 11)
+
222 
+
223 static uint32_t volatile hash = 0;
+
224 static uint8_t volatile outBits = 0;
225 
-
226 #endif // RNG_WATCHDOG
-
227 
-
238 RNGClass::RNGClass()
-
239  : credits(0)
-
240  , firstSave(1)
-
241  , timer(0)
-
242  , timeout(3600000UL) // 1 hour in milliseconds
-
243  , count(0)
-
244  , trngPosn(0)
-
245 {
-
246 }
-
247 
-
251 RNGClass::~RNGClass()
-
252 {
-
253 #if defined(RNG_DUE_TRNG)
-
254  // Disable the TRNG in the Arduino Due.
-
255  REG_TRNG_CR = TRNG_CR_KEY(0x524E47);
-
256 #endif
-
257 #if defined(RNG_WATCHDOG)
-
258  // Disable interrupts and reset the watchdog.
-
259  cli();
-
260  wdt_reset();
-
261 
-
262  // Clear the "reset due to watchdog" flag.
-
263  MCUSR &= ~(1 << WDRF);
-
264 
-
265  // Disable the watchdog.
-
266  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
-
267  _WD_CONTROL_REG = 0;
-
268 
-
269  // Re-enable interrupts. The watchdog should be stopped.
-
270  sei();
-
271 #endif
-
272  clean(block);
-
273  clean(stream);
-
274 }
-
275 
-
276 #if defined(RNG_DUE_TRNG)
-
277 
-
278 // Find the flash memory of interest. Allow for the possibility
-
279 // of other SAM-based Arduino variants in the future.
-
280 #if defined(IFLASH1_ADDR)
-
281 #define RNG_FLASH_ADDR IFLASH1_ADDR
-
282 #define RNG_FLASH_SIZE IFLASH1_SIZE
-
283 #define RNG_FLASH_PAGE_SIZE IFLASH1_PAGE_SIZE
-
284 #define RNG_EFC EFC1
-
285 #elif defined(IFLASH0_ADDR)
-
286 #define RNG_FLASH_ADDR IFLASH0_ADDR
-
287 #define RNG_FLASH_SIZE IFLASH0_SIZE
-
288 #define RNG_FLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
-
289 #define RNG_EFC EFC0
-
290 #else
-
291 #define RNG_FLASH_ADDR IFLASH_ADDR
-
292 #define RNG_FLASH_SIZE IFLASH_SIZE
-
293 #define RNG_FLASH_PAGE_SIZE IFLASH_PAGE_SIZE
-
294 #define RNG_EFC EFC
-
295 #endif
-
296 
-
297 // Address of the flash page to use for saving the seed on the Due.
-
298 // All SAM variants have a page size of 256 bytes or greater so there is
-
299 // plenty of room for the 48 byte seed in the last page of flash memory.
-
300 #define RNG_SEED_ADDR (RNG_FLASH_ADDR + RNG_FLASH_SIZE - RNG_FLASH_PAGE_SIZE)
-
301 #define RNG_SEED_PAGE ((RNG_FLASH_SIZE / RNG_FLASH_PAGE_SIZE) - 1)
+
226 // Watchdog interrupt handler. This fires off every 16ms. We collect
+
227 // 32 bits and then pass them off onto RNGClass::loop().
+
228 ISR(WDT_vect)
+
229 {
+
230  // Read the low byte of Timer 1. We assume that the timer was
+
231  // initialized by the Arduino startup code for PWM use or that the
+
232  // application is free-running Timer 1 for its own purposes.
+
233  // Timer 0 is used on systems that don't have a Timer 1.
+
234 #if defined(TCNT1L)
+
235  unsigned char value = TCNT1L;
+
236 #elif defined(TCNT0L)
+
237  unsigned char value = TCNT0L;
+
238 #else
+
239  unsigned char value = TCNT0;
+
240 #endif
+
241  // Use Jenkin's one-at-a-time hash function to scatter the entropy a bit.
+
242  // https://en.wikipedia.org/wiki/Jenkins_hash_function
+
243  hash += value;
+
244  hash += leftShift10(hash);
+
245  hash ^= rightShift6(hash);
+
246  ++outBits;
+
247 }
+
248 
+
249 #endif // RNG_WATCHDOG
+
250 
+
261 RNGClass::RNGClass()
+
262  : credits(0)
+
263  , firstSave(1)
+
264  , initialized(0)
+
265  , trngPending(0)
+
266  , timer(0)
+
267  , timeout(3600000UL) // 1 hour in milliseconds
+
268  , count(0)
+
269  , trngPosn(0)
+
270 {
+
271 }
+
272 
+
276 RNGClass::~RNGClass()
+
277 {
+
278 #if defined(RNG_DUE_TRNG)
+
279  // Disable the TRNG in the Arduino Due.
+
280  REG_TRNG_CR = TRNG_CR_KEY(0x524E47);
+
281 #endif
+
282 #if defined(RNG_WATCHDOG)
+
283  // Disable interrupts and reset the watchdog.
+
284  cli();
+
285  wdt_reset();
+
286 
+
287  // Clear the "reset due to watchdog" flag.
+
288  MCUSR &= ~(1 << WDRF);
+
289 
+
290  // Disable the watchdog.
+
291  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
+
292  _WD_CONTROL_REG = 0;
+
293 
+
294  // Re-enable interrupts. The watchdog should be stopped.
+
295  sei();
+
296 #endif
+
297  clean(block);
+
298  clean(stream);
+
299 }
+
300 
+
301 #if defined(RNG_DUE_TRNG)
302 
-
303 // Stir in the unique identifier for the Arduino Due's CPU.
-
304 // This function must be in RAM because programs running out of
-
305 // flash memory are not allowed to access the unique identifier.
-
306 // Info from: http://forum.arduino.cc/index.php?topic=289190.0
-
307 __attribute__((section(".ramfunc")))
-
308 static void stirUniqueIdentifier(void)
-
309 {
-
310  uint32_t id[4];
-
311 
-
312  // Start Read Unique Identifier.
-
313  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
-
314  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) != 0)
-
315  ; // do nothing until FRDY falls.
-
316 
-
317  // Read the identifier.
-
318  id[0] = *((const uint32_t *)RNG_FLASH_ADDR);
-
319  id[1] = *((const uint32_t *)(RNG_FLASH_ADDR + 4));
-
320  id[2] = *((const uint32_t *)(RNG_FLASH_ADDR + 8));
-
321  id[3] = *((const uint32_t *)(RNG_FLASH_ADDR + 12));
-
322 
-
323  // Stop Read Unique Identifier.
-
324  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI;
-
325  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
-
326  ; // do nothing until FRDY rises.
-
327 
-
328  // Stir the unique identifier into the entropy pool.
-
329  RNG.stir((uint8_t *)id, sizeof(id));
-
330 }
-
331 
-
332 // Erases the flash page containing the seed and then writes the new seed.
-
333 // It is assumed the seed has already been loaded into the latch registers.
-
334 __attribute__((section(".ramfunc")))
-
335 static void eraseAndWriteSeed()
-
336 {
-
337  // Execute the "Erase and Write Page" command.
-
338  RNG_EFC->EEFC_FCR = (0x5A << 24) | (RNG_SEED_PAGE << 8) | EFC_FCMD_EWP;
-
339 
-
340  // Wait for the FRDY bit to be raised.
-
341  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
-
342  ; // do nothing until FRDY rises.
-
343 }
-
344 
-
345 #endif
-
346 
-
360 void RNGClass::begin(const char *tag)
+
303 // Find the flash memory of interest. Allow for the possibility
+
304 // of other SAM-based Arduino variants in the future.
+
305 #if defined(IFLASH1_ADDR)
+
306 #define RNG_FLASH_ADDR IFLASH1_ADDR
+
307 #define RNG_FLASH_SIZE IFLASH1_SIZE
+
308 #define RNG_FLASH_PAGE_SIZE IFLASH1_PAGE_SIZE
+
309 #define RNG_EFC EFC1
+
310 #elif defined(IFLASH0_ADDR)
+
311 #define RNG_FLASH_ADDR IFLASH0_ADDR
+
312 #define RNG_FLASH_SIZE IFLASH0_SIZE
+
313 #define RNG_FLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
+
314 #define RNG_EFC EFC0
+
315 #else
+
316 #define RNG_FLASH_ADDR IFLASH_ADDR
+
317 #define RNG_FLASH_SIZE IFLASH_SIZE
+
318 #define RNG_FLASH_PAGE_SIZE IFLASH_PAGE_SIZE
+
319 #define RNG_EFC EFC
+
320 #endif
+
321 
+
322 // Address of the flash page to use for saving the seed on the Due.
+
323 // All SAM variants have a page size of 256 bytes or greater so there is
+
324 // plenty of room for the 48 byte seed in the last page of flash memory.
+
325 #define RNG_SEED_ADDR (RNG_FLASH_ADDR + RNG_FLASH_SIZE - RNG_FLASH_PAGE_SIZE)
+
326 #define RNG_SEED_PAGE ((RNG_FLASH_SIZE / RNG_FLASH_PAGE_SIZE) - 1)
+
327 
+
328 // Stir in the unique identifier for the Arduino Due's CPU.
+
329 // This function must be in RAM because programs running out of
+
330 // flash memory are not allowed to access the unique identifier.
+
331 // Info from: http://forum.arduino.cc/index.php?topic=289190.0
+
332 __attribute__((section(".ramfunc")))
+
333 static void stirUniqueIdentifier(void)
+
334 {
+
335  uint32_t id[4];
+
336 
+
337  // Start Read Unique Identifier.
+
338  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI;
+
339  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) != 0)
+
340  ; // do nothing until FRDY falls.
+
341 
+
342  // Read the identifier.
+
343  id[0] = *((const uint32_t *)RNG_FLASH_ADDR);
+
344  id[1] = *((const uint32_t *)(RNG_FLASH_ADDR + 4));
+
345  id[2] = *((const uint32_t *)(RNG_FLASH_ADDR + 8));
+
346  id[3] = *((const uint32_t *)(RNG_FLASH_ADDR + 12));
+
347 
+
348  // Stop Read Unique Identifier.
+
349  RNG_EFC->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI;
+
350  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
+
351  ; // do nothing until FRDY rises.
+
352 
+
353  // Stir the unique identifier into the entropy pool.
+
354  RNG.stir((uint8_t *)id, sizeof(id));
+
355 }
+
356 
+
357 // Erases the flash page containing the seed and then writes the new seed.
+
358 // It is assumed the seed has already been loaded into the latch registers.
+
359 __attribute__((section(".ramfunc")))
+
360 static void eraseAndWriteSeed()
361 {
-
362  // Initialize the ChaCha20 input block from the saved seed.
-
363  memcpy_P(block, tagRNG, sizeof(tagRNG));
-
364  memcpy_P(block + 4, initRNG, sizeof(initRNG));
-
365 #if defined(RNG_EEPROM)
-
366  int address = RNG_EEPROM_ADDRESS;
-
367  eeprom_read_block(stream, (const void *)address, SEED_SIZE);
-
368  if (crypto_crc8('S', stream, SEED_SIZE - 1) ==
-
369  ((const uint8_t *)stream)[SEED_SIZE - 1]) {
-
370  // We have a saved seed: XOR it with the initialization block.
-
371  // Note: the CRC-8 value is included. No point throwing it away.
-
372  for (int posn = 0; posn < 12; ++posn)
-
373  block[posn + 4] ^= stream[posn];
-
374  }
-
375 #elif defined(RNG_DUE_TRNG)
-
376  // Do we have a seed saved in the last page of flash memory on the Due?
-
377  int posn, counter;
-
378  if (crypto_crc8('S', ((const uint32_t *)RNG_SEED_ADDR) + 1, SEED_SIZE)
-
379  == ((const uint32_t *)RNG_SEED_ADDR)[0]) {
-
380  // XOR the saved seed with the initialization block.
-
381  for (posn = 0; posn < 12; ++posn)
-
382  block[posn + 4] ^= ((const uint32_t *)RNG_SEED_ADDR)[posn + 1];
-
383  }
-
384 
-
385  // If the device has just been reprogrammed, there will be no saved seed.
-
386  // XOR the initialization block with some output from the CPU's TRNG
-
387  // to permute the state in a first boot situation after reprogramming.
-
388  pmc_enable_periph_clk(ID_TRNG);
-
389  REG_TRNG_CR = TRNG_CR_KEY(0x524E47) | TRNG_CR_ENABLE;
-
390  REG_TRNG_IDR = TRNG_IDR_DATRDY; // Disable interrupts - we will poll.
-
391  for (posn = 0; posn < 12; ++posn) {
-
392  // According to the documentation the TRNG should produce a new
-
393  // 32-bit random value every 84 clock cycles. If it still hasn't
-
394  // produced a value after 200 iterations, then assume that the
-
395  // TRNG is not producing output and stop.
-
396  for (counter = 0; counter < 200; ++counter) {
-
397  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0)
-
398  break;
-
399  }
-
400  if (counter >= 200)
-
401  break;
-
402  block[posn + 4] ^= REG_TRNG_ODATA;
+
362  // Execute the "Erase and Write Page" command.
+
363  RNG_EFC->EEFC_FCR = (0x5A << 24) | (RNG_SEED_PAGE << 8) | EFC_FCMD_EWP;
+
364 
+
365  // Wait for the FRDY bit to be raised.
+
366  while ((RNG_EFC->EEFC_FSR & EEFC_FSR_FRDY) == 0)
+
367  ; // do nothing until FRDY rises.
+
368 }
+
369 
+
370 #endif
+
371 
+
385 void RNGClass::begin(const char *tag)
+
386 {
+
387  // Bail out if we have already done this.
+
388  if (initialized)
+
389  return;
+
390 
+
391  // Initialize the ChaCha20 input block from the saved seed.
+
392  memcpy_P(block, tagRNG, sizeof(tagRNG));
+
393  memcpy_P(block + 4, initRNG, sizeof(initRNG));
+
394 #if defined(RNG_EEPROM)
+
395  int address = RNG_EEPROM_ADDRESS;
+
396  eeprom_read_block(stream, (const void *)address, SEED_SIZE);
+
397  if (crypto_crc8('S', stream, SEED_SIZE - 1) ==
+
398  ((const uint8_t *)stream)[SEED_SIZE - 1]) {
+
399  // We have a saved seed: XOR it with the initialization block.
+
400  // Note: the CRC-8 value is included. No point throwing it away.
+
401  for (int posn = 0; posn < 12; ++posn)
+
402  block[posn + 4] ^= stream[posn];
403  }
-
404 #endif
-
405 
-
406  // No entropy credits for the saved seed.
-
407  credits = 0;
-
408 
-
409  // Trigger an automatic save once the entropy credits max out.
-
410  firstSave = 1;
-
411 
-
412  // Rekey the random number generator immediately.
-
413  rekey();
-
414 
-
415  // Stir in the supplied tag data but don't credit any entropy to it.
-
416  if (tag)
-
417  stir((const uint8_t *)tag, strlen(tag));
-
418 
-
419 #if defined(RNG_DUE_TRNG)
-
420  // Stir in the unique identifier for the CPU so that different
-
421  // devices will give different outputs even without seeding.
-
422  stirUniqueIdentifier();
-
423 #else
-
424  // AVR devices don't have anything like a serial number so it is
-
425  // difficult to make every device unique. Use the compilation
-
426  // time and date to provide a little randomness across applications
-
427  // if not across devices running the same pre-compiled application.
-
428  tag = __TIME__ __DATE__;
-
429  stir((const uint8_t *)tag, strlen(tag));
-
430 #endif
-
431 
-
432 #if defined(RNG_WATCHDOG)
-
433  // Disable interrupts and reset the watchdog.
-
434  cli();
-
435  wdt_reset();
-
436 
-
437  // Clear the "reset due to watchdog" flag.
-
438  MCUSR &= ~(1 << WDRF);
-
439 
-
440  // Enable the watchdog with the smallest duration (16ms)
-
441  // and interrupt-only mode.
-
442  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
-
443  _WD_CONTROL_REG = (1 << WDIE);
+
404 #elif defined(RNG_DUE_TRNG)
+
405  // Do we have a seed saved in the last page of flash memory on the Due?
+
406  if (crypto_crc8('S', ((const uint32_t *)RNG_SEED_ADDR) + 1, SEED_SIZE)
+
407  == ((const uint32_t *)RNG_SEED_ADDR)[0]) {
+
408  // XOR the saved seed with the initialization block.
+
409  for (int posn = 0; posn < 12; ++posn)
+
410  block[posn + 4] ^= ((const uint32_t *)RNG_SEED_ADDR)[posn + 1];
+
411  }
+
412 
+
413  // If the device has just been reprogrammed, there will be no saved seed.
+
414  // XOR the initialization block with some output from the CPU's TRNG
+
415  // to permute the state in a first boot situation after reprogramming.
+
416  pmc_enable_periph_clk(ID_TRNG);
+
417  REG_TRNG_CR = TRNG_CR_KEY(0x524E47) | TRNG_CR_ENABLE;
+
418  REG_TRNG_IDR = TRNG_IDR_DATRDY; // Disable interrupts - we will poll.
+
419  mixTRNG();
+
420 #endif
+
421 #if defined(RNG_ESP_NVS)
+
422  // Do we have a seed saved in ESP non-volatile storage (NVS)?
+
423  nvs_handle handle = 0;
+
424  if (nvs_open("rng", NVS_READONLY, &handle) == 0) {
+
425  size_t len = 0;
+
426  if (nvs_get_blob(handle, "seed", NULL, &len) == 0 && len == SEED_SIZE) {
+
427  uint32_t seed[12];
+
428  if (nvs_get_blob(handle, "seed", seed, &len) == 0) {
+
429  for (int posn = 0; posn < 12; ++posn)
+
430  block[posn + 4] ^= seed[posn];
+
431  }
+
432  clean(seed);
+
433  }
+
434  nvs_close(handle);
+
435  }
+
436 #endif
+
437 #if defined(RNG_WORD_TRNG)
+
438  // Mix in some output from a word-based TRNG to initialize the state.
+
439  mixTRNG();
+
440 #endif
+
441 
+
442  // No entropy credits for the saved seed.
+
443  credits = 0;
444 
-
445  // Re-enable interrupts. The watchdog should be running.
-
446  sei();
-
447 #endif
-
448 
-
449  // Re-save the seed to obliterate the previous value and to ensure
-
450  // that if the system is reset without a call to save() that we won't
-
451  // accidentally generate the same sequence of random data again.
-
452  save();
-
453 }
+
445  // Trigger an automatic save once the entropy credits max out.
+
446  firstSave = 1;
+
447 
+
448  // Rekey the random number generator immediately.
+
449  rekey();
+
450 
+
451  // Stir in the supplied tag data but don't credit any entropy to it.
+
452  if (tag)
+
453  stir((const uint8_t *)tag, strlen(tag));
454 
-
467 void RNGClass::addNoiseSource(NoiseSource &source)
-
468 {
-
469  #define MAX_NOISE_SOURCES (sizeof(noiseSources) / sizeof(noiseSources[0]))
-
470  if (count < MAX_NOISE_SOURCES) {
-
471  noiseSources[count++] = &source;
-
472  source.added();
-
473  }
-
474 }
-
475 
-
492 void RNGClass::setAutoSaveTime(uint16_t minutes)
-
493 {
-
494  if (!minutes)
-
495  minutes = 1; // Just in case.
-
496  timeout = ((uint32_t)minutes) * 60000U;
-
497 }
-
498 
-
516 void RNGClass::rand(uint8_t *data, size_t len)
-
517 {
-
518  // Decrease the amount of entropy in the pool.
-
519  if (len > (credits / 8))
-
520  credits = 0;
-
521  else
-
522  credits -= len * 8;
-
523 
-
524  // Generate the random data.
-
525  uint8_t count = 0;
-
526  while (len > 0) {
-
527  // Force a rekey if we have generated too many blocks in this request.
-
528  if (count >= RNG_REKEY_BLOCKS) {
-
529  rekey();
-
530  count = 1;
-
531  } else {
-
532  ++count;
-
533  }
-
534 
-
535  // Increment the low counter word and generate a new keystream block.
-
536  ++(block[12]);
-
537  ChaCha::hashCore(stream, block, RNG_ROUNDS);
-
538 
-
539  // Copy the data to the return buffer.
-
540  if (len < 64) {
-
541  memcpy(data, stream, len);
-
542  break;
-
543  } else {
-
544  memcpy(data, stream, 64);
-
545  data += 64;
-
546  len -= 64;
-
547  }
-
548  }
-
549 
-
550  // Force a rekey after every request.
-
551  rekey();
-
552 }
-
553 
-
593 bool RNGClass::available(size_t len) const
-
594 {
-
595  if (len >= (RNG_MAX_CREDITS / 8))
-
596  return credits >= RNG_MAX_CREDITS;
-
597  else
-
598  return len <= (credits / 8);
-
599 }
-
600 
-
626 void RNGClass::stir(const uint8_t *data, size_t len, unsigned int credit)
-
627 {
-
628  // Increase the entropy credit.
-
629  if ((credit / 8) >= len && len)
-
630  credit = len * 8;
-
631  if ((RNG_MAX_CREDITS - credits) > credit)
-
632  credits += credit;
-
633  else
-
634  credits = RNG_MAX_CREDITS;
-
635 
-
636  // Process the supplied input data.
-
637  if (len > 0) {
-
638  // XOR the data with the ChaCha input block in 48 byte
-
639  // chunks and rekey the ChaCha cipher for each chunk to mix
-
640  // the data in. This should scatter any "true entropy" in
-
641  // the input across the entire block.
-
642  while (len > 0) {
-
643  size_t templen = len;
-
644  if (templen > 48)
-
645  templen = 48;
-
646  uint8_t *output = ((uint8_t *)block) + 16;
-
647  len -= templen;
-
648  while (templen > 0) {
-
649  *output++ ^= *data++;
-
650  --templen;
-
651  }
-
652  rekey();
-
653  }
-
654  } else {
-
655  // There was no input data, so just force a rekey so we
-
656  // get some mixing of the state even without new data.
-
657  rekey();
-
658  }
-
659 
-
660  // Save if this is the first time we have reached max entropy.
-
661  // This provides some protection if the system is powered off before
-
662  // the first auto-save timeout occurs.
-
663  if (firstSave && credits >= RNG_MAX_CREDITS) {
-
664  firstSave = 0;
-
665  save();
-
666  }
-
667 }
-
668 
-
695 void RNGClass::save()
-
696 {
-
697  // Generate random data from the current state and save
-
698  // that as the seed. Then force a rekey.
-
699  ++(block[12]);
-
700  ChaCha::hashCore(stream, block, RNG_ROUNDS);
-
701 #if defined(RNG_EEPROM)
-
702  // We shorten the seed from 48 bytes to 47 to leave room for
-
703  // the CRC-8 value. We do this to align the data on an 8-byte
-
704  // boundary in EERPOM.
-
705  int address = RNG_EEPROM_ADDRESS;
-
706  eeprom_write_block(stream, (void *)address, SEED_SIZE - 1);
-
707  eeprom_write_byte((uint8_t *)(address + SEED_SIZE - 1),
-
708  crypto_crc8('S', stream, SEED_SIZE - 1));
-
709 #elif defined(RNG_DUE_TRNG)
-
710  unsigned posn;
-
711  ((uint32_t *)(RNG_SEED_ADDR))[0] = crypto_crc8('S', stream, SEED_SIZE);
-
712  for (posn = 0; posn < 12; ++posn)
-
713  ((uint32_t *)(RNG_SEED_ADDR))[posn + 1] = stream[posn];
-
714  for (posn = 13; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
-
715  ((uint32_t *)(RNG_SEED_ADDR))[posn + 13] = 0xFFFFFFFF;
-
716  eraseAndWriteSeed();
-
717 #endif
-
718  rekey();
-
719  timer = millis();
-
720 }
-
721 
-
728 void RNGClass::loop()
-
729 {
-
730  // Stir in the entropy from all registered noise sources.
-
731  for (uint8_t posn = 0; posn < count; ++posn)
-
732  noiseSources[posn]->stir();
-
733 
-
734 #if defined(RNG_DUE_TRNG)
-
735  // If there is data available from the Arudino Due's TRNG, then XOR
-
736  // it with the state block and increase the entropy credit. We don't
-
737  // call stir() yet because that will seriously slow down the system
-
738  // given how fast the TRNG is. Instead we save up the XOR'ed TRNG
-
739  // data until the next rand() call and then hash it to generate the
-
740  // desired output.
-
741  //
-
742  // The CPU documentation claims that the TRNG output is very good so
-
743  // this should only make the pool more and more random as time goes on.
-
744  // However there is a risk that the CPU manufacturer was pressured by
-
745  // government or intelligence agencies to insert a back door that
-
746  // generates predictable output. Or the manufacturer was overly
-
747  // optimistic about their TRNG design and it is actually flawed in a
-
748  // way they don't realise.
-
749  //
-
750  // If you are concerned about such threats, then make sure to mix in
-
751  // data from other noise sources. By hashing together the TRNG with
-
752  // the other noise data, rand() should produce unpredictable data even
-
753  // if one of the sources is actually predictable.
-
754  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0) {
-
755  block[4 + trngPosn] ^= REG_TRNG_ODATA;
-
756  if (++trngPosn >= 12)
-
757  trngPosn = 0;
-
758  if (credits < RNG_MAX_CREDITS) {
-
759  // Credit 1 bit of entropy for the word. The TRNG should be
-
760  // better than this but it is so fast that we want to collect
-
761  // up more data before passing it to the application.
-
762  ++credits;
-
763  }
-
764  }
-
765 #elif defined(RNG_WATCHDOG)
-
766  // Read the 32 bit buffer from the WDT interrupt.
-
767  cli();
-
768  if (outBits >= 32) {
-
769  uint32_t value = hash;
-
770  hash = 0;
-
771  outBits = 0;
-
772  sei();
-
773 
-
774  // Final steps of the Jenkin's one-at-a-time hash function.
-
775  // https://en.wikipedia.org/wiki/Jenkins_hash_function
-
776  value += leftShift3(value);
-
777  value ^= rightShift11(value);
-
778  value += leftShift15(value);
-
779 
-
780  // XOR the word with the state. Stir once we accumulate 48 bytes,
-
781  // which happens about once every 6.4 seconds.
-
782  block[4 + trngPosn] ^= value;
-
783  if (++trngPosn >= 12) {
-
784  trngPosn = 0;
-
785 
-
786  // Credit 1 bit of entropy for each byte of input. It can take
-
787  // between 30 and 40 seconds to accumulate 256 bits of credit.
-
788  stir(0, 0, 48);
-
789  }
-
790  } else {
-
791  sei();
+
455 #if defined(RNG_DUE_TRNG)
+
456  // Stir in the unique identifier for the CPU so that different
+
457  // devices will give different outputs even without seeding.
+
458  stirUniqueIdentifier();
+
459 #elif defined(ESP8266)
+
460  // ESP8266's have a 32-bit CPU chip ID and 32-bit flash chip ID
+
461  // that we can use as a device unique identifier.
+
462  uint32_t ids[2];
+
463  ids[0] = ESP.getChipId();
+
464  ids[1] = ESP.getFlashChipId();
+
465  stir((const uint8_t *)ids, sizeof(ids));
+
466 #elif defined(ESP32)
+
467  // ESP32's have a MAC address that can be used as a device identifier.
+
468  uint64_t mac = ESP.getEfuseMac();
+
469  stir((const uint8_t *)&mac, sizeof(mac));
+
470 #else
+
471  // AVR devices don't have anything like a serial number so it is
+
472  // difficult to make every device unique. Use the compilation
+
473  // time and date to provide a little randomness across applications
+
474  // if not across devices running the same pre-compiled application.
+
475  tag = __TIME__ __DATE__;
+
476  stir((const uint8_t *)tag, strlen(tag));
+
477 #endif
+
478 
+
479 #if defined(RNG_WATCHDOG)
+
480  // Disable interrupts and reset the watchdog.
+
481  cli();
+
482  wdt_reset();
+
483 
+
484  // Clear the "reset due to watchdog" flag.
+
485  MCUSR &= ~(1 << WDRF);
+
486 
+
487  // Enable the watchdog with the smallest duration (16ms)
+
488  // and interrupt-only mode.
+
489  _WD_CONTROL_REG |= (1 << _WD_CHANGE_BIT) | (1 << WDE);
+
490  _WD_CONTROL_REG = (1 << WDIE);
+
491 
+
492  // Re-enable interrupts. The watchdog should be running.
+
493  sei();
+
494 #endif
+
495 
+
496  // Re-save the seed to obliterate the previous value and to ensure
+
497  // that if the system is reset without a call to save() that we won't
+
498  // accidentally generate the same sequence of random data again.
+
499  save();
+
500 
+
501  // The RNG has now been initialized.
+
502  initialized = 1;
+
503 }
+
504 
+
517 void RNGClass::addNoiseSource(NoiseSource &source)
+
518 {
+
519  #define MAX_NOISE_SOURCES (sizeof(noiseSources) / sizeof(noiseSources[0]))
+
520  if (count < MAX_NOISE_SOURCES) {
+
521  noiseSources[count++] = &source;
+
522  source.added();
+
523  }
+
524 }
+
525 
+
542 void RNGClass::setAutoSaveTime(uint16_t minutes)
+
543 {
+
544  if (!minutes)
+
545  minutes = 1; // Just in case.
+
546  timeout = ((uint32_t)minutes) * 60000U;
+
547 }
+
548 
+
566 void RNGClass::rand(uint8_t *data, size_t len)
+
567 {
+
568  // Make sure that the RNG is initialized in case the application
+
569  // forgot to call RNG.begin() at startup time.
+
570  if (!initialized)
+
571  begin(0);
+
572 
+
573  // Decrease the amount of entropy in the pool.
+
574  if (len > (credits / 8))
+
575  credits = 0;
+
576  else
+
577  credits -= len * 8;
+
578 
+
579  // If we have pending TRNG data from the loop() function,
+
580  // then force a stir on the state. Otherwise mix in some
+
581  // fresh data from the TRNG because it is possible that
+
582  // the application forgot to call RNG.loop().
+
583  if (trngPending) {
+
584  stir(0, 0, 0);
+
585  trngPending = 0;
+
586  trngPosn = 0;
+
587  } else {
+
588  mixTRNG();
+
589  }
+
590 
+
591  // Generate the random data.
+
592  uint8_t count = 0;
+
593  while (len > 0) {
+
594  // Force a rekey if we have generated too many blocks in this request.
+
595  if (count >= RNG_REKEY_BLOCKS) {
+
596  rekey();
+
597  count = 1;
+
598  } else {
+
599  ++count;
+
600  }
+
601 
+
602  // Increment the low counter word and generate a new keystream block.
+
603  ++(block[12]);
+
604  ChaCha::hashCore(stream, block, RNG_ROUNDS);
+
605 
+
606  // Copy the data to the return buffer.
+
607  if (len < 64) {
+
608  memcpy(data, stream, len);
+
609  break;
+
610  } else {
+
611  memcpy(data, stream, 64);
+
612  data += 64;
+
613  len -= 64;
+
614  }
+
615  }
+
616 
+
617  // Force a rekey after every request.
+
618  rekey();
+
619 }
+
620 
+
660 bool RNGClass::available(size_t len) const
+
661 {
+
662  if (len >= (RNG_MAX_CREDITS / 8))
+
663  return credits >= RNG_MAX_CREDITS;
+
664  else
+
665  return len <= (credits / 8);
+
666 }
+
667 
+
693 void RNGClass::stir(const uint8_t *data, size_t len, unsigned int credit)
+
694 {
+
695  // Increase the entropy credit.
+
696  if ((credit / 8) >= len && len)
+
697  credit = len * 8;
+
698  if ((RNG_MAX_CREDITS - credits) > credit)
+
699  credits += credit;
+
700  else
+
701  credits = RNG_MAX_CREDITS;
+
702 
+
703  // Process the supplied input data.
+
704  if (len > 0) {
+
705  // XOR the data with the ChaCha input block in 48 byte
+
706  // chunks and rekey the ChaCha cipher for each chunk to mix
+
707  // the data in. This should scatter any "true entropy" in
+
708  // the input across the entire block.
+
709  while (len > 0) {
+
710  size_t templen = len;
+
711  if (templen > 48)
+
712  templen = 48;
+
713  uint8_t *output = ((uint8_t *)block) + 16;
+
714  len -= templen;
+
715  while (templen > 0) {
+
716  *output++ ^= *data++;
+
717  --templen;
+
718  }
+
719  rekey();
+
720  }
+
721  } else {
+
722  // There was no input data, so just force a rekey so we
+
723  // get some mixing of the state even without new data.
+
724  rekey();
+
725  }
+
726 
+
727  // Save if this is the first time we have reached max entropy.
+
728  // This provides some protection if the system is powered off before
+
729  // the first auto-save timeout occurs.
+
730  if (firstSave && credits >= RNG_MAX_CREDITS) {
+
731  firstSave = 0;
+
732  save();
+
733  }
+
734 }
+
735 
+
762 void RNGClass::save()
+
763 {
+
764  // Generate random data from the current state and save
+
765  // that as the seed. Then force a rekey.
+
766  ++(block[12]);
+
767  ChaCha::hashCore(stream, block, RNG_ROUNDS);
+
768 #if defined(RNG_EEPROM)
+
769  // We shorten the seed from 48 bytes to 47 to leave room for
+
770  // the CRC-8 value. We do this to align the data on an 8-byte
+
771  // boundary in EERPOM.
+
772  int address = RNG_EEPROM_ADDRESS;
+
773  eeprom_write_block(stream, (void *)address, SEED_SIZE - 1);
+
774  eeprom_write_byte((uint8_t *)(address + SEED_SIZE - 1),
+
775  crypto_crc8('S', stream, SEED_SIZE - 1));
+
776 #elif defined(RNG_DUE_TRNG)
+
777  unsigned posn;
+
778  ((uint32_t *)(RNG_SEED_ADDR))[0] = crypto_crc8('S', stream, SEED_SIZE);
+
779  for (posn = 0; posn < 12; ++posn)
+
780  ((uint32_t *)(RNG_SEED_ADDR))[posn + 1] = stream[posn];
+
781  for (posn = 13; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
+
782  ((uint32_t *)(RNG_SEED_ADDR))[posn + 13] = 0xFFFFFFFF;
+
783  eraseAndWriteSeed();
+
784 #elif defined(RNG_ESP_NVS)
+
785  // Save the seed into ESP non-volatile storage (NVS).
+
786  nvs_handle handle = 0;
+
787  if (nvs_open("rng", NVS_READWRITE, &handle) == 0) {
+
788  nvs_erase_all(handle);
+
789  nvs_set_blob(handle, "seed", stream, SEED_SIZE);
+
790  nvs_commit(handle);
+
791  nvs_close(handle);
792  }
793 #endif
-
794 
-
795  // Save the seed if the auto-save timer has expired.
-
796  if ((millis() - timer) >= timeout)
-
797  save();
-
798 }
-
799 
-
819 void RNGClass::destroy()
-
820 {
-
821  clean(block);
-
822  clean(stream);
-
823 #if defined(RNG_EEPROM)
-
824  int address = RNG_EEPROM_ADDRESS;
-
825  for (int posn = 0; posn < SEED_SIZE; ++posn)
-
826  eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
-
827 #elif defined(RNG_DUE_TRNG)
-
828  for (unsigned posn = 0; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
-
829  ((uint32_t *)(RNG_SEED_ADDR))[posn] = 0xFFFFFFFF;
-
830  eraseAndWriteSeed();
-
831 #endif
-
832 }
-
833 
-
837 void RNGClass::rekey()
-
838 {
-
839  // Rekey the cipher for the next request by generating a new block.
-
840  // This is intended to make it difficult to wind the random number
-
841  // backwards if the state is captured later. The first 16 bytes of
-
842  // "block" remain set to "tagRNG".
-
843  ++(block[12]);
-
844  ChaCha::hashCore(stream, block, RNG_ROUNDS);
-
845  memcpy(block + 4, stream, 48);
-
846 
-
847  // Permute the high word of the counter using the system microsecond
-
848  // counter to introduce a little bit of non-stir randomness for each
-
849  // request. Note: If random data is requested on a predictable schedule
-
850  // then this may not help very much. It is still necessary to stir in
-
851  // high quality entropy data on a regular basis using stir().
-
852  block[13] ^= micros();
-
853 }
-
RNGClass::save
void save()
Saves the random seed to EEPROM.
Definition: RNG.cpp:695
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
-
RNGClass::begin
void begin(const char *tag)
Initializes the random number generator.
Definition: RNG.cpp:360
+
794  rekey();
+
795  timer = millis();
+
796 }
+
797 
+
804 void RNGClass::loop()
+
805 {
+
806  // Stir in the entropy from all registered noise sources.
+
807  for (uint8_t posn = 0; posn < count; ++posn)
+
808  noiseSources[posn]->stir();
+
809 
+
810 #if defined(RNG_DUE_TRNG)
+
811  // If there is data available from the Arudino Due's TRNG, then XOR
+
812  // it with the state block and increase the entropy credit. We don't
+
813  // call stir() yet because that will seriously slow down the system
+
814  // given how fast the TRNG is. Instead we save up the XOR'ed TRNG
+
815  // data until the next rand() call and then hash it to generate the
+
816  // desired output.
+
817  //
+
818  // The CPU documentation claims that the TRNG output is very good so
+
819  // this should only make the pool more and more random as time goes on.
+
820  // However there is a risk that the CPU manufacturer was pressured by
+
821  // government or intelligence agencies to insert a back door that
+
822  // generates predictable output. Or the manufacturer was overly
+
823  // optimistic about their TRNG design and it is actually flawed in a
+
824  // way they don't realise.
+
825  //
+
826  // If you are concerned about such threats, then make sure to mix in
+
827  // data from other noise sources. By hashing together the TRNG with
+
828  // the other noise data, rand() should produce unpredictable data even
+
829  // if one of the sources is actually predictable.
+
830  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0) {
+
831  block[4 + trngPosn] ^= REG_TRNG_ODATA;
+
832  if (++trngPosn >= 12)
+
833  trngPosn = 0;
+
834  if (credits < RNG_MAX_CREDITS) {
+
835  // Credit 1 bit of entropy for the word. The TRNG should be
+
836  // better than this but it is so fast that we want to collect
+
837  // up more data before passing it to the application.
+
838  ++credits;
+
839  }
+
840  trngPending = 1;
+
841  }
+
842 #elif defined(RNG_WORD_TRNG)
+
843  // Read a word from the TRNG and XOR it into the state.
+
844  block[4 + trngPosn] ^= RNG_WORD_TRNG_GET();
+
845  if (++trngPosn >= 12)
+
846  trngPosn = 0;
+
847  if (credits < RNG_MAX_CREDITS) {
+
848  // Credit 1 bit of entropy for the word. The TRNG should be
+
849  // better than this but it is so fast that we want to collect
+
850  // up more data before passing it to the application.
+
851  ++credits;
+
852  }
+
853  trngPending = 1;
+
854 #elif defined(RNG_WATCHDOG)
+
855  // Read the 32 bit buffer from the WDT interrupt.
+
856  cli();
+
857  if (outBits >= 32) {
+
858  uint32_t value = hash;
+
859  hash = 0;
+
860  outBits = 0;
+
861  sei();
+
862 
+
863  // Final steps of the Jenkin's one-at-a-time hash function.
+
864  // https://en.wikipedia.org/wiki/Jenkins_hash_function
+
865  value += leftShift3(value);
+
866  value ^= rightShift11(value);
+
867  value += leftShift15(value);
+
868 
+
869  // Credit 1 bit of entropy for each byte of input. It can take
+
870  // between 30 and 40 seconds to accumulate 256 bits of credit.
+
871  credits += 4;
+
872  if (credits > RNG_MAX_CREDITS)
+
873  credits = RNG_MAX_CREDITS;
+
874 
+
875  // XOR the word with the state. Stir once we accumulate 48 bytes,
+
876  // which happens about once every 6.4 seconds.
+
877  block[4 + trngPosn] ^= value;
+
878  if (++trngPosn >= 12) {
+
879  trngPosn = 0;
+
880  trngPending = 0;
+
881  stir(0, 0, 0);
+
882  } else {
+
883  trngPending = 1;
+
884  }
+
885  } else {
+
886  sei();
+
887  }
+
888 #endif
+
889 
+
890  // Save the seed if the auto-save timer has expired.
+
891  if ((millis() - timer) >= timeout)
+
892  save();
+
893 }
+
894 
+
914 void RNGClass::destroy()
+
915 {
+
916  clean(block);
+
917  clean(stream);
+
918 #if defined(RNG_EEPROM)
+
919  int address = RNG_EEPROM_ADDRESS;
+
920  for (int posn = 0; posn < SEED_SIZE; ++posn)
+
921  eeprom_write_byte((uint8_t *)(address + posn), 0xFF);
+
922 #elif defined(RNG_DUE_TRNG)
+
923  for (unsigned posn = 0; posn < (RNG_FLASH_PAGE_SIZE / 4); ++posn)
+
924  ((uint32_t *)(RNG_SEED_ADDR))[posn] = 0xFFFFFFFF;
+
925  eraseAndWriteSeed();
+
926 #elif defined(RNG_ESP_NVS)
+
927  nvs_handle handle = 0;
+
928  if (nvs_open("rng", NVS_READWRITE, &handle) == 0) {
+
929  nvs_erase_all(handle);
+
930  nvs_commit(handle);
+
931  nvs_close(handle);
+
932  }
+
933 #endif
+
934  initialized = 0;
+
935 }
+
936 
+
940 void RNGClass::rekey()
+
941 {
+
942  // Rekey the cipher for the next request by generating a new block.
+
943  // This is intended to make it difficult to wind the random number
+
944  // backwards if the state is captured later. The first 16 bytes of
+
945  // "block" remain set to "tagRNG".
+
946  ++(block[12]);
+
947  ChaCha::hashCore(stream, block, RNG_ROUNDS);
+
948  memcpy(block + 4, stream, 48);
+
949 
+
950  // Permute the high word of the counter using the system microsecond
+
951  // counter to introduce a little bit of non-stir randomness for each
+
952  // request. Note: If random data is requested on a predictable schedule
+
953  // then this may not help very much. It is still necessary to stir in
+
954  // high quality entropy data on a regular basis using stir().
+
955  block[13] ^= micros();
+
956 }
+
957 
+
961 void RNGClass::mixTRNG()
+
962 {
+
963 #if defined(RNG_DUE_TRNG)
+
964  // Mix in 12 words from the Due's TRNG.
+
965  for (int posn = 0; posn < 12; ++posn) {
+
966  // According to the documentation the TRNG should produce a new
+
967  // 32-bit random value every 84 clock cycles. If it still hasn't
+
968  // produced a value after 200 iterations, then assume that the
+
969  // TRNG is not producing output and stop.
+
970  int counter;
+
971  for (counter = 0; counter < 200; ++counter) {
+
972  if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0)
+
973  break;
+
974  }
+
975  if (counter >= 200)
+
976  break;
+
977  block[posn + 4] ^= REG_TRNG_ODATA;
+
978  }
+
979 #elif defined(RNG_WORD_TRNG)
+
980  // Read 12 words from the TRNG and XOR them into the state.
+
981  for (uint8_t index = 4; index < 16; ++index)
+
982  block[index] ^= RNG_WORD_TRNG_GET();
+
983 #elif defined(RNG_WATCHDOG)
+
984  // Read the pending 32 bit buffer from the WDT interrupt and mix it in.
+
985  cli();
+
986  if (outBits >= 32) {
+
987  uint32_t value = hash;
+
988  hash = 0;
+
989  outBits = 0;
+
990  sei();
+
991 
+
992  // Final steps of the Jenkin's one-at-a-time hash function.
+
993  // https://en.wikipedia.org/wiki/Jenkins_hash_function
+
994  value += leftShift3(value);
+
995  value ^= rightShift11(value);
+
996  value += leftShift15(value);
+
997 
+
998  // XOR the word with the state.
+
999  block[4] ^= value;
+
1000  } else {
+
1001  sei();
+
1002  }
+
1003 #endif
+
1004 }
+
RNGClass::save
void save()
Saves the random seed to EEPROM.
Definition: RNG.cpp:762
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
+
RNGClass::begin
void begin(const char *tag)
Initializes the random number generator.
Definition: RNG.cpp:385
NoiseSource
Abstract base class for random noise sources.
Definition: NoiseSource.h:29
-
RNGClass::~RNGClass
~RNGClass()
Destroys this random number generator instance.
Definition: RNG.cpp:251
+
RNGClass::~RNGClass
~RNGClass()
Destroys this random number generator instance.
Definition: RNG.cpp:276
NoiseSource::added
virtual void added()
Called when the noise source is added to RNG with RNG.addNoiseSource().
Definition: NoiseSource.cpp:95
-
RNGClass::addNoiseSource
void addNoiseSource(NoiseSource &source)
Adds a noise source to the random number generator.
Definition: RNG.cpp:467
-
RNGClass::RNGClass
RNGClass()
Constructs a new random number generator instance.
Definition: RNG.cpp:238
-
RNGClass::destroy
void destroy()
Destroys the data in the random number pool and the saved seed in EEPROM.
Definition: RNG.cpp:819
-
RNGClass::available
bool available(size_t len) const
Determine if there is sufficient entropy available for a specific request size.
Definition: RNG.cpp:593
-
RNGClass::loop
void loop()
Run periodic housekeeping tasks on the random number generator.
Definition: RNG.cpp:728
+
RNGClass::addNoiseSource
void addNoiseSource(NoiseSource &source)
Adds a noise source to the random number generator.
Definition: RNG.cpp:517
+
RNGClass::RNGClass
RNGClass()
Constructs a new random number generator instance.
Definition: RNG.cpp:261
+
RNGClass::destroy
void destroy()
Destroys the data in the random number pool and the saved seed in EEPROM.
Definition: RNG.cpp:914
+
RNGClass::available
bool available(size_t len) const
Determine if there is sufficient entropy available for a specific request size.
Definition: RNG.cpp:660
+
RNGClass::loop
void loop()
Run periodic housekeeping tasks on the random number generator.
Definition: RNG.cpp:804
RNGClass
Pseudo random number generator suitable for cryptography.
Definition: RNG.h:31
RNGClass::SEED_SIZE
static const int SEED_SIZE
Size of a saved random number seed in EEPROM space.
Definition: RNG.h:53
ChaCha::hashCore
static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds)
Executes the ChaCha hash core on an input memory block.
Definition: ChaCha.cpp:253
-
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:626
-
RNGClass::setAutoSaveTime
void setAutoSaveTime(uint16_t minutes)
Sets the amount of time between automatic seed saves.
Definition: RNG.cpp:492
+
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:693
+
RNGClass::setAutoSaveTime
void setAutoSaveTime(uint16_t minutes)
Sets the amount of time between automatic seed saves.
Definition: RNG.cpp:542
diff --git a/RNG_8h_source.html b/RNG_8h_source.html index 8c654285..d17ab687 100644 --- a/RNG_8h_source.html +++ b/RNG_8h_source.html @@ -145,38 +145,41 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
55 private:
56  uint32_t block[16];
57  uint32_t stream[16];
-
58  uint16_t credits : 15;
+
58  uint16_t credits : 13;
59  uint16_t firstSave : 1;
-
60  unsigned long timer;
-
61  unsigned long timeout;
-
62  NoiseSource *noiseSources[4];
-
63  uint8_t count;
-
64  uint8_t trngPosn;
-
65 
-
66  void rekey();
-
67 };
-
68 
-
69 extern RNGClass RNG;
-
70 
-
71 #endif
-
RNGClass::save
void save()
Saves the random seed to EEPROM.
Definition: RNG.cpp:695
-
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:516
-
RNGClass::begin
void begin(const char *tag)
Initializes the random number generator.
Definition: RNG.cpp:360
+
60  uint16_t initialized : 1;
+
61  uint16_t trngPending : 1;
+
62  unsigned long timer;
+
63  unsigned long timeout;
+
64  NoiseSource *noiseSources[4];
+
65  uint8_t count;
+
66  uint8_t trngPosn;
+
67 
+
68  void rekey();
+
69  void mixTRNG();
+
70 };
+
71 
+
72 extern RNGClass RNG;
+
73 
+
74 #endif
+
RNGClass::save
void save()
Saves the random seed to EEPROM.
Definition: RNG.cpp:762
+
RNGClass::rand
void rand(uint8_t *data, size_t len)
Generates random bytes into a caller-supplied buffer.
Definition: RNG.cpp:566
+
RNGClass::begin
void begin(const char *tag)
Initializes the random number generator.
Definition: RNG.cpp:385
NoiseSource
Abstract base class for random noise sources.
Definition: NoiseSource.h:29
-
RNGClass::~RNGClass
~RNGClass()
Destroys this random number generator instance.
Definition: RNG.cpp:251
-
RNGClass::addNoiseSource
void addNoiseSource(NoiseSource &source)
Adds a noise source to the random number generator.
Definition: RNG.cpp:467
-
RNGClass::RNGClass
RNGClass()
Constructs a new random number generator instance.
Definition: RNG.cpp:238
-
RNGClass::destroy
void destroy()
Destroys the data in the random number pool and the saved seed in EEPROM.
Definition: RNG.cpp:819
-
RNGClass::available
bool available(size_t len) const
Determine if there is sufficient entropy available for a specific request size.
Definition: RNG.cpp:593
-
RNGClass::loop
void loop()
Run periodic housekeeping tasks on the random number generator.
Definition: RNG.cpp:728
+
RNGClass::~RNGClass
~RNGClass()
Destroys this random number generator instance.
Definition: RNG.cpp:276
+
RNGClass::addNoiseSource
void addNoiseSource(NoiseSource &source)
Adds a noise source to the random number generator.
Definition: RNG.cpp:517
+
RNGClass::RNGClass
RNGClass()
Constructs a new random number generator instance.
Definition: RNG.cpp:261
+
RNGClass::destroy
void destroy()
Destroys the data in the random number pool and the saved seed in EEPROM.
Definition: RNG.cpp:914
+
RNGClass::available
bool available(size_t len) const
Determine if there is sufficient entropy available for a specific request size.
Definition: RNG.cpp:660
+
RNGClass::loop
void loop()
Run periodic housekeeping tasks on the random number generator.
Definition: RNG.cpp:804
RNGClass
Pseudo random number generator suitable for cryptography.
Definition: RNG.h:31
RNGClass::SEED_SIZE
static const int SEED_SIZE
Size of a saved random number seed in EEPROM space.
Definition: RNG.h:53
-
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:626
-
RNGClass::setAutoSaveTime
void setAutoSaveTime(uint16_t minutes)
Sets the amount of time between automatic seed saves.
Definition: RNG.cpp:492
+
RNGClass::stir
void stir(const uint8_t *data, size_t len, unsigned int credit=0)
Stirs additional entropy data into the random pool.
Definition: RNG.cpp:693
+
RNGClass::setAutoSaveTime
void setAutoSaveTime(uint16_t minutes)
Sets the amount of time between automatic seed saves.
Definition: RNG.cpp:542
diff --git a/RTC_8cpp_source.html b/RTC_8cpp_source.html index 077accea..9c08b3f9 100644 --- a/RTC_8cpp_source.html +++ b/RTC_8cpp_source.html @@ -380,7 +380,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/RTC_8h_source.html b/RTC_8h_source.html index 06d1514a..ece2c0c2 100644 --- a/RTC_8h_source.html +++ b/RTC_8h_source.html @@ -237,7 +237,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/RingOscillatorNoiseSource_8cpp_source.html b/RingOscillatorNoiseSource_8cpp_source.html index 01a8284b..4687aeb9 100644 --- a/RingOscillatorNoiseSource_8cpp_source.html +++ b/RingOscillatorNoiseSource_8cpp_source.html @@ -285,7 +285,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/RingOscillatorNoiseSource_8h_source.html b/RingOscillatorNoiseSource_8h_source.html index 47d05897..48033101 100644 --- a/RingOscillatorNoiseSource_8h_source.html +++ b/RingOscillatorNoiseSource_8h_source.html @@ -145,7 +145,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA256_8cpp_source.html b/SHA256_8cpp_source.html index fd4c6e07..3efdb963 100644 --- a/SHA256_8cpp_source.html +++ b/SHA256_8cpp_source.html @@ -339,7 +339,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA256_8h_source.html b/SHA256_8h_source.html index 17469cf4..270c2ee2 100644 --- a/SHA256_8h_source.html +++ b/SHA256_8h_source.html @@ -160,7 +160,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA3_8cpp_source.html b/SHA3_8cpp_source.html index 82e980d7..1e4456d8 100644 --- a/SHA3_8cpp_source.html +++ b/SHA3_8cpp_source.html @@ -257,7 +257,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA3_8h_source.html b/SHA3_8h_source.html index 85c02c63..b0296c84 100644 --- a/SHA3_8h_source.html +++ b/SHA3_8h_source.html @@ -188,7 +188,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA512_8cpp_source.html b/SHA512_8cpp_source.html index ba44b40c..94f215bb 100644 --- a/SHA512_8cpp_source.html +++ b/SHA512_8cpp_source.html @@ -355,7 +355,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHA512_8h_source.html b/SHA512_8h_source.html index b9dd4075..754204a1 100644 --- a/SHA512_8h_source.html +++ b/SHA512_8h_source.html @@ -166,7 +166,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHAKE_8cpp_source.html b/SHAKE_8cpp_source.html index 88482061..b402393c 100644 --- a/SHAKE_8cpp_source.html +++ b/SHAKE_8cpp_source.html @@ -192,7 +192,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SHAKE_8h_source.html b/SHAKE_8h_source.html index accf8575..a2ab9038 100644 --- a/SHAKE_8h_source.html +++ b/SHAKE_8h_source.html @@ -174,7 +174,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Shell_8cpp_source.html b/Shell_8cpp_source.html index bba10149..cd742452 100644 --- a/Shell_8cpp_source.html +++ b/Shell_8cpp_source.html @@ -848,7 +848,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Shell_8h_source.html b/Shell_8h_source.html index e78001b2..25bef3d5 100644 --- a/Shell_8h_source.html +++ b/Shell_8h_source.html @@ -273,7 +273,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SoftI2C_8cpp_source.html b/SoftI2C_8cpp_source.html index 09677d85..2e98afc9 100644 --- a/SoftI2C_8cpp_source.html +++ b/SoftI2C_8cpp_source.html @@ -283,7 +283,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SoftI2C_8h_source.html b/SoftI2C_8h_source.html index d1fd3905..af0a02b9 100644 --- a/SoftI2C_8h_source.html +++ b/SoftI2C_8h_source.html @@ -157,7 +157,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SpeckSmall_8cpp_source.html b/SpeckSmall_8cpp_source.html index 3249a4a2..b011d652 100644 --- a/SpeckSmall_8cpp_source.html +++ b/SpeckSmall_8cpp_source.html @@ -649,7 +649,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SpeckSmall_8h_source.html b/SpeckSmall_8h_source.html index bfa51fc4..3a99e11b 100644 --- a/SpeckSmall_8h_source.html +++ b/SpeckSmall_8h_source.html @@ -141,7 +141,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SpeckTiny_8cpp_source.html b/SpeckTiny_8cpp_source.html index ae4cc6fe..5b856897 100644 --- a/SpeckTiny_8cpp_source.html +++ b/SpeckTiny_8cpp_source.html @@ -517,7 +517,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/SpeckTiny_8h_source.html b/SpeckTiny_8h_source.html index 9798c180..c2f7bee5 100644 --- a/SpeckTiny_8h_source.html +++ b/SpeckTiny_8h_source.html @@ -154,7 +154,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Speck_8cpp_source.html b/Speck_8cpp_source.html index c07bea55..e3c99654 100644 --- a/Speck_8cpp_source.html +++ b/Speck_8cpp_source.html @@ -618,7 +618,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Speck_8h_source.html b/Speck_8h_source.html index c4d7cc89..683753ff 100644 --- a/Speck_8h_source.html +++ b/Speck_8h_source.html @@ -149,7 +149,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TelnetDefs_8h_source.html b/TelnetDefs_8h_source.html index a8ce2ccd..fbfc3495 100644 --- a/TelnetDefs_8h_source.html +++ b/TelnetDefs_8h_source.html @@ -205,7 +205,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Terminal_8cpp_source.html b/Terminal_8cpp_source.html index a2d63d5a..cfff4087 100644 --- a/Terminal_8cpp_source.html +++ b/Terminal_8cpp_source.html @@ -1037,7 +1037,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/Terminal_8h_source.html b/Terminal_8h_source.html index 0c1f6f02..411680cd 100644 --- a/Terminal_8h_source.html +++ b/Terminal_8h_source.html @@ -299,7 +299,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TextField_8cpp_source.html b/TextField_8cpp_source.html index ac8cc8dc..9695cd70 100644 --- a/TextField_8cpp_source.html +++ b/TextField_8cpp_source.html @@ -156,7 +156,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TextField_8h_source.html b/TextField_8h_source.html index 359ba657..d33739a1 100644 --- a/TextField_8h_source.html +++ b/TextField_8h_source.html @@ -142,7 +142,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TimeField_8cpp_source.html b/TimeField_8cpp_source.html index 8f0febec..f2afcdea 100644 --- a/TimeField_8cpp_source.html +++ b/TimeField_8cpp_source.html @@ -325,7 +325,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TimeField_8h_source.html b/TimeField_8h_source.html index 61a8bcac..64de3b70 100644 --- a/TimeField_8h_source.html +++ b/TimeField_8h_source.html @@ -167,7 +167,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TransistorNoiseSource_8cpp_source.html b/TransistorNoiseSource_8cpp_source.html index c89df2c1..e5edb132 100644 --- a/TransistorNoiseSource_8cpp_source.html +++ b/TransistorNoiseSource_8cpp_source.html @@ -295,7 +295,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/TransistorNoiseSource_8h_source.html b/TransistorNoiseSource_8h_source.html index 8d2fbc8e..f4a88e3e 100644 --- a/TransistorNoiseSource_8h_source.html +++ b/TransistorNoiseSource_8h_source.html @@ -151,7 +151,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/USBKeysExtra_8h_source.html b/USBKeysExtra_8h_source.html index f8786ee3..bbbb7d3a 100644 --- a/USBKeysExtra_8h_source.html +++ b/USBKeysExtra_8h_source.html @@ -215,7 +215,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/XOF_8cpp_source.html b/XOF_8cpp_source.html index 5571c4e0..1654ce18 100644 --- a/XOF_8cpp_source.html +++ b/XOF_8cpp_source.html @@ -125,7 +125,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/XOF_8h_source.html b/XOF_8h_source.html index 802c03d8..3fb48711 100644 --- a/XOF_8h_source.html +++ b/XOF_8h_source.html @@ -152,7 +152,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/XTS_8cpp_source.html b/XTS_8cpp_source.html index c23cdde2..ae17d8c9 100644 --- a/XTS_8cpp_source.html +++ b/XTS_8cpp_source.html @@ -290,7 +290,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/XTS_8h_source.html b/XTS_8h_source.html index 8cc017bd..0a0147d8 100644 --- a/XTS_8h_source.html +++ b/XTS_8h_source.html @@ -217,7 +217,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/alarm-clock_8dox.html b/alarm-clock_8dox.html index a9128f7c..35e2bcf4 100644 --- a/alarm-clock_8dox.html +++ b/alarm-clock_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/alarm_clock.html b/alarm_clock.html index dbe69ad8..768737f3 100644 --- a/alarm_clock.html +++ b/alarm_clock.html @@ -140,7 +140,7 @@ Completed Clock diff --git a/annotated.html b/annotated.html index 7859b131..94606d8e 100644 --- a/annotated.html +++ b/annotated.html @@ -177,7 +177,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink-blink_8dox.html b/blink-blink_8dox.html index aa3107a1..ea656b22 100644 --- a/blink-blink_8dox.html +++ b/blink-blink_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink-charlieplex_8dox.html b/blink-charlieplex_8dox.html index 239b6c0a..f705f187 100644 --- a/blink-charlieplex_8dox.html +++ b/blink-charlieplex_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink-cylon_8dox.html b/blink-cylon_8dox.html index 1b01c250..d70e58df 100644 --- a/blink-cylon_8dox.html +++ b/blink-cylon_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink-startrek_8dox.html b/blink-startrek_8dox.html index e04130d7..40ca58e0 100644 --- a/blink-startrek_8dox.html +++ b/blink-startrek_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink_blink.html b/blink_blink.html index f1ab2621..ea139f44 100644 --- a/blink_blink.html +++ b/blink_blink.html @@ -120,7 +120,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink_charlieplex.html b/blink_charlieplex.html index 97bba350..0e64ac22 100644 --- a/blink_charlieplex.html +++ b/blink_charlieplex.html @@ -160,7 +160,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink_cylon.html b/blink_cylon.html index f5fa08e3..da6b52ab 100644 --- a/blink_cylon.html +++ b/blink_cylon.html @@ -171,7 +171,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/blink_startrek.html b/blink_startrek.html index a39efde9..99893792 100644 --- a/blink_startrek.html +++ b/blink_startrek.html @@ -237,7 +237,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAES128-members.html b/classAES128-members.html index 5b355890..e7c0c350 100644 --- a/classAES128-members.html +++ b/classAES128-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAES128.html b/classAES128.html index 93a05f23..9ebcae9a 100644 --- a/classAES128.html +++ b/classAES128.html @@ -265,7 +265,7 @@ Additional Inherited Members diff --git a/classAES192-members.html b/classAES192-members.html index 9439a71b..a788e226 100644 --- a/classAES192-members.html +++ b/classAES192-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAES192.html b/classAES192.html index a75b9357..e26bebc2 100644 --- a/classAES192.html +++ b/classAES192.html @@ -265,7 +265,7 @@ Additional Inherited Members diff --git a/classAES256-members.html b/classAES256-members.html index 84b0648d..fa777710 100644 --- a/classAES256-members.html +++ b/classAES256-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAES256.html b/classAES256.html index 81af23d7..b7163f0e 100644 --- a/classAES256.html +++ b/classAES256.html @@ -265,7 +265,7 @@ Additional Inherited Members diff --git a/classAESCommon-members.html b/classAESCommon-members.html index 0c216bae..4df437fb 100644 --- a/classAESCommon-members.html +++ b/classAESCommon-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAESCommon.html b/classAESCommon.html index 1f9a690d..2656a4af 100644 --- a/classAESCommon.html +++ b/classAESCommon.html @@ -322,7 +322,7 @@ Protected Member Functions diff --git a/classAuthenticatedCipher-members.html b/classAuthenticatedCipher-members.html index ba1f506e..8eff7227 100644 --- a/classAuthenticatedCipher-members.html +++ b/classAuthenticatedCipher-members.html @@ -108,7 +108,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classAuthenticatedCipher.html b/classAuthenticatedCipher.html index a485ea8a..2c3d9740 100644 --- a/classAuthenticatedCipher.html +++ b/classAuthenticatedCipher.html @@ -351,7 +351,7 @@ virtual  diff --git a/classBLAKE2b-members.html b/classBLAKE2b-members.html index b56118a9..22dbbf64 100644 --- a/classBLAKE2b-members.html +++ b/classBLAKE2b-members.html @@ -113,7 +113,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBLAKE2b.html b/classBLAKE2b.html index 8cdd9dc4..66f31580 100644 --- a/classBLAKE2b.html +++ b/classBLAKE2b.html @@ -600,7 +600,7 @@ Additional Inherited Members diff --git a/classBLAKE2s-members.html b/classBLAKE2s-members.html index 04521b30..b9ff32b9 100644 --- a/classBLAKE2s-members.html +++ b/classBLAKE2s-members.html @@ -112,7 +112,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBLAKE2s.html b/classBLAKE2s.html index 04537bee..d06b3dfa 100644 --- a/classBLAKE2s.html +++ b/classBLAKE2s.html @@ -600,7 +600,7 @@ Additional Inherited Members diff --git a/classBigNumberUtil-members.html b/classBigNumberUtil-members.html index 73a7eef1..316328eb 100644 --- a/classBigNumberUtil-members.html +++ b/classBigNumberUtil-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBigNumberUtil.html b/classBigNumberUtil.html index 37de8ce4..6f7a5fe1 100644 --- a/classBigNumberUtil.html +++ b/classBigNumberUtil.html @@ -143,7 +143,7 @@ Static Public Member Functions

Big numbers are represented as arrays of limb_t words, which may be 8 bits, 16 bits, or 32 bits in size depending upon how the library was configured. For AVR, 16 bit limbs usually give the best performance.

Limb arrays are ordered from the least significant word to the most significant.

-

Definition at line 71 of file BigNumberUtil.h.

+

Definition at line 72 of file BigNumberUtil.h.

Member Function Documentation

@@ -943,7 +943,7 @@ Static Public Member Functions
diff --git a/classBitmap-members.html b/classBitmap-members.html index 06143dc9..7b5f978d 100644 --- a/classBitmap-members.html +++ b/classBitmap-members.html @@ -138,7 +138,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBitmap.html b/classBitmap.html index 19aa1d8b..3bcd23e7 100644 --- a/classBitmap.html +++ b/classBitmap.html @@ -1745,7 +1745,7 @@ class DMD diff --git a/classBlinkLED-members.html b/classBlinkLED-members.html index edaee4cf..d442168b 100644 --- a/classBlinkLED-members.html +++ b/classBlinkLED-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBlinkLED.html b/classBlinkLED.html index 8188c246..1356c7fb 100644 --- a/classBlinkLED.html +++ b/classBlinkLED.html @@ -428,7 +428,7 @@ Public Member Functions diff --git a/classBlockCipher-members.html b/classBlockCipher-members.html index 9376f8b0..1f674b36 100644 --- a/classBlockCipher-members.html +++ b/classBlockCipher-members.html @@ -101,7 +101,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBlockCipher.html b/classBlockCipher.html index b2c48e41..8f6d438b 100644 --- a/classBlockCipher.html +++ b/classBlockCipher.html @@ -410,7 +410,7 @@ Public Member Functions diff --git a/classBoolField-members.html b/classBoolField-members.html index 83a5c5aa..2cd73b55 100644 --- a/classBoolField-members.html +++ b/classBoolField-members.html @@ -113,7 +113,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classBoolField.html b/classBoolField.html index 80a98b28..763afaf7 100644 --- a/classBoolField.html +++ b/classBoolField.html @@ -506,7 +506,7 @@ LiquidCrystal *  diff --git a/classCBC-members.html b/classCBC-members.html index b2568cb9..9a2d4339 100644 --- a/classCBC-members.html +++ b/classCBC-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCBC.html b/classCBC.html index c1e55513..c6aac793 100644 --- a/classCBC.html +++ b/classCBC.html @@ -185,7 +185,7 @@ class CBC< T > diff --git a/classCBCCommon-members.html b/classCBCCommon-members.html index dbb131e1..2fd3b74e 100644 --- a/classCBCCommon-members.html +++ b/classCBCCommon-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCBCCommon.html b/classCBCCommon.html index 76861b2a..4fc1319a 100644 --- a/classCBCCommon.html +++ b/classCBCCommon.html @@ -534,7 +534,7 @@ Protected Member Functions diff --git a/classCFB-members.html b/classCFB-members.html index fdeb7b68..b9c955c1 100644 --- a/classCFB-members.html +++ b/classCFB-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCFB.html b/classCFB.html index c5d34a94..d582f54a 100644 --- a/classCFB.html +++ b/classCFB.html @@ -185,7 +185,7 @@ class CFB< T > diff --git a/classCFBCommon-members.html b/classCFBCommon-members.html index ba26e5f5..7ff7906d 100644 --- a/classCFBCommon-members.html +++ b/classCFBCommon-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCFBCommon.html b/classCFBCommon.html index 34c51a5f..19773e3a 100644 --- a/classCFBCommon.html +++ b/classCFBCommon.html @@ -534,7 +534,7 @@ Protected Member Functions diff --git a/classCTR-members.html b/classCTR-members.html index a7cb52d4..c7dddb17 100644 --- a/classCTR-members.html +++ b/classCTR-members.html @@ -107,7 +107,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCTR.html b/classCTR.html index d00fa128..a5504bbf 100644 --- a/classCTR.html +++ b/classCTR.html @@ -181,7 +181,7 @@ class CTR< T > diff --git a/classCTRCommon-members.html b/classCTRCommon-members.html index 0ff1a7d5..05a860e3 100644 --- a/classCTRCommon-members.html +++ b/classCTRCommon-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCTRCommon.html b/classCTRCommon.html index 814c38d4..baaa6dfb 100644 --- a/classCTRCommon.html +++ b/classCTRCommon.html @@ -563,7 +563,7 @@ Protected Member Functions diff --git a/classChaCha-members.html b/classChaCha-members.html index 9b2859f7..fb737835 100644 --- a/classChaCha-members.html +++ b/classChaCha-members.html @@ -109,7 +109,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classChaCha.html b/classChaCha.html index 88858a6b..24ffdedf 100644 --- a/classChaCha.html +++ b/classChaCha.html @@ -673,7 +673,7 @@ class ChaChaPoly< diff --git a/classChaChaPoly-members.html b/classChaChaPoly-members.html index b44ea330..e6774748 100644 --- a/classChaChaPoly-members.html +++ b/classChaChaPoly-members.html @@ -115,7 +115,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classChaChaPoly.html b/classChaChaPoly.html index aaede2f5..679f1490 100644 --- a/classChaChaPoly.html +++ b/classChaChaPoly.html @@ -665,7 +665,7 @@ virtual  diff --git a/classCharlieplex-members.html b/classCharlieplex-members.html index e5daa0cc..86441cc2 100644 --- a/classCharlieplex-members.html +++ b/classCharlieplex-members.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCharlieplex.html b/classCharlieplex.html index 810a424c..d630a3df 100644 --- a/classCharlieplex.html +++ b/classCharlieplex.html @@ -538,7 +538,7 @@ Public Member Functions diff --git a/classChaseLEDs-members.html b/classChaseLEDs-members.html index cd5e0756..0bd51030 100644 --- a/classChaseLEDs-members.html +++ b/classChaseLEDs-members.html @@ -99,7 +99,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classChaseLEDs.html b/classChaseLEDs.html index 19752bda..682dc104 100644 --- a/classChaseLEDs.html +++ b/classChaseLEDs.html @@ -347,7 +347,7 @@ Protected Member Functions diff --git a/classCipher-members.html b/classCipher-members.html index 4c68e74d..99b54aa2 100644 --- a/classCipher-members.html +++ b/classCipher-members.html @@ -102,7 +102,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCipher.html b/classCipher.html index 97ac8155..3d2204ad 100644 --- a/classCipher.html +++ b/classCipher.html @@ -485,7 +485,7 @@ Public Member Functions diff --git a/classCurve25519-members.html b/classCurve25519-members.html index 34836b25..4f828bd8 100644 --- a/classCurve25519-members.html +++ b/classCurve25519-members.html @@ -97,7 +97,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classCurve25519.html b/classCurve25519.html index 9eada0c2..63578e65 100644 --- a/classCurve25519.html +++ b/classCurve25519.html @@ -303,7 +303,7 @@ class Ed25519 diff --git a/classDMD-members.html b/classDMD-members.html index bd3b9b45..02ff32f5 100644 --- a/classDMD-members.html +++ b/classDMD-members.html @@ -150,7 +150,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classDMD.html b/classDMD.html index 72fe8c1b..f1e252b4 100644 --- a/classDMD.html +++ b/classDMD.html @@ -755,7 +755,7 @@ Multiple panels diff --git a/classDS1307RTC-members.html b/classDS1307RTC-members.html index 0637a7f1..67cd939e 100644 --- a/classDS1307RTC-members.html +++ b/classDS1307RTC-members.html @@ -125,7 +125,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classDS1307RTC.html b/classDS1307RTC.html index a920dbe7..34cfab0f 100644 --- a/classDS1307RTC.html +++ b/classDS1307RTC.html @@ -598,7 +598,7 @@ static const uint8_t  diff --git a/classDS3231RTC-members.html b/classDS3231RTC-members.html index de557a0a..f6dfcb0d 100644 --- a/classDS3231RTC-members.html +++ b/classDS3231RTC-members.html @@ -133,7 +133,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classDS3231RTC.html b/classDS3231RTC.html index 2a7803c7..f20f7b3f 100644 --- a/classDS3231RTC.html +++ b/classDS3231RTC.html @@ -713,7 +713,7 @@ static const uint8_t  diff --git a/classDS3232RTC-members.html b/classDS3232RTC-members.html index 80458c24..d72f81b8 100644 --- a/classDS3232RTC-members.html +++ b/classDS3232RTC-members.html @@ -130,7 +130,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classDS3232RTC.html b/classDS3232RTC.html index 9758175e..f874f914 100644 --- a/classDS3232RTC.html +++ b/classDS3232RTC.html @@ -750,7 +750,7 @@ static const uint8_t  diff --git a/classEAX-members.html b/classEAX-members.html index c13fdfc0..4e904a12 100644 --- a/classEAX-members.html +++ b/classEAX-members.html @@ -118,7 +118,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classEAX.html b/classEAX.html index 7f9f0a48..9124e447 100644 --- a/classEAX.html +++ b/classEAX.html @@ -219,7 +219,7 @@ class EAX< T > diff --git a/classEAXCommon-members.html b/classEAXCommon-members.html index ab418d07..fc5d580d 100644 --- a/classEAXCommon-members.html +++ b/classEAXCommon-members.html @@ -117,7 +117,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classEAXCommon.html b/classEAXCommon.html index 44cf5017..e61fa007 100644 --- a/classEAXCommon.html +++ b/classEAXCommon.html @@ -732,7 +732,7 @@ Protected Member Functions diff --git a/classEEPROM24-members.html b/classEEPROM24-members.html index 00c9e9d4..5ef0ea27 100644 --- a/classEEPROM24-members.html +++ b/classEEPROM24-members.html @@ -101,7 +101,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classEEPROM24.html b/classEEPROM24.html index 7c2750b6..4f0e4a66 100644 --- a/classEEPROM24.html +++ b/classEEPROM24.html @@ -431,7 +431,7 @@ Public Member Functions diff --git a/classEd25519-members.html b/classEd25519-members.html index d282df8d..f8a63553 100644 --- a/classEd25519-members.html +++ b/classEd25519-members.html @@ -97,7 +97,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classEd25519.html b/classEd25519.html index 5e8e38d0..e0d6b392 100644 --- a/classEd25519.html +++ b/classEd25519.html @@ -354,7 +354,7 @@ Static Public Member Functions diff --git a/classField-members.html b/classField-members.html index 15da75e7..82b106e7 100644 --- a/classField-members.html +++ b/classField-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classField.html b/classField.html index 47ba8823..f594b726 100644 --- a/classField.html +++ b/classField.html @@ -424,7 +424,7 @@ class Form diff --git a/classForm-members.html b/classForm-members.html index 837f0eb2..803784b8 100644 --- a/classForm-members.html +++ b/classForm-members.html @@ -108,7 +108,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classForm.html b/classForm.html index 1d9e4d2b..194cd0ec 100644 --- a/classForm.html +++ b/classForm.html @@ -485,7 +485,7 @@ class Field diff --git a/classGCM-members.html b/classGCM-members.html index 1642e8ed..43df833b 100644 --- a/classGCM-members.html +++ b/classGCM-members.html @@ -119,7 +119,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classGCM.html b/classGCM.html index c2e78153..13364e87 100644 --- a/classGCM.html +++ b/classGCM.html @@ -223,7 +223,7 @@ class GCM< T > diff --git a/classGCMCommon-members.html b/classGCMCommon-members.html index 64285782..e4a9f96a 100644 --- a/classGCMCommon-members.html +++ b/classGCMCommon-members.html @@ -118,7 +118,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classGCMCommon.html b/classGCMCommon.html index 80c37c74..0b558679 100644 --- a/classGCMCommon.html +++ b/classGCMCommon.html @@ -736,7 +736,7 @@ Protected Member Functions diff --git a/classGF128-members.html b/classGF128-members.html index 4b214a36..bcfb09c1 100644 --- a/classGF128-members.html +++ b/classGF128-members.html @@ -98,7 +98,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classGF128.html b/classGF128.html index 797fa47f..6a8df945 100644 --- a/classGF128.html +++ b/classGF128.html @@ -334,7 +334,7 @@ Static Public Member Functions diff --git a/classGHASH-members.html b/classGHASH-members.html index 9a3d7ca0..123a86e8 100644 --- a/classGHASH-members.html +++ b/classGHASH-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classGHASH.html b/classGHASH.html index c311dea3..5f752e5f 100644 --- a/classGHASH.html +++ b/classGHASH.html @@ -265,7 +265,7 @@ void  diff --git a/classHash-members.html b/classHash-members.html index 98d7b301..5cf76d56 100644 --- a/classHash-members.html +++ b/classHash-members.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classHash.html b/classHash.html index 7831471e..739815f3 100644 --- a/classHash.html +++ b/classHash.html @@ -575,7 +575,7 @@ Protected Member Functions diff --git a/classI2CMaster-members.html b/classI2CMaster-members.html index d0d9085a..e7acb6cd 100644 --- a/classI2CMaster-members.html +++ b/classI2CMaster-members.html @@ -100,7 +100,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classI2CMaster.html b/classI2CMaster.html index 885955bf..e51d9dc7 100644 --- a/classI2CMaster.html +++ b/classI2CMaster.html @@ -328,7 +328,7 @@ virtual unsigned int  diff --git a/classIRreceiver-members.html b/classIRreceiver-members.html index 7d33ec23..db80847c 100644 --- a/classIRreceiver-members.html +++ b/classIRreceiver-members.html @@ -100,7 +100,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classIRreceiver.html b/classIRreceiver.html index 278a56ee..19327abb 100644 --- a/classIRreceiver.html +++ b/classIRreceiver.html @@ -328,7 +328,7 @@ void _IR_receive_interrupt diff --git a/classIntField-members.html b/classIntField-members.html index 6d4fbf90..3878e5d5 100644 --- a/classIntField-members.html +++ b/classIntField-members.html @@ -118,7 +118,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classIntField.html b/classIntField.html index 80c11819..3943ea35 100644 --- a/classIntField.html +++ b/classIntField.html @@ -647,7 +647,7 @@ LiquidCrystal *  diff --git a/classKeccakCore-members.html b/classKeccakCore-members.html index 45d114c4..ce05323f 100644 --- a/classKeccakCore-members.html +++ b/classKeccakCore-members.html @@ -108,7 +108,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classKeccakCore.html b/classKeccakCore.html index e9214fe1..06be1f6a 100644 --- a/classKeccakCore.html +++ b/classKeccakCore.html @@ -475,7 +475,7 @@ void  diff --git a/classLCD-members.html b/classLCD-members.html index a090bf40..cb6c3f79 100644 --- a/classLCD-members.html +++ b/classLCD-members.html @@ -110,7 +110,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classLCD.html b/classLCD.html index 5731a97e..8f7819ce 100644 --- a/classLCD.html +++ b/classLCD.html @@ -592,7 +592,7 @@ Support for DFRobot LCD Shield diff --git a/classListField-members.html b/classListField-members.html index f8c92607..0e1ecc16 100644 --- a/classListField-members.html +++ b/classListField-members.html @@ -111,7 +111,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classListField.html b/classListField.html index b23f5fb2..a903381d 100644 --- a/classListField.html +++ b/classListField.html @@ -411,7 +411,7 @@ LiquidCrystal *  diff --git a/classLoginShell-members.html b/classLoginShell-members.html index 075183cb..db71b990 100644 --- a/classLoginShell-members.html +++ b/classLoginShell-members.html @@ -180,7 +180,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classLoginShell.html b/classLoginShell.html index 40c19768..dc7462c7 100644 --- a/classLoginShell.html +++ b/classLoginShell.html @@ -572,7 +572,7 @@ Additional Inherited Members diff --git a/classMelody-members.html b/classMelody-members.html index 6e35bfb6..63cc58d9 100644 --- a/classMelody-members.html +++ b/classMelody-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classMelody.html b/classMelody.html index cf433a93..07a01322 100644 --- a/classMelody.html +++ b/classMelody.html @@ -371,7 +371,7 @@ bool  diff --git a/classNewHope-members.html b/classNewHope-members.html index a9d3bf7a..68242160 100644 --- a/classNewHope-members.html +++ b/classNewHope-members.html @@ -99,7 +99,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classNewHope.html b/classNewHope.html index 5aae4e32..57784bfb 100644 --- a/classNewHope.html +++ b/classNewHope.html @@ -229,7 +229,7 @@ Static Public Member Functions

The send value should be sent to Bob over the communications link and then it can be discarded. The sk value must be retained until the later call to sharedb().

See Also
sharedb(), shareda()
-

Definition at line 1014 of file NewHope.cpp.

+

Definition at line 1025 of file NewHope.cpp.

@@ -282,7 +282,7 @@ Static Public Member Functions
See Also
sharedb(), keygen()
-

Definition at line 1288 of file NewHope.cpp.

+

Definition at line 1319 of file NewHope.cpp.

@@ -351,7 +351,7 @@ Static Public Member Functions

It is assumed that if send and received overlap, then they are the same pointer. The bytes at the end of send may be used for temporary storage while the leading bytes of send / received are being processed.

See Also
shareda(), keygen()
-

Definition at line 1116 of file NewHope.cpp.

+

Definition at line 1137 of file NewHope.cpp.

@@ -362,7 +362,7 @@ Static Public Member Functions diff --git a/classNoiseSource-members.html b/classNoiseSource-members.html index ed49a53e..653a3714 100644 --- a/classNoiseSource-members.html +++ b/classNoiseSource-members.html @@ -99,7 +99,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classNoiseSource.html b/classNoiseSource.html index 7cea00aa..f49a4cc7 100644 --- a/classNoiseSource.html +++ b/classNoiseSource.html @@ -289,7 +289,7 @@ Protected Member Functions diff --git a/classOFB-members.html b/classOFB-members.html index 7ca26a4a..77c05f1b 100644 --- a/classOFB-members.html +++ b/classOFB-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classOFB.html b/classOFB.html index 5ee1be32..167e3679 100644 --- a/classOFB.html +++ b/classOFB.html @@ -181,7 +181,7 @@ class OFB< T > diff --git a/classOFBCommon-members.html b/classOFBCommon-members.html index 5478bf9a..27030170 100644 --- a/classOFBCommon-members.html +++ b/classOFBCommon-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classOFBCommon.html b/classOFBCommon.html index b428f5b9..9f98cc7f 100644 --- a/classOFBCommon.html +++ b/classOFBCommon.html @@ -534,7 +534,7 @@ Protected Member Functions diff --git a/classOMAC-members.html b/classOMAC-members.html index 6f420f7e..19383691 100644 --- a/classOMAC-members.html +++ b/classOMAC-members.html @@ -102,7 +102,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classOMAC.html b/classOMAC.html index b7eb53d6..c5afb3a4 100644 --- a/classOMAC.html +++ b/classOMAC.html @@ -387,7 +387,7 @@ void  diff --git a/classP521-members.html b/classP521-members.html index ee8ae543..f5d18631 100644 --- a/classP521-members.html +++ b/classP521-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classP521.html b/classP521.html index fea4d7a9..3fbdd377 100644 --- a/classP521.html +++ b/classP521.html @@ -646,7 +646,7 @@ Static Public Member Functions diff --git a/classPoly1305-members.html b/classPoly1305-members.html index 97065b29..09166d55 100644 --- a/classPoly1305-members.html +++ b/classPoly1305-members.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classPoly1305.html b/classPoly1305.html index 57b94f14..c1e2bee8 100644 --- a/classPoly1305.html +++ b/classPoly1305.html @@ -280,7 +280,7 @@ void  diff --git a/classRNGClass-members.html b/classRNGClass-members.html index a370a5e8..01887963 100644 --- a/classRNGClass-members.html +++ b/classRNGClass-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRNGClass.html b/classRNGClass.html index 0cb42b25..f7451e01 100644 --- a/classRNGClass.html +++ b/classRNGClass.html @@ -211,7 +211,7 @@ Static Public Attributes

This constructor must be followed by a call to begin() to properly initialize the random number generator.

See Also
begin()
-

Definition at line 238 of file RNG.cpp.

+

Definition at line 261 of file RNG.cpp.

@@ -240,7 +240,7 @@ Static Public Attributes

RNG supports a maximum of four noise sources. If the application needs more than that then the application must poll the noise sources itself by calling NoiseSource::stir() directly.

See Also
loop(), begin()
-

Definition at line 467 of file RNG.cpp.

+

Definition at line 517 of file RNG.cpp.

@@ -283,7 +283,7 @@ Static Public Attributes

If len is larger than the maximum number of entropy credits supported by the random number pool (384 bits, 48 bytes), then the maximum will be used instead. For example, asking if 512 bits (64 bytes) are available will return true if in reality only 384 bits are available. If this is a problem for the application's security requirements, then large requests for random data should be broken up into smaller chunks with the application waiting for the entropy pool to refill between chunks.

See Also
rand()
-

Definition at line 593 of file RNG.cpp.

+

Definition at line 660 of file RNG.cpp.

@@ -311,7 +311,7 @@ Static Public Attributes

This function should be followed by calls to addNoiseSource() to register the application's noise sources.

See Also
addNoiseSource(), stir(), save()
-

Definition at line 360 of file RNG.cpp.

+

Definition at line 385 of file RNG.cpp.

@@ -334,7 +334,7 @@ Static Public Attributes
Note
The rand() and save() functions take some care to manage the random number pool in a way that makes prediction of past outputs from a captured state very difficult. Future outputs may be predictable if noise or other high-entropy data is not mixed in with stir() on a regular basis.
See Also
begin()
-

Definition at line 819 of file RNG.cpp.

+

Definition at line 914 of file RNG.cpp.

@@ -354,7 +354,7 @@ Static Public Attributes

Run periodic housekeeping tasks on the random number generator.

This function must be called on a regular basis from the application's main "loop()" function.

-

Definition at line 728 of file RNG.cpp.

+

Definition at line 804 of file RNG.cpp.

@@ -394,7 +394,7 @@ Static Public Attributes

If the application requires a specific amount of entropy before generating important values, the available() function can be polled to determine when sufficient entropy is available.

See Also
available(), stir()
-

Definition at line 516 of file RNG.cpp.

+

Definition at line 566 of file RNG.cpp.

@@ -418,7 +418,7 @@ Static Public Attributes

The seed that is saved is generated in such a way that it cannot be used to predict random values that were generated previously or subsequently in the current session. So a compromise of the EEPROM contents of a captured device should not result in compromise of random values that have already been generated. However, if power is lost and the system restarted, then there will be a short period of time where the random state will be predictable from the seed. For this reason it is very important to stir() in new noise data at startup.

See Also
loop(), stir()
-

Definition at line 695 of file RNG.cpp.

+

Definition at line 762 of file RNG.cpp.

@@ -447,7 +447,7 @@ Static Public Attributes

This function is intended to help with EEPROM wear by slowing down how often seed data is saved as noise is stirred into the random pool. The exact period to use depends upon how long you intend to field the device before replacing it. For example, an EEPROM rated for 100k erase/write cycles will last about 69 days saving once a minute or 11 years saving once an hour.

See Also
save(), stir()
-

Definition at line 492 of file RNG.cpp.

+

Definition at line 542 of file RNG.cpp.

@@ -495,7 +495,7 @@ Static Public Attributes

If credit is zero, then the data will be stirred in but no entropy credit is given. This is useful for static values like serial numbers and MAC addresses that are different between devices but highly predictable.

See Also
loop()
-

Definition at line 626 of file RNG.cpp.

+

Definition at line 693 of file RNG.cpp.

@@ -532,7 +532,7 @@ Static Public Attributes diff --git a/classRTC-members.html b/classRTC-members.html index 8e768974..e3139ac2 100644 --- a/classRTC-members.html +++ b/classRTC-members.html @@ -123,7 +123,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRTC.html b/classRTC.html index ff57afdd..a5d3f07c 100644 --- a/classRTC.html +++ b/classRTC.html @@ -779,7 +779,7 @@ static const uint8_t  diff --git a/classRTCAlarm-members.html b/classRTCAlarm-members.html index 9f4e6cba..f5eb63b3 100644 --- a/classRTCAlarm-members.html +++ b/classRTCAlarm-members.html @@ -99,7 +99,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRTCDate-members.html b/classRTCDate-members.html index 9d14c1d2..32fce72a 100644 --- a/classRTCDate-members.html +++ b/classRTCDate-members.html @@ -96,7 +96,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRTCTime-members.html b/classRTCTime-members.html index a0d0d726..9c7522a8 100644 --- a/classRTCTime-members.html +++ b/classRTCTime-members.html @@ -96,7 +96,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRingOscillatorNoiseSource-members.html b/classRingOscillatorNoiseSource-members.html index 0405e022..312f5aaa 100644 --- a/classRingOscillatorNoiseSource-members.html +++ b/classRingOscillatorNoiseSource-members.html @@ -101,7 +101,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classRingOscillatorNoiseSource.html b/classRingOscillatorNoiseSource.html index 373d86a4..7df8ba2e 100644 --- a/classRingOscillatorNoiseSource.html +++ b/classRingOscillatorNoiseSource.html @@ -253,7 +253,7 @@ Additional Inherited Members diff --git a/classSHA256-members.html b/classSHA256-members.html index cafef998..a34cc43d 100644 --- a/classSHA256-members.html +++ b/classSHA256-members.html @@ -110,7 +110,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHA256.html b/classSHA256.html index af325351..f9532c04 100644 --- a/classSHA256.html +++ b/classSHA256.html @@ -506,7 +506,7 @@ Additional Inherited Members diff --git a/classSHA3__256-members.html b/classSHA3__256-members.html index 3dd33261..7817a90b 100644 --- a/classSHA3__256-members.html +++ b/classSHA3__256-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHA3__256.html b/classSHA3__256.html index cfd42360..f37147a4 100644 --- a/classSHA3__256.html +++ b/classSHA3__256.html @@ -506,7 +506,7 @@ Additional Inherited Members diff --git a/classSHA3__512-members.html b/classSHA3__512-members.html index 3e023934..de6e2f79 100644 --- a/classSHA3__512-members.html +++ b/classSHA3__512-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHA3__512.html b/classSHA3__512.html index cf821673..10937908 100644 --- a/classSHA3__512.html +++ b/classSHA3__512.html @@ -506,7 +506,7 @@ Additional Inherited Members diff --git a/classSHA512-members.html b/classSHA512-members.html index 9d90ba48..c671e164 100644 --- a/classSHA512-members.html +++ b/classSHA512-members.html @@ -112,7 +112,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHA512.html b/classSHA512.html index 34d2e0d6..546427a3 100644 --- a/classSHA512.html +++ b/classSHA512.html @@ -513,7 +513,7 @@ Additional Inherited Members diff --git a/classSHAKE-members.html b/classSHAKE-members.html index 4bfaea02..848cf037 100644 --- a/classSHAKE-members.html +++ b/classSHAKE-members.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHAKE.html b/classSHAKE.html index 61d564c3..7c9509be 100644 --- a/classSHAKE.html +++ b/classSHAKE.html @@ -443,7 +443,7 @@ Protected Member Functions diff --git a/classSHAKE128-members.html b/classSHAKE128-members.html index a329bd8e..d209997a 100644 --- a/classSHAKE128-members.html +++ b/classSHAKE128-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHAKE128.html b/classSHAKE128.html index b5f138a4..802677dd 100644 --- a/classSHAKE128.html +++ b/classSHAKE128.html @@ -171,7 +171,7 @@ Additional Inherited Members diff --git a/classSHAKE256-members.html b/classSHAKE256-members.html index 32b0e546..2107b15a 100644 --- a/classSHAKE256-members.html +++ b/classSHAKE256-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSHAKE256.html b/classSHAKE256.html index 0aabbb48..8f20308e 100644 --- a/classSHAKE256.html +++ b/classSHAKE256.html @@ -171,7 +171,7 @@ Additional Inherited Members diff --git a/classShell-members.html b/classShell-members.html index 6f3ee2dd..9b1e34ba 100644 --- a/classShell-members.html +++ b/classShell-members.html @@ -174,7 +174,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classShell.html b/classShell.html index 1cbc0e03..b7c989ad 100644 --- a/classShell.html +++ b/classShell.html @@ -837,7 +837,7 @@ Additional Inherited Members diff --git a/classShellArguments-members.html b/classShellArguments-members.html index 0d634304..fbef752a 100644 --- a/classShellArguments-members.html +++ b/classShellArguments-members.html @@ -96,7 +96,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classShellArguments.html b/classShellArguments.html index 9931410d..4e94ffb9 100644 --- a/classShellArguments.html +++ b/classShellArguments.html @@ -182,7 +182,7 @@ class Shell diff --git a/classSoftI2C-members.html b/classSoftI2C-members.html index 6a04a631..3dd16624 100644 --- a/classSoftI2C-members.html +++ b/classSoftI2C-members.html @@ -101,7 +101,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSoftI2C.html b/classSoftI2C.html index 036f5024..28e834d3 100644 --- a/classSoftI2C.html +++ b/classSoftI2C.html @@ -346,7 +346,7 @@ unsigned int  diff --git a/classSpeck-members.html b/classSpeck-members.html index a3080773..54b9210e 100644 --- a/classSpeck-members.html +++ b/classSpeck-members.html @@ -103,7 +103,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSpeck.html b/classSpeck.html index c33b7799..bd31e7b0 100644 --- a/classSpeck.html +++ b/classSpeck.html @@ -415,7 +415,7 @@ Public Member Functions diff --git a/classSpeckSmall-members.html b/classSpeckSmall-members.html index 0c6bfe7c..833b497d 100644 --- a/classSpeckSmall-members.html +++ b/classSpeckSmall-members.html @@ -105,7 +105,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSpeckSmall.html b/classSpeckSmall.html index 51c654e5..a5984ce7 100644 --- a/classSpeckSmall.html +++ b/classSpeckSmall.html @@ -319,7 +319,7 @@ Public Member Functions diff --git a/classSpeckTiny-members.html b/classSpeckTiny-members.html index 0645369e..c9723acc 100644 --- a/classSpeckTiny-members.html +++ b/classSpeckTiny-members.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classSpeckTiny.html b/classSpeckTiny.html index f3c27c9b..fd45d7e1 100644 --- a/classSpeckTiny.html +++ b/classSpeckTiny.html @@ -428,7 +428,7 @@ class SpeckSmall< diff --git a/classTerminal-members.html b/classTerminal-members.html index aa6fee8f..9846b4b0 100644 --- a/classTerminal-members.html +++ b/classTerminal-members.html @@ -156,7 +156,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classTerminal.html b/classTerminal.html index a201567b..160c5f8b 100644 --- a/classTerminal.html +++ b/classTerminal.html @@ -1443,7 +1443,7 @@ Static Public Member Functions diff --git a/classTextField-members.html b/classTextField-members.html index f214da5a..45f59fa3 100644 --- a/classTextField-members.html +++ b/classTextField-members.html @@ -109,7 +109,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classTextField.html b/classTextField.html index 4683751c..2b1b7ef9 100644 --- a/classTextField.html +++ b/classTextField.html @@ -343,7 +343,7 @@ LiquidCrystal *  diff --git a/classTimeField-members.html b/classTimeField-members.html index a4c52bc7..bc442cf3 100644 --- a/classTimeField-members.html +++ b/classTimeField-members.html @@ -113,7 +113,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classTimeField.html b/classTimeField.html index f96b18e3..6a691c13 100644 --- a/classTimeField.html +++ b/classTimeField.html @@ -541,7 +541,7 @@ LiquidCrystal *  diff --git a/classTransistorNoiseSource-members.html b/classTransistorNoiseSource-members.html index fd16925b..b6e87907 100644 --- a/classTransistorNoiseSource-members.html +++ b/classTransistorNoiseSource-members.html @@ -101,7 +101,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classTransistorNoiseSource.html b/classTransistorNoiseSource.html index ebb422a7..5f16352e 100644 --- a/classTransistorNoiseSource.html +++ b/classTransistorNoiseSource.html @@ -280,7 +280,7 @@ Additional Inherited Members diff --git a/classXOF-members.html b/classXOF-members.html index 2d124f33..532c6cd0 100644 --- a/classXOF-members.html +++ b/classXOF-members.html @@ -102,7 +102,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classXOF.html b/classXOF.html index 05d32410..936609f0 100644 --- a/classXOF.html +++ b/classXOF.html @@ -508,7 +508,7 @@ Public Member Functions diff --git a/classXTS-members.html b/classXTS-members.html index 070b07b2..1da767c0 100644 --- a/classXTS-members.html +++ b/classXTS-members.html @@ -107,7 +107,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classXTS.html b/classXTS.html index af61f21a..7f7e9694 100644 --- a/classXTS.html +++ b/classXTS.html @@ -220,7 +220,7 @@ template<typename T1, typename T2 = T1> diff --git a/classXTSCommon-members.html b/classXTSCommon-members.html index 542349ed..43cc7136 100644 --- a/classXTSCommon-members.html +++ b/classXTSCommon-members.html @@ -106,7 +106,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classXTSCommon.html b/classXTSCommon.html index 9772e239..86839bc7 100644 --- a/classXTSCommon.html +++ b/classXTSCommon.html @@ -497,7 +497,7 @@ class XTSSingleKeyCommon diff --git a/classXTSSingleKey-members.html b/classXTSSingleKey-members.html index bd1f5d30..b0947dbb 100644 --- a/classXTSSingleKey-members.html +++ b/classXTSSingleKey-members.html @@ -109,7 +109,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classXTSSingleKey.html b/classXTSSingleKey.html index 3a1cb5ee..77ef2b41 100644 --- a/classXTSSingleKey.html +++ b/classXTSSingleKey.html @@ -218,7 +218,7 @@ template<typename T > diff --git a/classXTSSingleKeyCommon-members.html b/classXTSSingleKeyCommon-members.html index 1359ef61..6767cc5f 100644 --- a/classXTSSingleKeyCommon-members.html +++ b/classXTSSingleKeyCommon-members.html @@ -107,7 +107,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/classXTSSingleKeyCommon.html b/classXTSSingleKeyCommon.html index 2513ae81..a739ebdb 100644 --- a/classXTSSingleKeyCommon.html +++ b/classXTSSingleKeyCommon.html @@ -257,7 +257,7 @@ Protected Member Functions diff --git a/classes.html b/classes.html index 27a1222f..de6bb91d 100644 --- a/classes.html +++ b/classes.html @@ -139,7 +139,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/crypto-esp_8dox.html b/crypto-esp_8dox.html new file mode 100644 index 00000000..5cdc9074 --- /dev/null +++ b/crypto-esp_8dox.html @@ -0,0 +1,95 @@ + + + + + + +ArduinoLibs: crypto-esp.dox File Reference + + + + + + + + + +
+
+ + + + + + +
+
ArduinoLibs +
+
+
+ + + + + + + + + +
+ +
+ +
+
+
+
crypto-esp.dox File Reference
+
+
+
+ + + + diff --git a/crypto-rng-ring_8dox.html b/crypto-rng-ring_8dox.html index 2b0e1fb8..fdc55c84 100644 --- a/crypto-rng-ring_8dox.html +++ b/crypto-rng-ring_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/crypto-rng_8dox.html b/crypto-rng_8dox.html index 8254a21b..713ec96e 100644 --- a/crypto-rng_8dox.html +++ b/crypto-rng_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/crypto.html b/crypto.html index 14ad9b94..7bffee3d 100644 --- a/crypto.html +++ b/crypto.html @@ -100,7 +100,8 @@ Supported Algorithms

Examples and other topics

Performance

@@ -391,7 +392,7 @@ Performance on ARM diff --git a/crypto_8dox.html b/crypto_8dox.html index 86640cb3..03c2251e 100644 --- a/crypto_8dox.html +++ b/crypto_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/crypto_esp.html b/crypto_esp.html new file mode 100644 index 00000000..b0c10262 --- /dev/null +++ b/crypto_esp.html @@ -0,0 +1,111 @@ + + + + + + +ArduinoLibs: Using the cryptography library with ESP8266 + + + + + + + + + +
+
+ + + + + + +
+
ArduinoLibs +
+
+
+ + + + + + + + +
+ +
+ +
+
+
+
Using the cryptography library with ESP8266
+
+
+

This library has been tested with ESP8266-based Arduino devices. Some people have had problems with earlier versions of the library, some of which have been fixed in the library and some of which need to be dealt with in the calling application.

+

This page describes the common problems that have been encountered and some suggested work arounds.

+

+Program memory

+

Earlier versions of the Arduino toolchain for ESP8266 had issues with program memory accesses. This example is from the Curve25519 code:

+
uint8_t check = (pgm_read_byte(point + 31) ^ k[31]) & 0x7F;
+

This would cause crashes. Rewriting the code as follows would help:

+
uint8_t check = (pgm_read_byte(&(point[31])) ^ k[31]) & 0x7F;
+

Note how a pointer operation (point + 31) was changed into an array operation (&(point[31])). Logically these two should be equivalent but earlier compilers somehow compiled the pointer-using code incorrectly.

+

This problem appears to have been fixed in more recent versions of the compiler so the first thing to try is to update your toolchain. Otherwise you may need to change more program memory accesses to get the library to work. Merge requests welcome.

+

+Watchdog

+

The most common reason why the cryptography code "fails" on ESP8266 is because of the system watchdog. By default the software watchdog on the ESP8266 will fire off after about 3 seconds and the hardware watchdog will fire off after about 8 seconds if the software watchdog was disabled.

+

Some of the example programs in the cryptography library can take a long time to run through all the tests, which makes watchdog failure very likely. User application code can have the same problem.

+

If you see the message "Soft WDT reset" then this is probably the cause. However disabling the software watchdog with either wdt_disable() or ESP.wdtDisable() will only shift the problem to later when the hardware watchdog fires off.

+

The macro crypto_feed_watchdog() in Crypto.h has been added to the library. If you call it at regular intervals and before or after cryptography operations then it should reduce the watchdog reset problem. It is safe to use this macro on non-ESP8266 platforms where it will define away to nothing.

+

The example programs have been modified to feed the watchdog regularly during the testing process. And long-running public key functions in classes like Curve25519 and P521 will feed the watchdog while the curves are being evaluated. But you still may need to call crypto_feed_watchdog() from your own code to keep the watchdog happy.

+

+Stack space

+

Another problem occurred in the NewHope implementation due to lack of stack space. NewHope was putting so much data on the stack that it caused a stack overflow and an exception. NewHope has been modified to move the state to the heap on ESP8266 to get it off the stack.

+

It is possible that your own application may have similar issues if you are allocating cryptographic objects on the stack. Recommend that you move data into global data space or to the heap to work around this problem.

+
+ + + + diff --git a/crypto_rng.html b/crypto_rng.html index 73bd9e80..53b73aba 100644 --- a/crypto_rng.html +++ b/crypto_rng.html @@ -190,7 +190,7 @@ Destroying secret data diff --git a/crypto_rng_ring.html b/crypto_rng_ring.html index 04f79791..247d6235 100644 --- a/crypto_rng_ring.html +++ b/crypto_rng_ring.html @@ -151,7 +151,7 @@ Connecting to the Arduino diff --git a/dir_1586d320a3b1e622174530fde769cda9.html b/dir_1586d320a3b1e622174530fde769cda9.html index 13ba6d98..649b6829 100644 --- a/dir_1586d320a3b1e622174530fde769cda9.html +++ b/dir_1586d320a3b1e622174530fde769cda9.html @@ -102,7 +102,7 @@ Files diff --git a/dir_1de32c476debcefedf4aa8bb43bea551.html b/dir_1de32c476debcefedf4aa8bb43bea551.html index 738e9665..253d4abb 100644 --- a/dir_1de32c476debcefedf4aa8bb43bea551.html +++ b/dir_1de32c476debcefedf4aa8bb43bea551.html @@ -106,7 +106,7 @@ Files diff --git a/dir_3dd03323535933fb3f714c41ff7a94da.html b/dir_3dd03323535933fb3f714c41ff7a94da.html index 43d3e550..8a9e1028 100644 --- a/dir_3dd03323535933fb3f714c41ff7a94da.html +++ b/dir_3dd03323535933fb3f714c41ff7a94da.html @@ -94,7 +94,7 @@ Files diff --git a/dir_470c03f38356b1f63943514897cb198b.html b/dir_470c03f38356b1f63943514897cb198b.html index 95eaa484..fe8f1d32 100644 --- a/dir_470c03f38356b1f63943514897cb198b.html +++ b/dir_470c03f38356b1f63943514897cb198b.html @@ -94,7 +94,7 @@ Files diff --git a/dir_48f64e79f12bd77ba047e9e436ec978c.html b/dir_48f64e79f12bd77ba047e9e436ec978c.html index 4d3d9ed4..fcb007b5 100644 --- a/dir_48f64e79f12bd77ba047e9e436ec978c.html +++ b/dir_48f64e79f12bd77ba047e9e436ec978c.html @@ -122,7 +122,7 @@ Files diff --git a/dir_5e87a7229a108582288ef7eda1233dc3.html b/dir_5e87a7229a108582288ef7eda1233dc3.html index 4c94e64b..5c926db8 100644 --- a/dir_5e87a7229a108582288ef7eda1233dc3.html +++ b/dir_5e87a7229a108582288ef7eda1233dc3.html @@ -94,7 +94,7 @@ Files diff --git a/dir_6591a2127a29f6cea3994dcb5b0596d1.html b/dir_6591a2127a29f6cea3994dcb5b0596d1.html index f7198e16..4583aaa5 100644 --- a/dir_6591a2127a29f6cea3994dcb5b0596d1.html +++ b/dir_6591a2127a29f6cea3994dcb5b0596d1.html @@ -106,7 +106,7 @@ Files diff --git a/dir_7e6ab9b017486261fe80629d442521f0.html b/dir_7e6ab9b017486261fe80629d442521f0.html index df65e7b6..d2fd3aa1 100644 --- a/dir_7e6ab9b017486261fe80629d442521f0.html +++ b/dir_7e6ab9b017486261fe80629d442521f0.html @@ -94,7 +94,7 @@ Files diff --git a/dir_9a34040863d1190c0e01b23e6b44de01.html b/dir_9a34040863d1190c0e01b23e6b44de01.html index 71c1d1fd..1588532f 100644 --- a/dir_9a34040863d1190c0e01b23e6b44de01.html +++ b/dir_9a34040863d1190c0e01b23e6b44de01.html @@ -96,7 +96,7 @@ Files diff --git a/dir_bc0718b08fb2015b8e59c47b2805f60c.html b/dir_bc0718b08fb2015b8e59c47b2805f60c.html index 17902b11..a0d14a80 100644 --- a/dir_bc0718b08fb2015b8e59c47b2805f60c.html +++ b/dir_bc0718b08fb2015b8e59c47b2805f60c.html @@ -116,7 +116,7 @@ Directories diff --git a/dir_be059bf9978ae156837504b1b8a7568c.html b/dir_be059bf9978ae156837504b1b8a7568c.html index 5e789aee..54888761 100644 --- a/dir_be059bf9978ae156837504b1b8a7568c.html +++ b/dir_be059bf9978ae156837504b1b8a7568c.html @@ -94,7 +94,7 @@ Files diff --git a/dir_e2ce51835550ba18edf07a8311722290.html b/dir_e2ce51835550ba18edf07a8311722290.html index 856fac5d..ff25df9f 100644 --- a/dir_e2ce51835550ba18edf07a8311722290.html +++ b/dir_e2ce51835550ba18edf07a8311722290.html @@ -240,7 +240,7 @@ Files diff --git a/dir_f34881fcf60f680b800190d5274dfaea.html b/dir_f34881fcf60f680b800190d5274dfaea.html index 49a3104d..7f1808b9 100644 --- a/dir_f34881fcf60f680b800190d5274dfaea.html +++ b/dir_f34881fcf60f680b800190d5274dfaea.html @@ -106,7 +106,7 @@ Files diff --git a/dir_f9b96888882c2691b8eeaeafd1b9501d.html b/dir_f9b96888882c2691b8eeaeafd1b9501d.html index b69144de..c4c6438a 100644 --- a/dir_f9b96888882c2691b8eeaeafd1b9501d.html +++ b/dir_f9b96888882c2691b8eeaeafd1b9501d.html @@ -102,7 +102,7 @@ Files diff --git a/dmd-demo_8dox.html b/dmd-demo_8dox.html index f3d79a01..47c86ac5 100644 --- a/dmd-demo_8dox.html +++ b/dmd-demo_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/dmd-running-figure_8dox.html b/dmd-running-figure_8dox.html index d71f5b54..fa8c43c5 100644 --- a/dmd-running-figure_8dox.html +++ b/dmd-running-figure_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/dmd_demo.html b/dmd_demo.html index f39ec8b1..6246116b 100644 --- a/dmd_demo.html +++ b/dmd_demo.html @@ -236,7 +236,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/dmd_running_figure.html b/dmd_running_figure.html index f634032b..6e4e71d0 100644 --- a/dmd_running_figure.html +++ b/dmd_running_figure.html @@ -430,7 +430,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/files.html b/files.html index f02ad440..acd66d66 100644 --- a/files.html +++ b/files.html @@ -231,7 +231,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions.html b/functions.html index dcab3995..06cabc45 100644 --- a/functions.html +++ b/functions.html @@ -193,7 +193,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_b.html b/functions_b.html index bea40534..97c0c218 100644 --- a/functions_b.html +++ b/functions_b.html @@ -208,7 +208,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_c.html b/functions_c.html index c88b734c..b5766653 100644 --- a/functions_c.html +++ b/functions_c.html @@ -261,7 +261,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_d.html b/functions_d.html index 3f1b35cd..ce8de027 100644 --- a/functions_d.html +++ b/functions_d.html @@ -300,7 +300,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_e.html b/functions_e.html index 0d7aa310..435b416e 100644 --- a/functions_e.html +++ b/functions_e.html @@ -219,7 +219,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_enum.html b/functions_enum.html index 872302ec..9a60b1f1 100644 --- a/functions_enum.html +++ b/functions_enum.html @@ -114,7 +114,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_eval.html b/functions_eval.html index eee933b4..62dc3451 100644 --- a/functions_eval.html +++ b/functions_eval.html @@ -168,7 +168,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_f.html b/functions_f.html index be4aecf7..3d638330 100644 --- a/functions_f.html +++ b/functions_f.html @@ -187,7 +187,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func.html b/functions_func.html index 9fdb31d8..5e07fba9 100644 --- a/functions_func.html +++ b/functions_func.html @@ -186,7 +186,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_b.html b/functions_func_b.html index 0e1a9b52..a976038f 100644 --- a/functions_func_b.html +++ b/functions_func_b.html @@ -194,7 +194,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_c.html b/functions_func_c.html index aa7a35e5..30b5f025 100644 --- a/functions_func_c.html +++ b/functions_func_c.html @@ -253,7 +253,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_d.html b/functions_func_d.html index f2a19f90..021c62fc 100644 --- a/functions_func_d.html +++ b/functions_func_d.html @@ -262,7 +262,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_e.html b/functions_func_e.html index f491725c..8fed9b5c 100644 --- a/functions_func_e.html +++ b/functions_func_e.html @@ -218,7 +218,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_f.html b/functions_func_f.html index 8ee6316a..3df051d2 100644 --- a/functions_func_f.html +++ b/functions_func_f.html @@ -180,7 +180,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_g.html b/functions_func_g.html index 0138afc7..98d86b09 100644 --- a/functions_func_g.html +++ b/functions_func_g.html @@ -144,7 +144,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_h.html b/functions_func_h.html index 5da3efef..f18195ab 100644 --- a/functions_func_h.html +++ b/functions_func_h.html @@ -161,7 +161,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_i.html b/functions_func_i.html index 35bc3f9d..9f2190a7 100644 --- a/functions_func_i.html +++ b/functions_func_i.html @@ -202,7 +202,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_k.html b/functions_func_k.html index ccb2ccdf..95747bbb 100644 --- a/functions_func_k.html +++ b/functions_func_k.html @@ -153,7 +153,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_l.html b/functions_func_l.html index 80872234..40f83bd1 100644 --- a/functions_func_l.html +++ b/functions_func_l.html @@ -131,7 +131,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); : Field
  • LCD() -: LCD +: LCD
  • led() : Charlieplex @@ -157,7 +157,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_m.html b/functions_func_m.html index 26ea70cb..6f34f7c1 100644 --- a/functions_func_m.html +++ b/functions_func_m.html @@ -160,7 +160,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_n.html b/functions_func_n.html index f4ec0bb6..05499efb 100644 --- a/functions_func_n.html +++ b/functions_func_n.html @@ -143,7 +143,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_o.html b/functions_func_o.html index 0d7cb3ec..47dab276 100644 --- a/functions_func_o.html +++ b/functions_func_o.html @@ -149,7 +149,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_p.html b/functions_func_p.html index 465ee416..87544389 100644 --- a/functions_func_p.html +++ b/functions_func_p.html @@ -179,7 +179,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_r.html b/functions_func_r.html index 3377cf0e..c9cf8212 100644 --- a/functions_func_r.html +++ b/functions_func_r.html @@ -228,7 +228,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_s.html b/functions_func_s.html index f4088319..4edd6f32 100644 --- a/functions_func_s.html +++ b/functions_func_s.html @@ -427,7 +427,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_t.html b/functions_func_t.html index c0bf0e3f..83e2fa79 100644 --- a/functions_func_t.html +++ b/functions_func_t.html @@ -161,7 +161,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_u.html b/functions_func_u.html index e95d3b06..d803647a 100644 --- a/functions_func_u.html +++ b/functions_func_u.html @@ -167,7 +167,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_v.html b/functions_func_v.html index 42393c92..7e1a93a4 100644 --- a/functions_func_v.html +++ b/functions_func_v.html @@ -139,7 +139,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_w.html b/functions_func_w.html index 41f7548e..741fb974 100644 --- a/functions_func_w.html +++ b/functions_func_w.html @@ -166,7 +166,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_x.html b/functions_func_x.html index 1de885d3..82259cd6 100644 --- a/functions_func_x.html +++ b/functions_func_x.html @@ -143,7 +143,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_func_~.html b/functions_func_~.html index 7754bc8d..6435ad21 100644 --- a/functions_func_~.html +++ b/functions_func_~.html @@ -242,7 +242,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_g.html b/functions_g.html index d73fbf1e..72a14d9d 100644 --- a/functions_g.html +++ b/functions_g.html @@ -148,7 +148,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_h.html b/functions_h.html index 0b8c31a3..4bea3197 100644 --- a/functions_h.html +++ b/functions_h.html @@ -166,7 +166,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_i.html b/functions_i.html index 6288d83d..f3492086 100644 --- a/functions_i.html +++ b/functions_i.html @@ -206,7 +206,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_k.html b/functions_k.html index 8de9244e..e282fd41 100644 --- a/functions_k.html +++ b/functions_k.html @@ -154,7 +154,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_l.html b/functions_l.html index 04093eb7..e2118268 100644 --- a/functions_l.html +++ b/functions_l.html @@ -132,7 +132,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); : Field
  • LCD() -: LCD +: LCD
  • led() : Charlieplex @@ -161,7 +161,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_m.html b/functions_m.html index 32ce959d..0484ad35 100644 --- a/functions_m.html +++ b/functions_m.html @@ -174,7 +174,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_n.html b/functions_n.html index 6c939a47..767ce33c 100644 --- a/functions_n.html +++ b/functions_n.html @@ -150,7 +150,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_o.html b/functions_o.html index f04b1d08..7de398c2 100644 --- a/functions_o.html +++ b/functions_o.html @@ -150,7 +150,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_p.html b/functions_p.html index 8607f888..68fd1504 100644 --- a/functions_p.html +++ b/functions_p.html @@ -183,7 +183,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_r.html b/functions_r.html index c8bf81ec..beb9fd33 100644 --- a/functions_r.html +++ b/functions_r.html @@ -235,7 +235,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_rela.html b/functions_rela.html index 61a3181b..4bd0c804 100644 --- a/functions_rela.html +++ b/functions_rela.html @@ -102,7 +102,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_s.html b/functions_s.html index 056bb15c..ee2a34f1 100644 --- a/functions_s.html +++ b/functions_s.html @@ -128,12 +128,12 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search');
  • save() : RNGClass
  • -
  • screenSaverMode() -: LCD -
  • ScreenSaverMode : LCD
  • +
  • screenSaverMode() +: LCD +
  • scroll() : Bitmap
  • @@ -444,7 +444,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_t.html b/functions_t.html index 7db31833..2c6d49ee 100644 --- a/functions_t.html +++ b/functions_t.html @@ -168,7 +168,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_type.html b/functions_type.html index 7ef9a4f9..999c4c6c 100644 --- a/functions_type.html +++ b/functions_type.html @@ -108,7 +108,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_u.html b/functions_u.html index b1bb819b..dd39248c 100644 --- a/functions_u.html +++ b/functions_u.html @@ -168,7 +168,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_v.html b/functions_v.html index 814788f1..cc2b0d11 100644 --- a/functions_v.html +++ b/functions_v.html @@ -143,7 +143,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_vars.html b/functions_vars.html index bc4e3673..29dd4942 100644 --- a/functions_vars.html +++ b/functions_vars.html @@ -157,7 +157,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_w.html b/functions_w.html index 68092d68..3dd82e59 100644 --- a/functions_w.html +++ b/functions_w.html @@ -174,7 +174,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_x.html b/functions_x.html index 317d4325..2453daed 100644 --- a/functions_x.html +++ b/functions_x.html @@ -144,7 +144,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_y.html b/functions_y.html index 584583e0..856bb5fc 100644 --- a/functions_y.html +++ b/functions_y.html @@ -135,7 +135,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/functions_~.html b/functions_~.html index fd2a56b6..1bf0f22f 100644 --- a/functions_~.html +++ b/functions_~.html @@ -243,7 +243,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/group__power__save.html b/group__power__save.html index 58018ea6..50621e4a 100644 --- a/group__power__save.html +++ b/group__power__save.html @@ -201,7 +201,7 @@ void  diff --git a/hierarchy.html b/hierarchy.html index 6f3aacde..2fce6de2 100644 --- a/hierarchy.html +++ b/hierarchy.html @@ -179,7 +179,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/index.html b/index.html index 1e69d99e..a4edc876 100644 --- a/index.html +++ b/index.html @@ -165,7 +165,7 @@ Other diff --git a/ir-dumpir_8dox.html b/ir-dumpir_8dox.html index fc6c8f17..74629eb4 100644 --- a/ir-dumpir_8dox.html +++ b/ir-dumpir_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ir-snake_8dox.html b/ir-snake_8dox.html index 55aed3ff..dbbae464 100644 --- a/ir-snake_8dox.html +++ b/ir-snake_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ir_dumpir.html b/ir_dumpir.html index e4e26864..2950046d 100644 --- a/ir_dumpir.html +++ b/ir_dumpir.html @@ -283,7 +283,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/ir_snake.html b/ir_snake.html index 232390f0..8063f528 100644 --- a/ir_snake.html +++ b/ir_snake.html @@ -273,7 +273,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/lcd-form_8dox.html b/lcd-form_8dox.html index 8ccd84b8..6ca7ab96 100644 --- a/lcd-form_8dox.html +++ b/lcd-form_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/lcd-helloworld_8dox.html b/lcd-helloworld_8dox.html index f0ffbebe..ab628291 100644 --- a/lcd-helloworld_8dox.html +++ b/lcd-helloworld_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/lcd_form.html b/lcd_form.html index e12242d9..c5d23d83 100644 --- a/lcd_form.html +++ b/lcd_form.html @@ -216,7 +216,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/lcd_hello_world.html b/lcd_hello_world.html index 069f6a7f..63e3c090 100644 --- a/lcd_hello_world.html +++ b/lcd_hello_world.html @@ -166,7 +166,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/mainpage_8dox.html b/mainpage_8dox.html index 438e61cc..9d14c24d 100644 --- a/mainpage_8dox.html +++ b/mainpage_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/modules.html b/modules.html index d9c75f01..169227b2 100644 --- a/modules.html +++ b/modules.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/newhope-small_8dox.html b/newhope-small_8dox.html index c782ca8c..b0826677 100644 --- a/newhope-small_8dox.html +++ b/newhope-small_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/newhope_small.html b/newhope_small.html index cb871eb5..1bfc7b73 100644 --- a/newhope_small.html +++ b/newhope_small.html @@ -250,7 +250,7 @@ Summary diff --git a/pages.html b/pages.html index 4e929af3..f1f2dc2e 100644 --- a/pages.html +++ b/pages.html @@ -86,24 +86,25 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); oCharlieplexing Example oCylon Eyes Example oStar Trek Example -oRing Oscillator Noise Sources -oGenerating random numbers -oCryptographic Library -oDot Matrix Display Demo -oRunning figure example -oDumping Infrared Remote Control Codes -oSnake Video Game Using an Infrared Remote Control -oForm example for LCD displays -oHello World for Freetronics LCD -oSmall Memory Footprint New Hope -oSerial port Shell example -\Telnet server example +oUsing the cryptography library with ESP8266 +oRing Oscillator Noise Sources +oGenerating random numbers +oCryptographic Library +oDot Matrix Display Demo +oRunning figure example +oDumping Infrared Remote Control Codes +oSnake Video Game Using an Infrared Remote Control +oForm example for LCD displays +oHello World for Freetronics LCD +oSmall Memory Footprint New Hope +oSerial port Shell example +\Telnet server example diff --git a/search/all_10.js b/search/all_10.js index 0beb4659..2c85e2ef 100644 --- a/search/all_10.js +++ b/search/all_10.js @@ -4,7 +4,7 @@ var searchData= ['snake_20video_20game_20using_20an_20infrared_20remote_20control',['Snake Video Game Using an Infrared Remote Control',['../ir_snake.html',1,'']]], ['small_20memory_20footprint_20new_20hope',['Small Memory Footprint New Hope',['../newhope_small.html',1,'']]], ['save',['save',['../classRNGClass.html#a139584fb249148e2058d1d645d090db7',1,'RNGClass']]], - ['screensavermode',['screenSaverMode',['../classLCD.html#a1917fa285f81f476b4c7cc20d15456b8',1,'LCD::screenSaverMode() const '],['../classLCD.html#a264bf94308c95d8598426e13dc8cdb28',1,'LCD::ScreenSaverMode()']]], + ['screensavermode',['ScreenSaverMode',['../classLCD.html#a264bf94308c95d8598426e13dc8cdb28',1,'LCD::ScreenSaverMode()'],['../classLCD.html#a1917fa285f81f476b4c7cc20d15456b8',1,'LCD::screenSaverMode() const ']]], ['scroll',['scroll',['../classBitmap.html#ae08eb6f9086f9923d8dc83a469ae4c4a',1,'Bitmap::scroll(int dx, int dy, Color fillColor=Black)'],['../classBitmap.html#af79ad4432297ff453fddc55625fec485',1,'Bitmap::scroll(int x, int y, int width, int height, int dx, int dy, Color fillColor=Black)']]], ['scrolldown',['scrollDown',['../classTerminal.html#a661474bb4790aa82178b3ce9a85e5dea',1,'Terminal']]], ['scrollup',['scrollUp',['../classTerminal.html#a30d8d69fd84cafc6c2c94ae6fc65b690',1,'Terminal']]], diff --git a/search/all_12.js b/search/all_12.js index f3d9a544..4f831ead 100644 --- a/search/all_12.js +++ b/search/all_12.js @@ -1,5 +1,6 @@ var searchData= [ + ['using_20the_20cryptography_20library_20with_20esp8266',['Using the cryptography library with ESP8266',['../crypto_esp.html',1,'']]], ['underline',['underline',['../classTerminal.html#a0e23c452353e7fdf0881d37521f3d105',1,'Terminal']]], ['unicodekey',['unicodeKey',['../classTerminal.html#a33e5eb60d69e4ccf6e3c90f7428b4961',1,'Terminal']]], ['unpackbe',['unpackBE',['../classBigNumberUtil.html#a63f9d7884eb36227d39e1b95e219d865',1,'BigNumberUtil']]], diff --git a/search/all_2.js b/search/all_2.js index ee043e76..7d324f8e 100644 --- a/search/all_2.js +++ b/search/all_2.js @@ -24,6 +24,7 @@ var searchData= ['copy',['copy',['../classBitmap.html#ab22fe1f3871934987a670b559f67c67c',1,'Bitmap']]], ['count',['count',['../classCharlieplex.html#a5008aa4143d381ce34a3aed1a3843e4e',1,'Charlieplex::count()'],['../classShellArguments.html#ad1d8f103c645bc280e518f2522a62cc1',1,'ShellArguments::count()']]], ['cryptographic_20library',['Cryptographic Library',['../crypto.html',1,'']]], + ['crypto_2desp_2edox',['crypto-esp.dox',['../crypto-esp_8dox.html',1,'']]], ['crypto_2drng_2dring_2edox',['crypto-rng-ring.dox',['../crypto-rng-ring_8dox.html',1,'']]], ['crypto_2drng_2edox',['crypto-rng.dox',['../crypto-rng_8dox.html',1,'']]], ['crypto_2edox',['crypto.dox',['../crypto_8dox.html',1,'']]], diff --git a/search/all_a.js b/search/all_a.js index 41efafab..bd27634d 100644 --- a/search/all_a.js +++ b/search/all_a.js @@ -1,7 +1,7 @@ var searchData= [ ['label',['label',['../classField.html#aaa861ef917130c989a955bc75c683afe',1,'Field']]], - ['lcd',['LCD',['../classLCD.html',1,'LCD'],['../classField.html#a5cf21bf958a71e51feac9e1bf9f599d1',1,'Field::lcd()'],['../classLCD.html#a00bb2db1390721abc7b24ac4b8c276c8',1,'LCD::LCD()'],['../classLCD.html#a067bc741cf27f143aba5d9f147908401',1,'LCD::LCD(uint8_t pin9)'],['../classLCD.html#a203d268bef6c61fa293562dbb0e9f51e',1,'LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)']]], + ['lcd',['LCD',['../classLCD.html',1,'LCD'],['../classLCD.html#a00bb2db1390721abc7b24ac4b8c276c8',1,'LCD::LCD()'],['../classLCD.html#a067bc741cf27f143aba5d9f147908401',1,'LCD::LCD(uint8_t pin9)'],['../classLCD.html#a203d268bef6c61fa293562dbb0e9f51e',1,'LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)'],['../classField.html#a5cf21bf958a71e51feac9e1bf9f599d1',1,'Field::lcd()']]], ['lcd_2dform_2edox',['lcd-form.dox',['../lcd-form_8dox.html',1,'']]], ['lcd_2dhelloworld_2edox',['lcd-helloworld.dox',['../lcd-helloworld_8dox.html',1,'']]], ['led',['led',['../classCharlieplex.html#a90fd09f24b62424b0b7b8bcdb0140b9d',1,'Charlieplex']]], diff --git a/search/files_2.js b/search/files_2.js index 4f67a847..8d28e41d 100644 --- a/search/files_2.js +++ b/search/files_2.js @@ -1,5 +1,6 @@ var searchData= [ + ['crypto_2desp_2edox',['crypto-esp.dox',['../crypto-esp_8dox.html',1,'']]], ['crypto_2drng_2dring_2edox',['crypto-rng-ring.dox',['../crypto-rng-ring_8dox.html',1,'']]], ['crypto_2drng_2edox',['crypto-rng.dox',['../crypto-rng_8dox.html',1,'']]], ['crypto_2edox',['crypto.dox',['../crypto_8dox.html',1,'']]] diff --git a/search/functions_a.js b/search/functions_a.js index f9b30a30..9b3cf49b 100644 --- a/search/functions_a.js +++ b/search/functions_a.js @@ -1,7 +1,7 @@ var searchData= [ ['label',['label',['../classField.html#aaa861ef917130c989a955bc75c683afe',1,'Field']]], - ['lcd',['lcd',['../classField.html#a5cf21bf958a71e51feac9e1bf9f599d1',1,'Field::lcd()'],['../classLCD.html#a00bb2db1390721abc7b24ac4b8c276c8',1,'LCD::LCD()'],['../classLCD.html#a067bc741cf27f143aba5d9f147908401',1,'LCD::LCD(uint8_t pin9)'],['../classLCD.html#a203d268bef6c61fa293562dbb0e9f51e',1,'LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)']]], + ['lcd',['LCD',['../classLCD.html#a00bb2db1390721abc7b24ac4b8c276c8',1,'LCD::LCD()'],['../classLCD.html#a067bc741cf27f143aba5d9f147908401',1,'LCD::LCD(uint8_t pin9)'],['../classLCD.html#a203d268bef6c61fa293562dbb0e9f51e',1,'LCD::LCD(uint8_t rs, uint8_t enable, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3)'],['../classField.html#a5cf21bf958a71e51feac9e1bf9f599d1',1,'Field::lcd()']]], ['led',['led',['../classCharlieplex.html#a90fd09f24b62424b0b7b8bcdb0140b9d',1,'Charlieplex']]], ['listfield',['ListField',['../classListField.html#a118501da7edb0b0bc6b493734975b4e9',1,'ListField::ListField(const String &label)'],['../classListField.html#aa303898a1f74b52c1c4982653de488b7',1,'ListField::ListField(Form &form, const String &label, ListItems items, int value=0)']]], ['loginshell',['LoginShell',['../classLoginShell.html#a8a6e6c259bc6415eb9cfbb13980e31d4',1,'LoginShell']]], diff --git a/search/pages_a.html b/search/pages_a.html new file mode 100644 index 00000000..1c097e55 --- /dev/null +++ b/search/pages_a.html @@ -0,0 +1,26 @@ + + + + + + + + + +
    +
    Loading...
    +
    + +
    Searching...
    +
    No Matches
    + +
    + + diff --git a/search/pages_a.js b/search/pages_a.js new file mode 100644 index 00000000..c53fdfac --- /dev/null +++ b/search/pages_a.js @@ -0,0 +1,4 @@ +var searchData= +[ + ['using_20the_20cryptography_20library_20with_20esp8266',['Using the cryptography library with ESP8266',['../crypto_esp.html',1,'']]] +]; diff --git a/search/search.js b/search/search.js index 74006a55..8a94f1c1 100644 --- a/search/search.js +++ b/search/search.js @@ -17,7 +17,7 @@ var indexSectionsWithContent = 7: "bcdglmrstwy", 8: "s", 9: "p", - 10: "abcdfghrst" + 10: "abcdfghrstu" }; var indexSectionNames = diff --git a/shell-serial_8dox.html b/shell-serial_8dox.html index 14e80609..ab8e447f 100644 --- a/shell-serial_8dox.html +++ b/shell-serial_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/shell-telnet_8dox.html b/shell-telnet_8dox.html index a3973282..5c94dd53 100644 --- a/shell-telnet_8dox.html +++ b/shell-telnet_8dox.html @@ -87,7 +87,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/shell_serial.html b/shell_serial.html index 4d428b8b..641c9b2e 100644 --- a/shell_serial.html +++ b/shell_serial.html @@ -156,7 +156,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/shell_telnet.html b/shell_telnet.html index 3ecb1fe6..d5ec859c 100644 --- a/shell_telnet.html +++ b/shell_telnet.html @@ -165,7 +165,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/structNewHopePrivateKey.html b/structNewHopePrivateKey.html index 0a180ee0..196adc48 100644 --- a/structNewHopePrivateKey.html +++ b/structNewHopePrivateKey.html @@ -104,7 +104,7 @@ var searchBox = new SearchBox("searchBox", "search",false,'Search'); diff --git a/structRTCAlarm.html b/structRTCAlarm.html index 37f7e1a1..c423a3da 100644 --- a/structRTCAlarm.html +++ b/structRTCAlarm.html @@ -200,7 +200,7 @@ uint8_t  diff --git a/structRTCDate.html b/structRTCDate.html index 1e10ca75..cb5f2c37 100644 --- a/structRTCDate.html +++ b/structRTCDate.html @@ -123,7 +123,7 @@ uint8_t  diff --git a/structRTCTime.html b/structRTCTime.html index a7ccee69..c2c6b289 100644 --- a/structRTCTime.html +++ b/structRTCTime.html @@ -123,7 +123,7 @@ uint8_t