Exemple #1
0
/** 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;
}
Exemple #2
0
/* 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);
}
Exemple #3
0
/**
 * 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 );
	}
}
Exemple #4
0
/** 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;
}