int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = STS_OK; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { bn_rand_mod(k, n); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, r); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } return result; }
int cp_ecdh_key(uint8_t *key, int key_len, bn_t d, ec_t q) { ec_t p; bn_t x, h; int l, result = STS_OK; uint8_t _x[FC_BYTES]; ec_null(p); bn_null(x); bn_null(h); TRY { ec_new(p); bn_new(x); bn_new(h); ec_curve_get_cof(h); if (bn_bits(h) < BN_DIGIT) { ec_mul_dig(p, q, h->dp[0]); } else { ec_mul(p, q, h); } ec_mul(p, p, d); if (ec_is_infty(p)) { result = STS_ERR; } ec_get_x(x, p); l = bn_size_bin(x); bn_write_bin(_x, l, x); md_kdf2(key, key_len, _x, l); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ec_free(p); bn_free(x); bn_free(h); } return result; }
int cp_ecss_ver(bn_t e, bn_t s, uint8_t *msg, int len, ec_t q) { bn_t n, ev, rv; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = 0; bn_null(n); bn_null(ev); bn_null(rv); ec_null(p); TRY { bn_new(n); bn_new(ev); bn_new(rv); ec_new(p); ec_curve_get_ord(n); if (bn_sign(e) == BN_POS && bn_sign(s) == BN_POS && !bn_is_zero(s)) { if (bn_cmp(e, n) == CMP_LT && bn_cmp(s, n) == CMP_LT) { ec_mul_sim_gen(p, s, q, e); ec_get_x(rv, p); bn_mod(rv, rv, n); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, rv); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(ev, hash, len); bn_rsh(ev, ev, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(ev, hash, MD_LEN); } bn_mod(ev, ev, n); result = dv_cmp_const(ev->dp, e->dp, MIN(ev->used, e->used)); result = (result == CMP_NE ? 0 : 1); if (ev->used != e->used) { result = 0; } } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(ev); bn_free(rv); ec_free(p); } return result; }
void cp_ecss_sig(bn_t e, bn_t s, unsigned char *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; unsigned char hash[MD_LEN]; unsigned char m[len + EC_BYTES]; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { do { bn_rand(k, BN_POS, bn_bits(n)); bn_mod(k, k, n); } while (bn_is_zero(k)); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, EC_BYTES, r); md_map(hash, m, len + EC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } }