grpc 1.10.0.pre1 → 1.10.0.pre2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +3 -3
  3. data/src/core/ext/filters/max_age/max_age_filter.cc +3 -0
  4. data/src/core/lib/surface/version.cc +1 -1
  5. data/src/ruby/lib/grpc/version.rb +1 -1
  6. data/third_party/boringssl/crypto/fipsmodule/aes/aes.c +1100 -0
  7. data/third_party/boringssl/crypto/fipsmodule/aes/key_wrap.c +138 -0
  8. data/third_party/boringssl/crypto/fipsmodule/aes/mode_wrappers.c +112 -0
  9. data/third_party/boringssl/crypto/fipsmodule/bn/add.c +375 -0
  10. data/third_party/boringssl/crypto/fipsmodule/bn/asm/x86_64-gcc.c +537 -0
  11. data/third_party/boringssl/crypto/fipsmodule/bn/bn.c +370 -0
  12. data/third_party/boringssl/crypto/fipsmodule/bn/bytes.c +269 -0
  13. data/third_party/boringssl/crypto/fipsmodule/bn/cmp.c +239 -0
  14. data/third_party/boringssl/crypto/fipsmodule/bn/ctx.c +303 -0
  15. data/third_party/boringssl/crypto/fipsmodule/bn/div.c +726 -0
  16. data/third_party/boringssl/crypto/fipsmodule/bn/exponentiation.c +1233 -0
  17. data/third_party/boringssl/crypto/fipsmodule/bn/gcd.c +627 -0
  18. data/third_party/boringssl/crypto/fipsmodule/bn/generic.c +715 -0
  19. data/third_party/boringssl/crypto/fipsmodule/bn/jacobi.c +146 -0
  20. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery.c +430 -0
  21. data/third_party/boringssl/crypto/fipsmodule/bn/montgomery_inv.c +207 -0
  22. data/third_party/boringssl/crypto/fipsmodule/bn/mul.c +869 -0
  23. data/third_party/boringssl/crypto/fipsmodule/bn/prime.c +894 -0
  24. data/third_party/boringssl/crypto/fipsmodule/bn/random.c +283 -0
  25. data/third_party/boringssl/crypto/fipsmodule/bn/rsaz_exp.c +254 -0
  26. data/third_party/boringssl/crypto/fipsmodule/bn/shift.c +307 -0
  27. data/third_party/boringssl/crypto/fipsmodule/bn/sqrt.c +502 -0
  28. data/third_party/boringssl/crypto/fipsmodule/cipher/aead.c +284 -0
  29. data/third_party/boringssl/crypto/fipsmodule/cipher/cipher.c +613 -0
  30. data/third_party/boringssl/crypto/fipsmodule/cipher/e_aes.c +1437 -0
  31. data/third_party/boringssl/crypto/fipsmodule/cipher/e_des.c +233 -0
  32. data/third_party/boringssl/crypto/fipsmodule/des/des.c +785 -0
  33. data/third_party/boringssl/crypto/fipsmodule/digest/digest.c +256 -0
  34. data/third_party/boringssl/crypto/fipsmodule/digest/digests.c +280 -0
  35. data/third_party/boringssl/crypto/fipsmodule/ec/ec.c +842 -0
  36. data/third_party/boringssl/crypto/fipsmodule/ec/ec_key.c +517 -0
  37. data/third_party/boringssl/crypto/fipsmodule/ec/ec_montgomery.c +304 -0
  38. data/third_party/boringssl/crypto/fipsmodule/ec/oct.c +404 -0
  39. data/third_party/boringssl/crypto/fipsmodule/ec/p224-64.c +1165 -0
  40. data/third_party/boringssl/crypto/fipsmodule/ec/p256-64.c +1708 -0
  41. data/third_party/boringssl/crypto/fipsmodule/ec/p256-x86_64.c +561 -0
  42. data/third_party/boringssl/crypto/fipsmodule/ec/simple.c +1113 -0
  43. data/third_party/boringssl/crypto/fipsmodule/ec/util-64.c +109 -0
  44. data/third_party/boringssl/crypto/fipsmodule/ec/wnaf.c +456 -0
  45. data/third_party/boringssl/crypto/fipsmodule/ecdsa/ecdsa.c +444 -0
  46. data/third_party/boringssl/crypto/fipsmodule/hmac/hmac.c +228 -0
  47. data/third_party/boringssl/crypto/fipsmodule/md4/md4.c +254 -0
  48. data/third_party/boringssl/crypto/fipsmodule/md5/md5.c +298 -0
  49. data/third_party/boringssl/crypto/fipsmodule/modes/cbc.c +212 -0
  50. data/third_party/boringssl/crypto/fipsmodule/modes/cfb.c +230 -0
  51. data/third_party/boringssl/crypto/fipsmodule/modes/ctr.c +219 -0
  52. data/third_party/boringssl/crypto/fipsmodule/modes/gcm.c +1074 -0
  53. data/third_party/boringssl/crypto/fipsmodule/modes/ofb.c +95 -0
  54. data/third_party/boringssl/crypto/fipsmodule/modes/polyval.c +91 -0
  55. data/third_party/boringssl/crypto/fipsmodule/rand/ctrdrbg.c +200 -0
  56. data/third_party/boringssl/crypto/fipsmodule/rand/rand.c +358 -0
  57. data/third_party/boringssl/crypto/fipsmodule/rand/urandom.c +302 -0
  58. data/third_party/boringssl/crypto/fipsmodule/rsa/blinding.c +263 -0
  59. data/third_party/boringssl/crypto/fipsmodule/rsa/padding.c +692 -0
  60. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa.c +855 -0
  61. data/third_party/boringssl/crypto/fipsmodule/rsa/rsa_impl.c +1061 -0
  62. data/third_party/boringssl/crypto/fipsmodule/sha/sha1-altivec.c +361 -0
  63. data/third_party/boringssl/crypto/fipsmodule/sha/sha1.c +375 -0
  64. data/third_party/boringssl/crypto/fipsmodule/sha/sha256.c +337 -0
  65. data/third_party/boringssl/crypto/fipsmodule/sha/sha512.c +608 -0
  66. metadata +62 -2
@@ -0,0 +1,1113 @@
1
+ /* Originally written by Bodo Moeller for the OpenSSL project.
2
+ * ====================================================================
3
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
4
+ *
5
+ * Redistribution and use in source and binary forms, with or without
6
+ * modification, are permitted provided that the following conditions
7
+ * are met:
8
+ *
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ *
12
+ * 2. Redistributions in binary form must reproduce the above copyright
13
+ * notice, this list of conditions and the following disclaimer in
14
+ * the documentation and/or other materials provided with the
15
+ * distribution.
16
+ *
17
+ * 3. All advertising materials mentioning features or use of this
18
+ * software must display the following acknowledgment:
19
+ * "This product includes software developed by the OpenSSL Project
20
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21
+ *
22
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23
+ * endorse or promote products derived from this software without
24
+ * prior written permission. For written permission, please contact
25
+ * openssl-core@openssl.org.
26
+ *
27
+ * 5. Products derived from this software may not be called "OpenSSL"
28
+ * nor may "OpenSSL" appear in their names without prior written
29
+ * permission of the OpenSSL Project.
30
+ *
31
+ * 6. Redistributions of any form whatsoever must retain the following
32
+ * acknowledgment:
33
+ * "This product includes software developed by the OpenSSL Project
34
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35
+ *
36
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
48
+ * ====================================================================
49
+ *
50
+ * This product includes cryptographic software written by Eric Young
51
+ * (eay@cryptsoft.com). This product includes software written by Tim
52
+ * Hudson (tjh@cryptsoft.com).
53
+ *
54
+ */
55
+ /* ====================================================================
56
+ * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED.
57
+ *
58
+ * Portions of the attached software ("Contribution") are developed by
59
+ * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project.
60
+ *
61
+ * The Contribution is licensed pursuant to the OpenSSL open source
62
+ * license provided above.
63
+ *
64
+ * The elliptic curve binary polynomial software is originally written by
65
+ * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems
66
+ * Laboratories. */
67
+
68
+ #include <openssl/ec.h>
69
+
70
+ #include <string.h>
71
+
72
+ #include <openssl/bn.h>
73
+ #include <openssl/err.h>
74
+ #include <openssl/mem.h>
75
+
76
+ #include "internal.h"
77
+ #include "../../internal.h"
78
+
79
+
80
+ // Most method functions in this file are designed to work with non-trivial
81
+ // representations of field elements if necessary (see ecp_mont.c): while
82
+ // standard modular addition and subtraction are used, the field_mul and
83
+ // field_sqr methods will be used for multiplication, and field_encode and
84
+ // field_decode (if defined) will be used for converting between
85
+ // representations.
86
+ //
87
+ // Functions here specifically assume that if a non-trivial representation is
88
+ // used, it is a Montgomery representation (i.e. 'encoding' means multiplying
89
+ // by some factor R).
90
+
91
+ int ec_GFp_simple_group_init(EC_GROUP *group) {
92
+ BN_init(&group->field);
93
+ BN_init(&group->a);
94
+ BN_init(&group->b);
95
+ BN_init(&group->one);
96
+ group->a_is_minus3 = 0;
97
+ return 1;
98
+ }
99
+
100
+ void ec_GFp_simple_group_finish(EC_GROUP *group) {
101
+ BN_free(&group->field);
102
+ BN_free(&group->a);
103
+ BN_free(&group->b);
104
+ BN_free(&group->one);
105
+ }
106
+
107
+ int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
108
+ if (!BN_copy(&dest->field, &src->field) ||
109
+ !BN_copy(&dest->a, &src->a) ||
110
+ !BN_copy(&dest->b, &src->b) ||
111
+ !BN_copy(&dest->one, &src->one)) {
112
+ return 0;
113
+ }
114
+
115
+ dest->a_is_minus3 = src->a_is_minus3;
116
+ return 1;
117
+ }
118
+
119
+ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
120
+ const BIGNUM *a, const BIGNUM *b,
121
+ BN_CTX *ctx) {
122
+ int ret = 0;
123
+ BN_CTX *new_ctx = NULL;
124
+ BIGNUM *tmp_a;
125
+
126
+ // p must be a prime > 3
127
+ if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
128
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
129
+ return 0;
130
+ }
131
+
132
+ if (ctx == NULL) {
133
+ ctx = new_ctx = BN_CTX_new();
134
+ if (ctx == NULL) {
135
+ return 0;
136
+ }
137
+ }
138
+
139
+ BN_CTX_start(ctx);
140
+ tmp_a = BN_CTX_get(ctx);
141
+ if (tmp_a == NULL) {
142
+ goto err;
143
+ }
144
+
145
+ // group->field
146
+ if (!BN_copy(&group->field, p)) {
147
+ goto err;
148
+ }
149
+ BN_set_negative(&group->field, 0);
150
+
151
+ // group->a
152
+ if (!BN_nnmod(tmp_a, a, p, ctx)) {
153
+ goto err;
154
+ }
155
+ if (group->meth->field_encode) {
156
+ if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) {
157
+ goto err;
158
+ }
159
+ } else if (!BN_copy(&group->a, tmp_a)) {
160
+ goto err;
161
+ }
162
+
163
+ // group->b
164
+ if (!BN_nnmod(&group->b, b, p, ctx)) {
165
+ goto err;
166
+ }
167
+ if (group->meth->field_encode &&
168
+ !group->meth->field_encode(group, &group->b, &group->b, ctx)) {
169
+ goto err;
170
+ }
171
+
172
+ // group->a_is_minus3
173
+ if (!BN_add_word(tmp_a, 3)) {
174
+ goto err;
175
+ }
176
+ group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field));
177
+
178
+ if (group->meth->field_encode != NULL) {
179
+ if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) {
180
+ goto err;
181
+ }
182
+ } else if (!BN_copy(&group->one, BN_value_one())) {
183
+ goto err;
184
+ }
185
+
186
+ ret = 1;
187
+
188
+ err:
189
+ BN_CTX_end(ctx);
190
+ BN_CTX_free(new_ctx);
191
+ return ret;
192
+ }
193
+
194
+ int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
195
+ BIGNUM *b, BN_CTX *ctx) {
196
+ int ret = 0;
197
+ BN_CTX *new_ctx = NULL;
198
+
199
+ if (p != NULL && !BN_copy(p, &group->field)) {
200
+ return 0;
201
+ }
202
+
203
+ if (a != NULL || b != NULL) {
204
+ if (group->meth->field_decode) {
205
+ if (ctx == NULL) {
206
+ ctx = new_ctx = BN_CTX_new();
207
+ if (ctx == NULL) {
208
+ return 0;
209
+ }
210
+ }
211
+ if (a != NULL && !group->meth->field_decode(group, a, &group->a, ctx)) {
212
+ goto err;
213
+ }
214
+ if (b != NULL && !group->meth->field_decode(group, b, &group->b, ctx)) {
215
+ goto err;
216
+ }
217
+ } else {
218
+ if (a != NULL && !BN_copy(a, &group->a)) {
219
+ goto err;
220
+ }
221
+ if (b != NULL && !BN_copy(b, &group->b)) {
222
+ goto err;
223
+ }
224
+ }
225
+ }
226
+
227
+ ret = 1;
228
+
229
+ err:
230
+ BN_CTX_free(new_ctx);
231
+ return ret;
232
+ }
233
+
234
+ unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) {
235
+ return BN_num_bits(&group->field);
236
+ }
237
+
238
+ int ec_GFp_simple_point_init(EC_POINT *point) {
239
+ BN_init(&point->X);
240
+ BN_init(&point->Y);
241
+ BN_init(&point->Z);
242
+
243
+ return 1;
244
+ }
245
+
246
+ void ec_GFp_simple_point_finish(EC_POINT *point) {
247
+ BN_free(&point->X);
248
+ BN_free(&point->Y);
249
+ BN_free(&point->Z);
250
+ }
251
+
252
+ void ec_GFp_simple_point_clear_finish(EC_POINT *point) {
253
+ BN_clear_free(&point->X);
254
+ BN_clear_free(&point->Y);
255
+ BN_clear_free(&point->Z);
256
+ }
257
+
258
+ int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) {
259
+ if (!BN_copy(&dest->X, &src->X) ||
260
+ !BN_copy(&dest->Y, &src->Y) ||
261
+ !BN_copy(&dest->Z, &src->Z)) {
262
+ return 0;
263
+ }
264
+
265
+ return 1;
266
+ }
267
+
268
+ int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
269
+ EC_POINT *point) {
270
+ BN_zero(&point->Z);
271
+ return 1;
272
+ }
273
+
274
+ static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out,
275
+ const BIGNUM *in, BN_CTX *ctx) {
276
+ if (in == NULL) {
277
+ return 1;
278
+ }
279
+ if (BN_is_negative(in) ||
280
+ BN_cmp(in, &group->field) >= 0) {
281
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
282
+ return 0;
283
+ }
284
+ if (group->meth->field_encode) {
285
+ return group->meth->field_encode(group, out, in, ctx);
286
+ }
287
+ return BN_copy(out, in) != NULL;
288
+ }
289
+
290
+ int ec_GFp_simple_set_Jprojective_coordinates_GFp(
291
+ const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, const BIGNUM *y,
292
+ const BIGNUM *z, BN_CTX *ctx) {
293
+ BN_CTX *new_ctx = NULL;
294
+ int ret = 0;
295
+
296
+ if (ctx == NULL) {
297
+ ctx = new_ctx = BN_CTX_new();
298
+ if (ctx == NULL) {
299
+ return 0;
300
+ }
301
+ }
302
+
303
+ if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) ||
304
+ !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) ||
305
+ !set_Jprojective_coordinate_GFp(group, &point->Z, z, ctx)) {
306
+ goto err;
307
+ }
308
+
309
+ ret = 1;
310
+
311
+ err:
312
+ BN_CTX_free(new_ctx);
313
+ return ret;
314
+ }
315
+
316
+ int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
317
+ const EC_POINT *point,
318
+ BIGNUM *x, BIGNUM *y,
319
+ BIGNUM *z, BN_CTX *ctx) {
320
+ BN_CTX *new_ctx = NULL;
321
+ int ret = 0;
322
+
323
+ if (group->meth->field_decode != 0) {
324
+ if (ctx == NULL) {
325
+ ctx = new_ctx = BN_CTX_new();
326
+ if (ctx == NULL) {
327
+ return 0;
328
+ }
329
+ }
330
+
331
+ if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
332
+ goto err;
333
+ }
334
+ if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
335
+ goto err;
336
+ }
337
+ if (z != NULL && !group->meth->field_decode(group, z, &point->Z, ctx)) {
338
+ goto err;
339
+ }
340
+ } else {
341
+ if (x != NULL && !BN_copy(x, &point->X)) {
342
+ goto err;
343
+ }
344
+ if (y != NULL && !BN_copy(y, &point->Y)) {
345
+ goto err;
346
+ }
347
+ if (z != NULL && !BN_copy(z, &point->Z)) {
348
+ goto err;
349
+ }
350
+ }
351
+
352
+ ret = 1;
353
+
354
+ err:
355
+ BN_CTX_free(new_ctx);
356
+ return ret;
357
+ }
358
+
359
+ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
360
+ EC_POINT *point, const BIGNUM *x,
361
+ const BIGNUM *y, BN_CTX *ctx) {
362
+ if (x == NULL || y == NULL) {
363
+ // unlike for projective coordinates, we do not tolerate this
364
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
365
+ return 0;
366
+ }
367
+
368
+ return ec_point_set_Jprojective_coordinates_GFp(group, point, x, y,
369
+ BN_value_one(), ctx);
370
+ }
371
+
372
+ int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
373
+ const EC_POINT *b, BN_CTX *ctx) {
374
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
375
+ BN_CTX *);
376
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
377
+ const BIGNUM *p;
378
+ BN_CTX *new_ctx = NULL;
379
+ BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
380
+ int ret = 0;
381
+
382
+ if (a == b) {
383
+ return EC_POINT_dbl(group, r, a, ctx);
384
+ }
385
+ if (EC_POINT_is_at_infinity(group, a)) {
386
+ return EC_POINT_copy(r, b);
387
+ }
388
+ if (EC_POINT_is_at_infinity(group, b)) {
389
+ return EC_POINT_copy(r, a);
390
+ }
391
+
392
+ field_mul = group->meth->field_mul;
393
+ field_sqr = group->meth->field_sqr;
394
+ p = &group->field;
395
+
396
+ if (ctx == NULL) {
397
+ ctx = new_ctx = BN_CTX_new();
398
+ if (ctx == NULL) {
399
+ return 0;
400
+ }
401
+ }
402
+
403
+ BN_CTX_start(ctx);
404
+ n0 = BN_CTX_get(ctx);
405
+ n1 = BN_CTX_get(ctx);
406
+ n2 = BN_CTX_get(ctx);
407
+ n3 = BN_CTX_get(ctx);
408
+ n4 = BN_CTX_get(ctx);
409
+ n5 = BN_CTX_get(ctx);
410
+ n6 = BN_CTX_get(ctx);
411
+ if (n6 == NULL) {
412
+ goto end;
413
+ }
414
+
415
+ // Note that in this function we must not read components of 'a' or 'b'
416
+ // once we have written the corresponding components of 'r'.
417
+ // ('r' might be one of 'a' or 'b'.)
418
+
419
+ // n1, n2
420
+ int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
421
+
422
+ if (b_Z_is_one) {
423
+ if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) {
424
+ goto end;
425
+ }
426
+ // n1 = X_a
427
+ // n2 = Y_a
428
+ } else {
429
+ if (!field_sqr(group, n0, &b->Z, ctx) ||
430
+ !field_mul(group, n1, &a->X, n0, ctx)) {
431
+ goto end;
432
+ }
433
+ // n1 = X_a * Z_b^2
434
+
435
+ if (!field_mul(group, n0, n0, &b->Z, ctx) ||
436
+ !field_mul(group, n2, &a->Y, n0, ctx)) {
437
+ goto end;
438
+ }
439
+ // n2 = Y_a * Z_b^3
440
+ }
441
+
442
+ // n3, n4
443
+ int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
444
+ if (a_Z_is_one) {
445
+ if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) {
446
+ goto end;
447
+ }
448
+ // n3 = X_b
449
+ // n4 = Y_b
450
+ } else {
451
+ if (!field_sqr(group, n0, &a->Z, ctx) ||
452
+ !field_mul(group, n3, &b->X, n0, ctx)) {
453
+ goto end;
454
+ }
455
+ // n3 = X_b * Z_a^2
456
+
457
+ if (!field_mul(group, n0, n0, &a->Z, ctx) ||
458
+ !field_mul(group, n4, &b->Y, n0, ctx)) {
459
+ goto end;
460
+ }
461
+ // n4 = Y_b * Z_a^3
462
+ }
463
+
464
+ // n5, n6
465
+ if (!BN_mod_sub_quick(n5, n1, n3, p) ||
466
+ !BN_mod_sub_quick(n6, n2, n4, p)) {
467
+ goto end;
468
+ }
469
+ // n5 = n1 - n3
470
+ // n6 = n2 - n4
471
+
472
+ if (BN_is_zero(n5)) {
473
+ if (BN_is_zero(n6)) {
474
+ // a is the same point as b
475
+ BN_CTX_end(ctx);
476
+ ret = EC_POINT_dbl(group, r, a, ctx);
477
+ ctx = NULL;
478
+ goto end;
479
+ } else {
480
+ // a is the inverse of b
481
+ BN_zero(&r->Z);
482
+ ret = 1;
483
+ goto end;
484
+ }
485
+ }
486
+
487
+ // 'n7', 'n8'
488
+ if (!BN_mod_add_quick(n1, n1, n3, p) ||
489
+ !BN_mod_add_quick(n2, n2, n4, p)) {
490
+ goto end;
491
+ }
492
+ // 'n7' = n1 + n3
493
+ // 'n8' = n2 + n4
494
+
495
+ // Z_r
496
+ if (a_Z_is_one && b_Z_is_one) {
497
+ if (!BN_copy(&r->Z, n5)) {
498
+ goto end;
499
+ }
500
+ } else {
501
+ if (a_Z_is_one) {
502
+ if (!BN_copy(n0, &b->Z)) {
503
+ goto end;
504
+ }
505
+ } else if (b_Z_is_one) {
506
+ if (!BN_copy(n0, &a->Z)) {
507
+ goto end;
508
+ }
509
+ } else if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) {
510
+ goto end;
511
+ }
512
+ if (!field_mul(group, &r->Z, n0, n5, ctx)) {
513
+ goto end;
514
+ }
515
+ }
516
+
517
+ // Z_r = Z_a * Z_b * n5
518
+
519
+ // X_r
520
+ if (!field_sqr(group, n0, n6, ctx) ||
521
+ !field_sqr(group, n4, n5, ctx) ||
522
+ !field_mul(group, n3, n1, n4, ctx) ||
523
+ !BN_mod_sub_quick(&r->X, n0, n3, p)) {
524
+ goto end;
525
+ }
526
+ // X_r = n6^2 - n5^2 * 'n7'
527
+
528
+ // 'n9'
529
+ if (!BN_mod_lshift1_quick(n0, &r->X, p) ||
530
+ !BN_mod_sub_quick(n0, n3, n0, p)) {
531
+ goto end;
532
+ }
533
+ // n9 = n5^2 * 'n7' - 2 * X_r
534
+
535
+ // Y_r
536
+ if (!field_mul(group, n0, n0, n6, ctx) ||
537
+ !field_mul(group, n5, n4, n5, ctx)) {
538
+ goto end; // now n5 is n5^3
539
+ }
540
+ if (!field_mul(group, n1, n2, n5, ctx) ||
541
+ !BN_mod_sub_quick(n0, n0, n1, p)) {
542
+ goto end;
543
+ }
544
+ if (BN_is_odd(n0) && !BN_add(n0, n0, p)) {
545
+ goto end;
546
+ }
547
+ // now 0 <= n0 < 2*p, and n0 is even
548
+ if (!BN_rshift1(&r->Y, n0)) {
549
+ goto end;
550
+ }
551
+ // Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2
552
+
553
+ ret = 1;
554
+
555
+ end:
556
+ if (ctx) {
557
+ // otherwise we already called BN_CTX_end
558
+ BN_CTX_end(ctx);
559
+ }
560
+ BN_CTX_free(new_ctx);
561
+ return ret;
562
+ }
563
+
564
+ int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
565
+ BN_CTX *ctx) {
566
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
567
+ BN_CTX *);
568
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
569
+ const BIGNUM *p;
570
+ BN_CTX *new_ctx = NULL;
571
+ BIGNUM *n0, *n1, *n2, *n3;
572
+ int ret = 0;
573
+
574
+ if (EC_POINT_is_at_infinity(group, a)) {
575
+ BN_zero(&r->Z);
576
+ return 1;
577
+ }
578
+
579
+ field_mul = group->meth->field_mul;
580
+ field_sqr = group->meth->field_sqr;
581
+ p = &group->field;
582
+
583
+ if (ctx == NULL) {
584
+ ctx = new_ctx = BN_CTX_new();
585
+ if (ctx == NULL) {
586
+ return 0;
587
+ }
588
+ }
589
+
590
+ BN_CTX_start(ctx);
591
+ n0 = BN_CTX_get(ctx);
592
+ n1 = BN_CTX_get(ctx);
593
+ n2 = BN_CTX_get(ctx);
594
+ n3 = BN_CTX_get(ctx);
595
+ if (n3 == NULL) {
596
+ goto err;
597
+ }
598
+
599
+ // Note that in this function we must not read components of 'a'
600
+ // once we have written the corresponding components of 'r'.
601
+ // ('r' might the same as 'a'.)
602
+
603
+ // n1
604
+ if (BN_cmp(&a->Z, &group->one) == 0) {
605
+ if (!field_sqr(group, n0, &a->X, ctx) ||
606
+ !BN_mod_lshift1_quick(n1, n0, p) ||
607
+ !BN_mod_add_quick(n0, n0, n1, p) ||
608
+ !BN_mod_add_quick(n1, n0, &group->a, p)) {
609
+ goto err;
610
+ }
611
+ // n1 = 3 * X_a^2 + a_curve
612
+ } else if (group->a_is_minus3) {
613
+ if (!field_sqr(group, n1, &a->Z, ctx) ||
614
+ !BN_mod_add_quick(n0, &a->X, n1, p) ||
615
+ !BN_mod_sub_quick(n2, &a->X, n1, p) ||
616
+ !field_mul(group, n1, n0, n2, ctx) ||
617
+ !BN_mod_lshift1_quick(n0, n1, p) ||
618
+ !BN_mod_add_quick(n1, n0, n1, p)) {
619
+ goto err;
620
+ }
621
+ // n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
622
+ // = 3 * X_a^2 - 3 * Z_a^4
623
+ } else {
624
+ if (!field_sqr(group, n0, &a->X, ctx) ||
625
+ !BN_mod_lshift1_quick(n1, n0, p) ||
626
+ !BN_mod_add_quick(n0, n0, n1, p) ||
627
+ !field_sqr(group, n1, &a->Z, ctx) ||
628
+ !field_sqr(group, n1, n1, ctx) ||
629
+ !field_mul(group, n1, n1, &group->a, ctx) ||
630
+ !BN_mod_add_quick(n1, n1, n0, p)) {
631
+ goto err;
632
+ }
633
+ // n1 = 3 * X_a^2 + a_curve * Z_a^4
634
+ }
635
+
636
+ // Z_r
637
+ if (BN_cmp(&a->Z, &group->one) == 0) {
638
+ if (!BN_copy(n0, &a->Y)) {
639
+ goto err;
640
+ }
641
+ } else if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) {
642
+ goto err;
643
+ }
644
+ if (!BN_mod_lshift1_quick(&r->Z, n0, p)) {
645
+ goto err;
646
+ }
647
+ // Z_r = 2 * Y_a * Z_a
648
+
649
+ // n2
650
+ if (!field_sqr(group, n3, &a->Y, ctx) ||
651
+ !field_mul(group, n2, &a->X, n3, ctx) ||
652
+ !BN_mod_lshift_quick(n2, n2, 2, p)) {
653
+ goto err;
654
+ }
655
+ // n2 = 4 * X_a * Y_a^2
656
+
657
+ // X_r
658
+ if (!BN_mod_lshift1_quick(n0, n2, p) ||
659
+ !field_sqr(group, &r->X, n1, ctx) ||
660
+ !BN_mod_sub_quick(&r->X, &r->X, n0, p)) {
661
+ goto err;
662
+ }
663
+ // X_r = n1^2 - 2 * n2
664
+
665
+ // n3
666
+ if (!field_sqr(group, n0, n3, ctx) ||
667
+ !BN_mod_lshift_quick(n3, n0, 3, p)) {
668
+ goto err;
669
+ }
670
+ // n3 = 8 * Y_a^4
671
+
672
+ // Y_r
673
+ if (!BN_mod_sub_quick(n0, n2, &r->X, p) ||
674
+ !field_mul(group, n0, n1, n0, ctx) ||
675
+ !BN_mod_sub_quick(&r->Y, n0, n3, p)) {
676
+ goto err;
677
+ }
678
+ // Y_r = n1 * (n2 - X_r) - n3
679
+
680
+ ret = 1;
681
+
682
+ err:
683
+ BN_CTX_end(ctx);
684
+ BN_CTX_free(new_ctx);
685
+ return ret;
686
+ }
687
+
688
+ int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
689
+ if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) {
690
+ // point is its own inverse
691
+ return 1;
692
+ }
693
+
694
+ return BN_usub(&point->Y, &group->field, &point->Y);
695
+ }
696
+
697
+ int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
698
+ return BN_is_zero(&point->Z);
699
+ }
700
+
701
+ int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
702
+ BN_CTX *ctx) {
703
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
704
+ BN_CTX *);
705
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
706
+ const BIGNUM *p;
707
+ BN_CTX *new_ctx = NULL;
708
+ BIGNUM *rh, *tmp, *Z4, *Z6;
709
+ int ret = 0;
710
+
711
+ if (EC_POINT_is_at_infinity(group, point)) {
712
+ return 1;
713
+ }
714
+
715
+ field_mul = group->meth->field_mul;
716
+ field_sqr = group->meth->field_sqr;
717
+ p = &group->field;
718
+
719
+ if (ctx == NULL) {
720
+ ctx = new_ctx = BN_CTX_new();
721
+ if (ctx == NULL) {
722
+ return 0;
723
+ }
724
+ }
725
+
726
+ BN_CTX_start(ctx);
727
+ rh = BN_CTX_get(ctx);
728
+ tmp = BN_CTX_get(ctx);
729
+ Z4 = BN_CTX_get(ctx);
730
+ Z6 = BN_CTX_get(ctx);
731
+ if (Z6 == NULL) {
732
+ goto err;
733
+ }
734
+
735
+ // We have a curve defined by a Weierstrass equation
736
+ // y^2 = x^3 + a*x + b.
737
+ // The point to consider is given in Jacobian projective coordinates
738
+ // where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
739
+ // Substituting this and multiplying by Z^6 transforms the above equation
740
+ // into
741
+ // Y^2 = X^3 + a*X*Z^4 + b*Z^6.
742
+ // To test this, we add up the right-hand side in 'rh'.
743
+
744
+ // rh := X^2
745
+ if (!field_sqr(group, rh, &point->X, ctx)) {
746
+ goto err;
747
+ }
748
+
749
+ if (BN_cmp(&point->Z, &group->one) != 0) {
750
+ if (!field_sqr(group, tmp, &point->Z, ctx) ||
751
+ !field_sqr(group, Z4, tmp, ctx) ||
752
+ !field_mul(group, Z6, Z4, tmp, ctx)) {
753
+ goto err;
754
+ }
755
+
756
+ // rh := (rh + a*Z^4)*X
757
+ if (group->a_is_minus3) {
758
+ if (!BN_mod_lshift1_quick(tmp, Z4, p) ||
759
+ !BN_mod_add_quick(tmp, tmp, Z4, p) ||
760
+ !BN_mod_sub_quick(rh, rh, tmp, p) ||
761
+ !field_mul(group, rh, rh, &point->X, ctx)) {
762
+ goto err;
763
+ }
764
+ } else {
765
+ if (!field_mul(group, tmp, Z4, &group->a, ctx) ||
766
+ !BN_mod_add_quick(rh, rh, tmp, p) ||
767
+ !field_mul(group, rh, rh, &point->X, ctx)) {
768
+ goto err;
769
+ }
770
+ }
771
+
772
+ // rh := rh + b*Z^6
773
+ if (!field_mul(group, tmp, &group->b, Z6, ctx) ||
774
+ !BN_mod_add_quick(rh, rh, tmp, p)) {
775
+ goto err;
776
+ }
777
+ } else {
778
+ // rh := (rh + a)*X
779
+ if (!BN_mod_add_quick(rh, rh, &group->a, p) ||
780
+ !field_mul(group, rh, rh, &point->X, ctx)) {
781
+ goto err;
782
+ }
783
+ // rh := rh + b
784
+ if (!BN_mod_add_quick(rh, rh, &group->b, p)) {
785
+ goto err;
786
+ }
787
+ }
788
+
789
+ // 'lh' := Y^2
790
+ if (!field_sqr(group, tmp, &point->Y, ctx)) {
791
+ goto err;
792
+ }
793
+
794
+ ret = (0 == BN_ucmp(tmp, rh));
795
+
796
+ err:
797
+ BN_CTX_end(ctx);
798
+ BN_CTX_free(new_ctx);
799
+ return ret;
800
+ }
801
+
802
+ int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
803
+ const EC_POINT *b, BN_CTX *ctx) {
804
+ // return values:
805
+ // -1 error
806
+ // 0 equal (in affine coordinates)
807
+ // 1 not equal
808
+
809
+ int (*field_mul)(const EC_GROUP *, BIGNUM *, const BIGNUM *, const BIGNUM *,
810
+ BN_CTX *);
811
+ int (*field_sqr)(const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
812
+ BN_CTX *new_ctx = NULL;
813
+ BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
814
+ const BIGNUM *tmp1_, *tmp2_;
815
+ int ret = -1;
816
+
817
+ if (EC_POINT_is_at_infinity(group, a)) {
818
+ return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
819
+ }
820
+
821
+ if (EC_POINT_is_at_infinity(group, b)) {
822
+ return 1;
823
+ }
824
+
825
+ int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0;
826
+ int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0;
827
+
828
+ if (a_Z_is_one && b_Z_is_one) {
829
+ return ((BN_cmp(&a->X, &b->X) == 0) && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1;
830
+ }
831
+
832
+ field_mul = group->meth->field_mul;
833
+ field_sqr = group->meth->field_sqr;
834
+
835
+ if (ctx == NULL) {
836
+ ctx = new_ctx = BN_CTX_new();
837
+ if (ctx == NULL) {
838
+ return -1;
839
+ }
840
+ }
841
+
842
+ BN_CTX_start(ctx);
843
+ tmp1 = BN_CTX_get(ctx);
844
+ tmp2 = BN_CTX_get(ctx);
845
+ Za23 = BN_CTX_get(ctx);
846
+ Zb23 = BN_CTX_get(ctx);
847
+ if (Zb23 == NULL) {
848
+ goto end;
849
+ }
850
+
851
+ // We have to decide whether
852
+ // (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
853
+ // or equivalently, whether
854
+ // (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
855
+
856
+ if (!b_Z_is_one) {
857
+ if (!field_sqr(group, Zb23, &b->Z, ctx) ||
858
+ !field_mul(group, tmp1, &a->X, Zb23, ctx)) {
859
+ goto end;
860
+ }
861
+ tmp1_ = tmp1;
862
+ } else {
863
+ tmp1_ = &a->X;
864
+ }
865
+ if (!a_Z_is_one) {
866
+ if (!field_sqr(group, Za23, &a->Z, ctx) ||
867
+ !field_mul(group, tmp2, &b->X, Za23, ctx)) {
868
+ goto end;
869
+ }
870
+ tmp2_ = tmp2;
871
+ } else {
872
+ tmp2_ = &b->X;
873
+ }
874
+
875
+ // compare X_a*Z_b^2 with X_b*Z_a^2
876
+ if (BN_cmp(tmp1_, tmp2_) != 0) {
877
+ ret = 1; // points differ
878
+ goto end;
879
+ }
880
+
881
+
882
+ if (!b_Z_is_one) {
883
+ if (!field_mul(group, Zb23, Zb23, &b->Z, ctx) ||
884
+ !field_mul(group, tmp1, &a->Y, Zb23, ctx)) {
885
+ goto end;
886
+ }
887
+ // tmp1_ = tmp1
888
+ } else {
889
+ tmp1_ = &a->Y;
890
+ }
891
+ if (!a_Z_is_one) {
892
+ if (!field_mul(group, Za23, Za23, &a->Z, ctx) ||
893
+ !field_mul(group, tmp2, &b->Y, Za23, ctx)) {
894
+ goto end;
895
+ }
896
+ // tmp2_ = tmp2
897
+ } else {
898
+ tmp2_ = &b->Y;
899
+ }
900
+
901
+ // compare Y_a*Z_b^3 with Y_b*Z_a^3
902
+ if (BN_cmp(tmp1_, tmp2_) != 0) {
903
+ ret = 1; // points differ
904
+ goto end;
905
+ }
906
+
907
+ // points are equal
908
+ ret = 0;
909
+
910
+ end:
911
+ BN_CTX_end(ctx);
912
+ BN_CTX_free(new_ctx);
913
+ return ret;
914
+ }
915
+
916
+ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
917
+ BN_CTX *ctx) {
918
+ BN_CTX *new_ctx = NULL;
919
+ BIGNUM *x, *y;
920
+ int ret = 0;
921
+
922
+ if (BN_cmp(&point->Z, &group->one) == 0 ||
923
+ EC_POINT_is_at_infinity(group, point)) {
924
+ return 1;
925
+ }
926
+
927
+ if (ctx == NULL) {
928
+ ctx = new_ctx = BN_CTX_new();
929
+ if (ctx == NULL) {
930
+ return 0;
931
+ }
932
+ }
933
+
934
+ BN_CTX_start(ctx);
935
+ x = BN_CTX_get(ctx);
936
+ y = BN_CTX_get(ctx);
937
+ if (y == NULL) {
938
+ goto err;
939
+ }
940
+
941
+ if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx) ||
942
+ !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) {
943
+ goto err;
944
+ }
945
+ if (BN_cmp(&point->Z, &group->one) != 0) {
946
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
947
+ goto err;
948
+ }
949
+
950
+ ret = 1;
951
+
952
+ err:
953
+ BN_CTX_end(ctx);
954
+ BN_CTX_free(new_ctx);
955
+ return ret;
956
+ }
957
+
958
+ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
959
+ EC_POINT *points[], BN_CTX *ctx) {
960
+ BN_CTX *new_ctx = NULL;
961
+ BIGNUM *tmp, *tmp_Z;
962
+ BIGNUM **prod_Z = NULL;
963
+ int ret = 0;
964
+
965
+ if (num == 0) {
966
+ return 1;
967
+ }
968
+
969
+ if (ctx == NULL) {
970
+ ctx = new_ctx = BN_CTX_new();
971
+ if (ctx == NULL) {
972
+ return 0;
973
+ }
974
+ }
975
+
976
+ BN_CTX_start(ctx);
977
+ tmp = BN_CTX_get(ctx);
978
+ tmp_Z = BN_CTX_get(ctx);
979
+ if (tmp == NULL || tmp_Z == NULL) {
980
+ goto err;
981
+ }
982
+
983
+ prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
984
+ if (prod_Z == NULL) {
985
+ goto err;
986
+ }
987
+ OPENSSL_memset(prod_Z, 0, num * sizeof(prod_Z[0]));
988
+ for (size_t i = 0; i < num; i++) {
989
+ prod_Z[i] = BN_new();
990
+ if (prod_Z[i] == NULL) {
991
+ goto err;
992
+ }
993
+ }
994
+
995
+ // Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
996
+ // skipping any zero-valued inputs (pretend that they're 1).
997
+
998
+ if (!BN_is_zero(&points[0]->Z)) {
999
+ if (!BN_copy(prod_Z[0], &points[0]->Z)) {
1000
+ goto err;
1001
+ }
1002
+ } else {
1003
+ if (BN_copy(prod_Z[0], &group->one) == NULL) {
1004
+ goto err;
1005
+ }
1006
+ }
1007
+
1008
+ for (size_t i = 1; i < num; i++) {
1009
+ if (!BN_is_zero(&points[i]->Z)) {
1010
+ if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1],
1011
+ &points[i]->Z, ctx)) {
1012
+ goto err;
1013
+ }
1014
+ } else {
1015
+ if (!BN_copy(prod_Z[i], prod_Z[i - 1])) {
1016
+ goto err;
1017
+ }
1018
+ }
1019
+ }
1020
+
1021
+ // Now use a single explicit inversion to replace every non-zero points[i]->Z
1022
+ // by its inverse. We use |BN_mod_inverse_odd| instead of doing a constant-
1023
+ // time inversion using Fermat's Little Theorem because this function is
1024
+ // usually only used for converting multiples of a public key point to
1025
+ // affine, and a public key point isn't secret. If we were to use Fermat's
1026
+ // Little Theorem then the cost of the inversion would usually be so high
1027
+ // that converting the multiples to affine would be counterproductive.
1028
+ int no_inverse;
1029
+ if (!BN_mod_inverse_odd(tmp, &no_inverse, prod_Z[num - 1], &group->field,
1030
+ ctx)) {
1031
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
1032
+ goto err;
1033
+ }
1034
+
1035
+ if (group->meth->field_encode != NULL) {
1036
+ // In the Montgomery case, we just turned R*H (representing H)
1037
+ // into 1/(R*H), but we need R*(1/H) (representing 1/H);
1038
+ // i.e. we need to multiply by the Montgomery factor twice.
1039
+ if (!group->meth->field_encode(group, tmp, tmp, ctx) ||
1040
+ !group->meth->field_encode(group, tmp, tmp, ctx)) {
1041
+ goto err;
1042
+ }
1043
+ }
1044
+
1045
+ for (size_t i = num - 1; i > 0; --i) {
1046
+ // Loop invariant: tmp is the product of the inverses of
1047
+ // points[0]->Z .. points[i]->Z (zero-valued inputs skipped).
1048
+ if (BN_is_zero(&points[i]->Z)) {
1049
+ continue;
1050
+ }
1051
+
1052
+ // Set tmp_Z to the inverse of points[i]->Z (as product
1053
+ // of Z inverses 0 .. i, Z values 0 .. i - 1).
1054
+ if (!group->meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx) ||
1055
+ // Update tmp to satisfy the loop invariant for i - 1.
1056
+ !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) ||
1057
+ // Replace points[i]->Z by its inverse.
1058
+ !BN_copy(&points[i]->Z, tmp_Z)) {
1059
+ goto err;
1060
+ }
1061
+ }
1062
+
1063
+ // Replace points[0]->Z by its inverse.
1064
+ if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) {
1065
+ goto err;
1066
+ }
1067
+
1068
+ // Finally, fix up the X and Y coordinates for all points.
1069
+ for (size_t i = 0; i < num; i++) {
1070
+ EC_POINT *p = points[i];
1071
+
1072
+ if (!BN_is_zero(&p->Z)) {
1073
+ // turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1).
1074
+ if (!group->meth->field_sqr(group, tmp, &p->Z, ctx) ||
1075
+ !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) ||
1076
+ !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) ||
1077
+ !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) {
1078
+ goto err;
1079
+ }
1080
+
1081
+ if (BN_copy(&p->Z, &group->one) == NULL) {
1082
+ goto err;
1083
+ }
1084
+ }
1085
+ }
1086
+
1087
+ ret = 1;
1088
+
1089
+ err:
1090
+ BN_CTX_end(ctx);
1091
+ BN_CTX_free(new_ctx);
1092
+ if (prod_Z != NULL) {
1093
+ for (size_t i = 0; i < num; i++) {
1094
+ if (prod_Z[i] == NULL) {
1095
+ break;
1096
+ }
1097
+ BN_clear_free(prod_Z[i]);
1098
+ }
1099
+ OPENSSL_free(prod_Z);
1100
+ }
1101
+
1102
+ return ret;
1103
+ }
1104
+
1105
+ int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1106
+ const BIGNUM *b, BN_CTX *ctx) {
1107
+ return BN_mod_mul(r, a, b, &group->field, ctx);
1108
+ }
1109
+
1110
+ int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
1111
+ BN_CTX *ctx) {
1112
+ return BN_mod_sqr(r, a, &group->field, ctx);
1113
+ }