Program Listing for File uint256.cu#
↰ Return to documentation for file (src/uint256.cu
)
#include "uint256.cuh"
// implementation
__host__ int hexToInt(const char *hex) {
int result = 0;
int len = strlen(hex);
for (int i = 0; i < len; i++) {
char c = tolower(hex[i]);
if (c >= '0' && c <= '9') {
result = result * 16 + (c - '0');
} else if (c >= 'a' && c <= 'f') {
result = result * 16 + (c - 'a' + 10);
} else {
// Invalid hexadecimal character
return -1;
}
}
return result;
}
__host__ void intToHex(int num, char *hex) {
// Assuming hex has enough space
char *ptr = hex;
do {
int remainder = num % 16;
if (remainder < 10) {
*ptr++ = '0' + remainder;
} else {
*ptr++ = 'a' + (remainder - 10);
}
num /= 16;
} while (num != 0);
*ptr-- = '\0'; // NULL-terminate the string and point to the last valid character
// Reverse the string
char *start = hex;
while (start < ptr) {
char t = *start;
*start = *ptr;
*ptr = t;
start++;
ptr--;
}
}
__host__ bool hex_to_decimal(const char *hex_str, char *dec_str) {
unsigned long long result = 0;
unsigned long long place = 1;
int len = strlen(hex_str);
for (int i = len - 1; i >= 0; i--) {
char c = tolower(hex_str[i]);
int digit;
if (c >= '0' && c <= '9') {
digit = c - '0';
} else if (c >= 'a' && c <= 'f') {
digit = 10 + (c - 'a');
} else {
return false;
}
result += digit * place;
place *= 16;
}
sprintf(dec_str, "%llu", result);
return true;
}
__host__ bool base_uint_set_hex(base_uint *val, const char *hex) {
memset(val->pn, 0, sizeof(val->pn));
size_t len = strlen(hex);
if (len == 0 || len > BITS / 4) return false;
// Iterate through the string from end to start
for (size_t i = 0; i < len; i++) {
char c = tolower(hex[len - 1 - i]);
uint32_t number = 0;
if (c >= '0' && c <= '9') {
number = c - '0';
} else if (c >= 'a' && c <= 'f') {
number = c - 'a' + 10;
} else {
return false; // Invalid character
}
// Determine which uint32_t element and position the hex character should be placed
val->pn[i / 8] |= (number << ((i % 8) * 4));
}
return true;
}
__host__ void base_uint_to_string(const base_uint *val, char *out_str) {
char hex_str[BITS / 4 + 1] = {0};
base_uint_get_hex(val, hex_str);
if (!hex_to_decimal(hex_str, out_str)) {
strcpy(out_str, "Error");
}
}
__host__ bool int_to_base_uint(int int_val, base_uint *val) {
char *p;
sprintf(p, "%08x", int_val);
printf("%s\n", p);
return base_uint_set_hex(val, p);
}
__host__ __device__ void base_uint_get_hex(const base_uint *val, char *hex) {
char *p = hex;
for (int i = WIDTH - 1; i >= 0; i--) {
// printf("%d ", val->pn[i]);
sprintf(p, "%08x", val->pn[i]);
p += 8;
}
}
__host__ __device__ void print_base_uint(const base_uint *val) {
for (int i = 0; i < WIDTH; i++) {
printf("%d ", val->pn[i]);
}
}
__host__ __device__ bool is_zero(const base_uint *num) {
for (int i = 0; i < WIDTH; i++) {
if (num->pn[i] != 0) {
return false;
}
}
return true;
}
__host__ __device__ base_uint bitwise_not(const base_uint *num) {
base_uint ret;
for (int i = 0; i < WIDTH; i++) {
ret.pn[i] = ~num->pn[i];
}
return ret;
}
__host__ __device__ void base_uint_set_bit(base_uint *value, uint32_t bitpos) {
value->pn[bitpos / 32] |= (1 << (bitpos % 32));
}
__host__ __device__ void base_uint_add(const base_uint *a, const base_uint *b, base_uint *result) {
uint64_t carry = 0;
for (size_t i = 0; i < WIDTH; i++) {
uint64_t sum = (uint64_t)a->pn[i] + b->pn[i] + carry;
printf("%d %d = %d %d\n", a->pn[i], b->pn[i], sum, carry);
result->pn[i] = (uint32_t)sum; // Store lower 32 bits
carry = sum >> 32; // Take upper 32 bits as the next carry
}
}
__host__ __device__ bool base_uint_sub(const base_uint *a, const base_uint *b, base_uint *result) {
uint64_t borrow = 0;
for (size_t i = 0; i < WIDTH; i++) {
uint64_t res = 0x100000000ULL + (uint64_t)a->pn[i] - b->pn[i] - borrow;
result->pn[i] = (uint32_t)res;
if (res >= 0x100000000ULL) {
borrow = 0;
} else {
borrow = 1;
}
}
// If borrow is still 1 after looping through all words, then a < b.
// Return false to indicate underflow
return borrow == 0;
}
/*
Warming:
1. Not tested yet.
2. Overflow wraparound is not correctly implemented yet.
*/
__host__ __device__ void base_uint_mul(const base_uint *a, const base_uint *b, base_uint *result) {
base_uint temp_result = {0};
for (size_t i = 0; i < WIDTH; i++) {
uint64_t carry = 0;
for (size_t j = 0; j < WIDTH; j++) {
if (i + j < WIDTH) {
uint64_t product = (uint64_t)a->pn[i] * b->pn[j] + temp_result.pn[i + j] + carry;
temp_result.pn[i + j] = (uint32_t)product;
carry = product >> 32;
}
}
}
for (size_t i = 0; i < WIDTH; i++) {
result->pn[i] = temp_result.pn[i];
}
}