diff options
author | Adam Langley <agl@chromium.org> | 2014-06-20 23:00:00 +0400 |
---|---|---|
committer | Adam Langley <agl@chromium.org> | 2014-06-21 00:17:36 +0400 |
commit | aeb088ac096ac7ca672a1066fba291935dfa4782 (patch) | |
tree | 4735ea9a0c84fb3ef8e8c25e739fa4cffd5d3d9f /crypto/ec/simple.c | |
parent | a5dc545bbcffd9c24cebe65e9ab5ce72d4535e3a (diff) |
EC infinity fix.
Fix handling of points at infinity in ec_GFp_simple_points_make_affine.
When inverting an array of Z coordinates, the algorithm is supposed to
treat any 0 essentially like a 1 to remain in the multiplicative group;
however, for one of the cases, we incorrectly multiplied by 0 and thus
ended up with garbage.
Diffstat (limited to 'crypto/ec/simple.c')
-rw-r--r-- | crypto/ec/simple.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/crypto/ec/simple.c b/crypto/ec/simple.c index 144d056a..c62deb0d 100644 --- a/crypto/ec/simple.c +++ b/crypto/ec/simple.c @@ -1232,6 +1232,11 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, if (heap == NULL) goto err; + /* TODO(bmoeller): There is no reason to use this tree structure. + * We should instead proceed sequentially, exactly as in + * ec_GFp_nistp_points_make_affine_internal, which makes everything + * much simpler. */ + /* The array is used as a binary tree, exactly as in heapsort: * * heap[1] @@ -1300,14 +1305,19 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, for (i = 2; i < pow2 / 2 + num; i += 2) { /* i is even */ if ((heap[i + 1] != NULL) && !BN_is_zero(heap[i + 1])) { - if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx)) - goto err; - if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx)) - goto err; - if (!BN_copy(heap[i], tmp0)) - goto err; - if (!BN_copy(heap[i + 1], tmp1)) - goto err; + if (!BN_is_zero(heap[i])) { + if (!group->meth->field_mul(group, tmp0, heap[i / 2], heap[i + 1], ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, heap[i / 2], heap[i], ctx)) + goto err; + if (!BN_copy(heap[i], tmp0)) + goto err; + if (!BN_copy(heap[i + 1], tmp1)) + goto err; + } else { + if (!BN_copy(heap[i + 1], heap[i / 2])) + goto err; + } } else { if (!BN_copy(heap[i], heap[i / 2])) goto err; |