670 lines
22 KiB
C
670 lines
22 KiB
C
/* $Id: bigd.h $ */
|
|
|
|
/***** BEGIN LICENSE BLOCK *****
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* Copyright (c) 2001-16 David Ireland, D.I. Management Services Pty Limited
|
|
* <http://www.di-mgt.com.au/bigdigits.html>. All rights reserved.
|
|
*
|
|
***** END LICENSE BLOCK *****/
|
|
/*
|
|
* Last updated:
|
|
* $Date: 2016-03-31 09:51:00 $
|
|
* $Revision: 2.6.1 $
|
|
* $Author: dai $
|
|
*/
|
|
|
|
/* ANNOTATION FOR DOXYGEN... */
|
|
|
|
/** @mainpage notitle
|
|
|
|
@section intro_sec Introduction
|
|
|
|
BigDigits is a free library of multiple-precision arithmetic routines written in ANSI C
|
|
to carry out calculations with the large natural numbers used in cryptography computations.
|
|
|
|
You can download it from http://www.di-mgt.com.au/bigdigits.html.
|
|
|
|
The BigDigits library is designed to work with the set of natural numbers \b N;
|
|
that is, the non-negative integers 0,1,2,... .
|
|
|
|
The library has two interfaces: the "bd" library and the underlying "mp" library.
|
|
The "bd" functions use an opaque BIGD object and
|
|
handle memory allocation automatically.
|
|
The "mp" functions use fixed-length arrays and
|
|
require a bit more care to use but the "mp" library is faster and
|
|
has an option (`NO_ALLOCS`) to avoid all memory allocation calls completely.
|
|
The "bd" library is an easier-to-use wrapper around the "mp" library.
|
|
|
|
The "bd" functions are described in bigd.h and the more elementary "mp" functions are in bigdigits.h.
|
|
|
|
There are some optional functions that generate random numbers using a "pretty-good" internal RNG
|
|
in bigdRand.h and bigdigitsRand.h for the "bd" and "mp" libraries, respectively.
|
|
|
|
*/
|
|
|
|
/** @file
|
|
Interface to the BigDigits "bd" functions using BIGD objects with automatic memory allocation
|
|
|
|
@par PROGRAMMER'S NOTES
|
|
Where the function computes a new BIGD value,
|
|
the result is returned in the first argument.
|
|
Some functions do not allow variables to overlap.
|
|
Functions of type `int` generally return 0 to denote success
|
|
but some return True/False (1/0) or borrow (+1) or error (-1).
|
|
Functions of type `size_t` (an unsigned int) return a length.
|
|
|
|
@par Memory allocation
|
|
Memory for each variable is allocated as required and is increased automatically if needed.
|
|
However, memory for a variable is only released when freed with bdFree().
|
|
The standard code for a variable `b` should be as follows:
|
|
@code
|
|
BIGD b;
|
|
b = bdNew();
|
|
// operations using b...
|
|
bdFree(&b);
|
|
@endcode*/
|
|
|
|
|
|
#ifndef BIGD_H_
|
|
#define BIGD_H_ 1
|
|
|
|
#include "bigdtypes.h"
|
|
|
|
/**** USER CONFIGURABLE SECTION ****/
|
|
|
|
/* [v2.1] Changed to use exact width integer types.
|
|
[v2.2] Moved macros for exact-width types to "bigdtypes.h"
|
|
*/
|
|
|
|
/** A synonym for a single digit (DIGIT_T is not exposed) */
|
|
typedef uint32_t bdigit_t;
|
|
|
|
/**** END OF USER CONFIGURABLE SECTION ****/
|
|
/** @cond */
|
|
/**** OPTIONAL PREPROCESSOR DEFINITIONS ****/
|
|
/*
|
|
Choose one of { USE_SPASM | USE_64WITH32 }
|
|
USE_SPASM: to use the faster x86 ASM routines (if __asm option is available with your compiler).
|
|
USE_64WITH32: to use the 64-bit integers if available (e.g. long long).
|
|
Default: use default internal routines spDivide and spMultiply.
|
|
The USE_SPASM option takes precedence over USE_64WITH32.
|
|
*/
|
|
|
|
#ifdef NO_ALLOCS
|
|
#error NO_ALLOCS is not permitted with bd functions
|
|
#endif
|
|
|
|
/*
|
|
This interface uses opaque pointers of type BIGD using
|
|
the conventions in "C Interfaces and Implementions" by
|
|
David R. Hanson, Addison-Wesley, 1996, pp21-4.
|
|
Thanks to Ian Tree for the C++ fudge.
|
|
*/
|
|
#define T BIGD
|
|
#ifdef __cplusplus
|
|
typedef struct T2 *T;
|
|
#else
|
|
typedef struct T *T;
|
|
#endif
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/** @endcond */
|
|
|
|
|
|
/******************************/
|
|
/* CONSTRUCTOR AND DESTRUCTOR */
|
|
/******************************/
|
|
/** Create new BIGD object
|
|
@returns Handle to new object
|
|
*/
|
|
BIGD bdNew(void);
|
|
|
|
/** Destroy BIGD object: zeroise contents and free allocated memory.
|
|
@remark Pass a *pointer* to the handle
|
|
*/
|
|
void bdFree(BIGD *bd);
|
|
|
|
/** Create a set of BIGD objects
|
|
@code
|
|
BIGD a, b, c;
|
|
bdNewVars(&a, &b, &c, NULL);
|
|
// do stuff with variables a, b, c...
|
|
bdFreeVars(&a, &b, &c, NULL);
|
|
@endcode
|
|
The `bdNewVars` function call above is equivalent to
|
|
@code
|
|
a = bdNew();
|
|
b = bdNew();
|
|
c = bdNew();
|
|
@endcode
|
|
|
|
@warning The list *must* finish with `NULL`
|
|
*/
|
|
void bdNewVars(BIGD *pb1, ...);
|
|
|
|
|
|
/** Destroy a set of BIGD objects
|
|
@code
|
|
BIGD a, b, c;
|
|
bdNewVars(&a, &b, &c, NULL);
|
|
// do stuff with variables a, b, c...
|
|
bdFreeVars(&a, &b, &c, NULL);
|
|
@endcode
|
|
The `bdFreeVars` function call above is equivalent to
|
|
@code
|
|
bdFree(&a);
|
|
bdFree(&b);
|
|
bdFree(&c);
|
|
@endcode
|
|
|
|
@warning The list *must* finish with `NULL`
|
|
*/
|
|
void bdFreeVars(BIGD *pb1, ...);
|
|
|
|
|
|
/*************************/
|
|
/* ARITHMETIC OPERATIONS */
|
|
/*************************/
|
|
|
|
/** Compute sum w = u + v
|
|
@return carry
|
|
@remark `w` and `v` must be separate variables.
|
|
Use bdAdd_s() to avoid overlap restriction.
|
|
*/
|
|
int bdAdd(BIGD w, BIGD u, BIGD v);
|
|
|
|
/** Compute difference w = u - v
|
|
@return borrow
|
|
@remark `w` and `v` must be separate variables.
|
|
Use bdSubtract_s() to avoid overlap restriction.
|
|
@warning Behaviour is undefined for negative numbers.
|
|
*/
|
|
int bdSubtract(BIGD w, BIGD u, BIGD v);
|
|
|
|
/** Compute product w = u * v
|
|
@remark `w` and `u` must be separate variables.
|
|
Use bdMultiply_s() to avoid overlap restriction.
|
|
*/
|
|
int bdMultiply(BIGD w, BIGD u, BIGD v);
|
|
|
|
/** Compute integer division of u by v such that u=qv+r
|
|
@param[out] q To receive quotient = u div v
|
|
@param[out] r To receive remainder = u mod v
|
|
@param[in] u Dividend
|
|
@param[in] v Divisor
|
|
@remark Trashes q and r first: `q` and `r` must be independent of `u` and `v`.
|
|
Use bdDivide_s() to avoid overlap restriction.
|
|
*/
|
|
int bdDivide(BIGD q, BIGD r, BIGD u, BIGD v);
|
|
|
|
/** Compute remainder r = u mod v
|
|
@remark `r` and `u` must be separate variables.
|
|
Use bdModulo_s() to avoid overlap restriction.
|
|
*/
|
|
int bdModulo(BIGD r, BIGD u, BIGD v);
|
|
|
|
/** Compute square w = x^2
|
|
@remark `w` and `x` must be separate variables.
|
|
Use bdSquare_s() to avoid overlap restriction.
|
|
*/
|
|
int bdSquare(BIGD w, BIGD x);
|
|
|
|
/** Computes y = g^n (up to available memory!)
|
|
@remark Be very careful that `n` is not too large
|
|
*/
|
|
int bdPower(BIGD y, BIGD g, unsigned short int n);
|
|
|
|
/** Computes integer square root s = floor(sqrt(x)) */
|
|
int bdSqrt(BIGD s, BIGD x);
|
|
|
|
/** Computes integer cube root s = floor(cuberoot(x)) */
|
|
int bdCubeRoot(BIGD s, BIGD x);
|
|
|
|
/** Sets a = a + 1
|
|
@return carry */
|
|
int bdIncrement(BIGD a);
|
|
|
|
/** Sets a = a - 1
|
|
@return borrow
|
|
@warning Behaviour is undefined if a becomes negative.
|
|
*/
|
|
int bdDecrement(BIGD a);
|
|
|
|
/* 'Safe' versions with no restrictions on overlap */
|
|
/* [v2.2] Changed name from ~Ex to ~_s */
|
|
|
|
/** Compute w = u + v without restrictions on overlap of bdAdd() */
|
|
int bdAdd_s(BIGD w, BIGD u, BIGD v);
|
|
/** Compute w = u - v without restrictions on overlap of bdSubtract() */
|
|
int bdSubtract_s(BIGD w, BIGD u, BIGD v);
|
|
/** Compute w = u * v without restrictions on overlap of bdMultiply() */
|
|
int bdMultiply_s(BIGD w, BIGD u, BIGD v);
|
|
/** Compute u div v without restrictions on overlap of bdDivide() */
|
|
int bdDivide_s(BIGD q, BIGD r, BIGD u, BIGD v);
|
|
/** Compute u mod v without restrictions on overlap of bdModulo() */
|
|
int bdModulo_s(BIGD r, BIGD u, BIGD v);
|
|
/** Compute s = x * x without restrictions on overlap of bdSquare() */
|
|
int bdSquare_s(BIGD s, BIGD x);
|
|
|
|
/* Keep the faith with the deprecated ~Ex version names */
|
|
#define bdAddEx(w, u, v) bdAdd_s((w), (u), (v))
|
|
#define bdSubtractEx(w, u, v) bdSubtract_s((w), (u), (v))
|
|
#define bdMultiplyEx(w, u, v) bdMultiply_s((w), (u), (v))
|
|
#define bdDivideEx(q, r, u, v) bdDivide_s((q), (r), (u), (v))
|
|
#define bdModuloEx(r, u, v) bdModulo_s((r), (u), (v))
|
|
#define bdSquareEx(s, x) bdSquare_s((s), (x))
|
|
|
|
|
|
/*************************/
|
|
/* COMPARISON OPERATIONS */
|
|
/*************************/
|
|
|
|
/** Returns true (1) if a == b, else false (0)
|
|
* @remark Not constant-time
|
|
*/
|
|
int bdIsEqual(BIGD a, BIGD b);
|
|
|
|
/** Returns sign of `(a-b)` in `{0,1,-1}`
|
|
* @remark Not constant-time
|
|
*/
|
|
int bdCompare(BIGD a, BIGD b);
|
|
|
|
/** Returns true (1) if a is zero, else false (0)
|
|
* @remark Not constant-time
|
|
*/
|
|
int bdIsZero(BIGD a);
|
|
|
|
/** Returns true (1) if a is even, else false (0) */
|
|
int bdIsEven(BIGD a);
|
|
|
|
/** Returns true (1) if a is odd, else false (0) */
|
|
int bdIsOdd(BIGD a);
|
|
|
|
/***************************************/
|
|
/* CONSTANT-TIME COMPARISON ALGORITHMS */
|
|
/***************************************/
|
|
/* -- added in [v2.6] */
|
|
|
|
/** Returns true if a == b, else false, using constant-time algorithm */
|
|
int bdIsEqual_ct(BIGD a, BIGD b);
|
|
|
|
/** Returns sign of `(a-b)` as `{-1,0,+1}` using constant-time algorithm */
|
|
int bdCompare_ct(BIGD a, BIGD b);
|
|
|
|
/** Returns true if a is zero, else false, using constant-time algorithm */
|
|
int bdIsZero_ct(BIGD a);
|
|
|
|
/*************************/
|
|
/* ASSIGNMENT OPERATIONS */
|
|
/*************************/
|
|
|
|
/** Sets a = b */
|
|
int bdSetEqual(BIGD a, BIGD b);
|
|
|
|
/** Sets a = 0 */
|
|
int bdSetZero(BIGD a);
|
|
|
|
|
|
/****************************/
|
|
/* NUMBER THEORY OPERATIONS */
|
|
/****************************/
|
|
|
|
/** Computes y = x^e mod m */
|
|
int bdModExp(BIGD y, BIGD x, BIGD e, BIGD m);
|
|
|
|
/** Computes y = x^e mod m in constant time
|
|
* @remark Resistant to simple power analysis attack on private exponent.
|
|
* Slower than bdModExp().
|
|
*/
|
|
int bdModExp_ct(BIGD y, BIGD x, BIGD e, BIGD m);
|
|
|
|
/** Computes a = (x * y) mod m */
|
|
int bdModMult(BIGD a, BIGD x, BIGD y, BIGD m);
|
|
|
|
/** Computes a = x^2 mod m */
|
|
int bdModSquare(BIGD a, BIGD x, BIGD m);
|
|
|
|
/** Computes the inverse of `a` modulo `m`, `x = a^{-1} mod m` */
|
|
int bdModInv(BIGD x, BIGD a, BIGD m);
|
|
|
|
/** Computes g = gcd(x, y), the greatest common divisor of x and y */
|
|
int bdGcd(BIGD g, BIGD x, BIGD y);
|
|
|
|
/** Returns the Jacobi symbol (a/n) = {-1, 0, +1}
|
|
@remark If n is prime then the Jacobi symbol becomes the Legendre symbol (a/p) defined to be
|
|
- (a/p) = +1 if a is a quadratic residue modulo p
|
|
- (a/p) = -1 if a is a quadratic non-residue modulo p
|
|
- (a/p) = 0 if a is divisible by p
|
|
*/
|
|
int bdJacobi(BIGD a, BIGD n);
|
|
|
|
|
|
/** Computes x = one square root of an integer `a` modulo an odd prime `p`
|
|
* @param x To receive the result
|
|
* @param a An integer expected to be a quadratic residue modulo p
|
|
* @param p An odd prime
|
|
* @return 0 if successful, or -1 if square root does not exist
|
|
* @remark More precisely, find an integer x such that x^2 mod p = a.
|
|
* Uses the Tonelli-Shanks algorithm. The other square root is `p - x`.
|
|
* @warning Check the return value before using the result `x`.
|
|
*/
|
|
int bdModSqrt(BIGD x, BIGD a, BIGD p);
|
|
|
|
|
|
/** Computes w = u/2 (mod p) for an odd prime p
|
|
* @pre Require u to be in the range `[0,p-1]`
|
|
*/
|
|
void bdModHalve(BIGD w, const BIGD u, const BIGD p);
|
|
|
|
|
|
/** Computes w = u + v (mod m)
|
|
* @pre Require u and v to be in the range `[0, m-1]`.
|
|
* The variables `w` and `v` must not overlap.
|
|
* @remark Quicker than adding then using mpModulo()
|
|
*/
|
|
void bdModAdd(BIGD w, BIGD u, BIGD v, BIGD m);
|
|
|
|
|
|
/** Computes w = u - v (mod m)
|
|
* @pre Require u and v to be in the range `[0, m-1]`.
|
|
* The variables `w` and `v` must not overlap.
|
|
* @remark Quicker than subtracting then using mpModulo()
|
|
*/
|
|
void bdModSub(BIGD w, BIGD u, BIGD v, BIGD m);
|
|
|
|
|
|
/** Returns true (1) if `b` is probably prime
|
|
@param[in] b Number to test
|
|
@param[in] ntests The count of Rabin-Miller primality tests to carry out (recommended at least 80)
|
|
@returns true (1) if b is probably prime otherwise false (0)
|
|
@remark Uses FIPS-186-2/Rabin-Miller with trial division by small primes,
|
|
which is faster in most cases than bdRabinMiller().
|
|
@see bdRabinMiller().
|
|
*/
|
|
int bdIsPrime(BIGD b, size_t ntests);
|
|
|
|
/** Returns true (1) if `b` is probably prime using just the Rabin-Miller test
|
|
@param[in] b Number to test (b > 2)
|
|
@param[in] ntests The count of Rabin-Miller primality tests to carry out (recommended at least 80)
|
|
@returns true (1) if b is probably prime otherwise false (0)
|
|
@remark bdIsPrime() is the recommended function to test for primality.
|
|
Use this variant if, for some reason,
|
|
you do not want to do the quicker trial division tests first.
|
|
@see bdIsPrime()
|
|
*/
|
|
int bdRabinMiller(BIGD b, size_t ntests);
|
|
|
|
|
|
/**********************************************/
|
|
/* FUNCTIONS THAT OPERATE WITH A SINGLE DIGIT */
|
|
/**********************************************/
|
|
/* [v2.6] Added bdShortIsEqual() and bdToShort() */
|
|
|
|
/** Converts a single digit into a BIGD
|
|
@param[out] b To receive the result
|
|
@param[in] d A single digit
|
|
@remark Use this to set a BIGD variable to a small integer.
|
|
*/
|
|
int bdSetShort(BIGD b, bdigit_t d);
|
|
|
|
/** Computes w = u + d where d is a single digit
|
|
@return carry
|
|
*/
|
|
int bdShortAdd(BIGD w, BIGD u, bdigit_t d);
|
|
|
|
/** Computes w = u - d where d is a single digit
|
|
@return borrow
|
|
*/
|
|
int bdShortSub(BIGD w, BIGD u, bdigit_t d);
|
|
|
|
/** Computes w = u * d where d is a single digit */
|
|
int bdShortMult(BIGD w, BIGD u, bdigit_t d);
|
|
|
|
/** Computes integer division of u by single digit d
|
|
@param[out] q To receive quotient = u div d
|
|
@param[out] r To receive remainder = u mod d
|
|
@param[in] u Dividend, a BIGD object
|
|
@param[in] d Divisor, a single digit
|
|
@remark A separate BIGD object `r` must be provided to receive the remainder.
|
|
*/
|
|
int bdShortDiv(BIGD q, BIGD r, BIGD u, bdigit_t d);
|
|
|
|
/** Computes r = u mod d where d is a single digit */
|
|
bdigit_t bdShortMod(BIGD r, BIGD u, bdigit_t d);
|
|
|
|
/** Returns sign of (a-d) where d is a single digit */
|
|
int bdShortCmp(BIGD a, bdigit_t d);
|
|
|
|
/** Returns true if a == d, else false, where d is a single digit */
|
|
int bdShortIsEqual(BIGD a, bdigit_t d);
|
|
|
|
/** Returns the least significant digit in b
|
|
* @return A single digit equal to the least significant digit in b
|
|
* @remark Use this to convert (truncate) a BIGD object into a short integer
|
|
*/
|
|
bdigit_t bdToShort(BIGD b);
|
|
|
|
|
|
/***********************/
|
|
/* BIT-WISE OPERATIONS */
|
|
/***********************/
|
|
/* [v2.1.0] Added ModPowerOf2, Xor, Or and AndBits functions */
|
|
/* [v2.2.0] Added NotBits, GetBit, SetBit functions */
|
|
|
|
/** Returns number of significant bits in b */
|
|
size_t bdBitLength(BIGD b);
|
|
|
|
/** Set bit n of a (0..nbits-1) with value 1 or 0 */
|
|
int bdSetBit(BIGD a, size_t n, int value);
|
|
|
|
/** Returns value 1 or 0 of bit n of a (0..nbits-1) */
|
|
int bdGetBit(BIGD a, size_t ibit);
|
|
|
|
/** Computes a = b << n */
|
|
void bdShiftLeft(BIGD a, BIGD b, size_t n);
|
|
|
|
/** Computes a = b >> n */
|
|
void bdShiftRight(BIGD a, BIGD b, size_t n);
|
|
|
|
/** Computes a = a mod 2^L, ie clears all bits greater than L */
|
|
void bdModPowerOf2(BIGD a, size_t L);
|
|
|
|
/** Computes bitwise operation a = b XOR c */
|
|
void bdXorBits(BIGD a, BIGD b, BIGD c);
|
|
|
|
/** Computes bitwise operation a = b OR c */
|
|
void bdOrBits(BIGD a, BIGD b, BIGD c);
|
|
|
|
/** Computes bitwise operation a = b AND c */
|
|
void bdAndBits(BIGD a, BIGD b, BIGD c);
|
|
|
|
/** Computes bitwise a = NOT b
|
|
@remark This flips all the bits up to the most significant digit, which may not be exactly what you want. */
|
|
void bdNotBits(BIGD a, BIGD b);
|
|
|
|
|
|
/*******************/
|
|
/* MISC OPERATIONS */
|
|
/*******************/
|
|
|
|
/** Returns number of significant digits in b */
|
|
size_t bdSizeof(BIGD b);
|
|
|
|
/** Print b in hex format with optional prefix and suffix strings */
|
|
void bdPrintHex(const char *prefix, BIGD b, const char *suffix);
|
|
|
|
/** Print b in decimal format with optional prefix and suffix strings */
|
|
void bdPrintDecimal(const char *prefix, BIGD b, const char *suffix);
|
|
|
|
/** Print b in bit (0/1) format with optional prefix and suffix strings */
|
|
void bdPrintBits(const char *prefix, BIGD b, const char *suffix);
|
|
|
|
/* Options for bdPrint */
|
|
#define BD_PRINT_NL 0x1 /* append a newline after printing */
|
|
#define BD_PRINT_TRIM 0x2 /* trim leading zero digits */
|
|
|
|
/** Print b in hex format to stdout
|
|
@param[in] b Number to print
|
|
@param[in] flags (see below)
|
|
@remark Flags are
|
|
- `0` default display leading zeros but no newline
|
|
- `BD_PRINT_NL` `0x1` append a newline after printing
|
|
- `BD_PRINT_TRIM` `0x2` trim leading zero digits
|
|
@deprecated Use bdPrintHex() or bdPrintDecimal().
|
|
*/
|
|
void bdPrint(BIGD b, size_t flags);
|
|
|
|
|
|
/***************/
|
|
/* CONVERSIONS */
|
|
/***************/
|
|
/* All bdConv functions return 0 on error */
|
|
/* "Octet" = an 8-bit byte */
|
|
|
|
/** Converts a byte array into a BIGD object
|
|
@param[out] b To receive the result
|
|
@param[in] octets Pointer to array of bytes (octets)
|
|
@param[in] nbytes Number of bytes in sequence
|
|
@returns Number of digits actually set, which may be larger than bdSizeof(BIGD b).
|
|
*/
|
|
size_t bdConvFromOctets(BIGD b, const unsigned char *octets, size_t nbytes);
|
|
|
|
/** Converts a BIGD into an array of bytes, in big-endian order
|
|
@param[in] b BIGD object to be converted
|
|
@param[out] octets Array of bytes (octets) to receive output
|
|
@param[in] nbytes Length of array to receive output
|
|
@returns Exact number of significant bytes in the result.
|
|
If `octets` is NULL or `nbytes` is zero then just returns required size (nsig).
|
|
@remark Will pad on the left with zeros if `nbytes` is larger than required,
|
|
or will truncate from the left if it is too short.
|
|
- if nbytes = nsig, octets <-- mmmnnn;
|
|
- if nbytes > nsig, octets <-- 000mmmnnn;
|
|
- if nbytes < nsig, octets <-- nnn.
|
|
*/
|
|
size_t bdConvToOctets(BIGD b, unsigned char *octets, size_t nbytes);
|
|
|
|
|
|
/** Convert string of hexadecimal characters into a BIGD object
|
|
@param[out] b To receive the result
|
|
@param[in] s Null-terminated string of hex digits `[0-9A-Fa-f]`
|
|
@returns Number of significant digits actually set, which could be 0.
|
|
*/
|
|
size_t bdConvFromHex(BIGD b, const char *s);
|
|
|
|
/** Convert BIGD object into a string of hexadecimal characters
|
|
@param[in] b BIGD object to be converted
|
|
@param[out] s String buffer to receive output
|
|
@param[in] smax Size of buffer *including* the terminating zero
|
|
@returns Exact number of characters required *excluding* the terminating zero.
|
|
If `s` is NULL or `smax` is zero then just returns required number.
|
|
@code
|
|
char *s;
|
|
size_t nchars = bdConvToHex(b, NULL, 0);
|
|
s = malloc(nchars+1); // NB add one extra
|
|
nchars = bdConvToHex(b, s, nchars+1);
|
|
@endcode
|
|
@remark Always returns the length of the string it tried to create,
|
|
even if the actual output was truncated, so remember to check.
|
|
*/
|
|
size_t bdConvToHex(BIGD b, char *s, size_t smax);
|
|
|
|
/** Convert string of decimal characters into a BIGD object
|
|
@param[out] b To receive the result
|
|
@param[in] s Null-terminated string of decimal digits `[0-9]`
|
|
@returns Number of significant digits actually set, which could be 0.
|
|
*/
|
|
size_t bdConvFromDecimal(BIGD b, const char *s);
|
|
|
|
/** Convert BIGD object into a string of decimal characters
|
|
@param[in] b BIGD object to be converted
|
|
@param[out] s String buffer to receive output
|
|
@param[in] smax Size of buffer *including* the terminating zero
|
|
@returns Exact number of characters required *excluding* the terminating zero.
|
|
If `s` is NULL or `smax` is zero then just returns required number.
|
|
@code
|
|
char *s;
|
|
size_t nchars = bdConvToDecimal(b, NULL, 0);
|
|
s = malloc(nchars+1); // NB add one extra
|
|
nchars = bdConvToDecimal(b, s, nchars+1);
|
|
@endcode
|
|
@remark Always returns the length of the string it tried to create,
|
|
even if the actual output was truncated, so remember to check.
|
|
*/
|
|
size_t bdConvToDecimal(BIGD b, char *s, size_t smax);
|
|
|
|
/****************************/
|
|
/* RANDOM NUMBER OPERATIONS */
|
|
/****************************/
|
|
|
|
/* [Version 2.1: bdRandDigit and bdRandomBits moved to bigdRand.h] */
|
|
|
|
/** Set a with a "random" value of random length up to ndigits long suitable for quick tests
|
|
* @return Number of digits actually set
|
|
* @remark For testing purposes only. Not crypto secure. Not thread safe.
|
|
*/
|
|
size_t bdSetRandTest(BIGD a, size_t ndigits);
|
|
|
|
/** Generate a quick-and-dirty random number a of bit length at most `nbits` using plain-old-rand
|
|
* @return Number of digits actually set
|
|
* @remark Not crypto secure. May give same value on repeated calls.
|
|
* @see bdRandomBits() or bdRandomSeeded().
|
|
*/
|
|
size_t bdQuickRandBits(BIGD a, size_t nbits);
|
|
|
|
/** TYPEDEF for user-defined random byte generator function */
|
|
typedef int (* BD_RANDFUNC)(unsigned char *buf, size_t nbytes, const unsigned char *seed, size_t seedlen);
|
|
|
|
/** Generate a random number nbits long using RandFunc
|
|
* @param[out] a To receive the result
|
|
* @param [in] nbits Maximum number of bits in number
|
|
* @param [in] seed Optional seed to add extra entropy
|
|
* @param [in] seedlen Number of bytes in seed
|
|
* @param [in] RandFunc User function to generate random bytes */
|
|
int bdRandomSeeded(BIGD a, size_t nbits, const unsigned char *seed,
|
|
size_t seedlen, BD_RANDFUNC RandFunc);
|
|
|
|
/** Generate a prime number
|
|
* @param[out] a To receive the result
|
|
* @param [in] nbits Maximum number of bits in number
|
|
* @param [in] ntests Number of primality tests to carry out (recommended at least 80)
|
|
* @param [in] seed Optional seed to add extra entropy
|
|
* @param [in] seedlen Number of bytes in seed
|
|
* @param [in] RandFunc User function to generate random bytes */
|
|
int bdGeneratePrime(BIGD a, size_t nbits, size_t ntests, const unsigned char *seed,
|
|
size_t seedlen, BD_RANDFUNC RandFunc);
|
|
|
|
/****************/
|
|
/* VERSION INFO */
|
|
/****************/
|
|
/** Returns version number = major*1000+minor*100+release*10+PP_OPTIONS */
|
|
int bdVersion(void);
|
|
/* Returns version number = major*1000+minor*100+release*10+uses_asm(0|1)+uses_64(0|2)
|
|
E.g. Version 2.3.0 will return 230x where x denotes the preprocessor options
|
|
x | USE_SPASM | USE_64WITH32 | NO_ALLOCS
|
|
--+-----------+--------------+----------
|
|
0 | No | No | N/A
|
|
1 | Yes | No | N/A
|
|
2 | No | Yes | N/A
|
|
3 | Yes | Yes* | N/A
|
|
--+-----------+--------------+----------
|
|
* USE_SPASM will take precedence over USE_64WITH32.
|
|
*/
|
|
|
|
/** Returns a pointer to a static string containing the time of compilation */
|
|
const char *bdCompileTime(void);
|
|
|
|
|
|
#undef T /* (for opaque BIGD pointer) */
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* BIGD_H_ */
|