mirror of
https://github.com/taigrr/arduinolibs
synced 2025-01-18 04:33:12 -08:00
Centralize the definition of big number limb types
This commit is contained in:
parent
a3d7f61b96
commit
3bcfbcd43b
51
libraries/Crypto/BigNumberUtil.h
Normal file
51
libraries/Crypto/BigNumberUtil.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Southern Storm Software, Pty Ltd.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CRYPTO_BIGNUMBERUTIL_h
|
||||||
|
#define CRYPTO_BIGNUMBERUTIL_h
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
#define BIGNUMBER_LIMB_8BIT 0
|
||||||
|
#define BIGNUMBER_LIMB_16BIT 1
|
||||||
|
#define BIGNUMBER_LIMB_32BIT 0
|
||||||
|
|
||||||
|
// Define the limb types to use on this platform.
|
||||||
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
|
typedef uint8_t limb_t;
|
||||||
|
typedef int8_t slimb_t;
|
||||||
|
typedef uint16_t dlimb_t;
|
||||||
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
|
typedef uint16_t limb_t;
|
||||||
|
typedef int16_t slimb_t;
|
||||||
|
typedef uint32_t dlimb_t;
|
||||||
|
#elif BIGNUMBER_LIMB_32BIT
|
||||||
|
typedef uint32_t limb_t;
|
||||||
|
typedef int32_t slimb_t;
|
||||||
|
typedef uint64_t dlimb_t;
|
||||||
|
#else
|
||||||
|
#error "limb_t must be 8, 16, or 32 bits in size"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
@ -468,7 +468,7 @@ void Curve25519::reduce(limb_t *result, limb_t *x, uint8_t size)
|
|||||||
* the caller knows that \a x is within the described range. A single
|
* the caller knows that \a x is within the described range. A single
|
||||||
* trial subtraction is all that is needed to reduce the number.
|
* trial subtraction is all that is needed to reduce the number.
|
||||||
*/
|
*/
|
||||||
Curve25519::limb_t Curve25519::reduceQuick(limb_t *x)
|
limb_t Curve25519::reduceQuick(limb_t *x)
|
||||||
{
|
{
|
||||||
limb_t temp[NUM_LIMBS];
|
limb_t temp[NUM_LIMBS];
|
||||||
dlimb_t carry;
|
dlimb_t carry;
|
||||||
@ -570,13 +570,13 @@ void Curve25519::mul(limb_t *result, const limb_t *x, const limb_t *y)
|
|||||||
void Curve25519::mulA24(limb_t *result, const limb_t *x)
|
void Curve25519::mulA24(limb_t *result, const limb_t *x)
|
||||||
{
|
{
|
||||||
// The constant a24 = 121665 (0x1DB41) as a limb array.
|
// The constant a24 = 121665 (0x1DB41) as a limb array.
|
||||||
#if CURVE25519_LIMB_8BIT
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
static limb_t const a24[3] PROGMEM = {0x41, 0xDB, 0x01};
|
static limb_t const a24[3] PROGMEM = {0x41, 0xDB, 0x01};
|
||||||
#define pgm_read_a24(index) (pgm_read_byte(&(a24[(index)])))
|
#define pgm_read_a24(index) (pgm_read_byte(&(a24[(index)])))
|
||||||
#elif CURVE25519_LIMB_16BIT
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
static limb_t const a24[2] PROGMEM = {0xDB41, 0x0001};
|
static limb_t const a24[2] PROGMEM = {0xDB41, 0x0001};
|
||||||
#define pgm_read_a24(index) (pgm_read_word(&(a24[(index)])))
|
#define pgm_read_a24(index) (pgm_read_word(&(a24[(index)])))
|
||||||
#elif CURVE25519_LIMB_32BIT
|
#elif BIGNUMBER_LIMB_32BIT
|
||||||
static limb_t const a24[1] PROGMEM = {0x0001DB41};
|
static limb_t const a24[1] PROGMEM = {0x0001DB41};
|
||||||
#define pgm_read_a24(index) (pgm_read_dword(&(a24[(index)])))
|
#define pgm_read_a24(index) (pgm_read_dword(&(a24[(index)])))
|
||||||
#else
|
#else
|
||||||
@ -781,15 +781,15 @@ void Curve25519::recip(limb_t *result, const limb_t *x)
|
|||||||
*/
|
*/
|
||||||
void Curve25519::unpack(limb_t *result, const uint8_t *x)
|
void Curve25519::unpack(limb_t *result, const uint8_t *x)
|
||||||
{
|
{
|
||||||
#if CURVE25519_LIMB_8BIT
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
memcpy(result, x, 32);
|
memcpy(result, x, 32);
|
||||||
result[31] &= 0x7F;
|
result[31] &= 0x7F;
|
||||||
#elif CURVE25519_LIMB_16BIT
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
for (uint8_t posn = 0; posn < 16; ++posn) {
|
for (uint8_t posn = 0; posn < 16; ++posn) {
|
||||||
result[posn] = ((limb_t)x[posn * 2]) | (((limb_t)x[posn * 2 + 1]) << 8);
|
result[posn] = ((limb_t)x[posn * 2]) | (((limb_t)x[posn * 2 + 1]) << 8);
|
||||||
}
|
}
|
||||||
result[15] &= 0x7FFF;
|
result[15] &= 0x7FFF;
|
||||||
#elif CURVE25519_LIMB_32BIT
|
#elif BIGNUMBER_LIMB_32BIT
|
||||||
for (uint8_t posn = 0; posn < 8; ++posn) {
|
for (uint8_t posn = 0; posn < 8; ++posn) {
|
||||||
result[posn] = ((limb_t)x[posn * 4]) |
|
result[posn] = ((limb_t)x[posn * 4]) |
|
||||||
(((limb_t)x[posn * 4 + 1]) << 8) |
|
(((limb_t)x[posn * 4 + 1]) << 8) |
|
||||||
@ -811,15 +811,15 @@ void Curve25519::unpack(limb_t *result, const uint8_t *x)
|
|||||||
*/
|
*/
|
||||||
void Curve25519::pack(uint8_t *result, const limb_t *x)
|
void Curve25519::pack(uint8_t *result, const limb_t *x)
|
||||||
{
|
{
|
||||||
#if CURVE25519_LIMB_8BIT
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
memcpy(result, x, 32);
|
memcpy(result, x, 32);
|
||||||
#elif CURVE25519_LIMB_16BIT
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
for (uint8_t posn = 0; posn < 16; ++posn) {
|
for (uint8_t posn = 0; posn < 16; ++posn) {
|
||||||
limb_t value = x[posn];
|
limb_t value = x[posn];
|
||||||
result[posn * 2] = (uint8_t)value;
|
result[posn * 2] = (uint8_t)value;
|
||||||
result[posn * 2 + 1] = (uint8_t)(value >> 8);
|
result[posn * 2 + 1] = (uint8_t)(value >> 8);
|
||||||
}
|
}
|
||||||
#elif CURVE25519_LIMB_32BIT
|
#elif BIGNUMBER_LIMB_32BIT
|
||||||
for (uint8_t posn = 0; posn < 8; ++posn) {
|
for (uint8_t posn = 0; posn < 8; ++posn) {
|
||||||
limb_t value = x[posn];
|
limb_t value = x[posn];
|
||||||
result[posn * 4] = (uint8_t)value;
|
result[posn * 4] = (uint8_t)value;
|
||||||
|
@ -23,15 +23,9 @@
|
|||||||
#ifndef CRYPTO_CURVE15519_h
|
#ifndef CRYPTO_CURVE15519_h
|
||||||
#define CRYPTO_CURVE15519_h
|
#define CRYPTO_CURVE15519_h
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "BigNumberUtil.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
// Define exactly one of these to 1 to set the size of the basic limb type.
|
|
||||||
// 16-bit limbs seems to give the best performance on 8-bit AVR micros.
|
|
||||||
#define CURVE25519_LIMB_8BIT 0
|
|
||||||
#define CURVE25519_LIMB_16BIT 1
|
|
||||||
#define CURVE25519_LIMB_32BIT 0
|
|
||||||
|
|
||||||
class Curve25519
|
class Curve25519
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -45,23 +39,6 @@ public:
|
|||||||
#else
|
#else
|
||||||
private:
|
private:
|
||||||
#endif
|
#endif
|
||||||
// Define the limb types to use on this platform.
|
|
||||||
#if CURVE25519_LIMB_8BIT
|
|
||||||
typedef uint8_t limb_t;
|
|
||||||
typedef int8_t slimb_t;
|
|
||||||
typedef uint16_t dlimb_t;
|
|
||||||
#elif CURVE25519_LIMB_16BIT
|
|
||||||
typedef uint16_t limb_t;
|
|
||||||
typedef int16_t slimb_t;
|
|
||||||
typedef uint32_t dlimb_t;
|
|
||||||
#elif CURVE25519_LIMB_32BIT
|
|
||||||
typedef uint32_t limb_t;
|
|
||||||
typedef int32_t slimb_t;
|
|
||||||
typedef uint64_t dlimb_t;
|
|
||||||
#else
|
|
||||||
#error "limb_t must be 8, 16, or 32 bits in size"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint8_t isWeakPoint(const uint8_t k[32]);
|
static uint8_t isWeakPoint(const uint8_t k[32]);
|
||||||
|
|
||||||
static void reduce(limb_t *result, limb_t *x, uint8_t size);
|
static void reduce(limb_t *result, limb_t *x, uint8_t size);
|
||||||
|
@ -63,9 +63,17 @@
|
|||||||
#define NUM_LIMBS_130BIT ((16 / sizeof(limb_t)) + 1)
|
#define NUM_LIMBS_130BIT ((16 / sizeof(limb_t)) + 1)
|
||||||
#define LIMB_BITS (sizeof(limb_t) * 8)
|
#define LIMB_BITS (sizeof(limb_t) * 8)
|
||||||
|
|
||||||
// Endian helper macros. Need modification if the size of limb_t changes.
|
// Endian helper macros for limbs and arrays of limbs.
|
||||||
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
|
#define lelimbtoh(x) (x)
|
||||||
|
#define htolelimb(x) (x)
|
||||||
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
#define lelimbtoh(x) (le16toh((x)))
|
#define lelimbtoh(x) (le16toh((x)))
|
||||||
#define htolelimb(x) (htole16((x)))
|
#define htolelimb(x) (htole16((x)))
|
||||||
|
#elif BIGNUMBER_LIMB_32BIT
|
||||||
|
#define lelimbtoh(x) (le32toh((x)))
|
||||||
|
#define htolelimb(x) (htole32((x)))
|
||||||
|
#endif
|
||||||
#if defined(CRYPTO_LITTLE_ENDIAN)
|
#if defined(CRYPTO_LITTLE_ENDIAN)
|
||||||
#define littleToHost(r,size) do { ; } while (0)
|
#define littleToHost(r,size) do { ; } while (0)
|
||||||
#else
|
#else
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
#ifndef CRYPTO_POLY1305_h
|
#ifndef CRYPTO_POLY1305_h
|
||||||
#define CRYPTO_POLY1305_h
|
#define CRYPTO_POLY1305_h
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include "BigNumberUtil.h"
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
class Poly1305
|
class Poly1305
|
||||||
@ -39,9 +39,6 @@ public:
|
|||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef uint16_t limb_t;
|
|
||||||
typedef int16_t slimb_t;
|
|
||||||
typedef uint32_t dlimb_t;
|
|
||||||
struct {
|
struct {
|
||||||
limb_t h[(16 / sizeof(limb_t)) + 1];
|
limb_t h[(16 / sizeof(limb_t)) + 1];
|
||||||
limb_t c[(16 / sizeof(limb_t)) + 1];
|
limb_t c[(16 / sizeof(limb_t)) + 1];
|
||||||
|
@ -34,19 +34,17 @@ of the full curve operation itself.
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// Copy some definitions from the Curve25519 class for convenience.
|
// Copy some definitions from the Curve25519 class for convenience.
|
||||||
#define NUM_LIMBS (32 / sizeof(Curve25519::limb_t))
|
#define NUM_LIMBS (32 / sizeof(limb_t))
|
||||||
#define LIMB_BITS (8 * sizeof(Curve25519::limb_t))
|
#define LIMB_BITS (8 * sizeof(limb_t))
|
||||||
#define limb_t Curve25519::limb_t
|
|
||||||
#define dlimb_t Curve25519::dlimb_t
|
|
||||||
#define INVERSE_LIMB (~((limb_t)0))
|
#define INVERSE_LIMB (~((limb_t)0))
|
||||||
|
|
||||||
// For simpleMod() below we need a type that is 4 times the size of limb_t.
|
// For simpleMod() below we need a type that is 4 times the size of limb_t.
|
||||||
#if CURVE25519_LIMB_8BIT
|
#if BIGNUMBER_LIMB_8BIT
|
||||||
#define qlimb_t uint32_t
|
#define qlimb_t uint32_t
|
||||||
#elif CURVE25519_LIMB_16BIT
|
#elif BIGNUMBER_LIMB_16BIT
|
||||||
#define qlimb_t uint64_t
|
#define qlimb_t uint64_t
|
||||||
#else
|
#else
|
||||||
#define CURVE25519_NO_QLIMB 1
|
#define BIGNUMBER_NO_QLIMB 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
limb_t arg1[NUM_LIMBS];
|
limb_t arg1[NUM_LIMBS];
|
||||||
@ -222,7 +220,7 @@ void simpleMul(limb_t *result, const limb_t *x, const limb_t *y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CURVE25519_NO_QLIMB)
|
#if defined(BIGNUMBER_NO_QLIMB)
|
||||||
|
|
||||||
// Quick check to correct the estimate on a quotient word.
|
// Quick check to correct the estimate on a quotient word.
|
||||||
static inline limb_t correctEstimate
|
static inline limb_t correctEstimate
|
||||||
@ -314,7 +312,7 @@ void simpleMod(limb_t *x)
|
|||||||
// One subtlety of Knuth's algorithm is that it looks like the test
|
// One subtlety of Knuth's algorithm is that it looks like the test
|
||||||
// is working with double-word quantities but it is actually using
|
// is working with double-word quantities but it is actually using
|
||||||
// double-word plus a carry bit. So we need to use qlimb_t for this.
|
// double-word plus a carry bit. So we need to use qlimb_t for this.
|
||||||
#if !defined(CURVE25519_NO_QLIMB)
|
#if !defined(BIGNUMBER_NO_QLIMB)
|
||||||
qlimb_t test = ((((qlimb_t)uword) - ((dlimb_t)q) * v[1]) << LIMB_BITS) + u[0];
|
qlimb_t test = ((((qlimb_t)uword) - ((dlimb_t)q) * v[1]) << LIMB_BITS) + u[0];
|
||||||
if ((((dlimb_t)q) * v[0]) > test) {
|
if ((((dlimb_t)q) * v[0]) > test) {
|
||||||
--q;
|
--q;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user