@fails-components/webtransport 0.0.1-rc.0 → 0.0.1-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (384) hide show
  1. package/.github/workflows/npm-publish-packages.yml +0 -0
  2. package/CMakeLists.txt +2 -0
  3. package/package.json +1 -1
  4. package/readme.md +0 -0
  5. package/src/http3serversession.h +1 -1
  6. package/src/webtransport.js +4 -2
  7. package/third_party/boringssl/src/CMakeLists.txt +9 -12
  8. package/third_party/boringssl/src/crypto/CMakeLists.txt +2 -3
  9. package/third_party/boringssl/src/crypto/asn1/time_support.c +206 -206
  10. package/third_party/boringssl/src/crypto/bio/socket_helper.c +124 -122
  11. package/third_party/boringssl/src/crypto/evp/digestsign.c +268 -231
  12. package/third_party/boringssl/src/crypto/evp/p_ec.c +286 -286
  13. package/third_party/boringssl/src/crypto/fipsmodule/aes/key_wrap.c +246 -236
  14. package/third_party/boringssl/src/crypto/fipsmodule/aes/mode_wrappers.c +124 -122
  15. package/third_party/boringssl/src/crypto/fipsmodule/bcm.c +3 -0
  16. package/third_party/boringssl/src/crypto/fipsmodule/bn/bytes.c +246 -230
  17. package/third_party/boringssl/src/crypto/fipsmodule/bn/internal.h +734 -715
  18. package/third_party/boringssl/src/crypto/fipsmodule/bn/random.c +349 -341
  19. package/third_party/boringssl/src/crypto/fipsmodule/cipher/cipher.c +670 -648
  20. package/third_party/boringssl/src/crypto/fipsmodule/cipher/e_aes.c +1504 -1472
  21. package/third_party/boringssl/src/crypto/{cipher_extra → fipsmodule/cipher}/e_aesccm.c +435 -446
  22. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cavp_3des_cmac_tests.txt +0 -0
  23. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cavp_aes128_cmac_tests.txt +0 -0
  24. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cavp_aes192_cmac_tests.txt +0 -0
  25. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cavp_aes256_cmac_tests.txt +0 -0
  26. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cmac.c +318 -278
  27. package/third_party/boringssl/src/crypto/{cmac → fipsmodule/cmac}/cmac_test.cc +268 -267
  28. package/third_party/boringssl/src/crypto/fipsmodule/dh/dh.c +5 -1
  29. package/third_party/boringssl/src/crypto/fipsmodule/ec/ec.c +11 -17
  30. package/third_party/boringssl/src/crypto/fipsmodule/ec/ec_key.c +15 -4
  31. package/third_party/boringssl/src/crypto/fipsmodule/ec/internal.h +2 -6
  32. package/third_party/boringssl/src/crypto/fipsmodule/ec/p224-64.c +1164 -1180
  33. package/third_party/boringssl/src/crypto/fipsmodule/ec/p256-nistz.c +3 -3
  34. package/third_party/boringssl/src/crypto/fipsmodule/ec/p256-nistz_test.cc +2 -2
  35. package/third_party/boringssl/src/crypto/fipsmodule/ec/p256.c +44 -33
  36. package/third_party/boringssl/src/crypto/fipsmodule/ec/scalar.c +169 -175
  37. package/third_party/boringssl/src/crypto/fipsmodule/ec/simple.c +352 -357
  38. package/third_party/boringssl/src/crypto/fipsmodule/ecdh/ecdh.c +4 -0
  39. package/third_party/boringssl/src/crypto/fipsmodule/ecdsa/ecdsa.c +14 -9
  40. package/third_party/boringssl/src/crypto/fipsmodule/hmac/hmac.c +256 -235
  41. package/third_party/boringssl/src/crypto/fipsmodule/rand/ctrdrbg.c +204 -202
  42. package/third_party/boringssl/src/crypto/fipsmodule/rsa/padding.c +702 -695
  43. package/third_party/boringssl/src/crypto/fipsmodule/rsa/rsa_impl.c +7 -2
  44. package/third_party/boringssl/src/crypto/fipsmodule/self_check/self_check.c +7 -0
  45. package/third_party/boringssl/src/crypto/fipsmodule/service_indicator/internal.h +89 -0
  46. package/third_party/boringssl/src/crypto/fipsmodule/service_indicator/service_indicator.c +333 -0
  47. package/third_party/boringssl/src/crypto/fipsmodule/service_indicator/service_indicator_test.cc +2410 -0
  48. package/third_party/boringssl/src/crypto/fipsmodule/sha/sha1.c +359 -357
  49. package/third_party/boringssl/src/crypto/fipsmodule/sha/sha256.c +325 -321
  50. package/third_party/boringssl/src/crypto/fipsmodule/sha/sha512.c +510 -508
  51. package/third_party/boringssl/src/crypto/fipsmodule/tls/kdf.c +177 -165
  52. package/third_party/boringssl/src/crypto/internal.h +13 -0
  53. package/third_party/boringssl/src/crypto/trust_token/trust_token_test.cc +884 -884
  54. package/third_party/boringssl/src/crypto/x509/internal.h +0 -2
  55. package/third_party/boringssl/src/crypto/x509/t_crl.c +148 -148
  56. package/third_party/boringssl/src/crypto/x509/t_req.c +249 -250
  57. package/third_party/boringssl/src/crypto/x509/t_x509.c +2 -3
  58. package/third_party/boringssl/src/crypto/x509/x509_req.c +262 -304
  59. package/third_party/boringssl/src/crypto/x509/x509_set.c +250 -240
  60. package/third_party/boringssl/src/crypto/x509/x509_test.cc +466 -4
  61. package/third_party/boringssl/src/crypto/x509/x509cset.c +292 -279
  62. package/third_party/boringssl/src/crypto/x509/x509rset.c +89 -86
  63. package/third_party/boringssl/src/crypto/x509/x_crl.c +37 -125
  64. package/third_party/boringssl/src/crypto/x509/x_req.c +114 -109
  65. package/third_party/boringssl/src/crypto/x509/x_x509.c +394 -394
  66. package/third_party/boringssl/src/crypto/x509v3/v3_akey.c +11 -16
  67. package/third_party/boringssl/src/crypto/x509v3/v3_alt.c +644 -642
  68. package/third_party/boringssl/src/crypto/x509v3/v3_bcons.c +130 -133
  69. package/third_party/boringssl/src/crypto/x509v3/v3_bitst.c +149 -144
  70. package/third_party/boringssl/src/crypto/x509v3/v3_cpols.c +496 -500
  71. package/third_party/boringssl/src/crypto/x509v3/v3_enum.c +105 -106
  72. package/third_party/boringssl/src/crypto/x509v3/v3_ia5.c +126 -121
  73. package/third_party/boringssl/src/crypto/x509v3/v3_info.c +206 -218
  74. package/third_party/boringssl/src/crypto/x509v3/v3_int.c +97 -91
  75. package/third_party/boringssl/src/crypto/x509v3/v3_pci.c +290 -289
  76. package/third_party/boringssl/src/crypto/x509v3/v3_skey.c +161 -156
  77. package/third_party/boringssl/src/crypto/x509v3/v3_utl.c +5 -3
  78. package/third_party/boringssl/src/include/openssl/aead.h +480 -480
  79. package/third_party/boringssl/src/include/openssl/asn1.h +2 -0
  80. package/third_party/boringssl/src/include/openssl/base.h +1 -1
  81. package/third_party/boringssl/src/include/openssl/service_indicator.h +96 -0
  82. package/third_party/boringssl/src/include/openssl/ssl.h +7 -0
  83. package/third_party/boringssl/src/include/openssl/x509.h +11 -33
  84. package/third_party/boringssl/src/include/openssl/x509v3.h +990 -1018
  85. package/third_party/boringssl/src/sources.cmake +4 -4
  86. package/third_party/boringssl/src/ssl/internal.h +10 -0
  87. package/third_party/boringssl/src/ssl/ssl_lib.cc +3081 -3072
  88. package/third_party/boringssl/src/ssl/ssl_test.cc +46 -0
  89. package/third_party/boringssl/src/ssl/tls13_server.cc +4 -6
  90. package/third_party/boringssl/src/util/bot/DEPS +14 -27
  91. package/third_party/boringssl/src/util/bot/UPDATING +3 -9
  92. package/third_party/boringssl/src/util/bot/update_clang.py +172 -172
  93. package/third_party/boringssl/src/util/bot/vs_toolchain.py +3 -3
  94. package/third_party/quiche/.bazelrc +8 -0
  95. package/third_party/quiche/BUILD.bazel +7 -0
  96. package/third_party/quiche/WHITESPACE +3 -1
  97. package/third_party/quiche/WORKSPACE.bazel +87 -0
  98. package/third_party/quiche/build/BUILD.bazel +7 -0
  99. package/third_party/quiche/build/source_list.bzl +1511 -0
  100. package/third_party/quiche/build/source_list.gni +1511 -0
  101. package/third_party/quiche/build/source_list.json +1511 -0
  102. package/third_party/quiche/build/test.bzl +26 -0
  103. package/third_party/quiche/build/zlib.BUILD +25 -0
  104. package/third_party/quiche/quiche/BUILD.bazel +270 -0
  105. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_enums.cc +3 -3
  106. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_enums.h +7 -7
  107. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_frame.cc +39 -18
  108. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_frame.h +11 -10
  109. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_frame_test.cc +67 -63
  110. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_headers.cc +13 -12
  111. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_headers.h +16 -8
  112. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_headers_test.cc +9 -9
  113. package/third_party/quiche/quiche/{common/balsa → balsa}/balsa_visitor_interface.h +4 -4
  114. package/third_party/quiche/quiche/{common/balsa → balsa}/framer_interface.h +3 -3
  115. package/third_party/quiche/quiche/{common/balsa → balsa}/header_api.h +3 -3
  116. package/third_party/quiche/quiche/{common/balsa → balsa}/header_properties.cc +1 -1
  117. package/third_party/quiche/quiche/{common/balsa → balsa}/header_properties.h +3 -3
  118. package/third_party/quiche/quiche/{common/balsa → balsa}/header_properties_test.cc +1 -1
  119. package/third_party/quiche/quiche/{common/balsa → balsa}/http_validation_policy.cc +1 -1
  120. package/third_party/quiche/quiche/{common/balsa → balsa}/http_validation_policy.h +3 -3
  121. package/third_party/quiche/quiche/{common/balsa → balsa}/noop_balsa_visitor.h +4 -4
  122. package/third_party/quiche/quiche/{common/balsa → balsa}/simple_buffer.cc +22 -29
  123. package/third_party/quiche/quiche/{common/balsa → balsa}/simple_buffer.h +18 -16
  124. package/third_party/quiche/quiche/{common/balsa → balsa}/simple_buffer_test.cc +79 -32
  125. package/third_party/quiche/quiche/{common/balsa → balsa}/standard_header_map.cc +1 -1
  126. package/third_party/quiche/quiche/{common/balsa → balsa}/standard_header_map.h +3 -3
  127. package/third_party/quiche/quiche/common/platform/api/quiche_command_line_flags.h +6 -1
  128. package/third_party/quiche/quiche/common/platform/api/quiche_flags.h +8 -0
  129. package/third_party/quiche/quiche/common/platform/api/quiche_logging.h +0 -3
  130. package/third_party/quiche/quiche/common/platform/api/quiche_lower_case_string_test.cc +29 -0
  131. package/third_party/quiche/quiche/common/platform/api/quiche_test.h +5 -7
  132. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quic_flags_impl.h +1 -1
  133. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_bug_tracker_impl.h +3 -2
  134. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_command_line_flags_impl.cc +41 -0
  135. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_command_line_flags_impl.h +33 -0
  136. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_expect_bug_impl.h +15 -0
  137. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_logging_impl.h +84 -50
  138. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_lower_case_string_impl.h +25 -0
  139. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_stack_trace_impl.cc +1 -1
  140. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_test_impl.cc +25 -0
  141. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_test_impl.h +56 -0
  142. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_test_output_impl.h +27 -0
  143. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_thread_impl.h +26 -0
  144. package/third_party/quiche/quiche/common/platform/default/quiche_platform_impl/quiche_url_utils_impl.cc +1 -0
  145. package/third_party/quiche/quiche/common/quiche_buffer_allocator_test.cc +1 -1
  146. package/third_party/quiche/quiche/common/quiche_mem_slice_storage.h +2 -3
  147. package/third_party/quiche/quiche/common/structured_headers.cc +14 -12
  148. package/third_party/quiche/quiche/http2/adapter/event_forwarder.cc +7 -5
  149. package/third_party/quiche/quiche/http2/adapter/event_forwarder.h +4 -2
  150. package/third_party/quiche/quiche/http2/adapter/event_forwarder_test.cc +14 -9
  151. package/third_party/quiche/quiche/http2/adapter/header_validator.cc +43 -19
  152. package/third_party/quiche/quiche/http2/adapter/header_validator.h +11 -40
  153. package/third_party/quiche/quiche/http2/adapter/header_validator_base.h +69 -0
  154. package/third_party/quiche/quiche/http2/adapter/header_validator_test.cc +73 -1
  155. package/third_party/quiche/quiche/http2/adapter/nghttp2_adapter_test.cc +66 -0
  156. package/third_party/quiche/quiche/http2/adapter/nghttp2_session_test.cc +8 -5
  157. package/third_party/quiche/quiche/http2/adapter/nghttp2_test.cc +1 -1
  158. package/third_party/quiche/quiche/http2/adapter/noop_header_validator.cc +22 -0
  159. package/third_party/quiche/quiche/http2/adapter/noop_header_validator.h +25 -0
  160. package/third_party/quiche/quiche/http2/adapter/noop_header_validator_test.cc +523 -0
  161. package/third_party/quiche/quiche/http2/adapter/oghttp2_adapter_test.cc +186 -5
  162. package/third_party/quiche/quiche/http2/adapter/oghttp2_session.cc +37 -43
  163. package/third_party/quiche/quiche/http2/adapter/oghttp2_session.h +22 -23
  164. package/third_party/quiche/quiche/http2/adapter/test_utils.cc +1 -1
  165. package/third_party/quiche/quiche/http2/adapter/window_manager_test.cc +11 -5
  166. package/third_party/quiche/quiche/http2/core/http2_trace_logging.cc +13 -11
  167. package/third_party/quiche/quiche/http2/core/http2_trace_logging.h +5 -4
  168. package/third_party/quiche/quiche/http2/core/priority_write_scheduler.h +42 -36
  169. package/third_party/quiche/quiche/http2/core/priority_write_scheduler_test.cc +2 -2
  170. package/third_party/quiche/quiche/http2/decoder/decode_buffer_test.cc +9 -9
  171. package/third_party/quiche/quiche/http2/decoder/decode_http2_structures_test.cc +1 -1
  172. package/third_party/quiche/quiche/http2/decoder/http2_frame_decoder_test.cc +14 -14
  173. package/third_party/quiche/quiche/http2/decoder/http2_structure_decoder_test.cc +17 -17
  174. package/third_party/quiche/quiche/http2/decoder/payload_decoders/altsvc_payload_decoder_test.cc +1 -1
  175. package/third_party/quiche/quiche/http2/decoder/payload_decoders/continuation_payload_decoder_test.cc +1 -1
  176. package/third_party/quiche/quiche/http2/decoder/payload_decoders/data_payload_decoder_test.cc +2 -2
  177. package/third_party/quiche/quiche/http2/decoder/payload_decoders/goaway_payload_decoder_test.cc +1 -1
  178. package/third_party/quiche/quiche/http2/decoder/payload_decoders/headers_payload_decoder_test.cc +1 -1
  179. package/third_party/quiche/quiche/http2/decoder/payload_decoders/ping_payload_decoder_test.cc +1 -1
  180. package/third_party/quiche/quiche/http2/decoder/payload_decoders/priority_payload_decoder_test.cc +1 -1
  181. package/third_party/quiche/quiche/http2/decoder/payload_decoders/priority_update_payload_decoder_test.cc +1 -1
  182. package/third_party/quiche/quiche/http2/decoder/payload_decoders/push_promise_payload_decoder_test.cc +1 -1
  183. package/third_party/quiche/quiche/http2/decoder/payload_decoders/rst_stream_payload_decoder_test.cc +1 -1
  184. package/third_party/quiche/quiche/http2/decoder/payload_decoders/settings_payload_decoder_test.cc +1 -1
  185. package/third_party/quiche/quiche/http2/decoder/payload_decoders/unknown_payload_decoder_test.cc +1 -1
  186. package/third_party/quiche/quiche/http2/decoder/payload_decoders/window_update_payload_decoder_test.cc +1 -1
  187. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_block_decoder_test.cc +2 -2
  188. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_decoder_state_test.cc +8 -8
  189. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_decoder_string_buffer_test.cc +4 -3
  190. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_decoder_tables_test.cc +17 -17
  191. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_decoder_test.cc +25 -25
  192. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_entry_decoder_test.cc +2 -2
  193. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_entry_type_decoder_test.cc +7 -6
  194. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_string_decoder_test.cc +6 -6
  195. package/third_party/quiche/quiche/http2/hpack/decoder/hpack_whole_entry_buffer_test.cc +1 -1
  196. package/third_party/quiche/quiche/http2/hpack/huffman/hpack_huffman_decoder_test.cc +2 -2
  197. package/third_party/quiche/quiche/http2/hpack/huffman/hpack_huffman_encoder_test.cc +1 -1
  198. package/third_party/quiche/quiche/http2/hpack/huffman/hpack_huffman_transcoder_test.cc +5 -5
  199. package/third_party/quiche/quiche/http2/hpack/varint/hpack_varint_decoder_test.cc +4 -4
  200. package/third_party/quiche/quiche/http2/hpack/varint/hpack_varint_round_trip_test.cc +1 -1
  201. package/third_party/quiche/quiche/http2/http2_constants_test.cc +1 -1
  202. package/third_party/quiche/quiche/http2/http2_structures_test.cc +23 -22
  203. package/third_party/quiche/quiche/http2/test_tools/frame_decoder_state_test_util.cc +1 -1
  204. package/third_party/quiche/quiche/http2/test_tools/frame_decoder_state_test_util.h +1 -1
  205. package/third_party/quiche/quiche/http2/test_tools/frame_parts.cc +38 -38
  206. package/third_party/quiche/quiche/http2/test_tools/hpack_block_collector.cc +15 -15
  207. package/third_party/quiche/quiche/http2/test_tools/hpack_entry_collector.cc +24 -22
  208. package/third_party/quiche/quiche/http2/test_tools/hpack_string_collector.cc +5 -5
  209. package/third_party/quiche/quiche/http2/test_tools/http2_frame_builder_test.cc +70 -89
  210. package/third_party/quiche/quiche/http2/test_tools/payload_decoder_base_test_util.cc +1 -1
  211. package/third_party/quiche/quiche/http2/test_tools/payload_decoder_base_test_util.h +29 -26
  212. package/third_party/quiche/quiche/http2/test_tools/{random_decoder_test.cc → random_decoder_test_base.cc} +13 -10
  213. package/third_party/quiche/quiche/http2/test_tools/{random_decoder_test.h → random_decoder_test_base.h} +15 -17
  214. package/third_party/quiche/quiche/http2/test_tools/{random_decoder_test_test.cc → random_decoder_test_base_test.cc} +1 -1
  215. package/third_party/quiche/quiche/http2/test_tools/verify_macros.h +32 -0
  216. package/third_party/quiche/quiche/quic/core/congestion_control/bbr2_sender.cc +2 -1
  217. package/third_party/quiche/quiche/quic/core/congestion_control/bbr2_simulator_test.cc +3 -2
  218. package/third_party/quiche/quiche/quic/core/congestion_control/bbr_sender_test.cc +3 -2
  219. package/third_party/quiche/quiche/quic/core/congestion_control/rtt_stats.cc +3 -2
  220. package/third_party/quiche/quiche/quic/core/congestion_control/rtt_stats.h +2 -1
  221. package/third_party/quiche/quiche/quic/core/congestion_control/rtt_stats_test.cc +2 -13
  222. package/third_party/quiche/quiche/quic/core/crypto/certificate_view.cc +15 -0
  223. package/third_party/quiche/quiche/quic/core/crypto/certificate_view.h +7 -0
  224. package/third_party/quiche/quiche/quic/core/crypto/certificate_view_test.cc +16 -0
  225. package/third_party/quiche/quiche/quic/core/crypto/crypto_protocol.h +1 -0
  226. package/third_party/quiche/quiche/quic/core/crypto/proof_source.h +2 -2
  227. package/third_party/quiche/quiche/quic/core/crypto/proof_source_x509.cc +3 -5
  228. package/third_party/quiche/quiche/quic/core/crypto/proof_source_x509.h +1 -2
  229. package/third_party/quiche/quiche/quic/core/crypto/quic_crypto_server_config.cc +1 -1
  230. package/third_party/quiche/quiche/quic/core/crypto/quic_crypto_server_config.h +3 -3
  231. package/third_party/quiche/quiche/quic/core/frames/quic_blocked_frame.cc +2 -8
  232. package/third_party/quiche/quiche/quic/core/frames/quic_blocked_frame.h +0 -1
  233. package/third_party/quiche/quiche/quic/core/frames/quic_crypto_frame.h +2 -0
  234. package/third_party/quiche/quiche/quic/core/frames/quic_frames_test.cc +2 -1
  235. package/third_party/quiche/quiche/quic/core/http/capsule.cc +2 -22
  236. package/third_party/quiche/quiche/quic/core/http/capsule.h +0 -2
  237. package/third_party/quiche/quiche/quic/core/http/capsule_test.cc +1 -2
  238. package/third_party/quiche/quiche/quic/core/http/end_to_end_test.cc +148 -57
  239. package/third_party/quiche/quiche/quic/core/http/http_constants.cc +1 -1
  240. package/third_party/quiche/quiche/quic/core/http/http_constants.h +2 -2
  241. package/third_party/quiche/quiche/quic/core/http/quic_header_list_test.cc +2 -2
  242. package/third_party/quiche/quiche/quic/core/http/quic_headers_stream_test.cc +18 -14
  243. package/third_party/quiche/quiche/quic/core/http/quic_send_control_stream.h +2 -1
  244. package/third_party/quiche/quiche/quic/core/http/quic_send_control_stream_test.cc +3 -7
  245. package/third_party/quiche/quiche/quic/core/http/quic_server_session_base.h +4 -0
  246. package/third_party/quiche/quiche/quic/core/http/quic_spdy_session.cc +47 -65
  247. package/third_party/quiche/quiche/quic/core/http/quic_spdy_session.h +5 -17
  248. package/third_party/quiche/quiche/quic/core/http/quic_spdy_session_test.cc +63 -54
  249. package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream.cc +34 -91
  250. package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream.h +1 -9
  251. package/third_party/quiche/quiche/quic/core/http/quic_spdy_stream_test.cc +27 -134
  252. package/third_party/quiche/quiche/quic/core/http/spdy_utils.cc +0 -41
  253. package/third_party/quiche/quiche/quic/core/http/spdy_utils.h +0 -9
  254. package/third_party/quiche/quiche/quic/core/http/spdy_utils_test.cc +0 -32
  255. package/third_party/quiche/quiche/quic/core/http/web_transport_http3.cc +0 -1
  256. package/third_party/quiche/quiche/quic/core/packet_number_indexed_queue_test.cc +2 -2
  257. package/third_party/quiche/quiche/quic/core/qpack/qpack_header_table.cc +2 -1
  258. package/third_party/quiche/quiche/quic/core/qpack/qpack_send_stream.h +2 -1
  259. package/third_party/quiche/quiche/quic/core/quic_arena_scoped_ptr_test.cc +2 -2
  260. package/third_party/quiche/quiche/quic/core/quic_connection.cc +68 -46
  261. package/third_party/quiche/quiche/quic/core/quic_connection.h +7 -6
  262. package/third_party/quiche/quiche/quic/core/quic_connection_context_test.cc +2 -2
  263. package/third_party/quiche/quiche/quic/core/quic_connection_id_manager_test.cc +2 -2
  264. package/third_party/quiche/quiche/quic/core/quic_connection_id_test.cc +2 -2
  265. package/third_party/quiche/quiche/quic/core/quic_connection_test.cc +45 -132
  266. package/third_party/quiche/quiche/quic/core/quic_constants.h +0 -7
  267. package/third_party/quiche/quiche/quic/core/quic_control_frame_manager.cc +11 -3
  268. package/third_party/quiche/quiche/quic/core/quic_control_frame_manager.h +1 -1
  269. package/third_party/quiche/quiche/quic/core/quic_control_frame_manager_test.cc +2 -2
  270. package/third_party/quiche/quiche/quic/core/quic_crypto_client_handshaker.cc +13 -1
  271. package/third_party/quiche/quiche/quic/core/quic_crypto_client_handshaker.h +3 -0
  272. package/third_party/quiche/quiche/quic/core/quic_crypto_client_handshaker_test.cc +2 -2
  273. package/third_party/quiche/quiche/quic/core/quic_crypto_client_stream.cc +6 -0
  274. package/third_party/quiche/quiche/quic/core/quic_crypto_client_stream.h +8 -0
  275. package/third_party/quiche/quiche/quic/core/quic_crypto_server_stream.cc +26 -13
  276. package/third_party/quiche/quiche/quic/core/quic_crypto_server_stream.h +5 -2
  277. package/third_party/quiche/quiche/quic/core/quic_crypto_stream.cc +55 -47
  278. package/third_party/quiche/quiche/quic/core/quic_crypto_stream.h +15 -10
  279. package/third_party/quiche/quiche/quic/core/quic_crypto_stream_test.cc +34 -5
  280. package/third_party/quiche/quiche/quic/core/quic_dispatcher.cc +20 -11
  281. package/third_party/quiche/quiche/quic/core/quic_dispatcher_test.cc +37 -13
  282. package/third_party/quiche/quiche/quic/core/quic_flags_list.h +6 -10
  283. package/third_party/quiche/quiche/quic/core/quic_flow_controller.cc +3 -3
  284. package/third_party/quiche/quiche/quic/core/quic_flow_controller.h +2 -2
  285. package/third_party/quiche/quiche/quic/core/quic_flow_controller_test.cc +15 -10
  286. package/third_party/quiche/quiche/quic/core/quic_framer.cc +1 -1
  287. package/third_party/quiche/quiche/quic/core/quic_one_block_arena.h +3 -2
  288. package/third_party/quiche/quiche/quic/core/quic_one_block_arena_test.cc +2 -2
  289. package/third_party/quiche/quiche/quic/core/quic_packet_creator.cc +3 -11
  290. package/third_party/quiche/quiche/quic/core/quic_packet_creator.h +0 -8
  291. package/third_party/quiche/quiche/quic/core/quic_ping_manager.cc +14 -14
  292. package/third_party/quiche/quiche/quic/core/quic_ping_manager_test.cc +48 -0
  293. package/third_party/quiche/quiche/quic/core/quic_received_packet_manager.cc +3 -18
  294. package/third_party/quiche/quiche/quic/core/quic_received_packet_manager_test.cc +4 -14
  295. package/third_party/quiche/quiche/quic/core/quic_server_id_test.cc +2 -2
  296. package/third_party/quiche/quiche/quic/core/quic_session.cc +4 -4
  297. package/third_party/quiche/quiche/quic/core/quic_session.h +1 -1
  298. package/third_party/quiche/quiche/quic/core/quic_session_test.cc +21 -1
  299. package/third_party/quiche/quiche/quic/core/quic_stream.cc +4 -7
  300. package/third_party/quiche/quiche/quic/core/quic_stream_test.cc +2 -4
  301. package/third_party/quiche/quiche/quic/core/quic_trace_visitor_test.cc +2 -2
  302. package/third_party/quiche/quiche/quic/core/quic_types.h +3 -8
  303. package/third_party/quiche/quiche/quic/core/quic_udp_socket_posix.cc +5 -4
  304. package/third_party/quiche/quiche/quic/core/quic_unacked_packet_map_test.cc +1 -1
  305. package/third_party/quiche/quiche/quic/core/quic_utils.cc +1 -1
  306. package/third_party/quiche/quiche/quic/core/quic_utils.h +2 -2
  307. package/third_party/quiche/quiche/quic/core/quic_versions_test.cc +0 -1
  308. package/third_party/quiche/quiche/quic/core/tls_client_handshaker.cc +13 -0
  309. package/third_party/quiche/quiche/quic/core/tls_client_handshaker.h +2 -0
  310. package/third_party/quiche/quiche/quic/core/tls_server_handshaker.cc +17 -3
  311. package/third_party/quiche/quiche/quic/core/tls_server_handshaker.h +3 -1
  312. package/third_party/quiche/quiche/quic/core/uber_received_packet_manager_test.cc +18 -10
  313. package/third_party/quiche/quiche/quic/masque/masque_client_bin.cc +6 -4
  314. package/third_party/quiche/quiche/quic/masque/masque_client_session.cc +23 -7
  315. package/third_party/quiche/quiche/quic/masque/masque_client_session.h +1 -1
  316. package/third_party/quiche/quiche/quic/masque/masque_server_backend.cc +13 -0
  317. package/third_party/quiche/quiche/quic/masque/masque_server_backend.h +2 -0
  318. package/third_party/quiche/quiche/quic/masque/masque_server_bin.cc +5 -4
  319. package/third_party/quiche/quiche/quic/masque/masque_server_session.cc +30 -40
  320. package/third_party/quiche/quiche/quic/masque/masque_server_session.h +1 -1
  321. package/third_party/quiche/quiche/quic/platform/api/quic_export.h +4 -4
  322. package/third_party/quiche/quiche/quic/platform/api/quic_flags.h +0 -1
  323. package/third_party/quiche/quiche/quic/platform/api/quic_logging.h +0 -6
  324. package/third_party/quiche/quiche/quic/platform/api/quic_test.h +6 -5
  325. package/third_party/quiche/quiche/quic/qbone/bonnet/icmp_reachable_test.cc +2 -2
  326. package/third_party/quiche/quiche/quic/qbone/bonnet/mock_qbone_tunnel.h +2 -0
  327. package/third_party/quiche/quiche/quic/qbone/bonnet/qbone_tunnel_interface.h +2 -0
  328. package/third_party/quiche/quiche/quic/qbone/bonnet/tun_device_controller_test.cc +2 -2
  329. package/third_party/quiche/quiche/quic/qbone/bonnet/tun_device_packet_exchanger_test.cc +2 -2
  330. package/third_party/quiche/quiche/quic/qbone/bonnet/tun_device_test.cc +2 -2
  331. package/third_party/quiche/quiche/quic/qbone/platform/netlink_test.cc +2 -2
  332. package/third_party/quiche/quiche/quic/qbone/platform/tcp_packet.cc +5 -4
  333. package/third_party/quiche/quiche/quic/qbone/qbone_client_session.cc +4 -2
  334. package/third_party/quiche/quiche/quic/qbone/qbone_packet_processor.cc +2 -1
  335. package/third_party/quiche/quiche/quic/qbone/qbone_packet_processor_test.cc +2 -2
  336. package/third_party/quiche/quiche/quic/qbone/qbone_server_session.cc +4 -2
  337. package/third_party/quiche/quiche/quic/qbone/qbone_session_base.cc +3 -2
  338. package/third_party/quiche/quiche/quic/qbone/qbone_stream.cc +4 -4
  339. package/third_party/quiche/quiche/quic/test_tools/quic_connection_peer.cc +1 -1
  340. package/third_party/quiche/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/index.html +63 -0
  341. package/third_party/quiche/quiche/quic/test_tools/quic_http_response_cache_data/test.example.com/map.html +65 -0
  342. package/third_party/quiche/quiche/quic/test_tools/quic_test_utils.cc +4 -3
  343. package/third_party/quiche/quiche/quic/test_tools/quic_test_utils.h +18 -1
  344. package/third_party/quiche/quiche/quic/test_tools/simulator/quic_endpoint_test.cc +1 -1
  345. package/third_party/quiche/quiche/quic/test_tools/simulator/simulator_test.cc +1 -1
  346. package/third_party/quiche/quiche/quic/test_tools/test_ticket_crypter.cc +1 -1
  347. package/third_party/quiche/quiche/quic/test_tools/test_ticket_crypter.h +2 -2
  348. package/third_party/quiche/quiche/quic/{core/crypto → tools}/crypto_message_printer_bin.cc +0 -0
  349. package/third_party/quiche/quiche/quic/{core/qpack → tools}/qpack_offline_decoder_bin.cc +0 -0
  350. package/third_party/quiche/quiche/quic/tools/quic_client_interop_test_bin.cc +4 -3
  351. package/third_party/quiche/quiche/quic/tools/quic_memory_cache_backend_test.cc +3 -31
  352. package/third_party/quiche/quiche/quic/tools/quic_packet_printer_bin.cc +2 -2
  353. package/third_party/quiche/quiche/quic/tools/quic_simple_server_session.h +1 -1
  354. package/third_party/quiche/quiche/quic/tools/quic_simple_server_session_test.cc +1 -1
  355. package/third_party/quiche/quiche/quic/tools/quic_toy_client.cc +52 -38
  356. package/third_party/quiche/quiche/quic/tools/quic_toy_server.cc +10 -7
  357. package/third_party/quiche/quiche/quic/tools/simple_ticket_crypter.cc +1 -1
  358. package/third_party/quiche/quiche/quic/tools/simple_ticket_crypter.h +1 -1
  359. package/third_party/quiche/quiche/quic/tools/web_transport_test_visitors.h +3 -2
  360. package/third_party/quiche/quiche/spdy/core/array_output_buffer.h +1 -1
  361. package/third_party/quiche/quiche/spdy/core/hpack/hpack_decoder_adapter_test.cc +1 -1
  362. package/third_party/quiche/quiche/spdy/core/hpack/hpack_encoder_test.cc +2 -1
  363. package/third_party/quiche/quiche/spdy/core/hpack/hpack_header_table_test.cc +1 -1
  364. package/third_party/quiche/quiche/spdy/core/hpack/hpack_round_trip_test.cc +2 -1
  365. package/third_party/quiche/quiche/spdy/core/hpack/hpack_static_table_test.cc +1 -1
  366. package/third_party/quiche/quiche/spdy/core/http2_frame_decoder_adapter.cc +8 -6
  367. package/third_party/quiche/quiche/spdy/core/http2_frame_decoder_adapter.h +17 -6
  368. package/third_party/quiche/quiche/spdy/core/metadata_extension.cc +1 -1
  369. package/third_party/quiche/quiche/spdy/core/metadata_extension_test.cc +1 -1
  370. package/third_party/quiche/quiche/spdy/core/spdy_framer_test.cc +21 -17
  371. package/third_party/quiche/quiche/spdy/core/spdy_intrusive_list_test.cc +3 -3
  372. package/third_party/quiche/quiche/spdy/core/spdy_no_op_visitor.h +6 -4
  373. package/third_party/quiche/quiche/spdy/core/spdy_pinnable_buffer_piece_test.cc +1 -1
  374. package/third_party/quiche/quiche/spdy/core/spdy_prefixed_buffer_reader_test.cc +1 -1
  375. package/third_party/quiche/quiche/spdy/core/spdy_protocol_test.cc +1 -1
  376. package/third_party/quiche/quiche/spdy/test_tools/mock_spdy_framer_visitor.h +5 -4
  377. package/third_party/boringssl/src/util/bot/cmake-win32.zip.sha1 +0 -1
  378. package/third_party/quiche/quiche/common/platform/api/quiche_mock_log.h +0 -18
  379. package/third_party/quiche/quiche/common/platform/api/quiche_test_helpers.h +0 -8
  380. package/third_party/quiche/quiche/quic/platform/api/quic_mock_log.h +0 -19
  381. package/third_party/quiche/quiche/quic/tools/quic_transport_simple_server_dispatcher.cc +0 -51
  382. package/third_party/quiche/quiche/quic/tools/quic_transport_simple_server_dispatcher.h +0 -41
  383. package/third_party/quiche/quiche/quic/tools/quic_transport_simple_server_session.cc +0 -168
  384. package/third_party/quiche/quiche/quic/tools/quic_transport_simple_server_session.h +0 -78
@@ -1,1180 +1,1164 @@
1
- /* Copyright (c) 2015, Google Inc.
2
- *
3
- * Permission to use, copy, modify, and/or distribute this software for any
4
- * purpose with or without fee is hereby granted, provided that the above
5
- * copyright notice and this permission notice appear in all copies.
6
- *
7
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
-
15
- // A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
16
- //
17
- // Inspired by Daniel J. Bernstein's public domain nistp224 implementation
18
- // and Adam Langley's public domain 64-bit C implementation of curve25519.
19
-
20
- #include <openssl/base.h>
21
-
22
- #include <openssl/bn.h>
23
- #include <openssl/ec.h>
24
- #include <openssl/err.h>
25
- #include <openssl/mem.h>
26
-
27
- #include <string.h>
28
-
29
- #include "internal.h"
30
- #include "../delocate.h"
31
- #include "../../internal.h"
32
-
33
-
34
- #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
35
-
36
- // Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
37
- // using 64-bit coefficients called 'limbs', and sometimes (for multiplication
38
- // results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
39
- // 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-p224_limb
40
- // representation is an 'p224_felem'; a 7-p224_widelimb representation is a
41
- // 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we
42
- // don't always reduce the representations: we ensure that inputs to each
43
- // p224_felem multiplication satisfy a_i < 2^60, so outputs satisfy b_i <
44
- // 4*2^60*2^60, and fit into a 128-bit word without overflow. The coefficients
45
- // are then again partially reduced to obtain an p224_felem satisfying a_i <
46
- // 2^57. We only reduce to the unique minimal representation at the end of the
47
- // computation.
48
-
49
- typedef uint64_t p224_limb;
50
- typedef uint128_t p224_widelimb;
51
-
52
- typedef p224_limb p224_felem[4];
53
- typedef p224_widelimb p224_widefelem[7];
54
-
55
- // Field element represented as a byte arrary. 28*8 = 224 bits is also the
56
- // group order size for the elliptic curve, and we also use this type for
57
- // scalars for point multiplication.
58
- typedef uint8_t p224_felem_bytearray[28];
59
-
60
- // Precomputed multiples of the standard generator
61
- // Points are given in coordinates (X, Y, Z) where Z normally is 1
62
- // (0 for the point at infinity).
63
- // For each field element, slice a_0 is word 0, etc.
64
- //
65
- // The table has 2 * 16 elements, starting with the following:
66
- // index | bits | point
67
- // ------+---------+------------------------------
68
- // 0 | 0 0 0 0 | 0G
69
- // 1 | 0 0 0 1 | 1G
70
- // 2 | 0 0 1 0 | 2^56G
71
- // 3 | 0 0 1 1 | (2^56 + 1)G
72
- // 4 | 0 1 0 0 | 2^112G
73
- // 5 | 0 1 0 1 | (2^112 + 1)G
74
- // 6 | 0 1 1 0 | (2^112 + 2^56)G
75
- // 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
76
- // 8 | 1 0 0 0 | 2^168G
77
- // 9 | 1 0 0 1 | (2^168 + 1)G
78
- // 10 | 1 0 1 0 | (2^168 + 2^56)G
79
- // 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
80
- // 12 | 1 1 0 0 | (2^168 + 2^112)G
81
- // 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
82
- // 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
83
- // 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
84
- // followed by a copy of this with each element multiplied by 2^28.
85
- //
86
- // The reason for this is so that we can clock bits into four different
87
- // locations when doing simple scalar multiplies against the base point,
88
- // and then another four locations using the second 16 elements.
89
- static const p224_felem g_p224_pre_comp[2][16][3] = {
90
- {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
91
- {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
92
- {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
93
- {1, 0, 0, 0}},
94
- {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
95
- {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
96
- {1, 0, 0, 0}},
97
- {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
98
- {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
99
- {1, 0, 0, 0}},
100
- {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
101
- {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
102
- {1, 0, 0, 0}},
103
- {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
104
- {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
105
- {1, 0, 0, 0}},
106
- {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
107
- {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
108
- {1, 0, 0, 0}},
109
- {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
110
- {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
111
- {1, 0, 0, 0}},
112
- {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
113
- {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
114
- {1, 0, 0, 0}},
115
- {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
116
- {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
117
- {1, 0, 0, 0}},
118
- {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
119
- {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
120
- {1, 0, 0, 0}},
121
- {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
122
- {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
123
- {1, 0, 0, 0}},
124
- {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
125
- {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
126
- {1, 0, 0, 0}},
127
- {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
128
- {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
129
- {1, 0, 0, 0}},
130
- {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
131
- {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
132
- {1, 0, 0, 0}},
133
- {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
134
- {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
135
- {1, 0, 0, 0}}},
136
- {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
137
- {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
138
- {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
139
- {1, 0, 0, 0}},
140
- {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
141
- {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
142
- {1, 0, 0, 0}},
143
- {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
144
- {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
145
- {1, 0, 0, 0}},
146
- {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
147
- {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
148
- {1, 0, 0, 0}},
149
- {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
150
- {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
151
- {1, 0, 0, 0}},
152
- {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
153
- {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
154
- {1, 0, 0, 0}},
155
- {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
156
- {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
157
- {1, 0, 0, 0}},
158
- {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
159
- {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
160
- {1, 0, 0, 0}},
161
- {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
162
- {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
163
- {1, 0, 0, 0}},
164
- {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
165
- {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
166
- {1, 0, 0, 0}},
167
- {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
168
- {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
169
- {1, 0, 0, 0}},
170
- {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
171
- {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
172
- {1, 0, 0, 0}},
173
- {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
174
- {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
175
- {1, 0, 0, 0}},
176
- {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
177
- {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
178
- {1, 0, 0, 0}},
179
- {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
180
- {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
181
- {1, 0, 0, 0}}}};
182
-
183
- static uint64_t p224_load_u64(const uint8_t in[8]) {
184
- uint64_t ret;
185
- OPENSSL_memcpy(&ret, in, sizeof(ret));
186
- return ret;
187
- }
188
-
189
- // Helper functions to convert field elements to/from internal representation
190
- static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) {
191
- out[0] = p224_load_u64(in) & 0x00ffffffffffffff;
192
- out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff;
193
- out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff;
194
- out[3] = p224_load_u64(in + 20) >> 8;
195
- }
196
-
197
- static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) {
198
- for (size_t i = 0; i < 7; ++i) {
199
- out[i] = in[0] >> (8 * i);
200
- out[i + 7] = in[1] >> (8 * i);
201
- out[i + 14] = in[2] >> (8 * i);
202
- out[i + 21] = in[3] >> (8 * i);
203
- }
204
- }
205
-
206
- static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) {
207
- p224_bin28_to_felem(out, in->bytes);
208
- }
209
-
210
- // Requires 0 <= in < 2*p (always call p224_felem_reduce first)
211
- static void p224_felem_to_generic(EC_FELEM *out, const p224_felem in) {
212
- // Reduce to unique minimal representation.
213
- static const int64_t two56 = ((p224_limb)1) << 56;
214
- // 0 <= in < 2*p, p = 2^224 - 2^96 + 1
215
- // if in > p , reduce in = in - 2^224 + 2^96 - 1
216
- int64_t tmp[4], a;
217
- tmp[0] = in[0];
218
- tmp[1] = in[1];
219
- tmp[2] = in[2];
220
- tmp[3] = in[3];
221
- // Case 1: a = 1 iff in >= 2^224
222
- a = (in[3] >> 56);
223
- tmp[0] -= a;
224
- tmp[1] += a << 40;
225
- tmp[3] &= 0x00ffffffffffffff;
226
- // Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and
227
- // the lower part is non-zero
228
- a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
229
- (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
230
- a &= 0x00ffffffffffffff;
231
- // turn a into an all-one mask (if a = 0) or an all-zero mask
232
- a = (a - 1) >> 63;
233
- // subtract 2^224 - 2^96 + 1 if a is all-one
234
- tmp[3] &= a ^ 0xffffffffffffffff;
235
- tmp[2] &= a ^ 0xffffffffffffffff;
236
- tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
237
- tmp[0] -= 1 & a;
238
-
239
- // eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
240
- // be non-zero, so we only need one step
241
- a = tmp[0] >> 63;
242
- tmp[0] += two56 & a;
243
- tmp[1] -= 1 & a;
244
-
245
- // carry 1 -> 2 -> 3
246
- tmp[2] += tmp[1] >> 56;
247
- tmp[1] &= 0x00ffffffffffffff;
248
-
249
- tmp[3] += tmp[2] >> 56;
250
- tmp[2] &= 0x00ffffffffffffff;
251
-
252
- // Now 0 <= tmp < p
253
- p224_felem tmp2;
254
- tmp2[0] = tmp[0];
255
- tmp2[1] = tmp[1];
256
- tmp2[2] = tmp[2];
257
- tmp2[3] = tmp[3];
258
-
259
- p224_felem_to_bin28(out->bytes, tmp2);
260
- // 224 is not a multiple of 64, so zero the remaining bytes.
261
- OPENSSL_memset(out->bytes + 28, 0, 32 - 28);
262
- }
263
-
264
-
265
- // Field operations, using the internal representation of field elements.
266
- // NB! These operations are specific to our point multiplication and cannot be
267
- // expected to be correct in general - e.g., multiplication with a large scalar
268
- // will cause an overflow.
269
-
270
- static void p224_felem_assign(p224_felem out, const p224_felem in) {
271
- out[0] = in[0];
272
- out[1] = in[1];
273
- out[2] = in[2];
274
- out[3] = in[3];
275
- }
276
-
277
- // Sum two field elements: out += in
278
- static void p224_felem_sum(p224_felem out, const p224_felem in) {
279
- out[0] += in[0];
280
- out[1] += in[1];
281
- out[2] += in[2];
282
- out[3] += in[3];
283
- }
284
-
285
- // Subtract field elements: out -= in
286
- // Assumes in[i] < 2^57
287
- static void p224_felem_diff(p224_felem out, const p224_felem in) {
288
- static const p224_limb two58p2 =
289
- (((p224_limb)1) << 58) + (((p224_limb)1) << 2);
290
- static const p224_limb two58m2 =
291
- (((p224_limb)1) << 58) - (((p224_limb)1) << 2);
292
- static const p224_limb two58m42m2 =
293
- (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_limb)1) << 2);
294
-
295
- // Add 0 mod 2^224-2^96+1 to ensure out > in
296
- out[0] += two58p2;
297
- out[1] += two58m42m2;
298
- out[2] += two58m2;
299
- out[3] += two58m2;
300
-
301
- out[0] -= in[0];
302
- out[1] -= in[1];
303
- out[2] -= in[2];
304
- out[3] -= in[3];
305
- }
306
-
307
- // Subtract in unreduced 128-bit mode: out -= in
308
- // Assumes in[i] < 2^119
309
- static void p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) {
310
- static const p224_widelimb two120 = ((p224_widelimb)1) << 120;
311
- static const p224_widelimb two120m64 =
312
- (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64);
313
- static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) -
314
- (((p224_widelimb)1) << 104) -
315
- (((p224_widelimb)1) << 64);
316
-
317
- // Add 0 mod 2^224-2^96+1 to ensure out > in
318
- out[0] += two120;
319
- out[1] += two120m64;
320
- out[2] += two120m64;
321
- out[3] += two120;
322
- out[4] += two120m104m64;
323
- out[5] += two120m64;
324
- out[6] += two120m64;
325
-
326
- out[0] -= in[0];
327
- out[1] -= in[1];
328
- out[2] -= in[2];
329
- out[3] -= in[3];
330
- out[4] -= in[4];
331
- out[5] -= in[5];
332
- out[6] -= in[6];
333
- }
334
-
335
- // Subtract in mixed mode: out128 -= in64
336
- // in[i] < 2^63
337
- static void p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) {
338
- static const p224_widelimb two64p8 =
339
- (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8);
340
- static const p224_widelimb two64m8 =
341
- (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8);
342
- static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) -
343
- (((p224_widelimb)1) << 48) -
344
- (((p224_widelimb)1) << 8);
345
-
346
- // Add 0 mod 2^224-2^96+1 to ensure out > in
347
- out[0] += two64p8;
348
- out[1] += two64m48m8;
349
- out[2] += two64m8;
350
- out[3] += two64m8;
351
-
352
- out[0] -= in[0];
353
- out[1] -= in[1];
354
- out[2] -= in[2];
355
- out[3] -= in[3];
356
- }
357
-
358
- // Multiply a field element by a scalar: out = out * scalar
359
- // The scalars we actually use are small, so results fit without overflow
360
- static void p224_felem_scalar(p224_felem out, const p224_limb scalar) {
361
- out[0] *= scalar;
362
- out[1] *= scalar;
363
- out[2] *= scalar;
364
- out[3] *= scalar;
365
- }
366
-
367
- // Multiply an unreduced field element by a scalar: out = out * scalar
368
- // The scalars we actually use are small, so results fit without overflow
369
- static void p224_widefelem_scalar(p224_widefelem out,
370
- const p224_widelimb scalar) {
371
- out[0] *= scalar;
372
- out[1] *= scalar;
373
- out[2] *= scalar;
374
- out[3] *= scalar;
375
- out[4] *= scalar;
376
- out[5] *= scalar;
377
- out[6] *= scalar;
378
- }
379
-
380
- // Square a field element: out = in^2
381
- static void p224_felem_square(p224_widefelem out, const p224_felem in) {
382
- p224_limb tmp0, tmp1, tmp2;
383
- tmp0 = 2 * in[0];
384
- tmp1 = 2 * in[1];
385
- tmp2 = 2 * in[2];
386
- out[0] = ((p224_widelimb)in[0]) * in[0];
387
- out[1] = ((p224_widelimb)in[0]) * tmp1;
388
- out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1];
389
- out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2;
390
- out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2];
391
- out[5] = ((p224_widelimb)in[3]) * tmp2;
392
- out[6] = ((p224_widelimb)in[3]) * in[3];
393
- }
394
-
395
- // Multiply two field elements: out = in1 * in2
396
- static void p224_felem_mul(p224_widefelem out, const p224_felem in1,
397
- const p224_felem in2) {
398
- out[0] = ((p224_widelimb)in1[0]) * in2[0];
399
- out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0];
400
- out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] +
401
- ((p224_widelimb)in1[2]) * in2[0];
402
- out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] +
403
- ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0];
404
- out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] +
405
- ((p224_widelimb)in1[3]) * in2[1];
406
- out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2];
407
- out[6] = ((p224_widelimb)in1[3]) * in2[3];
408
- }
409
-
410
- // Reduce seven 128-bit coefficients to four 64-bit coefficients.
411
- // Requires in[i] < 2^126,
412
- // ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
413
- static void p224_felem_reduce(p224_felem out, const p224_widefelem in) {
414
- static const p224_widelimb two127p15 =
415
- (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15);
416
- static const p224_widelimb two127m71 =
417
- (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71);
418
- static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) -
419
- (((p224_widelimb)1) << 71) -
420
- (((p224_widelimb)1) << 55);
421
- p224_widelimb output[5];
422
-
423
- // Add 0 mod 2^224-2^96+1 to ensure all differences are positive
424
- output[0] = in[0] + two127p15;
425
- output[1] = in[1] + two127m71m55;
426
- output[2] = in[2] + two127m71;
427
- output[3] = in[3];
428
- output[4] = in[4];
429
-
430
- // Eliminate in[4], in[5], in[6]
431
- output[4] += in[6] >> 16;
432
- output[3] += (in[6] & 0xffff) << 40;
433
- output[2] -= in[6];
434
-
435
- output[3] += in[5] >> 16;
436
- output[2] += (in[5] & 0xffff) << 40;
437
- output[1] -= in[5];
438
-
439
- output[2] += output[4] >> 16;
440
- output[1] += (output[4] & 0xffff) << 40;
441
- output[0] -= output[4];
442
-
443
- // Carry 2 -> 3 -> 4
444
- output[3] += output[2] >> 56;
445
- output[2] &= 0x00ffffffffffffff;
446
-
447
- output[4] = output[3] >> 56;
448
- output[3] &= 0x00ffffffffffffff;
449
-
450
- // Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72
451
-
452
- // Eliminate output[4]
453
- output[2] += output[4] >> 16;
454
- // output[2] < 2^56 + 2^56 = 2^57
455
- output[1] += (output[4] & 0xffff) << 40;
456
- output[0] -= output[4];
457
-
458
- // Carry 0 -> 1 -> 2 -> 3
459
- output[1] += output[0] >> 56;
460
- out[0] = output[0] & 0x00ffffffffffffff;
461
-
462
- output[2] += output[1] >> 56;
463
- // output[2] < 2^57 + 2^72
464
- out[1] = output[1] & 0x00ffffffffffffff;
465
- output[3] += output[2] >> 56;
466
- // output[3] <= 2^56 + 2^16
467
- out[2] = output[2] & 0x00ffffffffffffff;
468
-
469
- // out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
470
- // out[3] <= 2^56 + 2^16 (due to final carry),
471
- // so out < 2*p
472
- out[3] = output[3];
473
- }
474
-
475
- // Get negative value: out = -in
476
- // Requires in[i] < 2^63,
477
- // ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
478
- static void p224_felem_neg(p224_felem out, const p224_felem in) {
479
- p224_widefelem tmp = {0};
480
- p224_felem_diff_128_64(tmp, in);
481
- p224_felem_reduce(out, tmp);
482
- }
483
-
484
- // Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
485
- // elements are reduced to in < 2^225, so we only need to check three cases: 0,
486
- // 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
487
- static p224_limb p224_felem_is_zero(const p224_felem in) {
488
- p224_limb zero = in[0] | in[1] | in[2] | in[3];
489
- zero = (((int64_t)(zero)-1) >> 63) & 1;
490
-
491
- p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) |
492
- (in[2] ^ 0x00ffffffffffffff) |
493
- (in[3] ^ 0x00ffffffffffffff);
494
- two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1;
495
- p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) |
496
- (in[2] ^ 0x00ffffffffffffff) |
497
- (in[3] ^ 0x01ffffffffffffff);
498
- two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1;
499
- return (zero | two224m96p1 | two225m97p2);
500
- }
501
-
502
- // Invert a field element
503
- // Computation chain copied from djb's code
504
- static void p224_felem_inv(p224_felem out, const p224_felem in) {
505
- p224_felem ftmp, ftmp2, ftmp3, ftmp4;
506
- p224_widefelem tmp;
507
-
508
- p224_felem_square(tmp, in);
509
- p224_felem_reduce(ftmp, tmp); // 2
510
- p224_felem_mul(tmp, in, ftmp);
511
- p224_felem_reduce(ftmp, tmp); // 2^2 - 1
512
- p224_felem_square(tmp, ftmp);
513
- p224_felem_reduce(ftmp, tmp); // 2^3 - 2
514
- p224_felem_mul(tmp, in, ftmp);
515
- p224_felem_reduce(ftmp, tmp); // 2^3 - 1
516
- p224_felem_square(tmp, ftmp);
517
- p224_felem_reduce(ftmp2, tmp); // 2^4 - 2
518
- p224_felem_square(tmp, ftmp2);
519
- p224_felem_reduce(ftmp2, tmp); // 2^5 - 4
520
- p224_felem_square(tmp, ftmp2);
521
- p224_felem_reduce(ftmp2, tmp); // 2^6 - 8
522
- p224_felem_mul(tmp, ftmp2, ftmp);
523
- p224_felem_reduce(ftmp, tmp); // 2^6 - 1
524
- p224_felem_square(tmp, ftmp);
525
- p224_felem_reduce(ftmp2, tmp); // 2^7 - 2
526
- for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6
527
- p224_felem_square(tmp, ftmp2);
528
- p224_felem_reduce(ftmp2, tmp);
529
- }
530
- p224_felem_mul(tmp, ftmp2, ftmp);
531
- p224_felem_reduce(ftmp2, tmp); // 2^12 - 1
532
- p224_felem_square(tmp, ftmp2);
533
- p224_felem_reduce(ftmp3, tmp); // 2^13 - 2
534
- for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12
535
- p224_felem_square(tmp, ftmp3);
536
- p224_felem_reduce(ftmp3, tmp);
537
- }
538
- p224_felem_mul(tmp, ftmp3, ftmp2);
539
- p224_felem_reduce(ftmp2, tmp); // 2^24 - 1
540
- p224_felem_square(tmp, ftmp2);
541
- p224_felem_reduce(ftmp3, tmp); // 2^25 - 2
542
- for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24
543
- p224_felem_square(tmp, ftmp3);
544
- p224_felem_reduce(ftmp3, tmp);
545
- }
546
- p224_felem_mul(tmp, ftmp3, ftmp2);
547
- p224_felem_reduce(ftmp3, tmp); // 2^48 - 1
548
- p224_felem_square(tmp, ftmp3);
549
- p224_felem_reduce(ftmp4, tmp); // 2^49 - 2
550
- for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48
551
- p224_felem_square(tmp, ftmp4);
552
- p224_felem_reduce(ftmp4, tmp);
553
- }
554
- p224_felem_mul(tmp, ftmp3, ftmp4);
555
- p224_felem_reduce(ftmp3, tmp); // 2^96 - 1
556
- p224_felem_square(tmp, ftmp3);
557
- p224_felem_reduce(ftmp4, tmp); // 2^97 - 2
558
- for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24
559
- p224_felem_square(tmp, ftmp4);
560
- p224_felem_reduce(ftmp4, tmp);
561
- }
562
- p224_felem_mul(tmp, ftmp2, ftmp4);
563
- p224_felem_reduce(ftmp2, tmp); // 2^120 - 1
564
- for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6
565
- p224_felem_square(tmp, ftmp2);
566
- p224_felem_reduce(ftmp2, tmp);
567
- }
568
- p224_felem_mul(tmp, ftmp2, ftmp);
569
- p224_felem_reduce(ftmp, tmp); // 2^126 - 1
570
- p224_felem_square(tmp, ftmp);
571
- p224_felem_reduce(ftmp, tmp); // 2^127 - 2
572
- p224_felem_mul(tmp, ftmp, in);
573
- p224_felem_reduce(ftmp, tmp); // 2^127 - 1
574
- for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97
575
- p224_felem_square(tmp, ftmp);
576
- p224_felem_reduce(ftmp, tmp);
577
- }
578
- p224_felem_mul(tmp, ftmp, ftmp3);
579
- p224_felem_reduce(out, tmp); // 2^224 - 2^96 - 1
580
- }
581
-
582
- // Copy in constant time:
583
- // if icopy == 1, copy in to out,
584
- // if icopy == 0, copy out to itself.
585
- static void p224_copy_conditional(p224_felem out, const p224_felem in,
586
- p224_limb icopy) {
587
- // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
588
- const p224_limb copy = -icopy;
589
- for (size_t i = 0; i < 4; ++i) {
590
- const p224_limb tmp = copy & (in[i] ^ out[i]);
591
- out[i] ^= tmp;
592
- }
593
- }
594
-
595
- // ELLIPTIC CURVE POINT OPERATIONS
596
- //
597
- // Points are represented in Jacobian projective coordinates:
598
- // (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
599
- // or to the point at infinity if Z == 0.
600
-
601
- // Double an elliptic curve point:
602
- // (X', Y', Z') = 2 * (X, Y, Z), where
603
- // X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
604
- // Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
605
- // Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
606
- // Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
607
- // while x_out == y_in is not (maybe this works, but it's not tested).
608
- static void p224_point_double(p224_felem x_out, p224_felem y_out,
609
- p224_felem z_out, const p224_felem x_in,
610
- const p224_felem y_in, const p224_felem z_in) {
611
- p224_widefelem tmp, tmp2;
612
- p224_felem delta, gamma, beta, alpha, ftmp, ftmp2;
613
-
614
- p224_felem_assign(ftmp, x_in);
615
- p224_felem_assign(ftmp2, x_in);
616
-
617
- // delta = z^2
618
- p224_felem_square(tmp, z_in);
619
- p224_felem_reduce(delta, tmp);
620
-
621
- // gamma = y^2
622
- p224_felem_square(tmp, y_in);
623
- p224_felem_reduce(gamma, tmp);
624
-
625
- // beta = x*gamma
626
- p224_felem_mul(tmp, x_in, gamma);
627
- p224_felem_reduce(beta, tmp);
628
-
629
- // alpha = 3*(x-delta)*(x+delta)
630
- p224_felem_diff(ftmp, delta);
631
- // ftmp[i] < 2^57 + 2^58 + 2 < 2^59
632
- p224_felem_sum(ftmp2, delta);
633
- // ftmp2[i] < 2^57 + 2^57 = 2^58
634
- p224_felem_scalar(ftmp2, 3);
635
- // ftmp2[i] < 3 * 2^58 < 2^60
636
- p224_felem_mul(tmp, ftmp, ftmp2);
637
- // tmp[i] < 2^60 * 2^59 * 4 = 2^121
638
- p224_felem_reduce(alpha, tmp);
639
-
640
- // x' = alpha^2 - 8*beta
641
- p224_felem_square(tmp, alpha);
642
- // tmp[i] < 4 * 2^57 * 2^57 = 2^116
643
- p224_felem_assign(ftmp, beta);
644
- p224_felem_scalar(ftmp, 8);
645
- // ftmp[i] < 8 * 2^57 = 2^60
646
- p224_felem_diff_128_64(tmp, ftmp);
647
- // tmp[i] < 2^116 + 2^64 + 8 < 2^117
648
- p224_felem_reduce(x_out, tmp);
649
-
650
- // z' = (y + z)^2 - gamma - delta
651
- p224_felem_sum(delta, gamma);
652
- // delta[i] < 2^57 + 2^57 = 2^58
653
- p224_felem_assign(ftmp, y_in);
654
- p224_felem_sum(ftmp, z_in);
655
- // ftmp[i] < 2^57 + 2^57 = 2^58
656
- p224_felem_square(tmp, ftmp);
657
- // tmp[i] < 4 * 2^58 * 2^58 = 2^118
658
- p224_felem_diff_128_64(tmp, delta);
659
- // tmp[i] < 2^118 + 2^64 + 8 < 2^119
660
- p224_felem_reduce(z_out, tmp);
661
-
662
- // y' = alpha*(4*beta - x') - 8*gamma^2
663
- p224_felem_scalar(beta, 4);
664
- // beta[i] < 4 * 2^57 = 2^59
665
- p224_felem_diff(beta, x_out);
666
- // beta[i] < 2^59 + 2^58 + 2 < 2^60
667
- p224_felem_mul(tmp, alpha, beta);
668
- // tmp[i] < 4 * 2^57 * 2^60 = 2^119
669
- p224_felem_square(tmp2, gamma);
670
- // tmp2[i] < 4 * 2^57 * 2^57 = 2^116
671
- p224_widefelem_scalar(tmp2, 8);
672
- // tmp2[i] < 8 * 2^116 = 2^119
673
- p224_widefelem_diff(tmp, tmp2);
674
- // tmp[i] < 2^119 + 2^120 < 2^121
675
- p224_felem_reduce(y_out, tmp);
676
- }
677
-
678
- // Add two elliptic curve points:
679
- // (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
680
- // X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
681
- // 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
682
- // Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 *
683
- // X_1)^2 - X_3) -
684
- // Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
685
- // Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
686
- //
687
- // This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
688
-
689
- // This function is not entirely constant-time: it includes a branch for
690
- // checking whether the two input points are equal, (while not equal to the
691
- // point at infinity). This case never happens during single point
692
- // multiplication, so there is no timing leak for ECDH or ECDSA signing.
693
- static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3,
694
- const p224_felem x1, const p224_felem y1,
695
- const p224_felem z1, const int mixed,
696
- const p224_felem x2, const p224_felem y2,
697
- const p224_felem z2) {
698
- p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
699
- p224_widefelem tmp, tmp2;
700
- p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal;
701
-
702
- if (!mixed) {
703
- // ftmp2 = z2^2
704
- p224_felem_square(tmp, z2);
705
- p224_felem_reduce(ftmp2, tmp);
706
-
707
- // ftmp4 = z2^3
708
- p224_felem_mul(tmp, ftmp2, z2);
709
- p224_felem_reduce(ftmp4, tmp);
710
-
711
- // ftmp4 = z2^3*y1
712
- p224_felem_mul(tmp2, ftmp4, y1);
713
- p224_felem_reduce(ftmp4, tmp2);
714
-
715
- // ftmp2 = z2^2*x1
716
- p224_felem_mul(tmp2, ftmp2, x1);
717
- p224_felem_reduce(ftmp2, tmp2);
718
- } else {
719
- // We'll assume z2 = 1 (special case z2 = 0 is handled later)
720
-
721
- // ftmp4 = z2^3*y1
722
- p224_felem_assign(ftmp4, y1);
723
-
724
- // ftmp2 = z2^2*x1
725
- p224_felem_assign(ftmp2, x1);
726
- }
727
-
728
- // ftmp = z1^2
729
- p224_felem_square(tmp, z1);
730
- p224_felem_reduce(ftmp, tmp);
731
-
732
- // ftmp3 = z1^3
733
- p224_felem_mul(tmp, ftmp, z1);
734
- p224_felem_reduce(ftmp3, tmp);
735
-
736
- // tmp = z1^3*y2
737
- p224_felem_mul(tmp, ftmp3, y2);
738
- // tmp[i] < 4 * 2^57 * 2^57 = 2^116
739
-
740
- // ftmp3 = z1^3*y2 - z2^3*y1
741
- p224_felem_diff_128_64(tmp, ftmp4);
742
- // tmp[i] < 2^116 + 2^64 + 8 < 2^117
743
- p224_felem_reduce(ftmp3, tmp);
744
-
745
- // tmp = z1^2*x2
746
- p224_felem_mul(tmp, ftmp, x2);
747
- // tmp[i] < 4 * 2^57 * 2^57 = 2^116
748
-
749
- // ftmp = z1^2*x2 - z2^2*x1
750
- p224_felem_diff_128_64(tmp, ftmp2);
751
- // tmp[i] < 2^116 + 2^64 + 8 < 2^117
752
- p224_felem_reduce(ftmp, tmp);
753
-
754
- // the formulae are incorrect if the points are equal
755
- // so we check for this and do doubling if this happens
756
- x_equal = p224_felem_is_zero(ftmp);
757
- y_equal = p224_felem_is_zero(ftmp3);
758
- z1_is_zero = p224_felem_is_zero(z1);
759
- z2_is_zero = p224_felem_is_zero(z2);
760
- // In affine coordinates, (X_1, Y_1) == (X_2, Y_2)
761
- p224_limb is_nontrivial_double =
762
- x_equal & y_equal & (1 - z1_is_zero) & (1 - z2_is_zero);
763
- if (is_nontrivial_double) {
764
- p224_point_double(x3, y3, z3, x1, y1, z1);
765
- return;
766
- }
767
-
768
- // ftmp5 = z1*z2
769
- if (!mixed) {
770
- p224_felem_mul(tmp, z1, z2);
771
- p224_felem_reduce(ftmp5, tmp);
772
- } else {
773
- // special case z2 = 0 is handled later
774
- p224_felem_assign(ftmp5, z1);
775
- }
776
-
777
- // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2)
778
- p224_felem_mul(tmp, ftmp, ftmp5);
779
- p224_felem_reduce(z_out, tmp);
780
-
781
- // ftmp = (z1^2*x2 - z2^2*x1)^2
782
- p224_felem_assign(ftmp5, ftmp);
783
- p224_felem_square(tmp, ftmp);
784
- p224_felem_reduce(ftmp, tmp);
785
-
786
- // ftmp5 = (z1^2*x2 - z2^2*x1)^3
787
- p224_felem_mul(tmp, ftmp, ftmp5);
788
- p224_felem_reduce(ftmp5, tmp);
789
-
790
- // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2
791
- p224_felem_mul(tmp, ftmp2, ftmp);
792
- p224_felem_reduce(ftmp2, tmp);
793
-
794
- // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3
795
- p224_felem_mul(tmp, ftmp4, ftmp5);
796
- // tmp[i] < 4 * 2^57 * 2^57 = 2^116
797
-
798
- // tmp2 = (z1^3*y2 - z2^3*y1)^2
799
- p224_felem_square(tmp2, ftmp3);
800
- // tmp2[i] < 4 * 2^57 * 2^57 < 2^116
801
-
802
- // tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3
803
- p224_felem_diff_128_64(tmp2, ftmp5);
804
- // tmp2[i] < 2^116 + 2^64 + 8 < 2^117
805
-
806
- // ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
807
- p224_felem_assign(ftmp5, ftmp2);
808
- p224_felem_scalar(ftmp5, 2);
809
- // ftmp5[i] < 2 * 2^57 = 2^58
810
-
811
- /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
812
- 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
813
- p224_felem_diff_128_64(tmp2, ftmp5);
814
- // tmp2[i] < 2^117 + 2^64 + 8 < 2^118
815
- p224_felem_reduce(x_out, tmp2);
816
-
817
- // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out
818
- p224_felem_diff(ftmp2, x_out);
819
- // ftmp2[i] < 2^57 + 2^58 + 2 < 2^59
820
-
821
- // tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
822
- p224_felem_mul(tmp2, ftmp3, ftmp2);
823
- // tmp2[i] < 4 * 2^57 * 2^59 = 2^118
824
-
825
- /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
826
- z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
827
- p224_widefelem_diff(tmp2, tmp);
828
- // tmp2[i] < 2^118 + 2^120 < 2^121
829
- p224_felem_reduce(y_out, tmp2);
830
-
831
- // the result (x_out, y_out, z_out) is incorrect if one of the inputs is
832
- // the point at infinity, so we need to check for this separately
833
-
834
- // if point 1 is at infinity, copy point 2 to output, and vice versa
835
- p224_copy_conditional(x_out, x2, z1_is_zero);
836
- p224_copy_conditional(x_out, x1, z2_is_zero);
837
- p224_copy_conditional(y_out, y2, z1_is_zero);
838
- p224_copy_conditional(y_out, y1, z2_is_zero);
839
- p224_copy_conditional(z_out, z2, z1_is_zero);
840
- p224_copy_conditional(z_out, z1, z2_is_zero);
841
- p224_felem_assign(x3, x_out);
842
- p224_felem_assign(y3, y_out);
843
- p224_felem_assign(z3, z_out);
844
- }
845
-
846
- // p224_select_point selects the |idx|th point from a precomputation table and
847
- // copies it to out.
848
- static void p224_select_point(const uint64_t idx, size_t size,
849
- const p224_felem pre_comp[/*size*/][3],
850
- p224_felem out[3]) {
851
- p224_limb *outlimbs = &out[0][0];
852
- OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem));
853
-
854
- for (size_t i = 0; i < size; i++) {
855
- const p224_limb *inlimbs = &pre_comp[i][0][0];
856
- uint64_t mask = i ^ idx;
857
- mask |= mask >> 4;
858
- mask |= mask >> 2;
859
- mask |= mask >> 1;
860
- mask &= 1;
861
- mask--;
862
- for (size_t j = 0; j < 4 * 3; j++) {
863
- outlimbs[j] |= inlimbs[j] & mask;
864
- }
865
- }
866
- }
867
-
868
- // p224_get_bit returns the |i|th bit in |in|
869
- static crypto_word_t p224_get_bit(const p224_felem_bytearray in, size_t i) {
870
- if (i >= 224) {
871
- return 0;
872
- }
873
- return (in[i >> 3] >> (i & 7)) & 1;
874
- }
875
-
876
- // Takes the Jacobian coordinates (X, Y, Z) of a point and returns
877
- // (X', Y') = (X/Z^2, Y/Z^3)
878
- static int ec_GFp_nistp224_point_get_affine_coordinates(
879
- const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x,
880
- EC_FELEM *y) {
881
- if (ec_GFp_simple_is_at_infinity(group, point)) {
882
- OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
883
- return 0;
884
- }
885
-
886
- p224_felem z1, z2;
887
- p224_widefelem tmp;
888
- p224_generic_to_felem(z1, &point->Z);
889
- p224_felem_inv(z2, z1);
890
- p224_felem_square(tmp, z2);
891
- p224_felem_reduce(z1, tmp);
892
-
893
- if (x != NULL) {
894
- p224_felem x_in, x_out;
895
- p224_generic_to_felem(x_in, &point->X);
896
- p224_felem_mul(tmp, x_in, z1);
897
- p224_felem_reduce(x_out, tmp);
898
- p224_felem_to_generic(x, x_out);
899
- }
900
-
901
- if (y != NULL) {
902
- p224_felem y_in, y_out;
903
- p224_generic_to_felem(y_in, &point->Y);
904
- p224_felem_mul(tmp, z1, z2);
905
- p224_felem_reduce(z1, tmp);
906
- p224_felem_mul(tmp, y_in, z1);
907
- p224_felem_reduce(y_out, tmp);
908
- p224_felem_to_generic(y, y_out);
909
- }
910
-
911
- return 1;
912
- }
913
-
914
- static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_RAW_POINT *r,
915
- const EC_RAW_POINT *a, const EC_RAW_POINT *b) {
916
- p224_felem x1, y1, z1, x2, y2, z2;
917
- p224_generic_to_felem(x1, &a->X);
918
- p224_generic_to_felem(y1, &a->Y);
919
- p224_generic_to_felem(z1, &a->Z);
920
- p224_generic_to_felem(x2, &b->X);
921
- p224_generic_to_felem(y2, &b->Y);
922
- p224_generic_to_felem(z2, &b->Z);
923
- p224_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, z2);
924
- // The outputs are already reduced, but still need to be contracted.
925
- p224_felem_to_generic(&r->X, x1);
926
- p224_felem_to_generic(&r->Y, y1);
927
- p224_felem_to_generic(&r->Z, z1);
928
- }
929
-
930
- static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_RAW_POINT *r,
931
- const EC_RAW_POINT *a) {
932
- p224_felem x, y, z;
933
- p224_generic_to_felem(x, &a->X);
934
- p224_generic_to_felem(y, &a->Y);
935
- p224_generic_to_felem(z, &a->Z);
936
- p224_point_double(x, y, z, x, y, z);
937
- // The outputs are already reduced, but still need to be contracted.
938
- p224_felem_to_generic(&r->X, x);
939
- p224_felem_to_generic(&r->Y, y);
940
- p224_felem_to_generic(&r->Z, z);
941
- }
942
-
943
- static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3],
944
- const EC_RAW_POINT *p) {
945
- OPENSSL_memset(out[0], 0, sizeof(p224_felem) * 3);
946
-
947
- p224_generic_to_felem(out[1][0], &p->X);
948
- p224_generic_to_felem(out[1][1], &p->Y);
949
- p224_generic_to_felem(out[1][2], &p->Z);
950
-
951
- for (size_t j = 2; j <= 16; ++j) {
952
- if (j & 1) {
953
- p224_point_add(out[j][0], out[j][1], out[j][2], out[1][0], out[1][1],
954
- out[1][2], 0, out[j - 1][0], out[j - 1][1], out[j - 1][2]);
955
- } else {
956
- p224_point_double(out[j][0], out[j][1], out[j][2], out[j / 2][0],
957
- out[j / 2][1], out[j / 2][2]);
958
- }
959
- }
960
- }
961
-
962
- static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r,
963
- const EC_RAW_POINT *p,
964
- const EC_SCALAR *scalar) {
965
- p224_felem p_pre_comp[17][3];
966
- ec_GFp_nistp224_make_precomp(p_pre_comp, p);
967
-
968
- // Set nq to the point at infinity.
969
- p224_felem nq[3], tmp[4];
970
- OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
971
-
972
- int skip = 1; // Save two point operations in the first round.
973
- for (size_t i = 220; i < 221; i--) {
974
- if (!skip) {
975
- p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
976
- }
977
-
978
- // Add every 5 doublings.
979
- if (i % 5 == 0) {
980
- crypto_word_t bits = p224_get_bit(scalar->bytes, i + 4) << 5;
981
- bits |= p224_get_bit(scalar->bytes, i + 3) << 4;
982
- bits |= p224_get_bit(scalar->bytes, i + 2) << 3;
983
- bits |= p224_get_bit(scalar->bytes, i + 1) << 2;
984
- bits |= p224_get_bit(scalar->bytes, i) << 1;
985
- bits |= p224_get_bit(scalar->bytes, i - 1);
986
- crypto_word_t sign, digit;
987
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
988
-
989
- // Select the point to add or subtract.
990
- p224_select_point(digit, 17, (const p224_felem(*)[3])p_pre_comp, tmp);
991
- p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point
992
- p224_copy_conditional(tmp[1], tmp[3], sign);
993
-
994
- if (!skip) {
995
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
996
- tmp[0], tmp[1], tmp[2]);
997
- } else {
998
- OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
999
- skip = 0;
1000
- }
1001
- }
1002
- }
1003
-
1004
- // Reduce the output to its unique minimal representation.
1005
- p224_felem_to_generic(&r->X, nq[0]);
1006
- p224_felem_to_generic(&r->Y, nq[1]);
1007
- p224_felem_to_generic(&r->Z, nq[2]);
1008
- }
1009
-
1010
- static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group,
1011
- EC_RAW_POINT *r,
1012
- const EC_SCALAR *scalar) {
1013
- // Set nq to the point at infinity.
1014
- p224_felem nq[3], tmp[3];
1015
- OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
1016
-
1017
- int skip = 1; // Save two point operations in the first round.
1018
- for (size_t i = 27; i < 28; i--) {
1019
- // double
1020
- if (!skip) {
1021
- p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1022
- }
1023
-
1024
- // First, look 28 bits upwards.
1025
- crypto_word_t bits = p224_get_bit(scalar->bytes, i + 196) << 3;
1026
- bits |= p224_get_bit(scalar->bytes, i + 140) << 2;
1027
- bits |= p224_get_bit(scalar->bytes, i + 84) << 1;
1028
- bits |= p224_get_bit(scalar->bytes, i + 28);
1029
- // Select the point to add, in constant time.
1030
- p224_select_point(bits, 16, g_p224_pre_comp[1], tmp);
1031
-
1032
- if (!skip) {
1033
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1034
- tmp[0], tmp[1], tmp[2]);
1035
- } else {
1036
- OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
1037
- skip = 0;
1038
- }
1039
-
1040
- // Second, look at the current position/
1041
- bits = p224_get_bit(scalar->bytes, i + 168) << 3;
1042
- bits |= p224_get_bit(scalar->bytes, i + 112) << 2;
1043
- bits |= p224_get_bit(scalar->bytes, i + 56) << 1;
1044
- bits |= p224_get_bit(scalar->bytes, i);
1045
- // Select the point to add, in constant time.
1046
- p224_select_point(bits, 16, g_p224_pre_comp[0], tmp);
1047
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1048
- tmp[0], tmp[1], tmp[2]);
1049
- }
1050
-
1051
- // Reduce the output to its unique minimal representation.
1052
- p224_felem_to_generic(&r->X, nq[0]);
1053
- p224_felem_to_generic(&r->Y, nq[1]);
1054
- p224_felem_to_generic(&r->Z, nq[2]);
1055
- }
1056
-
1057
- static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group,
1058
- EC_RAW_POINT *r,
1059
- const EC_SCALAR *g_scalar,
1060
- const EC_RAW_POINT *p,
1061
- const EC_SCALAR *p_scalar) {
1062
- // TODO(davidben): If P-224 ECDSA verify performance ever matters, using
1063
- // |ec_compute_wNAF| for |p_scalar| would likely be an easy improvement.
1064
- p224_felem p_pre_comp[17][3];
1065
- ec_GFp_nistp224_make_precomp(p_pre_comp, p);
1066
-
1067
- // Set nq to the point at infinity.
1068
- p224_felem nq[3], tmp[3];
1069
- OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
1070
-
1071
- // Loop over both scalars msb-to-lsb, interleaving additions of multiples of
1072
- // the generator (two in each of the last 28 rounds) and additions of p (every
1073
- // 5th round).
1074
- int skip = 1; // Save two point operations in the first round.
1075
- for (size_t i = 220; i < 221; i--) {
1076
- if (!skip) {
1077
- p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1078
- }
1079
-
1080
- // Add multiples of the generator.
1081
- if (i <= 27) {
1082
- // First, look 28 bits upwards.
1083
- crypto_word_t bits = p224_get_bit(g_scalar->bytes, i + 196) << 3;
1084
- bits |= p224_get_bit(g_scalar->bytes, i + 140) << 2;
1085
- bits |= p224_get_bit(g_scalar->bytes, i + 84) << 1;
1086
- bits |= p224_get_bit(g_scalar->bytes, i + 28);
1087
-
1088
- size_t index = (size_t)bits;
1089
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1090
- g_p224_pre_comp[1][index][0], g_p224_pre_comp[1][index][1],
1091
- g_p224_pre_comp[1][index][2]);
1092
- assert(!skip);
1093
-
1094
- // Second, look at the current position.
1095
- bits = p224_get_bit(g_scalar->bytes, i + 168) << 3;
1096
- bits |= p224_get_bit(g_scalar->bytes, i + 112) << 2;
1097
- bits |= p224_get_bit(g_scalar->bytes, i + 56) << 1;
1098
- bits |= p224_get_bit(g_scalar->bytes, i);
1099
- index = (size_t)bits;
1100
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1101
- g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1],
1102
- g_p224_pre_comp[0][index][2]);
1103
- }
1104
-
1105
- // Incorporate |p_scalar| every 5 doublings.
1106
- if (i % 5 == 0) {
1107
- crypto_word_t bits = p224_get_bit(p_scalar->bytes, i + 4) << 5;
1108
- bits |= p224_get_bit(p_scalar->bytes, i + 3) << 4;
1109
- bits |= p224_get_bit(p_scalar->bytes, i + 2) << 3;
1110
- bits |= p224_get_bit(p_scalar->bytes, i + 1) << 2;
1111
- bits |= p224_get_bit(p_scalar->bytes, i) << 1;
1112
- bits |= p224_get_bit(p_scalar->bytes, i - 1);
1113
- crypto_word_t sign, digit;
1114
- ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1115
-
1116
- // Select the point to add or subtract.
1117
- OPENSSL_memcpy(tmp, p_pre_comp[digit], 3 * sizeof(p224_felem));
1118
- if (sign) {
1119
- p224_felem_neg(tmp[1], tmp[1]); // (X, -Y, Z) is the negative point
1120
- }
1121
-
1122
- if (!skip) {
1123
- p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
1124
- tmp[0], tmp[1], tmp[2]);
1125
- } else {
1126
- OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
1127
- skip = 0;
1128
- }
1129
- }
1130
- }
1131
-
1132
- // Reduce the output to its unique minimal representation.
1133
- p224_felem_to_generic(&r->X, nq[0]);
1134
- p224_felem_to_generic(&r->Y, nq[1]);
1135
- p224_felem_to_generic(&r->Z, nq[2]);
1136
- }
1137
-
1138
- static void ec_GFp_nistp224_felem_mul(const EC_GROUP *group, EC_FELEM *r,
1139
- const EC_FELEM *a, const EC_FELEM *b) {
1140
- p224_felem felem1, felem2;
1141
- p224_widefelem wide;
1142
- p224_generic_to_felem(felem1, a);
1143
- p224_generic_to_felem(felem2, b);
1144
- p224_felem_mul(wide, felem1, felem2);
1145
- p224_felem_reduce(felem1, wide);
1146
- p224_felem_to_generic(r, felem1);
1147
- }
1148
-
1149
- static void ec_GFp_nistp224_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
1150
- const EC_FELEM *a) {
1151
- p224_felem felem;
1152
- p224_generic_to_felem(felem, a);
1153
- p224_widefelem wide;
1154
- p224_felem_square(wide, felem);
1155
- p224_felem_reduce(felem, wide);
1156
- p224_felem_to_generic(r, felem);
1157
- }
1158
-
1159
- DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) {
1160
- out->group_init = ec_GFp_simple_group_init;
1161
- out->group_finish = ec_GFp_simple_group_finish;
1162
- out->group_set_curve = ec_GFp_simple_group_set_curve;
1163
- out->point_get_affine_coordinates =
1164
- ec_GFp_nistp224_point_get_affine_coordinates;
1165
- out->add = ec_GFp_nistp224_add;
1166
- out->dbl = ec_GFp_nistp224_dbl;
1167
- out->mul = ec_GFp_nistp224_point_mul;
1168
- out->mul_base = ec_GFp_nistp224_point_mul_base;
1169
- out->mul_public = ec_GFp_nistp224_point_mul_public;
1170
- out->felem_mul = ec_GFp_nistp224_felem_mul;
1171
- out->felem_sqr = ec_GFp_nistp224_felem_sqr;
1172
- out->felem_to_bytes = ec_GFp_simple_felem_to_bytes;
1173
- out->felem_from_bytes = ec_GFp_simple_felem_from_bytes;
1174
- out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery;
1175
- out->scalar_to_montgomery_inv_vartime =
1176
- ec_simple_scalar_to_montgomery_inv_vartime;
1177
- out->cmp_x_coordinate = ec_GFp_simple_cmp_x_coordinate;
1178
- }
1179
-
1180
- #endif // BORINGSSL_HAS_UINT128 && !SMALL
1
+ /* Copyright (c) 2015, Google Inc.
2
+ *
3
+ * Permission to use, copy, modify, and/or distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
+
15
+ // A 64-bit implementation of the NIST P-224 elliptic curve point multiplication
16
+ //
17
+ // Inspired by Daniel J. Bernstein's public domain nistp224 implementation
18
+ // and Adam Langley's public domain 64-bit C implementation of curve25519.
19
+
20
+ #include <openssl/base.h>
21
+
22
+ #include <openssl/bn.h>
23
+ #include <openssl/ec.h>
24
+ #include <openssl/err.h>
25
+ #include <openssl/mem.h>
26
+
27
+ #include <string.h>
28
+
29
+ #include "internal.h"
30
+ #include "../delocate.h"
31
+ #include "../../internal.h"
32
+
33
+
34
+ #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL)
35
+
36
+ // Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3
37
+ // using 64-bit coefficients called 'limbs', and sometimes (for multiplication
38
+ // results) as b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 +
39
+ // 2^336*b_6 using 128-bit coefficients called 'widelimbs'. A 4-p224_limb
40
+ // representation is an 'p224_felem'; a 7-p224_widelimb representation is a
41
+ // 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we
42
+ // don't always reduce the representations: we ensure that inputs to each
43
+ // p224_felem multiplication satisfy a_i < 2^60, so outputs satisfy b_i <
44
+ // 4*2^60*2^60, and fit into a 128-bit word without overflow. The coefficients
45
+ // are then again partially reduced to obtain an p224_felem satisfying a_i <
46
+ // 2^57. We only reduce to the unique minimal representation at the end of the
47
+ // computation.
48
+
49
+ typedef uint64_t p224_limb;
50
+ typedef uint128_t p224_widelimb;
51
+
52
+ typedef p224_limb p224_felem[4];
53
+ typedef p224_widelimb p224_widefelem[7];
54
+
55
+ // Precomputed multiples of the standard generator
56
+ // Points are given in coordinates (X, Y, Z) where Z normally is 1
57
+ // (0 for the point at infinity).
58
+ // For each field element, slice a_0 is word 0, etc.
59
+ //
60
+ // The table has 2 * 16 elements, starting with the following:
61
+ // index | bits | point
62
+ // ------+---------+------------------------------
63
+ // 0 | 0 0 0 0 | 0G
64
+ // 1 | 0 0 0 1 | 1G
65
+ // 2 | 0 0 1 0 | 2^56G
66
+ // 3 | 0 0 1 1 | (2^56 + 1)G
67
+ // 4 | 0 1 0 0 | 2^112G
68
+ // 5 | 0 1 0 1 | (2^112 + 1)G
69
+ // 6 | 0 1 1 0 | (2^112 + 2^56)G
70
+ // 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G
71
+ // 8 | 1 0 0 0 | 2^168G
72
+ // 9 | 1 0 0 1 | (2^168 + 1)G
73
+ // 10 | 1 0 1 0 | (2^168 + 2^56)G
74
+ // 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G
75
+ // 12 | 1 1 0 0 | (2^168 + 2^112)G
76
+ // 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G
77
+ // 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G
78
+ // 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G
79
+ // followed by a copy of this with each element multiplied by 2^28.
80
+ //
81
+ // The reason for this is so that we can clock bits into four different
82
+ // locations when doing simple scalar multiplies against the base point,
83
+ // and then another four locations using the second 16 elements.
84
+ static const p224_felem g_p224_pre_comp[2][16][3] = {
85
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
86
+ {{0x3280d6115c1d21, 0xc1d356c2112234, 0x7f321390b94a03, 0xb70e0cbd6bb4bf},
87
+ {0xd5819985007e34, 0x75a05a07476444, 0xfb4c22dfe6cd43, 0xbd376388b5f723},
88
+ {1, 0, 0, 0}},
89
+ {{0xfd9675666ebbe9, 0xbca7664d40ce5e, 0x2242df8d8a2a43, 0x1f49bbb0f99bc5},
90
+ {0x29e0b892dc9c43, 0xece8608436e662, 0xdc858f185310d0, 0x9812dd4eb8d321},
91
+ {1, 0, 0, 0}},
92
+ {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, 0x16e9a3bbce8a3f, 0xeedcccd8c2a748},
93
+ {0xf19f90ed50266d, 0xabf2b4bf65f9df, 0x313865468fafec, 0x5cb379ba910a17},
94
+ {1, 0, 0, 0}},
95
+ {{0x0641966cab26e3, 0x91fb2991fab0a0, 0xefec27a4e13a0b, 0x0499aa8a5f8ebe},
96
+ {0x7510407766af5d, 0x84d929610d5450, 0x81d77aae82f706, 0x6916f6d4338c5b},
97
+ {1, 0, 0, 0}},
98
+ {{0xea95ac3b1f15c6, 0x086000905e82d4, 0xdd323ae4d1c8b1, 0x932b56be7685a3},
99
+ {0x9ef93dea25dbbf, 0x41665960f390f0, 0xfdec76dbe2a8a7, 0x523e80f019062a},
100
+ {1, 0, 0, 0}},
101
+ {{0x822fdd26732c73, 0xa01c83531b5d0f, 0x363f37347c1ba4, 0xc391b45c84725c},
102
+ {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, 0xc393da7e222a7f, 0x1efb7890ede244},
103
+ {1, 0, 0, 0}},
104
+ {{0x4c9e90ca217da1, 0xd11beca79159bb, 0xff8d33c2c98b7c, 0x2610b39409f849},
105
+ {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, 0x966c079b753c89, 0xfe67e4e820b112},
106
+ {1, 0, 0, 0}},
107
+ {{0xe28cae2df5312d, 0xc71b61d16f5c6e, 0x79b7619a3e7c4c, 0x05c73240899b47},
108
+ {0x9f7f6382c73e3a, 0x18615165c56bda, 0x641fab2116fd56, 0x72855882b08394},
109
+ {1, 0, 0, 0}},
110
+ {{0x0469182f161c09, 0x74a98ca8d00fb5, 0xb89da93489a3e0, 0x41c98768fb0c1d},
111
+ {0xe5ea05fb32da81, 0x3dce9ffbca6855, 0x1cfe2d3fbf59e6, 0x0e5e03408738a7},
112
+ {1, 0, 0, 0}},
113
+ {{0xdab22b2333e87f, 0x4430137a5dd2f6, 0xe03ab9f738beb8, 0xcb0c5d0dc34f24},
114
+ {0x764a7df0c8fda5, 0x185ba5c3fa2044, 0x9281d688bcbe50, 0xc40331df893881},
115
+ {1, 0, 0, 0}},
116
+ {{0xb89530796f0f60, 0xade92bd26909a3, 0x1a0c83fb4884da, 0x1765bf22a5a984},
117
+ {0x772a9ee75db09e, 0x23bc6c67cec16f, 0x4c1edba8b14e2f, 0xe2a215d9611369},
118
+ {1, 0, 0, 0}},
119
+ {{0x571e509fb5efb3, 0xade88696410552, 0xc8ae85fada74fe, 0x6c7e4be83bbde3},
120
+ {0xff9f51160f4652, 0xb47ce2495a6539, 0xa2946c53b582f4, 0x286d2db3ee9a60},
121
+ {1, 0, 0, 0}},
122
+ {{0x40bbd5081a44af, 0x0995183b13926c, 0xbcefba6f47f6d0, 0x215619e9cc0057},
123
+ {0x8bc94d3b0df45e, 0xf11c54a3694f6f, 0x8631b93cdfe8b5, 0xe7e3f4b0982db9},
124
+ {1, 0, 0, 0}},
125
+ {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, 0x1c29819435d2c6, 0xc813132f4c07e9},
126
+ {0x2891425503b11f, 0x08781030579fea, 0xf5426ba5cc9674, 0x1e28ebf18562bc},
127
+ {1, 0, 0, 0}},
128
+ {{0x9f31997cc864eb, 0x06cd91d28b5e4c, 0xff17036691a973, 0xf1aef351497c58},
129
+ {0xdd1f2d600564ff, 0xdead073b1402db, 0x74a684435bd693, 0xeea7471f962558},
130
+ {1, 0, 0, 0}}},
131
+ {{{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
132
+ {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31},
133
+ {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d},
134
+ {1, 0, 0, 0}},
135
+ {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3},
136
+ {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a},
137
+ {1, 0, 0, 0}},
138
+ {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33},
139
+ {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100},
140
+ {1, 0, 0, 0}},
141
+ {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5},
142
+ {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea},
143
+ {1, 0, 0, 0}},
144
+ {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be},
145
+ {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51},
146
+ {1, 0, 0, 0}},
147
+ {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1},
148
+ {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb},
149
+ {1, 0, 0, 0}},
150
+ {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233},
151
+ {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def},
152
+ {1, 0, 0, 0}},
153
+ {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae},
154
+ {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45},
155
+ {1, 0, 0, 0}},
156
+ {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e},
157
+ {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb},
158
+ {1, 0, 0, 0}},
159
+ {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de},
160
+ {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3},
161
+ {1, 0, 0, 0}},
162
+ {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05},
163
+ {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58},
164
+ {1, 0, 0, 0}},
165
+ {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb},
166
+ {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0},
167
+ {1, 0, 0, 0}},
168
+ {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9},
169
+ {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea},
170
+ {1, 0, 0, 0}},
171
+ {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba},
172
+ {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405},
173
+ {1, 0, 0, 0}},
174
+ {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e},
175
+ {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e},
176
+ {1, 0, 0, 0}}}};
177
+
178
+
179
+ // Helper functions to convert field elements to/from internal representation
180
+
181
+ static void p224_generic_to_felem(p224_felem out, const EC_FELEM *in) {
182
+ // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM|
183
+ // uses four 64-bit words. (The top-most word only has 32 bits.)
184
+ out[0] = in->words[0] & 0x00ffffffffffffff;
185
+ out[1] = ((in->words[0] >> 56) | (in->words[1] << 8)) & 0x00ffffffffffffff;
186
+ out[2] = ((in->words[1] >> 48) | (in->words[2] << 16)) & 0x00ffffffffffffff;
187
+ out[3] = ((in->words[2] >> 40) | (in->words[3] << 24)) & 0x00ffffffffffffff;
188
+ }
189
+
190
+ // Requires 0 <= in < 2*p (always call p224_felem_reduce first)
191
+ static void p224_felem_to_generic(EC_FELEM *out, const p224_felem in) {
192
+ // Reduce to unique minimal representation.
193
+ static const int64_t two56 = ((p224_limb)1) << 56;
194
+ // 0 <= in < 2*p, p = 2^224 - 2^96 + 1
195
+ // if in > p , reduce in = in - 2^224 + 2^96 - 1
196
+ int64_t tmp[4], a;
197
+ tmp[0] = in[0];
198
+ tmp[1] = in[1];
199
+ tmp[2] = in[2];
200
+ tmp[3] = in[3];
201
+ // Case 1: a = 1 iff in >= 2^224
202
+ a = (in[3] >> 56);
203
+ tmp[0] -= a;
204
+ tmp[1] += a << 40;
205
+ tmp[3] &= 0x00ffffffffffffff;
206
+ // Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 and
207
+ // the lower part is non-zero
208
+ a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) |
209
+ (((int64_t)(in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63);
210
+ a &= 0x00ffffffffffffff;
211
+ // turn a into an all-one mask (if a = 0) or an all-zero mask
212
+ a = (a - 1) >> 63;
213
+ // subtract 2^224 - 2^96 + 1 if a is all-one
214
+ tmp[3] &= a ^ 0xffffffffffffffff;
215
+ tmp[2] &= a ^ 0xffffffffffffffff;
216
+ tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff;
217
+ tmp[0] -= 1 & a;
218
+
219
+ // eliminate negative coefficients: if tmp[0] is negative, tmp[1] must
220
+ // be non-zero, so we only need one step
221
+ a = tmp[0] >> 63;
222
+ tmp[0] += two56 & a;
223
+ tmp[1] -= 1 & a;
224
+
225
+ // carry 1 -> 2 -> 3
226
+ tmp[2] += tmp[1] >> 56;
227
+ tmp[1] &= 0x00ffffffffffffff;
228
+
229
+ tmp[3] += tmp[2] >> 56;
230
+ tmp[2] &= 0x00ffffffffffffff;
231
+
232
+ // Now 0 <= tmp < p
233
+ p224_felem tmp2;
234
+ tmp2[0] = tmp[0];
235
+ tmp2[1] = tmp[1];
236
+ tmp2[2] = tmp[2];
237
+ tmp2[3] = tmp[3];
238
+
239
+ // |p224_felem|'s minimal representation uses four 56-bit words. |EC_FELEM|
240
+ // uses four 64-bit words. (The top-most word only has 32 bits.)
241
+ out->words[0] = tmp2[0] | (tmp2[1] << 56);
242
+ out->words[1] = (tmp2[1] >> 8) | (tmp2[2] << 48);
243
+ out->words[2] = (tmp2[2] >> 16) | (tmp2[3] << 40);
244
+ out->words[3] = tmp2[3] >> 24;
245
+ }
246
+
247
+
248
+ // Field operations, using the internal representation of field elements.
249
+ // NB! These operations are specific to our point multiplication and cannot be
250
+ // expected to be correct in general - e.g., multiplication with a large scalar
251
+ // will cause an overflow.
252
+
253
+ static void p224_felem_assign(p224_felem out, const p224_felem in) {
254
+ out[0] = in[0];
255
+ out[1] = in[1];
256
+ out[2] = in[2];
257
+ out[3] = in[3];
258
+ }
259
+
260
+ // Sum two field elements: out += in
261
+ static void p224_felem_sum(p224_felem out, const p224_felem in) {
262
+ out[0] += in[0];
263
+ out[1] += in[1];
264
+ out[2] += in[2];
265
+ out[3] += in[3];
266
+ }
267
+
268
+ // Subtract field elements: out -= in
269
+ // Assumes in[i] < 2^57
270
+ static void p224_felem_diff(p224_felem out, const p224_felem in) {
271
+ static const p224_limb two58p2 =
272
+ (((p224_limb)1) << 58) + (((p224_limb)1) << 2);
273
+ static const p224_limb two58m2 =
274
+ (((p224_limb)1) << 58) - (((p224_limb)1) << 2);
275
+ static const p224_limb two58m42m2 =
276
+ (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_limb)1) << 2);
277
+
278
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
279
+ out[0] += two58p2;
280
+ out[1] += two58m42m2;
281
+ out[2] += two58m2;
282
+ out[3] += two58m2;
283
+
284
+ out[0] -= in[0];
285
+ out[1] -= in[1];
286
+ out[2] -= in[2];
287
+ out[3] -= in[3];
288
+ }
289
+
290
+ // Subtract in unreduced 128-bit mode: out -= in
291
+ // Assumes in[i] < 2^119
292
+ static void p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) {
293
+ static const p224_widelimb two120 = ((p224_widelimb)1) << 120;
294
+ static const p224_widelimb two120m64 =
295
+ (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64);
296
+ static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) -
297
+ (((p224_widelimb)1) << 104) -
298
+ (((p224_widelimb)1) << 64);
299
+
300
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
301
+ out[0] += two120;
302
+ out[1] += two120m64;
303
+ out[2] += two120m64;
304
+ out[3] += two120;
305
+ out[4] += two120m104m64;
306
+ out[5] += two120m64;
307
+ out[6] += two120m64;
308
+
309
+ out[0] -= in[0];
310
+ out[1] -= in[1];
311
+ out[2] -= in[2];
312
+ out[3] -= in[3];
313
+ out[4] -= in[4];
314
+ out[5] -= in[5];
315
+ out[6] -= in[6];
316
+ }
317
+
318
+ // Subtract in mixed mode: out128 -= in64
319
+ // in[i] < 2^63
320
+ static void p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) {
321
+ static const p224_widelimb two64p8 =
322
+ (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8);
323
+ static const p224_widelimb two64m8 =
324
+ (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8);
325
+ static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) -
326
+ (((p224_widelimb)1) << 48) -
327
+ (((p224_widelimb)1) << 8);
328
+
329
+ // Add 0 mod 2^224-2^96+1 to ensure out > in
330
+ out[0] += two64p8;
331
+ out[1] += two64m48m8;
332
+ out[2] += two64m8;
333
+ out[3] += two64m8;
334
+
335
+ out[0] -= in[0];
336
+ out[1] -= in[1];
337
+ out[2] -= in[2];
338
+ out[3] -= in[3];
339
+ }
340
+
341
+ // Multiply a field element by a scalar: out = out * scalar
342
+ // The scalars we actually use are small, so results fit without overflow
343
+ static void p224_felem_scalar(p224_felem out, const p224_limb scalar) {
344
+ out[0] *= scalar;
345
+ out[1] *= scalar;
346
+ out[2] *= scalar;
347
+ out[3] *= scalar;
348
+ }
349
+
350
+ // Multiply an unreduced field element by a scalar: out = out * scalar
351
+ // The scalars we actually use are small, so results fit without overflow
352
+ static void p224_widefelem_scalar(p224_widefelem out,
353
+ const p224_widelimb scalar) {
354
+ out[0] *= scalar;
355
+ out[1] *= scalar;
356
+ out[2] *= scalar;
357
+ out[3] *= scalar;
358
+ out[4] *= scalar;
359
+ out[5] *= scalar;
360
+ out[6] *= scalar;
361
+ }
362
+
363
+ // Square a field element: out = in^2
364
+ static void p224_felem_square(p224_widefelem out, const p224_felem in) {
365
+ p224_limb tmp0, tmp1, tmp2;
366
+ tmp0 = 2 * in[0];
367
+ tmp1 = 2 * in[1];
368
+ tmp2 = 2 * in[2];
369
+ out[0] = ((p224_widelimb)in[0]) * in[0];
370
+ out[1] = ((p224_widelimb)in[0]) * tmp1;
371
+ out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1];
372
+ out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2;
373
+ out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2];
374
+ out[5] = ((p224_widelimb)in[3]) * tmp2;
375
+ out[6] = ((p224_widelimb)in[3]) * in[3];
376
+ }
377
+
378
+ // Multiply two field elements: out = in1 * in2
379
+ static void p224_felem_mul(p224_widefelem out, const p224_felem in1,
380
+ const p224_felem in2) {
381
+ out[0] = ((p224_widelimb)in1[0]) * in2[0];
382
+ out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0];
383
+ out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] +
384
+ ((p224_widelimb)in1[2]) * in2[0];
385
+ out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] +
386
+ ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0];
387
+ out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] +
388
+ ((p224_widelimb)in1[3]) * in2[1];
389
+ out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2];
390
+ out[6] = ((p224_widelimb)in1[3]) * in2[3];
391
+ }
392
+
393
+ // Reduce seven 128-bit coefficients to four 64-bit coefficients.
394
+ // Requires in[i] < 2^126,
395
+ // ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
396
+ static void p224_felem_reduce(p224_felem out, const p224_widefelem in) {
397
+ static const p224_widelimb two127p15 =
398
+ (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15);
399
+ static const p224_widelimb two127m71 =
400
+ (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71);
401
+ static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) -
402
+ (((p224_widelimb)1) << 71) -
403
+ (((p224_widelimb)1) << 55);
404
+ p224_widelimb output[5];
405
+
406
+ // Add 0 mod 2^224-2^96+1 to ensure all differences are positive
407
+ output[0] = in[0] + two127p15;
408
+ output[1] = in[1] + two127m71m55;
409
+ output[2] = in[2] + two127m71;
410
+ output[3] = in[3];
411
+ output[4] = in[4];
412
+
413
+ // Eliminate in[4], in[5], in[6]
414
+ output[4] += in[6] >> 16;
415
+ output[3] += (in[6] & 0xffff) << 40;
416
+ output[2] -= in[6];
417
+
418
+ output[3] += in[5] >> 16;
419
+ output[2] += (in[5] & 0xffff) << 40;
420
+ output[1] -= in[5];
421
+
422
+ output[2] += output[4] >> 16;
423
+ output[1] += (output[4] & 0xffff) << 40;
424
+ output[0] -= output[4];
425
+
426
+ // Carry 2 -> 3 -> 4
427
+ output[3] += output[2] >> 56;
428
+ output[2] &= 0x00ffffffffffffff;
429
+
430
+ output[4] = output[3] >> 56;
431
+ output[3] &= 0x00ffffffffffffff;
432
+
433
+ // Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72
434
+
435
+ // Eliminate output[4]
436
+ output[2] += output[4] >> 16;
437
+ // output[2] < 2^56 + 2^56 = 2^57
438
+ output[1] += (output[4] & 0xffff) << 40;
439
+ output[0] -= output[4];
440
+
441
+ // Carry 0 -> 1 -> 2 -> 3
442
+ output[1] += output[0] >> 56;
443
+ out[0] = output[0] & 0x00ffffffffffffff;
444
+
445
+ output[2] += output[1] >> 56;
446
+ // output[2] < 2^57 + 2^72
447
+ out[1] = output[1] & 0x00ffffffffffffff;
448
+ output[3] += output[2] >> 56;
449
+ // output[3] <= 2^56 + 2^16
450
+ out[2] = output[2] & 0x00ffffffffffffff;
451
+
452
+ // out[0] < 2^56, out[1] < 2^56, out[2] < 2^56,
453
+ // out[3] <= 2^56 + 2^16 (due to final carry),
454
+ // so out < 2*p
455
+ out[3] = output[3];
456
+ }
457
+
458
+ // Get negative value: out = -in
459
+ // Requires in[i] < 2^63,
460
+ // ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16
461
+ static void p224_felem_neg(p224_felem out, const p224_felem in) {
462
+ p224_widefelem tmp = {0};
463
+ p224_felem_diff_128_64(tmp, in);
464
+ p224_felem_reduce(out, tmp);
465
+ }
466
+
467
+ // Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field
468
+ // elements are reduced to in < 2^225, so we only need to check three cases: 0,
469
+ // 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2
470
+ static p224_limb p224_felem_is_zero(const p224_felem in) {
471
+ p224_limb zero = in[0] | in[1] | in[2] | in[3];
472
+ zero = (((int64_t)(zero)-1) >> 63) & 1;
473
+
474
+ p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) |
475
+ (in[2] ^ 0x00ffffffffffffff) |
476
+ (in[3] ^ 0x00ffffffffffffff);
477
+ two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1;
478
+ p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) |
479
+ (in[2] ^ 0x00ffffffffffffff) |
480
+ (in[3] ^ 0x01ffffffffffffff);
481
+ two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1;
482
+ return (zero | two224m96p1 | two225m97p2);
483
+ }
484
+
485
+ // Invert a field element
486
+ // Computation chain copied from djb's code
487
+ static void p224_felem_inv(p224_felem out, const p224_felem in) {
488
+ p224_felem ftmp, ftmp2, ftmp3, ftmp4;
489
+ p224_widefelem tmp;
490
+
491
+ p224_felem_square(tmp, in);
492
+ p224_felem_reduce(ftmp, tmp); // 2
493
+ p224_felem_mul(tmp, in, ftmp);
494
+ p224_felem_reduce(ftmp, tmp); // 2^2 - 1
495
+ p224_felem_square(tmp, ftmp);
496
+ p224_felem_reduce(ftmp, tmp); // 2^3 - 2
497
+ p224_felem_mul(tmp, in, ftmp);
498
+ p224_felem_reduce(ftmp, tmp); // 2^3 - 1
499
+ p224_felem_square(tmp, ftmp);
500
+ p224_felem_reduce(ftmp2, tmp); // 2^4 - 2
501
+ p224_felem_square(tmp, ftmp2);
502
+ p224_felem_reduce(ftmp2, tmp); // 2^5 - 4
503
+ p224_felem_square(tmp, ftmp2);
504
+ p224_felem_reduce(ftmp2, tmp); // 2^6 - 8
505
+ p224_felem_mul(tmp, ftmp2, ftmp);
506
+ p224_felem_reduce(ftmp, tmp); // 2^6 - 1
507
+ p224_felem_square(tmp, ftmp);
508
+ p224_felem_reduce(ftmp2, tmp); // 2^7 - 2
509
+ for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6
510
+ p224_felem_square(tmp, ftmp2);
511
+ p224_felem_reduce(ftmp2, tmp);
512
+ }
513
+ p224_felem_mul(tmp, ftmp2, ftmp);
514
+ p224_felem_reduce(ftmp2, tmp); // 2^12 - 1
515
+ p224_felem_square(tmp, ftmp2);
516
+ p224_felem_reduce(ftmp3, tmp); // 2^13 - 2
517
+ for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12
518
+ p224_felem_square(tmp, ftmp3);
519
+ p224_felem_reduce(ftmp3, tmp);
520
+ }
521
+ p224_felem_mul(tmp, ftmp3, ftmp2);
522
+ p224_felem_reduce(ftmp2, tmp); // 2^24 - 1
523
+ p224_felem_square(tmp, ftmp2);
524
+ p224_felem_reduce(ftmp3, tmp); // 2^25 - 2
525
+ for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24
526
+ p224_felem_square(tmp, ftmp3);
527
+ p224_felem_reduce(ftmp3, tmp);
528
+ }
529
+ p224_felem_mul(tmp, ftmp3, ftmp2);
530
+ p224_felem_reduce(ftmp3, tmp); // 2^48 - 1
531
+ p224_felem_square(tmp, ftmp3);
532
+ p224_felem_reduce(ftmp4, tmp); // 2^49 - 2
533
+ for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48
534
+ p224_felem_square(tmp, ftmp4);
535
+ p224_felem_reduce(ftmp4, tmp);
536
+ }
537
+ p224_felem_mul(tmp, ftmp3, ftmp4);
538
+ p224_felem_reduce(ftmp3, tmp); // 2^96 - 1
539
+ p224_felem_square(tmp, ftmp3);
540
+ p224_felem_reduce(ftmp4, tmp); // 2^97 - 2
541
+ for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24
542
+ p224_felem_square(tmp, ftmp4);
543
+ p224_felem_reduce(ftmp4, tmp);
544
+ }
545
+ p224_felem_mul(tmp, ftmp2, ftmp4);
546
+ p224_felem_reduce(ftmp2, tmp); // 2^120 - 1
547
+ for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6
548
+ p224_felem_square(tmp, ftmp2);
549
+ p224_felem_reduce(ftmp2, tmp);
550
+ }
551
+ p224_felem_mul(tmp, ftmp2, ftmp);
552
+ p224_felem_reduce(ftmp, tmp); // 2^126 - 1
553
+ p224_felem_square(tmp, ftmp);
554
+ p224_felem_reduce(ftmp, tmp); // 2^127 - 2
555
+ p224_felem_mul(tmp, ftmp, in);
556
+ p224_felem_reduce(ftmp, tmp); // 2^127 - 1
557
+ for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97
558
+ p224_felem_square(tmp, ftmp);
559
+ p224_felem_reduce(ftmp, tmp);
560
+ }
561
+ p224_felem_mul(tmp, ftmp, ftmp3);
562
+ p224_felem_reduce(out, tmp); // 2^224 - 2^96 - 1
563
+ }
564
+
565
+ // Copy in constant time:
566
+ // if icopy == 1, copy in to out,
567
+ // if icopy == 0, copy out to itself.
568
+ static void p224_copy_conditional(p224_felem out, const p224_felem in,
569
+ p224_limb icopy) {
570
+ // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one
571
+ const p224_limb copy = -icopy;
572
+ for (size_t i = 0; i < 4; ++i) {
573
+ const p224_limb tmp = copy & (in[i] ^ out[i]);
574
+ out[i] ^= tmp;
575
+ }
576
+ }
577
+
578
+ // ELLIPTIC CURVE POINT OPERATIONS
579
+ //
580
+ // Points are represented in Jacobian projective coordinates:
581
+ // (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3),
582
+ // or to the point at infinity if Z == 0.
583
+
584
+ // Double an elliptic curve point:
585
+ // (X', Y', Z') = 2 * (X, Y, Z), where
586
+ // X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2
587
+ // Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2
588
+ // Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z
589
+ // Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed,
590
+ // while x_out == y_in is not (maybe this works, but it's not tested).
591
+ static void p224_point_double(p224_felem x_out, p224_felem y_out,
592
+ p224_felem z_out, const p224_felem x_in,
593
+ const p224_felem y_in, const p224_felem z_in) {
594
+ p224_widefelem tmp, tmp2;
595
+ p224_felem delta, gamma, beta, alpha, ftmp, ftmp2;
596
+
597
+ p224_felem_assign(ftmp, x_in);
598
+ p224_felem_assign(ftmp2, x_in);
599
+
600
+ // delta = z^2
601
+ p224_felem_square(tmp, z_in);
602
+ p224_felem_reduce(delta, tmp);
603
+
604
+ // gamma = y^2
605
+ p224_felem_square(tmp, y_in);
606
+ p224_felem_reduce(gamma, tmp);
607
+
608
+ // beta = x*gamma
609
+ p224_felem_mul(tmp, x_in, gamma);
610
+ p224_felem_reduce(beta, tmp);
611
+
612
+ // alpha = 3*(x-delta)*(x+delta)
613
+ p224_felem_diff(ftmp, delta);
614
+ // ftmp[i] < 2^57 + 2^58 + 2 < 2^59
615
+ p224_felem_sum(ftmp2, delta);
616
+ // ftmp2[i] < 2^57 + 2^57 = 2^58
617
+ p224_felem_scalar(ftmp2, 3);
618
+ // ftmp2[i] < 3 * 2^58 < 2^60
619
+ p224_felem_mul(tmp, ftmp, ftmp2);
620
+ // tmp[i] < 2^60 * 2^59 * 4 = 2^121
621
+ p224_felem_reduce(alpha, tmp);
622
+
623
+ // x' = alpha^2 - 8*beta
624
+ p224_felem_square(tmp, alpha);
625
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
626
+ p224_felem_assign(ftmp, beta);
627
+ p224_felem_scalar(ftmp, 8);
628
+ // ftmp[i] < 8 * 2^57 = 2^60
629
+ p224_felem_diff_128_64(tmp, ftmp);
630
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
631
+ p224_felem_reduce(x_out, tmp);
632
+
633
+ // z' = (y + z)^2 - gamma - delta
634
+ p224_felem_sum(delta, gamma);
635
+ // delta[i] < 2^57 + 2^57 = 2^58
636
+ p224_felem_assign(ftmp, y_in);
637
+ p224_felem_sum(ftmp, z_in);
638
+ // ftmp[i] < 2^57 + 2^57 = 2^58
639
+ p224_felem_square(tmp, ftmp);
640
+ // tmp[i] < 4 * 2^58 * 2^58 = 2^118
641
+ p224_felem_diff_128_64(tmp, delta);
642
+ // tmp[i] < 2^118 + 2^64 + 8 < 2^119
643
+ p224_felem_reduce(z_out, tmp);
644
+
645
+ // y' = alpha*(4*beta - x') - 8*gamma^2
646
+ p224_felem_scalar(beta, 4);
647
+ // beta[i] < 4 * 2^57 = 2^59
648
+ p224_felem_diff(beta, x_out);
649
+ // beta[i] < 2^59 + 2^58 + 2 < 2^60
650
+ p224_felem_mul(tmp, alpha, beta);
651
+ // tmp[i] < 4 * 2^57 * 2^60 = 2^119
652
+ p224_felem_square(tmp2, gamma);
653
+ // tmp2[i] < 4 * 2^57 * 2^57 = 2^116
654
+ p224_widefelem_scalar(tmp2, 8);
655
+ // tmp2[i] < 8 * 2^116 = 2^119
656
+ p224_widefelem_diff(tmp, tmp2);
657
+ // tmp[i] < 2^119 + 2^120 < 2^121
658
+ p224_felem_reduce(y_out, tmp);
659
+ }
660
+
661
+ // Add two elliptic curve points:
662
+ // (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where
663
+ // X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 -
664
+ // 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2
665
+ // Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 *
666
+ // X_1)^2 - X_3) -
667
+ // Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3
668
+ // Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2)
669
+ //
670
+ // This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0.
671
+
672
+ // This function is not entirely constant-time: it includes a branch for
673
+ // checking whether the two input points are equal, (while not equal to the
674
+ // point at infinity). This case never happens during single point
675
+ // multiplication, so there is no timing leak for ECDH or ECDSA signing.
676
+ static void p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3,
677
+ const p224_felem x1, const p224_felem y1,
678
+ const p224_felem z1, const int mixed,
679
+ const p224_felem x2, const p224_felem y2,
680
+ const p224_felem z2) {
681
+ p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out;
682
+ p224_widefelem tmp, tmp2;
683
+ p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal;
684
+
685
+ if (!mixed) {
686
+ // ftmp2 = z2^2
687
+ p224_felem_square(tmp, z2);
688
+ p224_felem_reduce(ftmp2, tmp);
689
+
690
+ // ftmp4 = z2^3
691
+ p224_felem_mul(tmp, ftmp2, z2);
692
+ p224_felem_reduce(ftmp4, tmp);
693
+
694
+ // ftmp4 = z2^3*y1
695
+ p224_felem_mul(tmp2, ftmp4, y1);
696
+ p224_felem_reduce(ftmp4, tmp2);
697
+
698
+ // ftmp2 = z2^2*x1
699
+ p224_felem_mul(tmp2, ftmp2, x1);
700
+ p224_felem_reduce(ftmp2, tmp2);
701
+ } else {
702
+ // We'll assume z2 = 1 (special case z2 = 0 is handled later)
703
+
704
+ // ftmp4 = z2^3*y1
705
+ p224_felem_assign(ftmp4, y1);
706
+
707
+ // ftmp2 = z2^2*x1
708
+ p224_felem_assign(ftmp2, x1);
709
+ }
710
+
711
+ // ftmp = z1^2
712
+ p224_felem_square(tmp, z1);
713
+ p224_felem_reduce(ftmp, tmp);
714
+
715
+ // ftmp3 = z1^3
716
+ p224_felem_mul(tmp, ftmp, z1);
717
+ p224_felem_reduce(ftmp3, tmp);
718
+
719
+ // tmp = z1^3*y2
720
+ p224_felem_mul(tmp, ftmp3, y2);
721
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
722
+
723
+ // ftmp3 = z1^3*y2 - z2^3*y1
724
+ p224_felem_diff_128_64(tmp, ftmp4);
725
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
726
+ p224_felem_reduce(ftmp3, tmp);
727
+
728
+ // tmp = z1^2*x2
729
+ p224_felem_mul(tmp, ftmp, x2);
730
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
731
+
732
+ // ftmp = z1^2*x2 - z2^2*x1
733
+ p224_felem_diff_128_64(tmp, ftmp2);
734
+ // tmp[i] < 2^116 + 2^64 + 8 < 2^117
735
+ p224_felem_reduce(ftmp, tmp);
736
+
737
+ // the formulae are incorrect if the points are equal
738
+ // so we check for this and do doubling if this happens
739
+ x_equal = p224_felem_is_zero(ftmp);
740
+ y_equal = p224_felem_is_zero(ftmp3);
741
+ z1_is_zero = p224_felem_is_zero(z1);
742
+ z2_is_zero = p224_felem_is_zero(z2);
743
+ // In affine coordinates, (X_1, Y_1) == (X_2, Y_2)
744
+ p224_limb is_nontrivial_double =
745
+ x_equal & y_equal & (1 - z1_is_zero) & (1 - z2_is_zero);
746
+ if (is_nontrivial_double) {
747
+ p224_point_double(x3, y3, z3, x1, y1, z1);
748
+ return;
749
+ }
750
+
751
+ // ftmp5 = z1*z2
752
+ if (!mixed) {
753
+ p224_felem_mul(tmp, z1, z2);
754
+ p224_felem_reduce(ftmp5, tmp);
755
+ } else {
756
+ // special case z2 = 0 is handled later
757
+ p224_felem_assign(ftmp5, z1);
758
+ }
759
+
760
+ // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2)
761
+ p224_felem_mul(tmp, ftmp, ftmp5);
762
+ p224_felem_reduce(z_out, tmp);
763
+
764
+ // ftmp = (z1^2*x2 - z2^2*x1)^2
765
+ p224_felem_assign(ftmp5, ftmp);
766
+ p224_felem_square(tmp, ftmp);
767
+ p224_felem_reduce(ftmp, tmp);
768
+
769
+ // ftmp5 = (z1^2*x2 - z2^2*x1)^3
770
+ p224_felem_mul(tmp, ftmp, ftmp5);
771
+ p224_felem_reduce(ftmp5, tmp);
772
+
773
+ // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2
774
+ p224_felem_mul(tmp, ftmp2, ftmp);
775
+ p224_felem_reduce(ftmp2, tmp);
776
+
777
+ // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3
778
+ p224_felem_mul(tmp, ftmp4, ftmp5);
779
+ // tmp[i] < 4 * 2^57 * 2^57 = 2^116
780
+
781
+ // tmp2 = (z1^3*y2 - z2^3*y1)^2
782
+ p224_felem_square(tmp2, ftmp3);
783
+ // tmp2[i] < 4 * 2^57 * 2^57 < 2^116
784
+
785
+ // tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3
786
+ p224_felem_diff_128_64(tmp2, ftmp5);
787
+ // tmp2[i] < 2^116 + 2^64 + 8 < 2^117
788
+
789
+ // ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2
790
+ p224_felem_assign(ftmp5, ftmp2);
791
+ p224_felem_scalar(ftmp5, 2);
792
+ // ftmp5[i] < 2 * 2^57 = 2^58
793
+
794
+ /* x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 -
795
+ 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */
796
+ p224_felem_diff_128_64(tmp2, ftmp5);
797
+ // tmp2[i] < 2^117 + 2^64 + 8 < 2^118
798
+ p224_felem_reduce(x_out, tmp2);
799
+
800
+ // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out
801
+ p224_felem_diff(ftmp2, x_out);
802
+ // ftmp2[i] < 2^57 + 2^58 + 2 < 2^59
803
+
804
+ // tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out)
805
+ p224_felem_mul(tmp2, ftmp3, ftmp2);
806
+ // tmp2[i] < 4 * 2^57 * 2^59 = 2^118
807
+
808
+ /* y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) -
809
+ z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */
810
+ p224_widefelem_diff(tmp2, tmp);
811
+ // tmp2[i] < 2^118 + 2^120 < 2^121
812
+ p224_felem_reduce(y_out, tmp2);
813
+
814
+ // the result (x_out, y_out, z_out) is incorrect if one of the inputs is
815
+ // the point at infinity, so we need to check for this separately
816
+
817
+ // if point 1 is at infinity, copy point 2 to output, and vice versa
818
+ p224_copy_conditional(x_out, x2, z1_is_zero);
819
+ p224_copy_conditional(x_out, x1, z2_is_zero);
820
+ p224_copy_conditional(y_out, y2, z1_is_zero);
821
+ p224_copy_conditional(y_out, y1, z2_is_zero);
822
+ p224_copy_conditional(z_out, z2, z1_is_zero);
823
+ p224_copy_conditional(z_out, z1, z2_is_zero);
824
+ p224_felem_assign(x3, x_out);
825
+ p224_felem_assign(y3, y_out);
826
+ p224_felem_assign(z3, z_out);
827
+ }
828
+
829
+ // p224_select_point selects the |idx|th point from a precomputation table and
830
+ // copies it to out.
831
+ static void p224_select_point(const uint64_t idx, size_t size,
832
+ const p224_felem pre_comp[/*size*/][3],
833
+ p224_felem out[3]) {
834
+ p224_limb *outlimbs = &out[0][0];
835
+ OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem));
836
+
837
+ for (size_t i = 0; i < size; i++) {
838
+ const p224_limb *inlimbs = &pre_comp[i][0][0];
839
+ uint64_t mask = i ^ idx;
840
+ mask |= mask >> 4;
841
+ mask |= mask >> 2;
842
+ mask |= mask >> 1;
843
+ mask &= 1;
844
+ mask--;
845
+ for (size_t j = 0; j < 4 * 3; j++) {
846
+ outlimbs[j] |= inlimbs[j] & mask;
847
+ }
848
+ }
849
+ }
850
+
851
+ // p224_get_bit returns the |i|th bit in |in|.
852
+ static crypto_word_t p224_get_bit(const EC_SCALAR *in, size_t i) {
853
+ if (i >= 224) {
854
+ return 0;
855
+ }
856
+ static_assert(sizeof(in->words[0]) == 8, "BN_ULONG is not 64-bit");
857
+ return (in->words[i >> 6] >> (i & 63)) & 1;
858
+ }
859
+
860
+ // Takes the Jacobian coordinates (X, Y, Z) of a point and returns
861
+ // (X', Y') = (X/Z^2, Y/Z^3)
862
+ static int ec_GFp_nistp224_point_get_affine_coordinates(
863
+ const EC_GROUP *group, const EC_RAW_POINT *point, EC_FELEM *x,
864
+ EC_FELEM *y) {
865
+ if (ec_GFp_simple_is_at_infinity(group, point)) {
866
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
867
+ return 0;
868
+ }
869
+
870
+ p224_felem z1, z2;
871
+ p224_widefelem tmp;
872
+ p224_generic_to_felem(z1, &point->Z);
873
+ p224_felem_inv(z2, z1);
874
+ p224_felem_square(tmp, z2);
875
+ p224_felem_reduce(z1, tmp);
876
+
877
+ if (x != NULL) {
878
+ p224_felem x_in, x_out;
879
+ p224_generic_to_felem(x_in, &point->X);
880
+ p224_felem_mul(tmp, x_in, z1);
881
+ p224_felem_reduce(x_out, tmp);
882
+ p224_felem_to_generic(x, x_out);
883
+ }
884
+
885
+ if (y != NULL) {
886
+ p224_felem y_in, y_out;
887
+ p224_generic_to_felem(y_in, &point->Y);
888
+ p224_felem_mul(tmp, z1, z2);
889
+ p224_felem_reduce(z1, tmp);
890
+ p224_felem_mul(tmp, y_in, z1);
891
+ p224_felem_reduce(y_out, tmp);
892
+ p224_felem_to_generic(y, y_out);
893
+ }
894
+
895
+ return 1;
896
+ }
897
+
898
+ static void ec_GFp_nistp224_add(const EC_GROUP *group, EC_RAW_POINT *r,
899
+ const EC_RAW_POINT *a, const EC_RAW_POINT *b) {
900
+ p224_felem x1, y1, z1, x2, y2, z2;
901
+ p224_generic_to_felem(x1, &a->X);
902
+ p224_generic_to_felem(y1, &a->Y);
903
+ p224_generic_to_felem(z1, &a->Z);
904
+ p224_generic_to_felem(x2, &b->X);
905
+ p224_generic_to_felem(y2, &b->Y);
906
+ p224_generic_to_felem(z2, &b->Z);
907
+ p224_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, z2);
908
+ // The outputs are already reduced, but still need to be contracted.
909
+ p224_felem_to_generic(&r->X, x1);
910
+ p224_felem_to_generic(&r->Y, y1);
911
+ p224_felem_to_generic(&r->Z, z1);
912
+ }
913
+
914
+ static void ec_GFp_nistp224_dbl(const EC_GROUP *group, EC_RAW_POINT *r,
915
+ const EC_RAW_POINT *a) {
916
+ p224_felem x, y, z;
917
+ p224_generic_to_felem(x, &a->X);
918
+ p224_generic_to_felem(y, &a->Y);
919
+ p224_generic_to_felem(z, &a->Z);
920
+ p224_point_double(x, y, z, x, y, z);
921
+ // The outputs are already reduced, but still need to be contracted.
922
+ p224_felem_to_generic(&r->X, x);
923
+ p224_felem_to_generic(&r->Y, y);
924
+ p224_felem_to_generic(&r->Z, z);
925
+ }
926
+
927
+ static void ec_GFp_nistp224_make_precomp(p224_felem out[17][3],
928
+ const EC_RAW_POINT *p) {
929
+ OPENSSL_memset(out[0], 0, sizeof(p224_felem) * 3);
930
+
931
+ p224_generic_to_felem(out[1][0], &p->X);
932
+ p224_generic_to_felem(out[1][1], &p->Y);
933
+ p224_generic_to_felem(out[1][2], &p->Z);
934
+
935
+ for (size_t j = 2; j <= 16; ++j) {
936
+ if (j & 1) {
937
+ p224_point_add(out[j][0], out[j][1], out[j][2], out[1][0], out[1][1],
938
+ out[1][2], 0, out[j - 1][0], out[j - 1][1], out[j - 1][2]);
939
+ } else {
940
+ p224_point_double(out[j][0], out[j][1], out[j][2], out[j / 2][0],
941
+ out[j / 2][1], out[j / 2][2]);
942
+ }
943
+ }
944
+ }
945
+
946
+ static void ec_GFp_nistp224_point_mul(const EC_GROUP *group, EC_RAW_POINT *r,
947
+ const EC_RAW_POINT *p,
948
+ const EC_SCALAR *scalar) {
949
+ p224_felem p_pre_comp[17][3];
950
+ ec_GFp_nistp224_make_precomp(p_pre_comp, p);
951
+
952
+ // Set nq to the point at infinity.
953
+ p224_felem nq[3], tmp[4];
954
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
955
+
956
+ int skip = 1; // Save two point operations in the first round.
957
+ for (size_t i = 220; i < 221; i--) {
958
+ if (!skip) {
959
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
960
+ }
961
+
962
+ // Add every 5 doublings.
963
+ if (i % 5 == 0) {
964
+ crypto_word_t bits = p224_get_bit(scalar, i + 4) << 5;
965
+ bits |= p224_get_bit(scalar, i + 3) << 4;
966
+ bits |= p224_get_bit(scalar, i + 2) << 3;
967
+ bits |= p224_get_bit(scalar, i + 1) << 2;
968
+ bits |= p224_get_bit(scalar, i) << 1;
969
+ bits |= p224_get_bit(scalar, i - 1);
970
+ crypto_word_t sign, digit;
971
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
972
+
973
+ // Select the point to add or subtract.
974
+ p224_select_point(digit, 17, (const p224_felem(*)[3])p_pre_comp, tmp);
975
+ p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point
976
+ p224_copy_conditional(tmp[1], tmp[3], sign);
977
+
978
+ if (!skip) {
979
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
980
+ tmp[0], tmp[1], tmp[2]);
981
+ } else {
982
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
983
+ skip = 0;
984
+ }
985
+ }
986
+ }
987
+
988
+ // Reduce the output to its unique minimal representation.
989
+ p224_felem_to_generic(&r->X, nq[0]);
990
+ p224_felem_to_generic(&r->Y, nq[1]);
991
+ p224_felem_to_generic(&r->Z, nq[2]);
992
+ }
993
+
994
+ static void ec_GFp_nistp224_point_mul_base(const EC_GROUP *group,
995
+ EC_RAW_POINT *r,
996
+ const EC_SCALAR *scalar) {
997
+ // Set nq to the point at infinity.
998
+ p224_felem nq[3], tmp[3];
999
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
1000
+
1001
+ int skip = 1; // Save two point operations in the first round.
1002
+ for (size_t i = 27; i < 28; i--) {
1003
+ // double
1004
+ if (!skip) {
1005
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1006
+ }
1007
+
1008
+ // First, look 28 bits upwards.
1009
+ crypto_word_t bits = p224_get_bit(scalar, i + 196) << 3;
1010
+ bits |= p224_get_bit(scalar, i + 140) << 2;
1011
+ bits |= p224_get_bit(scalar, i + 84) << 1;
1012
+ bits |= p224_get_bit(scalar, i + 28);
1013
+ // Select the point to add, in constant time.
1014
+ p224_select_point(bits, 16, g_p224_pre_comp[1], tmp);
1015
+
1016
+ if (!skip) {
1017
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1018
+ tmp[0], tmp[1], tmp[2]);
1019
+ } else {
1020
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
1021
+ skip = 0;
1022
+ }
1023
+
1024
+ // Second, look at the current position/
1025
+ bits = p224_get_bit(scalar, i + 168) << 3;
1026
+ bits |= p224_get_bit(scalar, i + 112) << 2;
1027
+ bits |= p224_get_bit(scalar, i + 56) << 1;
1028
+ bits |= p224_get_bit(scalar, i);
1029
+ // Select the point to add, in constant time.
1030
+ p224_select_point(bits, 16, g_p224_pre_comp[0], tmp);
1031
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1032
+ tmp[0], tmp[1], tmp[2]);
1033
+ }
1034
+
1035
+ // Reduce the output to its unique minimal representation.
1036
+ p224_felem_to_generic(&r->X, nq[0]);
1037
+ p224_felem_to_generic(&r->Y, nq[1]);
1038
+ p224_felem_to_generic(&r->Z, nq[2]);
1039
+ }
1040
+
1041
+ static void ec_GFp_nistp224_point_mul_public(const EC_GROUP *group,
1042
+ EC_RAW_POINT *r,
1043
+ const EC_SCALAR *g_scalar,
1044
+ const EC_RAW_POINT *p,
1045
+ const EC_SCALAR *p_scalar) {
1046
+ // TODO(davidben): If P-224 ECDSA verify performance ever matters, using
1047
+ // |ec_compute_wNAF| for |p_scalar| would likely be an easy improvement.
1048
+ p224_felem p_pre_comp[17][3];
1049
+ ec_GFp_nistp224_make_precomp(p_pre_comp, p);
1050
+
1051
+ // Set nq to the point at infinity.
1052
+ p224_felem nq[3], tmp[3];
1053
+ OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem));
1054
+
1055
+ // Loop over both scalars msb-to-lsb, interleaving additions of multiples of
1056
+ // the generator (two in each of the last 28 rounds) and additions of p (every
1057
+ // 5th round).
1058
+ int skip = 1; // Save two point operations in the first round.
1059
+ for (size_t i = 220; i < 221; i--) {
1060
+ if (!skip) {
1061
+ p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
1062
+ }
1063
+
1064
+ // Add multiples of the generator.
1065
+ if (i <= 27) {
1066
+ // First, look 28 bits upwards.
1067
+ crypto_word_t bits = p224_get_bit(g_scalar, i + 196) << 3;
1068
+ bits |= p224_get_bit(g_scalar, i + 140) << 2;
1069
+ bits |= p224_get_bit(g_scalar, i + 84) << 1;
1070
+ bits |= p224_get_bit(g_scalar, i + 28);
1071
+
1072
+ size_t index = (size_t)bits;
1073
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1074
+ g_p224_pre_comp[1][index][0], g_p224_pre_comp[1][index][1],
1075
+ g_p224_pre_comp[1][index][2]);
1076
+ assert(!skip);
1077
+
1078
+ // Second, look at the current position.
1079
+ bits = p224_get_bit(g_scalar, i + 168) << 3;
1080
+ bits |= p224_get_bit(g_scalar, i + 112) << 2;
1081
+ bits |= p224_get_bit(g_scalar, i + 56) << 1;
1082
+ bits |= p224_get_bit(g_scalar, i);
1083
+ index = (size_t)bits;
1084
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */,
1085
+ g_p224_pre_comp[0][index][0], g_p224_pre_comp[0][index][1],
1086
+ g_p224_pre_comp[0][index][2]);
1087
+ }
1088
+
1089
+ // Incorporate |p_scalar| every 5 doublings.
1090
+ if (i % 5 == 0) {
1091
+ crypto_word_t bits = p224_get_bit(p_scalar, i + 4) << 5;
1092
+ bits |= p224_get_bit(p_scalar, i + 3) << 4;
1093
+ bits |= p224_get_bit(p_scalar, i + 2) << 3;
1094
+ bits |= p224_get_bit(p_scalar, i + 1) << 2;
1095
+ bits |= p224_get_bit(p_scalar, i) << 1;
1096
+ bits |= p224_get_bit(p_scalar, i - 1);
1097
+ crypto_word_t sign, digit;
1098
+ ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
1099
+
1100
+ // Select the point to add or subtract.
1101
+ OPENSSL_memcpy(tmp, p_pre_comp[digit], 3 * sizeof(p224_felem));
1102
+ if (sign) {
1103
+ p224_felem_neg(tmp[1], tmp[1]); // (X, -Y, Z) is the negative point
1104
+ }
1105
+
1106
+ if (!skip) {
1107
+ p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */,
1108
+ tmp[0], tmp[1], tmp[2]);
1109
+ } else {
1110
+ OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem));
1111
+ skip = 0;
1112
+ }
1113
+ }
1114
+ }
1115
+
1116
+ // Reduce the output to its unique minimal representation.
1117
+ p224_felem_to_generic(&r->X, nq[0]);
1118
+ p224_felem_to_generic(&r->Y, nq[1]);
1119
+ p224_felem_to_generic(&r->Z, nq[2]);
1120
+ }
1121
+
1122
+ static void ec_GFp_nistp224_felem_mul(const EC_GROUP *group, EC_FELEM *r,
1123
+ const EC_FELEM *a, const EC_FELEM *b) {
1124
+ p224_felem felem1, felem2;
1125
+ p224_widefelem wide;
1126
+ p224_generic_to_felem(felem1, a);
1127
+ p224_generic_to_felem(felem2, b);
1128
+ p224_felem_mul(wide, felem1, felem2);
1129
+ p224_felem_reduce(felem1, wide);
1130
+ p224_felem_to_generic(r, felem1);
1131
+ }
1132
+
1133
+ static void ec_GFp_nistp224_felem_sqr(const EC_GROUP *group, EC_FELEM *r,
1134
+ const EC_FELEM *a) {
1135
+ p224_felem felem;
1136
+ p224_generic_to_felem(felem, a);
1137
+ p224_widefelem wide;
1138
+ p224_felem_square(wide, felem);
1139
+ p224_felem_reduce(felem, wide);
1140
+ p224_felem_to_generic(r, felem);
1141
+ }
1142
+
1143
+ DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) {
1144
+ out->group_init = ec_GFp_simple_group_init;
1145
+ out->group_finish = ec_GFp_simple_group_finish;
1146
+ out->group_set_curve = ec_GFp_simple_group_set_curve;
1147
+ out->point_get_affine_coordinates =
1148
+ ec_GFp_nistp224_point_get_affine_coordinates;
1149
+ out->add = ec_GFp_nistp224_add;
1150
+ out->dbl = ec_GFp_nistp224_dbl;
1151
+ out->mul = ec_GFp_nistp224_point_mul;
1152
+ out->mul_base = ec_GFp_nistp224_point_mul_base;
1153
+ out->mul_public = ec_GFp_nistp224_point_mul_public;
1154
+ out->felem_mul = ec_GFp_nistp224_felem_mul;
1155
+ out->felem_sqr = ec_GFp_nistp224_felem_sqr;
1156
+ out->felem_to_bytes = ec_GFp_simple_felem_to_bytes;
1157
+ out->felem_from_bytes = ec_GFp_simple_felem_from_bytes;
1158
+ out->scalar_inv0_montgomery = ec_simple_scalar_inv0_montgomery;
1159
+ out->scalar_to_montgomery_inv_vartime =
1160
+ ec_simple_scalar_to_montgomery_inv_vartime;
1161
+ out->cmp_x_coordinate = ec_GFp_simple_cmp_x_coordinate;
1162
+ }
1163
+
1164
+ #endif // BORINGSSL_HAS_UINT128 && !SMALL