diff options
Diffstat (limited to 'schnorr.c')
-rw-r--r-- | schnorr.c | 38 |
1 files changed, 32 insertions, 6 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: schnorr.c,v 1.3 2009/03/05 07:18:19 djm Exp $ */ | 1 | /* $OpenBSD: schnorr.c,v 1.5 2010/12/03 23:49:26 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008 Damien Miller. All rights reserved. | 3 | * Copyright (c) 2008 Damien Miller. All rights reserved. |
4 | * | 4 | * |
@@ -138,6 +138,10 @@ schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
138 | error("%s: g_x < 1", __func__); | 138 | error("%s: g_x < 1", __func__); |
139 | return -1; | 139 | return -1; |
140 | } | 140 | } |
141 | if (BN_cmp(g_x, grp_p) >= 0) { | ||
142 | error("%s: g_x > g", __func__); | ||
143 | return -1; | ||
144 | } | ||
141 | 145 | ||
142 | h = g_v = r = tmp = v = NULL; | 146 | h = g_v = r = tmp = v = NULL; |
143 | if ((bn_ctx = BN_CTX_new()) == NULL) { | 147 | if ((bn_ctx = BN_CTX_new()) == NULL) { |
@@ -254,14 +258,19 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
254 | const BIGNUM *r, const BIGNUM *e) | 258 | const BIGNUM *r, const BIGNUM *e) |
255 | { | 259 | { |
256 | int success = -1; | 260 | int success = -1; |
257 | BIGNUM *h, *g_xh, *g_r, *expected; | 261 | BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL; |
262 | BIGNUM *expected = NULL; | ||
258 | BN_CTX *bn_ctx; | 263 | BN_CTX *bn_ctx; |
259 | 264 | ||
260 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); | 265 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); |
261 | 266 | ||
262 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ | 267 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ |
263 | if (BN_cmp(g_x, BN_value_one()) <= 0) { | 268 | if (BN_cmp(g_x, BN_value_one()) <= 0) { |
264 | error("%s: g_x < 1", __func__); | 269 | error("%s: g_x <= 1", __func__); |
270 | return -1; | ||
271 | } | ||
272 | if (BN_cmp(g_x, grp_p) >= 0) { | ||
273 | error("%s: g_x >= p", __func__); | ||
265 | return -1; | 274 | return -1; |
266 | } | 275 | } |
267 | 276 | ||
@@ -272,6 +281,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
272 | } | 281 | } |
273 | if ((g_xh = BN_new()) == NULL || | 282 | if ((g_xh = BN_new()) == NULL || |
274 | (g_r = BN_new()) == NULL || | 283 | (g_r = BN_new()) == NULL || |
284 | (gx_q = BN_new()) == NULL || | ||
275 | (expected = BN_new()) == NULL) { | 285 | (expected = BN_new()) == NULL) { |
276 | error("%s: BN_new", __func__); | 286 | error("%s: BN_new", __func__); |
277 | goto out; | 287 | goto out; |
@@ -280,6 +290,17 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
280 | SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); | 290 | SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); |
281 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); | 291 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); |
282 | 292 | ||
293 | /* gx_q = (g^x)^q must === 1 mod p */ | ||
294 | if (BN_mod_exp(gx_q, g_x, grp_q, grp_p, bn_ctx) == -1) { | ||
295 | error("%s: BN_mod_exp (g_x^q mod p)", __func__); | ||
296 | goto out; | ||
297 | } | ||
298 | if (BN_cmp(gx_q, BN_value_one()) != 0) { | ||
299 | error("%s: Invalid signature (g^x)^q != 1 mod p", __func__); | ||
300 | goto out; | ||
301 | } | ||
302 | |||
303 | SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); | ||
283 | /* h = H(g || g^v || g^x || id) */ | 304 | /* h = H(g || g^v || g^x || id) */ |
284 | if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, | 305 | if ((h = schnorr_hash(grp_p, grp_q, grp_g, evp_md, e, g_x, |
285 | id, idlen)) == NULL) { | 306 | id, idlen)) == NULL) { |
@@ -314,9 +335,14 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
314 | BN_CTX_free(bn_ctx); | 335 | BN_CTX_free(bn_ctx); |
315 | if (h != NULL) | 336 | if (h != NULL) |
316 | BN_clear_free(h); | 337 | BN_clear_free(h); |
317 | BN_clear_free(g_xh); | 338 | if (gx_q != NULL) |
318 | BN_clear_free(g_r); | 339 | BN_clear_free(gx_q); |
319 | BN_clear_free(expected); | 340 | if (g_xh != NULL) |
341 | BN_clear_free(g_xh); | ||
342 | if (g_r != NULL) | ||
343 | BN_clear_free(g_r); | ||
344 | if (expected != NULL) | ||
345 | BN_clear_free(expected); | ||
320 | return success; | 346 | return success; |
321 | } | 347 | } |
322 | 348 | ||