diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | schnorr.c | 30 |
2 files changed, 30 insertions, 6 deletions
@@ -1,6 +1,12 @@ | |||
1 | 20101205 | 1 | 20101205 |
2 | - (dtucker) openbsd-compat/openssl-compat.c] remove sleep leftover from | 2 | - (dtucker) openbsd-compat/openssl-compat.c] remove sleep leftover from |
3 | debugging. Spotted by djm. | 3 | debugging. Spotted by djm. |
4 | - (dtucker) OpenBSD CVS Sync | ||
5 | - djm@cvs.openbsd.org 2010/12/03 23:49:26 | ||
6 | [schnorr.c] | ||
7 | check that g^x^q === 1 mod p; recommended by JPAKE author Feng Hao | ||
8 | (this code is still disabled, but apprently people are treating it as | ||
9 | a reference implementation) | ||
4 | 10 | ||
5 | 20101204 | 11 | 20101204 |
6 | - (djm) [openbsd-compat/bindresvport.c] Use arc4random_uniform(range) | 12 | - (djm) [openbsd-compat/bindresvport.c] Use arc4random_uniform(range) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: schnorr.c,v 1.4 2010/09/20 04:50:53 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 | * |
@@ -258,14 +258,15 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
258 | const BIGNUM *r, const BIGNUM *e) | 258 | const BIGNUM *r, const BIGNUM *e) |
259 | { | 259 | { |
260 | int success = -1; | 260 | int success = -1; |
261 | BIGNUM *h, *g_xh, *g_r, *expected; | 261 | BIGNUM *h = NULL, *g_xh = NULL, *g_r = NULL, *gx_q = NULL; |
262 | BIGNUM *expected = NULL; | ||
262 | BN_CTX *bn_ctx; | 263 | BN_CTX *bn_ctx; |
263 | 264 | ||
264 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); | 265 | SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); |
265 | 266 | ||
266 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ | 267 | /* Avoid degenerate cases: g^0 yields a spoofable signature */ |
267 | if (BN_cmp(g_x, BN_value_one()) <= 0) { | 268 | if (BN_cmp(g_x, BN_value_one()) <= 0) { |
268 | error("%s: g_x < 1", __func__); | 269 | error("%s: g_x <= 1", __func__); |
269 | return -1; | 270 | return -1; |
270 | } | 271 | } |
271 | if (BN_cmp(g_x, grp_p) >= 0) { | 272 | if (BN_cmp(g_x, grp_p) >= 0) { |
@@ -280,6 +281,7 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
280 | } | 281 | } |
281 | if ((g_xh = BN_new()) == NULL || | 282 | if ((g_xh = BN_new()) == NULL || |
282 | (g_r = BN_new()) == NULL || | 283 | (g_r = BN_new()) == NULL || |
284 | (gx_q = BN_new()) == NULL || | ||
283 | (expected = BN_new()) == NULL) { | 285 | (expected = BN_new()) == NULL) { |
284 | error("%s: BN_new", __func__); | 286 | error("%s: BN_new", __func__); |
285 | goto out; | 287 | goto out; |
@@ -288,6 +290,17 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
288 | SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); | 290 | SCHNORR_DEBUG_BN((e, "%s: e = ", __func__)); |
289 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); | 291 | SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); |
290 | 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__)); | ||
291 | /* h = H(g || g^v || g^x || id) */ | 304 | /* h = H(g || g^v || g^x || id) */ |
292 | 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, |
293 | id, idlen)) == NULL) { | 306 | id, idlen)) == NULL) { |
@@ -322,9 +335,14 @@ schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, | |||
322 | BN_CTX_free(bn_ctx); | 335 | BN_CTX_free(bn_ctx); |
323 | if (h != NULL) | 336 | if (h != NULL) |
324 | BN_clear_free(h); | 337 | BN_clear_free(h); |
325 | BN_clear_free(g_xh); | 338 | if (gx_q != NULL) |
326 | BN_clear_free(g_r); | 339 | BN_clear_free(gx_q); |
327 | 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); | ||
328 | return success; | 346 | return success; |
329 | } | 347 | } |
330 | 348 | ||