static void rest_add_expr(void) { number op1, op2; unsigned int tmp, rv, i; while (token.type == TOKEN_PLUS || token.type == TOKEN_MINUS) { tmp = token.type; get_next_token(); mul_expr(); if (err == SYN_ERR) { goto out; } rv = pop_item(&sp, &op2); if (rv != OK) { err = MEM_ERR; goto out; } rv = pop_item(&sp, &op1); if (rv != OK) { err = MEM_ERR; goto out; } if (op1.frac == op2.frac) goto main_part; if (op1.frac > op2.frac) { for (i = 0; i < (op1.frac - op2.frac); i++) rv = mpl_mul_dig(&op2.value, &op2.value, 10); if (rv != MPL_OK) { err = MEM_ERR; goto out; } op2.frac = op1.frac; } else { for (i = 0; i < (op2.frac - op1.frac); i++) rv = mpl_mul_dig(&op1.value, &op1.value, 10); if (rv != MPL_OK) { err = MEM_ERR; goto out; } op1.frac = op2.frac; } main_part: if (tmp == TOKEN_PLUS) { rv = mpl_add(&op1.value, &op1.value, &op2.value); if (rv != MPL_OK) { err = MEM_ERR; goto out; } } else if (tmp == TOKEN_MINUS) { rv = mpl_sub(&op1.value, &op1.value, &op2.value); if (rv != MPL_OK) { err = MEM_ERR; goto out; } } rv = push_item(&sp, &op1); if (rv != OK) { err = MEM_ERR; goto out; } mpl_clear(&op2.value); } if (token.type != TOKEN_EOL && token.type != TOKEN_RPARENTH) { err = SYN_ERR; goto out; } out: return ; }
int mpl_gcd(mpl_int *c, const mpl_int *a, const mpl_int *b) { mpl_int x, y, u, v; int rc, k; if ((rc = mpl_initv(&u, &v, NULL)) != MPL_OK) return rc; x.dig = a->dig; x.alloc = a->alloc; x.top = a->top; x.sign = MPL_SIGN_POS; y.dig = b->dig; y.alloc = b->alloc; y.top = b->top; y.sign = MPL_SIGN_POS; rc = mpl_copy(&u, &x); if (rc != MPL_OK) goto err; rc = mpl_copy(&v, &y); if (rc != MPL_OK) goto err; k = 0; while (mpl_iseven(&v) && mpl_iseven(&u)) { rc = mpl_shr(&u, 1); if (rc != MPL_OK) goto err; rc = mpl_shr(&v, 1); if (rc != MPL_OK) goto err; ++k; } do { /* Reduce u by factor of two. */ while (mpl_iseven(&u)) { rc = mpl_shr(&u, 1); if (rc != MPL_OK) goto err; } /* Reduce v by factor of two. */ while (mpl_iseven(&v)) { rc = mpl_shr(&v, 1); if (rc != MPL_OK) goto err; } /* Reduce greatest of u or v. */ if (mpl_cmp(&u, &v) != MPL_CMP_LT) { /* u = (u - v) / 2 */ rc = mpl_sub(&u, &u, &v); if (rc != MPL_OK) goto err; rc = mpl_shr(&u, 1); if (rc != MPL_OK) goto err; } else { /* v = (v - u) / 2 */ rc = mpl_sub(&v, &v, &u); if (rc != MPL_OK) goto err; rc = mpl_shr(&v, 1); if (rc != MPL_OK) goto err; } } while (!mpl_iszero(&u) && !mpl_iszero(&v)); if (mpl_iszero(&u)) { rc = mpl_copy(c, &v); if (rc != MPL_OK) goto err; } else { rc = mpl_copy(c, &u); if (rc != MPL_OK) goto err; } if (k > 0) { rc = mpl_shl(c, k); if (rc != MPL_OK) goto err; } rc = MPL_OK; err: mpl_clearv(&u, &v, NULL); return rc; }
int mpl_primality_miller_rabin(const mpl_int *m, int r, int (*rnd)(void *buf, size_t size, void *rndctx), void *rndctx) { mpl_int m_minus_one, one; mpl_int m_mod, a, t, x, mu; int i, rc, s, n; if (rnd == NULL || r == 0 || mpl_iszero(m)) return MPL_ERR; rc = mpl_initv(&m_minus_one, &one, &a, &t, &x, &mu, NULL); if (rc != MPL_OK) return rc; /* m_mod = |m| */ m_mod.dig = m->dig; m_mod.top = m->top; m_mod.sign = MPL_SIGN_POS; m_mod.alloc = 0; /* one = 1, m_minus_one = |m| - 1 */ mpl_set_one(&one); rc = mpl_sub(&m_minus_one, &m_mod, &one); if (rc != MPL_OK) goto out; /* Prepare Barrett reduction precalculated constant. */ rc = mpl_reduce_barrett_setup(&mu, &m_mod); if (rc != MPL_OK) goto out; /* Determine power of two used to construct |m|-1 = 2^s * t. */ s = 0; n = m_minus_one.top + 1; for (i = 0; i < n; i++) { _mpl_int_t dig; int cnt; dig = m_minus_one.dig[i]; for (cnt = 0; cnt < MPL_INT_BITS; cnt++) { if (dig & 0x1) goto brk_loop; dig >>= 1; ++s; } } brk_loop: /* The following condition is a paranoidal check. */ if (i >= n) { rc = MPL_ERR; goto out; } /* m_minus_one = 2^s * t */ rc = mpl_copy(&t, &m_minus_one); if (rc != MPL_OK) goto out; if (s > 0) { rc = mpl_shr(&t, s); if (rc != MPL_OK) goto out; } /* Number of random bytes one digit less than m. */ n = (m->top * MPL_INT_BITS) / CHAR_BIT; for (i = 0; i < r; i++) { int j; //rc = mpl_random(&a, n, rnd, rndctx); rc = mpl_rand_below(&a, &m_minus_one, rnd, rndctx); if (rc != MPL_OK) goto out; rc = mpl_mod_exp(&x, &a, &t, &m_mod); if (rc != MPL_OK) goto out; if (mpl_cmp(&x, &one) == MPL_CMP_EQ) continue; if (mpl_cmp(&x, &m_minus_one) == MPL_CMP_EQ) continue; for (j = 1; j < s; j++) { rc = mpl_sqr(&x, &x); if (rc != MPL_OK) goto out; rc = mpl_reduce_barrett(&x, &x, &m_mod, &mu); if (rc != MPL_OK) goto out; if (mpl_isone(&x)) { rc = MPL_COMPOSITE; goto out; } if (mpl_cmp(&x, &m_minus_one) == MPL_CMP_EQ) break; } if (j >= s) { rc = MPL_COMPOSITE; goto out; } } rc = MPL_OK; out: mpl_clearv(&m_minus_one, &one, &a, &t, &x, &mu, NULL); return rc; }