status_t element_invert(element_t c, element_t a) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, c); if(type == ZR) { bn_t s; bn_inits(s); // compute c = (1 / a) mod n bn_gcd_ext(s, c->bn, NULL, a->bn, a->order); if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); bn_free(s); } else if(type == G1) { g1_neg(c->g1, a->g1); } else if(type == G2) { g2_neg(c->g2, a->g2); } else if(type == GT) { gt_inv(c->gt, a->gt); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
status_t element_div(element_t c, element_t a, element_t b) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, b); LEAVE_IF(a->isInitialized != TRUE || b->isInitialized != TRUE || c->isInitialized != TRUE, "uninitialized arguments."); LEAVE_IF( c->type != type, "result initialized but invalid type."); if(type == ZR) { if(bn_is_zero(b->bn)) return ELEMENT_DIV_ZERO; // c = (1 / b) mod order element_invert(c, b); if(bn_is_one(a->bn)) return ELEMENT_OK; // bn_div(c->bn, a->bn, b->bn); // bn_mod(c->bn, c->bn, c->order); // remainder of ((a * c) / order) integer_t s; bn_inits(s); // c = (a * c) / order (remainder only) bn_mul(s, a->bn, c->bn); bn_div_rem(s, c->bn, s, a->order); // if(bn_sign(c->bn) == BN_NEG) bn_add(c->bn, c->bn, a->order); bn_free(s); } else if(type == G1) { g1_sub(c->g1, a->g1, b->g1); g1_norm(c->g1, c->g1); } else if(type == G2) { g2_sub(c->g2, a->g2, b->g2); g2_norm(c->g2, c->g2); } else if(type == GT) { gt_t t; gt_inits(t); gt_inv(t, b->gt); gt_mul(c->gt, a->gt, t); gt_free(t); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
status_t element_neg(element_t c, element_t a) { GroupType type = a->type; EXIT_IF_NOT_SAME(a, c); if(type == ZR) { bn_neg(c->bn, a->bn); } else if(type == G1) { g1_neg(c->g1, a->g1); } else if(type == G2) { g2_neg(c->g2, a->g2); } else if(type == GT) { gt_inv(c->gt, a->gt); } else { return ELEMENT_INVALID_TYPES; } return ELEMENT_OK; }
int cp_bgn_dec(dig_t *out, gt_t in[4], bgn_t prv) { int i, result = STS_ERR; g1_t g; g2_t h; gt_t t[4]; bn_t n, r, s; bn_null(n); bn_null(r); bn_null(s); g1_null(g); g2_null(h); TRY { bn_new(n); bn_new(r); bn_new(s); g1_new(g); g2_new(h); for (i = 0; i < 4; i++) { gt_null(t[i]); gt_new(t[i]); } gt_exp(t[0], in[0], prv->x); gt_exp(t[0], t[0], prv->x); gt_mul(t[1], in[1], in[2]); gt_exp(t[1], t[1], prv->x); gt_inv(t[1], t[1]); gt_mul(t[3], in[3], t[1]); gt_mul(t[3], t[3], t[0]); gt_get_ord(n); g1_get_gen(g); g2_get_gen(h); bn_mul(r, prv->x, prv->y); bn_sqr(r, r); bn_mul(s, prv->x, prv->y); bn_mul(s, s, prv->z); bn_sub(r, r, s); bn_sub(r, r, s); bn_sqr(s, prv->z); bn_add(r, r, s); bn_mod(r, r, n); pc_map(t[1], g, h); gt_exp(t[1], t[1], r); gt_copy(t[2], t[1]); if (gt_is_unity(t[3]) == 1) { *out = 0; result = STS_OK; } else { for (i = 0; i < INT_MAX; i++) { if (gt_cmp(t[2], t[3]) == CMP_EQ) { *out = i + 1; result = STS_OK; break; } gt_mul(t[2], t[2], t[1]); } } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(r); bn_free(s); g1_free(g); g2_free(h); for (i = 0; i < 4; i++) { gt_free(t[i]); } } return result; }