Initial commit

This commit is contained in:
2023-12-06 12:26:59 -05:00
commit 3ba560205c
34 changed files with 5246 additions and 0 deletions

View File

@ -0,0 +1,42 @@
#ifndef __AMSCLIL1_H__
#define __AMSCLIL1_H__
// Aaron M. Schinder
// Jan 2021
//
// C Large Integer Library 1
/////////////////////////////
//Standard Library Includes//
/////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>
#include <time.h>
#include <string.h>
//Other Libraries//
#include <amscutil1/amscutil1.h>
///////////////////////
// Component Headers //
///////////////////////
static int amsclil1_verbose = 0;
#include <amsclil1/amsclil1_operations.h>
#include <amsclil1/amsclil1_fbops.h>
#include <amsclil1/amsclil1_tests.h>
#include <amsclil1/amsclil1_ulint.h>
#include <amsclil1/amsclil1_hash.h>
#include <amsclil1/amsclil1_gutmannprng.h>
#endif

View File

@ -0,0 +1,140 @@
#ifndef __AMSCLIL_FBOPS_H__
#define __AMSCLIL_FBOPS_H__
///////////////////////////////
//AMS C Large Integer Library//
//Fixed Buffer Functions //
///////////////////////////////
//Fixed buffer unsigned large integer operations
//
//These are needed, because preallocating the working memory
//will be much faster than dynamically allocating within iterative
//operations
//For the convenience of the caller, these can be wrapped in
//operations acting on resizeable buffers. For speed, these can
//be set up and called directly, with allocation/deallocation taking
//place at the start and end of the wrapping routine.
//Uint32 Operators
// 01234567890123456789012345678901 - MISRA 31 character identifier limit
//Single "digit" operations - these are sometimes reimplimented directly for speed
void amsclil1_ui32_add(uint32_t op1, uint32_t op2, uint32_t *res, uint32_t *car);
void amsclil1_ui32_sub(uint32_t op1, uint32_t op2, uint32_t *res, uint32_t *car);
void amsclil1_ui32_mult(uint32_t op1, uint32_t op2, uint32_t *res, uint32_t *car);
void amsclil1_ui32_div(uint32_t op1, uint32_t op2, uint32_t *res, uint32_t *rem);
//comparison:
//0: a and b are equal, 1: a is greater, 2: b is greater
int amsclil1_fb32_cmp(uint32_t* a, uint32_t* b, long blen);
int amsclil1_fb32_iszero(uint32_t* a, long blen);
void amsclil1_fb32_setzero(uint32_t *a, long blen);
//most significant index
long amsclil1_fb32_msi(uint32_t*a, long blen);
//large integer display functions
void amsclil1_fb32_liprint(uint32_t* a, long blen); //print hex representation
void amsclil1_fb16_liprint(uint16_t* a, long blen); //print hex representation
void amsclil1_fb32_libinprint(uint32_t* a, long blen); //print binary representation
//bit shift operations
//lshift: <<: *2^shift
//wrk[blen]
void amsclil1_fb32_shiftl(uint32_t* a, long shift, uint32_t* wrk, long blen);
void amsclil1_fb32_shiftr(uint32_t* a, long shift, uint32_t* wrk, long blen);
//Fixed Buffer Operators
void amsclil1_fb32_add(uint32_t *a, uint32_t *b, uint32_t *c, long blen);
void amsclil1_fb32_sub(uint32_t *a, uint32_t *b, uint32_t *c, long blen);
//schoolbook multiplication
// karatsuba multiplication may be needed for large enough numbers
void amsclil1_fb32_mult(uint32_t *a, uint32_t *b, uint32_t *c, uint32_t *wrk, long blen);
//Division using algorithm [HAC 14.20]
int amsclil1_fb32_div(uint32_t *a, uint32_t *b, uint32_t *res, uint32_t *rem, uint32_t* wrk, long blen);
//Implement!
void amsclil1_fb32_decimal(uint32_t *a, uint8_t *dd, uint32_t* wrk, int blen);
//Modular exponentiation [now using HAC14.42 Barrett Reduction]
void amsclil1_fb32_modpower(uint32_t *a, uint32_t *pw, uint32_t *md, uint32_t *res, uint32_t *wrk, uint32_t *stor, int blen);
//non-cryptographic random integer for testing
void amsclil1_fb32_ncrandint(uint32_t *a, long blen);
//Euler greatest common divisor algorithm
void amsclil1_fb32_eulergcd(uint32_t *a, uint32_t *b, uint32_t *gcd, uint32_t *wrk, long blen);
//Least Common Multiple
void amsclil1_fb32_lcm(uint32_t *a, uint32_t *b, uint32_t *lcm, uint32_t *wrk, long blen);
//Multiplicative Inverse Algorithm
int amsclil1_fb32_multinv(uint32_t *z, uint32_t *dom, uint32_t *zinv, uint32_t *wrk, int blen);
//Euler totient function
// for prime numbers it's just n-1
//Carmichels Totient Function
////////////////////////////////////////
//Miscellaneous and Internal Functions//
////////////////////////////////////////
//16 bit fixed buffer operations
//used in HAC14.20 division algorithm
void amsclil1_fb16_mult(uint16_t *a, uint16_t *b, uint16_t *c, long blen);
//[HAC 14.42]: Barrett reduction of modular arithmetic
//Precomputation of mu divisor
void amsclil1_fb32_barrettmu(uint32_t *m, uint32_t *mu, uint32_t *wrk, long K, long blen);
//Barrett Reduced Modulus
//y = mod(x,m)
void amsclil1_fb32_barrettmod(uint32_t *x, uint32_t *m, uint32_t *y,
uint32_t *mu, uint32_t *wrk, long K, long Kx, long blen);
//Classical Fast Modular Exponentiation
void amsclil1_fb32_modpower_cls(uint32_t *a, uint32_t *pw, uint32_t *md, uint32_t *res, uint32_t *wrk, uint32_t *stor, int blen);
//Fast Modular Exponentiation with Barrett Reduction
void amsclil1_fb32_modpower_bar(uint32_t *a, uint32_t *pw, uint32_t *md, uint32_t *res, uint32_t *wrk, uint32_t *stor, int blen);
//Shifted Operations
//bit-shifted reads and writes
//don't move the array in memory, move the read/write
//perhaps it will save time within the division operation
int amsclil1_fb32_readshift(uint32_t* arr, long ind, long shift, uint32_t* val, long blen);
int amsclil1_fb32_writeshift(uint32_t* arr, long ind, long shift, uint32_t* val, long blen);
//Shifted Large Integer Display Function
void amsclil1_fb32_shiftliprint(uint32_t* a, long shift, long blen); //print hex representation
//Shifted integer, most significant index
long amsclil1_fb32_shiftmsi(uint32_t *a, long shift, long blen);
//Shifted comparison
int amsclil1_fb32_shiftcmp(uint32_t *a, uint32_t *b, long bshift, long blen);
//Shifted subtraction
void amsclil1_fb32_shiftsub(uint32_t *a, uint32_t *b, long bshift, uint32_t *c, long blen);
//internal digit shift subtraction
//this is supposed to be something like c = a - b*base^diff
void amsclil1_fb16_intlssub(uint16_t *a, uint16_t *b, long bshft, uint16_t *c, long blen);
//internal digit shift comparison
//this is supposed to be a <=> b*base^diff
int amsclil1_fb16_intlscmp(uint16_t *a, uint16_t *b, long bshft, long blen);
void amsclil1_fb16_intlmultsing(uint16_t *a, uint16_t b, long blen);
#endif

View File

@ -0,0 +1,33 @@
#ifndef __AMSCLIL1_GUTMANNPRNG_H__
#define __AMSCLIL1_GUTMANNPRNG_H__
typedef struct amsclil1_gprng_state
{
int randpool_length;
uint8_t *randpool;
int write_pointer;
int cycle_pointer;
} amsclil1_gprng_state;
int amsclil1_gprng_state_new(amsclil1_gprng_state **s);
void amsclil1_gprng_state_delete(amsclil1_gprng_state **s);
//sets new random pool length (default is 640 bytes)
int amsclil1_gprng_state_resize(amsclil1_gprng_state *s, int N);
void amsclil1_gprng_add_byte(amsclil1_gprng_state *s, uint8_t byte);
void amsclil1_gprng_add_bytes(amsclil1_gprng_state *s, uint8_t *bytes, int N);
void amsclil1_gprng_mix_once(amsclil1_gprng_state *s);
void amsclil1_gprng_mix(amsclil1_gprng_state *s);
//Original gprng hash is MD5, set to take 84 bytes in, and provide 16 bytes out
void amsclil1_gprng_hash(uint8_t *bytes_in, int Nin, uint8_t *bytes_out);
//: A randompool of 640 bytes (5120 bits) and a hash algorithm
// outputing 16 bytes (128) bits, requires 40 cycles, not 30, to
// completely cover the random pool.
#endif

View File

@ -0,0 +1,17 @@
#ifndef __AMSCLIL1_HASH_H__
#define __AMSCLIL1_HASH_H__
//////////////////
//Hash Functions//
//////////////////
//Low level components of many cryptographic operations
//MD5 Hash Algorithm
//Input: Some number of bytes in
//Output: 16 bytes (128 bits) digest out
int amsclil1_md5_hash(const uint8_t *bytes_in, size_t Nin, uint8_t *bytes16_out);
#endif

View File

@ -0,0 +1,7 @@
#ifndef __AMSCLIL_OPERATIONS_H__
#define __AMSCLIL_OPERATIONS_H__
#endif

View File

@ -0,0 +1,39 @@
#ifndef __AMSCLIL1_TESTS_H__
#define __AMSCLIL1_TESTS_H__
void test_fbops_printcmp();
void test_fbops_shiftread();
void test_fbops_shiftwrite();
void test_fbops_lshiftrshift();
void test_modtdiv();
void test_addsub();
void test_mult();
void test_div();
void test_modpower();
void test_mult_time();
void test_div_time();
//non_cryptographic test randomness
void amsclil1_fb32_testrandom(uint32_t* a,long blen);
void test_barrettmod();
void barret_modpower_test();
void barrett_mod_fuzztest();
void modpower_timetests();
void test_amsclil1_fb32_eulergcd();
void test_fb16_comparison_sub();
void test_div_stress_test();
void test_div_stress_test2();
void test_ui64bitshifts();
void amsclil1_test_fb32_lcm1();
#endif

View File

@ -0,0 +1,82 @@
#ifndef __AMSCLIL1_ULINT_HPP__
#define __AMSCLIL1_ULINT_HPP__
///////////////////////////////////
// Unsigned Large Integer Object //
///////////////////////////////////
// This is an unsigned large integer object based on 32-bit words. 32 bits seems to be
// the fastest width for the underlying data.
typedef struct amsclil1_ulint
{
int N;
uint32_t *data;
} amsclil1_ulint;
// Container Class Routines
int amsclil1_ulint_new(amsclil1_ulint **pnt);
void amsclil1_ulint_delete(amsclil1_ulint **pnt);
int amsclil1_ulint_init(amsclil1_ulint *pnt);
void amsclil1_ulint_cleanup(amsclil1_ulint *pnt);
//resize integer buffer to new size _N
int amsclil1_ulint_resize(amsclil1_ulint *pnt, int _N);
//If _N is greater than current size, expand to larger size, otherwise do nothing
int amsclil1_ulint_resizetomin(amsclil1_ulint *pnt, int _N);
//Most significant index of number
int amsclil1_ulint_msindex(amsclil1_ulint *pnt);
//shrink memory to most significant index
int amsclil1_ulint_shrinktofit(amsclil1_ulint *pnt);
//sets all data to 0
void amsclil1_ulint_clear(amsclil1_ulint *pnt);
//copies src data to dest. resizes dest if necessary, otherwise does not.
int amsclil1_ulint_copy(amsclil1_ulint *dest, amsclil1_ulint *src);
// Display
void amsclil1_ulint_printhex(amsclil1_ulint *pnt);
void amsclil1_ulint_printbits(amsclil1_ulint *pnt);
// Conversion To/From amscutil bytebuffer
// Comparators
// Unsigned Large Integer Comparison Operator:
// 0 - a==b
// 1 - a>b
// 2 - a<b
int amsclil1_ulint_cmp(amsclil1_ulint *a, amsclil1_ulint *b);
int amsclil1_ulint_iszero(amsclil1_ulint *a);
// Math Operations
// These operations may be slower than the preallocated fixed buffer operations
// They are included for simplicity in constructing and testing algorithms.
// The necessary sizes and working memory is preallocated during execution.
// Inputs are copied internally, so output can point to the same integer as input.
int amsclil1_ulint_add(amsclil1_ulint *a, amsclil1_ulint *b, amsclil1_ulint *c);
int amsclil1_ulint_sub(amsclil1_ulint *a, amsclil1_ulint *b, amsclil1_ulint *c);
int amsclil1_ulint_mult(amsclil1_ulint *a, amsclil1_ulint *b, amsclil1_ulint *c);
//int amsclil1_ulint_div(amsclil1_ulint *a, amsclil1_ulint *b, amsclil1_ulint *q, amsclil1_ulint *r);
//modpower
//rep_modpower
//gcd
//lcm
//Tests
void amsclil1_ulint_tests1();
#endif