1
0
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:
Rhys Weatherley 2015-03-31 09:43:09 +10:00
parent a3d7f61b96
commit 3bcfbcd43b
6 changed files with 79 additions and 48 deletions

View 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

View File

@ -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
* 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];
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)
{
// 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};
#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};
#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};
#define pgm_read_a24(index) (pgm_read_dword(&(a24[(index)])))
#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)
{
#if CURVE25519_LIMB_8BIT
#if BIGNUMBER_LIMB_8BIT
memcpy(result, x, 32);
result[31] &= 0x7F;
#elif CURVE25519_LIMB_16BIT
#elif BIGNUMBER_LIMB_16BIT
for (uint8_t posn = 0; posn < 16; ++posn) {
result[posn] = ((limb_t)x[posn * 2]) | (((limb_t)x[posn * 2 + 1]) << 8);
}
result[15] &= 0x7FFF;
#elif CURVE25519_LIMB_32BIT
#elif BIGNUMBER_LIMB_32BIT
for (uint8_t posn = 0; posn < 8; ++posn) {
result[posn] = ((limb_t)x[posn * 4]) |
(((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)
{
#if CURVE25519_LIMB_8BIT
#if BIGNUMBER_LIMB_8BIT
memcpy(result, x, 32);
#elif CURVE25519_LIMB_16BIT
#elif BIGNUMBER_LIMB_16BIT
for (uint8_t posn = 0; posn < 16; ++posn) {
limb_t value = x[posn];
result[posn * 2] = (uint8_t)value;
result[posn * 2 + 1] = (uint8_t)(value >> 8);
}
#elif CURVE25519_LIMB_32BIT
#elif BIGNUMBER_LIMB_32BIT
for (uint8_t posn = 0; posn < 8; ++posn) {
limb_t value = x[posn];
result[posn * 4] = (uint8_t)value;

View File

@ -23,15 +23,9 @@
#ifndef CRYPTO_CURVE15519_h
#define CRYPTO_CURVE15519_h
#include <inttypes.h>
#include "BigNumberUtil.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
{
public:
@ -45,23 +39,6 @@ public:
#else
private:
#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 void reduce(limb_t *result, limb_t *x, uint8_t size);

View File

@ -63,9 +63,17 @@
#define NUM_LIMBS_130BIT ((16 / sizeof(limb_t)) + 1)
#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 htolelimb(x) (htole16((x)))
#elif BIGNUMBER_LIMB_32BIT
#define lelimbtoh(x) (le32toh((x)))
#define htolelimb(x) (htole32((x)))
#endif
#if defined(CRYPTO_LITTLE_ENDIAN)
#define littleToHost(r,size) do { ; } while (0)
#else

View File

@ -23,7 +23,7 @@
#ifndef CRYPTO_POLY1305_h
#define CRYPTO_POLY1305_h
#include <inttypes.h>
#include "BigNumberUtil.h"
#include <stddef.h>
class Poly1305
@ -39,9 +39,6 @@ public:
void clear();
private:
typedef uint16_t limb_t;
typedef int16_t slimb_t;
typedef uint32_t dlimb_t;
struct {
limb_t h[(16 / sizeof(limb_t)) + 1];
limb_t c[(16 / sizeof(limb_t)) + 1];

View File

@ -34,19 +34,17 @@ of the full curve operation itself.
#include <string.h>
// Copy some definitions from the Curve25519 class for convenience.
#define NUM_LIMBS (32 / sizeof(Curve25519::limb_t))
#define LIMB_BITS (8 * sizeof(Curve25519::limb_t))
#define limb_t Curve25519::limb_t
#define dlimb_t Curve25519::dlimb_t
#define NUM_LIMBS (32 / sizeof(limb_t))
#define LIMB_BITS (8 * sizeof(limb_t))
#define INVERSE_LIMB (~((limb_t)0))
// 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
#elif CURVE25519_LIMB_16BIT
#elif BIGNUMBER_LIMB_16BIT
#define qlimb_t uint64_t
#else
#define CURVE25519_NO_QLIMB 1
#define BIGNUMBER_NO_QLIMB 1
#endif
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.
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
// 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.
#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];
if ((((dlimb_t)q) * v[0]) > test) {
--q;