1 /* Based on https://github.com/kokke/tiny-bignum-c.
2  * Enjoy it --FXTi
3  */
4 
5 #include <r_util.h>
6 
7 /* Functions for shifting number in-place. */
8 static void _lshift_one_bit(RNumBig *a);
9 static void _rshift_one_bit(RNumBig *a);
10 static void _lshift_word(RNumBig *a, int nwords);
11 static void _rshift_word(RNumBig *a, int nwords);
12 static void _r_big_zero_out(RNumBig *n);
13 
r_big_new(void)14 R_API RNumBig *r_big_new(void) {
15 	RNumBig *n = R_NEW (RNumBig);
16 	if (n) {
17 		_r_big_zero_out (n);
18 	}
19 	return n;
20 }
21 
r_big_free(RNumBig * b)22 R_API void r_big_free(RNumBig *b) {
23 	free (b);
24 }
25 
r_big_init(RNumBig * b)26 R_API void r_big_init(RNumBig *b) {
27 	_r_big_zero_out (b);
28 }
29 
r_big_fini(RNumBig * b)30 R_API void r_big_fini(RNumBig *b) {
31 	_r_big_zero_out (b);
32 }
33 
r_big_from_int(RNumBig * b,st64 n)34 R_API void r_big_from_int(RNumBig *b, st64 n) {
35 	r_return_if_fail (b);
36 
37 	_r_big_zero_out (b);
38 	b->sign = (n < 0)? -1: 1;
39 	R_BIG_DTYPE_TMP v = n * b->sign;
40 
41 	/* Endianness issue if machine is not little-endian? */
42 #ifdef R_BIG_WORD_SIZE
43 #if (R_BIG_WORD_SIZE == 1)
44 	b->array[0] = (v & 0x000000ff);
45 	b->array[1] = (v & 0x0000ff00) >> 8;
46 	b->array[2] = (v & 0x00ff0000) >> 16;
47 	b->array[3] = (v & 0xff000000) >> 24;
48 #elif (R_BIG_WORD_SIZE == 2)
49 	b->array[0] = (v & 0x0000ffff);
50 	b->array[1] = (v & 0xffff0000) >> 16;
51 #elif (R_BIG_WORD_SIZE == 4)
52 	b->array[0] = v;
53 	R_BIG_DTYPE_TMP num_32 = 32;
54 	R_BIG_DTYPE_TMP tmp = v >> num_32;
55 	b->array[1] = tmp;
56 #endif
57 #endif
58 }
59 
r_big_from_unsigned(RNumBig * b,ut64 v)60 static void r_big_from_unsigned(RNumBig *b, ut64 v) {
61 	r_return_if_fail (b);
62 
63 	_r_big_zero_out (b);
64 
65 	/* Endianness issue if machine is not little-endian? */
66 #ifdef R_BIG_WORD_SIZE
67 #if (R_BIG_WORD_SIZE == 1)
68 	b->array[0] = (v & 0x000000ff);
69 	b->array[1] = (v & 0x0000ff00) >> 8;
70 	b->array[2] = (v & 0x00ff0000) >> 16;
71 	b->array[3] = (v & 0xff000000) >> 24;
72 #elif (R_BIG_WORD_SIZE == 2)
73 	b->array[0] = (v & 0x0000ffff);
74 	b->array[1] = (v & 0xffff0000) >> 16;
75 #elif (R_BIG_WORD_SIZE == 4)
76 	b->array[0] = v;
77 	R_BIG_DTYPE_TMP num_32 = 32;
78 	R_BIG_DTYPE_TMP tmp = v >> num_32;
79 	b->array[1] = tmp;
80 #endif
81 #endif
82 }
83 
r_big_to_int(RNumBig * b)84 R_API st64 r_big_to_int(RNumBig *b) {
85 	r_return_val_if_fail (b, 0);
86 
87 	R_BIG_DTYPE_TMP ret = 0;
88 
89 	/* Endianness issue if machine is not little-endian? */
90 #if (R_BIG_WORD_SIZE == 1)
91 	ret += b->array[0];
92 	ret += b->array[1] << 8;
93 	ret += b->array[2] << 16;
94 	ret += b->array[3] << 24;
95 #elif (R_BIG_WORD_SIZE == 2)
96 	ret += b->array[0];
97 	ret += b->array[1] << 16;
98 #elif (R_BIG_WORD_SIZE == 4)
99 	ret += b->array[1];
100 	ret <<= 32;
101 	ret += b->array[0];
102 #endif
103 
104 	if (b->sign < 0) {
105 		return -ret;
106 	}
107 	return ret;
108 }
109 
r_big_from_hexstr(RNumBig * n,const char * str)110 R_API void r_big_from_hexstr(RNumBig *n, const char *str) {
111 	r_return_if_fail (n);
112 	r_return_if_fail (str);
113 	int nbytes = strlen (str);
114 
115 	_r_big_zero_out (n);
116 
117 	if (str[0] == '-') {
118 		n->sign = -1;
119 		str += 1;
120 		nbytes -= 1;
121 	}
122 
123 	if (str[0] == '0' && str[1] == 'x') {
124 		str += 2;
125 		nbytes -= 2;
126 	}
127 	r_return_if_fail (nbytes > 0);
128 
129 	R_BIG_DTYPE tmp;
130 	int i = nbytes - (2 * R_BIG_WORD_SIZE); /* index into string */
131 	int j = 0; /* index into array */
132 
133 	while (i >= 0) {
134 		tmp = 0;
135 		sscanf (&str[i], R_BIG_SSCANF_FORMAT_STR, &tmp);
136 		n->array[j] = tmp;
137 		i -= (2 * R_BIG_WORD_SIZE); /* step R_BIG_WORD_SIZE hex-byte(s) back in the string. */
138 		j += 1; /* step one element forward in the array. */
139 	}
140 
141 	if (-2 * R_BIG_WORD_SIZE < i) {
142 		char buffer[2 * R_BIG_WORD_SIZE];
143 		memset (buffer, 0, sizeof (buffer));
144 		i += 2 * R_BIG_WORD_SIZE - 1;
145 		for (; i >= 0; i--) {
146 			buffer[i] = str[i];
147 		}
148 		tmp = 0;
149 		sscanf (buffer, R_BIG_SSCANF_FORMAT_STR, &tmp);
150 		n->array[j] = tmp;
151 	}
152 }
153 
r_big_to_hexstr(RNumBig * b)154 R_API char *r_big_to_hexstr(RNumBig *b) {
155 	r_return_val_if_fail (b, NULL);
156 
157 	int j = R_BIG_ARRAY_SIZE - 1; /* index into array - reading "MSB" first -> big-endian */
158 	size_t i = 0; /* index into string representation. */
159 	size_t k = 0; /* Leading zero's amount */
160 	size_t z, last_z = 2 * R_BIG_WORD_SIZE;
161 
162 	for (; b->array[j] == 0 && j >= 0; j--) {
163 	}
164 	if (j == -1) {
165 		return "0x0";
166 	}
167 
168 	size_t size = 3 + 2 * R_BIG_WORD_SIZE * (j + 1) + ((b->sign > 0)? 0: 1);
169 	char *ret_str = calloc (size, sizeof (char));
170 	if (!ret_str) {
171 		return NULL;
172 	}
173 
174 	if (b->sign < 0) {
175 		ret_str[i++] = '-';
176 	}
177 	ret_str[i++] = '0';
178 	ret_str[i++] = 'x';
179 
180 	r_snprintf (ret_str + i, R_BIG_FORMAT_STR_LEN, R_BIG_SPRINTF_FORMAT_STR, b->array[j--]);
181 	for (; ret_str[i + k] == '0' && k < 2 * R_BIG_WORD_SIZE; k++) {
182 	}
183 	for (z = k; ret_str[i + z] && z < last_z; z++) {
184 		ret_str[i + z - k] = ret_str[i + z];
185 	}
186 	i += z - k;
187 	ret_str[i] = '\x00'; // Truncate string for case(j < 0)
188 
189 	for (; j >= 0; j--) {
190 		r_snprintf (ret_str + i, R_BIG_FORMAT_STR_LEN, R_BIG_SPRINTF_FORMAT_STR, b->array[j]);
191 		i += 2 * R_BIG_WORD_SIZE;
192 	}
193 
194 	return ret_str;
195 }
196 
r_big_assign(RNumBig * dst,RNumBig * src)197 R_API void r_big_assign(RNumBig *dst, RNumBig *src) {
198 	r_return_if_fail (dst);
199 	r_return_if_fail (src);
200 
201 	memcpy (dst, src, sizeof (RNumBig));
202 }
203 
r_big_add_inner(RNumBig * c,RNumBig * a,RNumBig * b)204 static void r_big_add_inner(RNumBig *c, RNumBig *a, RNumBig *b) {
205 	R_BIG_DTYPE_TMP tmp;
206 	int carry = 0;
207 	int i;
208 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
209 		tmp = (R_BIG_DTYPE_TMP)a->array[i] + b->array[i] + carry;
210 		carry = (tmp > R_BIG_MAX_VAL);
211 		c->array[i] = (tmp & R_BIG_MAX_VAL);
212 	}
213 }
214 
r_big_sub_inner(RNumBig * c,RNumBig * a,RNumBig * b)215 static void r_big_sub_inner(RNumBig *c, RNumBig *a, RNumBig *b) {
216 	R_BIG_DTYPE_TMP res;
217 	RNumBig *tmp;
218 	R_BIG_DTYPE_TMP tmp1;
219 	R_BIG_DTYPE_TMP tmp2;
220 	int borrow = 0;
221 	int sign = r_big_cmp (a, b);
222 	c->sign = (sign >= 0? 1: -1);
223 	if (sign < 0) {
224 		tmp = a;
225 		a = b;
226 		b = tmp;
227 	}
228 	int i;
229 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
230 		tmp1 = (R_BIG_DTYPE_TMP)a->array[i] + (R_BIG_MAX_VAL + 1); /* + number_base */
231 		tmp2 = (R_BIG_DTYPE_TMP)b->array[i] + borrow;
232 
233 		res = (tmp1 - tmp2);
234 		c->array[i] = (R_BIG_DTYPE) (res & R_BIG_MAX_VAL); /* "modulo number_base" == "% (number_base - 1)" if nu    mber_base is 2^N */
235 		borrow = (res <= R_BIG_MAX_VAL);
236 	}
237 }
238 
r_big_add(RNumBig * c,RNumBig * a,RNumBig * b)239 R_API void r_big_add(RNumBig *c, RNumBig *a, RNumBig *b) {
240 	r_return_if_fail (a);
241 	r_return_if_fail (b);
242 	r_return_if_fail (c);
243 
244 	if (a->sign >= 0 && b->sign >= 0) {
245 		r_big_add_inner (c, a, b);
246 		c->sign = 1;
247 		return;
248 	}
249 	if (a->sign >= 0 && b->sign < 0) {
250 		r_big_sub_inner (c, a, b);
251 		return;
252 	}
253 	if (a->sign < 0 && b->sign >= 0) {
254 		r_big_sub_inner (c, b, a);
255 		return;
256 	}
257 	if (a->sign < 0 && b->sign < 0) {
258 		r_big_add_inner (c, a, b);
259 		c->sign = -1;
260 		return;
261 	}
262 }
263 
r_big_sub(RNumBig * c,RNumBig * a,RNumBig * b)264 R_API void r_big_sub(RNumBig *c, RNumBig *a, RNumBig *b) {
265 	r_return_if_fail (a);
266 	r_return_if_fail (b);
267 	r_return_if_fail (c);
268 
269 	if (a->sign >= 0 && b->sign >= 0) {
270 		r_big_sub_inner (c, a, b);
271 		return;
272 	}
273 	if (a->sign >= 0 && b->sign < 0) {
274 		r_big_add_inner (c, a, b);
275 		c->sign = 1;
276 		return;
277 	}
278 	if (a->sign < 0 && b->sign >= 0) {
279 		r_big_add_inner (c, a, b);
280 		c->sign = -1;
281 		return;
282 	}
283 	if (a->sign < 0 && b->sign < 0) {
284 		r_big_sub_inner (c, b, a);
285 		return;
286 	}
287 }
288 
r_big_mul(RNumBig * c,RNumBig * a,RNumBig * b)289 R_API void r_big_mul(RNumBig *c, RNumBig *a, RNumBig *b) {
290 	r_return_if_fail (a);
291 	r_return_if_fail (b);
292 	r_return_if_fail (c);
293 
294 	RNumBig *row = r_big_new ();
295 	RNumBig *tmp = r_big_new ();
296 	RNumBig *res = r_big_new ();
297 	int i, j;
298 
299 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
300 		_r_big_zero_out (row);
301 
302 		for (j = 0; j < R_BIG_ARRAY_SIZE; j++) {
303 			if (i + j < R_BIG_ARRAY_SIZE) {
304 				_r_big_zero_out (tmp);
305 				R_BIG_DTYPE_TMP intermediate = ((R_BIG_DTYPE_TMP)a->array[i] * (R_BIG_DTYPE_TMP)b->array[j]);
306 				r_big_from_unsigned (tmp, intermediate);
307 				_lshift_word (tmp, i + j);
308 				r_big_add (row, row, tmp);
309 			}
310 		}
311 		r_big_add (res, row, res);
312 	}
313 
314 	res->sign = a->sign * b->sign;
315 	if (r_big_is_zero (res)) {
316 		res->sign = 1; // For -1 * 0 case
317 	}
318 	r_big_assign (c, res);
319 
320 	r_big_free (row);
321 	r_big_free (tmp);
322 	r_big_free (res);
323 }
324 
r_big_div(RNumBig * c,RNumBig * a,RNumBig * b)325 R_API void r_big_div(RNumBig *c, RNumBig *a, RNumBig *b) {
326 	r_return_if_fail (a);
327 	r_return_if_fail (b);
328 	r_return_if_fail (c);
329 	r_return_if_fail (!r_big_is_zero (b));
330 
331 	RNumBig *current = r_big_new ();
332 	RNumBig *denom = r_big_new ();
333 	;
334 	RNumBig *tmp = r_big_new ();
335 	int sign = a->sign * b->sign;
336 
337 	r_big_from_int (current, 1); // int current = 1;
338 	r_big_assign (denom, b); // denom = b
339 	denom->sign = 1;
340 	r_big_assign (tmp, denom); // tmp = denom = b
341 	_lshift_one_bit (tmp); // tmp <= 1
342 
343 	while (r_big_cmp (tmp, a) != 1) { // while (tmp <= a)
344 		if ((denom->array[R_BIG_ARRAY_SIZE - 1] >> (R_BIG_WORD_SIZE * 8 - 1)) == 1) {
345 			break; // Reach the max value
346 		}
347 		_lshift_one_bit (tmp); // tmp <= 1
348 		_lshift_one_bit (denom); // denom <= 1
349 		_lshift_one_bit (current); // current <= 1
350 	}
351 
352 	r_big_assign (tmp, a); // tmp = a
353 	tmp->sign = 1;
354 	_r_big_zero_out (c); // int answer = 0;
355 
356 	while (!r_big_is_zero (current)) // while (current != 0)
357 	{
358 		if (r_big_cmp (tmp, denom) != -1) //   if (dividend >= denom)
359 		{
360 			r_big_sub (tmp, tmp, denom); //     dividend -= denom;
361 			r_big_or (c, current, c); //     answer |= current;
362 		}
363 		_rshift_one_bit (current); //   current >>= 1;
364 		_rshift_one_bit (denom); //   denom >>= 1;
365 	} // return answer;
366 
367 	c->sign = sign;
368 	if (r_big_is_zero (c)) {
369 		c->sign = 1; // For -1 * 0 case
370 	}
371 	r_big_free (current);
372 	r_big_free (denom);
373 	r_big_free (tmp);
374 }
375 
r_big_mod(RNumBig * c,RNumBig * a,RNumBig * b)376 R_API void r_big_mod(RNumBig *c, RNumBig *a, RNumBig *b) {
377 	/*
378     Take divmod and throw away div part
379     */
380 	r_return_if_fail (a);
381 	r_return_if_fail (b);
382 	r_return_if_fail (c);
383 	r_return_if_fail (!r_big_is_zero (b));
384 
385 	RNumBig *tmp = r_big_new ();
386 
387 	r_big_divmod (tmp, c, a, b);
388 
389 	r_big_free (tmp);
390 }
391 
r_big_divmod(RNumBig * c,RNumBig * d,RNumBig * a,RNumBig * b)392 R_API void r_big_divmod(RNumBig *c, RNumBig *d, RNumBig *a, RNumBig *b) {
393 	/*
394     Puts a%b in d
395     and a/b in c
396 
397     mod(a,b) = a - ((a / b) * b)
398 
399     example:
400       mod(8, 3) = 8 - ((8 / 3) * 3) = 2
401     */
402 	r_return_if_fail (a);
403 	r_return_if_fail (b);
404 	r_return_if_fail (c);
405 	r_return_if_fail (!r_big_is_zero (b));
406 
407 	RNumBig *tmp = r_big_new ();
408 
409 	/* c = (a / b) */
410 	r_big_div (c, a, b);
411 
412 	/* tmp = (c * b) */
413 	r_big_mul (tmp, c, b);
414 
415 	/* d = a - tmp */
416 	r_big_sub (d, a, tmp);
417 
418 	r_big_free (tmp);
419 }
420 
r_big_and(RNumBig * c,RNumBig * a,RNumBig * b)421 R_API void r_big_and(RNumBig *c, RNumBig *a, RNumBig *b) {
422 	r_return_if_fail (a);
423 	r_return_if_fail (b);
424 	r_return_if_fail (c);
425 	r_return_if_fail (a->sign > 0);
426 	r_return_if_fail (b->sign > 0);
427 
428 	int i;
429 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
430 		c->array[i] = (a->array[i] & b->array[i]);
431 	}
432 }
433 
r_big_or(RNumBig * c,RNumBig * a,RNumBig * b)434 R_API void r_big_or(RNumBig *c, RNumBig *a, RNumBig *b) {
435 	r_return_if_fail (a);
436 	r_return_if_fail (b);
437 	r_return_if_fail (c);
438 	r_return_if_fail (a->sign > 0);
439 	r_return_if_fail (b->sign > 0);
440 
441 	int i;
442 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
443 		c->array[i] = (a->array[i] | b->array[i]);
444 	}
445 }
446 
r_big_xor(RNumBig * c,RNumBig * a,RNumBig * b)447 R_API void r_big_xor(RNumBig *c, RNumBig *a, RNumBig *b) {
448 	r_return_if_fail (a);
449 	r_return_if_fail (b);
450 	r_return_if_fail (c);
451 	r_return_if_fail (a->sign > 0);
452 	r_return_if_fail (b->sign > 0);
453 
454 	int i;
455 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
456 		c->array[i] = (a->array[i] ^ b->array[i]);
457 	}
458 }
459 
r_big_lshift(RNumBig * b,RNumBig * a,size_t nbits)460 R_API void r_big_lshift(RNumBig *b, RNumBig *a, size_t nbits) {
461 	r_return_if_fail (a);
462 	r_return_if_fail (b);
463 	r_return_if_fail (a->sign > 0);
464 	r_return_if_fail (b->sign > 0);
465 
466 	r_big_assign (b, a);
467 	/* Handle shift in multiples of word-size */
468 	const int nbits_pr_word = (R_BIG_WORD_SIZE * 8);
469 	int nwords = nbits / nbits_pr_word;
470 	if (nwords != 0) {
471 		_lshift_word (b, nwords);
472 		nbits -= (nwords * nbits_pr_word);
473 	}
474 
475 	if (nbits != 0) {
476 		int i;
477 		for (i = (R_BIG_ARRAY_SIZE - 1); i > 0; i--) {
478 			b->array[i] = (b->array[i] << nbits) | (b->array[i - 1] >> ((8 * R_BIG_WORD_SIZE) - nbits));
479 		}
480 		b->array[i] <<= nbits;
481 	}
482 }
483 
r_big_rshift(RNumBig * b,RNumBig * a,size_t nbits)484 R_API void r_big_rshift(RNumBig *b, RNumBig *a, size_t nbits) {
485 	r_return_if_fail (a);
486 	r_return_if_fail (b);
487 	r_return_if_fail (a->sign > 0);
488 	r_return_if_fail (b->sign > 0);
489 
490 	r_big_assign (b, a);
491 	/* Handle shift in multiples of word-size */
492 	const int nbits_pr_word = (R_BIG_WORD_SIZE * 8);
493 	int nwords = nbits / nbits_pr_word;
494 	if (nwords != 0) {
495 		_rshift_word (b, nwords);
496 		nbits -= (nwords * nbits_pr_word);
497 	}
498 
499 	if (nbits != 0) {
500 		int i;
501 		for (i = 0; i < (R_BIG_ARRAY_SIZE - 1); i++) {
502 			b->array[i] = (b->array[i] >> nbits) | (b->array[i + 1] << ((8 * R_BIG_WORD_SIZE) - nbits));
503 		}
504 		b->array[i] >>= nbits;
505 	}
506 }
507 
r_big_cmp(RNumBig * a,RNumBig * b)508 R_API int r_big_cmp(RNumBig *a, RNumBig *b) {
509 	r_return_val_if_fail (a, 0);
510 	r_return_val_if_fail (b, 0);
511 
512 	if (a->sign != b->sign)
513 		return a->sign > 0? 1: -1;
514 
515 	int i = R_BIG_ARRAY_SIZE;
516 	do {
517 		i -= 1; /* Decrement first, to start with last array element */
518 		if (a->array[i] > b->array[i]) {
519 			return 1 * a->sign;
520 		}
521 		if (a->array[i] < b->array[i]) {
522 			return -1 * a->sign;
523 		}
524 	} while (i != 0);
525 
526 	return 0;
527 }
528 
r_big_is_zero(RNumBig * a)529 R_API int r_big_is_zero(RNumBig *a) {
530 	r_return_val_if_fail (a, -1);
531 
532 	int i;
533 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
534 		if (a->array[i]) {
535 			return 0;
536 		}
537 	}
538 
539 	return 1;
540 }
541 
r_big_inc(RNumBig * a)542 R_API void r_big_inc(RNumBig *a) {
543 	r_return_if_fail (a);
544 	RNumBig *tmp = r_big_new ();
545 
546 	r_big_from_int (tmp, 1);
547 	r_big_add (a, a, tmp);
548 
549 	r_big_free (tmp);
550 }
551 
r_big_dec(RNumBig * a)552 R_API void r_big_dec(RNumBig *a) {
553 	r_return_if_fail (a);
554 	RNumBig *tmp = r_big_new ();
555 
556 	r_big_from_int (tmp, 1);
557 	r_big_sub (a, a, tmp);
558 
559 	r_big_free (tmp);
560 }
561 
r_big_powm(RNumBig * c,RNumBig * a,RNumBig * b,RNumBig * m)562 R_API void r_big_powm(RNumBig *c, RNumBig *a, RNumBig *b, RNumBig *m) {
563 	r_return_if_fail (a);
564 	r_return_if_fail (b);
565 	r_return_if_fail (c);
566 	r_return_if_fail (m);
567 
568 	RNumBig *bcopy = r_big_new ();
569 	RNumBig *acopy = r_big_new ();
570 
571 	r_big_assign (bcopy, b);
572 	r_big_assign (acopy, a);
573 	r_big_mod (acopy, acopy, m);
574 	r_big_from_int (c, 1);
575 
576 	while (!r_big_is_zero (bcopy)) {
577 		if (r_big_to_int (bcopy) % 2 == 1) {
578 			r_big_mul (c, c, acopy);
579 			r_big_mod (c, c, m);
580 		}
581 		_rshift_one_bit (bcopy);
582 		r_big_mul (acopy, acopy, acopy);
583 		r_big_mod (acopy, acopy, m);
584 	}
585 
586 	r_big_free (bcopy);
587 	r_big_free (acopy);
588 }
589 
r_big_isqrt(RNumBig * b,RNumBig * a)590 R_API void r_big_isqrt(RNumBig *b, RNumBig *a) {
591 	r_return_if_fail (a);
592 	r_return_if_fail (b);
593 
594 	RNumBig *tmp = r_big_new ();
595 	RNumBig *low = r_big_new ();
596 	RNumBig *high = r_big_new ();
597 	RNumBig *mid = r_big_new ();
598 
599 	r_big_assign (high, a);
600 	r_big_rshift (mid, high, 1);
601 	r_big_inc (mid);
602 
603 	while (r_big_cmp (high, low) > 0) {
604 		r_big_mul (tmp, mid, mid);
605 		if (r_big_cmp (tmp, a) > 0) {
606 			r_big_assign (high, mid);
607 			r_big_dec (high);
608 		} else {
609 			r_big_assign (low, mid);
610 		}
611 		r_big_sub (mid, high, low);
612 		_rshift_one_bit (mid);
613 		r_big_add (mid, mid, low);
614 		r_big_inc (mid);
615 	}
616 	r_big_assign (b, low);
617 
618 	r_big_free (tmp);
619 	r_big_free (low);
620 	r_big_free (high);
621 	r_big_free (mid);
622 }
623 
624 /* Private / Static functions. */
_rshift_word(RNumBig * a,int nwords)625 static void _rshift_word(RNumBig *a, int nwords) {
626 	/* Naive method: */
627 	r_return_if_fail (a);
628 	r_return_if_fail (nwords >= 0);
629 
630 	size_t i;
631 	if (nwords >= R_BIG_ARRAY_SIZE) {
632 		for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
633 			a->array[i] = 0;
634 		}
635 		return;
636 	}
637 
638 	for (i = 0; i < R_BIG_ARRAY_SIZE - nwords; i++) {
639 		a->array[i] = a->array[i + nwords];
640 	}
641 	for (; i < R_BIG_ARRAY_SIZE; i++) {
642 		a->array[i] = 0;
643 	}
644 }
645 
_lshift_word(RNumBig * a,int nwords)646 static void _lshift_word(RNumBig *a, int nwords) {
647 	r_return_if_fail (a);
648 	r_return_if_fail (nwords >= 0);
649 
650 	int i;
651 	/* Shift whole words */
652 	for (i = (R_BIG_ARRAY_SIZE - 1); i >= nwords; i--) {
653 		a->array[i] = a->array[i - nwords];
654 	}
655 	/* Zero pad shifted words. */
656 	for (; i >= 0; i--) {
657 		a->array[i] = 0;
658 	}
659 }
660 
_lshift_one_bit(RNumBig * a)661 static void _lshift_one_bit(RNumBig *a) {
662 	r_return_if_fail (a);
663 
664 	int i;
665 	for (i = (R_BIG_ARRAY_SIZE - 1); i > 0; i--) {
666 		a->array[i] = (a->array[i] << 1) | (a->array[i - 1] >> ((8 * R_BIG_WORD_SIZE) - 1));
667 	}
668 	a->array[0] <<= 1;
669 }
670 
_rshift_one_bit(RNumBig * a)671 static void _rshift_one_bit(RNumBig *a) {
672 	r_return_if_fail (a);
673 
674 	int i;
675 	for (i = 0; i < (R_BIG_ARRAY_SIZE - 1); i++) {
676 		a->array[i] = (a->array[i] >> 1) | (a->array[i + 1] << ((8 * R_BIG_WORD_SIZE) - 1));
677 	}
678 	a->array[R_BIG_ARRAY_SIZE - 1] >>= 1;
679 }
680 
_r_big_zero_out(RNumBig * a)681 static void _r_big_zero_out(RNumBig *a) {
682 	r_return_if_fail (a);
683 
684 	size_t i;
685 	for (i = 0; i < R_BIG_ARRAY_SIZE; i++) {
686 		a->array[i] = 0;
687 	}
688 	a->sign = 1; /* hack to avoid -0 */
689 }
690