ecp_smpl.c 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723
  1. /*
  2. * Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. /*
  11. * ECDSA low-level APIs are deprecated for public use, but still ok for
  12. * internal use.
  13. */
  14. #include "internal/deprecated.h"
  15. #include <openssl/err.h>
  16. #include <openssl/symhacks.h>
  17. #include "ec_local.h"
  18. const EC_METHOD *EC_GFp_simple_method(void)
  19. {
  20. static const EC_METHOD ret = {
  21. EC_FLAGS_DEFAULT_OCT,
  22. NID_X9_62_prime_field,
  23. ossl_ec_GFp_simple_group_init,
  24. ossl_ec_GFp_simple_group_finish,
  25. ossl_ec_GFp_simple_group_clear_finish,
  26. ossl_ec_GFp_simple_group_copy,
  27. ossl_ec_GFp_simple_group_set_curve,
  28. ossl_ec_GFp_simple_group_get_curve,
  29. ossl_ec_GFp_simple_group_get_degree,
  30. ossl_ec_group_simple_order_bits,
  31. ossl_ec_GFp_simple_group_check_discriminant,
  32. ossl_ec_GFp_simple_point_init,
  33. ossl_ec_GFp_simple_point_finish,
  34. ossl_ec_GFp_simple_point_clear_finish,
  35. ossl_ec_GFp_simple_point_copy,
  36. ossl_ec_GFp_simple_point_set_to_infinity,
  37. ossl_ec_GFp_simple_point_set_affine_coordinates,
  38. ossl_ec_GFp_simple_point_get_affine_coordinates,
  39. 0, 0, 0,
  40. ossl_ec_GFp_simple_add,
  41. ossl_ec_GFp_simple_dbl,
  42. ossl_ec_GFp_simple_invert,
  43. ossl_ec_GFp_simple_is_at_infinity,
  44. ossl_ec_GFp_simple_is_on_curve,
  45. ossl_ec_GFp_simple_cmp,
  46. ossl_ec_GFp_simple_make_affine,
  47. ossl_ec_GFp_simple_points_make_affine,
  48. 0 /* mul */ ,
  49. 0 /* precompute_mult */ ,
  50. 0 /* have_precompute_mult */ ,
  51. ossl_ec_GFp_simple_field_mul,
  52. ossl_ec_GFp_simple_field_sqr,
  53. 0 /* field_div */ ,
  54. ossl_ec_GFp_simple_field_inv,
  55. 0 /* field_encode */ ,
  56. 0 /* field_decode */ ,
  57. 0, /* field_set_to_one */
  58. ossl_ec_key_simple_priv2oct,
  59. ossl_ec_key_simple_oct2priv,
  60. 0, /* set private */
  61. ossl_ec_key_simple_generate_key,
  62. ossl_ec_key_simple_check_key,
  63. ossl_ec_key_simple_generate_public_key,
  64. 0, /* keycopy */
  65. 0, /* keyfinish */
  66. ossl_ecdh_simple_compute_key,
  67. ossl_ecdsa_simple_sign_setup,
  68. ossl_ecdsa_simple_sign_sig,
  69. ossl_ecdsa_simple_verify_sig,
  70. 0, /* field_inverse_mod_ord */
  71. ossl_ec_GFp_simple_blind_coordinates,
  72. ossl_ec_GFp_simple_ladder_pre,
  73. ossl_ec_GFp_simple_ladder_step,
  74. ossl_ec_GFp_simple_ladder_post
  75. };
  76. return &ret;
  77. }
  78. /*
  79. * Most method functions in this file are designed to work with
  80. * non-trivial representations of field elements if necessary
  81. * (see ecp_mont.c): while standard modular addition and subtraction
  82. * are used, the field_mul and field_sqr methods will be used for
  83. * multiplication, and field_encode and field_decode (if defined)
  84. * will be used for converting between representations.
  85. *
  86. * Functions ec_GFp_simple_points_make_affine() and
  87. * ec_GFp_simple_point_get_affine_coordinates() specifically assume
  88. * that if a non-trivial representation is used, it is a Montgomery
  89. * representation (i.e. 'encoding' means multiplying by some factor R).
  90. */
  91. int ossl_ec_GFp_simple_group_init(EC_GROUP *group)
  92. {
  93. group->field = BN_new();
  94. group->a = BN_new();
  95. group->b = BN_new();
  96. if (group->field == NULL || group->a == NULL || group->b == NULL) {
  97. BN_free(group->field);
  98. BN_free(group->a);
  99. BN_free(group->b);
  100. return 0;
  101. }
  102. group->a_is_minus3 = 0;
  103. return 1;
  104. }
  105. void ossl_ec_GFp_simple_group_finish(EC_GROUP *group)
  106. {
  107. BN_free(group->field);
  108. BN_free(group->a);
  109. BN_free(group->b);
  110. }
  111. void ossl_ec_GFp_simple_group_clear_finish(EC_GROUP *group)
  112. {
  113. BN_clear_free(group->field);
  114. BN_clear_free(group->a);
  115. BN_clear_free(group->b);
  116. }
  117. int ossl_ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src)
  118. {
  119. if (!BN_copy(dest->field, src->field))
  120. return 0;
  121. if (!BN_copy(dest->a, src->a))
  122. return 0;
  123. if (!BN_copy(dest->b, src->b))
  124. return 0;
  125. dest->a_is_minus3 = src->a_is_minus3;
  126. return 1;
  127. }
  128. int ossl_ec_GFp_simple_group_set_curve(EC_GROUP *group,
  129. const BIGNUM *p, const BIGNUM *a,
  130. const BIGNUM *b, BN_CTX *ctx)
  131. {
  132. int ret = 0;
  133. BN_CTX *new_ctx = NULL;
  134. BIGNUM *tmp_a;
  135. /* p must be a prime > 3 */
  136. if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
  137. ERR_raise(ERR_LIB_EC, EC_R_INVALID_FIELD);
  138. return 0;
  139. }
  140. if (ctx == NULL) {
  141. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  142. if (ctx == NULL)
  143. return 0;
  144. }
  145. BN_CTX_start(ctx);
  146. tmp_a = BN_CTX_get(ctx);
  147. if (tmp_a == NULL)
  148. goto err;
  149. /* group->field */
  150. if (!BN_copy(group->field, p))
  151. goto err;
  152. BN_set_negative(group->field, 0);
  153. /* group->a */
  154. if (!BN_nnmod(tmp_a, a, p, ctx))
  155. goto err;
  156. if (group->meth->field_encode != NULL) {
  157. if (!group->meth->field_encode(group, group->a, tmp_a, ctx))
  158. goto err;
  159. } else if (!BN_copy(group->a, tmp_a))
  160. goto err;
  161. /* group->b */
  162. if (!BN_nnmod(group->b, b, p, ctx))
  163. goto err;
  164. if (group->meth->field_encode != NULL)
  165. if (!group->meth->field_encode(group, group->b, group->b, ctx))
  166. goto err;
  167. /* group->a_is_minus3 */
  168. if (!BN_add_word(tmp_a, 3))
  169. goto err;
  170. group->a_is_minus3 = (0 == BN_cmp(tmp_a, group->field));
  171. ret = 1;
  172. err:
  173. BN_CTX_end(ctx);
  174. BN_CTX_free(new_ctx);
  175. return ret;
  176. }
  177. int ossl_ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p,
  178. BIGNUM *a, BIGNUM *b, BN_CTX *ctx)
  179. {
  180. int ret = 0;
  181. BN_CTX *new_ctx = NULL;
  182. if (p != NULL) {
  183. if (!BN_copy(p, group->field))
  184. return 0;
  185. }
  186. if (a != NULL || b != NULL) {
  187. if (group->meth->field_decode != NULL) {
  188. if (ctx == NULL) {
  189. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  190. if (ctx == NULL)
  191. return 0;
  192. }
  193. if (a != NULL) {
  194. if (!group->meth->field_decode(group, a, group->a, ctx))
  195. goto err;
  196. }
  197. if (b != NULL) {
  198. if (!group->meth->field_decode(group, b, group->b, ctx))
  199. goto err;
  200. }
  201. } else {
  202. if (a != NULL) {
  203. if (!BN_copy(a, group->a))
  204. goto err;
  205. }
  206. if (b != NULL) {
  207. if (!BN_copy(b, group->b))
  208. goto err;
  209. }
  210. }
  211. }
  212. ret = 1;
  213. err:
  214. BN_CTX_free(new_ctx);
  215. return ret;
  216. }
  217. int ossl_ec_GFp_simple_group_get_degree(const EC_GROUP *group)
  218. {
  219. return BN_num_bits(group->field);
  220. }
  221. int ossl_ec_GFp_simple_group_check_discriminant(const EC_GROUP *group,
  222. BN_CTX *ctx)
  223. {
  224. int ret = 0;
  225. BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
  226. const BIGNUM *p = group->field;
  227. BN_CTX *new_ctx = NULL;
  228. if (ctx == NULL) {
  229. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  230. if (ctx == NULL) {
  231. ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
  232. goto err;
  233. }
  234. }
  235. BN_CTX_start(ctx);
  236. a = BN_CTX_get(ctx);
  237. b = BN_CTX_get(ctx);
  238. tmp_1 = BN_CTX_get(ctx);
  239. tmp_2 = BN_CTX_get(ctx);
  240. order = BN_CTX_get(ctx);
  241. if (order == NULL)
  242. goto err;
  243. if (group->meth->field_decode != NULL) {
  244. if (!group->meth->field_decode(group, a, group->a, ctx))
  245. goto err;
  246. if (!group->meth->field_decode(group, b, group->b, ctx))
  247. goto err;
  248. } else {
  249. if (!BN_copy(a, group->a))
  250. goto err;
  251. if (!BN_copy(b, group->b))
  252. goto err;
  253. }
  254. /*-
  255. * check the discriminant:
  256. * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p)
  257. * 0 =< a, b < p
  258. */
  259. if (BN_is_zero(a)) {
  260. if (BN_is_zero(b))
  261. goto err;
  262. } else if (!BN_is_zero(b)) {
  263. if (!BN_mod_sqr(tmp_1, a, p, ctx))
  264. goto err;
  265. if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx))
  266. goto err;
  267. if (!BN_lshift(tmp_1, tmp_2, 2))
  268. goto err;
  269. /* tmp_1 = 4*a^3 */
  270. if (!BN_mod_sqr(tmp_2, b, p, ctx))
  271. goto err;
  272. if (!BN_mul_word(tmp_2, 27))
  273. goto err;
  274. /* tmp_2 = 27*b^2 */
  275. if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx))
  276. goto err;
  277. if (BN_is_zero(a))
  278. goto err;
  279. }
  280. ret = 1;
  281. err:
  282. BN_CTX_end(ctx);
  283. BN_CTX_free(new_ctx);
  284. return ret;
  285. }
  286. int ossl_ec_GFp_simple_point_init(EC_POINT *point)
  287. {
  288. point->X = BN_new();
  289. point->Y = BN_new();
  290. point->Z = BN_new();
  291. point->Z_is_one = 0;
  292. if (point->X == NULL || point->Y == NULL || point->Z == NULL) {
  293. BN_free(point->X);
  294. BN_free(point->Y);
  295. BN_free(point->Z);
  296. return 0;
  297. }
  298. return 1;
  299. }
  300. void ossl_ec_GFp_simple_point_finish(EC_POINT *point)
  301. {
  302. BN_free(point->X);
  303. BN_free(point->Y);
  304. BN_free(point->Z);
  305. }
  306. void ossl_ec_GFp_simple_point_clear_finish(EC_POINT *point)
  307. {
  308. BN_clear_free(point->X);
  309. BN_clear_free(point->Y);
  310. BN_clear_free(point->Z);
  311. point->Z_is_one = 0;
  312. }
  313. int ossl_ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src)
  314. {
  315. if (!BN_copy(dest->X, src->X))
  316. return 0;
  317. if (!BN_copy(dest->Y, src->Y))
  318. return 0;
  319. if (!BN_copy(dest->Z, src->Z))
  320. return 0;
  321. dest->Z_is_one = src->Z_is_one;
  322. dest->curve_name = src->curve_name;
  323. return 1;
  324. }
  325. int ossl_ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group,
  326. EC_POINT *point)
  327. {
  328. point->Z_is_one = 0;
  329. BN_zero(point->Z);
  330. return 1;
  331. }
  332. int ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group,
  333. EC_POINT *point,
  334. const BIGNUM *x,
  335. const BIGNUM *y,
  336. const BIGNUM *z,
  337. BN_CTX *ctx)
  338. {
  339. BN_CTX *new_ctx = NULL;
  340. int ret = 0;
  341. if (ctx == NULL) {
  342. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  343. if (ctx == NULL)
  344. return 0;
  345. }
  346. if (x != NULL) {
  347. if (!BN_nnmod(point->X, x, group->field, ctx))
  348. goto err;
  349. if (group->meth->field_encode) {
  350. if (!group->meth->field_encode(group, point->X, point->X, ctx))
  351. goto err;
  352. }
  353. }
  354. if (y != NULL) {
  355. if (!BN_nnmod(point->Y, y, group->field, ctx))
  356. goto err;
  357. if (group->meth->field_encode) {
  358. if (!group->meth->field_encode(group, point->Y, point->Y, ctx))
  359. goto err;
  360. }
  361. }
  362. if (z != NULL) {
  363. int Z_is_one;
  364. if (!BN_nnmod(point->Z, z, group->field, ctx))
  365. goto err;
  366. Z_is_one = BN_is_one(point->Z);
  367. if (group->meth->field_encode) {
  368. if (Z_is_one && (group->meth->field_set_to_one != 0)) {
  369. if (!group->meth->field_set_to_one(group, point->Z, ctx))
  370. goto err;
  371. } else {
  372. if (!group->
  373. meth->field_encode(group, point->Z, point->Z, ctx))
  374. goto err;
  375. }
  376. }
  377. point->Z_is_one = Z_is_one;
  378. }
  379. ret = 1;
  380. err:
  381. BN_CTX_free(new_ctx);
  382. return ret;
  383. }
  384. int ossl_ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group,
  385. const EC_POINT *point,
  386. BIGNUM *x, BIGNUM *y,
  387. BIGNUM *z, BN_CTX *ctx)
  388. {
  389. BN_CTX *new_ctx = NULL;
  390. int ret = 0;
  391. if (group->meth->field_decode != NULL) {
  392. if (ctx == NULL) {
  393. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  394. if (ctx == NULL)
  395. return 0;
  396. }
  397. if (x != NULL) {
  398. if (!group->meth->field_decode(group, x, point->X, ctx))
  399. goto err;
  400. }
  401. if (y != NULL) {
  402. if (!group->meth->field_decode(group, y, point->Y, ctx))
  403. goto err;
  404. }
  405. if (z != NULL) {
  406. if (!group->meth->field_decode(group, z, point->Z, ctx))
  407. goto err;
  408. }
  409. } else {
  410. if (x != NULL) {
  411. if (!BN_copy(x, point->X))
  412. goto err;
  413. }
  414. if (y != NULL) {
  415. if (!BN_copy(y, point->Y))
  416. goto err;
  417. }
  418. if (z != NULL) {
  419. if (!BN_copy(z, point->Z))
  420. goto err;
  421. }
  422. }
  423. ret = 1;
  424. err:
  425. BN_CTX_free(new_ctx);
  426. return ret;
  427. }
  428. int ossl_ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
  429. EC_POINT *point,
  430. const BIGNUM *x,
  431. const BIGNUM *y, BN_CTX *ctx)
  432. {
  433. if (x == NULL || y == NULL) {
  434. /*
  435. * unlike for projective coordinates, we do not tolerate this
  436. */
  437. ERR_raise(ERR_LIB_EC, ERR_R_PASSED_NULL_PARAMETER);
  438. return 0;
  439. }
  440. return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
  441. BN_value_one(), ctx);
  442. }
  443. int ossl_ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
  444. const EC_POINT *point,
  445. BIGNUM *x, BIGNUM *y,
  446. BN_CTX *ctx)
  447. {
  448. BN_CTX *new_ctx = NULL;
  449. BIGNUM *Z, *Z_1, *Z_2, *Z_3;
  450. const BIGNUM *Z_;
  451. int ret = 0;
  452. if (EC_POINT_is_at_infinity(group, point)) {
  453. ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
  454. return 0;
  455. }
  456. if (ctx == NULL) {
  457. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  458. if (ctx == NULL)
  459. return 0;
  460. }
  461. BN_CTX_start(ctx);
  462. Z = BN_CTX_get(ctx);
  463. Z_1 = BN_CTX_get(ctx);
  464. Z_2 = BN_CTX_get(ctx);
  465. Z_3 = BN_CTX_get(ctx);
  466. if (Z_3 == NULL)
  467. goto err;
  468. /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
  469. if (group->meth->field_decode != NULL) {
  470. if (!group->meth->field_decode(group, Z, point->Z, ctx))
  471. goto err;
  472. Z_ = Z;
  473. } else {
  474. Z_ = point->Z;
  475. }
  476. if (BN_is_one(Z_)) {
  477. if (group->meth->field_decode != NULL) {
  478. if (x != NULL) {
  479. if (!group->meth->field_decode(group, x, point->X, ctx))
  480. goto err;
  481. }
  482. if (y != NULL) {
  483. if (!group->meth->field_decode(group, y, point->Y, ctx))
  484. goto err;
  485. }
  486. } else {
  487. if (x != NULL) {
  488. if (!BN_copy(x, point->X))
  489. goto err;
  490. }
  491. if (y != NULL) {
  492. if (!BN_copy(y, point->Y))
  493. goto err;
  494. }
  495. }
  496. } else {
  497. if (!group->meth->field_inv(group, Z_1, Z_, ctx)) {
  498. ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
  499. goto err;
  500. }
  501. if (group->meth->field_encode == NULL) {
  502. /* field_sqr works on standard representation */
  503. if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
  504. goto err;
  505. } else {
  506. if (!BN_mod_sqr(Z_2, Z_1, group->field, ctx))
  507. goto err;
  508. }
  509. if (x != NULL) {
  510. /*
  511. * in the Montgomery case, field_mul will cancel out Montgomery
  512. * factor in X:
  513. */
  514. if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
  515. goto err;
  516. }
  517. if (y != NULL) {
  518. if (group->meth->field_encode == NULL) {
  519. /*
  520. * field_mul works on standard representation
  521. */
  522. if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
  523. goto err;
  524. } else {
  525. if (!BN_mod_mul(Z_3, Z_2, Z_1, group->field, ctx))
  526. goto err;
  527. }
  528. /*
  529. * in the Montgomery case, field_mul will cancel out Montgomery
  530. * factor in Y:
  531. */
  532. if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
  533. goto err;
  534. }
  535. }
  536. ret = 1;
  537. err:
  538. BN_CTX_end(ctx);
  539. BN_CTX_free(new_ctx);
  540. return ret;
  541. }
  542. int ossl_ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  543. const EC_POINT *b, BN_CTX *ctx)
  544. {
  545. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  546. const BIGNUM *, BN_CTX *);
  547. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  548. const BIGNUM *p;
  549. BN_CTX *new_ctx = NULL;
  550. BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
  551. int ret = 0;
  552. if (a == b)
  553. return EC_POINT_dbl(group, r, a, ctx);
  554. if (EC_POINT_is_at_infinity(group, a))
  555. return EC_POINT_copy(r, b);
  556. if (EC_POINT_is_at_infinity(group, b))
  557. return EC_POINT_copy(r, a);
  558. field_mul = group->meth->field_mul;
  559. field_sqr = group->meth->field_sqr;
  560. p = group->field;
  561. if (ctx == NULL) {
  562. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  563. if (ctx == NULL)
  564. return 0;
  565. }
  566. BN_CTX_start(ctx);
  567. n0 = BN_CTX_get(ctx);
  568. n1 = BN_CTX_get(ctx);
  569. n2 = BN_CTX_get(ctx);
  570. n3 = BN_CTX_get(ctx);
  571. n4 = BN_CTX_get(ctx);
  572. n5 = BN_CTX_get(ctx);
  573. n6 = BN_CTX_get(ctx);
  574. if (n6 == NULL)
  575. goto end;
  576. /*
  577. * Note that in this function we must not read components of 'a' or 'b'
  578. * once we have written the corresponding components of 'r'. ('r' might
  579. * be one of 'a' or 'b'.)
  580. */
  581. /* n1, n2 */
  582. if (b->Z_is_one) {
  583. if (!BN_copy(n1, a->X))
  584. goto end;
  585. if (!BN_copy(n2, a->Y))
  586. goto end;
  587. /* n1 = X_a */
  588. /* n2 = Y_a */
  589. } else {
  590. if (!field_sqr(group, n0, b->Z, ctx))
  591. goto end;
  592. if (!field_mul(group, n1, a->X, n0, ctx))
  593. goto end;
  594. /* n1 = X_a * Z_b^2 */
  595. if (!field_mul(group, n0, n0, b->Z, ctx))
  596. goto end;
  597. if (!field_mul(group, n2, a->Y, n0, ctx))
  598. goto end;
  599. /* n2 = Y_a * Z_b^3 */
  600. }
  601. /* n3, n4 */
  602. if (a->Z_is_one) {
  603. if (!BN_copy(n3, b->X))
  604. goto end;
  605. if (!BN_copy(n4, b->Y))
  606. goto end;
  607. /* n3 = X_b */
  608. /* n4 = Y_b */
  609. } else {
  610. if (!field_sqr(group, n0, a->Z, ctx))
  611. goto end;
  612. if (!field_mul(group, n3, b->X, n0, ctx))
  613. goto end;
  614. /* n3 = X_b * Z_a^2 */
  615. if (!field_mul(group, n0, n0, a->Z, ctx))
  616. goto end;
  617. if (!field_mul(group, n4, b->Y, n0, ctx))
  618. goto end;
  619. /* n4 = Y_b * Z_a^3 */
  620. }
  621. /* n5, n6 */
  622. if (!BN_mod_sub_quick(n5, n1, n3, p))
  623. goto end;
  624. if (!BN_mod_sub_quick(n6, n2, n4, p))
  625. goto end;
  626. /* n5 = n1 - n3 */
  627. /* n6 = n2 - n4 */
  628. if (BN_is_zero(n5)) {
  629. if (BN_is_zero(n6)) {
  630. /* a is the same point as b */
  631. BN_CTX_end(ctx);
  632. ret = EC_POINT_dbl(group, r, a, ctx);
  633. ctx = NULL;
  634. goto end;
  635. } else {
  636. /* a is the inverse of b */
  637. BN_zero(r->Z);
  638. r->Z_is_one = 0;
  639. ret = 1;
  640. goto end;
  641. }
  642. }
  643. /* 'n7', 'n8' */
  644. if (!BN_mod_add_quick(n1, n1, n3, p))
  645. goto end;
  646. if (!BN_mod_add_quick(n2, n2, n4, p))
  647. goto end;
  648. /* 'n7' = n1 + n3 */
  649. /* 'n8' = n2 + n4 */
  650. /* Z_r */
  651. if (a->Z_is_one && b->Z_is_one) {
  652. if (!BN_copy(r->Z, n5))
  653. goto end;
  654. } else {
  655. if (a->Z_is_one) {
  656. if (!BN_copy(n0, b->Z))
  657. goto end;
  658. } else if (b->Z_is_one) {
  659. if (!BN_copy(n0, a->Z))
  660. goto end;
  661. } else {
  662. if (!field_mul(group, n0, a->Z, b->Z, ctx))
  663. goto end;
  664. }
  665. if (!field_mul(group, r->Z, n0, n5, ctx))
  666. goto end;
  667. }
  668. r->Z_is_one = 0;
  669. /* Z_r = Z_a * Z_b * n5 */
  670. /* X_r */
  671. if (!field_sqr(group, n0, n6, ctx))
  672. goto end;
  673. if (!field_sqr(group, n4, n5, ctx))
  674. goto end;
  675. if (!field_mul(group, n3, n1, n4, ctx))
  676. goto end;
  677. if (!BN_mod_sub_quick(r->X, n0, n3, p))
  678. goto end;
  679. /* X_r = n6^2 - n5^2 * 'n7' */
  680. /* 'n9' */
  681. if (!BN_mod_lshift1_quick(n0, r->X, p))
  682. goto end;
  683. if (!BN_mod_sub_quick(n0, n3, n0, p))
  684. goto end;
  685. /* n9 = n5^2 * 'n7' - 2 * X_r */
  686. /* Y_r */
  687. if (!field_mul(group, n0, n0, n6, ctx))
  688. goto end;
  689. if (!field_mul(group, n5, n4, n5, ctx))
  690. goto end; /* now n5 is n5^3 */
  691. if (!field_mul(group, n1, n2, n5, ctx))
  692. goto end;
  693. if (!BN_mod_sub_quick(n0, n0, n1, p))
  694. goto end;
  695. if (BN_is_odd(n0))
  696. if (!BN_add(n0, n0, p))
  697. goto end;
  698. /* now 0 <= n0 < 2*p, and n0 is even */
  699. if (!BN_rshift1(r->Y, n0))
  700. goto end;
  701. /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
  702. ret = 1;
  703. end:
  704. BN_CTX_end(ctx);
  705. BN_CTX_free(new_ctx);
  706. return ret;
  707. }
  708. int ossl_ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  709. BN_CTX *ctx)
  710. {
  711. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  712. const BIGNUM *, BN_CTX *);
  713. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  714. const BIGNUM *p;
  715. BN_CTX *new_ctx = NULL;
  716. BIGNUM *n0, *n1, *n2, *n3;
  717. int ret = 0;
  718. if (EC_POINT_is_at_infinity(group, a)) {
  719. BN_zero(r->Z);
  720. r->Z_is_one = 0;
  721. return 1;
  722. }
  723. field_mul = group->meth->field_mul;
  724. field_sqr = group->meth->field_sqr;
  725. p = group->field;
  726. if (ctx == NULL) {
  727. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  728. if (ctx == NULL)
  729. return 0;
  730. }
  731. BN_CTX_start(ctx);
  732. n0 = BN_CTX_get(ctx);
  733. n1 = BN_CTX_get(ctx);
  734. n2 = BN_CTX_get(ctx);
  735. n3 = BN_CTX_get(ctx);
  736. if (n3 == NULL)
  737. goto err;
  738. /*
  739. * Note that in this function we must not read components of 'a' once we
  740. * have written the corresponding components of 'r'. ('r' might the same
  741. * as 'a'.)
  742. */
  743. /* n1 */
  744. if (a->Z_is_one) {
  745. if (!field_sqr(group, n0, a->X, ctx))
  746. goto err;
  747. if (!BN_mod_lshift1_quick(n1, n0, p))
  748. goto err;
  749. if (!BN_mod_add_quick(n0, n0, n1, p))
  750. goto err;
  751. if (!BN_mod_add_quick(n1, n0, group->a, p))
  752. goto err;
  753. /* n1 = 3 * X_a^2 + a_curve */
  754. } else if (group->a_is_minus3) {
  755. if (!field_sqr(group, n1, a->Z, ctx))
  756. goto err;
  757. if (!BN_mod_add_quick(n0, a->X, n1, p))
  758. goto err;
  759. if (!BN_mod_sub_quick(n2, a->X, n1, p))
  760. goto err;
  761. if (!field_mul(group, n1, n0, n2, ctx))
  762. goto err;
  763. if (!BN_mod_lshift1_quick(n0, n1, p))
  764. goto err;
  765. if (!BN_mod_add_quick(n1, n0, n1, p))
  766. goto err;
  767. /*-
  768. * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
  769. * = 3 * X_a^2 - 3 * Z_a^4
  770. */
  771. } else {
  772. if (!field_sqr(group, n0, a->X, ctx))
  773. goto err;
  774. if (!BN_mod_lshift1_quick(n1, n0, p))
  775. goto err;
  776. if (!BN_mod_add_quick(n0, n0, n1, p))
  777. goto err;
  778. if (!field_sqr(group, n1, a->Z, ctx))
  779. goto err;
  780. if (!field_sqr(group, n1, n1, ctx))
  781. goto err;
  782. if (!field_mul(group, n1, n1, group->a, ctx))
  783. goto err;
  784. if (!BN_mod_add_quick(n1, n1, n0, p))
  785. goto err;
  786. /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
  787. }
  788. /* Z_r */
  789. if (a->Z_is_one) {
  790. if (!BN_copy(n0, a->Y))
  791. goto err;
  792. } else {
  793. if (!field_mul(group, n0, a->Y, a->Z, ctx))
  794. goto err;
  795. }
  796. if (!BN_mod_lshift1_quick(r->Z, n0, p))
  797. goto err;
  798. r->Z_is_one = 0;
  799. /* Z_r = 2 * Y_a * Z_a */
  800. /* n2 */
  801. if (!field_sqr(group, n3, a->Y, ctx))
  802. goto err;
  803. if (!field_mul(group, n2, a->X, n3, ctx))
  804. goto err;
  805. if (!BN_mod_lshift_quick(n2, n2, 2, p))
  806. goto err;
  807. /* n2 = 4 * X_a * Y_a^2 */
  808. /* X_r */
  809. if (!BN_mod_lshift1_quick(n0, n2, p))
  810. goto err;
  811. if (!field_sqr(group, r->X, n1, ctx))
  812. goto err;
  813. if (!BN_mod_sub_quick(r->X, r->X, n0, p))
  814. goto err;
  815. /* X_r = n1^2 - 2 * n2 */
  816. /* n3 */
  817. if (!field_sqr(group, n0, n3, ctx))
  818. goto err;
  819. if (!BN_mod_lshift_quick(n3, n0, 3, p))
  820. goto err;
  821. /* n3 = 8 * Y_a^4 */
  822. /* Y_r */
  823. if (!BN_mod_sub_quick(n0, n2, r->X, p))
  824. goto err;
  825. if (!field_mul(group, n0, n1, n0, ctx))
  826. goto err;
  827. if (!BN_mod_sub_quick(r->Y, n0, n3, p))
  828. goto err;
  829. /* Y_r = n1 * (n2 - X_r) - n3 */
  830. ret = 1;
  831. err:
  832. BN_CTX_end(ctx);
  833. BN_CTX_free(new_ctx);
  834. return ret;
  835. }
  836. int ossl_ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point,
  837. BN_CTX *ctx)
  838. {
  839. if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
  840. /* point is its own inverse */
  841. return 1;
  842. return BN_usub(point->Y, group->field, point->Y);
  843. }
  844. int ossl_ec_GFp_simple_is_at_infinity(const EC_GROUP *group,
  845. const EC_POINT *point)
  846. {
  847. return BN_is_zero(point->Z);
  848. }
  849. int ossl_ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  850. BN_CTX *ctx)
  851. {
  852. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  853. const BIGNUM *, BN_CTX *);
  854. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  855. const BIGNUM *p;
  856. BN_CTX *new_ctx = NULL;
  857. BIGNUM *rh, *tmp, *Z4, *Z6;
  858. int ret = -1;
  859. if (EC_POINT_is_at_infinity(group, point))
  860. return 1;
  861. field_mul = group->meth->field_mul;
  862. field_sqr = group->meth->field_sqr;
  863. p = group->field;
  864. if (ctx == NULL) {
  865. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  866. if (ctx == NULL)
  867. return -1;
  868. }
  869. BN_CTX_start(ctx);
  870. rh = BN_CTX_get(ctx);
  871. tmp = BN_CTX_get(ctx);
  872. Z4 = BN_CTX_get(ctx);
  873. Z6 = BN_CTX_get(ctx);
  874. if (Z6 == NULL)
  875. goto err;
  876. /*-
  877. * We have a curve defined by a Weierstrass equation
  878. * y^2 = x^3 + a*x + b.
  879. * The point to consider is given in Jacobian projective coordinates
  880. * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
  881. * Substituting this and multiplying by Z^6 transforms the above equation into
  882. * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
  883. * To test this, we add up the right-hand side in 'rh'.
  884. */
  885. /* rh := X^2 */
  886. if (!field_sqr(group, rh, point->X, ctx))
  887. goto err;
  888. if (!point->Z_is_one) {
  889. if (!field_sqr(group, tmp, point->Z, ctx))
  890. goto err;
  891. if (!field_sqr(group, Z4, tmp, ctx))
  892. goto err;
  893. if (!field_mul(group, Z6, Z4, tmp, ctx))
  894. goto err;
  895. /* rh := (rh + a*Z^4)*X */
  896. if (group->a_is_minus3) {
  897. if (!BN_mod_lshift1_quick(tmp, Z4, p))
  898. goto err;
  899. if (!BN_mod_add_quick(tmp, tmp, Z4, p))
  900. goto err;
  901. if (!BN_mod_sub_quick(rh, rh, tmp, p))
  902. goto err;
  903. if (!field_mul(group, rh, rh, point->X, ctx))
  904. goto err;
  905. } else {
  906. if (!field_mul(group, tmp, Z4, group->a, ctx))
  907. goto err;
  908. if (!BN_mod_add_quick(rh, rh, tmp, p))
  909. goto err;
  910. if (!field_mul(group, rh, rh, point->X, ctx))
  911. goto err;
  912. }
  913. /* rh := rh + b*Z^6 */
  914. if (!field_mul(group, tmp, group->b, Z6, ctx))
  915. goto err;
  916. if (!BN_mod_add_quick(rh, rh, tmp, p))
  917. goto err;
  918. } else {
  919. /* point->Z_is_one */
  920. /* rh := (rh + a)*X */
  921. if (!BN_mod_add_quick(rh, rh, group->a, p))
  922. goto err;
  923. if (!field_mul(group, rh, rh, point->X, ctx))
  924. goto err;
  925. /* rh := rh + b */
  926. if (!BN_mod_add_quick(rh, rh, group->b, p))
  927. goto err;
  928. }
  929. /* 'lh' := Y^2 */
  930. if (!field_sqr(group, tmp, point->Y, ctx))
  931. goto err;
  932. ret = (0 == BN_ucmp(tmp, rh));
  933. err:
  934. BN_CTX_end(ctx);
  935. BN_CTX_free(new_ctx);
  936. return ret;
  937. }
  938. int ossl_ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
  939. const EC_POINT *b, BN_CTX *ctx)
  940. {
  941. /*-
  942. * return values:
  943. * -1 error
  944. * 0 equal (in affine coordinates)
  945. * 1 not equal
  946. */
  947. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  948. const BIGNUM *, BN_CTX *);
  949. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  950. BN_CTX *new_ctx = NULL;
  951. BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
  952. const BIGNUM *tmp1_, *tmp2_;
  953. int ret = -1;
  954. if (EC_POINT_is_at_infinity(group, a)) {
  955. return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  956. }
  957. if (EC_POINT_is_at_infinity(group, b))
  958. return 1;
  959. if (a->Z_is_one && b->Z_is_one) {
  960. return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
  961. }
  962. field_mul = group->meth->field_mul;
  963. field_sqr = group->meth->field_sqr;
  964. if (ctx == NULL) {
  965. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  966. if (ctx == NULL)
  967. return -1;
  968. }
  969. BN_CTX_start(ctx);
  970. tmp1 = BN_CTX_get(ctx);
  971. tmp2 = BN_CTX_get(ctx);
  972. Za23 = BN_CTX_get(ctx);
  973. Zb23 = BN_CTX_get(ctx);
  974. if (Zb23 == NULL)
  975. goto end;
  976. /*-
  977. * We have to decide whether
  978. * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
  979. * or equivalently, whether
  980. * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
  981. */
  982. if (!b->Z_is_one) {
  983. if (!field_sqr(group, Zb23, b->Z, ctx))
  984. goto end;
  985. if (!field_mul(group, tmp1, a->X, Zb23, ctx))
  986. goto end;
  987. tmp1_ = tmp1;
  988. } else
  989. tmp1_ = a->X;
  990. if (!a->Z_is_one) {
  991. if (!field_sqr(group, Za23, a->Z, ctx))
  992. goto end;
  993. if (!field_mul(group, tmp2, b->X, Za23, ctx))
  994. goto end;
  995. tmp2_ = tmp2;
  996. } else
  997. tmp2_ = b->X;
  998. /* compare X_a*Z_b^2 with X_b*Z_a^2 */
  999. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1000. ret = 1; /* points differ */
  1001. goto end;
  1002. }
  1003. if (!b->Z_is_one) {
  1004. if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
  1005. goto end;
  1006. if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
  1007. goto end;
  1008. /* tmp1_ = tmp1 */
  1009. } else
  1010. tmp1_ = a->Y;
  1011. if (!a->Z_is_one) {
  1012. if (!field_mul(group, Za23, Za23, a->Z, ctx))
  1013. goto end;
  1014. if (!field_mul(group, tmp2, b->Y, Za23, ctx))
  1015. goto end;
  1016. /* tmp2_ = tmp2 */
  1017. } else
  1018. tmp2_ = b->Y;
  1019. /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
  1020. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1021. ret = 1; /* points differ */
  1022. goto end;
  1023. }
  1024. /* points are equal */
  1025. ret = 0;
  1026. end:
  1027. BN_CTX_end(ctx);
  1028. BN_CTX_free(new_ctx);
  1029. return ret;
  1030. }
  1031. int ossl_ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
  1032. BN_CTX *ctx)
  1033. {
  1034. BN_CTX *new_ctx = NULL;
  1035. BIGNUM *x, *y;
  1036. int ret = 0;
  1037. if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
  1038. return 1;
  1039. if (ctx == NULL) {
  1040. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  1041. if (ctx == NULL)
  1042. return 0;
  1043. }
  1044. BN_CTX_start(ctx);
  1045. x = BN_CTX_get(ctx);
  1046. y = BN_CTX_get(ctx);
  1047. if (y == NULL)
  1048. goto err;
  1049. if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
  1050. goto err;
  1051. if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
  1052. goto err;
  1053. if (!point->Z_is_one) {
  1054. ERR_raise(ERR_LIB_EC, ERR_R_INTERNAL_ERROR);
  1055. goto err;
  1056. }
  1057. ret = 1;
  1058. err:
  1059. BN_CTX_end(ctx);
  1060. BN_CTX_free(new_ctx);
  1061. return ret;
  1062. }
  1063. int ossl_ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
  1064. EC_POINT *points[], BN_CTX *ctx)
  1065. {
  1066. BN_CTX *new_ctx = NULL;
  1067. BIGNUM *tmp, *tmp_Z;
  1068. BIGNUM **prod_Z = NULL;
  1069. size_t i;
  1070. int ret = 0;
  1071. if (num == 0)
  1072. return 1;
  1073. if (ctx == NULL) {
  1074. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  1075. if (ctx == NULL)
  1076. return 0;
  1077. }
  1078. BN_CTX_start(ctx);
  1079. tmp = BN_CTX_get(ctx);
  1080. tmp_Z = BN_CTX_get(ctx);
  1081. if (tmp_Z == NULL)
  1082. goto err;
  1083. prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
  1084. if (prod_Z == NULL)
  1085. goto err;
  1086. for (i = 0; i < num; i++) {
  1087. prod_Z[i] = BN_new();
  1088. if (prod_Z[i] == NULL)
  1089. goto err;
  1090. }
  1091. /*
  1092. * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
  1093. * skipping any zero-valued inputs (pretend that they're 1).
  1094. */
  1095. if (!BN_is_zero(points[0]->Z)) {
  1096. if (!BN_copy(prod_Z[0], points[0]->Z))
  1097. goto err;
  1098. } else {
  1099. if (group->meth->field_set_to_one != 0) {
  1100. if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
  1101. goto err;
  1102. } else {
  1103. if (!BN_one(prod_Z[0]))
  1104. goto err;
  1105. }
  1106. }
  1107. for (i = 1; i < num; i++) {
  1108. if (!BN_is_zero(points[i]->Z)) {
  1109. if (!group->
  1110. meth->field_mul(group, prod_Z[i], prod_Z[i - 1], points[i]->Z,
  1111. ctx))
  1112. goto err;
  1113. } else {
  1114. if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
  1115. goto err;
  1116. }
  1117. }
  1118. /*
  1119. * Now use a single explicit inversion to replace every non-zero
  1120. * points[i]->Z by its inverse.
  1121. */
  1122. if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) {
  1123. ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
  1124. goto err;
  1125. }
  1126. if (group->meth->field_encode != NULL) {
  1127. /*
  1128. * In the Montgomery case, we just turned R*H (representing H) into
  1129. * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
  1130. * multiply by the Montgomery factor twice.
  1131. */
  1132. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1133. goto err;
  1134. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1135. goto err;
  1136. }
  1137. for (i = num - 1; i > 0; --i) {
  1138. /*
  1139. * Loop invariant: tmp is the product of the inverses of points[0]->Z
  1140. * .. points[i]->Z (zero-valued inputs skipped).
  1141. */
  1142. if (!BN_is_zero(points[i]->Z)) {
  1143. /*
  1144. * Set tmp_Z to the inverse of points[i]->Z (as product of Z
  1145. * inverses 0 .. i, Z values 0 .. i - 1).
  1146. */
  1147. if (!group->
  1148. meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
  1149. goto err;
  1150. /*
  1151. * Update tmp to satisfy the loop invariant for i - 1.
  1152. */
  1153. if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
  1154. goto err;
  1155. /* Replace points[i]->Z by its inverse. */
  1156. if (!BN_copy(points[i]->Z, tmp_Z))
  1157. goto err;
  1158. }
  1159. }
  1160. if (!BN_is_zero(points[0]->Z)) {
  1161. /* Replace points[0]->Z by its inverse. */
  1162. if (!BN_copy(points[0]->Z, tmp))
  1163. goto err;
  1164. }
  1165. /* Finally, fix up the X and Y coordinates for all points. */
  1166. for (i = 0; i < num; i++) {
  1167. EC_POINT *p = points[i];
  1168. if (!BN_is_zero(p->Z)) {
  1169. /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
  1170. if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
  1171. goto err;
  1172. if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
  1173. goto err;
  1174. if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
  1175. goto err;
  1176. if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
  1177. goto err;
  1178. if (group->meth->field_set_to_one != 0) {
  1179. if (!group->meth->field_set_to_one(group, p->Z, ctx))
  1180. goto err;
  1181. } else {
  1182. if (!BN_one(p->Z))
  1183. goto err;
  1184. }
  1185. p->Z_is_one = 1;
  1186. }
  1187. }
  1188. ret = 1;
  1189. err:
  1190. BN_CTX_end(ctx);
  1191. BN_CTX_free(new_ctx);
  1192. if (prod_Z != NULL) {
  1193. for (i = 0; i < num; i++) {
  1194. if (prod_Z[i] == NULL)
  1195. break;
  1196. BN_clear_free(prod_Z[i]);
  1197. }
  1198. OPENSSL_free(prod_Z);
  1199. }
  1200. return ret;
  1201. }
  1202. int ossl_ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1203. const BIGNUM *b, BN_CTX *ctx)
  1204. {
  1205. return BN_mod_mul(r, a, b, group->field, ctx);
  1206. }
  1207. int ossl_ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1208. BN_CTX *ctx)
  1209. {
  1210. return BN_mod_sqr(r, a, group->field, ctx);
  1211. }
  1212. /*-
  1213. * Computes the multiplicative inverse of a in GF(p), storing the result in r.
  1214. * If a is zero (or equivalent), you'll get an EC_R_CANNOT_INVERT error.
  1215. * Since we don't have a Mont structure here, SCA hardening is with blinding.
  1216. * NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.)
  1217. */
  1218. int ossl_ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r,
  1219. const BIGNUM *a, BN_CTX *ctx)
  1220. {
  1221. BIGNUM *e = NULL;
  1222. BN_CTX *new_ctx = NULL;
  1223. int ret = 0;
  1224. if (ctx == NULL
  1225. && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL)
  1226. return 0;
  1227. BN_CTX_start(ctx);
  1228. if ((e = BN_CTX_get(ctx)) == NULL)
  1229. goto err;
  1230. do {
  1231. if (!BN_priv_rand_range_ex(e, group->field, 0, ctx))
  1232. goto err;
  1233. } while (BN_is_zero(e));
  1234. /* r := a * e */
  1235. if (!group->meth->field_mul(group, r, a, e, ctx))
  1236. goto err;
  1237. /* r := 1/(a * e) */
  1238. if (!BN_mod_inverse(r, r, group->field, ctx)) {
  1239. ERR_raise(ERR_LIB_EC, EC_R_CANNOT_INVERT);
  1240. goto err;
  1241. }
  1242. /* r := e/(a * e) = 1/a */
  1243. if (!group->meth->field_mul(group, r, r, e, ctx))
  1244. goto err;
  1245. ret = 1;
  1246. err:
  1247. BN_CTX_end(ctx);
  1248. BN_CTX_free(new_ctx);
  1249. return ret;
  1250. }
  1251. /*-
  1252. * Apply randomization of EC point projective coordinates:
  1253. *
  1254. * (X, Y, Z) = (lambda^2*X, lambda^3*Y, lambda*Z)
  1255. * lambda = [1, group->field)
  1256. *
  1257. */
  1258. int ossl_ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
  1259. BN_CTX *ctx)
  1260. {
  1261. int ret = 0;
  1262. BIGNUM *lambda = NULL;
  1263. BIGNUM *temp = NULL;
  1264. BN_CTX_start(ctx);
  1265. lambda = BN_CTX_get(ctx);
  1266. temp = BN_CTX_get(ctx);
  1267. if (temp == NULL) {
  1268. ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
  1269. goto end;
  1270. }
  1271. /*-
  1272. * Make sure lambda is not zero.
  1273. * If the RNG fails, we cannot blind but nevertheless want
  1274. * code to continue smoothly and not clobber the error stack.
  1275. */
  1276. do {
  1277. ERR_set_mark();
  1278. ret = BN_priv_rand_range_ex(lambda, group->field, 0, ctx);
  1279. ERR_pop_to_mark();
  1280. if (ret == 0) {
  1281. ret = 1;
  1282. goto end;
  1283. }
  1284. } while (BN_is_zero(lambda));
  1285. /* if field_encode defined convert between representations */
  1286. if ((group->meth->field_encode != NULL
  1287. && !group->meth->field_encode(group, lambda, lambda, ctx))
  1288. || !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)
  1289. || !group->meth->field_sqr(group, temp, lambda, ctx)
  1290. || !group->meth->field_mul(group, p->X, p->X, temp, ctx)
  1291. || !group->meth->field_mul(group, temp, temp, lambda, ctx)
  1292. || !group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
  1293. goto end;
  1294. p->Z_is_one = 0;
  1295. ret = 1;
  1296. end:
  1297. BN_CTX_end(ctx);
  1298. return ret;
  1299. }
  1300. /*-
  1301. * Input:
  1302. * - p: affine coordinates
  1303. *
  1304. * Output:
  1305. * - s := p, r := 2p: blinded projective (homogeneous) coordinates
  1306. *
  1307. * For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve
  1308. * multiplication resistant against side channel attacks" appendix, described at
  1309. * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2
  1310. * simplified for Z1=1.
  1311. *
  1312. * Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z)
  1313. * for any non-zero \lambda that holds for projective (homogeneous) coords.
  1314. */
  1315. int ossl_ec_GFp_simple_ladder_pre(const EC_GROUP *group,
  1316. EC_POINT *r, EC_POINT *s,
  1317. EC_POINT *p, BN_CTX *ctx)
  1318. {
  1319. BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
  1320. t1 = s->Z;
  1321. t2 = r->Z;
  1322. t3 = s->X;
  1323. t4 = r->X;
  1324. t5 = s->Y;
  1325. if (!p->Z_is_one /* r := 2p */
  1326. || !group->meth->field_sqr(group, t3, p->X, ctx)
  1327. || !BN_mod_sub_quick(t4, t3, group->a, group->field)
  1328. || !group->meth->field_sqr(group, t4, t4, ctx)
  1329. || !group->meth->field_mul(group, t5, p->X, group->b, ctx)
  1330. || !BN_mod_lshift_quick(t5, t5, 3, group->field)
  1331. /* r->X coord output */
  1332. || !BN_mod_sub_quick(r->X, t4, t5, group->field)
  1333. || !BN_mod_add_quick(t1, t3, group->a, group->field)
  1334. || !group->meth->field_mul(group, t2, p->X, t1, ctx)
  1335. || !BN_mod_add_quick(t2, group->b, t2, group->field)
  1336. /* r->Z coord output */
  1337. || !BN_mod_lshift_quick(r->Z, t2, 2, group->field))
  1338. return 0;
  1339. /* make sure lambda (r->Y here for storage) is not zero */
  1340. do {
  1341. if (!BN_priv_rand_range_ex(r->Y, group->field, 0, ctx))
  1342. return 0;
  1343. } while (BN_is_zero(r->Y));
  1344. /* make sure lambda (s->Z here for storage) is not zero */
  1345. do {
  1346. if (!BN_priv_rand_range_ex(s->Z, group->field, 0, ctx))
  1347. return 0;
  1348. } while (BN_is_zero(s->Z));
  1349. /* if field_encode defined convert between representations */
  1350. if (group->meth->field_encode != NULL
  1351. && (!group->meth->field_encode(group, r->Y, r->Y, ctx)
  1352. || !group->meth->field_encode(group, s->Z, s->Z, ctx)))
  1353. return 0;
  1354. /* blind r and s independently */
  1355. if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
  1356. || !group->meth->field_mul(group, r->X, r->X, r->Y, ctx)
  1357. || !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */
  1358. return 0;
  1359. r->Z_is_one = 0;
  1360. s->Z_is_one = 0;
  1361. return 1;
  1362. }
  1363. /*-
  1364. * Input:
  1365. * - s, r: projective (homogeneous) coordinates
  1366. * - p: affine coordinates
  1367. *
  1368. * Output:
  1369. * - s := r + s, r := 2r: projective (homogeneous) coordinates
  1370. *
  1371. * Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
  1372. * "A fast parallel elliptic curve multiplication resistant against side channel
  1373. * attacks", as described at
  1374. * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4
  1375. */
  1376. int ossl_ec_GFp_simple_ladder_step(const EC_GROUP *group,
  1377. EC_POINT *r, EC_POINT *s,
  1378. EC_POINT *p, BN_CTX *ctx)
  1379. {
  1380. int ret = 0;
  1381. BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
  1382. BN_CTX_start(ctx);
  1383. t0 = BN_CTX_get(ctx);
  1384. t1 = BN_CTX_get(ctx);
  1385. t2 = BN_CTX_get(ctx);
  1386. t3 = BN_CTX_get(ctx);
  1387. t4 = BN_CTX_get(ctx);
  1388. t5 = BN_CTX_get(ctx);
  1389. t6 = BN_CTX_get(ctx);
  1390. if (t6 == NULL
  1391. || !group->meth->field_mul(group, t6, r->X, s->X, ctx)
  1392. || !group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
  1393. || !group->meth->field_mul(group, t4, r->X, s->Z, ctx)
  1394. || !group->meth->field_mul(group, t3, r->Z, s->X, ctx)
  1395. || !group->meth->field_mul(group, t5, group->a, t0, ctx)
  1396. || !BN_mod_add_quick(t5, t6, t5, group->field)
  1397. || !BN_mod_add_quick(t6, t3, t4, group->field)
  1398. || !group->meth->field_mul(group, t5, t6, t5, ctx)
  1399. || !group->meth->field_sqr(group, t0, t0, ctx)
  1400. || !BN_mod_lshift_quick(t2, group->b, 2, group->field)
  1401. || !group->meth->field_mul(group, t0, t2, t0, ctx)
  1402. || !BN_mod_lshift1_quick(t5, t5, group->field)
  1403. || !BN_mod_sub_quick(t3, t4, t3, group->field)
  1404. /* s->Z coord output */
  1405. || !group->meth->field_sqr(group, s->Z, t3, ctx)
  1406. || !group->meth->field_mul(group, t4, s->Z, p->X, ctx)
  1407. || !BN_mod_add_quick(t0, t0, t5, group->field)
  1408. /* s->X coord output */
  1409. || !BN_mod_sub_quick(s->X, t0, t4, group->field)
  1410. || !group->meth->field_sqr(group, t4, r->X, ctx)
  1411. || !group->meth->field_sqr(group, t5, r->Z, ctx)
  1412. || !group->meth->field_mul(group, t6, t5, group->a, ctx)
  1413. || !BN_mod_add_quick(t1, r->X, r->Z, group->field)
  1414. || !group->meth->field_sqr(group, t1, t1, ctx)
  1415. || !BN_mod_sub_quick(t1, t1, t4, group->field)
  1416. || !BN_mod_sub_quick(t1, t1, t5, group->field)
  1417. || !BN_mod_sub_quick(t3, t4, t6, group->field)
  1418. || !group->meth->field_sqr(group, t3, t3, ctx)
  1419. || !group->meth->field_mul(group, t0, t5, t1, ctx)
  1420. || !group->meth->field_mul(group, t0, t2, t0, ctx)
  1421. /* r->X coord output */
  1422. || !BN_mod_sub_quick(r->X, t3, t0, group->field)
  1423. || !BN_mod_add_quick(t3, t4, t6, group->field)
  1424. || !group->meth->field_sqr(group, t4, t5, ctx)
  1425. || !group->meth->field_mul(group, t4, t4, t2, ctx)
  1426. || !group->meth->field_mul(group, t1, t1, t3, ctx)
  1427. || !BN_mod_lshift1_quick(t1, t1, group->field)
  1428. /* r->Z coord output */
  1429. || !BN_mod_add_quick(r->Z, t4, t1, group->field))
  1430. goto err;
  1431. ret = 1;
  1432. err:
  1433. BN_CTX_end(ctx);
  1434. return ret;
  1435. }
  1436. /*-
  1437. * Input:
  1438. * - s, r: projective (homogeneous) coordinates
  1439. * - p: affine coordinates
  1440. *
  1441. * Output:
  1442. * - r := (x,y): affine coordinates
  1443. *
  1444. * Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
  1445. * Elliptic Curves and Side-Channel Attacks", modified to work in mixed
  1446. * projective coords, i.e. p is affine and (r,s) in projective (homogeneous)
  1447. * coords, and return r in affine coordinates.
  1448. *
  1449. * X4 = two*Y1*X2*Z3*Z2;
  1450. * Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2);
  1451. * Z4 = two*Y1*Z3*SQR(Z2);
  1452. *
  1453. * Z4 != 0 because:
  1454. * - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch);
  1455. * - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch);
  1456. * - Y1==0 implies p has order 2, so either r or s are infinity and handled by
  1457. * one of the BN_is_zero(...) branches.
  1458. */
  1459. int ossl_ec_GFp_simple_ladder_post(const EC_GROUP *group,
  1460. EC_POINT *r, EC_POINT *s,
  1461. EC_POINT *p, BN_CTX *ctx)
  1462. {
  1463. int ret = 0;
  1464. BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
  1465. if (BN_is_zero(r->Z))
  1466. return EC_POINT_set_to_infinity(group, r);
  1467. if (BN_is_zero(s->Z)) {
  1468. if (!EC_POINT_copy(r, p)
  1469. || !EC_POINT_invert(group, r, ctx))
  1470. return 0;
  1471. return 1;
  1472. }
  1473. BN_CTX_start(ctx);
  1474. t0 = BN_CTX_get(ctx);
  1475. t1 = BN_CTX_get(ctx);
  1476. t2 = BN_CTX_get(ctx);
  1477. t3 = BN_CTX_get(ctx);
  1478. t4 = BN_CTX_get(ctx);
  1479. t5 = BN_CTX_get(ctx);
  1480. t6 = BN_CTX_get(ctx);
  1481. if (t6 == NULL
  1482. || !BN_mod_lshift1_quick(t4, p->Y, group->field)
  1483. || !group->meth->field_mul(group, t6, r->X, t4, ctx)
  1484. || !group->meth->field_mul(group, t6, s->Z, t6, ctx)
  1485. || !group->meth->field_mul(group, t5, r->Z, t6, ctx)
  1486. || !BN_mod_lshift1_quick(t1, group->b, group->field)
  1487. || !group->meth->field_mul(group, t1, s->Z, t1, ctx)
  1488. || !group->meth->field_sqr(group, t3, r->Z, ctx)
  1489. || !group->meth->field_mul(group, t2, t3, t1, ctx)
  1490. || !group->meth->field_mul(group, t6, r->Z, group->a, ctx)
  1491. || !group->meth->field_mul(group, t1, p->X, r->X, ctx)
  1492. || !BN_mod_add_quick(t1, t1, t6, group->field)
  1493. || !group->meth->field_mul(group, t1, s->Z, t1, ctx)
  1494. || !group->meth->field_mul(group, t0, p->X, r->Z, ctx)
  1495. || !BN_mod_add_quick(t6, r->X, t0, group->field)
  1496. || !group->meth->field_mul(group, t6, t6, t1, ctx)
  1497. || !BN_mod_add_quick(t6, t6, t2, group->field)
  1498. || !BN_mod_sub_quick(t0, t0, r->X, group->field)
  1499. || !group->meth->field_sqr(group, t0, t0, ctx)
  1500. || !group->meth->field_mul(group, t0, t0, s->X, ctx)
  1501. || !BN_mod_sub_quick(t0, t6, t0, group->field)
  1502. || !group->meth->field_mul(group, t1, s->Z, t4, ctx)
  1503. || !group->meth->field_mul(group, t1, t3, t1, ctx)
  1504. || (group->meth->field_decode != NULL
  1505. && !group->meth->field_decode(group, t1, t1, ctx))
  1506. || !group->meth->field_inv(group, t1, t1, ctx)
  1507. || (group->meth->field_encode != NULL
  1508. && !group->meth->field_encode(group, t1, t1, ctx))
  1509. || !group->meth->field_mul(group, r->X, t5, t1, ctx)
  1510. || !group->meth->field_mul(group, r->Y, t0, t1, ctx))
  1511. goto err;
  1512. if (group->meth->field_set_to_one != NULL) {
  1513. if (!group->meth->field_set_to_one(group, r->Z, ctx))
  1514. goto err;
  1515. } else {
  1516. if (!BN_one(r->Z))
  1517. goto err;
  1518. }
  1519. r->Z_is_one = 1;
  1520. ret = 1;
  1521. err:
  1522. BN_CTX_end(ctx);
  1523. return ret;
  1524. }