bool CBBigIntEqualsAdditionByBigInt(CBBigInt * a,CBBigInt * b){ if (a->length < b->length) { if (NOT CBBigIntRealloc(a, b->length)) return false; // Make certain expansion of data is empty memset(a->data + a->length, 0, b->length - a->length); a->length = b->length; } // a->length >= b->length bool overflow = 0; uint8_t x = 0; for (; x < b->length; x++) { a->data[x] += b->data[x] + overflow; // a->data[x] now equals the result of the addition. // The overflow will never go beyond 1. Imagine a->data[x] == 0xff, b->data[x] == 0xff and the overflow is 1, the new overflow is still 1 and a->data[x] is 0xff. Therefore it does work. overflow = (a->data[x] < (b->data[x] + overflow))? 1 : 0; } // Propagate overflow up the whole length of a if necessary while (overflow && x < a->length) overflow = NOT ++a->data[x++]; // Index at x, increment x, increment data, test new value for overflow. if (overflow) { // Add extra byte a->length++; if (NOT CBBigIntRealloc(a, a->length)) return false; a->data[a->length - 1] = 1; } return true; }
bool CBBigIntEqualsMultiplicationByUInt8(CBBigInt * a,uint8_t b){ if (NOT b) { // Mutliplication by zero. "a" becomes zero a->length = 1; a->data[0] = 0; return true; } if (a->length == 1 && NOT a->data[0]) // "a" is zero return true; // Multiply b by each byte and then add to answer uint16_t carry = 0; uint8_t x = 0; for (; x < a->length; x++) { carry = carry + a->data[x] * b; // Allow for overflow onto next byte. a->data[x] = carry; carry >>= 8; } if (carry) { // If last byte is not zero, adjust length. if (NOT CBBigIntRealloc(a, a->length+1)) return false; a->length++; a->data[x] = carry; } return true; }
bool CBDecodeBase58(CBBigInt * bi, char * str){ // ??? Quite likely these functions can be improved CBBigInt bi2; if (NOT CBBigIntAlloc(&bi2, 1)) return false; bi->data[0] = 0; bi->length = 1; for (uint8_t x = strlen(str) - 1;; x--){ // Working backwards // Get index in alphabet array uint8_t alphaIndex = str[x]; if (alphaIndex != 49){ // If not 1 if (str[x] < 58){ // Numbers alphaIndex -= 49; }else if (str[x] < 73){ // A-H alphaIndex -= 56; }else if (str[x] < 79){ // J-N alphaIndex -= 57; }else if (str[x] < 91){ // P-Z alphaIndex -= 58; }else if (str[x] < 108){ // a-k alphaIndex -= 64; }else{ // m-z alphaIndex -= 65; } if (NOT CBBigIntFromPowUInt8(&bi2, 58, strlen(str) - 1 - x)){ // Error occured. free(bi2.data); return false; } if (NOT CBBigIntEqualsMultiplicationByUInt8(&bi2, alphaIndex)){ // Error occured. free(bi2.data); return false; } if (NOT CBBigIntEqualsAdditionByBigInt(bi, &bi2)){ // Error occured. free(bi2.data); return false; } } if (NOT x) break; } free(bi2.data); // Got CBBigInt from base-58 string. Add zeros on end. uint8_t zeros = 0; for (uint8_t x = 0; x < strlen(str); x++) if (str[x] == '1') zeros++; else break; if (zeros) { bi->length += zeros; if (NOT CBBigIntRealloc(bi, bi->length)) return false; memset(bi->data + bi->length - zeros, 0, zeros); } return true; }