uECC.c 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669
  1. /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
  2. #include "uECC.h"
  3. #include "uECC_vli.h"
  4. #ifndef uECC_RNG_MAX_TRIES
  5. #define uECC_RNG_MAX_TRIES 64
  6. #endif
  7. #if uECC_ENABLE_VLI_API
  8. #define uECC_VLI_API
  9. #else
  10. #define uECC_VLI_API static
  11. #endif
  12. #if (uECC_PLATFORM == uECC_avr) || \
  13. (uECC_PLATFORM == uECC_arm) || \
  14. (uECC_PLATFORM == uECC_arm_thumb) || \
  15. (uECC_PLATFORM == uECC_arm_thumb2)
  16. #define CONCATX(a, ...) a ## __VA_ARGS__
  17. #define CONCAT(a, ...) CONCATX(a, __VA_ARGS__)
  18. #define STRX(a) #a
  19. #define STR(a) STRX(a)
  20. #define EVAL(...) EVAL1(EVAL1(EVAL1(EVAL1(__VA_ARGS__))))
  21. #define EVAL1(...) EVAL2(EVAL2(EVAL2(EVAL2(__VA_ARGS__))))
  22. #define EVAL2(...) EVAL3(EVAL3(EVAL3(EVAL3(__VA_ARGS__))))
  23. #define EVAL3(...) EVAL4(EVAL4(EVAL4(EVAL4(__VA_ARGS__))))
  24. #define EVAL4(...) __VA_ARGS__
  25. #define DEC_1 0
  26. #define DEC_2 1
  27. #define DEC_3 2
  28. #define DEC_4 3
  29. #define DEC_5 4
  30. #define DEC_6 5
  31. #define DEC_7 6
  32. #define DEC_8 7
  33. #define DEC_9 8
  34. #define DEC_10 9
  35. #define DEC_11 10
  36. #define DEC_12 11
  37. #define DEC_13 12
  38. #define DEC_14 13
  39. #define DEC_15 14
  40. #define DEC_16 15
  41. #define DEC_17 16
  42. #define DEC_18 17
  43. #define DEC_19 18
  44. #define DEC_20 19
  45. #define DEC_21 20
  46. #define DEC_22 21
  47. #define DEC_23 22
  48. #define DEC_24 23
  49. #define DEC_25 24
  50. #define DEC_26 25
  51. #define DEC_27 26
  52. #define DEC_28 27
  53. #define DEC_29 28
  54. #define DEC_30 29
  55. #define DEC_31 30
  56. #define DEC_32 31
  57. #define DEC(N) CONCAT(DEC_, N)
  58. #define SECOND_ARG(_, val, ...) val
  59. #define SOME_CHECK_0 ~, 0
  60. #define GET_SECOND_ARG(...) SECOND_ARG(__VA_ARGS__, SOME,)
  61. #define SOME_OR_0(N) GET_SECOND_ARG(CONCAT(SOME_CHECK_, N))
  62. #define EMPTY(...)
  63. #define DEFER(...) __VA_ARGS__ EMPTY()
  64. #define REPEAT_NAME_0() REPEAT_0
  65. #define REPEAT_NAME_SOME() REPEAT_SOME
  66. #define REPEAT_0(...)
  67. #define REPEAT_SOME(N, stuff) DEFER(CONCAT(REPEAT_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), stuff) stuff
  68. #define REPEAT(N, stuff) EVAL(REPEAT_SOME(N, stuff))
  69. #define REPEATM_NAME_0() REPEATM_0
  70. #define REPEATM_NAME_SOME() REPEATM_SOME
  71. #define REPEATM_0(...)
  72. #define REPEATM_SOME(N, macro) macro(N) \
  73. DEFER(CONCAT(REPEATM_NAME_, SOME_OR_0(DEC(N))))()(DEC(N), macro)
  74. #define REPEATM(N, macro) EVAL(REPEATM_SOME(N, macro))
  75. #endif
  76. #include "platform-specific.inc"
  77. #if (uECC_WORD_SIZE == 1)
  78. #if uECC_SUPPORTS_secp160r1
  79. #define uECC_MAX_WORDS 21 /* Due to the size of curve_n. */
  80. #endif
  81. #if uECC_SUPPORTS_secp192r1
  82. #undef uECC_MAX_WORDS
  83. #define uECC_MAX_WORDS 24
  84. #endif
  85. #if uECC_SUPPORTS_secp224r1
  86. #undef uECC_MAX_WORDS
  87. #define uECC_MAX_WORDS 28
  88. #endif
  89. #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1)
  90. #undef uECC_MAX_WORDS
  91. #define uECC_MAX_WORDS 32
  92. #endif
  93. #elif (uECC_WORD_SIZE == 4)
  94. #if uECC_SUPPORTS_secp160r1
  95. #define uECC_MAX_WORDS 6 /* Due to the size of curve_n. */
  96. #endif
  97. #if uECC_SUPPORTS_secp192r1
  98. #undef uECC_MAX_WORDS
  99. #define uECC_MAX_WORDS 6
  100. #endif
  101. #if uECC_SUPPORTS_secp224r1
  102. #undef uECC_MAX_WORDS
  103. #define uECC_MAX_WORDS 7
  104. #endif
  105. #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1)
  106. #undef uECC_MAX_WORDS
  107. #define uECC_MAX_WORDS 8
  108. #endif
  109. #elif (uECC_WORD_SIZE == 8)
  110. #if uECC_SUPPORTS_secp160r1
  111. #define uECC_MAX_WORDS 3
  112. #endif
  113. #if uECC_SUPPORTS_secp192r1
  114. #undef uECC_MAX_WORDS
  115. #define uECC_MAX_WORDS 3
  116. #endif
  117. #if uECC_SUPPORTS_secp224r1
  118. #undef uECC_MAX_WORDS
  119. #define uECC_MAX_WORDS 4
  120. #endif
  121. #if (uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1)
  122. #undef uECC_MAX_WORDS
  123. #define uECC_MAX_WORDS 4
  124. #endif
  125. #endif /* uECC_WORD_SIZE */
  126. #define BITS_TO_WORDS(num_bits) ((num_bits + ((uECC_WORD_SIZE * 8) - 1)) / (uECC_WORD_SIZE * 8))
  127. #define BITS_TO_BYTES(num_bits) ((num_bits + 7) / 8)
  128. struct uECC_Curve_t {
  129. wordcount_t num_words;
  130. wordcount_t num_bytes;
  131. bitcount_t num_n_bits;
  132. uECC_word_t p[uECC_MAX_WORDS];
  133. uECC_word_t n[uECC_MAX_WORDS];
  134. uECC_word_t G[uECC_MAX_WORDS * 2];
  135. uECC_word_t b[uECC_MAX_WORDS];
  136. void (*double_jacobian)(uECC_word_t * X1,
  137. uECC_word_t * Y1,
  138. uECC_word_t * Z1,
  139. uECC_Curve curve);
  140. #if uECC_SUPPORT_COMPRESSED_POINT
  141. void (*mod_sqrt)(uECC_word_t *a, uECC_Curve curve);
  142. #endif
  143. void (*x_side)(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve);
  144. #if (uECC_OPTIMIZATION_LEVEL > 0)
  145. void (*mmod_fast)(uECC_word_t *result, uECC_word_t *product);
  146. #endif
  147. };
  148. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  149. static void bcopy(uint8_t *dst,
  150. const uint8_t *src,
  151. unsigned num_bytes) {
  152. while (0 != num_bytes) {
  153. num_bytes--;
  154. dst[num_bytes] = src[num_bytes];
  155. }
  156. }
  157. #endif
  158. static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left,
  159. const uECC_word_t *right,
  160. wordcount_t num_words);
  161. #if (uECC_PLATFORM == uECC_arm || uECC_PLATFORM == uECC_arm_thumb || \
  162. uECC_PLATFORM == uECC_arm_thumb2)
  163. #include "asm_arm.inc"
  164. #endif
  165. #if (uECC_PLATFORM == uECC_avr)
  166. #include "asm_avr.inc"
  167. #endif
  168. #if default_RNG_defined
  169. static uECC_RNG_Function g_rng_function = &default_RNG;
  170. #else
  171. static uECC_RNG_Function g_rng_function = 0;
  172. #endif
  173. void uECC_set_rng(uECC_RNG_Function rng_function) {
  174. g_rng_function = rng_function;
  175. }
  176. uECC_RNG_Function uECC_get_rng(void) {
  177. return g_rng_function;
  178. }
  179. int uECC_curve_private_key_size(uECC_Curve curve) {
  180. return BITS_TO_BYTES(curve->num_n_bits);
  181. }
  182. int uECC_curve_public_key_size(uECC_Curve curve) {
  183. return 2 * curve->num_bytes;
  184. }
  185. #if !asm_clear
  186. uECC_VLI_API void uECC_vli_clear(uECC_word_t *vli, wordcount_t num_words) {
  187. wordcount_t i;
  188. for (i = 0; i < num_words; ++i) {
  189. vli[i] = 0;
  190. }
  191. }
  192. #endif /* !asm_clear */
  193. /* Constant-time comparison to zero - secure way to compare long integers */
  194. /* Returns 1 if vli == 0, 0 otherwise. */
  195. uECC_VLI_API uECC_word_t uECC_vli_isZero(const uECC_word_t *vli, wordcount_t num_words) {
  196. uECC_word_t bits = 0;
  197. wordcount_t i;
  198. for (i = 0; i < num_words; ++i) {
  199. bits |= vli[i];
  200. }
  201. return (bits == 0);
  202. }
  203. /* Returns nonzero if bit 'bit' of vli is set. */
  204. uECC_VLI_API uECC_word_t uECC_vli_testBit(const uECC_word_t *vli, bitcount_t bit) {
  205. return (vli[bit >> uECC_WORD_BITS_SHIFT] & ((uECC_word_t)1 << (bit & uECC_WORD_BITS_MASK)));
  206. }
  207. /* Counts the number of words in vli. */
  208. static wordcount_t vli_numDigits(const uECC_word_t *vli, const wordcount_t max_words) {
  209. wordcount_t i;
  210. /* Search from the end until we find a non-zero digit.
  211. We do it in reverse because we expect that most digits will be nonzero. */
  212. for (i = max_words - 1; i >= 0 && vli[i] == 0; --i) {
  213. }
  214. return (i + 1);
  215. }
  216. /* Counts the number of bits required to represent vli. */
  217. uECC_VLI_API bitcount_t uECC_vli_numBits(const uECC_word_t *vli, const wordcount_t max_words) {
  218. uECC_word_t i;
  219. uECC_word_t digit;
  220. wordcount_t num_digits = vli_numDigits(vli, max_words);
  221. if (num_digits == 0) {
  222. return 0;
  223. }
  224. digit = vli[num_digits - 1];
  225. for (i = 0; digit; ++i) {
  226. digit >>= 1;
  227. }
  228. return (((bitcount_t)(num_digits - 1) << uECC_WORD_BITS_SHIFT) + i);
  229. }
  230. /* Sets dest = src. */
  231. #if !asm_set
  232. uECC_VLI_API void uECC_vli_set(uECC_word_t *dest, const uECC_word_t *src, wordcount_t num_words) {
  233. wordcount_t i;
  234. for (i = 0; i < num_words; ++i) {
  235. dest[i] = src[i];
  236. }
  237. }
  238. #endif /* !asm_set */
  239. /* Returns sign of left - right. */
  240. static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left,
  241. const uECC_word_t *right,
  242. wordcount_t num_words) {
  243. wordcount_t i;
  244. for (i = num_words - 1; i >= 0; --i) {
  245. if (left[i] > right[i]) {
  246. return 1;
  247. } else if (left[i] < right[i]) {
  248. return -1;
  249. }
  250. }
  251. return 0;
  252. }
  253. /* Constant-time comparison function - secure way to compare long integers */
  254. /* Returns one if left == right, zero otherwise. */
  255. uECC_VLI_API uECC_word_t uECC_vli_equal(const uECC_word_t *left,
  256. const uECC_word_t *right,
  257. wordcount_t num_words) {
  258. uECC_word_t diff = 0;
  259. wordcount_t i;
  260. for (i = num_words - 1; i >= 0; --i) {
  261. diff |= (left[i] ^ right[i]);
  262. }
  263. return (diff == 0);
  264. }
  265. uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result,
  266. const uECC_word_t *left,
  267. const uECC_word_t *right,
  268. wordcount_t num_words);
  269. /* Returns sign of left - right, in constant time. */
  270. uECC_VLI_API cmpresult_t uECC_vli_cmp(const uECC_word_t *left,
  271. const uECC_word_t *right,
  272. wordcount_t num_words) {
  273. uECC_word_t tmp[uECC_MAX_WORDS];
  274. uECC_word_t neg = !!uECC_vli_sub(tmp, left, right, num_words);
  275. uECC_word_t equal = uECC_vli_isZero(tmp, num_words);
  276. return (cmpresult_t)(!equal - 2 * neg);
  277. }
  278. /* Computes vli = vli >> 1. */
  279. #if !asm_rshift1
  280. uECC_VLI_API void uECC_vli_rshift1(uECC_word_t *vli, wordcount_t num_words) {
  281. uECC_word_t *end = vli;
  282. uECC_word_t carry = 0;
  283. vli += num_words;
  284. while (vli-- > end) {
  285. uECC_word_t temp = *vli;
  286. *vli = (temp >> 1) | carry;
  287. carry = temp << (uECC_WORD_BITS - 1);
  288. }
  289. }
  290. #endif /* !asm_rshift1 */
  291. /* Computes result = left + right, returning carry. Can modify in place. */
  292. #if !asm_add
  293. uECC_VLI_API uECC_word_t uECC_vli_add(uECC_word_t *result,
  294. const uECC_word_t *left,
  295. const uECC_word_t *right,
  296. wordcount_t num_words) {
  297. uECC_word_t carry = 0;
  298. wordcount_t i;
  299. for (i = 0; i < num_words; ++i) {
  300. uECC_word_t sum = left[i] + right[i] + carry;
  301. if (sum != left[i]) {
  302. carry = (sum < left[i]);
  303. }
  304. result[i] = sum;
  305. }
  306. return carry;
  307. }
  308. #endif /* !asm_add */
  309. /* Computes result = left - right, returning borrow. Can modify in place. */
  310. #if !asm_sub
  311. uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result,
  312. const uECC_word_t *left,
  313. const uECC_word_t *right,
  314. wordcount_t num_words) {
  315. uECC_word_t borrow = 0;
  316. wordcount_t i;
  317. for (i = 0; i < num_words; ++i) {
  318. uECC_word_t diff = left[i] - right[i] - borrow;
  319. if (diff != left[i]) {
  320. borrow = (diff > left[i]);
  321. }
  322. result[i] = diff;
  323. }
  324. return borrow;
  325. }
  326. #endif /* !asm_sub */
  327. #if !asm_mult || (uECC_SQUARE_FUNC && !asm_square) || \
  328. (uECC_SUPPORTS_secp256k1 && (uECC_OPTIMIZATION_LEVEL > 0) && \
  329. ((uECC_WORD_SIZE == 1) || (uECC_WORD_SIZE == 8)))
  330. static void muladd(uECC_word_t a,
  331. uECC_word_t b,
  332. uECC_word_t *r0,
  333. uECC_word_t *r1,
  334. uECC_word_t *r2) {
  335. #if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128
  336. uint64_t a0 = a & 0xffffffffull;
  337. uint64_t a1 = a >> 32;
  338. uint64_t b0 = b & 0xffffffffull;
  339. uint64_t b1 = b >> 32;
  340. uint64_t i0 = a0 * b0;
  341. uint64_t i1 = a0 * b1;
  342. uint64_t i2 = a1 * b0;
  343. uint64_t i3 = a1 * b1;
  344. uint64_t p0, p1;
  345. i2 += (i0 >> 32);
  346. i2 += i1;
  347. if (i2 < i1) { /* overflow */
  348. i3 += 0x100000000ull;
  349. }
  350. p0 = (i0 & 0xffffffffull) | (i2 << 32);
  351. p1 = i3 + (i2 >> 32);
  352. *r0 += p0;
  353. *r1 += (p1 + (*r0 < p0));
  354. *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0));
  355. #else
  356. uECC_dword_t p = (uECC_dword_t)a * b;
  357. uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0;
  358. r01 += p;
  359. *r2 += (r01 < p);
  360. *r1 = r01 >> uECC_WORD_BITS;
  361. *r0 = (uECC_word_t)r01;
  362. #endif
  363. }
  364. #endif /* muladd needed */
  365. #if !asm_mult
  366. uECC_VLI_API void uECC_vli_mult(uECC_word_t *result,
  367. const uECC_word_t *left,
  368. const uECC_word_t *right,
  369. wordcount_t num_words) {
  370. uECC_word_t r0 = 0;
  371. uECC_word_t r1 = 0;
  372. uECC_word_t r2 = 0;
  373. wordcount_t i, k;
  374. /* Compute each digit of result in sequence, maintaining the carries. */
  375. for (k = 0; k < num_words; ++k) {
  376. for (i = 0; i <= k; ++i) {
  377. muladd(left[i], right[k - i], &r0, &r1, &r2);
  378. }
  379. result[k] = r0;
  380. r0 = r1;
  381. r1 = r2;
  382. r2 = 0;
  383. }
  384. for (k = num_words; k < num_words * 2 - 1; ++k) {
  385. for (i = (k + 1) - num_words; i < num_words; ++i) {
  386. muladd(left[i], right[k - i], &r0, &r1, &r2);
  387. }
  388. result[k] = r0;
  389. r0 = r1;
  390. r1 = r2;
  391. r2 = 0;
  392. }
  393. result[num_words * 2 - 1] = r0;
  394. }
  395. #endif /* !asm_mult */
  396. #if uECC_SQUARE_FUNC
  397. #if !asm_square
  398. static void mul2add(uECC_word_t a,
  399. uECC_word_t b,
  400. uECC_word_t *r0,
  401. uECC_word_t *r1,
  402. uECC_word_t *r2) {
  403. #if uECC_WORD_SIZE == 8 && !SUPPORTS_INT128
  404. uint64_t a0 = a & 0xffffffffull;
  405. uint64_t a1 = a >> 32;
  406. uint64_t b0 = b & 0xffffffffull;
  407. uint64_t b1 = b >> 32;
  408. uint64_t i0 = a0 * b0;
  409. uint64_t i1 = a0 * b1;
  410. uint64_t i2 = a1 * b0;
  411. uint64_t i3 = a1 * b1;
  412. uint64_t p0, p1;
  413. i2 += (i0 >> 32);
  414. i2 += i1;
  415. if (i2 < i1)
  416. { /* overflow */
  417. i3 += 0x100000000ull;
  418. }
  419. p0 = (i0 & 0xffffffffull) | (i2 << 32);
  420. p1 = i3 + (i2 >> 32);
  421. *r2 += (p1 >> 63);
  422. p1 = (p1 << 1) | (p0 >> 63);
  423. p0 <<= 1;
  424. *r0 += p0;
  425. *r1 += (p1 + (*r0 < p0));
  426. *r2 += ((*r1 < p1) || (*r1 == p1 && *r0 < p0));
  427. #else
  428. uECC_dword_t p = (uECC_dword_t)a * b;
  429. uECC_dword_t r01 = ((uECC_dword_t)(*r1) << uECC_WORD_BITS) | *r0;
  430. *r2 += (p >> (uECC_WORD_BITS * 2 - 1));
  431. p *= 2;
  432. r01 += p;
  433. *r2 += (r01 < p);
  434. *r1 = r01 >> uECC_WORD_BITS;
  435. *r0 = (uECC_word_t)r01;
  436. #endif
  437. }
  438. uECC_VLI_API void uECC_vli_square(uECC_word_t *result,
  439. const uECC_word_t *left,
  440. wordcount_t num_words) {
  441. uECC_word_t r0 = 0;
  442. uECC_word_t r1 = 0;
  443. uECC_word_t r2 = 0;
  444. wordcount_t i, k;
  445. for (k = 0; k < num_words * 2 - 1; ++k) {
  446. uECC_word_t min = (k < num_words ? 0 : (k + 1) - num_words);
  447. for (i = min; i <= k && i <= k - i; ++i) {
  448. if (i < k-i) {
  449. mul2add(left[i], left[k - i], &r0, &r1, &r2);
  450. } else {
  451. muladd(left[i], left[k - i], &r0, &r1, &r2);
  452. }
  453. }
  454. result[k] = r0;
  455. r0 = r1;
  456. r1 = r2;
  457. r2 = 0;
  458. }
  459. result[num_words * 2 - 1] = r0;
  460. }
  461. #endif /* !asm_square */
  462. #else /* uECC_SQUARE_FUNC */
  463. #if uECC_ENABLE_VLI_API
  464. uECC_VLI_API void uECC_vli_square(uECC_word_t *result,
  465. const uECC_word_t *left,
  466. wordcount_t num_words) {
  467. uECC_vli_mult(result, left, left, num_words);
  468. }
  469. #endif /* uECC_ENABLE_VLI_API */
  470. #endif /* uECC_SQUARE_FUNC */
  471. /* Computes result = (left + right) % mod.
  472. Assumes that left < mod and right < mod, and that result does not overlap mod. */
  473. uECC_VLI_API void uECC_vli_modAdd(uECC_word_t *result,
  474. const uECC_word_t *left,
  475. const uECC_word_t *right,
  476. const uECC_word_t *mod,
  477. wordcount_t num_words) {
  478. uECC_word_t carry = uECC_vli_add(result, left, right, num_words);
  479. if (carry || uECC_vli_cmp_unsafe(mod, result, num_words) != 1) {
  480. /* result > mod (result = mod + remainder), so subtract mod to get remainder. */
  481. uECC_vli_sub(result, result, mod, num_words);
  482. }
  483. }
  484. /* Computes result = (left - right) % mod.
  485. Assumes that left < mod and right < mod, and that result does not overlap mod. */
  486. uECC_VLI_API void uECC_vli_modSub(uECC_word_t *result,
  487. const uECC_word_t *left,
  488. const uECC_word_t *right,
  489. const uECC_word_t *mod,
  490. wordcount_t num_words) {
  491. uECC_word_t l_borrow = uECC_vli_sub(result, left, right, num_words);
  492. if (l_borrow) {
  493. /* In this case, result == -diff == (max int) - diff. Since -x % d == d - x,
  494. we can get the correct result from result + mod (with overflow). */
  495. uECC_vli_add(result, result, mod, num_words);
  496. }
  497. }
  498. /* Computes result = product % mod, where product is 2N words long. */
  499. /* Currently only designed to work for curve_p or curve_n. */
  500. uECC_VLI_API void uECC_vli_mmod(uECC_word_t *result,
  501. uECC_word_t *product,
  502. const uECC_word_t *mod,
  503. wordcount_t num_words) {
  504. uECC_word_t mod_multiple[2 * uECC_MAX_WORDS];
  505. uECC_word_t tmp[2 * uECC_MAX_WORDS];
  506. uECC_word_t *v[2] = {tmp, product};
  507. uECC_word_t index;
  508. /* Shift mod so its highest set bit is at the maximum position. */
  509. bitcount_t shift = (num_words * 2 * uECC_WORD_BITS) - uECC_vli_numBits(mod, num_words);
  510. wordcount_t word_shift = shift / uECC_WORD_BITS;
  511. wordcount_t bit_shift = shift % uECC_WORD_BITS;
  512. uECC_word_t carry = 0;
  513. uECC_vli_clear(mod_multiple, word_shift);
  514. if (bit_shift > 0) {
  515. for(index = 0; index < (uECC_word_t)num_words; ++index) {
  516. mod_multiple[word_shift + index] = (mod[index] << bit_shift) | carry;
  517. carry = mod[index] >> (uECC_WORD_BITS - bit_shift);
  518. }
  519. } else {
  520. uECC_vli_set(mod_multiple + word_shift, mod, num_words);
  521. }
  522. for (index = 1; shift >= 0; --shift) {
  523. uECC_word_t borrow = 0;
  524. wordcount_t i;
  525. for (i = 0; i < num_words * 2; ++i) {
  526. uECC_word_t diff = v[index][i] - mod_multiple[i] - borrow;
  527. if (diff != v[index][i]) {
  528. borrow = (diff > v[index][i]);
  529. }
  530. v[1 - index][i] = diff;
  531. }
  532. index = !(index ^ borrow); /* Swap the index if there was no borrow */
  533. uECC_vli_rshift1(mod_multiple, num_words);
  534. mod_multiple[num_words - 1] |= mod_multiple[num_words] << (uECC_WORD_BITS - 1);
  535. uECC_vli_rshift1(mod_multiple + num_words, num_words);
  536. }
  537. uECC_vli_set(result, v[index], num_words);
  538. }
  539. /* Computes result = (left * right) % mod. */
  540. uECC_VLI_API void uECC_vli_modMult(uECC_word_t *result,
  541. const uECC_word_t *left,
  542. const uECC_word_t *right,
  543. const uECC_word_t *mod,
  544. wordcount_t num_words) {
  545. uECC_word_t product[2 * uECC_MAX_WORDS];
  546. uECC_vli_mult(product, left, right, num_words);
  547. uECC_vli_mmod(result, product, mod, num_words);
  548. }
  549. uECC_VLI_API void uECC_vli_modMult_fast(uECC_word_t *result,
  550. const uECC_word_t *left,
  551. const uECC_word_t *right,
  552. uECC_Curve curve) {
  553. uECC_word_t product[2 * uECC_MAX_WORDS];
  554. uECC_vli_mult(product, left, right, curve->num_words);
  555. #if (uECC_OPTIMIZATION_LEVEL > 0)
  556. curve->mmod_fast(result, product);
  557. #else
  558. uECC_vli_mmod(result, product, curve->p, curve->num_words);
  559. #endif
  560. }
  561. #if uECC_SQUARE_FUNC
  562. #if uECC_ENABLE_VLI_API
  563. /* Computes result = left^2 % mod. */
  564. uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result,
  565. const uECC_word_t *left,
  566. const uECC_word_t *mod,
  567. wordcount_t num_words) {
  568. uECC_word_t product[2 * uECC_MAX_WORDS];
  569. uECC_vli_square(product, left, num_words);
  570. uECC_vli_mmod(result, product, mod, num_words);
  571. }
  572. #endif /* uECC_ENABLE_VLI_API */
  573. uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result,
  574. const uECC_word_t *left,
  575. uECC_Curve curve) {
  576. uECC_word_t product[2 * uECC_MAX_WORDS];
  577. uECC_vli_square(product, left, curve->num_words);
  578. #if (uECC_OPTIMIZATION_LEVEL > 0)
  579. curve->mmod_fast(result, product);
  580. #else
  581. uECC_vli_mmod(result, product, curve->p, curve->num_words);
  582. #endif
  583. }
  584. #else /* uECC_SQUARE_FUNC */
  585. #if uECC_ENABLE_VLI_API
  586. uECC_VLI_API void uECC_vli_modSquare(uECC_word_t *result,
  587. const uECC_word_t *left,
  588. const uECC_word_t *mod,
  589. wordcount_t num_words) {
  590. uECC_vli_modMult(result, left, left, mod, num_words);
  591. }
  592. #endif /* uECC_ENABLE_VLI_API */
  593. uECC_VLI_API void uECC_vli_modSquare_fast(uECC_word_t *result,
  594. const uECC_word_t *left,
  595. uECC_Curve curve) {
  596. uECC_vli_modMult_fast(result, left, left, curve);
  597. }
  598. #endif /* uECC_SQUARE_FUNC */
  599. #define EVEN(vli) (!(vli[0] & 1))
  600. static void vli_modInv_update(uECC_word_t *uv,
  601. const uECC_word_t *mod,
  602. wordcount_t num_words) {
  603. uECC_word_t carry = 0;
  604. if (!EVEN(uv)) {
  605. carry = uECC_vli_add(uv, uv, mod, num_words);
  606. }
  607. uECC_vli_rshift1(uv, num_words);
  608. if (carry) {
  609. uv[num_words - 1] |= HIGH_BIT_SET;
  610. }
  611. }
  612. /* Computes result = (1 / input) % mod. All VLIs are the same size.
  613. See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" */
  614. uECC_VLI_API void uECC_vli_modInv(uECC_word_t *result,
  615. const uECC_word_t *input,
  616. const uECC_word_t *mod,
  617. wordcount_t num_words) {
  618. uECC_word_t a[uECC_MAX_WORDS], b[uECC_MAX_WORDS], u[uECC_MAX_WORDS], v[uECC_MAX_WORDS];
  619. cmpresult_t cmpResult;
  620. if (uECC_vli_isZero(input, num_words)) {
  621. uECC_vli_clear(result, num_words);
  622. return;
  623. }
  624. uECC_vli_set(a, input, num_words);
  625. uECC_vli_set(b, mod, num_words);
  626. uECC_vli_clear(u, num_words);
  627. u[0] = 1;
  628. uECC_vli_clear(v, num_words);
  629. while ((cmpResult = uECC_vli_cmp_unsafe(a, b, num_words)) != 0) {
  630. if (EVEN(a)) {
  631. uECC_vli_rshift1(a, num_words);
  632. vli_modInv_update(u, mod, num_words);
  633. } else if (EVEN(b)) {
  634. uECC_vli_rshift1(b, num_words);
  635. vli_modInv_update(v, mod, num_words);
  636. } else if (cmpResult > 0) {
  637. uECC_vli_sub(a, a, b, num_words);
  638. uECC_vli_rshift1(a, num_words);
  639. if (uECC_vli_cmp_unsafe(u, v, num_words) < 0) {
  640. uECC_vli_add(u, u, mod, num_words);
  641. }
  642. uECC_vli_sub(u, u, v, num_words);
  643. vli_modInv_update(u, mod, num_words);
  644. } else {
  645. uECC_vli_sub(b, b, a, num_words);
  646. uECC_vli_rshift1(b, num_words);
  647. if (uECC_vli_cmp_unsafe(v, u, num_words) < 0) {
  648. uECC_vli_add(v, v, mod, num_words);
  649. }
  650. uECC_vli_sub(v, v, u, num_words);
  651. vli_modInv_update(v, mod, num_words);
  652. }
  653. }
  654. uECC_vli_set(result, u, num_words);
  655. }
  656. /* ------ Point operations ------ */
  657. #include "curve-specific.inc"
  658. /* Returns 1 if 'point' is the point at infinity, 0 otherwise. */
  659. #define EccPoint_isZero(point, curve) uECC_vli_isZero((point), (curve)->num_words * 2)
  660. /* Point multiplication algorithm using Montgomery's ladder with co-Z coordinates.
  661. From http://eprint.iacr.org/2011/338.pdf
  662. */
  663. /* Modify (x1, y1) => (x1 * z^2, y1 * z^3) */
  664. static void apply_z(uECC_word_t * X1,
  665. uECC_word_t * Y1,
  666. const uECC_word_t * const Z,
  667. uECC_Curve curve) {
  668. uECC_word_t t1[uECC_MAX_WORDS];
  669. uECC_vli_modSquare_fast(t1, Z, curve); /* z^2 */
  670. uECC_vli_modMult_fast(X1, X1, t1, curve); /* x1 * z^2 */
  671. uECC_vli_modMult_fast(t1, t1, Z, curve); /* z^3 */
  672. uECC_vli_modMult_fast(Y1, Y1, t1, curve); /* y1 * z^3 */
  673. }
  674. /* P = (x1, y1) => 2P, (x2, y2) => P' */
  675. static void XYcZ_initial_double(uECC_word_t * X1,
  676. uECC_word_t * Y1,
  677. uECC_word_t * X2,
  678. uECC_word_t * Y2,
  679. const uECC_word_t * const initial_Z,
  680. uECC_Curve curve) {
  681. uECC_word_t z[uECC_MAX_WORDS];
  682. wordcount_t num_words = curve->num_words;
  683. if (initial_Z) {
  684. uECC_vli_set(z, initial_Z, num_words);
  685. } else {
  686. uECC_vli_clear(z, num_words);
  687. z[0] = 1;
  688. }
  689. uECC_vli_set(X2, X1, num_words);
  690. uECC_vli_set(Y2, Y1, num_words);
  691. apply_z(X1, Y1, z, curve);
  692. curve->double_jacobian(X1, Y1, z, curve);
  693. apply_z(X2, Y2, z, curve);
  694. }
  695. /* Input P = (x1, y1, Z), Q = (x2, y2, Z)
  696. Output P' = (x1', y1', Z3), P + Q = (x3, y3, Z3)
  697. or P => P', Q => P + Q
  698. */
  699. static void XYcZ_add(uECC_word_t * X1,
  700. uECC_word_t * Y1,
  701. uECC_word_t * X2,
  702. uECC_word_t * Y2,
  703. uECC_Curve curve) {
  704. /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
  705. uECC_word_t t5[uECC_MAX_WORDS];
  706. wordcount_t num_words = curve->num_words;
  707. uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
  708. uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
  709. uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
  710. uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
  711. uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
  712. uECC_vli_modSquare_fast(t5, Y2, curve); /* t5 = (y2 - y1)^2 = D */
  713. uECC_vli_modSub(t5, t5, X1, curve->p, num_words); /* t5 = D - B */
  714. uECC_vli_modSub(t5, t5, X2, curve->p, num_words); /* t5 = D - B - C = x3 */
  715. uECC_vli_modSub(X2, X2, X1, curve->p, num_words); /* t3 = C - B */
  716. uECC_vli_modMult_fast(Y1, Y1, X2, curve); /* t2 = y1*(C - B) */
  717. uECC_vli_modSub(X2, X1, t5, curve->p, num_words); /* t3 = B - x3 */
  718. uECC_vli_modMult_fast(Y2, Y2, X2, curve); /* t4 = (y2 - y1)*(B - x3) */
  719. uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y3 */
  720. uECC_vli_set(X2, t5, num_words);
  721. }
  722. /* Input P = (x1, y1, Z), Q = (x2, y2, Z)
  723. Output P + Q = (x3, y3, Z3), P - Q = (x3', y3', Z3)
  724. or P => P - Q, Q => P + Q
  725. */
  726. static void XYcZ_addC(uECC_word_t * X1,
  727. uECC_word_t * Y1,
  728. uECC_word_t * X2,
  729. uECC_word_t * Y2,
  730. uECC_Curve curve) {
  731. /* t1 = X1, t2 = Y1, t3 = X2, t4 = Y2 */
  732. uECC_word_t t5[uECC_MAX_WORDS];
  733. uECC_word_t t6[uECC_MAX_WORDS];
  734. uECC_word_t t7[uECC_MAX_WORDS];
  735. wordcount_t num_words = curve->num_words;
  736. uECC_vli_modSub(t5, X2, X1, curve->p, num_words); /* t5 = x2 - x1 */
  737. uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = (x2 - x1)^2 = A */
  738. uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = x1*A = B */
  739. uECC_vli_modMult_fast(X2, X2, t5, curve); /* t3 = x2*A = C */
  740. uECC_vli_modAdd(t5, Y2, Y1, curve->p, num_words); /* t5 = y2 + y1 */
  741. uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = y2 - y1 */
  742. uECC_vli_modSub(t6, X2, X1, curve->p, num_words); /* t6 = C - B */
  743. uECC_vli_modMult_fast(Y1, Y1, t6, curve); /* t2 = y1 * (C - B) = E */
  744. uECC_vli_modAdd(t6, X1, X2, curve->p, num_words); /* t6 = B + C */
  745. uECC_vli_modSquare_fast(X2, Y2, curve); /* t3 = (y2 - y1)^2 = D */
  746. uECC_vli_modSub(X2, X2, t6, curve->p, num_words); /* t3 = D - (B + C) = x3 */
  747. uECC_vli_modSub(t7, X1, X2, curve->p, num_words); /* t7 = B - x3 */
  748. uECC_vli_modMult_fast(Y2, Y2, t7, curve); /* t4 = (y2 - y1)*(B - x3) */
  749. uECC_vli_modSub(Y2, Y2, Y1, curve->p, num_words); /* t4 = (y2 - y1)*(B - x3) - E = y3 */
  750. uECC_vli_modSquare_fast(t7, t5, curve); /* t7 = (y2 + y1)^2 = F */
  751. uECC_vli_modSub(t7, t7, t6, curve->p, num_words); /* t7 = F - (B + C) = x3' */
  752. uECC_vli_modSub(t6, t7, X1, curve->p, num_words); /* t6 = x3' - B */
  753. uECC_vli_modMult_fast(t6, t6, t5, curve); /* t6 = (y2+y1)*(x3' - B) */
  754. uECC_vli_modSub(Y1, t6, Y1, curve->p, num_words); /* t2 = (y2+y1)*(x3' - B) - E = y3' */
  755. uECC_vli_set(X1, t7, num_words);
  756. }
  757. /* result may overlap point. */
  758. static void EccPoint_mult(uECC_word_t * result,
  759. const uECC_word_t * point,
  760. const uECC_word_t * scalar,
  761. const uECC_word_t * initial_Z,
  762. bitcount_t num_bits,
  763. uECC_Curve curve) {
  764. /* R0 and R1 */
  765. uECC_word_t Rx[2][uECC_MAX_WORDS];
  766. uECC_word_t Ry[2][uECC_MAX_WORDS];
  767. uECC_word_t z[uECC_MAX_WORDS];
  768. bitcount_t i;
  769. uECC_word_t nb;
  770. wordcount_t num_words = curve->num_words;
  771. uECC_vli_set(Rx[1], point, num_words);
  772. uECC_vli_set(Ry[1], point + num_words, num_words);
  773. XYcZ_initial_double(Rx[1], Ry[1], Rx[0], Ry[0], initial_Z, curve);
  774. for (i = num_bits - 2; i > 0; --i) {
  775. nb = !uECC_vli_testBit(scalar, i);
  776. XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
  777. XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
  778. }
  779. nb = !uECC_vli_testBit(scalar, 0);
  780. XYcZ_addC(Rx[1 - nb], Ry[1 - nb], Rx[nb], Ry[nb], curve);
  781. /* Find final 1/Z value. */
  782. uECC_vli_modSub(z, Rx[1], Rx[0], curve->p, num_words); /* X1 - X0 */
  783. uECC_vli_modMult_fast(z, z, Ry[1 - nb], curve); /* Yb * (X1 - X0) */
  784. uECC_vli_modMult_fast(z, z, point, curve); /* xP * Yb * (X1 - X0) */
  785. uECC_vli_modInv(z, z, curve->p, num_words); /* 1 / (xP * Yb * (X1 - X0)) */
  786. /* yP / (xP * Yb * (X1 - X0)) */
  787. uECC_vli_modMult_fast(z, z, point + num_words, curve);
  788. uECC_vli_modMult_fast(z, z, Rx[1 - nb], curve); /* Xb * yP / (xP * Yb * (X1 - X0)) */
  789. /* End 1/Z calculation */
  790. XYcZ_add(Rx[nb], Ry[nb], Rx[1 - nb], Ry[1 - nb], curve);
  791. apply_z(Rx[0], Ry[0], z, curve);
  792. uECC_vli_set(result, Rx[0], num_words);
  793. uECC_vli_set(result + num_words, Ry[0], num_words);
  794. }
  795. static uECC_word_t regularize_k(const uECC_word_t * const k,
  796. uECC_word_t *k0,
  797. uECC_word_t *k1,
  798. uECC_Curve curve) {
  799. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  800. bitcount_t num_n_bits = curve->num_n_bits;
  801. uECC_word_t carry = uECC_vli_add(k0, k, curve->n, num_n_words) ||
  802. (num_n_bits < ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8) &&
  803. uECC_vli_testBit(k0, num_n_bits));
  804. uECC_vli_add(k1, k0, curve->n, num_n_words);
  805. return carry;
  806. }
  807. /* Generates a random integer in the range 0 < random < top.
  808. Both random and top have num_words words. */
  809. uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random,
  810. const uECC_word_t *top,
  811. wordcount_t num_words) {
  812. uECC_word_t mask = (uECC_word_t)-1;
  813. uECC_word_t tries;
  814. bitcount_t num_bits = uECC_vli_numBits(top, num_words);
  815. if (!g_rng_function) {
  816. return 0;
  817. }
  818. for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
  819. if (!g_rng_function((uint8_t *)random, num_words * uECC_WORD_SIZE)) {
  820. return 0;
  821. }
  822. random[num_words - 1] &= mask >> ((bitcount_t)(num_words * uECC_WORD_SIZE * 8 - num_bits));
  823. if (!uECC_vli_isZero(random, num_words) &&
  824. uECC_vli_cmp(top, random, num_words) == 1) {
  825. return 1;
  826. }
  827. }
  828. return 0;
  829. }
  830. static uECC_word_t EccPoint_compute_public_key(uECC_word_t *result,
  831. uECC_word_t *private_key,
  832. uECC_Curve curve) {
  833. uECC_word_t tmp1[uECC_MAX_WORDS];
  834. uECC_word_t tmp2[uECC_MAX_WORDS];
  835. uECC_word_t *p2[2] = {tmp1, tmp2};
  836. uECC_word_t *initial_Z = 0;
  837. uECC_word_t carry;
  838. /* Regularize the bitcount for the private key so that attackers cannot use a side channel
  839. attack to learn the number of leading zeros. */
  840. carry = regularize_k(private_key, tmp1, tmp2, curve);
  841. /* If an RNG function was specified, try to get a random initial Z value to improve
  842. protection against side-channel attacks. */
  843. if (g_rng_function) {
  844. if (!uECC_generate_random_int(p2[carry], curve->p, curve->num_words)) {
  845. return 0;
  846. }
  847. initial_Z = p2[carry];
  848. }
  849. EccPoint_mult(result, curve->G, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
  850. if (EccPoint_isZero(result, curve)) {
  851. return 0;
  852. }
  853. return 1;
  854. }
  855. #if uECC_WORD_SIZE == 1
  856. uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
  857. int num_bytes,
  858. const uint8_t *native) {
  859. wordcount_t i;
  860. for (i = 0; i < num_bytes; ++i) {
  861. bytes[i] = native[(num_bytes - 1) - i];
  862. }
  863. }
  864. uECC_VLI_API void uECC_vli_bytesToNative(uint8_t *native,
  865. const uint8_t *bytes,
  866. int num_bytes) {
  867. uECC_vli_nativeToBytes(native, num_bytes, bytes);
  868. }
  869. #else
  870. uECC_VLI_API void uECC_vli_nativeToBytes(uint8_t *bytes,
  871. int num_bytes,
  872. const uECC_word_t *native) {
  873. int i;
  874. for (i = 0; i < num_bytes; ++i) {
  875. unsigned b = num_bytes - 1 - i;
  876. bytes[i] = (uint8_t)(native[b / uECC_WORD_SIZE] >> (8 * (b % uECC_WORD_SIZE)));
  877. }
  878. }
  879. uECC_VLI_API void uECC_vli_bytesToNative(uECC_word_t *native,
  880. const uint8_t *bytes,
  881. int num_bytes) {
  882. int i;
  883. uECC_vli_clear(native, (num_bytes + (uECC_WORD_SIZE - 1)) / uECC_WORD_SIZE);
  884. for (i = 0; i < num_bytes; ++i) {
  885. unsigned b = num_bytes - 1 - i;
  886. native[b / uECC_WORD_SIZE] |=
  887. (uECC_word_t)bytes[i] << (8 * (b % uECC_WORD_SIZE));
  888. }
  889. }
  890. #endif /* uECC_WORD_SIZE */
  891. int uECC_make_key(uint8_t *public_key,
  892. uint8_t *private_key,
  893. uECC_Curve curve) {
  894. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  895. uECC_word_t *_private = (uECC_word_t *)private_key;
  896. uECC_word_t *_public = (uECC_word_t *)public_key;
  897. #else
  898. uECC_word_t _private[uECC_MAX_WORDS];
  899. uECC_word_t _public[uECC_MAX_WORDS * 2];
  900. #endif
  901. uECC_word_t tries;
  902. for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
  903. if (!uECC_generate_random_int(_private, curve->n, BITS_TO_WORDS(curve->num_n_bits))) {
  904. return 0;
  905. }
  906. if (EccPoint_compute_public_key(_public, _private, curve)) {
  907. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  908. uECC_vli_nativeToBytes(private_key, BITS_TO_BYTES(curve->num_n_bits), _private);
  909. uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
  910. uECC_vli_nativeToBytes(
  911. public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words);
  912. #endif
  913. return 1;
  914. }
  915. }
  916. return 0;
  917. }
  918. int uECC_shared_secret(const uint8_t *public_key,
  919. const uint8_t *private_key,
  920. uint8_t *secret,
  921. uECC_Curve curve) {
  922. uECC_word_t _public[uECC_MAX_WORDS * 2];
  923. uECC_word_t _private[uECC_MAX_WORDS];
  924. uECC_word_t tmp[uECC_MAX_WORDS];
  925. uECC_word_t *p2[2] = {_private, tmp};
  926. uECC_word_t *initial_Z = 0;
  927. uECC_word_t carry;
  928. wordcount_t num_words = curve->num_words;
  929. wordcount_t num_bytes = curve->num_bytes;
  930. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  931. bcopy((uint8_t *) _private, private_key, num_bytes);
  932. bcopy((uint8_t *) _public, public_key, num_bytes*2);
  933. #else
  934. uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits));
  935. uECC_vli_bytesToNative(_public, public_key, num_bytes);
  936. uECC_vli_bytesToNative(_public + num_words, public_key + num_bytes, num_bytes);
  937. #endif
  938. /* Regularize the bitcount for the private key so that attackers cannot use a side channel
  939. attack to learn the number of leading zeros. */
  940. carry = regularize_k(_private, _private, tmp, curve);
  941. /* If an RNG function was specified, try to get a random initial Z value to improve
  942. protection against side-channel attacks. */
  943. if (g_rng_function) {
  944. if (!uECC_generate_random_int(p2[carry], curve->p, num_words)) {
  945. return 0;
  946. }
  947. initial_Z = p2[carry];
  948. }
  949. EccPoint_mult(_public, _public, p2[!carry], initial_Z, curve->num_n_bits + 1, curve);
  950. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  951. bcopy((uint8_t *) secret, (uint8_t *) _public, num_bytes);
  952. #else
  953. uECC_vli_nativeToBytes(secret, num_bytes, _public);
  954. #endif
  955. return !EccPoint_isZero(_public, curve);
  956. }
  957. #if uECC_SUPPORT_COMPRESSED_POINT
  958. void uECC_compress(const uint8_t *public_key, uint8_t *compressed, uECC_Curve curve) {
  959. wordcount_t i;
  960. for (i = 0; i < curve->num_bytes; ++i) {
  961. compressed[i+1] = public_key[i];
  962. }
  963. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  964. compressed[0] = 2 + (public_key[curve->num_bytes] & 0x01);
  965. #else
  966. compressed[0] = 2 + (public_key[curve->num_bytes * 2 - 1] & 0x01);
  967. #endif
  968. }
  969. void uECC_decompress(const uint8_t *compressed, uint8_t *public_key, uECC_Curve curve) {
  970. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  971. uECC_word_t *point = (uECC_word_t *)public_key;
  972. #else
  973. uECC_word_t point[uECC_MAX_WORDS * 2];
  974. #endif
  975. uECC_word_t *y = point + curve->num_words;
  976. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  977. bcopy(public_key, compressed+1, curve->num_bytes);
  978. #else
  979. uECC_vli_bytesToNative(point, compressed + 1, curve->num_bytes);
  980. #endif
  981. curve->x_side(y, point, curve);
  982. curve->mod_sqrt(y, curve);
  983. if ((y[0] & 0x01) != (compressed[0] & 0x01)) {
  984. uECC_vli_sub(y, curve->p, y, curve->num_words);
  985. }
  986. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  987. uECC_vli_nativeToBytes(public_key, curve->num_bytes, point);
  988. uECC_vli_nativeToBytes(public_key + curve->num_bytes, curve->num_bytes, y);
  989. #endif
  990. }
  991. #endif /* uECC_SUPPORT_COMPRESSED_POINT */
  992. uECC_VLI_API int uECC_valid_point(const uECC_word_t *point, uECC_Curve curve) {
  993. uECC_word_t tmp1[uECC_MAX_WORDS];
  994. uECC_word_t tmp2[uECC_MAX_WORDS];
  995. wordcount_t num_words = curve->num_words;
  996. /* The point at infinity is invalid. */
  997. if (EccPoint_isZero(point, curve)) {
  998. return 0;
  999. }
  1000. /* x and y must be smaller than p. */
  1001. if (uECC_vli_cmp_unsafe(curve->p, point, num_words) != 1 ||
  1002. uECC_vli_cmp_unsafe(curve->p, point + num_words, num_words) != 1) {
  1003. return 0;
  1004. }
  1005. uECC_vli_modSquare_fast(tmp1, point + num_words, curve);
  1006. curve->x_side(tmp2, point, curve); /* tmp2 = x^3 + ax + b */
  1007. /* Make sure that y^2 == x^3 + ax + b */
  1008. return (int)(uECC_vli_equal(tmp1, tmp2, num_words));
  1009. }
  1010. int uECC_valid_public_key(const uint8_t *public_key, uECC_Curve curve) {
  1011. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1012. uECC_word_t *_public = (uECC_word_t *)public_key;
  1013. #else
  1014. uECC_word_t _public[uECC_MAX_WORDS * 2];
  1015. #endif
  1016. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  1017. uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
  1018. uECC_vli_bytesToNative(
  1019. _public + curve->num_words, public_key + curve->num_bytes, curve->num_bytes);
  1020. #endif
  1021. return uECC_valid_point(_public, curve);
  1022. }
  1023. int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve) {
  1024. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1025. uECC_word_t *_private = (uECC_word_t *)private_key;
  1026. uECC_word_t *_public = (uECC_word_t *)public_key;
  1027. #else
  1028. uECC_word_t _private[uECC_MAX_WORDS];
  1029. uECC_word_t _public[uECC_MAX_WORDS * 2];
  1030. #endif
  1031. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  1032. uECC_vli_bytesToNative(_private, private_key, BITS_TO_BYTES(curve->num_n_bits));
  1033. #endif
  1034. /* Make sure the private key is in the range [1, n-1]. */
  1035. if (uECC_vli_isZero(_private, BITS_TO_WORDS(curve->num_n_bits))) {
  1036. return 0;
  1037. }
  1038. if (uECC_vli_cmp(curve->n, _private, BITS_TO_WORDS(curve->num_n_bits)) != 1) {
  1039. return 0;
  1040. }
  1041. /* Compute public key. */
  1042. if (!EccPoint_compute_public_key(_public, _private, curve)) {
  1043. return 0;
  1044. }
  1045. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  1046. uECC_vli_nativeToBytes(public_key, curve->num_bytes, _public);
  1047. uECC_vli_nativeToBytes(
  1048. public_key + curve->num_bytes, curve->num_bytes, _public + curve->num_words);
  1049. #endif
  1050. return 1;
  1051. }
  1052. /* -------- ECDSA code -------- */
  1053. static void bits2int(uECC_word_t *native,
  1054. const uint8_t *bits,
  1055. unsigned bits_size,
  1056. uECC_Curve curve) {
  1057. unsigned num_n_bytes = BITS_TO_BYTES(curve->num_n_bits);
  1058. unsigned num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  1059. int shift;
  1060. uECC_word_t carry;
  1061. uECC_word_t *ptr;
  1062. if (bits_size > num_n_bytes) {
  1063. bits_size = num_n_bytes;
  1064. }
  1065. uECC_vli_clear(native, num_n_words);
  1066. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1067. bcopy((uint8_t *) native, bits, bits_size);
  1068. #else
  1069. uECC_vli_bytesToNative(native, bits, bits_size);
  1070. #endif
  1071. if (bits_size * 8 <= (unsigned)curve->num_n_bits) {
  1072. return;
  1073. }
  1074. shift = bits_size * 8 - curve->num_n_bits;
  1075. carry = 0;
  1076. ptr = native + num_n_words;
  1077. while (ptr-- > native) {
  1078. uECC_word_t temp = *ptr;
  1079. *ptr = (temp >> shift) | carry;
  1080. carry = temp << (uECC_WORD_BITS - shift);
  1081. }
  1082. /* Reduce mod curve_n */
  1083. if (uECC_vli_cmp_unsafe(curve->n, native, num_n_words) != 1) {
  1084. uECC_vli_sub(native, native, curve->n, num_n_words);
  1085. }
  1086. }
  1087. static int uECC_sign_with_k_internal(const uint8_t *private_key,
  1088. const uint8_t *message_hash,
  1089. unsigned hash_size,
  1090. uECC_word_t *k,
  1091. uint8_t *signature,
  1092. uECC_Curve curve) {
  1093. uECC_word_t tmp[uECC_MAX_WORDS];
  1094. uECC_word_t s[uECC_MAX_WORDS];
  1095. uECC_word_t *k2[2] = {tmp, s};
  1096. uECC_word_t *initial_Z = 0;
  1097. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1098. uECC_word_t *p = (uECC_word_t *)signature;
  1099. #else
  1100. uECC_word_t p[uECC_MAX_WORDS * 2];
  1101. #endif
  1102. uECC_word_t carry;
  1103. wordcount_t num_words = curve->num_words;
  1104. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  1105. bitcount_t num_n_bits = curve->num_n_bits;
  1106. /* Make sure 0 < k < curve_n */
  1107. if (uECC_vli_isZero(k, num_words) || uECC_vli_cmp(curve->n, k, num_n_words) != 1) {
  1108. return 0;
  1109. }
  1110. carry = regularize_k(k, tmp, s, curve);
  1111. /* If an RNG function was specified, try to get a random initial Z value to improve
  1112. protection against side-channel attacks. */
  1113. if (g_rng_function) {
  1114. if (!uECC_generate_random_int(k2[carry], curve->p, num_words)) {
  1115. return 0;
  1116. }
  1117. initial_Z = k2[carry];
  1118. }
  1119. EccPoint_mult(p, curve->G, k2[!carry], initial_Z, num_n_bits + 1, curve);
  1120. if (uECC_vli_isZero(p, num_words)) {
  1121. return 0;
  1122. }
  1123. /* If an RNG function was specified, get a random number
  1124. to prevent side channel analysis of k. */
  1125. if (!g_rng_function) {
  1126. uECC_vli_clear(tmp, num_n_words);
  1127. tmp[0] = 1;
  1128. } else if (!uECC_generate_random_int(tmp, curve->n, num_n_words)) {
  1129. return 0;
  1130. }
  1131. /* Prevent side channel analysis of uECC_vli_modInv() to determine
  1132. bits of k / the private key by premultiplying by a random number */
  1133. uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k' = rand * k */
  1134. uECC_vli_modInv(k, k, curve->n, num_n_words); /* k = 1 / k' */
  1135. uECC_vli_modMult(k, k, tmp, curve->n, num_n_words); /* k = 1 / k */
  1136. #if uECC_VLI_NATIVE_LITTLE_ENDIAN == 0
  1137. uECC_vli_nativeToBytes(signature, curve->num_bytes, p); /* store r */
  1138. #endif
  1139. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1140. bcopy((uint8_t *) tmp, private_key, BITS_TO_BYTES(curve->num_n_bits));
  1141. #else
  1142. uECC_vli_bytesToNative(tmp, private_key, BITS_TO_BYTES(curve->num_n_bits)); /* tmp = d */
  1143. #endif
  1144. s[num_n_words - 1] = 0;
  1145. uECC_vli_set(s, p, num_words);
  1146. uECC_vli_modMult(s, tmp, s, curve->n, num_n_words); /* s = r*d */
  1147. bits2int(tmp, message_hash, hash_size, curve);
  1148. uECC_vli_modAdd(s, tmp, s, curve->n, num_n_words); /* s = e + r*d */
  1149. uECC_vli_modMult(s, s, k, curve->n, num_n_words); /* s = (e + r*d) / k */
  1150. if (uECC_vli_numBits(s, num_n_words) > (bitcount_t)curve->num_bytes * 8) {
  1151. return 0;
  1152. }
  1153. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1154. bcopy((uint8_t *) signature + curve->num_bytes, (uint8_t *) s, curve->num_bytes);
  1155. #else
  1156. uECC_vli_nativeToBytes(signature + curve->num_bytes, curve->num_bytes, s);
  1157. #endif
  1158. return 1;
  1159. }
  1160. /* For testing - sign with an explicitly specified k value */
  1161. int uECC_sign_with_k(const uint8_t *private_key,
  1162. const uint8_t *message_hash,
  1163. unsigned hash_size,
  1164. const uint8_t *k,
  1165. uint8_t *signature,
  1166. uECC_Curve curve) {
  1167. uECC_word_t k2[uECC_MAX_WORDS];
  1168. bits2int(k2, k, BITS_TO_BYTES(curve->num_n_bits), curve);
  1169. return uECC_sign_with_k_internal(private_key, message_hash, hash_size, k2, signature, curve);
  1170. }
  1171. int uECC_sign(const uint8_t *private_key,
  1172. const uint8_t *message_hash,
  1173. unsigned hash_size,
  1174. uint8_t *signature,
  1175. uECC_Curve curve) {
  1176. uECC_word_t k[uECC_MAX_WORDS];
  1177. uECC_word_t tries;
  1178. for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
  1179. if (!uECC_generate_random_int(k, curve->n, BITS_TO_WORDS(curve->num_n_bits))) {
  1180. return 0;
  1181. }
  1182. if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, k, signature, curve)) {
  1183. return 1;
  1184. }
  1185. }
  1186. return 0;
  1187. }
  1188. /* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always
  1189. the same size as the hash result size. */
  1190. static void HMAC_init(const uECC_HashContext *hash_context, const uint8_t *K) {
  1191. uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size;
  1192. unsigned i;
  1193. for (i = 0; i < hash_context->result_size; ++i)
  1194. pad[i] = K[i] ^ 0x36;
  1195. for (; i < hash_context->block_size; ++i)
  1196. pad[i] = 0x36;
  1197. hash_context->init_hash(hash_context);
  1198. hash_context->update_hash(hash_context, pad, hash_context->block_size);
  1199. }
  1200. static void HMAC_update(const uECC_HashContext *hash_context,
  1201. const uint8_t *message,
  1202. unsigned message_size) {
  1203. hash_context->update_hash(hash_context, message, message_size);
  1204. }
  1205. static void HMAC_finish(const uECC_HashContext *hash_context,
  1206. const uint8_t *K,
  1207. uint8_t *result) {
  1208. uint8_t *pad = hash_context->tmp + 2 * hash_context->result_size;
  1209. unsigned i;
  1210. for (i = 0; i < hash_context->result_size; ++i)
  1211. pad[i] = K[i] ^ 0x5c;
  1212. for (; i < hash_context->block_size; ++i)
  1213. pad[i] = 0x5c;
  1214. hash_context->finish_hash(hash_context, result);
  1215. hash_context->init_hash(hash_context);
  1216. hash_context->update_hash(hash_context, pad, hash_context->block_size);
  1217. hash_context->update_hash(hash_context, result, hash_context->result_size);
  1218. hash_context->finish_hash(hash_context, result);
  1219. }
  1220. /* V = HMAC_K(V) */
  1221. static void update_V(const uECC_HashContext *hash_context, uint8_t *K, uint8_t *V) {
  1222. HMAC_init(hash_context, K);
  1223. HMAC_update(hash_context, V, hash_context->result_size);
  1224. HMAC_finish(hash_context, K, V);
  1225. }
  1226. /* Deterministic signing, similar to RFC 6979. Differences are:
  1227. * We just use H(m) directly rather than bits2octets(H(m))
  1228. (it is not reduced modulo curve_n).
  1229. * We generate a value for k (aka T) directly rather than converting endianness.
  1230. Layout of hash_context->tmp: <K> | <V> | (1 byte overlapped 0x00 or 0x01) / <HMAC pad> */
  1231. int uECC_sign_deterministic(const uint8_t *private_key,
  1232. const uint8_t *message_hash,
  1233. unsigned hash_size,
  1234. const uECC_HashContext *hash_context,
  1235. uint8_t *signature,
  1236. uECC_Curve curve) {
  1237. uint8_t *K = hash_context->tmp;
  1238. uint8_t *V = K + hash_context->result_size;
  1239. wordcount_t num_bytes = curve->num_bytes;
  1240. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  1241. bitcount_t num_n_bits = curve->num_n_bits;
  1242. uECC_word_t tries;
  1243. unsigned i;
  1244. for (i = 0; i < hash_context->result_size; ++i) {
  1245. V[i] = 0x01;
  1246. K[i] = 0;
  1247. }
  1248. /* K = HMAC_K(V || 0x00 || int2octets(x) || h(m)) */
  1249. HMAC_init(hash_context, K);
  1250. V[hash_context->result_size] = 0x00;
  1251. HMAC_update(hash_context, V, hash_context->result_size + 1);
  1252. HMAC_update(hash_context, private_key, num_bytes);
  1253. HMAC_update(hash_context, message_hash, hash_size);
  1254. HMAC_finish(hash_context, K, K);
  1255. update_V(hash_context, K, V);
  1256. /* K = HMAC_K(V || 0x01 || int2octets(x) || h(m)) */
  1257. HMAC_init(hash_context, K);
  1258. V[hash_context->result_size] = 0x01;
  1259. HMAC_update(hash_context, V, hash_context->result_size + 1);
  1260. HMAC_update(hash_context, private_key, num_bytes);
  1261. HMAC_update(hash_context, message_hash, hash_size);
  1262. HMAC_finish(hash_context, K, K);
  1263. update_V(hash_context, K, V);
  1264. for (tries = 0; tries < uECC_RNG_MAX_TRIES; ++tries) {
  1265. uECC_word_t T[uECC_MAX_WORDS];
  1266. uint8_t *T_ptr = (uint8_t *)T;
  1267. wordcount_t T_bytes = 0;
  1268. for (;;) {
  1269. update_V(hash_context, K, V);
  1270. for (i = 0; i < hash_context->result_size; ++i) {
  1271. T_ptr[T_bytes++] = V[i];
  1272. if (T_bytes >= num_n_words * uECC_WORD_SIZE) {
  1273. goto filled;
  1274. }
  1275. }
  1276. }
  1277. filled:
  1278. if ((bitcount_t)num_n_words * uECC_WORD_SIZE * 8 > num_n_bits) {
  1279. uECC_word_t mask = (uECC_word_t)-1;
  1280. T[num_n_words - 1] &=
  1281. mask >> ((bitcount_t)(num_n_words * uECC_WORD_SIZE * 8 - num_n_bits));
  1282. }
  1283. if (uECC_sign_with_k_internal(private_key, message_hash, hash_size, T, signature, curve)) {
  1284. return 1;
  1285. }
  1286. /* K = HMAC_K(V || 0x00) */
  1287. HMAC_init(hash_context, K);
  1288. V[hash_context->result_size] = 0x00;
  1289. HMAC_update(hash_context, V, hash_context->result_size + 1);
  1290. HMAC_finish(hash_context, K, K);
  1291. update_V(hash_context, K, V);
  1292. }
  1293. return 0;
  1294. }
  1295. static bitcount_t smax(bitcount_t a, bitcount_t b) {
  1296. return (a > b ? a : b);
  1297. }
  1298. int uECC_verify(const uint8_t *public_key,
  1299. const uint8_t *message_hash,
  1300. unsigned hash_size,
  1301. const uint8_t *signature,
  1302. uECC_Curve curve) {
  1303. uECC_word_t u1[uECC_MAX_WORDS], u2[uECC_MAX_WORDS];
  1304. uECC_word_t z[uECC_MAX_WORDS];
  1305. uECC_word_t sum[uECC_MAX_WORDS * 2];
  1306. uECC_word_t rx[uECC_MAX_WORDS];
  1307. uECC_word_t ry[uECC_MAX_WORDS];
  1308. uECC_word_t tx[uECC_MAX_WORDS];
  1309. uECC_word_t ty[uECC_MAX_WORDS];
  1310. uECC_word_t tz[uECC_MAX_WORDS];
  1311. const uECC_word_t *points[4];
  1312. const uECC_word_t *point;
  1313. bitcount_t num_bits;
  1314. bitcount_t i;
  1315. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1316. uECC_word_t *_public = (uECC_word_t *)public_key;
  1317. #else
  1318. uECC_word_t _public[uECC_MAX_WORDS * 2];
  1319. #endif
  1320. uECC_word_t r[uECC_MAX_WORDS], s[uECC_MAX_WORDS];
  1321. wordcount_t num_words = curve->num_words;
  1322. wordcount_t num_n_words = BITS_TO_WORDS(curve->num_n_bits);
  1323. rx[num_n_words - 1] = 0;
  1324. r[num_n_words - 1] = 0;
  1325. s[num_n_words - 1] = 0;
  1326. #if uECC_VLI_NATIVE_LITTLE_ENDIAN
  1327. bcopy((uint8_t *) r, signature, curve->num_bytes);
  1328. bcopy((uint8_t *) s, signature + curve->num_bytes, curve->num_bytes);
  1329. #else
  1330. uECC_vli_bytesToNative(_public, public_key, curve->num_bytes);
  1331. uECC_vli_bytesToNative(
  1332. _public + num_words, public_key + curve->num_bytes, curve->num_bytes);
  1333. uECC_vli_bytesToNative(r, signature, curve->num_bytes);
  1334. uECC_vli_bytesToNative(s, signature + curve->num_bytes, curve->num_bytes);
  1335. #endif
  1336. /* r, s must not be 0. */
  1337. if (uECC_vli_isZero(r, num_words) || uECC_vli_isZero(s, num_words)) {
  1338. return 0;
  1339. }
  1340. /* r, s must be < n. */
  1341. if (uECC_vli_cmp_unsafe(curve->n, r, num_n_words) != 1 ||
  1342. uECC_vli_cmp_unsafe(curve->n, s, num_n_words) != 1) {
  1343. return 0;
  1344. }
  1345. /* Calculate u1 and u2. */
  1346. uECC_vli_modInv(z, s, curve->n, num_n_words); /* z = 1/s */
  1347. u1[num_n_words - 1] = 0;
  1348. bits2int(u1, message_hash, hash_size, curve);
  1349. uECC_vli_modMult(u1, u1, z, curve->n, num_n_words); /* u1 = e/s */
  1350. uECC_vli_modMult(u2, r, z, curve->n, num_n_words); /* u2 = r/s */
  1351. /* Calculate sum = G + Q. */
  1352. uECC_vli_set(sum, _public, num_words);
  1353. uECC_vli_set(sum + num_words, _public + num_words, num_words);
  1354. uECC_vli_set(tx, curve->G, num_words);
  1355. uECC_vli_set(ty, curve->G + num_words, num_words);
  1356. uECC_vli_modSub(z, sum, tx, curve->p, num_words); /* z = x2 - x1 */
  1357. XYcZ_add(tx, ty, sum, sum + num_words, curve);
  1358. uECC_vli_modInv(z, z, curve->p, num_words); /* z = 1/z */
  1359. apply_z(sum, sum + num_words, z, curve);
  1360. /* Use Shamir's trick to calculate u1*G + u2*Q */
  1361. points[0] = 0;
  1362. points[1] = curve->G;
  1363. points[2] = _public;
  1364. points[3] = sum;
  1365. num_bits = smax(uECC_vli_numBits(u1, num_n_words),
  1366. uECC_vli_numBits(u2, num_n_words));
  1367. point = points[(!!uECC_vli_testBit(u1, num_bits - 1)) |
  1368. ((!!uECC_vli_testBit(u2, num_bits - 1)) << 1)];
  1369. uECC_vli_set(rx, point, num_words);
  1370. uECC_vli_set(ry, point + num_words, num_words);
  1371. uECC_vli_clear(z, num_words);
  1372. z[0] = 1;
  1373. for (i = num_bits - 2; i >= 0; --i) {
  1374. uECC_word_t index;
  1375. curve->double_jacobian(rx, ry, z, curve);
  1376. index = (!!uECC_vli_testBit(u1, i)) | ((!!uECC_vli_testBit(u2, i)) << 1);
  1377. point = points[index];
  1378. if (point) {
  1379. uECC_vli_set(tx, point, num_words);
  1380. uECC_vli_set(ty, point + num_words, num_words);
  1381. apply_z(tx, ty, z, curve);
  1382. uECC_vli_modSub(tz, rx, tx, curve->p, num_words); /* Z = x2 - x1 */
  1383. XYcZ_add(tx, ty, rx, ry, curve);
  1384. uECC_vli_modMult_fast(z, z, tz, curve);
  1385. }
  1386. }
  1387. uECC_vli_modInv(z, z, curve->p, num_words); /* Z = 1/Z */
  1388. apply_z(rx, ry, z, curve);
  1389. /* v = x1 (mod n) */
  1390. if (uECC_vli_cmp_unsafe(curve->n, rx, num_n_words) != 1) {
  1391. uECC_vli_sub(rx, rx, curve->n, num_n_words);
  1392. }
  1393. /* Accept only if v == r. */
  1394. return (int)(uECC_vli_equal(rx, r, num_words));
  1395. }
  1396. #if uECC_ENABLE_VLI_API
  1397. unsigned uECC_curve_num_words(uECC_Curve curve) {
  1398. return curve->num_words;
  1399. }
  1400. unsigned uECC_curve_num_bytes(uECC_Curve curve) {
  1401. return curve->num_bytes;
  1402. }
  1403. unsigned uECC_curve_num_bits(uECC_Curve curve) {
  1404. return curve->num_bytes * 8;
  1405. }
  1406. unsigned uECC_curve_num_n_words(uECC_Curve curve) {
  1407. return BITS_TO_WORDS(curve->num_n_bits);
  1408. }
  1409. unsigned uECC_curve_num_n_bytes(uECC_Curve curve) {
  1410. return BITS_TO_BYTES(curve->num_n_bits);
  1411. }
  1412. unsigned uECC_curve_num_n_bits(uECC_Curve curve) {
  1413. return curve->num_n_bits;
  1414. }
  1415. const uECC_word_t *uECC_curve_p(uECC_Curve curve) {
  1416. return curve->p;
  1417. }
  1418. const uECC_word_t *uECC_curve_n(uECC_Curve curve) {
  1419. return curve->n;
  1420. }
  1421. const uECC_word_t *uECC_curve_G(uECC_Curve curve) {
  1422. return curve->G;
  1423. }
  1424. const uECC_word_t *uECC_curve_b(uECC_Curve curve) {
  1425. return curve->b;
  1426. }
  1427. #if uECC_SUPPORT_COMPRESSED_POINT
  1428. void uECC_vli_mod_sqrt(uECC_word_t *a, uECC_Curve curve) {
  1429. curve->mod_sqrt(a, curve);
  1430. }
  1431. #endif
  1432. void uECC_vli_mmod_fast(uECC_word_t *result, uECC_word_t *product, uECC_Curve curve) {
  1433. #if (uECC_OPTIMIZATION_LEVEL > 0)
  1434. curve->mmod_fast(result, product);
  1435. #else
  1436. uECC_vli_mmod(result, product, curve->p, curve->num_words);
  1437. #endif
  1438. }
  1439. void uECC_point_mult(uECC_word_t *result,
  1440. const uECC_word_t *point,
  1441. const uECC_word_t *scalar,
  1442. uECC_Curve curve) {
  1443. uECC_word_t tmp1[uECC_MAX_WORDS];
  1444. uECC_word_t tmp2[uECC_MAX_WORDS];
  1445. uECC_word_t *p2[2] = {tmp1, tmp2};
  1446. uECC_word_t carry = regularize_k(scalar, tmp1, tmp2, curve);
  1447. EccPoint_mult(result, point, p2[!carry], 0, curve->num_n_bits + 1, curve);
  1448. }
  1449. #endif /* uECC_ENABLE_VLI_API */