From 93ebab379bf9f3bd3948b263da7362cfc07abc5e Mon Sep 17 00:00:00 2001 From: Kevin Cotugno Date: Wed, 10 Oct 2018 16:40:47 -0700 Subject: [PATCH] WIP --- c/big_int.c | 80 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 66 insertions(+), 14 deletions(-) diff --git a/c/big_int.c b/c/big_int.c index 4d52469..ea3796f 100644 --- a/c/big_int.c +++ b/c/big_int.c @@ -26,13 +26,23 @@ #define LSHIFT32(x) (x << BIT_SIZE) #define RSHIFT32(x) (x >> BIT_SIZE) +#define SWAP(x, y) { void *tmp = x; x = y, y = tmp; } + +typedef unsigned BOOL; + struct big_int { uint64_t count; uint64_t size; uint32_t* buf; }; -void big_int_grow(struct big_int* i, int copy); +struct big_int* big_int_init(uint64_t x); +void big_int_destroy(struct big_int* i); +void big_int_internal_grow(struct big_int* i, size_t size, BOOL copy); +void big_int_grow(struct big_int* i, BOOL copy); +uint64_t big_int_bit_len(struct big_int* i); +void big_int_add(struct big_int *a, struct big_int *b); +void big_int_sub(struct big_int* a, struct big_int* b); struct big_int* big_int_init(uint64_t x) { @@ -53,28 +63,32 @@ void big_int_destroy(struct big_int* i) free(i); } -void big_int_grow(struct big_int* i, int copy) +void big_int_internal_grow(struct big_int* i, size_t size, BOOL copy) { uint32_t* tmp; - size_t new_size = (size_t)i->size * MEM_STEPS; - - tmp = (uint32_t*)calloc(new_size, sizeof(uint32_t)); - - if (copy) - memcpy(tmp, i->buf, sizeof(uint32_t) * (size_t)i->size); + tmp = (uint32_t*)calloc(size, sizeof(uint32_t) * size); if (tmp == NULL) { printf("Unable to allocate memory"); exit(1); } + if (copy) + memcpy(tmp, i->buf, sizeof(uint32_t) * (size_t)i->size); + i->buf = tmp; - i->size = new_size; + i->size = size; +} + +void big_int_grow(struct big_int* i, BOOL copy) +{ + size_t new_size = (size_t)i->size * MEM_STEPS; + big_int_internal_grow(i, new_size, copy); } uint64_t big_int_bit_len(struct big_int* i) { - uint64_t j = 32; + uint32_t j = 32; uint32_t x = i->buf[i->count - 1]; if (x <= 0x0000ffff) j -= 16, x <<= 16; @@ -121,12 +135,11 @@ void big_int_add(struct big_int *a, struct big_int *b) i++; } while(i < a->count || i < b->count || carry > 0); - uint32_t* tmp_ptr = a->buf; - a->buf = result->buf; + SWAP(a->buf, result->buf); a->count = i; a->size = result->size; - free(tmp_ptr); + big_int_destroy(result); } void big_int_add_uint32(struct big_int* a, uint32_t b) @@ -134,19 +147,58 @@ void big_int_add_uint32(struct big_int* a, uint32_t b) big_int_add(a, big_int_init(b)); } +void big_int_sub(struct big_int* a, struct big_int* b) +{ + struct big_int* result = big_int_init(0); + uint64_t tmp = 0; + uint64_t carry = 0; + + uint64_t i = a->count + 2; + do { + uint64_t x = 0, y = 0; + + if (i - 2 < a->count) { + x = (uint64_t)a->buf[i - 2]; + } + + x |= carry; + + if (i - 2 < b->count) { + y = (uint64_t)b->buf[i - 2]; + } + + tmp = x - y; + result->buf[i - 1] = (uint32_t)RSHIFT32(UPPER64(tmp)); + carry = LSHIFT32(LOWER64(tmp)); + + --i; + } while(i > 0); + + SWAP(a->buf, result->buf); + a->size = result->size; + + big_int_destroy(result); +} + int main(void) { struct big_int* bi = big_int_init(123456789); big_int_add_uint32(bi, 123456789); - for (int i = 0; i < 1000; i++) + for (int i = 0; i < 10; i++) big_int_add(bi, bi); for (uint64_t i = 0; i < bi->count; i++) printf("[%" PRIu32 "] ", bi->buf[i]); printf("\n"); + big_int_sub(bi, big_int_init(53350)); + + for (uint64_t i = 0; i < bi->count; i++) + printf("[%" PRIu32 "] ", bi->buf[i]); + printf("\n"); + printf("%lu\n", big_int_bit_len(bi)); printf("%" PRIu64 "\n", bi->size);