diff --git a/libraries/Crypto/BigNumberUtil.cpp b/libraries/Crypto/BigNumberUtil.cpp index d942ab22..976603c5 100644 --- a/libraries/Crypto/BigNumberUtil.cpp +++ b/libraries/Crypto/BigNumberUtil.cpp @@ -96,7 +96,7 @@ void BigNumberUtil::unpackLE(limb_t *limbs, size_t count, --count; len -= 4; } - if (count > 0) { + if (count > 0 && len > 0) { if (len == 3) { *limbs++ = ((limb_t)(bytes[0])) | (((limb_t)(bytes[1])) << 8) | @@ -104,7 +104,7 @@ void BigNumberUtil::unpackLE(limb_t *limbs, size_t count, } else if (len == 2) { *limbs++ = ((limb_t)(bytes[0])) | (((limb_t)(bytes[1])) << 8); - } else if (len == 1) { + } else { *limbs++ = ((limb_t)(bytes[0])); } --count; @@ -113,6 +113,35 @@ void BigNumberUtil::unpackLE(limb_t *limbs, size_t count, *limbs++ = 0; --count; } +#elif BIGNUMBER_LIMB_64BIT + while (count > 0 && len >= 8) { + *limbs++ = ((limb_t)(bytes[0])) | + (((limb_t)(bytes[1])) << 8) | + (((limb_t)(bytes[2])) << 16) | + (((limb_t)(bytes[3])) << 24) | + (((limb_t)(bytes[4])) << 32) | + (((limb_t)(bytes[5])) << 40) | + (((limb_t)(bytes[6])) << 48) | + (((limb_t)(bytes[7])) << 56); + bytes += 8; + --count; + len -= 8; + } + if (count > 0 && len > 0) { + limb_t word = 0; + uint8_t shift = 0; + while (len > 0 && shift < 64) { + word |= (((limb_t)(*bytes++)) << shift); + shift += 8; + --len; + } + *limbs++ = word; + --count; + } + while (count > 0) { + *limbs++ = 0; + --count; + } #endif } @@ -186,6 +215,33 @@ void BigNumberUtil::unpackBE(limb_t *limbs, size_t count, } } memset(limbs, 0, count * sizeof(limb_t)); +#elif BIGNUMBER_LIMB_64BIT + bytes += len; + while (count > 0 && len >= 8) { + --count; + bytes -= 8; + len -= 8; + *limbs++ = ((limb_t)(bytes[7])) | + (((limb_t)(bytes[6])) << 8) | + (((limb_t)(bytes[5])) << 16) | + (((limb_t)(bytes[4])) << 24) | + (((limb_t)(bytes[3])) << 32) | + (((limb_t)(bytes[2])) << 40) | + (((limb_t)(bytes[1])) << 48) | + (((limb_t)(bytes[0])) << 56); + } + if (count > 0 && len > 0) { + limb_t word = 0; + uint8_t shift = 0; + while (len > 0 && shift < 64) { + word |= (((limb_t)(*(--bytes))) << shift); + shift += 8; + --len; + } + *limbs++ = word; + --count; + } + memset(limbs, 0, count * sizeof(limb_t)); #endif } @@ -272,6 +328,31 @@ void BigNumberUtil::packLE(uint8_t *bytes, size_t len, } } memset(bytes, 0, len); +#elif BIGNUMBER_LIMB_64BIT + limb_t word; + while (count > 0 && len >= 8) { + word = *limbs++; + bytes[0] = (uint8_t)word; + bytes[1] = (uint8_t)(word >> 8); + bytes[2] = (uint8_t)(word >> 16); + bytes[3] = (uint8_t)(word >> 24); + bytes[4] = (uint8_t)(word >> 32); + bytes[5] = (uint8_t)(word >> 40); + bytes[6] = (uint8_t)(word >> 48); + bytes[7] = (uint8_t)(word >> 56); + --count; + len -= 8; + bytes += 8; + } + if (count > 0) { + word = *limbs; + while (len > 0) { + *bytes++ = (uint8_t)word; + word >>= 8; + --len; + } + } + memset(bytes, 0, len); #endif } @@ -362,6 +443,39 @@ void BigNumberUtil::packBE(uint8_t *bytes, size_t len, *bytes++ = (uint8_t)(word >> 8); *bytes++ = (uint8_t)word; } +#elif BIGNUMBER_LIMB_64BIT + size_t countBytes = count * sizeof(limb_t); + limb_t word; + if (len >= countBytes) { + size_t size = len - countBytes; + memset(bytes, 0, size); + len -= size; + bytes += size; + limbs += count; + } else { + count = len / sizeof(limb_t); + limbs += count; + uint8_t size = len & 7; + uint8_t shift = size * 8; + word = *limbs; + while (size > 0) { + shift -= 8; + *bytes++ = (uint8_t)(word >> shift); + --size; + } + } + while (count > 0) { + --count; + word = *(--limbs); + *bytes++ = (uint8_t)(word >> 56); + *bytes++ = (uint8_t)(word >> 48); + *bytes++ = (uint8_t)(word >> 40); + *bytes++ = (uint8_t)(word >> 32); + *bytes++ = (uint8_t)(word >> 24); + *bytes++ = (uint8_t)(word >> 16); + *bytes++ = (uint8_t)(word >> 8); + *bytes++ = (uint8_t)word; + } #endif } diff --git a/libraries/Crypto/BigNumberUtil.h b/libraries/Crypto/BigNumberUtil.h index 2bf2724e..28d83e7f 100644 --- a/libraries/Crypto/BigNumberUtil.h +++ b/libraries/Crypto/BigNumberUtil.h @@ -27,16 +27,24 @@ #include // Define exactly one of these to 1 to set the size of the basic limb type. -// 16-bit limbs seem to give the best performance on 8-bit AVR micros. #if defined(__AVR__) +// 16-bit limbs seem to give the best performance on 8-bit AVR micros. #define BIGNUMBER_LIMB_8BIT 0 #define BIGNUMBER_LIMB_16BIT 1 #define BIGNUMBER_LIMB_32BIT 0 +#define BIGNUMBER_LIMB_64BIT 0 +#elif defined(__GNUC__) && __WORDSIZE == 64 +// 64-bit system with 128-bit double limbs. +#define BIGNUMBER_LIMB_8BIT 0 +#define BIGNUMBER_LIMB_16BIT 0 +#define BIGNUMBER_LIMB_32BIT 0 +#define BIGNUMBER_LIMB_64BIT 1 #else -// On all other platforms, assume 32-bit is best (e.g. ARM). +// On all other platforms, assume 32-bit is best. #define BIGNUMBER_LIMB_8BIT 0 #define BIGNUMBER_LIMB_16BIT 0 #define BIGNUMBER_LIMB_32BIT 1 +#define BIGNUMBER_LIMB_64BIT 0 #endif // Define the limb types to use on this platform. @@ -52,8 +60,12 @@ typedef uint32_t dlimb_t; typedef uint32_t limb_t; typedef int32_t slimb_t; typedef uint64_t dlimb_t; +#elif BIGNUMBER_LIMB_64BIT +typedef uint64_t limb_t; +typedef int64_t slimb_t; +typedef unsigned __int128 dlimb_t; #else -#error "limb_t must be 8, 16, or 32 bits in size" +#error "limb_t must be 8, 16, 32, or 64 bits in size" #endif class BigNumberUtil diff --git a/libraries/Crypto/Curve25519.cpp b/libraries/Crypto/Curve25519.cpp index ed17a71e..a81989ed 100644 --- a/libraries/Crypto/Curve25519.cpp +++ b/libraries/Crypto/Curve25519.cpp @@ -962,10 +962,10 @@ void Curve25519::mulA24(limb_t *result, const limb_t *x) static limb_t const a24[3] PROGMEM = {0x41, 0xDB, 0x01}; #elif BIGNUMBER_LIMB_16BIT static limb_t const a24[2] PROGMEM = {0xDB41, 0x0001}; -#elif BIGNUMBER_LIMB_32BIT +#elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT static limb_t const a24[1] PROGMEM = {0x0001DB41}; #else - #error "limb_t must be 8, 16, or 32 bits in size" + #error "limb_t must be 8, 16, 32, or 64 bits in size" #endif #define NUM_A24_LIMBS (sizeof(a24) / sizeof(limb_t)) @@ -1572,8 +1572,8 @@ bool Curve25519::sqrt(limb_t *result, const limb_t *x) { // sqrt(-1) mod (2^255 - 19). static limb_t const numSqrtM1[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x4A0EA0B0), LIMB(0xC4EE1B27), LIMB(0xAD2FE478), LIMB(0x2F431806), - LIMB(0x3DFBD7A7), LIMB(0x2B4D0099), LIMB(0x4FC1DF0B), LIMB(0x2B832480) + LIMB_PAIR(0x4A0EA0B0, 0xC4EE1B27), LIMB_PAIR(0xAD2FE478, 0x2F431806), + LIMB_PAIR(0x3DFBD7A7, 0x2B4D0099), LIMB_PAIR(0x4FC1DF0B, 0x2B832480) }; limb_t y[NUM_LIMBS_256BIT]; diff --git a/libraries/Crypto/Ed25519.cpp b/libraries/Crypto/Ed25519.cpp index 39c7e91a..a62a3e08 100644 --- a/libraries/Crypto/Ed25519.cpp +++ b/libraries/Crypto/Ed25519.cpp @@ -77,38 +77,38 @@ // 37095705934669439343138083508754565189542113879843219016388785533085940283555 static limb_t const numD[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x135978A3), LIMB(0x75EB4DCA), LIMB(0x4141D8AB), LIMB(0x00700A4D), - LIMB(0x7779E898), LIMB(0x8CC74079), LIMB(0x2B6FFE73), LIMB(0x52036CEE) + LIMB_PAIR(0x135978A3, 0x75EB4DCA), LIMB_PAIR(0x4141D8AB, 0x00700A4D), + LIMB_PAIR(0x7779E898, 0x8CC74079), LIMB_PAIR(0x2B6FFE73, 0x52036CEE) }; // d * 2 static limb_t const numDx2[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x26B2F159), LIMB(0xEBD69B94), LIMB(0x8283B156), LIMB(0x00E0149A), - LIMB(0xEEF3D130), LIMB(0x198E80F2), LIMB(0x56DFFCE7), LIMB(0x2406D9DC) + LIMB_PAIR(0x26B2F159, 0xEBD69B94), LIMB_PAIR(0x8283B156, 0x00E0149A), + LIMB_PAIR(0xEEF3D130, 0x198E80F2), LIMB_PAIR(0x56DFFCE7, 0x2406D9DC) }; // Extended homogenous co-ordinates for the base point. static limb_t const numBx[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x8F25D51A), LIMB(0xC9562D60), LIMB(0x9525A7B2), LIMB(0x692CC760), - LIMB(0xFDD6DC5C), LIMB(0xC0A4E231), LIMB(0xCD6E53FE), LIMB(0x216936D3) + LIMB_PAIR(0x8F25D51A, 0xC9562D60), LIMB_PAIR(0x9525A7B2, 0x692CC760), + LIMB_PAIR(0xFDD6DC5C, 0xC0A4E231), LIMB_PAIR(0xCD6E53FE, 0x216936D3) }; static limb_t const numBy[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x66666658), LIMB(0x66666666), LIMB(0x66666666), LIMB(0x66666666), - LIMB(0x66666666), LIMB(0x66666666), LIMB(0x66666666), LIMB(0x66666666) + LIMB_PAIR(0x66666658, 0x66666666), LIMB_PAIR(0x66666666, 0x66666666), + LIMB_PAIR(0x66666666, 0x66666666), LIMB_PAIR(0x66666666, 0x66666666) }; static limb_t const numBz[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x00000001), LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), - LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000) + LIMB_PAIR(0x00000001, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000), + LIMB_PAIR(0x00000000, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000) }; static limb_t const numBt[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0xA5B7DDA3), LIMB(0x6DDE8AB3), LIMB(0x775152F5), LIMB(0x20F09F80), - LIMB(0x64ABE37D), LIMB(0x66EA4E8E), LIMB(0xD78B7665), LIMB(0x67875F0F) + LIMB_PAIR(0xA5B7DDA3, 0x6DDE8AB3), LIMB_PAIR(0x775152F5, 0x20F09F80), + LIMB_PAIR(0x64ABE37D, 0x66EA4E8E), LIMB_PAIR(0xD78B7665, 0x67875F0F) }; // 2^252 + 27742317777372353535851937790883648493 static limb_t const numQ[NUM_LIMBS_256BIT] PROGMEM = { - LIMB(0x5CF5D3ED), LIMB(0x5812631A), LIMB(0xA2F79CD6), LIMB(0x14DEF9DE), - LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), LIMB(0x10000000) + LIMB_PAIR(0x5CF5D3ED, 0x5812631A), LIMB_PAIR(0xA2F79CD6, 0x14DEF9DE), + LIMB_PAIR(0x00000000, 0x00000000), LIMB_PAIR(0x00000000, 0x10000000) }; /** @endcond */ @@ -316,8 +316,8 @@ void Ed25519::reduceQ(limb_t *result, limb_t *r) // precision in m, r is at most two subtractions of q away from the // final result. static limb_t const numM[NUM_LIMBS_256BIT + 1] PROGMEM = { - LIMB(0x0A2C131B), LIMB(0xED9CE5A3), LIMB(0x086329A7), LIMB(0x2106215D), - LIMB(0xFFFFFFEB), LIMB(0xFFFFFFFF), LIMB(0xFFFFFFFF), LIMB(0xFFFFFFFF), + LIMB_PAIR(0x0A2C131B, 0xED9CE5A3), LIMB_PAIR(0x086329A7, 0x2106215D), + LIMB_PAIR(0xFFFFFFEB, 0xFFFFFFFF), LIMB_PAIR(0xFFFFFFFF, 0xFFFFFFFF), 0x0F }; limb_t temp[NUM_LIMBS_512BIT + NUM_LIMBS_256BIT + 1]; diff --git a/libraries/Crypto/P521.cpp b/libraries/Crypto/P521.cpp index 8ebeb2d0..a8c5e425 100644 --- a/libraries/Crypto/P521.cpp +++ b/libraries/Crypto/P521.cpp @@ -26,7 +26,6 @@ #include "SHA512.h" #include "utility/LimbUtil.h" #include -#include /** * \class P521 P521.h @@ -77,37 +76,37 @@ // The group order "q" value from RFC 4754 and RFC 5903. This is the // same as the "n" value from Appendix D.1.2.5 of NIST FIPS 186-4. static limb_t const P521_q[NUM_LIMBS_521BIT] PROGMEM = { - LIMB(0x91386409), LIMB(0xbb6fb71e), LIMB(0x899c47ae), LIMB(0x3bb5c9b8), - LIMB(0xf709a5d0), LIMB(0x7fcc0148), LIMB(0xbf2f966b), LIMB(0x51868783), - LIMB(0xfffffffa), LIMB(0xffffffff), LIMB(0xffffffff), LIMB(0xffffffff), - LIMB(0xffffffff), LIMB(0xffffffff), LIMB(0xffffffff), LIMB(0xffffffff), + LIMB_PAIR(0x91386409, 0xbb6fb71e), LIMB_PAIR(0x899c47ae, 0x3bb5c9b8), + LIMB_PAIR(0xf709a5d0, 0x7fcc0148), LIMB_PAIR(0xbf2f966b, 0x51868783), + LIMB_PAIR(0xfffffffa, 0xffffffff), LIMB_PAIR(0xffffffff, 0xffffffff), + LIMB_PAIR(0xffffffff, 0xffffffff), LIMB_PAIR(0xffffffff, 0xffffffff), LIMB_PARTIAL(0x1ff) }; // The "b" value from Appendix D.1.2.5 of NIST FIPS 186-4. static limb_t const P521_b[NUM_LIMBS_521BIT] PROGMEM = { - LIMB(0x6b503f00), LIMB(0xef451fd4), LIMB(0x3d2c34f1), LIMB(0x3573df88), - LIMB(0x3bb1bf07), LIMB(0x1652c0bd), LIMB(0xec7e937b), LIMB(0x56193951), - LIMB(0x8ef109e1), LIMB(0xb8b48991), LIMB(0x99b315f3), LIMB(0xa2da725b), - LIMB(0xb68540ee), LIMB(0x929a21a0), LIMB(0x8e1c9a1f), LIMB(0x953eb961), + LIMB_PAIR(0x6b503f00, 0xef451fd4), LIMB_PAIR(0x3d2c34f1, 0x3573df88), + LIMB_PAIR(0x3bb1bf07, 0x1652c0bd), LIMB_PAIR(0xec7e937b, 0x56193951), + LIMB_PAIR(0x8ef109e1, 0xb8b48991), LIMB_PAIR(0x99b315f3, 0xa2da725b), + LIMB_PAIR(0xb68540ee, 0x929a21a0), LIMB_PAIR(0x8e1c9a1f, 0x953eb961), LIMB_PARTIAL(0x051) }; // The "Gx" value from Appendix D.1.2.5 of NIST FIPS 186-4. static limb_t const P521_Gx[NUM_LIMBS_521BIT] PROGMEM = { - LIMB(0xc2e5bd66), LIMB(0xf97e7e31), LIMB(0x856a429b), LIMB(0x3348b3c1), - LIMB(0xa2ffa8de), LIMB(0xfe1dc127), LIMB(0xefe75928), LIMB(0xa14b5e77), - LIMB(0x6b4d3dba), LIMB(0xf828af60), LIMB(0x053fb521), LIMB(0x9c648139), - LIMB(0x2395b442), LIMB(0x9e3ecb66), LIMB(0x0404e9cd), LIMB(0x858e06b7), + LIMB_PAIR(0xc2e5bd66, 0xf97e7e31), LIMB_PAIR(0x856a429b, 0x3348b3c1), + LIMB_PAIR(0xa2ffa8de, 0xfe1dc127), LIMB_PAIR(0xefe75928, 0xa14b5e77), + LIMB_PAIR(0x6b4d3dba, 0xf828af60), LIMB_PAIR(0x053fb521, 0x9c648139), + LIMB_PAIR(0x2395b442, 0x9e3ecb66), LIMB_PAIR(0x0404e9cd, 0x858e06b7), LIMB_PARTIAL(0x0c6) }; // The "Gy" value from Appendix D.1.2.5 of NIST FIPS 186-4. static limb_t const P521_Gy[NUM_LIMBS_521BIT] PROGMEM = { - LIMB(0x9fd16650), LIMB(0x88be9476), LIMB(0xa272c240), LIMB(0x353c7086), - LIMB(0x3fad0761), LIMB(0xc550b901), LIMB(0x5ef42640), LIMB(0x97ee7299), - LIMB(0x273e662c), LIMB(0x17afbd17), LIMB(0x579b4468), LIMB(0x98f54449), - LIMB(0x2c7d1bd9), LIMB(0x5c8a5fb4), LIMB(0x9a3bc004), LIMB(0x39296a78), + LIMB_PAIR(0x9fd16650, 0x88be9476), LIMB_PAIR(0xa272c240, 0x353c7086), + LIMB_PAIR(0x3fad0761, 0xc550b901), LIMB_PAIR(0x5ef42640, 0x97ee7299), + LIMB_PAIR(0x273e662c, 0x17afbd17), LIMB_PAIR(0x579b4468, 0x98f54449), + LIMB_PAIR(0x2c7d1bd9, 0x5c8a5fb4), LIMB_PAIR(0x9a3bc004, 0x39296a78), LIMB_PARTIAL(0x118) }; @@ -783,7 +782,7 @@ bool P521::inRange(const limb_t *x) */ void P521::reduce(limb_t *result, const limb_t *x) { -#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT +#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT // According to NIST FIPS 186-4, we add the high 521 bits to the // low 521 bits and then do a trial subtraction of 2^521 - 1. // We do both in a single step. Subtracting 2^521 - 1 is equivalent @@ -881,7 +880,7 @@ void P521::reduceQuick(limb_t *x) // If the carry out was 0, then we need to add 2^521 - 1 back again. // To preserve the timing we perform a conditional subtract of 1 and // then mask off the high bits. -#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT +#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT carry = ((x[NUM_LIMBS_521BIT - 1] >> 9) ^ 0x01) & 0x01; xx = x; for (index = 0; index < NUM_LIMBS_521BIT; ++index) { @@ -1005,7 +1004,7 @@ void P521::mulLiteral(limb_t *result, const limb_t *x, limb_t y) // Reduce the value modulo 2^521 - 1. The high half is only a // single limb, so we can short-cut some of reduce() here. -#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT +#if BIGNUMBER_LIMB_16BIT || BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT limb_t word = result[NUM_LIMBS_521BIT - 1]; carry = (word >> 9) + 1; word &= 0x1FF; @@ -1392,10 +1391,10 @@ void P521::reduceQ(limb_t *result, const limb_t *r) // Note: m is a 522-bit number, which fits in the same number of limbs // as a 521-bit number assuming that limbs are 8 bits or more in size. static limb_t const numM[NUM_LIMBS_521BIT] PROGMEM = { - LIMB(0x6EC79BF7), LIMB(0x449048E1), LIMB(0x7663B851), LIMB(0xC44A3647), - LIMB(0x08F65A2F), LIMB(0x8033FEB7), LIMB(0x40D06994), LIMB(0xAE79787C), - LIMB(0x00000005), LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), - LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), LIMB(0x00000000), + LIMB_PAIR(0x6EC79BF7, 0x449048E1), LIMB_PAIR(0x7663B851, 0xC44A3647), + LIMB_PAIR(0x08F65A2F, 0x8033FEB7), LIMB_PAIR(0x40D06994, 0xAE79787C), + LIMB_PAIR(0x00000005, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000), + LIMB_PAIR(0x00000000, 0x00000000), LIMB_PAIR(0x00000000, 0x00000000), LIMB_PARTIAL(0x200) }; limb_t temp[NUM_LIMBS_1042BIT + NUM_LIMBS_521BIT]; @@ -1412,10 +1411,10 @@ void P521::reduceQ(limb_t *result, const limb_t *r) temp2[index] = (limb_t)carry; carry >>= LIMB_BITS; } -#elif BIGNUMBER_LIMB_32BIT +#elif BIGNUMBER_LIMB_32BIT || BIGNUMBER_LIMB_64BIT dlimb_t carry = temp[NUM_LIMBS_BITS(1024)] >> 18; for (uint8_t index = 0; index < NUM_LIMBS_521BIT; ++index) { - carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1024) + index + 1])) << 14; + carry += ((dlimb_t)(temp[NUM_LIMBS_BITS(1024) + index + 1])) << (LIMB_BITS - 18); temp2[index] = (limb_t)carry; carry >>= LIMB_BITS; } @@ -1466,8 +1465,8 @@ void P521::recipQ(limb_t *result, const limb_t *x) { // Bottom 265 bits of q - 2. The top 256 bits are all-1's. static limb_t const P521_q_m2[] PROGMEM = { - LIMB(0x91386407), LIMB(0xbb6fb71e), LIMB(0x899c47ae), LIMB(0x3bb5c9b8), - LIMB(0xf709a5d0), LIMB(0x7fcc0148), LIMB(0xbf2f966b), LIMB(0x51868783), + LIMB_PAIR(0x91386407, 0xbb6fb71e), LIMB_PAIR(0x899c47ae, 0x3bb5c9b8), + LIMB_PAIR(0xf709a5d0, 0x7fcc0148), LIMB_PAIR(0xbf2f966b, 0x51868783), LIMB_PARTIAL(0x1fa) }; diff --git a/libraries/Crypto/Poly1305.cpp b/libraries/Crypto/Poly1305.cpp index 01ed6546..c9e28518 100644 --- a/libraries/Crypto/Poly1305.cpp +++ b/libraries/Crypto/Poly1305.cpp @@ -72,6 +72,9 @@ #elif BIGNUMBER_LIMB_32BIT #define lelimbtoh(x) (le32toh((x))) #define htolelimb(x) (htole32((x))) +#elif BIGNUMBER_LIMB_64BIT +#define lelimbtoh(x) (le64toh((x))) +#define htolelimb(x) (htole64((x))) #endif #if defined(CRYPTO_LITTLE_ENDIAN) #define littleToHost(r,size) do { ; } while (0) diff --git a/libraries/Crypto/examples/TestBigNumberUtil/TestBigNumberUtil.ino b/libraries/Crypto/examples/TestBigNumberUtil/TestBigNumberUtil.ino index bdc4ae98..126ad21b 100644 --- a/libraries/Crypto/examples/TestBigNumberUtil/TestBigNumberUtil.ino +++ b/libraries/Crypto/examples/TestBigNumberUtil/TestBigNumberUtil.ino @@ -223,8 +223,21 @@ static void truncateNumber(limb_t *limbs, size_t bytes) mask = 0x000000FF; else if (posn2 == 2) mask = 0x0000FFFF; +#if BIGNUMBER_LIMB_64BIT + else if (posn2 == 3) + mask = 0x00FFFFFF; + else if (posn2 == 4) + mask = 0xFFFFFFFF; + else if (posn2 == 5) + mask = 0xFFFFFFFFFF; + else if (posn2 == 6) + mask = 0xFFFFFFFFFFFF; + else + mask = 0xFFFFFFFFFFFFFF; +#else else mask = 0x00FFFFFF; +#endif limbs[posn / sizeof(limb_t)] &= mask; } } diff --git a/libraries/Crypto/utility/LimbUtil.h b/libraries/Crypto/utility/LimbUtil.h index bdbaca0a..313a5e46 100644 --- a/libraries/Crypto/utility/LimbUtil.h +++ b/libraries/Crypto/utility/LimbUtil.h @@ -42,20 +42,29 @@ #define pgm_read_limb(x) (pgm_read_word((x))) #elif BIGNUMBER_LIMB_32BIT #define pgm_read_limb(x) (pgm_read_dword((x))) +#elif BIGNUMBER_LIMB_64BIT +#define pgm_read_limb(x) (pgm_read_qword((x))) #endif // Expand a 32-bit value into a set of limbs depending upon the limb size. // This is used when initializing constant big number values in the code. +// For 64-bit system compatibility it is necessary to use LIMB_PAIR(x, y). #if BIGNUMBER_LIMB_8BIT #define LIMB(value) ((uint8_t)(value)), \ ((uint8_t)((value) >> 8)), \ ((uint8_t)((value) >> 16)), \ ((uint8_t)((value) >> 24)) +#define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) #elif BIGNUMBER_LIMB_16BIT #define LIMB(value) ((uint16_t)(value)), \ ((uint16_t)((value) >> 16)) +#define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) #elif BIGNUMBER_LIMB_32BIT #define LIMB(value) (value) +#define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) +#elif BIGNUMBER_LIMB_64BIT +#define LIMB(value) (value) +#define LIMB_PAIR(x,y) ((((uint64_t)(y)) << 32) | ((uint64_t)(x))) #endif #endif