/** Get value of big integer. * * Allows to obtain the value of big integer, provided that it fits * into a small integer. * * @param bigint Bigint to obtain value from. * @param dval Place to store value. * @return EOK on success, ELIMIT if bigint is too big to fit * to @a dval. */ int bigint_get_value_int(bigint_t *bigint, int *dval) { bigint_t vval, diff; size_t idx; int val; bool_t zf; #ifdef DEBUG_BIGINT_TRACE printf("Get int value of bigint.\n"); #endif val = 0; for (idx = 0; idx < bigint->length; ++idx) { val = val * BIGINT_BASE + bigint->digit[idx]; } if (bigint->negative) val = - val; /* If the value did not fit @c val now contains garbage. Verify. */ bigint_init(&vval, val); bigint_sub(bigint, &vval, &diff); zf = bigint_is_zero(&diff); bigint_destroy(&vval); bigint_destroy(&diff); /* If the difference is not zero, the verification failed. */ if (zf != b_true) return EINVAL; *dval = val; return EOK; }
/* Return 1 if the current cell is 0 and 0 otherwise */ int is_zero(Memory *mem) { void *cell; /* memory leak, return 0 even though the program is about to die */ if(!(cell = get_cell(mem))) return 0; if(wrap) return *(unsigned char *)cell == 0; else return bigint_is_zero(cell); }
/** * Perform modular exponentiation of big integers * * @v base0 Element 0 of big integer base * @v modulus0 Element 0 of big integer modulus * @v exponent0 Element 0 of big integer exponent * @v result0 Element 0 of big integer to hold result * @v size Number of elements in base, modulus, and result * @v exponent_size Number of elements in exponent * @v tmp Temporary working space */ void bigint_mod_exp_raw ( const bigint_element_t *base0, const bigint_element_t *modulus0, const bigint_element_t *exponent0, bigint_element_t *result0, unsigned int size, unsigned int exponent_size, void *tmp ) { const bigint_t ( size ) __attribute__ (( may_alias )) *base = ( ( const void * ) base0 ); const bigint_t ( size ) __attribute__ (( may_alias )) *modulus = ( ( const void * ) modulus0 ); const bigint_t ( exponent_size ) __attribute__ (( may_alias )) *exponent = ( ( const void * ) exponent0 ); bigint_t ( size ) __attribute__ (( may_alias )) *result = ( ( void * ) result0 ); size_t mod_multiply_len = bigint_mod_multiply_tmp_len ( modulus ); struct { bigint_t ( size ) base; bigint_t ( exponent_size ) exponent; uint8_t mod_multiply[mod_multiply_len]; } *temp = tmp; static const uint8_t start[1] = { 0x01 }; memcpy ( &temp->base, base, sizeof ( temp->base ) ); memcpy ( &temp->exponent, exponent, sizeof ( temp->exponent ) ); bigint_init ( result, start, sizeof ( start ) ); while ( ! bigint_is_zero ( &temp->exponent ) ) { if ( bigint_bit_is_set ( &temp->exponent, 0 ) ) { bigint_mod_multiply ( result, &temp->base, modulus, result, temp->mod_multiply ); } bigint_ror ( &temp->exponent ); bigint_mod_multiply ( &temp->base, &temp->base, modulus, &temp->base, temp->mod_multiply ); } }
/** Convert bigint to string. * * @param bigint Bigint to convert. * @param dptr Place to store pointer to new string. */ void bigint_get_as_string(bigint_t *bigint, char **dptr) { static const char digits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; bigint_t val, tmp; bigint_word_t rem; size_t nchars; char *str; size_t idx; #ifdef DEBUG_BIGINT_TRACE printf("Convert bigint to string.\n"); #endif static_assert(BIGINT_BASE >= 10); /* Compute number of characters. */ nchars = 0; if (bigint_is_zero(bigint) || bigint->negative) nchars += 1; /* '0' or '-' */ bigint_clone(bigint, &val); while (bigint_is_zero(&val) != b_true) { bigint_div_digit(&val, 10, &tmp, &rem); bigint_destroy(&val); bigint_shallow_copy(&tmp, &val); nchars += 1; } bigint_destroy(&val); /* Store characters to array. */ str = malloc(nchars * sizeof(char) + 1); if (str == NULL) { printf("Memory allocation failed.\n"); exit(1); } if (bigint_is_zero(bigint)) { str[0] = '0'; } else if (bigint->negative) { str[0] = '-'; } idx = 1; bigint_clone(bigint, &val); while (bigint_is_zero(&val) != b_true) { bigint_div_digit(&val, 10, &tmp, &rem); bigint_destroy(&val); bigint_shallow_copy(&tmp, &val); str[nchars - idx] = digits[(int) rem]; ++idx; } bigint_destroy(&val); str[nchars] = '\0'; *dptr = str; }