version 1.4, 2010/09/20 04:50:53 |
version 1.5, 2010/12/03 23:49:26 |
|
|
const BIGNUM *r, const BIGNUM *e) |
const BIGNUM *r, const BIGNUM *e) |
{ |
{ |
int success = -1; |
int success = -1; |
BIGNUM *h, *g_xh, *g_r, *expected; |
BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL; |
|
BIGNUM *expected = NULL; |
BN_CTX *bn_ctx; |
BN_CTX *bn_ctx; |
|
|
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); |
SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); |
|
|
/* Avoid degenerate cases: g^0 yields a spoofable signature */ |
/* Avoid degenerate cases: g^0 yields a spoofable signature */ |
if (BN_cmp(g_x, BN_value_one()) <= 0) { |
if (BN_cmp(g_x, BN_value_one()) <= 0) { |
error("%s: g_x < 1", __func__); |
error("%s: g_x <= 1", __func__); |
return -1; |
return -1; |
} |
} |
if (BN_cmp(g_x, grp_p) >= 0) { |
if (BN_cmp(g_x, grp_p) >= 0) { |
|
|
} |
} |
if ((g_xh = BN_new()) == NULL || |
if ((g_xh = BN_new()) == NULL || |
(g_r = BN_new()) == NULL || |
(g_r = BN_new()) == NULL || |
|
(gx_q = BN_new()) == NULL || |
(expected = BN_new()) == NULL) { |
(expected = BN_new()) == NULL) { |
error("%s: BN_new", __func__); |
error("%s: BN_new", __func__); |
goto out; |
goto out; |
|
|
SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); |
SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); |
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); |
SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); |
|
|
|
/* gx_q = (g^x)^q must === 1 mod p */ |
|
if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) { |
|
error("%s: BN_mod_exp (g_x^q mod p)", __func__); |
|
goto out; |
|
} |
|
if (BN_cmp(gx_q, BN_value_one()) != 0) { |
|
error("%s: Invalid signature (g^x)^q != 1 mod p", __func__); |
|
goto out; |
|
} |
|
|
|
SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); |
/* h = H(g || g^v || g^x || id) */ |
/* h = H(g || g^v || g^x || id) */ |
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, |
if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, |
id, idlen)) == NULL) { |
id, idlen)) == NULL) { |
|
|
BN_CTX_free(bn_ctx); |
BN_CTX_free(bn_ctx); |
if (h != NULL) |
if (h != NULL) |
BN_clear_free(h); |
BN_clear_free(h); |
BN_clear_free(g_xh); |
if (gx_q != NULL) |
BN_clear_free(g_r); |
BN_clear_free(gx_q); |
BN_clear_free(expected); |
if (g_xh != NULL) |
|
BN_clear_free(g_xh); |
|
if (g_r != NULL) |
|
BN_clear_free(g_r); |
|
if (expected != NULL) |
|
BN_clear_free(expected); |
return success; |
return success; |
} |
} |
|
|