ecp_smpl.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724
  1. /*
  2. * Copyright 2001-2020 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. ec_GFp_simple_group_init,
  24. ec_GFp_simple_group_finish,
  25. ec_GFp_simple_group_clear_finish,
  26. ec_GFp_simple_group_copy,
  27. ec_GFp_simple_group_set_curve,
  28. ec_GFp_simple_group_get_curve,
  29. ec_GFp_simple_group_get_degree,
  30. ec_group_simple_order_bits,
  31. ec_GFp_simple_group_check_discriminant,
  32. ec_GFp_simple_point_init,
  33. ec_GFp_simple_point_finish,
  34. ec_GFp_simple_point_clear_finish,
  35. ec_GFp_simple_point_copy,
  36. ec_GFp_simple_point_set_to_infinity,
  37. ec_GFp_simple_point_set_affine_coordinates,
  38. ec_GFp_simple_point_get_affine_coordinates,
  39. 0, 0, 0,
  40. ec_GFp_simple_add,
  41. ec_GFp_simple_dbl,
  42. ec_GFp_simple_invert,
  43. ec_GFp_simple_is_at_infinity,
  44. ec_GFp_simple_is_on_curve,
  45. ec_GFp_simple_cmp,
  46. ec_GFp_simple_make_affine,
  47. ec_GFp_simple_points_make_affine,
  48. 0 /* mul */ ,
  49. 0 /* precompute_mult */ ,
  50. 0 /* have_precompute_mult */ ,
  51. ec_GFp_simple_field_mul,
  52. ec_GFp_simple_field_sqr,
  53. 0 /* field_div */ ,
  54. ec_GFp_simple_field_inv,
  55. 0 /* field_encode */ ,
  56. 0 /* field_decode */ ,
  57. 0, /* field_set_to_one */
  58. ec_key_simple_priv2oct,
  59. ec_key_simple_oct2priv,
  60. 0, /* set private */
  61. ec_key_simple_generate_key,
  62. ec_key_simple_check_key,
  63. ec_key_simple_generate_public_key,
  64. 0, /* keycopy */
  65. 0, /* keyfinish */
  66. ecdh_simple_compute_key,
  67. ecdsa_simple_sign_setup,
  68. ecdsa_simple_sign_sig,
  69. ecdsa_simple_verify_sig,
  70. 0, /* field_inverse_mod_ord */
  71. ec_GFp_simple_blind_coordinates,
  72. ec_GFp_simple_ladder_pre,
  73. ec_GFp_simple_ladder_step,
  74. 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 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 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 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 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 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. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, 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) {
  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)
  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 ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a,
  178. 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) {
  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 ec_GFp_simple_group_get_degree(const EC_GROUP *group)
  218. {
  219. return BN_num_bits(group->field);
  220. }
  221. int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx)
  222. {
  223. int ret = 0;
  224. BIGNUM *a, *b, *order, *tmp_1, *tmp_2;
  225. const BIGNUM *p = group->field;
  226. BN_CTX *new_ctx = NULL;
  227. if (ctx == NULL) {
  228. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  229. if (ctx == NULL) {
  230. ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT,
  231. ERR_R_MALLOC_FAILURE);
  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) {
  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 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 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 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 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 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 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 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 != 0) {
  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 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. ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES,
  438. ERR_R_PASSED_NULL_PARAMETER);
  439. return 0;
  440. }
  441. return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y,
  442. BN_value_one(), ctx);
  443. }
  444. int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
  445. const EC_POINT *point,
  446. BIGNUM *x, BIGNUM *y,
  447. BN_CTX *ctx)
  448. {
  449. BN_CTX *new_ctx = NULL;
  450. BIGNUM *Z, *Z_1, *Z_2, *Z_3;
  451. const BIGNUM *Z_;
  452. int ret = 0;
  453. if (EC_POINT_is_at_infinity(group, point)) {
  454. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  455. EC_R_POINT_AT_INFINITY);
  456. return 0;
  457. }
  458. if (ctx == NULL) {
  459. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  460. if (ctx == NULL)
  461. return 0;
  462. }
  463. BN_CTX_start(ctx);
  464. Z = BN_CTX_get(ctx);
  465. Z_1 = BN_CTX_get(ctx);
  466. Z_2 = BN_CTX_get(ctx);
  467. Z_3 = BN_CTX_get(ctx);
  468. if (Z_3 == NULL)
  469. goto err;
  470. /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
  471. if (group->meth->field_decode) {
  472. if (!group->meth->field_decode(group, Z, point->Z, ctx))
  473. goto err;
  474. Z_ = Z;
  475. } else {
  476. Z_ = point->Z;
  477. }
  478. if (BN_is_one(Z_)) {
  479. if (group->meth->field_decode) {
  480. if (x != NULL) {
  481. if (!group->meth->field_decode(group, x, point->X, ctx))
  482. goto err;
  483. }
  484. if (y != NULL) {
  485. if (!group->meth->field_decode(group, y, point->Y, ctx))
  486. goto err;
  487. }
  488. } else {
  489. if (x != NULL) {
  490. if (!BN_copy(x, point->X))
  491. goto err;
  492. }
  493. if (y != NULL) {
  494. if (!BN_copy(y, point->Y))
  495. goto err;
  496. }
  497. }
  498. } else {
  499. if (!group->meth->field_inv(group, Z_1, Z_, ctx)) {
  500. ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES,
  501. ERR_R_BN_LIB);
  502. goto err;
  503. }
  504. if (group->meth->field_encode == 0) {
  505. /* field_sqr works on standard representation */
  506. if (!group->meth->field_sqr(group, Z_2, Z_1, ctx))
  507. goto err;
  508. } else {
  509. if (!BN_mod_sqr(Z_2, Z_1, group->field, ctx))
  510. goto err;
  511. }
  512. if (x != NULL) {
  513. /*
  514. * in the Montgomery case, field_mul will cancel out Montgomery
  515. * factor in X:
  516. */
  517. if (!group->meth->field_mul(group, x, point->X, Z_2, ctx))
  518. goto err;
  519. }
  520. if (y != NULL) {
  521. if (group->meth->field_encode == 0) {
  522. /*
  523. * field_mul works on standard representation
  524. */
  525. if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx))
  526. goto err;
  527. } else {
  528. if (!BN_mod_mul(Z_3, Z_2, Z_1, group->field, ctx))
  529. goto err;
  530. }
  531. /*
  532. * in the Montgomery case, field_mul will cancel out Montgomery
  533. * factor in Y:
  534. */
  535. if (!group->meth->field_mul(group, y, point->Y, Z_3, ctx))
  536. goto err;
  537. }
  538. }
  539. ret = 1;
  540. err:
  541. BN_CTX_end(ctx);
  542. BN_CTX_free(new_ctx);
  543. return ret;
  544. }
  545. int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  546. const EC_POINT *b, BN_CTX *ctx)
  547. {
  548. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  549. const BIGNUM *, BN_CTX *);
  550. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  551. const BIGNUM *p;
  552. BN_CTX *new_ctx = NULL;
  553. BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6;
  554. int ret = 0;
  555. if (a == b)
  556. return EC_POINT_dbl(group, r, a, ctx);
  557. if (EC_POINT_is_at_infinity(group, a))
  558. return EC_POINT_copy(r, b);
  559. if (EC_POINT_is_at_infinity(group, b))
  560. return EC_POINT_copy(r, a);
  561. field_mul = group->meth->field_mul;
  562. field_sqr = group->meth->field_sqr;
  563. p = group->field;
  564. if (ctx == NULL) {
  565. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  566. if (ctx == NULL)
  567. return 0;
  568. }
  569. BN_CTX_start(ctx);
  570. n0 = BN_CTX_get(ctx);
  571. n1 = BN_CTX_get(ctx);
  572. n2 = BN_CTX_get(ctx);
  573. n3 = BN_CTX_get(ctx);
  574. n4 = BN_CTX_get(ctx);
  575. n5 = BN_CTX_get(ctx);
  576. n6 = BN_CTX_get(ctx);
  577. if (n6 == NULL)
  578. goto end;
  579. /*
  580. * Note that in this function we must not read components of 'a' or 'b'
  581. * once we have written the corresponding components of 'r'. ('r' might
  582. * be one of 'a' or 'b'.)
  583. */
  584. /* n1, n2 */
  585. if (b->Z_is_one) {
  586. if (!BN_copy(n1, a->X))
  587. goto end;
  588. if (!BN_copy(n2, a->Y))
  589. goto end;
  590. /* n1 = X_a */
  591. /* n2 = Y_a */
  592. } else {
  593. if (!field_sqr(group, n0, b->Z, ctx))
  594. goto end;
  595. if (!field_mul(group, n1, a->X, n0, ctx))
  596. goto end;
  597. /* n1 = X_a * Z_b^2 */
  598. if (!field_mul(group, n0, n0, b->Z, ctx))
  599. goto end;
  600. if (!field_mul(group, n2, a->Y, n0, ctx))
  601. goto end;
  602. /* n2 = Y_a * Z_b^3 */
  603. }
  604. /* n3, n4 */
  605. if (a->Z_is_one) {
  606. if (!BN_copy(n3, b->X))
  607. goto end;
  608. if (!BN_copy(n4, b->Y))
  609. goto end;
  610. /* n3 = X_b */
  611. /* n4 = Y_b */
  612. } else {
  613. if (!field_sqr(group, n0, a->Z, ctx))
  614. goto end;
  615. if (!field_mul(group, n3, b->X, n0, ctx))
  616. goto end;
  617. /* n3 = X_b * Z_a^2 */
  618. if (!field_mul(group, n0, n0, a->Z, ctx))
  619. goto end;
  620. if (!field_mul(group, n4, b->Y, n0, ctx))
  621. goto end;
  622. /* n4 = Y_b * Z_a^3 */
  623. }
  624. /* n5, n6 */
  625. if (!BN_mod_sub_quick(n5, n1, n3, p))
  626. goto end;
  627. if (!BN_mod_sub_quick(n6, n2, n4, p))
  628. goto end;
  629. /* n5 = n1 - n3 */
  630. /* n6 = n2 - n4 */
  631. if (BN_is_zero(n5)) {
  632. if (BN_is_zero(n6)) {
  633. /* a is the same point as b */
  634. BN_CTX_end(ctx);
  635. ret = EC_POINT_dbl(group, r, a, ctx);
  636. ctx = NULL;
  637. goto end;
  638. } else {
  639. /* a is the inverse of b */
  640. BN_zero(r->Z);
  641. r->Z_is_one = 0;
  642. ret = 1;
  643. goto end;
  644. }
  645. }
  646. /* 'n7', 'n8' */
  647. if (!BN_mod_add_quick(n1, n1, n3, p))
  648. goto end;
  649. if (!BN_mod_add_quick(n2, n2, n4, p))
  650. goto end;
  651. /* 'n7' = n1 + n3 */
  652. /* 'n8' = n2 + n4 */
  653. /* Z_r */
  654. if (a->Z_is_one && b->Z_is_one) {
  655. if (!BN_copy(r->Z, n5))
  656. goto end;
  657. } else {
  658. if (a->Z_is_one) {
  659. if (!BN_copy(n0, b->Z))
  660. goto end;
  661. } else if (b->Z_is_one) {
  662. if (!BN_copy(n0, a->Z))
  663. goto end;
  664. } else {
  665. if (!field_mul(group, n0, a->Z, b->Z, ctx))
  666. goto end;
  667. }
  668. if (!field_mul(group, r->Z, n0, n5, ctx))
  669. goto end;
  670. }
  671. r->Z_is_one = 0;
  672. /* Z_r = Z_a * Z_b * n5 */
  673. /* X_r */
  674. if (!field_sqr(group, n0, n6, ctx))
  675. goto end;
  676. if (!field_sqr(group, n4, n5, ctx))
  677. goto end;
  678. if (!field_mul(group, n3, n1, n4, ctx))
  679. goto end;
  680. if (!BN_mod_sub_quick(r->X, n0, n3, p))
  681. goto end;
  682. /* X_r = n6^2 - n5^2 * 'n7' */
  683. /* 'n9' */
  684. if (!BN_mod_lshift1_quick(n0, r->X, p))
  685. goto end;
  686. if (!BN_mod_sub_quick(n0, n3, n0, p))
  687. goto end;
  688. /* n9 = n5^2 * 'n7' - 2 * X_r */
  689. /* Y_r */
  690. if (!field_mul(group, n0, n0, n6, ctx))
  691. goto end;
  692. if (!field_mul(group, n5, n4, n5, ctx))
  693. goto end; /* now n5 is n5^3 */
  694. if (!field_mul(group, n1, n2, n5, ctx))
  695. goto end;
  696. if (!BN_mod_sub_quick(n0, n0, n1, p))
  697. goto end;
  698. if (BN_is_odd(n0))
  699. if (!BN_add(n0, n0, p))
  700. goto end;
  701. /* now 0 <= n0 < 2*p, and n0 is even */
  702. if (!BN_rshift1(r->Y, n0))
  703. goto end;
  704. /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */
  705. ret = 1;
  706. end:
  707. BN_CTX_end(ctx);
  708. BN_CTX_free(new_ctx);
  709. return ret;
  710. }
  711. int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
  712. BN_CTX *ctx)
  713. {
  714. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  715. const BIGNUM *, BN_CTX *);
  716. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  717. const BIGNUM *p;
  718. BN_CTX *new_ctx = NULL;
  719. BIGNUM *n0, *n1, *n2, *n3;
  720. int ret = 0;
  721. if (EC_POINT_is_at_infinity(group, a)) {
  722. BN_zero(r->Z);
  723. r->Z_is_one = 0;
  724. return 1;
  725. }
  726. field_mul = group->meth->field_mul;
  727. field_sqr = group->meth->field_sqr;
  728. p = group->field;
  729. if (ctx == NULL) {
  730. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  731. if (ctx == NULL)
  732. return 0;
  733. }
  734. BN_CTX_start(ctx);
  735. n0 = BN_CTX_get(ctx);
  736. n1 = BN_CTX_get(ctx);
  737. n2 = BN_CTX_get(ctx);
  738. n3 = BN_CTX_get(ctx);
  739. if (n3 == NULL)
  740. goto err;
  741. /*
  742. * Note that in this function we must not read components of 'a' once we
  743. * have written the corresponding components of 'r'. ('r' might the same
  744. * as 'a'.)
  745. */
  746. /* n1 */
  747. if (a->Z_is_one) {
  748. if (!field_sqr(group, n0, a->X, ctx))
  749. goto err;
  750. if (!BN_mod_lshift1_quick(n1, n0, p))
  751. goto err;
  752. if (!BN_mod_add_quick(n0, n0, n1, p))
  753. goto err;
  754. if (!BN_mod_add_quick(n1, n0, group->a, p))
  755. goto err;
  756. /* n1 = 3 * X_a^2 + a_curve */
  757. } else if (group->a_is_minus3) {
  758. if (!field_sqr(group, n1, a->Z, ctx))
  759. goto err;
  760. if (!BN_mod_add_quick(n0, a->X, n1, p))
  761. goto err;
  762. if (!BN_mod_sub_quick(n2, a->X, n1, p))
  763. goto err;
  764. if (!field_mul(group, n1, n0, n2, ctx))
  765. goto err;
  766. if (!BN_mod_lshift1_quick(n0, n1, p))
  767. goto err;
  768. if (!BN_mod_add_quick(n1, n0, n1, p))
  769. goto err;
  770. /*-
  771. * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2)
  772. * = 3 * X_a^2 - 3 * Z_a^4
  773. */
  774. } else {
  775. if (!field_sqr(group, n0, a->X, ctx))
  776. goto err;
  777. if (!BN_mod_lshift1_quick(n1, n0, p))
  778. goto err;
  779. if (!BN_mod_add_quick(n0, n0, n1, p))
  780. goto err;
  781. if (!field_sqr(group, n1, a->Z, ctx))
  782. goto err;
  783. if (!field_sqr(group, n1, n1, ctx))
  784. goto err;
  785. if (!field_mul(group, n1, n1, group->a, ctx))
  786. goto err;
  787. if (!BN_mod_add_quick(n1, n1, n0, p))
  788. goto err;
  789. /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */
  790. }
  791. /* Z_r */
  792. if (a->Z_is_one) {
  793. if (!BN_copy(n0, a->Y))
  794. goto err;
  795. } else {
  796. if (!field_mul(group, n0, a->Y, a->Z, ctx))
  797. goto err;
  798. }
  799. if (!BN_mod_lshift1_quick(r->Z, n0, p))
  800. goto err;
  801. r->Z_is_one = 0;
  802. /* Z_r = 2 * Y_a * Z_a */
  803. /* n2 */
  804. if (!field_sqr(group, n3, a->Y, ctx))
  805. goto err;
  806. if (!field_mul(group, n2, a->X, n3, ctx))
  807. goto err;
  808. if (!BN_mod_lshift_quick(n2, n2, 2, p))
  809. goto err;
  810. /* n2 = 4 * X_a * Y_a^2 */
  811. /* X_r */
  812. if (!BN_mod_lshift1_quick(n0, n2, p))
  813. goto err;
  814. if (!field_sqr(group, r->X, n1, ctx))
  815. goto err;
  816. if (!BN_mod_sub_quick(r->X, r->X, n0, p))
  817. goto err;
  818. /* X_r = n1^2 - 2 * n2 */
  819. /* n3 */
  820. if (!field_sqr(group, n0, n3, ctx))
  821. goto err;
  822. if (!BN_mod_lshift_quick(n3, n0, 3, p))
  823. goto err;
  824. /* n3 = 8 * Y_a^4 */
  825. /* Y_r */
  826. if (!BN_mod_sub_quick(n0, n2, r->X, p))
  827. goto err;
  828. if (!field_mul(group, n0, n1, n0, ctx))
  829. goto err;
  830. if (!BN_mod_sub_quick(r->Y, n0, n3, p))
  831. goto err;
  832. /* Y_r = n1 * (n2 - X_r) - n3 */
  833. ret = 1;
  834. err:
  835. BN_CTX_end(ctx);
  836. BN_CTX_free(new_ctx);
  837. return ret;
  838. }
  839. int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx)
  840. {
  841. if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(point->Y))
  842. /* point is its own inverse */
  843. return 1;
  844. return BN_usub(point->Y, group->field, point->Y);
  845. }
  846. int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point)
  847. {
  848. return BN_is_zero(point->Z);
  849. }
  850. int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
  851. BN_CTX *ctx)
  852. {
  853. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  854. const BIGNUM *, BN_CTX *);
  855. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  856. const BIGNUM *p;
  857. BN_CTX *new_ctx = NULL;
  858. BIGNUM *rh, *tmp, *Z4, *Z6;
  859. int ret = -1;
  860. if (EC_POINT_is_at_infinity(group, point))
  861. return 1;
  862. field_mul = group->meth->field_mul;
  863. field_sqr = group->meth->field_sqr;
  864. p = group->field;
  865. if (ctx == NULL) {
  866. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  867. if (ctx == NULL)
  868. return -1;
  869. }
  870. BN_CTX_start(ctx);
  871. rh = BN_CTX_get(ctx);
  872. tmp = BN_CTX_get(ctx);
  873. Z4 = BN_CTX_get(ctx);
  874. Z6 = BN_CTX_get(ctx);
  875. if (Z6 == NULL)
  876. goto err;
  877. /*-
  878. * We have a curve defined by a Weierstrass equation
  879. * y^2 = x^3 + a*x + b.
  880. * The point to consider is given in Jacobian projective coordinates
  881. * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3).
  882. * Substituting this and multiplying by Z^6 transforms the above equation into
  883. * Y^2 = X^3 + a*X*Z^4 + b*Z^6.
  884. * To test this, we add up the right-hand side in 'rh'.
  885. */
  886. /* rh := X^2 */
  887. if (!field_sqr(group, rh, point->X, ctx))
  888. goto err;
  889. if (!point->Z_is_one) {
  890. if (!field_sqr(group, tmp, point->Z, ctx))
  891. goto err;
  892. if (!field_sqr(group, Z4, tmp, ctx))
  893. goto err;
  894. if (!field_mul(group, Z6, Z4, tmp, ctx))
  895. goto err;
  896. /* rh := (rh + a*Z^4)*X */
  897. if (group->a_is_minus3) {
  898. if (!BN_mod_lshift1_quick(tmp, Z4, p))
  899. goto err;
  900. if (!BN_mod_add_quick(tmp, tmp, Z4, p))
  901. goto err;
  902. if (!BN_mod_sub_quick(rh, rh, tmp, p))
  903. goto err;
  904. if (!field_mul(group, rh, rh, point->X, ctx))
  905. goto err;
  906. } else {
  907. if (!field_mul(group, tmp, Z4, group->a, ctx))
  908. goto err;
  909. if (!BN_mod_add_quick(rh, rh, tmp, p))
  910. goto err;
  911. if (!field_mul(group, rh, rh, point->X, ctx))
  912. goto err;
  913. }
  914. /* rh := rh + b*Z^6 */
  915. if (!field_mul(group, tmp, group->b, Z6, ctx))
  916. goto err;
  917. if (!BN_mod_add_quick(rh, rh, tmp, p))
  918. goto err;
  919. } else {
  920. /* point->Z_is_one */
  921. /* rh := (rh + a)*X */
  922. if (!BN_mod_add_quick(rh, rh, group->a, p))
  923. goto err;
  924. if (!field_mul(group, rh, rh, point->X, ctx))
  925. goto err;
  926. /* rh := rh + b */
  927. if (!BN_mod_add_quick(rh, rh, group->b, p))
  928. goto err;
  929. }
  930. /* 'lh' := Y^2 */
  931. if (!field_sqr(group, tmp, point->Y, ctx))
  932. goto err;
  933. ret = (0 == BN_ucmp(tmp, rh));
  934. err:
  935. BN_CTX_end(ctx);
  936. BN_CTX_free(new_ctx);
  937. return ret;
  938. }
  939. int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a,
  940. const EC_POINT *b, BN_CTX *ctx)
  941. {
  942. /*-
  943. * return values:
  944. * -1 error
  945. * 0 equal (in affine coordinates)
  946. * 1 not equal
  947. */
  948. int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *,
  949. const BIGNUM *, BN_CTX *);
  950. int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *);
  951. BN_CTX *new_ctx = NULL;
  952. BIGNUM *tmp1, *tmp2, *Za23, *Zb23;
  953. const BIGNUM *tmp1_, *tmp2_;
  954. int ret = -1;
  955. if (EC_POINT_is_at_infinity(group, a)) {
  956. return EC_POINT_is_at_infinity(group, b) ? 0 : 1;
  957. }
  958. if (EC_POINT_is_at_infinity(group, b))
  959. return 1;
  960. if (a->Z_is_one && b->Z_is_one) {
  961. return ((BN_cmp(a->X, b->X) == 0) && BN_cmp(a->Y, b->Y) == 0) ? 0 : 1;
  962. }
  963. field_mul = group->meth->field_mul;
  964. field_sqr = group->meth->field_sqr;
  965. if (ctx == NULL) {
  966. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  967. if (ctx == NULL)
  968. return -1;
  969. }
  970. BN_CTX_start(ctx);
  971. tmp1 = BN_CTX_get(ctx);
  972. tmp2 = BN_CTX_get(ctx);
  973. Za23 = BN_CTX_get(ctx);
  974. Zb23 = BN_CTX_get(ctx);
  975. if (Zb23 == NULL)
  976. goto end;
  977. /*-
  978. * We have to decide whether
  979. * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3),
  980. * or equivalently, whether
  981. * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3).
  982. */
  983. if (!b->Z_is_one) {
  984. if (!field_sqr(group, Zb23, b->Z, ctx))
  985. goto end;
  986. if (!field_mul(group, tmp1, a->X, Zb23, ctx))
  987. goto end;
  988. tmp1_ = tmp1;
  989. } else
  990. tmp1_ = a->X;
  991. if (!a->Z_is_one) {
  992. if (!field_sqr(group, Za23, a->Z, ctx))
  993. goto end;
  994. if (!field_mul(group, tmp2, b->X, Za23, ctx))
  995. goto end;
  996. tmp2_ = tmp2;
  997. } else
  998. tmp2_ = b->X;
  999. /* compare X_a*Z_b^2 with X_b*Z_a^2 */
  1000. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1001. ret = 1; /* points differ */
  1002. goto end;
  1003. }
  1004. if (!b->Z_is_one) {
  1005. if (!field_mul(group, Zb23, Zb23, b->Z, ctx))
  1006. goto end;
  1007. if (!field_mul(group, tmp1, a->Y, Zb23, ctx))
  1008. goto end;
  1009. /* tmp1_ = tmp1 */
  1010. } else
  1011. tmp1_ = a->Y;
  1012. if (!a->Z_is_one) {
  1013. if (!field_mul(group, Za23, Za23, a->Z, ctx))
  1014. goto end;
  1015. if (!field_mul(group, tmp2, b->Y, Za23, ctx))
  1016. goto end;
  1017. /* tmp2_ = tmp2 */
  1018. } else
  1019. tmp2_ = b->Y;
  1020. /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */
  1021. if (BN_cmp(tmp1_, tmp2_) != 0) {
  1022. ret = 1; /* points differ */
  1023. goto end;
  1024. }
  1025. /* points are equal */
  1026. ret = 0;
  1027. end:
  1028. BN_CTX_end(ctx);
  1029. BN_CTX_free(new_ctx);
  1030. return ret;
  1031. }
  1032. int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
  1033. BN_CTX *ctx)
  1034. {
  1035. BN_CTX *new_ctx = NULL;
  1036. BIGNUM *x, *y;
  1037. int ret = 0;
  1038. if (point->Z_is_one || EC_POINT_is_at_infinity(group, point))
  1039. return 1;
  1040. if (ctx == NULL) {
  1041. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  1042. if (ctx == NULL)
  1043. return 0;
  1044. }
  1045. BN_CTX_start(ctx);
  1046. x = BN_CTX_get(ctx);
  1047. y = BN_CTX_get(ctx);
  1048. if (y == NULL)
  1049. goto err;
  1050. if (!EC_POINT_get_affine_coordinates(group, point, x, y, ctx))
  1051. goto err;
  1052. if (!EC_POINT_set_affine_coordinates(group, point, x, y, ctx))
  1053. goto err;
  1054. if (!point->Z_is_one) {
  1055. ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR);
  1056. goto err;
  1057. }
  1058. ret = 1;
  1059. err:
  1060. BN_CTX_end(ctx);
  1061. BN_CTX_free(new_ctx);
  1062. return ret;
  1063. }
  1064. int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
  1065. EC_POINT *points[], BN_CTX *ctx)
  1066. {
  1067. BN_CTX *new_ctx = NULL;
  1068. BIGNUM *tmp, *tmp_Z;
  1069. BIGNUM **prod_Z = NULL;
  1070. size_t i;
  1071. int ret = 0;
  1072. if (num == 0)
  1073. return 1;
  1074. if (ctx == NULL) {
  1075. ctx = new_ctx = BN_CTX_new_ex(group->libctx);
  1076. if (ctx == NULL)
  1077. return 0;
  1078. }
  1079. BN_CTX_start(ctx);
  1080. tmp = BN_CTX_get(ctx);
  1081. tmp_Z = BN_CTX_get(ctx);
  1082. if (tmp_Z == NULL)
  1083. goto err;
  1084. prod_Z = OPENSSL_malloc(num * sizeof(prod_Z[0]));
  1085. if (prod_Z == NULL)
  1086. goto err;
  1087. for (i = 0; i < num; i++) {
  1088. prod_Z[i] = BN_new();
  1089. if (prod_Z[i] == NULL)
  1090. goto err;
  1091. }
  1092. /*
  1093. * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z,
  1094. * skipping any zero-valued inputs (pretend that they're 1).
  1095. */
  1096. if (!BN_is_zero(points[0]->Z)) {
  1097. if (!BN_copy(prod_Z[0], points[0]->Z))
  1098. goto err;
  1099. } else {
  1100. if (group->meth->field_set_to_one != 0) {
  1101. if (!group->meth->field_set_to_one(group, prod_Z[0], ctx))
  1102. goto err;
  1103. } else {
  1104. if (!BN_one(prod_Z[0]))
  1105. goto err;
  1106. }
  1107. }
  1108. for (i = 1; i < num; i++) {
  1109. if (!BN_is_zero(points[i]->Z)) {
  1110. if (!group->
  1111. meth->field_mul(group, prod_Z[i], prod_Z[i - 1], points[i]->Z,
  1112. ctx))
  1113. goto err;
  1114. } else {
  1115. if (!BN_copy(prod_Z[i], prod_Z[i - 1]))
  1116. goto err;
  1117. }
  1118. }
  1119. /*
  1120. * Now use a single explicit inversion to replace every non-zero
  1121. * points[i]->Z by its inverse.
  1122. */
  1123. if (!group->meth->field_inv(group, tmp, prod_Z[num - 1], ctx)) {
  1124. ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB);
  1125. goto err;
  1126. }
  1127. if (group->meth->field_encode != 0) {
  1128. /*
  1129. * In the Montgomery case, we just turned R*H (representing H) into
  1130. * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to
  1131. * multiply by the Montgomery factor twice.
  1132. */
  1133. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1134. goto err;
  1135. if (!group->meth->field_encode(group, tmp, tmp, ctx))
  1136. goto err;
  1137. }
  1138. for (i = num - 1; i > 0; --i) {
  1139. /*
  1140. * Loop invariant: tmp is the product of the inverses of points[0]->Z
  1141. * .. points[i]->Z (zero-valued inputs skipped).
  1142. */
  1143. if (!BN_is_zero(points[i]->Z)) {
  1144. /*
  1145. * Set tmp_Z to the inverse of points[i]->Z (as product of Z
  1146. * inverses 0 .. i, Z values 0 .. i - 1).
  1147. */
  1148. if (!group->
  1149. meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx))
  1150. goto err;
  1151. /*
  1152. * Update tmp to satisfy the loop invariant for i - 1.
  1153. */
  1154. if (!group->meth->field_mul(group, tmp, tmp, points[i]->Z, ctx))
  1155. goto err;
  1156. /* Replace points[i]->Z by its inverse. */
  1157. if (!BN_copy(points[i]->Z, tmp_Z))
  1158. goto err;
  1159. }
  1160. }
  1161. if (!BN_is_zero(points[0]->Z)) {
  1162. /* Replace points[0]->Z by its inverse. */
  1163. if (!BN_copy(points[0]->Z, tmp))
  1164. goto err;
  1165. }
  1166. /* Finally, fix up the X and Y coordinates for all points. */
  1167. for (i = 0; i < num; i++) {
  1168. EC_POINT *p = points[i];
  1169. if (!BN_is_zero(p->Z)) {
  1170. /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */
  1171. if (!group->meth->field_sqr(group, tmp, p->Z, ctx))
  1172. goto err;
  1173. if (!group->meth->field_mul(group, p->X, p->X, tmp, ctx))
  1174. goto err;
  1175. if (!group->meth->field_mul(group, tmp, tmp, p->Z, ctx))
  1176. goto err;
  1177. if (!group->meth->field_mul(group, p->Y, p->Y, tmp, ctx))
  1178. goto err;
  1179. if (group->meth->field_set_to_one != 0) {
  1180. if (!group->meth->field_set_to_one(group, p->Z, ctx))
  1181. goto err;
  1182. } else {
  1183. if (!BN_one(p->Z))
  1184. goto err;
  1185. }
  1186. p->Z_is_one = 1;
  1187. }
  1188. }
  1189. ret = 1;
  1190. err:
  1191. BN_CTX_end(ctx);
  1192. BN_CTX_free(new_ctx);
  1193. if (prod_Z != NULL) {
  1194. for (i = 0; i < num; i++) {
  1195. if (prod_Z[i] == NULL)
  1196. break;
  1197. BN_clear_free(prod_Z[i]);
  1198. }
  1199. OPENSSL_free(prod_Z);
  1200. }
  1201. return ret;
  1202. }
  1203. int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1204. const BIGNUM *b, BN_CTX *ctx)
  1205. {
  1206. return BN_mod_mul(r, a, b, group->field, ctx);
  1207. }
  1208. int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1209. BN_CTX *ctx)
  1210. {
  1211. return BN_mod_sqr(r, a, group->field, ctx);
  1212. }
  1213. /*-
  1214. * Computes the multiplicative inverse of a in GF(p), storing the result in r.
  1215. * If a is zero (or equivalent), you'll get a EC_R_CANNOT_INVERT error.
  1216. * Since we don't have a Mont structure here, SCA hardening is with blinding.
  1217. * NB: "a" must be in _decoded_ form. (i.e. field_decode must precede.)
  1218. */
  1219. int ec_GFp_simple_field_inv(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
  1220. BN_CTX *ctx)
  1221. {
  1222. BIGNUM *e = NULL;
  1223. BN_CTX *new_ctx = NULL;
  1224. int ret = 0;
  1225. if (ctx == NULL
  1226. && (ctx = new_ctx = BN_CTX_secure_new_ex(group->libctx)) == NULL)
  1227. return 0;
  1228. BN_CTX_start(ctx);
  1229. if ((e = BN_CTX_get(ctx)) == NULL)
  1230. goto err;
  1231. do {
  1232. if (!BN_priv_rand_range_ex(e, group->field, ctx))
  1233. goto err;
  1234. } while (BN_is_zero(e));
  1235. /* r := a * e */
  1236. if (!group->meth->field_mul(group, r, a, e, ctx))
  1237. goto err;
  1238. /* r := 1/(a * e) */
  1239. if (!BN_mod_inverse(r, r, group->field, ctx)) {
  1240. ECerr(EC_F_EC_GFP_SIMPLE_FIELD_INV, EC_R_CANNOT_INVERT);
  1241. goto err;
  1242. }
  1243. /* r := e/(a * e) = 1/a */
  1244. if (!group->meth->field_mul(group, r, r, e, ctx))
  1245. goto err;
  1246. ret = 1;
  1247. err:
  1248. BN_CTX_end(ctx);
  1249. BN_CTX_free(new_ctx);
  1250. return ret;
  1251. }
  1252. /*-
  1253. * Apply randomization of EC point projective coordinates:
  1254. *
  1255. * (X, Y ,Z ) = (lambda^2*X, lambda^3*Y, lambda*Z)
  1256. * lambda = [1,group->field)
  1257. *
  1258. */
  1259. int ec_GFp_simple_blind_coordinates(const EC_GROUP *group, EC_POINT *p,
  1260. BN_CTX *ctx)
  1261. {
  1262. int ret = 0;
  1263. BIGNUM *lambda = NULL;
  1264. BIGNUM *temp = NULL;
  1265. BN_CTX_start(ctx);
  1266. lambda = BN_CTX_get(ctx);
  1267. temp = BN_CTX_get(ctx);
  1268. if (temp == NULL) {
  1269. ECerr(EC_F_EC_GFP_SIMPLE_BLIND_COORDINATES, ERR_R_MALLOC_FAILURE);
  1270. goto end;
  1271. }
  1272. /*-
  1273. * Make sure lambda is not zero.
  1274. * If the RNG fails, we cannot blind but nevertheless want
  1275. * code to continue smoothly and not clobber the error stack.
  1276. */
  1277. do {
  1278. ERR_set_mark();
  1279. ret = BN_priv_rand_range_ex(lambda, group->field, ctx);
  1280. ERR_pop_to_mark();
  1281. if (ret == 0) {
  1282. ret = 1;
  1283. goto end;
  1284. }
  1285. } while (BN_is_zero(lambda));
  1286. /* if field_encode defined convert between representations */
  1287. if ((group->meth->field_encode != NULL
  1288. && !group->meth->field_encode(group, lambda, lambda, ctx))
  1289. || !group->meth->field_mul(group, p->Z, p->Z, lambda, ctx)
  1290. || !group->meth->field_sqr(group, temp, lambda, ctx)
  1291. || !group->meth->field_mul(group, p->X, p->X, temp, ctx)
  1292. || !group->meth->field_mul(group, temp, temp, lambda, ctx)
  1293. || !group->meth->field_mul(group, p->Y, p->Y, temp, ctx))
  1294. goto end;
  1295. p->Z_is_one = 0;
  1296. ret = 1;
  1297. end:
  1298. BN_CTX_end(ctx);
  1299. return ret;
  1300. }
  1301. /*-
  1302. * Input:
  1303. * - p: affine coordinates
  1304. *
  1305. * Output:
  1306. * - s := p, r := 2p: blinded projective (homogeneous) coordinates
  1307. *
  1308. * For doubling we use Formula 3 from Izu-Takagi "A fast parallel elliptic curve
  1309. * multiplication resistant against side channel attacks" appendix, described at
  1310. * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#doubling-dbl-2002-it-2
  1311. * simplified for Z1=1.
  1312. *
  1313. * Blinding uses the equivalence relation (\lambda X, \lambda Y, \lambda Z)
  1314. * for any non-zero \lambda that holds for projective (homogeneous) coords.
  1315. */
  1316. int ec_GFp_simple_ladder_pre(const EC_GROUP *group,
  1317. EC_POINT *r, EC_POINT *s,
  1318. EC_POINT *p, BN_CTX *ctx)
  1319. {
  1320. BIGNUM *t1, *t2, *t3, *t4, *t5 = NULL;
  1321. t1 = s->Z;
  1322. t2 = r->Z;
  1323. t3 = s->X;
  1324. t4 = r->X;
  1325. t5 = s->Y;
  1326. if (!p->Z_is_one /* r := 2p */
  1327. || !group->meth->field_sqr(group, t3, p->X, ctx)
  1328. || !BN_mod_sub_quick(t4, t3, group->a, group->field)
  1329. || !group->meth->field_sqr(group, t4, t4, ctx)
  1330. || !group->meth->field_mul(group, t5, p->X, group->b, ctx)
  1331. || !BN_mod_lshift_quick(t5, t5, 3, group->field)
  1332. /* r->X coord output */
  1333. || !BN_mod_sub_quick(r->X, t4, t5, group->field)
  1334. || !BN_mod_add_quick(t1, t3, group->a, group->field)
  1335. || !group->meth->field_mul(group, t2, p->X, t1, ctx)
  1336. || !BN_mod_add_quick(t2, group->b, t2, group->field)
  1337. /* r->Z coord output */
  1338. || !BN_mod_lshift_quick(r->Z, t2, 2, group->field))
  1339. return 0;
  1340. /* make sure lambda (r->Y here for storage) is not zero */
  1341. do {
  1342. if (!BN_priv_rand_range_ex(r->Y, group->field, ctx))
  1343. return 0;
  1344. } while (BN_is_zero(r->Y));
  1345. /* make sure lambda (s->Z here for storage) is not zero */
  1346. do {
  1347. if (!BN_priv_rand_range_ex(s->Z, group->field, ctx))
  1348. return 0;
  1349. } while (BN_is_zero(s->Z));
  1350. /* if field_encode defined convert between representations */
  1351. if (group->meth->field_encode != NULL
  1352. && (!group->meth->field_encode(group, r->Y, r->Y, ctx)
  1353. || !group->meth->field_encode(group, s->Z, s->Z, ctx)))
  1354. return 0;
  1355. /* blind r and s independently */
  1356. if (!group->meth->field_mul(group, r->Z, r->Z, r->Y, ctx)
  1357. || !group->meth->field_mul(group, r->X, r->X, r->Y, ctx)
  1358. || !group->meth->field_mul(group, s->X, p->X, s->Z, ctx)) /* s := p */
  1359. return 0;
  1360. r->Z_is_one = 0;
  1361. s->Z_is_one = 0;
  1362. return 1;
  1363. }
  1364. /*-
  1365. * Input:
  1366. * - s, r: projective (homogeneous) coordinates
  1367. * - p: affine coordinates
  1368. *
  1369. * Output:
  1370. * - s := r + s, r := 2r: projective (homogeneous) coordinates
  1371. *
  1372. * Differential addition-and-doubling using Eq. (9) and (10) from Izu-Takagi
  1373. * "A fast parallel elliptic curve multiplication resistant against side channel
  1374. * attacks", as described at
  1375. * https://hyperelliptic.org/EFD/g1p/auto-shortw-xz.html#ladder-mladd-2002-it-4
  1376. */
  1377. int ec_GFp_simple_ladder_step(const EC_GROUP *group,
  1378. EC_POINT *r, EC_POINT *s,
  1379. EC_POINT *p, BN_CTX *ctx)
  1380. {
  1381. int ret = 0;
  1382. BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
  1383. BN_CTX_start(ctx);
  1384. t0 = BN_CTX_get(ctx);
  1385. t1 = BN_CTX_get(ctx);
  1386. t2 = BN_CTX_get(ctx);
  1387. t3 = BN_CTX_get(ctx);
  1388. t4 = BN_CTX_get(ctx);
  1389. t5 = BN_CTX_get(ctx);
  1390. t6 = BN_CTX_get(ctx);
  1391. if (t6 == NULL
  1392. || !group->meth->field_mul(group, t6, r->X, s->X, ctx)
  1393. || !group->meth->field_mul(group, t0, r->Z, s->Z, ctx)
  1394. || !group->meth->field_mul(group, t4, r->X, s->Z, ctx)
  1395. || !group->meth->field_mul(group, t3, r->Z, s->X, ctx)
  1396. || !group->meth->field_mul(group, t5, group->a, t0, ctx)
  1397. || !BN_mod_add_quick(t5, t6, t5, group->field)
  1398. || !BN_mod_add_quick(t6, t3, t4, group->field)
  1399. || !group->meth->field_mul(group, t5, t6, t5, ctx)
  1400. || !group->meth->field_sqr(group, t0, t0, ctx)
  1401. || !BN_mod_lshift_quick(t2, group->b, 2, group->field)
  1402. || !group->meth->field_mul(group, t0, t2, t0, ctx)
  1403. || !BN_mod_lshift1_quick(t5, t5, group->field)
  1404. || !BN_mod_sub_quick(t3, t4, t3, group->field)
  1405. /* s->Z coord output */
  1406. || !group->meth->field_sqr(group, s->Z, t3, ctx)
  1407. || !group->meth->field_mul(group, t4, s->Z, p->X, ctx)
  1408. || !BN_mod_add_quick(t0, t0, t5, group->field)
  1409. /* s->X coord output */
  1410. || !BN_mod_sub_quick(s->X, t0, t4, group->field)
  1411. || !group->meth->field_sqr(group, t4, r->X, ctx)
  1412. || !group->meth->field_sqr(group, t5, r->Z, ctx)
  1413. || !group->meth->field_mul(group, t6, t5, group->a, ctx)
  1414. || !BN_mod_add_quick(t1, r->X, r->Z, group->field)
  1415. || !group->meth->field_sqr(group, t1, t1, ctx)
  1416. || !BN_mod_sub_quick(t1, t1, t4, group->field)
  1417. || !BN_mod_sub_quick(t1, t1, t5, group->field)
  1418. || !BN_mod_sub_quick(t3, t4, t6, group->field)
  1419. || !group->meth->field_sqr(group, t3, t3, ctx)
  1420. || !group->meth->field_mul(group, t0, t5, t1, ctx)
  1421. || !group->meth->field_mul(group, t0, t2, t0, ctx)
  1422. /* r->X coord output */
  1423. || !BN_mod_sub_quick(r->X, t3, t0, group->field)
  1424. || !BN_mod_add_quick(t3, t4, t6, group->field)
  1425. || !group->meth->field_sqr(group, t4, t5, ctx)
  1426. || !group->meth->field_mul(group, t4, t4, t2, ctx)
  1427. || !group->meth->field_mul(group, t1, t1, t3, ctx)
  1428. || !BN_mod_lshift1_quick(t1, t1, group->field)
  1429. /* r->Z coord output */
  1430. || !BN_mod_add_quick(r->Z, t4, t1, group->field))
  1431. goto err;
  1432. ret = 1;
  1433. err:
  1434. BN_CTX_end(ctx);
  1435. return ret;
  1436. }
  1437. /*-
  1438. * Input:
  1439. * - s, r: projective (homogeneous) coordinates
  1440. * - p: affine coordinates
  1441. *
  1442. * Output:
  1443. * - r := (x,y): affine coordinates
  1444. *
  1445. * Recovers the y-coordinate of r using Eq. (8) from Brier-Joye, "Weierstrass
  1446. * Elliptic Curves and Side-Channel Attacks", modified to work in mixed
  1447. * projective coords, i.e. p is affine and (r,s) in projective (homogeneous)
  1448. * coords, and return r in affine coordinates.
  1449. *
  1450. * X4 = two*Y1*X2*Z3*Z2;
  1451. * Y4 = two*b*Z3*SQR(Z2) + Z3*(a*Z2+X1*X2)*(X1*Z2+X2) - X3*SQR(X1*Z2-X2);
  1452. * Z4 = two*Y1*Z3*SQR(Z2);
  1453. *
  1454. * Z4 != 0 because:
  1455. * - Z2==0 implies r is at infinity (handled by the BN_is_zero(r->Z) branch);
  1456. * - Z3==0 implies s is at infinity (handled by the BN_is_zero(s->Z) branch);
  1457. * - Y1==0 implies p has order 2, so either r or s are infinity and handled by
  1458. * one of the BN_is_zero(...) branches.
  1459. */
  1460. int ec_GFp_simple_ladder_post(const EC_GROUP *group,
  1461. EC_POINT *r, EC_POINT *s,
  1462. EC_POINT *p, BN_CTX *ctx)
  1463. {
  1464. int ret = 0;
  1465. BIGNUM *t0, *t1, *t2, *t3, *t4, *t5, *t6 = NULL;
  1466. if (BN_is_zero(r->Z))
  1467. return EC_POINT_set_to_infinity(group, r);
  1468. if (BN_is_zero(s->Z)) {
  1469. if (!EC_POINT_copy(r, p)
  1470. || !EC_POINT_invert(group, r, ctx))
  1471. return 0;
  1472. return 1;
  1473. }
  1474. BN_CTX_start(ctx);
  1475. t0 = BN_CTX_get(ctx);
  1476. t1 = BN_CTX_get(ctx);
  1477. t2 = BN_CTX_get(ctx);
  1478. t3 = BN_CTX_get(ctx);
  1479. t4 = BN_CTX_get(ctx);
  1480. t5 = BN_CTX_get(ctx);
  1481. t6 = BN_CTX_get(ctx);
  1482. if (t6 == NULL
  1483. || !BN_mod_lshift1_quick(t4, p->Y, group->field)
  1484. || !group->meth->field_mul(group, t6, r->X, t4, ctx)
  1485. || !group->meth->field_mul(group, t6, s->Z, t6, ctx)
  1486. || !group->meth->field_mul(group, t5, r->Z, t6, ctx)
  1487. || !BN_mod_lshift1_quick(t1, group->b, group->field)
  1488. || !group->meth->field_mul(group, t1, s->Z, t1, ctx)
  1489. || !group->meth->field_sqr(group, t3, r->Z, ctx)
  1490. || !group->meth->field_mul(group, t2, t3, t1, ctx)
  1491. || !group->meth->field_mul(group, t6, r->Z, group->a, ctx)
  1492. || !group->meth->field_mul(group, t1, p->X, r->X, ctx)
  1493. || !BN_mod_add_quick(t1, t1, t6, group->field)
  1494. || !group->meth->field_mul(group, t1, s->Z, t1, ctx)
  1495. || !group->meth->field_mul(group, t0, p->X, r->Z, ctx)
  1496. || !BN_mod_add_quick(t6, r->X, t0, group->field)
  1497. || !group->meth->field_mul(group, t6, t6, t1, ctx)
  1498. || !BN_mod_add_quick(t6, t6, t2, group->field)
  1499. || !BN_mod_sub_quick(t0, t0, r->X, group->field)
  1500. || !group->meth->field_sqr(group, t0, t0, ctx)
  1501. || !group->meth->field_mul(group, t0, t0, s->X, ctx)
  1502. || !BN_mod_sub_quick(t0, t6, t0, group->field)
  1503. || !group->meth->field_mul(group, t1, s->Z, t4, ctx)
  1504. || !group->meth->field_mul(group, t1, t3, t1, ctx)
  1505. || (group->meth->field_decode != NULL
  1506. && !group->meth->field_decode(group, t1, t1, ctx))
  1507. || !group->meth->field_inv(group, t1, t1, ctx)
  1508. || (group->meth->field_encode != NULL
  1509. && !group->meth->field_encode(group, t1, t1, ctx))
  1510. || !group->meth->field_mul(group, r->X, t5, t1, ctx)
  1511. || !group->meth->field_mul(group, r->Y, t0, t1, ctx))
  1512. goto err;
  1513. if (group->meth->field_set_to_one != NULL) {
  1514. if (!group->meth->field_set_to_one(group, r->Z, ctx))
  1515. goto err;
  1516. } else {
  1517. if (!BN_one(r->Z))
  1518. goto err;
  1519. }
  1520. r->Z_is_one = 1;
  1521. ret = 1;
  1522. err:
  1523. BN_CTX_end(ctx);
  1524. return ret;
  1525. }