incubator-nuttx/include/crypto/bn.h

243 lines
6.8 KiB
C

/****************************************************************************
* include/crypto/bn.h
*
* SPDX-License-Identifier: Unlicense
*
* This is free and unencumbered software released into the public domain.
* Anyone is free to copy, modify, publish, use, compile, sell, or
* distribute this software, either in source code form or as a compiled
* binary, for any purpose, commercial or non-commercial, and by any
* means.
* In jurisdictions that recognize copyright laws, the author or authors
* of this software dedicate any and all copyright interest in the
* software to the public domain. We make this dedication for the benefit
* of the public at large and to the detriment of our heirs and
* successors. We intend this dedication to be an overt act of
* relinquishment in perpetuity of all present and future rights to this
* software under copyright law.
*
* 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 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.
*
* For more information, please refer to <https://unlicense.org>
****************************************************************************/
#ifndef __INCLUDE_CRYPTO_BIGNUM_H
#define __INCLUDE_CRYPTO_BIGNUM_H
/* Big number library - arithmetic on multiple-precision unsigned integers.
*
* This library is an implementation of arithmetic on arbitrarily large
* integers.
*
* The difference between this and other implementations, is that the data
* structure
* has optimal memory utilization (i.e. a 1024 bit integer takes up 128 bytes
* RAM),
* and all memory is allocated statically: no dynamic allocation for better
* or worse.
*
* Primary goals are correctness, clarity of code and clean, portable
* implementation.
* Secondary goal is a memory footprint small enough to make it suitable for
* use in
* embedded applications.
*
*
* The current state is correct functionality and adequate performance.
* There may well be room for performance-optimizations and improvements.
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* This macro defines the word size in bytes of the array that constitues the
* big-number data structure.
*/
#define WORD_SIZE 1
/* Size of big-numbers in bytes */
#define BN_ARRAY_SIZE (512 / WORD_SIZE)
/* Data type of array in structure */
#define DTYPE uint8_t
/* Data-type larger than DTYPE, for holding intermediate results of
* calculations
*/
#define DTYPE_TMP uint32_t
/* bitmask for getting MSB */
#define DTYPE_MSB ((DTYPE_TMP)(0x80))
/* sprintf format string */
#define SPRINTF_FORMAT_STR "%.02x"
#define SSCANF_FORMAT_STR "%2hhx"
/* Max value of integer type */
#define MAX_VAL ((DTYPE_TMP)0xFF)
/****************************************************************************
* Public Types
****************************************************************************/
/* Data-holding structure: array of DTYPEs */
struct bn
{
/* Sign: -1 if the bignum is negative, 1 otherwise. */
int s;
DTYPE array[BN_ARRAY_SIZE];
};
/* Tokens returned by bignum_cmp() for value comparison */
enum
{
SMALLER = -1,
EQUAL = 0,
LARGER = 1
};
/****************************************************************************
* Public Functions Prototype
****************************************************************************/
/* Initialization functions: */
void bignum_init(FAR struct bn *n);
void bignum_from_int(FAR struct bn *n, DTYPE_TMP i);
int bignum_to_int(FAR struct bn *n);
void bignum_from_string(FAR struct bn *n, FAR char *str, int nbytes);
void bignum_to_string(FAR struct bn *n, FAR char *str, int maxsize);
/* Basic arithmetic operations: */
/* c = a + b */
void bignum_add(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = |a| + |b| */
void bignum_add_abs(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a - b */
void bignum_sub(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = |a| - |b| */
void bignum_sub_abs(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a * b */
void bignum_mul(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a / b */
void bignum_div(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a % b */
void bignum_mod(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a / b, d = a % b */
void bignum_divmod(FAR struct bn *a, FAR struct bn *b,
FAR struct bn *c, FAR struct bn *d);
/* Bitwise operations: */
/* c = a & b */
void bignum_and(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a | b */
void bignum_or(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* c = a ^ b */
void bignum_xor(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* b = a << nbits */
void bignum_lshift(FAR struct bn *a, FAR struct bn *b, int nbits);
/* b = a >> nbits */
void bignum_rshift(FAR struct bn *a, FAR struct bn *b, int nbits);
/* Special operators and comparison */
/* Compare: returns LARGER, EQUAL or SMALLER */
int bignum_cmp(FAR struct bn *a, FAR struct bn *b);
/* Compare |A| and |B| */
int bignum_cmp_abs(FAR struct bn *a, FAR struct bn *b);
/* For comparison with zero */
int bignum_is_zero(FAR struct bn *n);
/* Increment: add one to n */
void bignum_inc(FAR struct bn *n);
/* Decrement: subtract one from n */
void bignum_dec(FAR struct bn *n);
/* Calculate a^b -- e.g. 2^10 => 1024 */
void bignum_pow(FAR struct bn *a, FAR struct bn *b, FAR struct bn *c);
/* Integer square root -- e.g. isqrt(5) => 2 */
void bignum_isqrt(FAR struct bn *a, FAR struct bn *b);
/* Copy src into dst -- dst := src */
void bignum_assign(FAR struct bn *dst, FAR struct bn *src);
/* CRK_EXP_MOD algorithm */
void pow_mod_faster(FAR struct bn *a, FAR struct bn *b,
FAR struct bn *n, FAR struct bn *res);
/* Return the number of less significant zero-bits */
int bignum_lsb(FAR struct bn *a);
/* g = gcd(a, b) */
void bignum_gcd(FAR struct bn *a, FAR struct bn *b, FAR struct bn *g);
/* Modular inverse: c = a^-1 mod n */
int bignum_inv_mod(FAR struct bn *a, FAR struct bn *n, FAR struct bn *c);
#endif /* __INCLUDE_CRYPTO_BIGNUM_H */