static size_t ccn_write_radix_size(cc_size n, const cc_unit *s, unsigned radix) { if (ccn_is_zero(n, s)) { return 1; } /* digs is the digit count */ cc_unit uradix[1] = { radix }; size_t k = ccn_bitlen(1, uradix) - 1; size_t l = ccn_trailing_zeros(1, uradix); if (k == l) { /* Radix is 2**k. */ return (ccn_bitlen(n, s) + k - 1) / k; } else { size_t size = 0; n = ccn_n(n, s); cc_unit t[n]; ccn_set(n, t, s); cc_unit v[1]; while (n) { ccn_div1(n, t, v, t, radix); n = ccn_n(n, t); ++size; } return size; } }
static int ccrsa_priv_init(ccrsa_priv_ctx_t privkey, size_t p_size, const uint8_t* p, size_t q_size, const uint8_t* q, size_t dp_size, const uint8_t* dp, size_t dq_size, const uint8_t* dq, size_t qinv_size, const uint8_t* qinv) { int result = -1; const cc_size np = cczp_n(ccrsa_ctx_private_zp(privkey)); cc_size nq = cczp_n(ccrsa_ctx_private_zq(privkey)); if (ccn_read_uint(np, CCZP_PRIME(ccrsa_ctx_private_zp(privkey)), p_size, p)) goto errOut; cczp_init(ccrsa_ctx_private_zp(privkey)); if (ccn_read_uint(np, ccrsa_ctx_private_dp(privkey), dp_size, dp)) goto errOut; if (ccn_read_uint(np, ccrsa_ctx_private_qinv(privkey), qinv_size, qinv)) goto errOut; if (ccn_read_uint(nq, CCZP_PRIME(ccrsa_ctx_private_zq(privkey)), q_size, q)) goto errOut; nq = ccn_n(nq, cczp_prime(ccrsa_ctx_private_zq(privkey))); CCZP_N(ccrsa_ctx_private_zq(privkey)) = nq; cczp_init(ccrsa_ctx_private_zq(privkey)); if (ccn_read_uint(nq, ccrsa_ctx_private_dq(privkey), dq_size, dq)) goto errOut; result = 0; errOut: return result; }
void ccz_sqrmod(ccz *r, const ccz *s, const ccz *t) { ccz_set_sign(r, 1); ccz_set_capacity(r, CC_MAX(2 * ccz_n(s), ccz_n(t))); ccz_zp_decl(t, zt); ccn_sqr(ccz_n(s), r->u, s->u); cczp_modn(zt, r->u, 2 * ccz_n(s), r->u); ccz_set_n(r, ccn_n(cczp_n(zt), r->u)); }
void ccz_invmod(ccz *r, const ccz *s, const ccz *t) { ccz_set_sign(r, 1); ccz_set_capacity(r, ccz_n(t)); ccz_zp_decl(t, zt); cc_unit u[cczp_n(zt)]; cczp_modn(zt, u, ccz_n(s), s->u); cczp_mod_inv_slow(zt, r->u, u); ccz_set_n(r, ccn_n(cczp_n(zt), r->u)); }
void ccz_gcd(ccz *r, const ccz *s, const ccz *t) { if (ccz_n(s) < ccz_n(t)) CC_SWAP(s,t); ccz_set_sign(r, 1); ccz_set_capacity(r, ccz_n(s)); ccn_gcdn(ccz_n(s), r->u, ccz_n(s), s->u, ccz_n(t), t->u); /* r will never be larger than t, so ccz_n(t) is ok here. */ ccz_set_n(r, ccn_n(ccz_n(t), r->u)); }
void ccz_lsl(ccz *r, const ccz *s, size_t k) { ccz_set_sign(r, ccz_sign(s)); ccz_set_capacity(r, ccz_n(s) + ccn_nof(k)); cc_size kn = k / CCN_UNIT_BITS; k &= (CCN_UNIT_BITS - 1); if (k) { r->u[kn + ccz_n(s)] = ccn_shift_left(ccz_n(s), r->u + kn, s->u, k); ccz_set_n(r, ccn_n(ccz_n(s) + kn + 1, r->u)); } else if (kn || r != s) { /* Must copy in reverse due to potential overlap. */ CC_MEMMOVE(r->u + kn, s->u, ccn_sizeof_n(ccz_n(s))); ccz_set_n(r, ccz_n(s) + kn); } ccn_zero(kn, r->u); }
static void ccn_write_radix(cc_size n, const cc_unit *s, size_t out_size, char *out, unsigned radix) { assert(radix <= strlen(ccn_radix_digit_map)); cc_unit t[n]; cc_unit v[1]={0}; ccn_set(n, t, s); /* Write from the end of the buffer backwards. */ for (char *p = out, *q = p + out_size; p < q;) { ccn_div1(n, t, v, t, radix); n = ccn_n(n, t); *--q = ccn_radix_digit_map[v[0]]; if (ccn_is_zero(n, t)) { /* Pad remaining space with zeros. */ while (p < q) { *--q = '0'; } break; } } }
void ccz_mul(ccz *r, const ccz *_s, const ccz *_t) { //s will the largest array of _s and _t int cond = ccz_n(_s) > ccz_n(_t); const ccz *s = cc_muxp(cond, _s, _t); const ccz *t = cc_muxp(cond, _t, _s); ccz_set_sign(r, ccz_sign(s) * ccz_sign(t)); #if 0 ccz_set_capacity(r, ccz_n(s) + ccz_n(t)); ccn_muln(ccz_n(s), r, s, ccz_n(t), t); #else ccz_set_capacity(r, 2 * ccz_n(s)); /* TODO Use r->u instead of stack allocation here if in place ccn_mul works. */ cc_unit u[ccz_n(s)]; cc_unit v[ccz_n(s)]; ccn_setn(ccz_n(s), u, ccz_n(t), t->u); // represent t on ccz_n(s) units ccn_set(ccz_n(s), v, s->u); // To support s->u == r->u, not in a if to avoid time leakage ccn_mul(ccz_n(s), r->u, v, u); #endif ccz_set_n(r, ccn_n(ccz_n(s) + ccz_n(t), r->u)); }