int cp_bdpe_dec(dig_t *out, uint8_t *in, int in_len, bdpe_t prv) { bn_t m, t, z; unsigned i; int size, result = STS_OK; size = bn_size_bin(prv->n); if (in_len < 0 || in_len != size) { return STS_ERR; } bn_null(m); bn_null(t); bn_null(z); TRY { bn_new(m); bn_new(t); bn_new(z); /* Compute t = (p-1)(q-1)/block. */ bn_mul(t, prv->p, prv->q); bn_sub(t, t, prv->p); bn_sub(t, t, prv->q); bn_add_dig(t, t, 1); bn_div_dig(t, t, prv->t); bn_read_bin(m, in, in_len); bn_mxp(m, m, t, prv->n); bn_mxp(t, prv->y, t, prv->n); for (i = 0; i < prv->t; i++) { bn_mxp_dig(z, t, i, prv->n); if (bn_cmp(z, m) == CMP_EQ) { *out = i; break; } } if (i == prv->t) { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(t); bn_free(z); } return result; }
int cp_bdpe_enc(uint8_t *out, int *out_len, dig_t in, bdpe_t pub) { bn_t m, u; int size, result = STS_OK; bn_null(m); bn_null(u); size = bn_size_bin(pub->n); if (in > pub->t) { return STS_ERR; } TRY { bn_new(m); bn_new(u); bn_set_dig(m, in); do { bn_rand(u, BN_POS, bn_bits(pub->n)); bn_mod(u, u, pub->n); } while (bn_is_zero(u)); bn_mxp(m, pub->y, m, pub->n); bn_mxp_dig(u, u, pub->t, pub->n); bn_mul(m, m, u); bn_mod(m, m, pub->n); if (size <= *out_len) { *out_len = size; memset(out, 0, *out_len); bn_write_bin(out, size, m); } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(u); } return result; }