grpc 1.84.0 → 1.85.0.pre1

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 (1004) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +40 -27
  3. data/include/grpc/event_engine/memory_allocator.h +1 -0
  4. data/include/grpc/grpc.h +3 -0
  5. data/include/grpc/grpc_security_constants.h +2 -0
  6. data/include/grpc/impl/channel_arg_names.h +4 -0
  7. data/src/core/call/call_filters.h +10 -10
  8. data/src/core/{lib/security/authorization → call}/evaluate_args.cc +22 -1
  9. data/src/core/{lib/security/authorization → call}/evaluate_args.h +19 -5
  10. data/src/core/call/filter_fusion.h +15 -15
  11. data/src/core/call/interception_chain.h +3 -3
  12. data/src/core/call/metadata_batch.cc +1 -0
  13. data/src/core/call/metadata_batch.h +45 -33
  14. data/src/core/call/parsed_metadata.h +3 -3
  15. data/src/core/call/request_buffer.cc +6 -6
  16. data/src/core/call/request_buffer.h +1 -1
  17. data/src/core/channelz/channel_trace.cc +5 -5
  18. data/src/core/channelz/channel_trace.h +1 -1
  19. data/src/core/channelz/channelz.cc +9 -9
  20. data/src/core/channelz/channelz.h +12 -12
  21. data/src/core/channelz/channelz_registry.cc +10 -10
  22. data/src/core/channelz/ztrace_collector.h +5 -5
  23. data/src/core/client_channel/client_channel.cc +4 -4
  24. data/src/core/client_channel/client_channel_filter.cc +14 -14
  25. data/src/core/client_channel/global_subchannel_pool.cc +4 -4
  26. data/src/core/client_channel/subchannel.cc +24 -23
  27. data/src/core/client_channel/subchannel_stream_client.cc +5 -5
  28. data/src/core/credentials/call/external/aws_external_account_credentials.cc +7 -7
  29. data/src/core/credentials/call/external/aws_request_signer.cc +16 -0
  30. data/src/core/credentials/call/external/external_account_credentials.cc +4 -4
  31. data/src/core/credentials/call/regional_access_boundary_fetcher.cc +9 -9
  32. data/src/core/credentials/call/token_fetcher/token_fetcher_credentials.cc +4 -4
  33. data/src/core/credentials/transport/google_default/google_default_credentials.cc +3 -3
  34. data/src/core/credentials/transport/ssl/ssl_security_connector.cc +1 -1
  35. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.cc +9 -9
  36. data/src/core/credentials/transport/tls/grpc_tls_certificate_distributor.h +1 -1
  37. data/src/core/credentials/transport/tls/grpc_tls_certificate_provider.cc +6 -6
  38. data/src/core/credentials/transport/tls/grpc_tls_certificate_verifier.cc +3 -3
  39. data/src/core/credentials/transport/tls/grpc_tls_crl_provider.cc +4 -4
  40. data/src/core/credentials/transport/tls/ssl_utils.cc +10 -0
  41. data/src/core/credentials/transport/tls/tls_security_connector.cc +10 -10
  42. data/src/core/credentials/transport/tls/tls_security_connector.h +6 -6
  43. data/src/core/credentials/transport/tls/tls_utils.h +9 -0
  44. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +1 -1
  45. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -1
  46. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.cc +2 -2
  47. data/src/core/ext/filters/gcp_authentication/gcp_authentication_filter.h +1 -1
  48. data/src/core/ext/filters/http/message_compress/compression_filter.cc +15 -0
  49. data/src/core/ext/filters/rbac/rbac_filter.h +1 -1
  50. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +5 -5
  51. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +30 -21
  52. data/src/core/ext/transport/chttp2/server/chttp2_server.h +5 -11
  53. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +14 -11
  54. data/src/core/ext/transport/chttp2/transport/flow_control.cc +1 -0
  55. data/src/core/ext/transport/chttp2/transport/flow_control.h +0 -4
  56. data/src/core/ext/transport/chttp2/transport/frame.h +9 -0
  57. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +12 -9
  58. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +4 -2
  59. data/src/core/ext/transport/chttp2/transport/http2_client_transport.cc +16 -18
  60. data/src/core/ext/transport/chttp2/transport/http2_client_transport.h +2 -1
  61. data/src/core/ext/transport/chttp2/transport/http2_server_transport.cc +277 -189
  62. data/src/core/ext/transport/chttp2/transport/http2_server_transport.h +40 -17
  63. data/src/core/ext/transport/chttp2/transport/http2_transport.cc +12 -24
  64. data/src/core/ext/transport/chttp2/transport/http2_transport.h +3 -29
  65. data/src/core/ext/transport/chttp2/transport/internal.h +2 -2
  66. data/src/core/ext/transport/chttp2/transport/parsing.cc +3 -2
  67. data/src/core/ext/transport/chttp2/transport/read_context.h +96 -3
  68. data/src/core/ext/transport/chttp2/transport/reclaimer.cc +32 -0
  69. data/src/core/ext/transport/chttp2/transport/reclaimer.h +64 -0
  70. data/src/core/ext/transport/chttp2/transport/security_frame.h +8 -8
  71. data/src/core/ext/transport/chttp2/transport/stream_data_queue.h +17 -9
  72. data/src/core/ext/transport/chttp2/transport/write_cycle.h +23 -3
  73. data/src/core/ext/transport/inproc/inproc_transport.cc +5 -5
  74. data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb.h +137 -73
  75. data/src/core/ext/upb-gen/grpc/channelz/v1/channelz.upb_minitable.c +45 -25
  76. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb.h +6 -6
  77. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.c +4 -4
  78. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/altscontext.upb_minitable.h +5 -5
  79. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb.h +46 -26
  80. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.c +17 -14
  81. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/handshaker.upb_minitable.h +5 -5
  82. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb.h +5 -5
  83. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.c +3 -3
  84. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/gcp/transport_security_common.upb_minitable.h +5 -5
  85. data/src/core/ext/upb-gen/grpc/health/v1/health.upb.h +329 -0
  86. data/src/core/ext/upb-gen/grpc/health/v1/health.upb_minitable.c +128 -0
  87. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/health/v1/health.upb_minitable.h +8 -5
  88. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb.h +5 -5
  89. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.c +3 -3
  90. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lb/v1/load_balancer.upb_minitable.h +5 -5
  91. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb.h +185 -23
  92. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.c +20 -12
  93. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls.upb_minitable.h +5 -5
  94. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb.h +58 -42
  95. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.c +17 -12
  96. data/src/core/ext/upb-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upb_minitable.h +5 -5
  97. data/src/core/ext/upbdefs-gen/grpc/channelz/v1/channelz.upbdefs.c +567 -549
  98. data/src/core/ext/upbdefs-gen/grpc/lookup/v1/rls_config.upbdefs.c +182 -0
  99. data/src/core/ext/upbdefs-gen/{src/proto/grpc → grpc}/lookup/v1/rls_config.upbdefs.h +14 -14
  100. data/src/core/filter/ext_proc/ext_proc_filter.cc +1603 -46
  101. data/src/core/filter/ext_proc/ext_proc_filter.h +55 -22
  102. data/src/core/filter/ext_proc/ext_proc_messages.cc +106 -51
  103. data/src/core/filter/ext_proc/ext_proc_messages.h +36 -9
  104. data/src/core/handshaker/handshaker.cc +4 -4
  105. data/src/core/handshaker/http_connect/http_connect_client_handshaker.cc +3 -3
  106. data/src/core/handshaker/security/pipelined_secure_endpoint.cc +10 -10
  107. data/src/core/handshaker/security/secure_endpoint.cc +13 -13
  108. data/src/core/handshaker/security/security_handshaker.cc +6 -6
  109. data/src/core/handshaker/tcp_connect/tcp_connect_handshaker.cc +4 -4
  110. data/src/core/lib/channel/channel_args.cc +20 -0
  111. data/src/core/lib/channel/channel_args.h +17 -17
  112. data/src/core/lib/channel/promise_based_filter.cc +2 -2
  113. data/src/core/lib/channel/promise_based_filter.h +66 -27
  114. data/src/core/lib/debug/trace_flags.cc +2 -0
  115. data/src/core/lib/debug/trace_flags.h +1 -0
  116. data/src/core/lib/event_engine/ares_resolver.cc +14 -14
  117. data/src/core/lib/event_engine/cf_engine/cf_engine.cc +7 -7
  118. data/src/core/lib/event_engine/cf_engine/cfsocket_listener.cc +4 -4
  119. data/src/core/lib/event_engine/default_event_engine.cc +5 -5
  120. data/src/core/lib/event_engine/posix_engine/ev_epoll1_linux.cc +9 -9
  121. data/src/core/lib/event_engine/posix_engine/ev_poll_posix.cc +16 -14
  122. data/src/core/lib/event_engine/posix_engine/file_descriptor_collection.cc +6 -6
  123. data/src/core/lib/event_engine/posix_engine/grpc_polled_fd_posix.h +3 -3
  124. data/src/core/lib/event_engine/posix_engine/posix_endpoint.cc +1 -1
  125. data/src/core/lib/event_engine/posix_engine/posix_endpoint.h +7 -7
  126. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +17 -17
  127. data/src/core/lib/event_engine/posix_engine/posix_engine_listener.cc +3 -3
  128. data/src/core/lib/event_engine/posix_engine/timer.cc +5 -5
  129. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +5 -5
  130. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.cc +3 -3
  131. data/src/core/lib/event_engine/posix_engine/traced_buffer_list.h +1 -1
  132. data/src/core/lib/event_engine/thread_pool/thread_count.cc +1 -1
  133. data/src/core/lib/event_engine/thread_pool/thread_count.h +3 -3
  134. data/src/core/lib/event_engine/thread_pool/work_stealing_thread_pool.cc +50 -21
  135. data/src/core/lib/event_engine/thready_event_engine/thready_event_engine.cc +3 -3
  136. data/src/core/lib/event_engine/windows/grpc_polled_fd_windows.cc +3 -3
  137. data/src/core/lib/event_engine/windows/windows_engine.cc +15 -15
  138. data/src/core/lib/event_engine/windows/windows_listener.cc +6 -6
  139. data/src/core/lib/event_engine/work_queue/basic_work_queue.cc +6 -6
  140. data/src/core/lib/experiments/experiments.cc +48 -0
  141. data/src/core/lib/experiments/experiments.h +24 -0
  142. data/src/core/lib/iomgr/buffer_list.cc +3 -3
  143. data/src/core/lib/iomgr/buffer_list.h +1 -1
  144. data/src/core/lib/iomgr/combiner.cc +0 -1
  145. data/src/core/lib/iomgr/ev_apple.cc +4 -4
  146. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +2 -2
  147. data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
  148. data/src/core/lib/iomgr/tcp_posix.cc +7 -7
  149. data/src/core/lib/promise/activity.cc +1 -1
  150. data/src/core/lib/promise/activity.h +1 -1
  151. data/src/core/lib/promise/arena_promise.h +7 -7
  152. data/src/core/lib/promise/detail/promise_factory.h +8 -8
  153. data/src/core/lib/promise/detail/promise_like.h +4 -4
  154. data/src/core/lib/promise/inter_activity_latch.h +6 -6
  155. data/src/core/lib/promise/inter_activity_pipe.h +1 -1
  156. data/src/core/lib/promise/observable.h +3 -3
  157. data/src/core/lib/promise/party.cc +1 -1
  158. data/src/core/lib/promise/try_seq.h +2 -2
  159. data/src/core/lib/resource_quota/arena.h +3 -3
  160. data/src/core/lib/resource_quota/memory_quota.cc +16 -16
  161. data/src/core/lib/resource_quota/memory_quota.h +1 -1
  162. data/src/core/lib/resource_quota/thread_quota.cc +3 -3
  163. data/src/core/lib/security/authorization/audit_logging.cc +5 -5
  164. data/src/core/lib/security/authorization/authorization_engine.h +1 -1
  165. data/src/core/lib/security/authorization/grpc_authorization_engine.h +1 -1
  166. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +1 -1
  167. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +1 -1
  168. data/src/core/lib/security/authorization/matchers.h +1 -1
  169. data/src/core/lib/surface/call.cc +8 -7
  170. data/src/core/lib/surface/call.h +3 -3
  171. data/src/core/lib/surface/call_utils.h +4 -0
  172. data/src/core/lib/surface/channel.cc +1 -1
  173. data/src/core/lib/surface/channel.h +1 -1
  174. data/src/core/lib/surface/channel_init.cc +1 -1
  175. data/src/core/lib/surface/init.cc +7 -7
  176. data/src/core/lib/surface/lame_client.cc +1 -1
  177. data/src/core/lib/surface/legacy_channel.cc +2 -2
  178. data/src/core/lib/surface/version.cc +1 -1
  179. data/src/core/lib/transport/transport_framing_endpoint_extension.h +3 -3
  180. data/src/core/load_balancing/autosharding/autosharding.cc +931 -0
  181. data/src/core/load_balancing/autosharding/autosharding.h +78 -0
  182. data/src/core/load_balancing/grpclb/grpclb_client_stats.cc +2 -2
  183. data/src/core/load_balancing/grpclb/load_balancer_api.cc +1 -1
  184. data/src/core/load_balancing/grpclb/load_balancer_api.h +3 -1
  185. data/src/core/load_balancing/health_check_client.cc +7 -7
  186. data/src/core/load_balancing/lb_policy.cc +1 -1
  187. data/src/core/load_balancing/oob_backend_metric.cc +5 -5
  188. data/src/core/load_balancing/outlier_detection/outlier_detection.cc +2 -2
  189. data/src/core/load_balancing/ring_hash/ring_hash.cc +109 -37
  190. data/src/core/load_balancing/rls/rls.cc +23 -17
  191. data/src/core/load_balancing/weighted_round_robin/weighted_round_robin.cc +10 -10
  192. data/src/core/load_balancing/xds/cds.cc +6 -5
  193. data/src/core/load_balancing/xds/xds_cluster_impl.cc +2 -2
  194. data/src/core/load_balancing/xds/xds_override_host.cc +10 -10
  195. data/src/core/mitigation_engine/mitigation_engine.h +28 -4
  196. data/src/core/plugin_registry/grpc_plugin_registry.cc +2 -0
  197. data/src/core/resolver/dns/dns_resolver.cc +7 -7
  198. data/src/core/resolver/fake/fake_resolver.cc +5 -5
  199. data/src/core/resolver/google_c2p/google_c2p_resolver.cc +38 -30
  200. data/src/core/server/server.cc +30 -30
  201. data/src/core/server/server.h +4 -3
  202. data/src/core/server/server_config_selector_filter.cc +3 -3
  203. data/src/core/server/xds_server_config_fetcher_legacy.cc +15 -15
  204. data/src/core/telemetry/default_tcp_tracer.cc +1 -1
  205. data/src/core/telemetry/instrument.cc +30 -16
  206. data/src/core/telemetry/instrument.h +3 -3
  207. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
  208. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +4 -4
  209. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h +2 -2
  210. data/src/core/tsi/alts/handshaker/alts_tsi_utils.h +1 -1
  211. data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
  212. data/src/core/tsi/ssl/key_logging/ssl_key_logging.cc +5 -5
  213. data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +3 -3
  214. data/src/core/tsi/ssl_transport_security.cc +46 -13
  215. data/src/core/tsi/ssl_transport_security.h +7 -0
  216. data/src/core/tsi/ssl_transport_security_utils.cc +16 -6
  217. data/src/core/util/event_log.cc +3 -3
  218. data/src/core/util/http_client/httpcli.cc +5 -5
  219. data/src/core/util/http_client/httpcli.h +1 -1
  220. data/src/core/util/json/json_object_loader.cc +7 -0
  221. data/src/core/util/json/json_object_loader.h +17 -2
  222. data/src/core/util/latent_see.cc +123 -36
  223. data/src/core/util/latent_see.h +14 -1
  224. data/src/core/util/mpscq.cc +1 -1
  225. data/src/core/util/notification.h +4 -4
  226. data/src/core/util/sync.h +20 -6
  227. data/src/core/util/table.h +20 -22
  228. data/src/core/util/work_serializer.cc +2 -2
  229. data/src/core/xds/grpc/blackboard.cc +4 -3
  230. data/src/core/xds/grpc/certificate_provider_store.cc +2 -2
  231. data/src/core/xds/grpc/streaming_call_promise_wrapper.cc +181 -0
  232. data/src/core/xds/grpc/streaming_call_promise_wrapper.h +213 -0
  233. data/src/core/xds/grpc/xds_bootstrap_grpc_builder.cc +2 -2
  234. data/src/core/xds/grpc/xds_client_grpc.cc +8 -8
  235. data/src/core/xds/grpc/xds_cluster_specifier_plugin.cc +2 -2
  236. data/src/core/xds/grpc/xds_endpoint.cc +1 -1
  237. data/src/core/xds/grpc/xds_endpoint_parser.cc +11 -0
  238. data/src/core/xds/grpc/xds_grpc_service_parser.cc +12 -10
  239. data/src/core/xds/grpc/xds_http_ext_proc_filter.cc +17 -14
  240. data/src/core/xds/grpc/xds_matcher.h +2 -2
  241. data/src/core/xds/grpc/xds_transport_grpc.cc +125 -85
  242. data/src/core/xds/grpc/xds_transport_grpc.h +19 -4
  243. data/src/core/xds/xds_client/lrs_client.cc +22 -19
  244. data/src/core/xds/xds_client/xds_client.cc +19 -16
  245. data/src/core/xds/xds_client/xds_transport.h +49 -3
  246. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -0
  247. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -0
  248. data/src/ruby/lib/grpc/version.rb +1 -1
  249. data/src/ruby/pb/README.md +1 -1
  250. data/src/ruby/pb/generate_proto_ruby.sh +1 -1
  251. data/third_party/abseil-cpp/absl/algorithm/algorithm.h +34 -2
  252. data/third_party/abseil-cpp/absl/algorithm/container.h +345 -147
  253. data/third_party/abseil-cpp/absl/base/attributes.h +67 -44
  254. data/third_party/abseil-cpp/absl/base/call_once.h +1 -0
  255. data/third_party/abseil-cpp/absl/base/casts.cc +61 -0
  256. data/third_party/abseil-cpp/absl/base/casts.h +135 -2
  257. data/third_party/abseil-cpp/absl/base/config.h +63 -41
  258. data/third_party/abseil-cpp/absl/base/fast_type_id.h +30 -2
  259. data/third_party/abseil-cpp/absl/base/internal/dynamic_annotations.h +1 -1
  260. data/third_party/abseil-cpp/absl/base/internal/hardening.h +136 -0
  261. data/third_party/abseil-cpp/absl/base/internal/iterator_traits.h +6 -2
  262. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc +39 -4
  263. data/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h +6 -0
  264. data/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h +77 -15
  265. data/third_party/abseil-cpp/absl/base/internal/raw_logging.cc +3 -4
  266. data/third_party/abseil-cpp/absl/base/internal/spinlock.cc +26 -24
  267. data/third_party/abseil-cpp/absl/base/internal/spinlock.h +74 -29
  268. data/third_party/abseil-cpp/absl/base/internal/sysinfo.cc +1 -11
  269. data/third_party/abseil-cpp/absl/base/internal/thread_identity.h +52 -0
  270. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc +5 -1
  271. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h +5 -0
  272. data/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock_config.h +1 -1
  273. data/third_party/abseil-cpp/absl/base/macros.h +76 -37
  274. data/third_party/abseil-cpp/absl/base/nullability.h +5 -5
  275. data/third_party/abseil-cpp/absl/base/optimization.h +4 -5
  276. data/third_party/abseil-cpp/absl/base/options.h +46 -18
  277. data/third_party/abseil-cpp/absl/base/policy_checks.h +5 -5
  278. data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.cc → throw_delegate.cc} +9 -7
  279. data/third_party/abseil-cpp/absl/base/{internal/throw_delegate.h → throw_delegate.h} +4 -14
  280. data/third_party/abseil-cpp/absl/cleanup/cleanup.h +7 -2
  281. data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +3 -2
  282. data/third_party/abseil-cpp/absl/container/btree_map.h +60 -10
  283. data/third_party/abseil-cpp/absl/container/btree_set.h +61 -15
  284. data/third_party/abseil-cpp/absl/container/fixed_array.h +19 -21
  285. data/third_party/abseil-cpp/absl/container/flat_hash_map.h +49 -27
  286. data/third_party/abseil-cpp/absl/container/flat_hash_set.h +50 -26
  287. data/third_party/abseil-cpp/absl/container/inlined_vector.h +42 -36
  288. data/third_party/abseil-cpp/absl/container/internal/btree.h +32 -24
  289. data/third_party/abseil-cpp/absl/container/internal/btree_container.h +30 -22
  290. data/third_party/abseil-cpp/absl/container/internal/common.h +57 -5
  291. data/third_party/abseil-cpp/absl/container/internal/common_policy_traits.h +1 -1
  292. data/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h +40 -36
  293. data/third_party/abseil-cpp/absl/container/internal/container_memory.h +119 -39
  294. data/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h +14 -2
  295. data/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h +14 -22
  296. data/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h +52 -52
  297. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.cc +7 -7
  298. data/third_party/abseil-cpp/absl/container/internal/hashtablez_sampler.h +7 -7
  299. data/third_party/abseil-cpp/absl/container/internal/inlined_vector.h +32 -40
  300. data/third_party/abseil-cpp/absl/container/internal/layout.h +13 -13
  301. data/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h +95 -72
  302. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc +633 -365
  303. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h +1016 -749
  304. data/third_party/abseil-cpp/absl/container/internal/raw_hash_set_resize_impl.h +0 -1
  305. data/third_party/abseil-cpp/absl/container/node_hash_map.h +58 -35
  306. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc +23 -6
  307. data/third_party/abseil-cpp/absl/crc/internal/cpu_detect.h +7 -1
  308. data/third_party/abseil-cpp/absl/crc/internal/crc.cc +4 -6
  309. data/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h +41 -0
  310. data/third_party/abseil-cpp/absl/crc/internal/crc_internal.h +0 -16
  311. data/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc +5 -0
  312. data/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc +304 -188
  313. data/third_party/abseil-cpp/absl/crc/internal/non_temporal_arm_intrinsics.h +4 -2
  314. data/third_party/abseil-cpp/absl/debugging/internal/demangle.cc +2 -2
  315. data/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.h +8 -0
  316. data/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h +4 -4
  317. data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc +15 -1
  318. data/third_party/abseil-cpp/absl/debugging/internal/examine_stack.h +7 -1
  319. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc +12 -1
  320. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h +6 -5
  321. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_emscripten-inl.inc +13 -11
  322. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_generic-inl.inc +14 -7
  323. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_powerpc-inl.inc +3 -2
  324. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc +6 -1
  325. data/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc +14 -8
  326. data/third_party/abseil-cpp/absl/debugging/internal/symbolize.h +48 -38
  327. data/third_party/abseil-cpp/absl/debugging/internal/vdso_support.cc +4 -0
  328. data/third_party/abseil-cpp/absl/debugging/stacktrace.cc +63 -118
  329. data/third_party/abseil-cpp/absl/debugging/stacktrace.h +7 -47
  330. data/third_party/abseil-cpp/absl/debugging/symbolize.cc +20 -2
  331. data/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc +83 -149
  332. data/third_party/abseil-cpp/absl/debugging/symbolize_emscripten.inc +4 -17
  333. data/third_party/abseil-cpp/absl/debugging/symbolize_unimplemented.inc +4 -4
  334. data/third_party/abseil-cpp/absl/debugging/symbolize_win32.inc +2 -4
  335. data/third_party/abseil-cpp/absl/flags/commandlineflag.h +8 -6
  336. data/third_party/abseil-cpp/absl/flags/declare.h +9 -0
  337. data/third_party/abseil-cpp/absl/flags/flag.h +2 -1
  338. data/third_party/abseil-cpp/absl/flags/internal/commandlineflag.h +1 -1
  339. data/third_party/abseil-cpp/absl/flags/internal/flag.cc +19 -18
  340. data/third_party/abseil-cpp/absl/flags/internal/flag.h +33 -34
  341. data/third_party/abseil-cpp/absl/flags/internal/program_name.cc +2 -2
  342. data/third_party/abseil-cpp/absl/flags/marshalling.cc +1 -16
  343. data/third_party/abseil-cpp/absl/flags/marshalling.h +2 -28
  344. data/third_party/abseil-cpp/absl/flags/reflection.cc +11 -7
  345. data/third_party/abseil-cpp/absl/flags/usage_config.cc +2 -2
  346. data/third_party/abseil-cpp/absl/functional/any_invocable.h +22 -19
  347. data/third_party/abseil-cpp/absl/functional/bind_front.h +7 -1
  348. data/third_party/abseil-cpp/absl/functional/function_ref.h +125 -20
  349. data/third_party/abseil-cpp/absl/functional/internal/any_invocable.h +43 -31
  350. data/third_party/abseil-cpp/absl/functional/internal/front_binder.h +4 -4
  351. data/third_party/abseil-cpp/absl/functional/internal/function_ref.h +44 -6
  352. data/third_party/abseil-cpp/absl/hash/hash.h +1 -1
  353. data/third_party/abseil-cpp/absl/hash/internal/city.cc +39 -51
  354. data/third_party/abseil-cpp/absl/hash/internal/hash.cc +379 -14
  355. data/third_party/abseil-cpp/absl/hash/internal/hash.h +457 -353
  356. data/third_party/abseil-cpp/absl/log/absl_vlog_is_on.h +0 -2
  357. data/third_party/abseil-cpp/absl/log/internal/check_impl.h +2 -1
  358. data/third_party/abseil-cpp/absl/log/internal/check_op.cc +4 -0
  359. data/third_party/abseil-cpp/absl/log/internal/check_op.h +128 -50
  360. data/third_party/abseil-cpp/absl/log/internal/conditions.h +38 -35
  361. data/third_party/abseil-cpp/absl/log/internal/log_impl.h +108 -110
  362. data/third_party/abseil-cpp/absl/log/internal/log_message.cc +10 -6
  363. data/third_party/abseil-cpp/absl/log/internal/log_message.h +19 -1
  364. data/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc +4 -4
  365. data/third_party/abseil-cpp/absl/log/internal/nullstream.h +1 -1
  366. data/third_party/abseil-cpp/absl/log/internal/proto.cc +13 -0
  367. data/third_party/abseil-cpp/absl/log/internal/strip.h +30 -31
  368. data/third_party/abseil-cpp/absl/log/internal/structured_proto.cc +5 -5
  369. data/third_party/abseil-cpp/absl/log/internal/structured_proto.h +6 -5
  370. data/third_party/abseil-cpp/absl/log/internal/vlog_config.cc +30 -30
  371. data/third_party/abseil-cpp/absl/log/internal/vlog_config.h +0 -1
  372. data/third_party/abseil-cpp/absl/log/log.h +2 -2
  373. data/third_party/abseil-cpp/absl/log/log_entry.cc +263 -0
  374. data/third_party/abseil-cpp/absl/log/log_entry.h +2 -0
  375. data/third_party/abseil-cpp/absl/log/vlog_is_on.h +0 -2
  376. data/third_party/abseil-cpp/absl/memory/memory.h +55 -5
  377. data/third_party/abseil-cpp/absl/meta/type_traits.h +161 -56
  378. data/third_party/abseil-cpp/absl/numeric/int128.h +41 -21
  379. data/third_party/abseil-cpp/absl/numeric/int128_have_intrinsic.inc +16 -22
  380. data/third_party/abseil-cpp/absl/numeric/int128_no_intrinsic.inc +5 -7
  381. data/third_party/abseil-cpp/absl/numeric/internal/bits.h +32 -4
  382. data/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h +9 -9
  383. data/third_party/abseil-cpp/absl/random/beta_distribution.h +2 -2
  384. data/third_party/abseil-cpp/absl/random/bit_gen_ref.h +26 -53
  385. data/third_party/abseil-cpp/absl/random/discrete_distribution.h +1 -1
  386. data/third_party/abseil-cpp/absl/random/distributions.h +17 -17
  387. data/third_party/abseil-cpp/absl/random/exponential_distribution.h +1 -1
  388. data/third_party/abseil-cpp/absl/random/internal/distribution_caller.h +8 -21
  389. data/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc +2 -2
  390. data/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits.h +1 -1
  391. data/third_party/abseil-cpp/absl/random/internal/generate_real.h +1 -1
  392. data/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h +2 -2
  393. data/third_party/abseil-cpp/absl/random/internal/nonsecure_base.h +2 -2
  394. data/third_party/abseil-cpp/absl/random/internal/pcg_engine.h +6 -6
  395. data/third_party/abseil-cpp/absl/random/internal/platform.h +0 -13
  396. data/third_party/abseil-cpp/absl/random/internal/randen_detect.cc +6 -6
  397. data/third_party/abseil-cpp/absl/random/internal/randen_engine.h +2 -2
  398. data/third_party/abseil-cpp/absl/random/internal/salted_seed_seq.h +6 -5
  399. data/third_party/abseil-cpp/absl/random/internal/seed_material.cc +5 -31
  400. data/third_party/abseil-cpp/absl/random/internal/seed_material.h +2 -1
  401. data/third_party/abseil-cpp/absl/random/internal/traits.h +21 -0
  402. data/third_party/abseil-cpp/absl/random/internal/uniform_helper.h +23 -23
  403. data/third_party/abseil-cpp/absl/random/mocking_access.h +74 -0
  404. data/third_party/abseil-cpp/absl/random/uniform_real_distribution.h +1 -1
  405. data/third_party/abseil-cpp/absl/status/internal/status_internal.cc +63 -18
  406. data/third_party/abseil-cpp/absl/status/internal/status_internal.h +30 -4
  407. data/third_party/abseil-cpp/absl/status/internal/statusor_internal.h +225 -63
  408. data/third_party/abseil-cpp/absl/status/status.cc +66 -70
  409. data/third_party/abseil-cpp/absl/status/status.h +254 -23
  410. data/third_party/abseil-cpp/absl/status/status_payload_printer.h +3 -2
  411. data/third_party/abseil-cpp/absl/status/statusor.h +117 -137
  412. data/third_party/abseil-cpp/absl/strings/ascii.h +10 -6
  413. data/third_party/abseil-cpp/absl/strings/cord.cc +41 -17
  414. data/third_party/abseil-cpp/absl/strings/cord.h +26 -17
  415. data/third_party/abseil-cpp/absl/strings/cord_buffer.h +4 -2
  416. data/third_party/abseil-cpp/absl/strings/escaping.cc +305 -125
  417. data/third_party/abseil-cpp/absl/strings/escaping.h +12 -2
  418. data/third_party/abseil-cpp/absl/strings/internal/append_and_overwrite.h +93 -0
  419. data/third_party/abseil-cpp/absl/strings/internal/cord_internal.h +2 -2
  420. data/third_party/abseil-cpp/absl/strings/internal/cordz_handle.cc +6 -6
  421. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc +27 -21
  422. data/third_party/abseil-cpp/absl/strings/internal/cordz_info.h +11 -19
  423. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.cc +6 -0
  424. data/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance.h +1 -0
  425. data/third_party/abseil-cpp/absl/strings/internal/escaping.cc +0 -141
  426. data/third_party/abseil-cpp/absl/strings/internal/escaping.h +2 -24
  427. data/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized.h +31 -36
  428. data/third_party/abseil-cpp/absl/strings/internal/stl_type_traits.h +39 -39
  429. data/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h +14 -22
  430. data/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h +2 -2
  431. data/third_party/abseil-cpp/absl/strings/internal/str_format/checker.h +2 -4
  432. data/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc +921 -231
  433. data/third_party/abseil-cpp/absl/strings/internal/str_join_internal.h +18 -16
  434. data/third_party/abseil-cpp/absl/strings/internal/str_split_internal.h +16 -12
  435. data/third_party/abseil-cpp/absl/strings/internal/stringify_sink.h +12 -0
  436. data/third_party/abseil-cpp/absl/strings/numbers.cc +477 -8
  437. data/third_party/abseil-cpp/absl/strings/numbers.h +29 -12
  438. data/third_party/abseil-cpp/absl/strings/resize_and_overwrite.h +198 -0
  439. data/third_party/abseil-cpp/absl/strings/str_cat.cc +96 -91
  440. data/third_party/abseil-cpp/absl/strings/str_cat.h +53 -13
  441. data/third_party/abseil-cpp/absl/strings/str_split.h +14 -9
  442. data/third_party/abseil-cpp/absl/strings/string_view.h +10 -716
  443. data/third_party/abseil-cpp/absl/strings/substitute.cc +24 -24
  444. data/third_party/abseil-cpp/absl/strings/substitute.h +2 -2
  445. data/third_party/abseil-cpp/absl/synchronization/barrier.cc +1 -1
  446. data/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc +2 -2
  447. data/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc +24 -3
  448. data/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc +30 -33
  449. data/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h +2 -2
  450. data/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.h +5 -0
  451. data/third_party/abseil-cpp/absl/synchronization/mutex.cc +41 -29
  452. data/third_party/abseil-cpp/absl/synchronization/mutex.h +199 -94
  453. data/third_party/abseil-cpp/absl/synchronization/notification.cc +5 -5
  454. data/third_party/abseil-cpp/absl/synchronization/notification.h +1 -1
  455. data/third_party/abseil-cpp/absl/time/clock.cc +29 -30
  456. data/third_party/abseil-cpp/absl/time/clock.h +3 -0
  457. data/third_party/abseil-cpp/absl/time/duration.cc +2 -2
  458. data/third_party/abseil-cpp/absl/time/format.cc +3 -10
  459. data/third_party/abseil-cpp/absl/time/internal/cctz/include/cctz/civil_time_detail.h +12 -0
  460. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc +131 -91
  461. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup.cc +6 -103
  462. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.cc +185 -0
  463. data/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_name_win.h +37 -0
  464. data/third_party/abseil-cpp/absl/time/internal/cctz/src/tzfile.h +10 -15
  465. data/third_party/abseil-cpp/absl/time/time.cc +4 -4
  466. data/third_party/abseil-cpp/absl/time/time.h +14 -13
  467. data/third_party/abseil-cpp/absl/types/compare.h +64 -63
  468. data/third_party/abseil-cpp/absl/types/internal/span.h +6 -6
  469. data/third_party/abseil-cpp/absl/types/optional.h +31 -4
  470. data/third_party/abseil-cpp/absl/types/optional_ref.h +295 -0
  471. data/third_party/{boringssl-with-bazel/crypto/x509/x_val.cc → abseil-cpp/absl/types/source_location.cc} +4 -14
  472. data/third_party/abseil-cpp/absl/types/source_location.h +172 -0
  473. data/third_party/abseil-cpp/absl/types/span.h +67 -38
  474. data/third_party/abseil-cpp/absl/types/variant.h +75 -18
  475. data/third_party/abseil-cpp/absl/utility/utility.h +112 -16
  476. data/third_party/boringssl-with-bazel/crypto/aes/aes.cc +3 -0
  477. data/third_party/boringssl-with-bazel/crypto/armv8_feature_parsing.h +67 -0
  478. data/third_party/boringssl-with-bazel/crypto/asn1/a_bitstr.cc +143 -105
  479. data/third_party/boringssl-with-bazel/crypto/asn1/a_bool.cc +5 -8
  480. data/third_party/boringssl-with-bazel/crypto/asn1/a_d2i_fp.cc +3 -3
  481. data/third_party/boringssl-with-bazel/crypto/asn1/a_dup.cc +6 -6
  482. data/third_party/boringssl-with-bazel/crypto/asn1/a_gentm.cc +33 -12
  483. data/third_party/boringssl-with-bazel/crypto/asn1/a_i2d_fp.cc +7 -6
  484. data/third_party/boringssl-with-bazel/crypto/asn1/a_int.cc +80 -52
  485. data/third_party/boringssl-with-bazel/crypto/asn1/a_mbstr.cc +7 -4
  486. data/third_party/boringssl-with-bazel/crypto/asn1/a_object.cc +70 -72
  487. data/third_party/boringssl-with-bazel/crypto/asn1/a_strex.cc +38 -42
  488. data/third_party/boringssl-with-bazel/crypto/asn1/a_strnid.cc +41 -39
  489. data/third_party/boringssl-with-bazel/crypto/asn1/a_time.cc +59 -35
  490. data/third_party/boringssl-with-bazel/crypto/asn1/a_type.cc +275 -15
  491. data/third_party/boringssl-with-bazel/crypto/asn1/a_utctm.cc +32 -13
  492. data/third_party/boringssl-with-bazel/crypto/asn1/asn1_lib.cc +128 -30
  493. data/third_party/boringssl-with-bazel/crypto/asn1/asn_pack.cc +10 -10
  494. data/third_party/boringssl-with-bazel/crypto/asn1/f_int.cc +1 -1
  495. data/third_party/boringssl-with-bazel/crypto/asn1/f_string.cc +1 -1
  496. data/third_party/boringssl-with-bazel/crypto/asn1/internal.h +261 -115
  497. data/third_party/boringssl-with-bazel/crypto/asn1/posix_time.cc +8 -5
  498. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_dec.cc +373 -725
  499. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_enc.cc +211 -526
  500. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_fre.cc +22 -19
  501. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_new.cc +26 -24
  502. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_typ.cc +19 -5
  503. data/third_party/boringssl-with-bazel/crypto/asn1/tasn_utl.cc +47 -51
  504. data/third_party/boringssl-with-bazel/crypto/base64/base64.cc +14 -15
  505. data/third_party/boringssl-with-bazel/crypto/bcm_support.h +7 -29
  506. data/third_party/boringssl-with-bazel/crypto/bio/bio.cc +234 -176
  507. data/third_party/boringssl-with-bazel/crypto/bio/bio_mem.cc +72 -86
  508. data/third_party/boringssl-with-bazel/crypto/bio/connect.cc +153 -199
  509. data/third_party/boringssl-with-bazel/crypto/bio/errno.cc +3 -1
  510. data/third_party/boringssl-with-bazel/crypto/bio/fd.cc +56 -55
  511. data/third_party/boringssl-with-bazel/crypto/bio/file.cc +70 -78
  512. data/third_party/boringssl-with-bazel/crypto/bio/hexdump.cc +6 -4
  513. data/third_party/boringssl-with-bazel/crypto/bio/internal.h +69 -17
  514. data/third_party/boringssl-with-bazel/crypto/bio/pair.cc +117 -136
  515. data/third_party/boringssl-with-bazel/crypto/bio/printf.cc +1 -1
  516. data/third_party/boringssl-with-bazel/crypto/bio/socket.cc +116 -50
  517. data/third_party/boringssl-with-bazel/crypto/bio/socket_helper.cc +53 -5
  518. data/third_party/boringssl-with-bazel/crypto/blake2/blake2.cc +9 -5
  519. data/third_party/boringssl-with-bazel/crypto/bn/bn_asn1.cc +2 -2
  520. data/third_party/boringssl-with-bazel/crypto/bn/convert.cc +56 -70
  521. data/third_party/boringssl-with-bazel/crypto/bn/div.cc +102 -0
  522. data/third_party/boringssl-with-bazel/crypto/bn/exponentiation.cc +26 -42
  523. data/third_party/boringssl-with-bazel/crypto/bn/sqrt.cc +93 -0
  524. data/third_party/boringssl-with-bazel/crypto/buf/buf.cc +6 -5
  525. data/third_party/boringssl-with-bazel/crypto/bytestring/asn1_compat.cc +6 -5
  526. data/third_party/boringssl-with-bazel/crypto/bytestring/ber.cc +22 -20
  527. data/third_party/boringssl-with-bazel/crypto/bytestring/cbb.cc +119 -59
  528. data/third_party/boringssl-with-bazel/crypto/bytestring/cbs.cc +115 -31
  529. data/third_party/boringssl-with-bazel/crypto/bytestring/internal.h +79 -24
  530. data/third_party/boringssl-with-bazel/crypto/bytestring/unicode.cc +2 -2
  531. data/third_party/boringssl-with-bazel/crypto/chacha/chacha.cc +5 -3
  532. data/third_party/boringssl-with-bazel/crypto/chacha/internal.h +23 -22
  533. data/third_party/boringssl-with-bazel/crypto/cipher/derive_key.cc +14 -18
  534. data/third_party/boringssl-with-bazel/crypto/cipher/e_aesctrhmac.cc +73 -58
  535. data/third_party/boringssl-with-bazel/crypto/cipher/e_aeseax.cc +132 -70
  536. data/third_party/boringssl-with-bazel/crypto/cipher/e_aesgcmsiv.cc +390 -249
  537. data/third_party/boringssl-with-bazel/crypto/cipher/e_chacha20poly1305.cc +200 -137
  538. data/third_party/boringssl-with-bazel/crypto/cipher/e_des.cc +45 -29
  539. data/third_party/boringssl-with-bazel/crypto/cipher/e_null.cc +9 -5
  540. data/third_party/boringssl-with-bazel/crypto/cipher/e_rc2.cc +43 -28
  541. data/third_party/boringssl-with-bazel/crypto/cipher/e_rc4.cc +7 -5
  542. data/third_party/boringssl-with-bazel/crypto/cipher/e_tls.cc +250 -237
  543. data/third_party/boringssl-with-bazel/crypto/cipher/get_cipher.cc +12 -12
  544. data/third_party/boringssl-with-bazel/crypto/cipher/internal.h +59 -59
  545. data/third_party/boringssl-with-bazel/crypto/cipher/tls_cbc.cc +111 -111
  546. data/third_party/boringssl-with-bazel/crypto/cms/cms.cc +48 -42
  547. data/third_party/boringssl-with-bazel/crypto/conf/conf.cc +69 -63
  548. data/third_party/boringssl-with-bazel/crypto/conf/internal.h +11 -12
  549. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_apple.cc +8 -5
  550. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_fuchsia.cc +6 -1
  551. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_linux.cc +7 -1
  552. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_openbsd.cc +7 -21
  553. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_sysreg.cc +15 -41
  554. data/third_party/boringssl-with-bazel/crypto/cpu_aarch64_win.cc +16 -3
  555. data/third_party/boringssl-with-bazel/crypto/cpu_arm_freebsd.cc +4 -2
  556. data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.cc +54 -31
  557. data/third_party/boringssl-with-bazel/crypto/cpu_arm_linux.h +79 -101
  558. data/third_party/boringssl-with-bazel/crypto/cpu_intel.cc +51 -45
  559. data/third_party/boringssl-with-bazel/crypto/crypto.cc +26 -55
  560. data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519.cc +28 -25
  561. data/third_party/boringssl-with-bazel/crypto/curve25519/curve25519_tables.h +6 -6
  562. data/third_party/boringssl-with-bazel/crypto/curve25519/internal.h +14 -15
  563. data/third_party/boringssl-with-bazel/crypto/curve25519/spake25519.cc +23 -20
  564. data/third_party/boringssl-with-bazel/crypto/des/des.cc +27 -19
  565. data/third_party/boringssl-with-bazel/crypto/des/internal.h +4 -9
  566. data/third_party/boringssl-with-bazel/crypto/dh/dh_asn1.cc +34 -49
  567. data/third_party/boringssl-with-bazel/crypto/dh/params.cc +44 -41
  568. data/third_party/boringssl-with-bazel/crypto/digest/digest_extra.cc +87 -40
  569. data/third_party/boringssl-with-bazel/crypto/dsa/dsa.cc +237 -260
  570. data/third_party/boringssl-with-bazel/crypto/dsa/dsa_asn1.cc +100 -173
  571. data/third_party/boringssl-with-bazel/crypto/dsa/internal.h +23 -21
  572. data/third_party/boringssl-with-bazel/crypto/ec/ec_asn1.cc +181 -209
  573. data/third_party/boringssl-with-bazel/crypto/ec/ec_derive.cc +26 -28
  574. data/third_party/boringssl-with-bazel/crypto/ec/hash_to_curve.cc +265 -174
  575. data/third_party/boringssl-with-bazel/crypto/ec/internal.h +54 -18
  576. data/third_party/boringssl-with-bazel/crypto/ecdh/ecdh.cc +7 -5
  577. data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_asn1.cc +50 -70
  578. data/third_party/boringssl-with-bazel/crypto/ecdsa/ecdsa_p1363.cc +54 -0
  579. data/third_party/boringssl-with-bazel/crypto/engine/engine.cc +7 -7
  580. data/third_party/boringssl-with-bazel/crypto/err/err.cc +116 -105
  581. data/third_party/boringssl-with-bazel/crypto/err/internal.h +8 -21
  582. data/third_party/boringssl-with-bazel/crypto/evp/evp.cc +238 -166
  583. data/third_party/boringssl-with-bazel/crypto/evp/evp_asn1.cc +202 -234
  584. data/third_party/boringssl-with-bazel/crypto/evp/evp_ctx.cc +260 -159
  585. data/third_party/boringssl-with-bazel/crypto/evp/evp_kem.cc +82 -0
  586. data/third_party/boringssl-with-bazel/crypto/evp/internal.h +292 -137
  587. data/third_party/boringssl-with-bazel/crypto/evp/p_dh.cc +198 -25
  588. data/third_party/boringssl-with-bazel/crypto/evp/p_dsa.cc +333 -0
  589. data/third_party/boringssl-with-bazel/crypto/evp/p_ec.cc +427 -42
  590. data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519.cc +270 -14
  591. data/third_party/boringssl-with-bazel/crypto/evp/p_hkdf.cc +70 -102
  592. data/third_party/boringssl-with-bazel/crypto/evp/p_mldsa.cc +549 -0
  593. data/third_party/boringssl-with-bazel/crypto/evp/p_mlkem.cc +485 -0
  594. data/third_party/boringssl-with-bazel/crypto/evp/p_rsa.cc +666 -158
  595. data/third_party/boringssl-with-bazel/crypto/evp/p_x25519.cc +290 -28
  596. data/third_party/boringssl-with-bazel/crypto/evp/p_xwing.cc +273 -0
  597. data/third_party/boringssl-with-bazel/crypto/evp/pbkdf.cc +14 -7
  598. data/third_party/boringssl-with-bazel/crypto/evp/print.cc +34 -89
  599. data/third_party/boringssl-with-bazel/crypto/evp/scrypt.cc +23 -21
  600. data/third_party/boringssl-with-bazel/crypto/evp/sign.cc +23 -42
  601. data/third_party/boringssl-with-bazel/crypto/ex_data.cc +40 -41
  602. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes.cc.inc +34 -28
  603. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/aes_nohw.cc.inc +119 -121
  604. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cbc.cc.inc +16 -14
  605. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/cfb.cc.inc +12 -10
  606. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ctr.cc.inc +7 -5
  607. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm.cc.inc +39 -29
  608. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/gcm_nohw.cc.inc +15 -13
  609. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/internal.h +193 -177
  610. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/key_wrap.cc.inc +5 -3
  611. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/mode_wrappers.cc.inc +7 -3
  612. data/third_party/boringssl-with-bazel/crypto/fipsmodule/aes/ofb.cc.inc +7 -5
  613. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm.cc +24 -19
  614. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bcm_interface.h +512 -384
  615. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/add.cc.inc +7 -5
  616. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/asm/x86_64-gcc.cc.inc +63 -44
  617. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bn.cc.inc +40 -37
  618. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/bytes.cc.inc +27 -22
  619. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/cmp.cc.inc +9 -7
  620. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/ctx.cc.inc +62 -126
  621. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div.cc.inc +92 -167
  622. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/div_extra.cc.inc +15 -12
  623. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/exponentiation.cc.inc +96 -93
  624. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd.cc.inc +73 -92
  625. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/gcd_extra.cc.inc +59 -71
  626. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/generic.cc.inc +54 -57
  627. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/internal.h +333 -255
  628. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/jacobi.cc.inc +12 -19
  629. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery.cc.inc +80 -95
  630. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/montgomery_inv.cc.inc +53 -96
  631. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/mul.cc.inc +58 -419
  632. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/prime.cc.inc +164 -213
  633. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/random.cc.inc +27 -26
  634. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.cc.inc +12 -10
  635. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/rsaz_exp.h +47 -49
  636. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/shift.cc.inc +14 -17
  637. data/third_party/boringssl-with-bazel/crypto/fipsmodule/bn/sqrt.cc.inc +19 -108
  638. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/aead.cc.inc +427 -105
  639. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/cipher.cc.inc +412 -212
  640. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aes.cc.inc +230 -225
  641. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/e_aesccm.cc.inc +115 -84
  642. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cipher/internal.h +374 -27
  643. data/third_party/boringssl-with-bazel/crypto/fipsmodule/cmac/cmac.cc.inc +28 -23
  644. data/third_party/boringssl-with-bazel/crypto/fipsmodule/delocate.h +36 -40
  645. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/check.cc.inc +68 -78
  646. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/dh.cc.inc +154 -196
  647. data/third_party/boringssl-with-bazel/crypto/fipsmodule/dh/internal.h +24 -24
  648. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digest.cc.inc +40 -69
  649. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/digests.cc.inc +13 -7
  650. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/internal.h +13 -11
  651. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digest/md32_common.h +86 -81
  652. data/third_party/boringssl-with-bazel/crypto/fipsmodule/digestsign/digestsign.cc.inc +38 -34
  653. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec.cc.inc +187 -196
  654. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_key.cc.inc +196 -154
  655. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/ec_montgomery.cc.inc +65 -125
  656. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/felem.cc.inc +85 -22
  657. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/internal.h +281 -287
  658. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/oct.cc.inc +23 -22
  659. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256.cc.inc +514 -573
  660. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256_internal.h +193 -0
  661. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/scalar.cc.inc +44 -39
  662. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple.cc.inc +58 -90
  663. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/simple_mul.cc.inc +39 -34
  664. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/util.cc.inc +6 -3
  665. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/wnaf.cc.inc +23 -20
  666. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdh/ecdh.cc.inc +6 -3
  667. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/ecdsa.cc.inc +47 -37
  668. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ecdsa/internal.h +5 -10
  669. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/internal.h +38 -0
  670. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/jitter.cc.inc +463 -0
  671. data/third_party/boringssl-with-bazel/crypto/fipsmodule/entropy/sha512.cc.inc +329 -0
  672. data/third_party/boringssl-with-bazel/crypto/fipsmodule/hkdf/hkdf.cc.inc +8 -6
  673. data/third_party/boringssl-with-bazel/crypto/fipsmodule/hmac/hmac.cc.inc +19 -16
  674. data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/internal.h +41 -15
  675. data/third_party/boringssl-with-bazel/crypto/fipsmodule/keccak/keccak.cc.inc +172 -44
  676. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/fips_known_values.inc +5 -5
  677. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mldsa/mldsa.cc.inc +1632 -766
  678. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/fips_known_values.inc +5 -5
  679. data/third_party/boringssl-with-bazel/crypto/fipsmodule/mlkem/mlkem.cc.inc +740 -436
  680. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/android_entropy_client.cc.inc +82 -0
  681. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/ctrdrbg.cc.inc +240 -53
  682. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/internal.h +41 -26
  683. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rand/rand.cc.inc +221 -218
  684. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/internal.h +64 -67
  685. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/padding.cc.inc +49 -57
  686. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa.cc.inc +247 -234
  687. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/rsa_impl.cc.inc +392 -692
  688. data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/fips.cc.inc +10 -10
  689. data/third_party/boringssl-with-bazel/crypto/fipsmodule/self_check/self_check.cc.inc +479 -449
  690. data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/internal.h +34 -11
  691. data/third_party/boringssl-with-bazel/crypto/fipsmodule/service_indicator/service_indicator.cc.inc +46 -43
  692. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/internal.h +61 -70
  693. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha1.cc.inc +27 -13
  694. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha256.cc.inc +46 -30
  695. data/third_party/boringssl-with-bazel/crypto/fipsmodule/sha/sha512.cc.inc +47 -47
  696. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/address.h +98 -73
  697. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.cc.inc +108 -98
  698. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/fors.h +14 -24
  699. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.cc.inc +94 -91
  700. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/merkle.h +19 -31
  701. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/params.h +156 -56
  702. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/slhdsa.cc.inc +318 -132
  703. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.cc.inc +234 -81
  704. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/thash.h +20 -34
  705. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.cc.inc +97 -96
  706. data/third_party/boringssl-with-bazel/crypto/fipsmodule/slhdsa/wots.h +10 -20
  707. data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/internal.h +2 -16
  708. data/third_party/boringssl-with-bazel/crypto/fipsmodule/tls/kdf.cc.inc +26 -26
  709. data/third_party/boringssl-with-bazel/crypto/fuzzer_mode.cc +5 -5
  710. data/third_party/boringssl-with-bazel/crypto/hpke/hpke.cc +461 -97
  711. data/third_party/boringssl-with-bazel/crypto/hrss/hrss.cc +153 -149
  712. data/third_party/boringssl-with-bazel/crypto/hrss/internal.h +9 -13
  713. data/third_party/boringssl-with-bazel/crypto/internal.h +531 -394
  714. data/third_party/boringssl-with-bazel/crypto/kyber/internal.h +117 -12
  715. data/third_party/boringssl-with-bazel/crypto/kyber/kyber.cc +59 -58
  716. data/third_party/boringssl-with-bazel/crypto/lhash/internal.h +38 -37
  717. data/third_party/boringssl-with-bazel/crypto/lhash/lhash.cc +68 -65
  718. data/third_party/boringssl-with-bazel/crypto/md4/md4.cc +19 -6
  719. data/third_party/boringssl-with-bazel/crypto/md5/internal.h +6 -9
  720. data/third_party/boringssl-with-bazel/crypto/md5/md5.cc +18 -6
  721. data/third_party/boringssl-with-bazel/crypto/mem.cc +61 -65
  722. data/third_party/boringssl-with-bazel/crypto/mem_internal.h +671 -0
  723. data/third_party/boringssl-with-bazel/crypto/mldsa/mldsa.cc +238 -32
  724. data/third_party/boringssl-with-bazel/crypto/mlkem/mlkem.cc +21 -65
  725. data/third_party/boringssl-with-bazel/crypto/obj/obj.cc +132 -157
  726. data/third_party/boringssl-with-bazel/crypto/obj/obj_dat.h +79 -1
  727. data/third_party/boringssl-with-bazel/crypto/obj/obj_xref.cc +14 -11
  728. data/third_party/boringssl-with-bazel/crypto/params_internal.h +30 -0
  729. data/third_party/boringssl-with-bazel/crypto/pem/internal.h +20 -15
  730. data/third_party/boringssl-with-bazel/crypto/pem/pem_all.cc +20 -19
  731. data/third_party/boringssl-with-bazel/crypto/pem/pem_info.cc +72 -76
  732. data/third_party/boringssl-with-bazel/crypto/pem/pem_lib.cc +215 -217
  733. data/third_party/boringssl-with-bazel/crypto/pem/pem_oth.cc +6 -6
  734. data/third_party/boringssl-with-bazel/crypto/pem/pem_pk8.cc +13 -13
  735. data/third_party/boringssl-with-bazel/crypto/pem/pem_pkey.cc +11 -11
  736. data/third_party/boringssl-with-bazel/crypto/pkcs7/internal.h +12 -17
  737. data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7.cc +29 -27
  738. data/third_party/boringssl-with-bazel/crypto/pkcs7/pkcs7_x509.cc +55 -49
  739. data/third_party/boringssl-with-bazel/crypto/pkcs8/internal.h +21 -26
  740. data/third_party/boringssl-with-bazel/crypto/pkcs8/p5_pbev2.cc +33 -31
  741. data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8.cc +73 -81
  742. data/third_party/boringssl-with-bazel/crypto/pkcs8/pkcs8_x509.cc +139 -138
  743. data/third_party/boringssl-with-bazel/crypto/poly1305/internal.h +3 -7
  744. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305.cc +5 -4
  745. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_arm.cc +43 -47
  746. data/third_party/boringssl-with-bazel/crypto/poly1305/poly1305_vec.cc +29 -26
  747. data/third_party/boringssl-with-bazel/crypto/pool/internal.h +64 -20
  748. data/third_party/boringssl-with-bazel/crypto/pool/pool.cc +177 -157
  749. data/third_party/boringssl-with-bazel/crypto/rand/deterministic.cc +9 -16
  750. data/third_party/boringssl-with-bazel/crypto/rand/fork_detect.cc +70 -42
  751. data/third_party/boringssl-with-bazel/crypto/rand/forkunsafe.cc +7 -7
  752. data/third_party/boringssl-with-bazel/crypto/rand/getentropy.cc +6 -13
  753. data/third_party/boringssl-with-bazel/crypto/rand/internal.h +16 -4
  754. data/third_party/boringssl-with-bazel/crypto/rand/ios.cc +4 -11
  755. data/third_party/boringssl-with-bazel/crypto/rand/rand.cc +11 -9
  756. data/third_party/boringssl-with-bazel/crypto/rand/trusty.cc +4 -11
  757. data/third_party/boringssl-with-bazel/crypto/rand/urandom.cc +16 -195
  758. data/third_party/boringssl-with-bazel/crypto/rand/windows.cc +12 -19
  759. data/third_party/boringssl-with-bazel/crypto/refcount.cc +7 -17
  760. data/third_party/boringssl-with-bazel/crypto/rsa/internal.h +22 -7
  761. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_asn1.cc +199 -78
  762. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_crypt.cc +49 -50
  763. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_extra.cc +11 -0
  764. data/third_party/boringssl-with-bazel/crypto/rsa/rsa_print.cc +4 -6
  765. data/third_party/boringssl-with-bazel/crypto/sha/sha1.cc +3 -0
  766. data/third_party/boringssl-with-bazel/crypto/sha/sha256.cc +3 -1
  767. data/third_party/boringssl-with-bazel/crypto/sha/sha512.cc +6 -4
  768. data/third_party/boringssl-with-bazel/crypto/siphash/siphash.cc +2 -0
  769. data/third_party/boringssl-with-bazel/crypto/slhdsa/slhdsa.cc +43 -6
  770. data/third_party/boringssl-with-bazel/crypto/spake2plus/internal.h +31 -31
  771. data/third_party/boringssl-with-bazel/crypto/spake2plus/spake2plus.cc +1 -1
  772. data/third_party/boringssl-with-bazel/crypto/stack/stack.cc +89 -130
  773. data/third_party/boringssl-with-bazel/crypto/thread.cc +14 -14
  774. data/third_party/boringssl-with-bazel/crypto/thread_none.cc +10 -13
  775. data/third_party/boringssl-with-bazel/crypto/thread_pthread.cc +22 -35
  776. data/third_party/boringssl-with-bazel/crypto/thread_win.cc +29 -40
  777. data/third_party/boringssl-with-bazel/crypto/trust_token/internal.h +81 -88
  778. data/third_party/boringssl-with-bazel/crypto/trust_token/pmbtoken.cc +160 -144
  779. data/third_party/boringssl-with-bazel/crypto/trust_token/trust_token.cc +96 -80
  780. data/third_party/boringssl-with-bazel/crypto/trust_token/voprf.cc +90 -87
  781. data/third_party/boringssl-with-bazel/crypto/x509/a_digest.cc +5 -5
  782. data/third_party/boringssl-with-bazel/crypto/x509/a_sign.cc +51 -48
  783. data/third_party/boringssl-with-bazel/crypto/x509/a_verify.cc +30 -34
  784. data/third_party/boringssl-with-bazel/crypto/x509/algorithm.cc +47 -16
  785. data/third_party/boringssl-with-bazel/crypto/x509/asn1_gen.cc +41 -43
  786. data/third_party/boringssl-with-bazel/crypto/x509/by_dir.cc +183 -237
  787. data/third_party/boringssl-with-bazel/crypto/x509/by_file.cc +29 -30
  788. data/third_party/boringssl-with-bazel/crypto/x509/internal.h +276 -180
  789. data/third_party/boringssl-with-bazel/crypto/x509/name_print.cc +15 -13
  790. data/third_party/boringssl-with-bazel/crypto/x509/policy.cc +415 -525
  791. data/third_party/boringssl-with-bazel/crypto/x509/rsa_pss.cc +94 -271
  792. data/third_party/boringssl-with-bazel/crypto/x509/t_crl.cc +11 -8
  793. data/third_party/boringssl-with-bazel/crypto/x509/t_req.cc +26 -23
  794. data/third_party/boringssl-with-bazel/crypto/x509/t_x509.cc +26 -22
  795. data/third_party/boringssl-with-bazel/crypto/x509/t_x509a.cc +3 -1
  796. data/third_party/boringssl-with-bazel/crypto/x509/v3_akey.cc +69 -76
  797. data/third_party/boringssl-with-bazel/crypto/x509/v3_akeya.cc +2 -2
  798. data/third_party/boringssl-with-bazel/crypto/x509/v3_alt.cc +112 -69
  799. data/third_party/boringssl-with-bazel/crypto/x509/v3_bcons.cc +15 -14
  800. data/third_party/boringssl-with-bazel/crypto/x509/v3_bitst.cc +16 -18
  801. data/third_party/boringssl-with-bazel/crypto/x509/v3_conf.cc +62 -67
  802. data/third_party/boringssl-with-bazel/crypto/x509/v3_cpols.cc +143 -170
  803. data/third_party/boringssl-with-bazel/crypto/x509/v3_crld.cc +121 -165
  804. data/third_party/boringssl-with-bazel/crypto/x509/v3_enum.cc +13 -12
  805. data/third_party/boringssl-with-bazel/crypto/x509/v3_extku.cc +17 -34
  806. data/third_party/boringssl-with-bazel/crypto/x509/v3_genn.cc +20 -10
  807. data/third_party/boringssl-with-bazel/crypto/x509/v3_ia5.cc +22 -18
  808. data/third_party/boringssl-with-bazel/crypto/x509/v3_info.cc +45 -47
  809. data/third_party/boringssl-with-bazel/crypto/x509/v3_int.cc +35 -33
  810. data/third_party/boringssl-with-bazel/crypto/x509/v3_lib.cc +106 -61
  811. data/third_party/boringssl-with-bazel/crypto/x509/v3_ncons.cc +642 -358
  812. data/third_party/boringssl-with-bazel/crypto/x509/v3_ocsp.cc +25 -22
  813. data/third_party/boringssl-with-bazel/crypto/x509/v3_pcons.cc +15 -14
  814. data/third_party/boringssl-with-bazel/crypto/x509/v3_pmaps.cc +16 -15
  815. data/third_party/boringssl-with-bazel/crypto/x509/v3_prn.cc +6 -6
  816. data/third_party/boringssl-with-bazel/crypto/x509/v3_purp.cc +150 -137
  817. data/third_party/boringssl-with-bazel/crypto/x509/v3_skey.cc +23 -26
  818. data/third_party/boringssl-with-bazel/crypto/x509/v3_utl.cc +151 -178
  819. data/third_party/boringssl-with-bazel/crypto/x509/x509.cc +1 -1
  820. data/third_party/boringssl-with-bazel/crypto/x509/x509_att.cc +32 -30
  821. data/third_party/boringssl-with-bazel/crypto/x509/x509_cmp.cc +95 -88
  822. data/third_party/boringssl-with-bazel/crypto/x509/x509_d2.cc +9 -9
  823. data/third_party/boringssl-with-bazel/crypto/x509/x509_def.cc +6 -8
  824. data/third_party/boringssl-with-bazel/crypto/x509/x509_ext.cc +46 -24
  825. data/third_party/boringssl-with-bazel/crypto/x509/x509_lu.cc +211 -195
  826. data/third_party/boringssl-with-bazel/crypto/x509/x509_obj.cc +20 -16
  827. data/third_party/boringssl-with-bazel/crypto/x509/x509_req.cc +37 -46
  828. data/third_party/boringssl-with-bazel/crypto/x509/x509_set.cc +62 -90
  829. data/third_party/boringssl-with-bazel/crypto/x509/x509_trs.cc +18 -13
  830. data/third_party/boringssl-with-bazel/crypto/x509/x509_v3.cc +33 -33
  831. data/third_party/boringssl-with-bazel/crypto/x509/x509_vfy.cc +109 -110
  832. data/third_party/boringssl-with-bazel/crypto/x509/x509_vpm.cc +56 -47
  833. data/third_party/boringssl-with-bazel/crypto/x509/x509cset.cc +27 -40
  834. data/third_party/boringssl-with-bazel/crypto/x509/x509name.cc +77 -67
  835. data/third_party/boringssl-with-bazel/crypto/x509/x509rset.cc +5 -17
  836. data/third_party/boringssl-with-bazel/crypto/x509/x509spki.cc +13 -13
  837. data/third_party/boringssl-with-bazel/crypto/x509/x_algor.cc +131 -24
  838. data/third_party/boringssl-with-bazel/crypto/x509/x_all.cc +72 -39
  839. data/third_party/boringssl-with-bazel/crypto/x509/x_attrib.cc +10 -4
  840. data/third_party/boringssl-with-bazel/crypto/x509/x_crl.cc +77 -44
  841. data/third_party/boringssl-with-bazel/crypto/x509/x_exten.cc +6 -0
  842. data/third_party/boringssl-with-bazel/crypto/x509/x_name.cc +311 -383
  843. data/third_party/boringssl-with-bazel/crypto/x509/x_pubkey.cc +129 -82
  844. data/third_party/boringssl-with-bazel/crypto/x509/x_req.cc +11 -6
  845. data/third_party/boringssl-with-bazel/crypto/x509/x_sig.cc +4 -4
  846. data/third_party/boringssl-with-bazel/crypto/x509/x_spki.cc +11 -1
  847. data/third_party/boringssl-with-bazel/crypto/x509/x_x509.cc +285 -280
  848. data/third_party/boringssl-with-bazel/crypto/x509/x_x509a.cc +60 -60
  849. data/third_party/boringssl-with-bazel/crypto/xwing/xwing.cc +257 -0
  850. data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_64_win_asm.inc +301 -0
  851. data/third_party/boringssl-with-bazel/gen/boringssl_prefix_symbols_internal_x86_win_asm.inc +301 -0
  852. data/third_party/boringssl-with-bazel/gen/crypto/err_data.cc +526 -500
  853. data/third_party/boringssl-with-bazel/include/openssl/aead.h +286 -114
  854. data/third_party/boringssl-with-bazel/include/openssl/aes.h +43 -43
  855. data/third_party/boringssl-with-bazel/include/openssl/asm_base.h +29 -16
  856. data/third_party/boringssl-with-bazel/include/openssl/asn1.h +641 -631
  857. data/third_party/boringssl-with-bazel/include/openssl/asn1t.h +7 -9
  858. data/third_party/boringssl-with-bazel/include/openssl/base.h +34 -54
  859. data/third_party/boringssl-with-bazel/include/openssl/base64.h +30 -30
  860. data/third_party/boringssl-with-bazel/include/openssl/bio.h +373 -316
  861. data/third_party/boringssl-with-bazel/include/openssl/blake2.h +15 -11
  862. data/third_party/boringssl-with-bazel/include/openssl/blowfish.h +10 -3
  863. data/third_party/boringssl-with-bazel/include/openssl/bn.h +298 -306
  864. data/third_party/boringssl-with-bazel/include/openssl/buf.h +14 -14
  865. data/third_party/boringssl-with-bazel/include/openssl/bytestring.h +272 -207
  866. data/third_party/boringssl-with-bazel/include/openssl/cast.h +45 -8
  867. data/third_party/boringssl-with-bazel/include/openssl/chacha.h +3 -3
  868. data/third_party/boringssl-with-bazel/include/openssl/cipher.h +334 -152
  869. data/third_party/boringssl-with-bazel/include/openssl/cmac.h +13 -13
  870. data/third_party/boringssl-with-bazel/include/openssl/cms.h +35 -34
  871. data/third_party/boringssl-with-bazel/include/openssl/conf.h +15 -14
  872. data/third_party/boringssl-with-bazel/include/openssl/crypto.h +15 -13
  873. data/third_party/boringssl-with-bazel/include/openssl/ctrdrbg.h +49 -15
  874. data/third_party/boringssl-with-bazel/include/openssl/curve25519.h +24 -24
  875. data/third_party/boringssl-with-bazel/include/openssl/des.h +22 -16
  876. data/third_party/boringssl-with-bazel/include/openssl/dh.h +95 -95
  877. data/third_party/boringssl-with-bazel/include/openssl/digest.h +140 -71
  878. data/third_party/boringssl-with-bazel/include/openssl/dsa.h +101 -101
  879. data/third_party/boringssl-with-bazel/include/openssl/ec.h +143 -119
  880. data/third_party/boringssl-with-bazel/include/openssl/ec_key.h +97 -97
  881. data/third_party/boringssl-with-bazel/include/openssl/ecdh.h +9 -9
  882. data/third_party/boringssl-with-bazel/include/openssl/ecdsa.h +89 -46
  883. data/third_party/boringssl-with-bazel/include/openssl/engine.h +5 -5
  884. data/third_party/boringssl-with-bazel/include/openssl/err.h +73 -71
  885. data/third_party/boringssl-with-bazel/include/openssl/evp.h +824 -344
  886. data/third_party/boringssl-with-bazel/include/openssl/evp_errors.h +9 -2
  887. data/third_party/boringssl-with-bazel/include/openssl/ex_data.h +27 -32
  888. data/third_party/boringssl-with-bazel/include/openssl/hkdf.h +6 -6
  889. data/third_party/boringssl-with-bazel/include/openssl/hmac.h +31 -31
  890. data/third_party/boringssl-with-bazel/include/openssl/hpke.h +133 -117
  891. data/third_party/boringssl-with-bazel/include/openssl/hrss.h +14 -8
  892. data/third_party/boringssl-with-bazel/include/openssl/kdf.h +20 -19
  893. data/third_party/boringssl-with-bazel/include/openssl/lhash.h +4 -25
  894. data/third_party/boringssl-with-bazel/include/openssl/md4.h +14 -7
  895. data/third_party/boringssl-with-bazel/include/openssl/md5.h +7 -7
  896. data/third_party/boringssl-with-bazel/include/openssl/mem.h +38 -38
  897. data/third_party/boringssl-with-bazel/include/openssl/mldsa.h +380 -24
  898. data/third_party/boringssl-with-bazel/include/openssl/mlkem.h +43 -43
  899. data/third_party/boringssl-with-bazel/include/openssl/nid.h +1297 -2
  900. data/third_party/boringssl-with-bazel/include/openssl/obj.h +49 -49
  901. data/third_party/boringssl-with-bazel/include/openssl/opensslconf.h +30 -0
  902. data/third_party/boringssl-with-bazel/include/openssl/params.h +42 -0
  903. data/third_party/boringssl-with-bazel/include/openssl/pem.h +39 -30
  904. data/third_party/boringssl-with-bazel/include/openssl/pkcs7.h +40 -40
  905. data/third_party/boringssl-with-bazel/include/openssl/pkcs8.h +69 -63
  906. data/third_party/boringssl-with-bazel/include/openssl/poly1305.h +8 -5
  907. data/third_party/boringssl-with-bazel/include/openssl/pool.h +54 -25
  908. data/third_party/boringssl-with-bazel/include/openssl/posix_time.h +6 -6
  909. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols.h +7866 -0
  910. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_S.h +585 -0
  911. data/third_party/boringssl-with-bazel/include/openssl/prefix_symbols_internal_c.h +305 -0
  912. data/third_party/boringssl-with-bazel/include/openssl/rand.h +18 -18
  913. data/third_party/boringssl-with-bazel/include/openssl/rc4.h +4 -4
  914. data/third_party/boringssl-with-bazel/include/openssl/ripemd.h +15 -10
  915. data/third_party/boringssl-with-bazel/include/openssl/rsa.h +272 -235
  916. data/third_party/boringssl-with-bazel/include/openssl/service_indicator.h +4 -81
  917. data/third_party/boringssl-with-bazel/include/openssl/sha.h +43 -166
  918. data/third_party/boringssl-with-bazel/include/openssl/sha2.h +201 -0
  919. data/third_party/boringssl-with-bazel/include/openssl/slhdsa.h +100 -48
  920. data/third_party/boringssl-with-bazel/include/openssl/span.h +190 -75
  921. data/third_party/boringssl-with-bazel/include/openssl/ssl.h +2168 -1567
  922. data/third_party/boringssl-with-bazel/include/openssl/ssl3.h +11 -69
  923. data/third_party/boringssl-with-bazel/include/openssl/stack.h +135 -80
  924. data/third_party/boringssl-with-bazel/include/openssl/target.h +13 -1
  925. data/third_party/boringssl-with-bazel/include/openssl/thread.h +0 -10
  926. data/third_party/boringssl-with-bazel/include/openssl/tls1.h +31 -310
  927. data/third_party/boringssl-with-bazel/include/openssl/tls_prf.h +47 -0
  928. data/third_party/boringssl-with-bazel/include/openssl/trust_token.h +97 -92
  929. data/third_party/boringssl-with-bazel/include/openssl/type_check.h +1 -1
  930. data/third_party/boringssl-with-bazel/include/openssl/x509.h +1805 -1857
  931. data/third_party/boringssl-with-bazel/include/openssl/x509v3.h +1 -1
  932. data/third_party/boringssl-with-bazel/include/openssl/xwing.h +115 -0
  933. data/third_party/boringssl-with-bazel/ssl/bio_ssl.cc +24 -19
  934. data/third_party/boringssl-with-bazel/ssl/d1_both.cc +59 -57
  935. data/third_party/boringssl-with-bazel/ssl/d1_lib.cc +53 -42
  936. data/third_party/boringssl-with-bazel/ssl/d1_pkt.cc +4 -4
  937. data/third_party/boringssl-with-bazel/ssl/d1_srtp.cc +2 -2
  938. data/third_party/boringssl-with-bazel/ssl/dtls_method.cc +10 -10
  939. data/third_party/boringssl-with-bazel/ssl/dtls_record.cc +6 -6
  940. data/third_party/boringssl-with-bazel/ssl/encrypted_client_hello.cc +61 -71
  941. data/third_party/boringssl-with-bazel/ssl/extensions.cc +967 -366
  942. data/third_party/boringssl-with-bazel/ssl/handoff.cc +77 -38
  943. data/third_party/boringssl-with-bazel/ssl/handshake.cc +63 -30
  944. data/third_party/boringssl-with-bazel/ssl/handshake_client.cc +129 -85
  945. data/third_party/boringssl-with-bazel/ssl/handshake_server.cc +116 -68
  946. data/third_party/boringssl-with-bazel/ssl/internal.h +983 -1207
  947. data/third_party/boringssl-with-bazel/ssl/s3_both.cc +34 -29
  948. data/third_party/boringssl-with-bazel/ssl/s3_lib.cc +4 -3
  949. data/third_party/boringssl-with-bazel/ssl/s3_pkt.cc +12 -12
  950. data/third_party/boringssl-with-bazel/ssl/ssl_aead_ctx.cc +5 -5
  951. data/third_party/boringssl-with-bazel/ssl/ssl_asn1.cc +114 -59
  952. data/third_party/boringssl-with-bazel/ssl/ssl_buffer.cc +17 -18
  953. data/third_party/boringssl-with-bazel/ssl/ssl_cert.cc +99 -61
  954. data/third_party/boringssl-with-bazel/ssl/ssl_cipher.cc +143 -134
  955. data/third_party/boringssl-with-bazel/ssl/ssl_credential.cc +188 -90
  956. data/third_party/boringssl-with-bazel/ssl/ssl_file.cc +132 -225
  957. data/third_party/boringssl-with-bazel/ssl/ssl_key_share.cc +79 -7
  958. data/third_party/boringssl-with-bazel/ssl/ssl_lib.cc +698 -302
  959. data/third_party/boringssl-with-bazel/ssl/ssl_privkey.cc +102 -45
  960. data/third_party/boringssl-with-bazel/ssl/ssl_session.cc +117 -102
  961. data/third_party/boringssl-with-bazel/ssl/ssl_transcript.cc +3 -3
  962. data/third_party/boringssl-with-bazel/ssl/ssl_versions.cc +24 -24
  963. data/third_party/boringssl-with-bazel/ssl/ssl_x509.cc +184 -170
  964. data/third_party/boringssl-with-bazel/ssl/t1_enc.cc +12 -10
  965. data/third_party/boringssl-with-bazel/ssl/tls13_both.cc +86 -54
  966. data/third_party/boringssl-with-bazel/ssl/tls13_client.cc +176 -90
  967. data/third_party/boringssl-with-bazel/ssl/tls13_enc.cc +166 -112
  968. data/third_party/boringssl-with-bazel/ssl/tls13_server.cc +188 -97
  969. data/third_party/boringssl-with-bazel/ssl/tls_method.cc +23 -23
  970. data/third_party/boringssl-with-bazel/ssl/tls_record.cc +17 -14
  971. data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_bareminimum.c.inc +47 -0
  972. data/third_party/boringssl-with-bazel/third_party/fiat/bedrock_unverified_platform.c.inc +137 -0
  973. data/third_party/boringssl-with-bazel/third_party/fiat/curve25519_64_adx.h +37 -33
  974. data/third_party/boringssl-with-bazel/third_party/fiat/p256_64.h +4 -93
  975. data/third_party/boringssl-with-bazel/third_party/fiat/p256_64_msvc.h +4 -69
  976. data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_32.br.c.inc +71 -0
  977. data/third_party/boringssl-with-bazel/third_party/fiat/p256_field_64.br.c.inc +84 -0
  978. data/third_party/boringssl-with-bazel/third_party/fiat/p256_point.br.c.inc +166 -0
  979. metadata +77 -52
  980. data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +0 -240
  981. data/src/core/ext/transport/chttp2/transport/bin_decoder.h +0 -56
  982. data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb.h +0 -157
  983. data/src/core/ext/upb-gen/src/proto/grpc/health/v1/health.upb_minitable.c +0 -72
  984. data/src/core/ext/upbdefs-gen/src/proto/grpc/lookup/v1/rls_config.upbdefs.c +0 -181
  985. data/third_party/abseil-cpp/absl/base/internal/identity.h +0 -39
  986. data/third_party/abseil-cpp/absl/base/internal/nullability_deprecated.h +0 -106
  987. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.cc +0 -105
  988. data/third_party/abseil-cpp/absl/hash/internal/low_level_hash.h +0 -50
  989. data/third_party/abseil-cpp/absl/strings/string_view.cc +0 -257
  990. data/third_party/boringssl-with-bazel/crypto/evp/p_dh_asn1.cc +0 -142
  991. data/third_party/boringssl-with-bazel/crypto/evp/p_dsa_asn1.cc +0 -279
  992. data/third_party/boringssl-with-bazel/crypto/evp/p_ec_asn1.cc +0 -286
  993. data/third_party/boringssl-with-bazel/crypto/evp/p_ed25519_asn1.cc +0 -225
  994. data/third_party/boringssl-with-bazel/crypto/evp/p_rsa_asn1.cc +0 -198
  995. data/third_party/boringssl-with-bazel/crypto/evp/p_x25519_asn1.cc +0 -237
  996. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p224-64.cc.inc +0 -1163
  997. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.cc.inc +0 -741
  998. data/third_party/boringssl-with-bazel/crypto/fipsmodule/ec/p256-nistz.h +0 -207
  999. data/third_party/boringssl-with-bazel/crypto/fipsmodule/rsa/blinding.cc.inc +0 -147
  1000. data/third_party/boringssl-with-bazel/crypto/rand/getrandom_fillin.h +0 -64
  1001. data/third_party/boringssl-with-bazel/crypto/rand/passive.cc +0 -178
  1002. data/third_party/boringssl-with-bazel/crypto/x509/ext_dat.h +0 -92
  1003. data/third_party/boringssl-with-bazel/include/openssl/bcm_public.h +0 -82
  1004. data/third_party/boringssl-with-bazel/include/openssl/experimental/kyber.h +0 -146
@@ -24,9 +24,21 @@
24
24
  #include <openssl/rand.h>
25
25
 
26
26
  #include "../../internal.h"
27
+ #include "../../mem_internal.h"
27
28
  #include "../bcm_interface.h"
28
29
  #include "../keccak/internal.h"
29
30
 
31
+
32
+ using namespace bssl;
33
+
34
+ #if defined(BORINGSSL_FIPS)
35
+
36
+ DEFINE_STATIC_ONCE(g_mldsa_keygen_self_test_once)
37
+ DEFINE_STATIC_ONCE(g_mldsa_sign_self_test_once)
38
+ DEFINE_STATIC_ONCE(g_mldsa_verify_self_test_once)
39
+
40
+ #endif
41
+
30
42
  namespace mldsa {
31
43
  namespace {
32
44
 
@@ -50,9 +62,9 @@ constexpr uint32_t kPrime = 8380417;
50
62
  constexpr uint32_t kPrimeNegInverse = 4236238847;
51
63
  constexpr int kDroppedBits = 13;
52
64
  constexpr uint32_t kHalfPrime = (kPrime - 1) / 2;
53
- constexpr uint32_t kGamma2 = (kPrime - 1) / 32;
54
- // 256^-1 mod kPrime, in Montgomery form.
55
- constexpr uint32_t kInverseDegreeMontgomery = 41978;
65
+ // 256^-1 * R^2 mod kPrime. This is not 256^-1 in Montgomery form, but 256^-1
66
+ // doubly-converted to Montgomery form.
67
+ constexpr uint32_t kInverseDegreeDoubleMontgomery = 41978;
56
68
 
57
69
  // Constants that vary depending on ML-DSA size.
58
70
  //
@@ -62,18 +74,22 @@ constexpr uint32_t kInverseDegreeMontgomery = 41978;
62
74
  template <int K>
63
75
  constexpr size_t public_key_bytes() {
64
76
  if constexpr (K == 6) {
65
- return BCM_MLDSA65_PUBLIC_KEY_BYTES;
77
+ return MLDSA65_PUBLIC_KEY_BYTES;
66
78
  } else if constexpr (K == 8) {
67
- return BCM_MLDSA87_PUBLIC_KEY_BYTES;
79
+ return MLDSA87_PUBLIC_KEY_BYTES;
80
+ } else if constexpr (K == 4) {
81
+ return MLDSA44_PUBLIC_KEY_BYTES;
68
82
  }
69
83
  }
70
84
 
71
85
  template <int K>
72
86
  constexpr size_t signature_bytes() {
73
87
  if constexpr (K == 6) {
74
- return BCM_MLDSA65_SIGNATURE_BYTES;
88
+ return MLDSA65_SIGNATURE_BYTES;
75
89
  } else if constexpr (K == 8) {
76
- return BCM_MLDSA87_SIGNATURE_BYTES;
90
+ return MLDSA87_SIGNATURE_BYTES;
91
+ } else if constexpr (K == 4) {
92
+ return MLDSA44_SIGNATURE_BYTES;
77
93
  }
78
94
  }
79
95
 
@@ -83,6 +99,8 @@ constexpr int tau() {
83
99
  return 49;
84
100
  } else if constexpr (K == 8) {
85
101
  return 60;
102
+ } else if constexpr (K == 4) {
103
+ return 39;
86
104
  }
87
105
  }
88
106
 
@@ -92,22 +110,71 @@ constexpr int lambda_bytes() {
92
110
  return 192 / 8;
93
111
  } else if constexpr (K == 8) {
94
112
  return 256 / 8;
113
+ } else if constexpr (K == 4) {
114
+ return 128 / 8;
115
+ }
116
+ }
117
+
118
+ template <int K>
119
+ constexpr int gamma1_bits() {
120
+ if constexpr (K == 6 || K == 8) {
121
+ return 19;
122
+ } else if constexpr (K == 4) {
123
+ return 17;
95
124
  }
96
125
  }
97
126
 
98
127
  template <int K>
99
128
  constexpr int gamma1() {
129
+ return 1 << gamma1_bits<K>();
130
+ }
131
+
132
+ template <int K>
133
+ constexpr int scalar_le_gamma1_bytes() {
134
+ return ((gamma1_bits<K>() + 1) * kDegree) / 8;
135
+ }
136
+
137
+ template <int K>
138
+ constexpr uint32_t w1_coeffs_bits() {
139
+ if constexpr (K == 6 || K == 8) {
140
+ return 4;
141
+ } else if constexpr (K == 4) {
142
+ return 6;
143
+ }
144
+ }
145
+
146
+ template <int K>
147
+ constexpr uint32_t w1_scalar_bytes() {
148
+ return (w1_coeffs_bits<K>() * kDegree) / 8;
149
+ }
150
+
151
+ template <int K>
152
+ constexpr uint32_t w1_bytes() {
153
+ return w1_scalar_bytes<K>() * K;
154
+ }
155
+
156
+ template <int K>
157
+ constexpr uint32_t prime_minus_one_over_gamma2() {
100
158
  if constexpr (K == 6 || K == 8) {
101
- return 1 << 19;
159
+ return 32;
160
+ } else if constexpr (K == 4) {
161
+ return 88;
102
162
  }
103
163
  }
104
164
 
165
+ template <int K>
166
+ constexpr uint32_t gamma2() {
167
+ return (kPrime - 1) / prime_minus_one_over_gamma2<K>();
168
+ }
169
+
105
170
  template <int K>
106
171
  constexpr int beta() {
107
172
  if constexpr (K == 6) {
108
173
  return 196;
109
174
  } else if constexpr (K == 8) {
110
175
  return 120;
176
+ } else if constexpr (K == 4) {
177
+ return 78;
111
178
  }
112
179
  }
113
180
 
@@ -117,6 +184,8 @@ constexpr int omega() {
117
184
  return 55;
118
185
  } else if constexpr (K == 8) {
119
186
  return 75;
187
+ } else if constexpr (K == 4) {
188
+ return 80;
120
189
  }
121
190
  }
122
191
 
@@ -124,7 +193,7 @@ template <int K>
124
193
  constexpr int eta() {
125
194
  if constexpr (K == 6) {
126
195
  return 4;
127
- } else if constexpr (K == 8) {
196
+ } else if constexpr (K == 8 || K == 4) {
128
197
  return 2;
129
198
  }
130
199
  }
@@ -133,16 +202,16 @@ template <int K>
133
202
  constexpr int plus_minus_eta_bitlen() {
134
203
  if constexpr (K == 6) {
135
204
  return 4;
136
- } else if constexpr (K == 8) {
205
+ } else if constexpr (K == 8 || K == 4) {
137
206
  return 3;
138
207
  }
139
208
  }
140
209
 
141
210
  // Fundamental types.
142
211
 
143
- typedef struct scalar {
212
+ struct scalar {
144
213
  uint32_t c[kDegree];
145
- } scalar;
214
+ };
146
215
 
147
216
  template <int K>
148
217
  struct vector {
@@ -222,54 +291,74 @@ static const uint32_t kNTTRootsMontgomery[256] = {
222
291
  7826001, 3919660, 8332111, 7018208, 3937738, 1400424, 7534263, 1976782};
223
292
 
224
293
  // Reduces x mod kPrime in constant time, where 0 <= x < 2*kPrime.
225
- uint32_t reduce_once(uint32_t x) {
294
+ inline uint32_t reduce_once(uint32_t x) {
226
295
  declassify_assert(x < 2 * kPrime);
227
296
  // return x < kPrime ? x : x - kPrime;
228
- return constant_time_select_int(constant_time_lt_w(x, kPrime), x, x - kPrime);
297
+ const uint32_t subtracted = x - kPrime;
298
+ uint32_t mask = 0u - (subtracted >> 31);
299
+ // Although this is a constant-time select, we omit a value barrier here.
300
+ // Value barriers impede auto-vectorization (likely because it forces the
301
+ // value to transit through a general-purpose register). This is a difference
302
+ // of 1.4x to 1.5x in signing performance.
303
+ //
304
+ // We usually add value barriers to selects because Clang turns consecutive
305
+ // selects with the same condition into a branch instead of CMOV/CSEL. This
306
+ // condition does not occur in ML-DSA, so omitting it seems to be generally
307
+ // safe. However, see `coefficient_from_nibble`.
308
+ return (mask & x) | (~mask & subtracted);
229
309
  }
230
310
 
231
- // Returns the absolute value in constant time.
232
- uint32_t abs_signed(uint32_t x) {
233
- // return is_positive(x) ? x : -x;
234
- // Note: MSVC doesn't like applying the unary minus operator to unsigned types
235
- // (warning C4146), so we write the negation as a bitwise not plus one
236
- // (assuming two's complement representation).
237
- return constant_time_select_int(constant_time_lt_w(x, 0x80000000), x, 0u - x);
311
+ // Returns the absolute value in constant time, interpreting the high bit as a
312
+ // sign bit.
313
+ inline uint32_t abs_signed(uint32_t x) {
314
+ // return is_negative(x) ? -x : x;
315
+ uint32_t mask = 0u - (x >> 31);
316
+ return constant_time_select_32(mask, 0u - x, x);
238
317
  }
239
318
 
240
319
  // Returns the absolute value modulo kPrime.
241
- uint32_t abs_mod_prime(uint32_t x) {
320
+ inline uint32_t abs_mod_prime(uint32_t x) {
242
321
  declassify_assert(x < kPrime);
243
- // return x > kHalfPrime ? kPrime - x : x;
244
- return constant_time_select_int(constant_time_lt_w(kHalfPrime, x), kPrime - x,
245
- x);
322
+ // return x <= kHalfPrime ? x : kPrime - x;
323
+ uint32_t mask = x - kHalfPrime - 1;
324
+ mask = 0u - (mask >> 31);
325
+ return constant_time_select_32(mask, x, kPrime - x);
246
326
  }
247
327
 
248
- // Returns the maximum of two values in constant time.
249
- uint32_t maximum(uint32_t x, uint32_t y) {
328
+ // Returns the maximum of two values in constant time. Each value must be less
329
+ // than kPrime.
330
+ inline uint32_t maximum_reduced(uint32_t x, uint32_t y) {
331
+ declassify_assert(x < kPrime);
332
+ declassify_assert(y < kPrime);
250
333
  // return x < y ? y : x;
251
- return constant_time_select_int(constant_time_lt_w(x, y), y, x);
334
+ uint32_t mask = x - y;
335
+ mask = 0u - (mask >> 31);
336
+ return constant_time_select_32(mask, y, x);
252
337
  }
253
338
 
254
- uint32_t mod_sub(uint32_t a, uint32_t b) {
339
+ inline uint32_t mod_sub(uint32_t a, uint32_t b) {
255
340
  declassify_assert(a < kPrime);
256
341
  declassify_assert(b < kPrime);
257
- return reduce_once(kPrime + a - b);
342
+ uint32_t r = a - b;
343
+ // return r < 0 ? r + kPrime : r;
344
+ uint32_t mask = 0u - (r >> 31);
345
+ // See `reduce_once` for why this does not have a value barrier.
346
+ return (mask & (r + kPrime)) | (~mask & r);
258
347
  }
259
348
 
260
- void scalar_add(scalar *out, const scalar *lhs, const scalar *rhs) {
349
+ inline void scalar_add(scalar *out, const scalar *lhs, const scalar *rhs) {
261
350
  for (int i = 0; i < kDegree; i++) {
262
351
  out->c[i] = reduce_once(lhs->c[i] + rhs->c[i]);
263
352
  }
264
353
  }
265
354
 
266
- void scalar_sub(scalar *out, const scalar *lhs, const scalar *rhs) {
355
+ inline void scalar_sub(scalar *out, const scalar *lhs, const scalar *rhs) {
267
356
  for (int i = 0; i < kDegree; i++) {
268
357
  out->c[i] = mod_sub(lhs->c[i], rhs->c[i]);
269
358
  }
270
359
  }
271
360
 
272
- uint32_t reduce_montgomery(uint64_t x) {
361
+ inline uint32_t reduce_montgomery(uint64_t x) {
273
362
  declassify_assert(x <= ((uint64_t)kPrime << 32));
274
363
  uint64_t a = (uint32_t)x * kPrimeNegInverse;
275
364
  uint64_t b = x + a * kPrime;
@@ -278,8 +367,11 @@ uint32_t reduce_montgomery(uint64_t x) {
278
367
  return reduce_once(c);
279
368
  }
280
369
 
281
- // Multiply two scalars in the number theoretically transformed state.
282
- void scalar_mult(scalar *out, const scalar *lhs, const scalar *rhs) {
370
+ // Montgomery-multiply two scalars in the number theoretically transformed
371
+ // state. Each term gains an extra R^-1 term, which is expected to be canceled
372
+ // by `scalar_inverse_ntt_montgomery`.
373
+ inline void scalar_mult_montgomery(scalar *out, const scalar *lhs,
374
+ const scalar *rhs) {
283
375
  for (int i = 0; i < kDegree; i++) {
284
376
  out->c[i] = reduce_montgomery((uint64_t)lhs->c[i] * (uint64_t)rhs->c[i]);
285
377
  }
@@ -288,115 +380,140 @@ void scalar_mult(scalar *out, const scalar *lhs, const scalar *rhs) {
288
380
  // In place number theoretic transform of a given scalar.
289
381
  //
290
382
  // FIPS 204, Algorithm 41 (`NTT`).
291
- static void scalar_ntt(scalar *s) {
292
- // Step: 1, 2, 4, 8, ..., 128
293
- // Offset: 128, 64, 32, 16, ..., 1
294
- int offset = kDegree;
295
- for (int step = 1; step < kDegree; step <<= 1) {
296
- offset >>= 1;
297
- int k = 0;
298
- for (int i = 0; i < step; i++) {
299
- assert(k == 2 * offset * i);
300
- const uint32_t step_root = kNTTRootsMontgomery[step + i];
301
- for (int j = k; j < k + offset; j++) {
302
- uint32_t even = s->c[j];
303
- // |reduce_montgomery| works on values up to kPrime*R and R > 2*kPrime.
304
- // |step_root| < kPrime because it's static data. |s->c[...]| is <
305
- // kPrime by the invariants of that struct.
306
- uint32_t odd =
307
- reduce_montgomery((uint64_t)step_root * (uint64_t)s->c[j + offset]);
308
- s->c[j] = reduce_once(odd + even);
309
- s->c[j + offset] = mod_sub(even, odd);
310
- }
311
- k += 2 * offset;
312
- }
313
- }
314
- }
315
-
316
- // In place inverse number theoretic transform of a given scalar.
383
+ inline void scalar_ntt(scalar *s) {
384
+ // Manually unrolled loop to maximize vectorization.
385
+ #define ITER(step, offset) \
386
+ { \
387
+ int k = 0; \
388
+ for (int i = 0; i < step; i++) { \
389
+ const uint32_t step_root = kNTTRootsMontgomery[step + i]; \
390
+ for (int j = k; j < k + offset; j++) { \
391
+ uint32_t even = s->c[j]; \
392
+ /* `reduce_montgomery` works on values up to kPrime*R and R \
393
+ * 2*kPrime. `step_root` < kPrime because it's static data. \
394
+ * `s->c[...]` is < kPrime by the invariants of that struct. */ \
395
+ uint32_t odd = reduce_montgomery((uint64_t)step_root * \
396
+ (uint64_t)s->c[j + offset]); \
397
+ s->c[j] = reduce_once(odd + even); \
398
+ s->c[j + offset] = mod_sub(even, odd); \
399
+ } \
400
+ k += 2 * offset; \
401
+ } \
402
+ }
403
+
404
+ ITER(1, 128)
405
+ ITER(2, 64)
406
+ ITER(4, 32)
407
+ ITER(8, 16)
408
+ ITER(16, 8)
409
+ ITER(32, 4)
410
+ ITER(64, 2)
411
+ ITER(128, 1)
412
+ static_assert(kDegree == 256);
413
+ #undef ITER
414
+ }
415
+
416
+ // In place inverse number theoretic transform of a given scalar, but with each
417
+ // term multiplied by an extra factor of R. This is function is intended to be
418
+ // used with products that have gone through `reduce_montgomery` one extra time,
419
+ // so the extra R^-1 term is canceled out.
317
420
  //
318
421
  // FIPS 204, Algorithm 42 (`NTT^-1`).
319
- void scalar_inverse_ntt(scalar *s) {
320
- // Step: 128, 64, 32, 16, ..., 1
321
- // Offset: 1, 2, 4, 8, ..., 128
322
- int step = kDegree;
323
- for (int offset = 1; offset < kDegree; offset <<= 1) {
324
- step >>= 1;
325
- int k = 0;
326
- for (int i = 0; i < step; i++) {
327
- assert(k == 2 * offset * i);
328
- const uint32_t step_root =
329
- kPrime - kNTTRootsMontgomery[step + (step - 1 - i)];
330
- for (int j = k; j < k + offset; j++) {
331
- uint32_t even = s->c[j];
332
- uint32_t odd = s->c[j + offset];
333
- s->c[j] = reduce_once(odd + even);
334
-
335
- // |reduce_montgomery| works on values up to kPrime*R and R > 2*kPrime.
336
- // kPrime + even < 2*kPrime because |even| < kPrime, by the invariants
337
- // of that structure. Thus kPrime + even - odd < 2*kPrime because odd >=
338
- // 0, because it's unsigned and less than kPrime. Lastly step_root <
339
- // kPrime, because |kNTTRootsMontgomery| is static data.
340
- s->c[j + offset] = reduce_montgomery((uint64_t)step_root *
341
- (uint64_t)(kPrime + even - odd));
342
- }
343
- k += 2 * offset;
344
- }
345
- }
422
+ inline void scalar_inverse_ntt_montgomery(scalar *s) {
423
+ // Manually unrolled loop to maximize vectorization.
424
+ #define ITER(step, offset) \
425
+ { \
426
+ int k = 0; \
427
+ for (int i = 0; i < step; i++) { \
428
+ const uint32_t step_root = \
429
+ kPrime - kNTTRootsMontgomery[step + (step - 1 - i)]; \
430
+ for (int j = k; j < k + offset; j++) { \
431
+ uint32_t even = s->c[j]; \
432
+ uint32_t odd = s->c[j + offset]; \
433
+ s->c[j] = reduce_once(odd + even); \
434
+ /* `reduce_montgomery` works on values up to kPrime*R and R > \
435
+ * 2*kPrime. kPrime + even < 2*kPrime because `even` < kPrime, by the \
436
+ * invariants of that structure. Thus kPrime + even - odd < 2*kPrime \
437
+ * because odd >= 0, because it's unsigned and less than kPrime. \
438
+ * Lastly step_root < kPrime, because `kNTTRootsMontgomery` is static \
439
+ * data. */ \
440
+ s->c[j + offset] = reduce_montgomery((uint64_t)step_root * \
441
+ (uint64_t)(kPrime + even - odd)); \
442
+ } \
443
+ k += 2 * offset; \
444
+ } \
445
+ }
446
+
447
+ ITER(128, 1)
448
+ ITER(64, 2)
449
+ ITER(32, 4)
450
+ ITER(16, 8)
451
+ ITER(8, 16)
452
+ ITER(4, 32)
453
+ ITER(2, 64)
454
+ ITER(1, 128)
455
+ static_assert(kDegree == 256);
456
+ #undef ITER
457
+
458
+ // `kInverseDegreeDoubleMontgomery` has been double-converted to Montgomery
459
+ // form, so the result is an extra R term in the final result.
346
460
  for (int i = 0; i < kDegree; i++) {
347
- s->c[i] = reduce_montgomery((uint64_t)s->c[i] *
348
- (uint64_t)kInverseDegreeMontgomery);
461
+ s->c[i] = reduce_montgomery(uint64_t{s->c[i]} *
462
+ uint64_t{kInverseDegreeDoubleMontgomery});
349
463
  }
350
464
  }
351
465
 
352
466
  template <int X>
353
- void vector_zero(vector<X> *out) {
467
+ inline void vector_zero(vector<X> *out) {
354
468
  OPENSSL_memset(out, 0, sizeof(*out));
355
469
  }
356
470
 
357
471
  template <int X>
358
- void vector_add(vector<X> *out, const vector<X> *lhs, const vector<X> *rhs) {
472
+ inline void vector_add(vector<X> *out, const vector<X> *lhs,
473
+ const vector<X> *rhs) {
359
474
  for (int i = 0; i < X; i++) {
360
475
  scalar_add(&out->v[i], &lhs->v[i], &rhs->v[i]);
361
476
  }
362
477
  }
363
478
 
364
479
  template <int X>
365
- void vector_sub(vector<X> *out, const vector<X> *lhs, const vector<X> *rhs) {
480
+ inline void vector_sub(vector<X> *out, const vector<X> *lhs,
481
+ const vector<X> *rhs) {
366
482
  for (int i = 0; i < X; i++) {
367
483
  scalar_sub(&out->v[i], &lhs->v[i], &rhs->v[i]);
368
484
  }
369
485
  }
370
486
 
371
487
  template <int X>
372
- void vector_mult_scalar(vector<X> *out, const vector<X> *lhs,
373
- const scalar *rhs) {
488
+ inline void vector_mult_scalar_montgomery(vector<X> *out, const vector<X> *lhs,
489
+ const scalar *rhs) {
374
490
  for (int i = 0; i < X; i++) {
375
- scalar_mult(&out->v[i], &lhs->v[i], rhs);
491
+ scalar_mult_montgomery(&out->v[i], &lhs->v[i], rhs);
376
492
  }
377
493
  }
378
494
 
379
495
  template <int X>
380
- void vector_ntt(vector<X> *a) {
496
+ inline void vector_ntt(vector<X> *a) {
381
497
  for (int i = 0; i < X; i++) {
382
498
  scalar_ntt(&a->v[i]);
383
499
  }
384
500
  }
385
501
 
386
502
  template <int X>
387
- void vector_inverse_ntt(vector<X> *a) {
503
+ inline void vector_inverse_ntt_montgomery(vector<X> *a) {
388
504
  for (int i = 0; i < X; i++) {
389
- scalar_inverse_ntt(&a->v[i]);
505
+ scalar_inverse_ntt_montgomery(&a->v[i]);
390
506
  }
391
507
  }
392
508
 
393
509
  template <int K, int L>
394
- void matrix_mult(vector<K> *out, const matrix<K, L> *m, const vector<L> *a) {
510
+ inline void matrix_mult_montgomery(vector<K> *out, const matrix<K, L> *m,
511
+ const vector<L> *a) {
395
512
  vector_zero(out);
396
513
  for (int i = 0; i < K; i++) {
397
514
  for (int j = 0; j < L; j++) {
398
515
  scalar product;
399
- scalar_mult(&product, &m->v[i][j], &a->v[j]);
516
+ scalar_mult_montgomery(&product, &m->v[i][j], &a->v[j]);
400
517
  scalar_add(&out->v[i], &out->v[i], &product);
401
518
  }
402
519
  }
@@ -405,7 +522,7 @@ void matrix_mult(vector<K> *out, const matrix<K, L> *m, const vector<L> *a) {
405
522
  /* Rounding & hints */
406
523
 
407
524
  // FIPS 204, Algorithm 35 (`Power2Round`).
408
- void power2_round(uint32_t *r1, uint32_t *r0, uint32_t r) {
525
+ inline void power2_round(uint32_t *r1, uint32_t *r0, uint32_t r) {
409
526
  *r1 = r >> kDroppedBits;
410
527
  *r0 = r - (*r1 << kDroppedBits);
411
528
 
@@ -416,13 +533,13 @@ void power2_round(uint32_t *r1, uint32_t *r0, uint32_t r) {
416
533
  crypto_word_t mask =
417
534
  constant_time_lt_w((uint32_t)(1 << (kDroppedBits - 1)), *r0);
418
535
  // r0 = mask ? r0_adjusted : r0
419
- *r0 = constant_time_select_int(mask, r0_adjusted, *r0);
536
+ *r0 = constant_time_select_32(mask, r0_adjusted, *r0);
420
537
  // r1 = mask ? r1_adjusted : r1
421
- *r1 = constant_time_select_int(mask, r1_adjusted, *r1);
538
+ *r1 = constant_time_select_32(mask, r1_adjusted, *r1);
422
539
  }
423
540
 
424
541
  // Scale back previously rounded value.
425
- void scale_power2_round(uint32_t *out, uint32_t r1) {
542
+ inline void scale_power2_round(uint32_t *out, uint32_t r1) {
426
543
  // Pre-condition: 0 <= r1 <= 2^10 - 1
427
544
  assert(r1 < (1u << 10));
428
545
 
@@ -433,42 +550,54 @@ void scale_power2_round(uint32_t *out, uint32_t r1) {
433
550
  }
434
551
 
435
552
  // FIPS 204, Algorithm 37 (`HighBits`).
436
- uint32_t high_bits(uint32_t x) {
553
+ template <int K>
554
+ inline uint32_t high_bits(uint32_t x) {
437
555
  // Reference description (given 0 <= x < q):
438
556
  //
439
557
  // ```
440
- // int32_t r0 = x mod+- (2 * kGamma2);
558
+ // int32_t r0 = x mod+- (2 * gamma2);
441
559
  // if (x - r0 == q - 1) {
442
560
  // return 0;
443
561
  // } else {
444
- // return (x - r0) / (2 * kGamma2);
562
+ // return (x - r0) / (2 * gamma2);
445
563
  // }
446
564
  // ```
447
565
  //
448
- // Below is the formula taken from the reference implementation.
449
- //
450
- // Here, kGamma2 == 2^18 - 2^8
451
- // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4
452
566
  uint32_t r1 = (x + 127) >> 7;
453
- r1 = (r1 * 1025 + (1 << 21)) >> 22;
454
- r1 &= 15;
567
+ if constexpr (prime_minus_one_over_gamma2<K>() == 32) {
568
+ // Below is the formula taken from the reference implementation.
569
+ //
570
+ // Here, Gamma2 == 2^18 - 2^8
571
+ // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4
572
+ r1 = (r1 * 1025 + (1 << 21)) >> 22;
573
+ r1 &= 15;
574
+ } else if constexpr (prime_minus_one_over_gamma2<K>() == 88) {
575
+ // 1488/2^24 is close enough to 1/1488 so that r1 becomes x/(2 gamma2)
576
+ // rounded down.
577
+ r1 = (r1 * 11275 + (1 << 23)) >> 24;
578
+
579
+ // For corner-case r1 = (Q-1)/(2 gamma2) = 44, we have to set r1=0.
580
+ r1 ^= ((uint32_t)(((int32_t)(43 - r1)) >> 31)) & r1;
581
+ }
455
582
  return r1;
456
583
  }
457
584
 
458
585
  // FIPS 204, Algorithm 36 (`Decompose`).
459
- void decompose(uint32_t *r1, int32_t *r0, uint32_t r) {
460
- *r1 = high_bits(r);
586
+ template <int K>
587
+ inline void decompose(uint32_t *r1, int32_t *r0, uint32_t r) {
588
+ *r1 = high_bits<K>(r);
461
589
 
462
590
  *r0 = r;
463
- *r0 -= *r1 * 2 * (int32_t)kGamma2;
591
+ *r0 -= *r1 * 2 * (int32_t)gamma2<K>();
464
592
  *r0 -= (((int32_t)kHalfPrime - *r0) >> 31) & (int32_t)kPrime;
465
593
  }
466
594
 
467
595
  // FIPS 204, Algorithm 38 (`LowBits`).
468
- int32_t low_bits(uint32_t x) {
596
+ template <int K>
597
+ inline int32_t low_bits(uint32_t x) {
469
598
  uint32_t r1;
470
599
  int32_t r0;
471
- decompose(&r1, &r0, x);
600
+ decompose<K>(&r1, &r0, x);
472
601
  return r0;
473
602
  }
474
603
 
@@ -480,110 +609,137 @@ int32_t low_bits(uint32_t x) {
480
609
  //
481
610
  // It then computes HighBits (algorithm 37) of z and z+r. But z+r is just w -
482
611
  // cs2, so this takes three arguments and saves an addition.
483
- int32_t make_hint(uint32_t ct0, uint32_t cs2, uint32_t w) {
612
+ template <int K>
613
+ inline int32_t make_hint(uint32_t ct0, uint32_t cs2, uint32_t w) {
484
614
  uint32_t r_plus_z = mod_sub(w, cs2);
485
615
  uint32_t r = reduce_once(r_plus_z + ct0);
486
- return high_bits(r) != high_bits(r_plus_z);
616
+ return high_bits<K>(r) != high_bits<K>(r_plus_z);
487
617
  }
488
618
 
489
619
  // FIPS 204, Algorithm 40 (`UseHint`).
490
- uint32_t use_hint_vartime(uint32_t h, uint32_t r) {
620
+ template <int K>
621
+ inline uint32_t use_hint_vartime(uint32_t h, uint32_t r) {
491
622
  uint32_t r1;
492
623
  int32_t r0;
493
- decompose(&r1, &r0, r);
624
+ decompose<K>(&r1, &r0, r);
494
625
 
495
626
  if (h) {
496
- if (r0 > 0) {
497
- // m = 16, thus |mod m| in the spec turns into |& 15|.
498
- return (r1 + 1) & 15;
627
+ if constexpr (prime_minus_one_over_gamma2<K>() == 32) {
628
+ if (r0 > 0) {
629
+ // (Q-1)/(2 gamma2) = m = 16, thus `mod m` in the spec turns into
630
+ // `& 15`.
631
+ return (r1 + 1) & 15;
632
+ } else {
633
+ return (r1 - 1) & 15;
634
+ }
499
635
  } else {
500
- return (r1 - 1) & 15;
636
+ // m = 44
637
+ static_assert(prime_minus_one_over_gamma2<K>() == 88);
638
+ if (r0 > 0) {
639
+ if (r1 == 43) {
640
+ return 0;
641
+ } else {
642
+ return r1 + 1;
643
+ }
644
+ } else {
645
+ if (r1 == 0) {
646
+ return 43;
647
+ } else {
648
+ return r1 - 1;
649
+ }
650
+ }
501
651
  }
502
652
  }
503
653
  return r1;
504
654
  }
505
655
 
506
- void scalar_power2_round(scalar *s1, scalar *s0, const scalar *s) {
656
+ inline void scalar_power2_round(scalar *s1, scalar *s0, const scalar *s) {
507
657
  for (int i = 0; i < kDegree; i++) {
508
658
  power2_round(&s1->c[i], &s0->c[i], s->c[i]);
509
659
  }
510
660
  }
511
661
 
512
- void scalar_scale_power2_round(scalar *out, const scalar *in) {
662
+ inline void scalar_scale_power2_round(scalar *out, const scalar *in) {
513
663
  for (int i = 0; i < kDegree; i++) {
514
664
  scale_power2_round(&out->c[i], in->c[i]);
515
665
  }
516
666
  }
517
667
 
518
- void scalar_high_bits(scalar *out, const scalar *in) {
668
+ template <int K>
669
+ inline void scalar_high_bits(scalar *out, const scalar *in) {
519
670
  for (int i = 0; i < kDegree; i++) {
520
- out->c[i] = high_bits(in->c[i]);
671
+ out->c[i] = high_bits<K>(in->c[i]);
521
672
  }
522
673
  }
523
674
 
524
- void scalar_low_bits(scalar *out, const scalar *in) {
675
+ template <int K>
676
+ inline void scalar_low_bits(scalar *out, const scalar *in) {
525
677
  for (int i = 0; i < kDegree; i++) {
526
- out->c[i] = low_bits(in->c[i]);
678
+ out->c[i] = low_bits<K>(in->c[i]);
527
679
  }
528
680
  }
529
681
 
530
- void scalar_max(uint32_t *max, const scalar *s) {
682
+ inline void scalar_max(uint32_t *max, const scalar *s) {
531
683
  for (int i = 0; i < kDegree; i++) {
532
684
  uint32_t abs = abs_mod_prime(s->c[i]);
533
- *max = maximum(*max, abs);
685
+ *max = maximum_reduced(*max, abs);
534
686
  }
535
687
  }
536
688
 
537
- void scalar_max_signed(uint32_t *max, const scalar *s) {
689
+ inline void scalar_max_signed(uint32_t *max, const scalar *s) {
538
690
  for (int i = 0; i < kDegree; i++) {
539
691
  uint32_t abs = abs_signed(s->c[i]);
540
- *max = maximum(*max, abs);
692
+ *max = maximum_reduced(*max, abs);
541
693
  }
542
694
  }
543
695
 
544
- void scalar_make_hint(scalar *out, const scalar *ct0, const scalar *cs2,
545
- const scalar *w) {
696
+ template <int K>
697
+ inline void scalar_make_hint(scalar *out, const scalar *ct0, const scalar *cs2,
698
+ const scalar *w) {
546
699
  for (int i = 0; i < kDegree; i++) {
547
- out->c[i] = make_hint(ct0->c[i], cs2->c[i], w->c[i]);
700
+ out->c[i] = make_hint<K>(ct0->c[i], cs2->c[i], w->c[i]);
548
701
  }
549
702
  }
550
703
 
551
- void scalar_use_hint_vartime(scalar *out, const scalar *h, const scalar *r) {
704
+ template <int K>
705
+ inline void scalar_use_hint_vartime(scalar *out, const scalar *h,
706
+ const scalar *r) {
552
707
  for (int i = 0; i < kDegree; i++) {
553
- out->c[i] = use_hint_vartime(h->c[i], r->c[i]);
708
+ out->c[i] = use_hint_vartime<K>(h->c[i], r->c[i]);
554
709
  }
555
710
  }
556
711
 
557
712
  template <int X>
558
- void vector_power2_round(vector<X> *t1, vector<X> *t0, const vector<X> *t) {
713
+ inline void vector_power2_round(vector<X> *t1, vector<X> *t0,
714
+ const vector<X> *t) {
559
715
  for (int i = 0; i < X; i++) {
560
716
  scalar_power2_round(&t1->v[i], &t0->v[i], &t->v[i]);
561
717
  }
562
718
  }
563
719
 
564
720
  template <int X>
565
- void vector_scale_power2_round(vector<X> *out, const vector<X> *in) {
721
+ inline void vector_scale_power2_round(vector<X> *out, const vector<X> *in) {
566
722
  for (int i = 0; i < X; i++) {
567
723
  scalar_scale_power2_round(&out->v[i], &in->v[i]);
568
724
  }
569
725
  }
570
726
 
571
- template <int X>
572
- void vector_high_bits(vector<X> *out, const vector<X> *in) {
573
- for (int i = 0; i < X; i++) {
574
- scalar_high_bits(&out->v[i], &in->v[i]);
727
+ template <int K>
728
+ inline void vector_high_bits(vector<K> *out, const vector<K> *in) {
729
+ for (int i = 0; i < K; i++) {
730
+ scalar_high_bits<K>(&out->v[i], &in->v[i]);
575
731
  }
576
732
  }
577
733
 
578
- template <int X>
579
- void vector_low_bits(vector<X> *out, const vector<X> *in) {
580
- for (int i = 0; i < X; i++) {
581
- scalar_low_bits(&out->v[i], &in->v[i]);
734
+ template <int K>
735
+ inline void vector_low_bits(vector<K> *out, const vector<K> *in) {
736
+ for (int i = 0; i < K; i++) {
737
+ scalar_low_bits<K>(&out->v[i], &in->v[i]);
582
738
  }
583
739
  }
584
740
 
585
741
  template <int X>
586
- uint32_t vector_max(const vector<X> *a) {
742
+ inline uint32_t vector_max(const vector<X> *a) {
587
743
  uint32_t max = 0;
588
744
  for (int i = 0; i < X; i++) {
589
745
  scalar_max(&max, &a->v[i]);
@@ -592,7 +748,7 @@ uint32_t vector_max(const vector<X> *a) {
592
748
  }
593
749
 
594
750
  template <int X>
595
- uint32_t vector_max_signed(const vector<X> *a) {
751
+ inline uint32_t vector_max_signed(const vector<X> *a) {
596
752
  uint32_t max = 0;
597
753
  for (int i = 0; i < X; i++) {
598
754
  scalar_max_signed(&max, &a->v[i]);
@@ -602,7 +758,7 @@ uint32_t vector_max_signed(const vector<X> *a) {
602
758
 
603
759
  // The input vector contains only zeroes and ones.
604
760
  template <int X>
605
- size_t vector_count_ones(const vector<X> *a) {
761
+ inline size_t vector_count_ones(const vector<X> *a) {
606
762
  size_t count = 0;
607
763
  for (int i = 0; i < X; i++) {
608
764
  for (int j = 0; j < kDegree; j++) {
@@ -612,26 +768,30 @@ size_t vector_count_ones(const vector<X> *a) {
612
768
  return count;
613
769
  }
614
770
 
615
- template <int X>
616
- void vector_make_hint(vector<X> *out, const vector<X> *ct0,
617
- const vector<X> *cs2, const vector<X> *w) {
618
- for (int i = 0; i < X; i++) {
619
- scalar_make_hint(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]);
771
+ template <int K>
772
+ inline void vector_make_hint(vector<K> *out, const vector<K> *ct0,
773
+ const vector<K> *cs2, const vector<K> *w) {
774
+ for (int i = 0; i < K; i++) {
775
+ scalar_make_hint<K>(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]);
620
776
  }
621
777
  }
622
778
 
623
- template <int X>
624
- void vector_use_hint_vartime(vector<X> *out, const vector<X> *h,
625
- const vector<X> *r) {
626
- for (int i = 0; i < X; i++) {
627
- scalar_use_hint_vartime(&out->v[i], &h->v[i], &r->v[i]);
779
+ template <int K>
780
+ inline void vector_use_hint_vartime(vector<K> *out, const vector<K> *h,
781
+ const vector<K> *r) {
782
+ for (int i = 0; i < K; i++) {
783
+ scalar_use_hint_vartime<K>(&out->v[i], &h->v[i], &r->v[i]);
628
784
  }
629
785
  }
630
786
 
631
787
  /* Bit packing */
632
788
 
789
+ template <int bits>
790
+ inline void scalar_encode(uint8_t *out, const scalar *s);
791
+
633
792
  // FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 4.
634
- static void scalar_encode_4(uint8_t out[128], const scalar *s) {
793
+ template <>
794
+ inline void scalar_encode<4>(uint8_t out[128], const scalar *s) {
635
795
  // Every two elements lands on a byte boundary.
636
796
  static_assert(kDegree % 2 == 0, "kDegree must be a multiple of 2");
637
797
  for (int i = 0; i < kDegree / 2; i++) {
@@ -643,8 +803,29 @@ static void scalar_encode_4(uint8_t out[128], const scalar *s) {
643
803
  }
644
804
  }
645
805
 
806
+ // FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 6.
807
+ template <>
808
+ inline void scalar_encode<6>(uint8_t out[192], const scalar *s) {
809
+ // Every four elements lands on a byte boundary.
810
+ static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
811
+ for (int i = 0; i < kDegree / 4; i++) {
812
+ uint32_t a = s->c[4 * i];
813
+ uint32_t b = s->c[4 * i + 1];
814
+ uint32_t c = s->c[4 * i + 2];
815
+ uint32_t d = s->c[4 * i + 3];
816
+ declassify_assert(a < 64);
817
+ declassify_assert(b < 64);
818
+ declassify_assert(c < 64);
819
+ declassify_assert(d < 64);
820
+ out[3 * i] = a | (b << 6);
821
+ out[3 * i + 1] = (b >> 2) | (c << 4);
822
+ out[3 * i + 2] = (c >> 4) | (d << 2);
823
+ }
824
+ }
825
+
646
826
  // FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 10.
647
- void scalar_encode_10(uint8_t out[320], const scalar *s) {
827
+ template <>
828
+ inline void scalar_encode<10>(uint8_t out[320], const scalar *s) {
648
829
  // Every four elements lands on a byte boundary.
649
830
  static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
650
831
  for (int i = 0; i < kDegree / 4; i++) {
@@ -664,8 +845,12 @@ void scalar_encode_10(uint8_t out[320], const scalar *s) {
664
845
  }
665
846
  }
666
847
 
848
+ template <int bits, uint32_t max>
849
+ inline void scalar_encode_signed(uint8_t *out, const scalar *s);
850
+
667
851
  // FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 4 and b = 4.
668
- void scalar_encode_signed_4_4(uint8_t out[128], const scalar *s) {
852
+ template <>
853
+ inline void scalar_encode_signed<4, 4>(uint8_t out[128], const scalar *s) {
669
854
  // Every two elements lands on a byte boundary.
670
855
  static_assert(kDegree % 2 == 0, "kDegree must be a multiple of 2");
671
856
  for (int i = 0; i < kDegree / 2; i++) {
@@ -678,7 +863,8 @@ void scalar_encode_signed_4_4(uint8_t out[128], const scalar *s) {
678
863
  }
679
864
 
680
865
  // FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 3 and b = 2.
681
- static void scalar_encode_signed_3_2(uint8_t out[96], const scalar *s) {
866
+ template <>
867
+ inline void scalar_encode_signed<3, 2>(uint8_t out[96], const scalar *s) {
682
868
  static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8");
683
869
  for (int i = 0; i < kDegree / 8; i++) {
684
870
  uint32_t a = mod_sub(2, s->c[8 * i]);
@@ -699,7 +885,9 @@ static void scalar_encode_signed_3_2(uint8_t out[96], const scalar *s) {
699
885
 
700
886
  // FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 13 and b =
701
887
  // 2^12.
702
- void scalar_encode_signed_13_12(uint8_t out[416], const scalar *s) {
888
+ template <>
889
+ inline void scalar_encode_signed<13, (1u << 12)>(uint8_t out[416],
890
+ const scalar *s) {
703
891
  static const uint32_t kMax = 1u << 12;
704
892
  // Every two elements lands on a byte boundary.
705
893
  static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8");
@@ -730,16 +918,18 @@ void scalar_encode_signed_13_12(uint8_t out[416], const scalar *s) {
730
918
  e |= g << 14;
731
919
  e |= h << 27;
732
920
  h >>= 5;
733
- OPENSSL_memcpy(&out[13 * i], &a, sizeof(a));
734
- OPENSSL_memcpy(&out[13 * i + 4], &c, sizeof(c));
735
- OPENSSL_memcpy(&out[13 * i + 8], &e, sizeof(e));
736
- OPENSSL_memcpy(&out[13 * i + 12], &h, 1);
921
+ CRYPTO_store_u32_le(&out[13 * i], a);
922
+ CRYPTO_store_u32_le(&out[13 * i + 4], c);
923
+ CRYPTO_store_u32_le(&out[13 * i + 8], e);
924
+ out[13 * i + 12] = static_cast<uint8_t>(h);
737
925
  }
738
926
  }
739
927
 
740
928
  // FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 20 and b =
741
929
  // 2^19.
742
- void scalar_encode_signed_20_19(uint8_t out[640], const scalar *s) {
930
+ template <>
931
+ inline void scalar_encode_signed<20, (1u << 19)>(uint8_t out[640],
932
+ const scalar *s) {
743
933
  static const uint32_t kMax = 1u << 19;
744
934
  // Every two elements lands on a byte boundary.
745
935
  static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
@@ -757,37 +947,49 @@ void scalar_encode_signed_20_19(uint8_t out[640], const scalar *s) {
757
947
  b |= c << 8;
758
948
  b |= d << 28;
759
949
  d >>= 4;
760
- OPENSSL_memcpy(&out[10 * i], &a, sizeof(a));
761
- OPENSSL_memcpy(&out[10 * i + 4], &b, sizeof(b));
762
- OPENSSL_memcpy(&out[10 * i + 8], &d, 2);
950
+ CRYPTO_store_u32_le(&out[10 * i], a);
951
+ CRYPTO_store_u32_le(&out[10 * i + 4], b);
952
+ CRYPTO_store_u16_le(&out[10 * i + 8], static_cast<uint16_t>(d));
763
953
  }
764
954
  }
765
955
 
766
- // FIPS 204, Algorithm 17 (`BitPack`).
767
- void scalar_encode_signed(uint8_t *out, const scalar *s, int bits,
768
- uint32_t max) {
769
- if (bits == 3) {
770
- assert(max == 2);
771
- scalar_encode_signed_3_2(out, s);
772
- } else if (bits == 4) {
773
- assert(max == 4);
774
- scalar_encode_signed_4_4(out, s);
775
- } else if (bits == 20) {
776
- assert(max == 1u << 19);
777
- scalar_encode_signed_20_19(out, s);
778
- } else {
779
- assert(bits == 13);
780
- assert(max == 1u << 12);
781
- scalar_encode_signed_13_12(out, s);
956
+ // FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 18 and b =
957
+ // 2^17.
958
+ template <>
959
+ inline void scalar_encode_signed<18, (1u << 17)>(uint8_t out[576],
960
+ const scalar *s) {
961
+ static const uint32_t kMax = 1u << 17;
962
+ static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
963
+ for (int i = 0; i < kDegree / 4; i++) {
964
+ uint32_t a = mod_sub(kMax, s->c[4 * i]);
965
+ uint32_t b = mod_sub(kMax, s->c[4 * i + 1]);
966
+ uint32_t c = mod_sub(kMax, s->c[4 * i + 2]);
967
+ uint32_t d = mod_sub(kMax, s->c[4 * i + 3]);
968
+ declassify_assert(a < (1u << 18));
969
+ declassify_assert(b < (1u << 18));
970
+ declassify_assert(c < (1u << 18));
971
+ declassify_assert(d < (1u << 18));
972
+ out[9 * i] = (uint8_t)a;
973
+ out[9 * i + 1] = (uint8_t)(a >> 8);
974
+ out[9 * i + 2] = (uint8_t)(a >> 16) | (uint8_t)(b << 2);
975
+ out[9 * i + 3] = (uint8_t)(b >> 6);
976
+ out[9 * i + 4] = (uint8_t)(b >> 14) | (uint8_t)(c << 4);
977
+ out[9 * i + 5] = (uint8_t)(c >> 4);
978
+ out[9 * i + 6] = (uint8_t)(c >> 12) | (uint8_t)(d << 6);
979
+ out[9 * i + 7] = (uint8_t)(d >> 2);
980
+ out[9 * i + 8] = (uint8_t)(d >> 10);
782
981
  }
783
982
  }
784
983
 
984
+ template <int bits>
985
+ inline void scalar_decode(scalar *out, const uint8_t *in);
986
+
785
987
  // FIPS 204, Algorithm 18 (`SimpleBitUnpack`). Specialized for bitlen(b) == 10.
786
- void scalar_decode_10(scalar *out, const uint8_t in[320]) {
787
- uint32_t v;
988
+ template <>
989
+ inline void scalar_decode<10>(scalar *out, const uint8_t in[320]) {
788
990
  static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
789
991
  for (int i = 0; i < kDegree / 4; i++) {
790
- OPENSSL_memcpy(&v, &in[5 * i], sizeof(v));
992
+ uint32_t v = CRYPTO_load_u32_le(&in[5 * i]);
791
993
  out->c[4 * i] = v & 0x3ff;
792
994
  out->c[4 * i + 1] = (v >> 10) & 0x3ff;
793
995
  out->c[4 * i + 2] = (v >> 20) & 0x3ff;
@@ -795,13 +997,16 @@ void scalar_decode_10(scalar *out, const uint8_t in[320]) {
795
997
  }
796
998
  }
797
999
 
1000
+ template <int bits, uint32_t max>
1001
+ inline int scalar_decode_signed(scalar *out, const uint8_t *in);
1002
+
798
1003
  // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 4 and b =
799
1004
  // 4.
800
- int scalar_decode_signed_4_4(scalar *out, const uint8_t in[128]) {
801
- uint32_t v;
1005
+ template <>
1006
+ inline int scalar_decode_signed<4, 4>(scalar *out, const uint8_t in[128]) {
802
1007
  static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8");
803
1008
  for (int i = 0; i < kDegree / 8; i++) {
804
- OPENSSL_memcpy(&v, &in[4 * i], sizeof(v));
1009
+ uint32_t v = CRYPTO_load_u32_le(&in[4 * i]);
805
1010
  // None of the nibbles may be >= 9. So if the MSB of any nibble is set, none
806
1011
  // of the other bits may be set. First, select all the MSBs.
807
1012
  const uint32_t msbs = v & 0x88888888u;
@@ -827,7 +1032,8 @@ int scalar_decode_signed_4_4(scalar *out, const uint8_t in[128]) {
827
1032
 
828
1033
  // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 3 and b =
829
1034
  // 2.
830
- static int scalar_decode_signed_3_2(scalar *out, const uint8_t in[96]) {
1035
+ template <>
1036
+ inline int scalar_decode_signed<3, 2>(scalar *out, const uint8_t in[96]) {
831
1037
  uint32_t v;
832
1038
  uint8_t v_bytes[sizeof(v)] = {0};
833
1039
  static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8");
@@ -860,19 +1066,19 @@ static int scalar_decode_signed_3_2(scalar *out, const uint8_t in[96]) {
860
1066
 
861
1067
  // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 13 and b =
862
1068
  // 2^12.
863
- void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) {
1069
+ template <>
1070
+ inline int scalar_decode_signed<13, (1u << 12)>(scalar *out,
1071
+ const uint8_t in[416]) {
864
1072
  static const uint32_t kMax = 1u << 12;
865
1073
  static const uint32_t k13Bits = (1u << 13) - 1;
866
1074
  static const uint32_t k7Bits = (1u << 7) - 1;
867
1075
 
868
- uint32_t a, b, c;
869
- uint8_t d;
870
1076
  static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8");
871
1077
  for (int i = 0; i < kDegree / 8; i++) {
872
- OPENSSL_memcpy(&a, &in[13 * i], sizeof(a));
873
- OPENSSL_memcpy(&b, &in[13 * i + 4], sizeof(b));
874
- OPENSSL_memcpy(&c, &in[13 * i + 8], sizeof(c));
875
- d = in[13 * i + 12];
1078
+ uint32_t a = CRYPTO_load_u32_le(&in[13 * i]);
1079
+ uint32_t b = CRYPTO_load_u32_le(&in[13 * i + 4]);
1080
+ uint32_t c = CRYPTO_load_u32_le(&in[13 * i + 8]);
1081
+ uint8_t d = in[13 * i + 12];
876
1082
 
877
1083
  // It's not possible for a 13-bit number to be out of range when the max is
878
1084
  // 2^12.
@@ -885,21 +1091,51 @@ void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) {
885
1091
  out->c[i * 8 + 6] = mod_sub(kMax, (c >> 14) & k13Bits);
886
1092
  out->c[i * 8 + 7] = mod_sub(kMax, (c >> 27) | ((uint32_t)d) << 5);
887
1093
  }
1094
+ return 1;
1095
+ }
1096
+
1097
+ // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 18 and b =
1098
+ // 2^17.
1099
+ template <>
1100
+ inline int scalar_decode_signed<18, (1u << 17)>(scalar *out,
1101
+ const uint8_t in[576]) {
1102
+ static const uint32_t kMax = 1u << 17;
1103
+
1104
+ static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
1105
+ for (int i = 0; i < kDegree / 4; i++) {
1106
+ uint32_t a = uint32_t{in[9 * i]} | (uint32_t{in[9 * i + 1]} << 8) |
1107
+ ((uint32_t{in[9 * i + 2]} & 0x3) << 16);
1108
+ uint32_t b = (uint32_t{in[9 * i + 2]} >> 2) |
1109
+ (uint32_t{in[9 * i + 3]} << 6) |
1110
+ ((uint32_t{in[9 * i + 4]} & 0xf) << 14);
1111
+ uint32_t c = (uint32_t{in[9 * i + 4]} >> 4) |
1112
+ (uint32_t{in[9 * i + 5]} << 4) |
1113
+ ((uint32_t{in[9 * i + 6]} & 0x3f) << 12);
1114
+ uint32_t d = (uint32_t{in[9 * i + 6]} >> 6) |
1115
+ (uint32_t{in[9 * i + 7]} << 2) |
1116
+ (uint32_t{in[9 * i + 8]} << 10);
1117
+
1118
+ out->c[i * 4] = mod_sub(kMax, a);
1119
+ out->c[i * 4 + 1] = mod_sub(kMax, b);
1120
+ out->c[i * 4 + 2] = mod_sub(kMax, c);
1121
+ out->c[i * 4 + 3] = mod_sub(kMax, d);
1122
+ }
1123
+ return 1;
888
1124
  }
889
1125
 
890
1126
  // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 20 and b =
891
1127
  // 2^19.
892
- void scalar_decode_signed_20_19(scalar *out, const uint8_t in[640]) {
1128
+ template <>
1129
+ inline int scalar_decode_signed<20, (1u << 19)>(scalar *out,
1130
+ const uint8_t in[640]) {
893
1131
  static const uint32_t kMax = 1u << 19;
894
1132
  static const uint32_t k20Bits = (1u << 20) - 1;
895
1133
 
896
- uint32_t a, b;
897
- uint16_t c;
898
1134
  static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4");
899
1135
  for (int i = 0; i < kDegree / 4; i++) {
900
- OPENSSL_memcpy(&a, &in[10 * i], sizeof(a));
901
- OPENSSL_memcpy(&b, &in[10 * i + 4], sizeof(b));
902
- OPENSSL_memcpy(&c, &in[10 * i + 8], sizeof(c));
1136
+ uint32_t a = CRYPTO_load_u32_le(&in[10 * i]);
1137
+ uint32_t b = CRYPTO_load_u32_le(&in[10 * i + 4]);
1138
+ uint16_t c = CRYPTO_load_u16_le(&in[10 * i + 8]);
903
1139
 
904
1140
  // It's not possible for a 20-bit number to be out of range when the max is
905
1141
  // 2^19.
@@ -908,29 +1144,10 @@ void scalar_decode_signed_20_19(scalar *out, const uint8_t in[640]) {
908
1144
  out->c[i * 4 + 2] = mod_sub(kMax, (b >> 8) & k20Bits);
909
1145
  out->c[i * 4 + 3] = mod_sub(kMax, (b >> 28) | ((uint32_t)c) << 4);
910
1146
  }
1147
+ return 1;
911
1148
  }
912
1149
 
913
- // FIPS 204, Algorithm 19 (`BitUnpack`).
914
- int scalar_decode_signed(scalar *out, const uint8_t *in, int bits,
915
- uint32_t max) {
916
- if (bits == 3) {
917
- assert(max == 2);
918
- return scalar_decode_signed_3_2(out, in);
919
- } else if (bits == 4) {
920
- assert(max == 4);
921
- return scalar_decode_signed_4_4(out, in);
922
- } else if (bits == 13) {
923
- assert(max == (1u << 12));
924
- scalar_decode_signed_13_12(out, in);
925
- return 1;
926
- } else if (bits == 20) {
927
- assert(max == (1u << 19));
928
- scalar_decode_signed_20_19(out, in);
929
- return 1;
930
- } else {
931
- abort();
932
- }
933
- }
1150
+
934
1151
 
935
1152
  /* Expansion functions */
936
1153
 
@@ -938,97 +1155,159 @@ int scalar_decode_signed(scalar *out, const uint8_t *in, int bits,
938
1155
  //
939
1156
  // Rejection samples a Keccak stream to get uniformly distributed elements. This
940
1157
  // is used for matrix expansion and only operates on public inputs.
941
- void scalar_from_keccak_vartime(scalar *out,
942
- const uint8_t derived_seed[kRhoBytes + 2]) {
943
- struct BORINGSSL_keccak_st keccak_ctx;
944
- BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake128);
945
- BORINGSSL_keccak_absorb(&keccak_ctx, derived_seed, kRhoBytes + 2);
946
- assert(keccak_ctx.squeeze_offset == 0);
947
- assert(keccak_ctx.rate_bytes == 168);
1158
+ inline void scalar_from_keccak_block_vartime(scalar *out, int *done,
1159
+ const uint8_t block[168]) {
1160
+ for (size_t i = 0; i < 168 && *done < kDegree; i += 3) {
1161
+ // FIPS 204, Algorithm 14 (`CoeffFromThreeBytes`).
1162
+ uint32_t value = (uint32_t)block[i] | ((uint32_t)block[i + 1] << 8) |
1163
+ (((uint32_t)block[i + 2] & 0x7f) << 16);
1164
+ if (value < kPrime) {
1165
+ out->c[(*done)++] = value;
1166
+ }
1167
+ }
1168
+ }
1169
+
1170
+ // FIPS 204, Algorithm 30 (`RejNTTPoly`).
1171
+ //
1172
+ // Rejection samples a Keccak stream to get uniformly distributed elements. This
1173
+ // is used for matrix expansion and only operates on public inputs.
1174
+ inline void scalar_from_keccak_vartime(scalar *out,
1175
+ BORINGSSL_keccak_st *keccak_ctx) {
1176
+ assert(keccak_ctx->squeeze_offset == 0);
1177
+ assert(keccak_ctx->rate_bytes == 168);
948
1178
  static_assert(168 % 3 == 0, "block and coefficient boundaries do not align");
949
1179
 
950
1180
  int done = 0;
951
1181
  while (done < kDegree) {
952
1182
  uint8_t block[168];
953
- BORINGSSL_keccak_squeeze(&keccak_ctx, block, sizeof(block));
954
- for (size_t i = 0; i < sizeof(block) && done < kDegree; i += 3) {
955
- // FIPS 204, Algorithm 14 (`CoeffFromThreeBytes`).
956
- uint32_t value = (uint32_t)block[i] | ((uint32_t)block[i + 1] << 8) |
957
- (((uint32_t)block[i + 2] & 0x7f) << 16);
958
- if (value < kPrime) {
959
- out->c[done++] = value;
960
- }
961
- }
1183
+ BORINGSSL_keccak_squeeze(keccak_ctx, block, sizeof(block));
1184
+ scalar_from_keccak_block_vartime(out, &done, block);
1185
+ }
1186
+ }
1187
+
1188
+ #if defined(HAVE_KECCAK_X2)
1189
+ inline void scalar_from_keccak_vartime_x2(scalar *out[2],
1190
+ BORINGSSL_keccak_st keccak_ctx[2]) {
1191
+ assert(keccak_ctx[0].squeeze_offset == 0);
1192
+ assert(keccak_ctx[0].rate_bytes == 168);
1193
+ assert(keccak_ctx[1].squeeze_offset == 0);
1194
+ assert(keccak_ctx[1].rate_bytes == 168);
1195
+ static_assert(168 % 3 == 0, "block and coefficient boundaries do not align");
1196
+
1197
+ int done[2] = {0, 0};
1198
+ while (done[0] < kDegree || done[1] < kDegree) {
1199
+ uint8_t block[2][168];
1200
+ uint8_t *blocks[] = {block[0], block[1]};
1201
+ BORINGSSL_keccak_squeeze_x2(keccak_ctx, blocks, sizeof(block[0]));
1202
+ scalar_from_keccak_block_vartime(out[0], &done[0], block[0]);
1203
+ scalar_from_keccak_block_vartime(out[1], &done[1], block[1]);
962
1204
  }
963
1205
  }
1206
+ #endif
964
1207
 
965
1208
  template <int ETA>
966
- static bool coefficient_from_nibble(uint32_t nibble, uint32_t *result);
1209
+ inline bool coefficient_from_nibble(uint32_t nibble, uint32_t *result);
967
1210
 
968
1211
  template <>
969
- bool coefficient_from_nibble<4>(uint32_t nibble, uint32_t *result) {
1212
+ inline bool coefficient_from_nibble<4>(uint32_t nibble, uint32_t *result) {
970
1213
  if (constant_time_declassify_int(nibble < 9)) {
971
- *result = mod_sub(4, nibble);
1214
+ // Knowing bounds on `nibble` seems to tempt some versions of Clang to emit
1215
+ // a branch, if we don't have a barrier in `mod_sub`.
1216
+ *result = mod_sub(4, value_barrier_u32(nibble));
972
1217
  return true;
973
1218
  }
974
1219
  return false;
975
1220
  }
976
1221
 
977
1222
  template <>
978
- bool coefficient_from_nibble<2>(uint32_t nibble, uint32_t *result) {
1223
+ inline bool coefficient_from_nibble<2>(uint32_t nibble, uint32_t *result) {
979
1224
  if (constant_time_declassify_int(nibble < 15)) {
980
- *result = mod_sub(2, nibble % 5);
1225
+ // Knowing bounds on `nibble` seems to tempt some versions of Clang to emit
1226
+ // a branch, if we don't have a barrier in `mod_sub`.
1227
+ // Constant time "nibble % 5".
1228
+ nibble = nibble - 5 * ((205 * nibble) >> 10);
1229
+ *result = mod_sub(2, value_barrier_u32(nibble));
981
1230
  return true;
982
1231
  }
983
1232
  return false;
984
1233
  }
985
1234
 
1235
+ template <int ETA>
1236
+ inline void scalar_uniform_block(scalar *out, int *done,
1237
+ const uint8_t block[136]) {
1238
+ for (size_t i = 0; i < 136 && *done < kDegree; ++i) {
1239
+ uint32_t t0 = block[i] & 0x0F;
1240
+ uint32_t t1 = block[i] >> 4;
1241
+ // FIPS 204, Algorithm 15 (`CoefFromHalfByte`). Although both the input
1242
+ // and output here are secret, it is OK to leak when we rejected a byte.
1243
+ // Individual bytes of the SHAKE-256 stream are (indistinguishable from)
1244
+ // independent of each other and the original seed, so leaking information
1245
+ // about the rejected bytes does not reveal the input or output.
1246
+ uint32_t v;
1247
+ if (coefficient_from_nibble<ETA>(t0, &v)) {
1248
+ out->c[(*done)++] = v;
1249
+ }
1250
+ if (*done < kDegree && coefficient_from_nibble<ETA>(t1, &v)) {
1251
+ out->c[(*done)++] = v;
1252
+ }
1253
+ }
1254
+ }
1255
+
986
1256
  // FIPS 204, Algorithm 31 (`RejBoundedPoly`).
987
1257
  template <int ETA>
988
- void scalar_uniform(scalar *out, const uint8_t derived_seed[kSigmaBytes + 2]) {
989
- struct BORINGSSL_keccak_st keccak_ctx;
990
- BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
991
- BORINGSSL_keccak_absorb(&keccak_ctx, derived_seed, kSigmaBytes + 2);
992
- assert(keccak_ctx.squeeze_offset == 0);
993
- assert(keccak_ctx.rate_bytes == 136);
1258
+ inline void scalar_uniform(scalar *out, BORINGSSL_keccak_st *keccak_ctx) {
1259
+ assert(keccak_ctx->squeeze_offset == 0);
1260
+ assert(keccak_ctx->rate_bytes == 136);
994
1261
 
995
1262
  int done = 0;
996
1263
  while (done < kDegree) {
997
1264
  uint8_t block[136];
998
- BORINGSSL_keccak_squeeze(&keccak_ctx, block, sizeof(block));
999
- for (size_t i = 0; i < sizeof(block) && done < kDegree; ++i) {
1000
- uint32_t t0 = block[i] & 0x0F;
1001
- uint32_t t1 = block[i] >> 4;
1002
- // FIPS 204, Algorithm 15 (`CoefFromHalfByte`). Although both the input
1003
- // and output here are secret, it is OK to leak when we rejected a byte.
1004
- // Individual bytes of the SHAKE-256 stream are (indistiguishable from)
1005
- // independent of each other and the original seed, so leaking information
1006
- // about the rejected bytes does not reveal the input or output.
1007
- uint32_t v;
1008
- if (coefficient_from_nibble<ETA>(t0, &v)) {
1009
- out->c[done++] = v;
1010
- }
1011
- if (done < kDegree && coefficient_from_nibble<ETA>(t1, &v)) {
1012
- out->c[done++] = v;
1013
- }
1014
- }
1265
+ BORINGSSL_keccak_squeeze(keccak_ctx, block, sizeof(block));
1266
+ scalar_uniform_block<ETA>(out, &done, block);
1015
1267
  }
1016
1268
  }
1017
1269
 
1018
- // FIPS 204, Algorithm 34 (`ExpandMask`), but just a single step.
1019
- void scalar_sample_mask(scalar *out,
1020
- const uint8_t derived_seed[kRhoPrimeBytes + 2]) {
1021
- uint8_t buf[640];
1022
- BORINGSSL_keccak(buf, sizeof(buf), derived_seed, kRhoPrimeBytes + 2,
1023
- boringssl_shake256);
1270
+ #if defined(HAVE_KECCAK_X2)
1271
+ template <int ETA>
1272
+ inline void scalar_uniform_x2(scalar *out[2],
1273
+ BORINGSSL_keccak_st keccak_ctx[2]) {
1274
+ assert(keccak_ctx[0].squeeze_offset == 0);
1275
+ assert(keccak_ctx[0].rate_bytes == 136);
1276
+ assert(keccak_ctx[1].squeeze_offset == 0);
1277
+ assert(keccak_ctx[1].rate_bytes == 136);
1278
+
1279
+ int done[2] = {0, 0};
1280
+ while (done[0] < kDegree || done[1] < kDegree) {
1281
+ uint8_t block[2][136];
1282
+ uint8_t *blocks[] = {block[0], block[1]};
1283
+ BORINGSSL_keccak_squeeze_x2(keccak_ctx, blocks, sizeof(block[0]));
1284
+ scalar_uniform_block<ETA>(out[0], &done[0], block[0]);
1285
+ scalar_uniform_block<ETA>(out[1], &done[1], block[1]);
1286
+ }
1287
+ }
1288
+ #endif
1024
1289
 
1025
- scalar_decode_signed_20_19(out, buf);
1290
+ // FIPS 204, Algorithm 34 (`ExpandMask`), but just a single step.
1291
+ template <int K>
1292
+ inline void scalar_sample_mask(scalar *out,
1293
+ const uint8_t rho_prime[kRhoPrimeBytes],
1294
+ size_t index) {
1295
+ uint8_t buf[scalar_le_gamma1_bytes<K>()];
1296
+ struct BORINGSSL_keccak_st ctx;
1297
+ BORINGSSL_keccak_init(&ctx, boringssl_shake256);
1298
+ BORINGSSL_keccak_absorb(&ctx, rho_prime, kRhoPrimeBytes);
1299
+ uint8_t index_buf[2];
1300
+ index_buf[0] = static_cast<uint8_t>(index);
1301
+ index_buf[1] = static_cast<uint8_t>(index >> 8);
1302
+ BORINGSSL_keccak_absorb(&ctx, index_buf, 2);
1303
+ BORINGSSL_keccak_squeeze(&ctx, buf, sizeof(buf));
1304
+ scalar_decode_signed<gamma1_bits<K>() + 1, gamma1<K>()>(out, buf);
1026
1305
  }
1027
1306
 
1028
1307
  // FIPS 204, Algorithm 29 (`SampleInBall`).
1029
- void scalar_sample_in_ball_vartime(scalar *out, const uint8_t *seed, int len,
1030
- int tau) {
1031
- struct BORINGSSL_keccak_st keccak_ctx;
1308
+ inline void scalar_sample_in_ball_vartime(scalar *out, const uint8_t *seed,
1309
+ int len, int tau) {
1310
+ BORINGSSL_keccak_st keccak_ctx;
1032
1311
  BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1033
1312
  BORINGSSL_keccak_absorb(&keccak_ctx, seed, len);
1034
1313
  assert(keccak_ctx.squeeze_offset == 0);
@@ -1068,58 +1347,135 @@ void scalar_sample_in_ball_vartime(scalar *out, const uint8_t *seed, int len,
1068
1347
  }
1069
1348
  }
1070
1349
 
1071
- // FIPS 204, Algorithm 32 (`ExpandA`).
1072
1350
  template <int K, int L>
1073
- void matrix_expand(matrix<K, L> *out, const uint8_t rho[kRhoBytes]) {
1351
+ inline void matrix_expand_step(scalar *out, const uint8_t rho[kRhoBytes],
1352
+ int index) {
1353
+ BORINGSSL_keccak_st keccak_ctx;
1354
+ BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake128);
1355
+ BORINGSSL_keccak_absorb(&keccak_ctx, rho, kRhoBytes);
1356
+ uint8_t index_buf[2];
1357
+ index_buf[0] = static_cast<uint8_t>(index % L);
1358
+ index_buf[1] = static_cast<uint8_t>(index / L);
1359
+ BORINGSSL_keccak_absorb(&keccak_ctx, index_buf, 2);
1360
+ scalar_from_keccak_vartime(out, &keccak_ctx);
1361
+ }
1362
+
1363
+ #if defined(HAVE_KECCAK_X2)
1364
+ template <int K, int L>
1365
+ inline void matrix_expand_step_x2(matrix<K, L> *out,
1366
+ const uint8_t rho[kRhoBytes], int index) {
1367
+ BORINGSSL_keccak_st keccak_ctx[2];
1368
+ BORINGSSL_keccak_init(&keccak_ctx[0], boringssl_shake128);
1369
+ BORINGSSL_keccak_init(&keccak_ctx[1], boringssl_shake128);
1370
+ BORINGSSL_keccak_absorb(&keccak_ctx[0], rho, kRhoBytes);
1371
+ BORINGSSL_keccak_absorb(&keccak_ctx[1], rho, kRhoBytes);
1372
+ uint8_t index_buf[2];
1373
+ index_buf[0] = static_cast<uint8_t>(index % L);
1374
+ index_buf[1] = static_cast<uint8_t>(index / L);
1375
+ BORINGSSL_keccak_absorb(&keccak_ctx[0], index_buf, 2);
1376
+ index_buf[0] = static_cast<uint8_t>((index + 1) % L);
1377
+ index_buf[1] = static_cast<uint8_t>((index + 1) / L);
1378
+ BORINGSSL_keccak_absorb(&keccak_ctx[1], index_buf, 2);
1379
+
1380
+ scalar *outs[] = {&out->v[index / L][index % L],
1381
+ &out->v[(index + 1) / L][(index + 1) % L]};
1382
+ scalar_from_keccak_vartime_x2(outs, keccak_ctx);
1383
+ }
1384
+ #endif
1385
+
1386
+ template <int K, int L>
1387
+ inline void matrix_expand(matrix<K, L> *out, const uint8_t rho[kRhoBytes]) {
1074
1388
  static_assert(K <= 0x100, "K must fit in 8 bits");
1075
1389
  static_assert(L <= 0x100, "L must fit in 8 bits");
1076
1390
 
1077
- uint8_t derived_seed[kRhoBytes + 2];
1078
- OPENSSL_memcpy(derived_seed, rho, kRhoBytes);
1079
- for (int i = 0; i < K; i++) {
1080
- for (int j = 0; j < L; j++) {
1081
- derived_seed[kRhoBytes + 1] = (uint8_t)i;
1082
- derived_seed[kRhoBytes] = (uint8_t)j;
1083
- scalar_from_keccak_vartime(&out->v[i][j], derived_seed);
1084
- }
1391
+ int index = 0;
1392
+ #if defined(HAVE_KECCAK_X2)
1393
+ for (; index + 2 <= K * L; index += 2) {
1394
+ matrix_expand_step_x2(out, rho, index);
1085
1395
  }
1396
+ #endif
1397
+
1398
+ for (; index < K * L; index++) {
1399
+ matrix_expand_step<K, L>(&out->v[index / L][index % L], rho, index);
1400
+ }
1401
+ }
1402
+
1403
+ template <int K>
1404
+ inline void vector_expand_short_step(scalar *out,
1405
+ const uint8_t sigma[kSigmaBytes],
1406
+ int index) {
1407
+ BORINGSSL_keccak_st keccak_ctx;
1408
+ BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1409
+ BORINGSSL_keccak_absorb(&keccak_ctx, sigma, kSigmaBytes);
1410
+ uint8_t index_buf[2];
1411
+ index_buf[0] = static_cast<uint8_t>(index);
1412
+ index_buf[1] = 0;
1413
+ BORINGSSL_keccak_absorb(&keccak_ctx, index_buf, 2);
1414
+ scalar_uniform<eta<K>()>(out, &keccak_ctx);
1415
+ }
1416
+
1417
+ #if defined(HAVE_KECCAK_X2)
1418
+ template <int K>
1419
+ inline void vector_expand_short_step_x2(scalar *out0, scalar *out1,
1420
+ const uint8_t sigma[kSigmaBytes],
1421
+ int index) {
1422
+ BORINGSSL_keccak_st keccak_ctx[2];
1423
+ BORINGSSL_keccak_init(&keccak_ctx[0], boringssl_shake256);
1424
+ BORINGSSL_keccak_init(&keccak_ctx[1], boringssl_shake256);
1425
+ BORINGSSL_keccak_absorb(&keccak_ctx[0], sigma, kSigmaBytes);
1426
+ BORINGSSL_keccak_absorb(&keccak_ctx[1], sigma, kSigmaBytes);
1427
+ uint8_t index_buf[2];
1428
+ index_buf[0] = static_cast<uint8_t>(index);
1429
+ index_buf[1] = 0;
1430
+ BORINGSSL_keccak_absorb(&keccak_ctx[0], index_buf, 2);
1431
+ index_buf[0] = static_cast<uint8_t>(index + 1);
1432
+ index_buf[1] = 0;
1433
+ BORINGSSL_keccak_absorb(&keccak_ctx[1], index_buf, 2);
1434
+
1435
+ scalar *outs[] = {out0, out1};
1436
+ scalar_uniform_x2<eta<K>()>(outs, keccak_ctx);
1086
1437
  }
1438
+ #endif
1087
1439
 
1088
1440
  // FIPS 204, Algorithm 33 (`ExpandS`).
1089
1441
  template <int K, int L>
1090
- void vector_expand_short(vector<L> *s1, vector<K> *s2,
1091
- const uint8_t sigma[kSigmaBytes]) {
1442
+ inline void vector_expand_short(vector<L> *s1, vector<K> *s2,
1443
+ const uint8_t sigma[kSigmaBytes]) {
1092
1444
  static_assert(K <= 0x100, "K must fit in 8 bits");
1093
1445
  static_assert(L <= 0x100, "L must fit in 8 bits");
1094
1446
  static_assert(K + L <= 0x100, "K+L must fit in 8 bits");
1095
1447
 
1096
- uint8_t derived_seed[kSigmaBytes + 2];
1097
- OPENSSL_memcpy(derived_seed, sigma, kSigmaBytes);
1098
- derived_seed[kSigmaBytes] = 0;
1099
- derived_seed[kSigmaBytes + 1] = 0;
1448
+ scalar *all_scalars[K + L];
1100
1449
  for (int i = 0; i < L; i++) {
1101
- scalar_uniform<eta<K>()>(&s1->v[i], derived_seed);
1102
- ++derived_seed[kSigmaBytes];
1450
+ all_scalars[i] = &s1->v[i];
1103
1451
  }
1104
1452
  for (int i = 0; i < K; i++) {
1105
- scalar_uniform<eta<K>()>(&s2->v[i], derived_seed);
1106
- ++derived_seed[kSigmaBytes];
1453
+ all_scalars[L + i] = &s2->v[i];
1454
+ }
1455
+
1456
+ int index = 0;
1457
+ #if defined(HAVE_KECCAK_X2)
1458
+ for (; index + 2 <= K + L; index += 2) {
1459
+ vector_expand_short_step_x2<K>(all_scalars[index], all_scalars[index + 1],
1460
+ sigma, index);
1461
+ }
1462
+ #endif
1463
+
1464
+ for (; index < K + L; index++) {
1465
+ vector_expand_short_step<K>(all_scalars[index], sigma, index);
1107
1466
  }
1108
1467
  }
1109
1468
 
1110
1469
  // FIPS 204, Algorithm 34 (`ExpandMask`).
1111
- template <int L>
1112
- void vector_expand_mask(vector<L> *out, const uint8_t seed[kRhoPrimeBytes],
1113
- size_t kappa) {
1470
+ template <int K, int L>
1471
+ inline void vector_expand_mask(vector<L> *out,
1472
+ const uint8_t rho_prime[kRhoPrimeBytes],
1473
+ size_t kappa) {
1114
1474
  assert(kappa + L <= 0x10000);
1115
1475
 
1116
- uint8_t derived_seed[kRhoPrimeBytes + 2];
1117
- OPENSSL_memcpy(derived_seed, seed, kRhoPrimeBytes);
1118
1476
  for (int i = 0; i < L; i++) {
1119
1477
  size_t index = kappa + i;
1120
- derived_seed[kRhoPrimeBytes] = index & 0xFF;
1121
- derived_seed[kRhoPrimeBytes + 1] = (index >> 8) & 0xFF;
1122
- scalar_sample_mask(&out->v[i], derived_seed);
1478
+ scalar_sample_mask<K>(&out->v[i], rho_prime, index);
1123
1479
  }
1124
1480
  }
1125
1481
 
@@ -1127,50 +1483,60 @@ void vector_expand_mask(vector<L> *out, const uint8_t seed[kRhoPrimeBytes],
1127
1483
 
1128
1484
  // FIPS 204, Algorithm 16 (`SimpleBitPack`).
1129
1485
  //
1130
- // Encodes an entire vector into 32*K*|bits| bytes. Note that since 256
1486
+ // Encodes an entire vector into 32*K*`bits` bytes. Note that since 256
1131
1487
  // (kDegree) is divisible by 8, the individual vector entries will always fill a
1132
1488
  // whole number of bytes, so we do not need to worry about bit packing here.
1133
- template <int K>
1134
- void vector_encode(uint8_t *out, const vector<K> *a, int bits) {
1135
- if (bits == 4) {
1136
- for (int i = 0; i < K; i++) {
1137
- scalar_encode_4(out + i * bits * kDegree / 8, &a->v[i]);
1138
- }
1139
- } else {
1140
- assert(bits == 10);
1141
- for (int i = 0; i < K; i++) {
1142
- scalar_encode_10(out + i * bits * kDegree / 8, &a->v[i]);
1143
- }
1489
+ template <int bits, int K>
1490
+ inline void vector_encode(uint8_t *out, const vector<K> *a) {
1491
+ for (int i = 0; i < K; i++) {
1492
+ scalar_encode<bits>(out + i * bits * kDegree / 8, &a->v[i]);
1144
1493
  }
1145
1494
  }
1146
1495
 
1147
1496
  // FIPS 204, Algorithm 18 (`SimpleBitUnpack`).
1148
- template <int K>
1149
- void vector_decode_10(vector<K> *out, const uint8_t *in) {
1497
+ template <int bits, int K>
1498
+ inline void vector_decode(vector<K> *out, const uint8_t *in) {
1150
1499
  for (int i = 0; i < K; i++) {
1151
- scalar_decode_10(&out->v[i], in + i * 10 * kDegree / 8);
1500
+ scalar_decode<bits>(&out->v[i], in + i * bits * kDegree / 8);
1152
1501
  }
1153
1502
  }
1154
1503
 
1155
1504
  // FIPS 204, Algorithm 17 (`BitPack`).
1156
1505
  //
1157
- // Encodes an entire vector into 32*L*|bits| bytes. Note that since 256
1506
+ // Encodes an entire vector into 32*L*`bits` bytes. Note that since 256
1158
1507
  // (kDegree) is divisible by 8, the individual vector entries will always fill a
1159
1508
  // whole number of bytes, so we do not need to worry about bit packing here.
1160
- template <int X>
1161
- void vector_encode_signed(uint8_t *out, const vector<X> *a, int bits,
1162
- uint32_t max) {
1509
+ template <int bits, uint32_t max, int X>
1510
+ inline void vector_encode_signed(uint8_t *out, const vector<X> *a) {
1163
1511
  for (int i = 0; i < X; i++) {
1164
- scalar_encode_signed(out + i * bits * kDegree / 8, &a->v[i], bits, max);
1512
+ scalar_encode_signed<bits, max>(out + i * bits * kDegree / 8, &a->v[i]);
1165
1513
  }
1166
1514
  }
1167
1515
 
1168
- template <int X>
1169
- int vector_decode_signed(vector<X> *out, const uint8_t *in, int bits,
1170
- uint32_t max) {
1516
+ // `vector_encode_signed_ntt` behaves like `vector_encode_signed` but takes its
1517
+ // input in NTT form. This is only used by the testing-only `skEncode` and
1518
+ // `skDecode` functions and is not performance-sensitive.
1519
+ template <int bits, uint32_t max, int X>
1520
+ inline void vector_encode_signed_ntt(uint8_t *out, const vector<X> *a_ntt) {
1521
+ vector<X> a = *a_ntt;
1522
+ vector_inverse_ntt_montgomery(&a);
1523
+ // `vector_inverse_ntt_montgomery` adds an extra factor of R, which we must
1524
+ // cancel with a Montgomery reduction.
1525
+ for (int i = 0; i < X; i++) {
1526
+ for (int j = 0; j < kDegree; j++) {
1527
+ a.v[i].c[j] = reduce_montgomery(a.v[i].c[j]);
1528
+ }
1529
+ }
1530
+
1531
+ vector_encode_signed<bits, max>(out, &a);
1532
+ }
1533
+
1534
+ // FIPS 204, Algorithm 19 (`BitUnpack`).
1535
+ template <int bits, uint32_t max, int X>
1536
+ inline int vector_decode_signed(vector<X> *out, const uint8_t *in) {
1171
1537
  for (int i = 0; i < X; i++) {
1172
- if (!scalar_decode_signed(&out->v[i], in + i * bits * kDegree / 8, bits,
1173
- max)) {
1538
+ if (!scalar_decode_signed<bits, max>(&out->v[i],
1539
+ in + i * bits * kDegree / 8)) {
1174
1540
  return 0;
1175
1541
  }
1176
1542
  }
@@ -1179,13 +1545,13 @@ int vector_decode_signed(vector<X> *out, const uint8_t *in, int bits,
1179
1545
 
1180
1546
  // FIPS 204, Algorithm 28 (`w1Encode`).
1181
1547
  template <int K>
1182
- void w1_encode(uint8_t out[128 * K], const vector<K> *w1) {
1183
- vector_encode(out, w1, 4);
1548
+ inline void w1_encode(uint8_t out[w1_bytes<K>()], const vector<K> *w1) {
1549
+ vector_encode<w1_coeffs_bits<K>()>(out, w1);
1184
1550
  }
1185
1551
 
1186
1552
  // FIPS 204, Algorithm 20 (`HintBitPack`).
1187
1553
  template <int K>
1188
- void hint_bit_pack(uint8_t out[omega<K>() + K], const vector<K> *h) {
1554
+ inline void hint_bit_pack(uint8_t out[omega<K>() + K], const vector<K> *h) {
1189
1555
  OPENSSL_memset(out, 0, omega<K>() + K);
1190
1556
  int index = 0;
1191
1557
  for (int i = 0; i < K; i++) {
@@ -1202,7 +1568,7 @@ void hint_bit_pack(uint8_t out[omega<K>() + K], const vector<K> *h) {
1202
1568
 
1203
1569
  // FIPS 204, Algorithm 21 (`HintBitUnpack`).
1204
1570
  template <int K>
1205
- int hint_bit_unpack(vector<K> *h, const uint8_t in[omega<K>() + K]) {
1571
+ inline int hint_bit_unpack(vector<K> *h, const uint8_t in[omega<K>() + K]) {
1206
1572
  vector_zero(h);
1207
1573
  int index = 0;
1208
1574
  for (int i = 0; i < K; i++) {
@@ -1241,12 +1607,11 @@ struct public_key {
1241
1607
 
1242
1608
  template <int K, int L>
1243
1609
  struct private_key {
1244
- uint8_t rho[kRhoBytes];
1610
+ public_key<K> pub;
1245
1611
  uint8_t k[kKBytes];
1246
- uint8_t public_key_hash[kTrBytes];
1247
- vector<L> s1;
1248
- vector<K> s2;
1249
- vector<K> t0;
1612
+ vector<L> s1_ntt;
1613
+ vector<K> s2_ntt;
1614
+ vector<K> t0_ntt;
1250
1615
  };
1251
1616
 
1252
1617
  template <int K, int L>
@@ -1258,7 +1623,7 @@ struct signature {
1258
1623
 
1259
1624
  // FIPS 204, Algorithm 22 (`pkEncode`).
1260
1625
  template <int K>
1261
- int mldsa_marshal_public_key(CBB *out, const struct public_key<K> *pub) {
1626
+ inline int mldsa_marshal_public_key(CBB *out, const public_key<K> *pub) {
1262
1627
  if (!CBB_add_bytes(out, pub->rho, sizeof(pub->rho))) {
1263
1628
  return 0;
1264
1629
  }
@@ -1267,14 +1632,14 @@ int mldsa_marshal_public_key(CBB *out, const struct public_key<K> *pub) {
1267
1632
  if (!CBB_add_space(out, &vectork_output, 320 * K)) {
1268
1633
  return 0;
1269
1634
  }
1270
- vector_encode(vectork_output, &pub->t1, 10);
1635
+ vector_encode<10>(vectork_output, &pub->t1);
1271
1636
 
1272
1637
  return 1;
1273
1638
  }
1274
1639
 
1275
1640
  // FIPS 204, Algorithm 23 (`pkDecode`).
1276
1641
  template <int K>
1277
- int mldsa_parse_public_key(struct public_key<K> *pub, CBS *in) {
1642
+ inline int mldsa_parse_public_key(public_key<K> *pub, CBS *in) {
1278
1643
  const CBS orig_in = *in;
1279
1644
 
1280
1645
  if (!CBS_copy_bytes(in, pub->rho, sizeof(pub->rho))) {
@@ -1285,7 +1650,7 @@ int mldsa_parse_public_key(struct public_key<K> *pub, CBS *in) {
1285
1650
  if (!CBS_get_bytes(in, &t1_bytes, 320 * K) || CBS_len(in) != 0) {
1286
1651
  return 0;
1287
1652
  }
1288
- vector_decode_10(&pub->t1, CBS_data(&t1_bytes));
1653
+ vector_decode<10>(&pub->t1, CBS_data(&t1_bytes));
1289
1654
 
1290
1655
  // Compute pre-cached values.
1291
1656
  BORINGSSL_keccak(pub->public_key_hash, sizeof(pub->public_key_hash),
@@ -1296,11 +1661,11 @@ int mldsa_parse_public_key(struct public_key<K> *pub, CBS *in) {
1296
1661
 
1297
1662
  // FIPS 204, Algorithm 24 (`skEncode`).
1298
1663
  template <int K, int L>
1299
- int mldsa_marshal_private_key(CBB *out, const struct private_key<K, L> *priv) {
1300
- if (!CBB_add_bytes(out, priv->rho, sizeof(priv->rho)) ||
1664
+ inline int mldsa_marshal_private_key(CBB *out, const private_key<K, L> *priv) {
1665
+ if (!CBB_add_bytes(out, priv->pub.rho, sizeof(priv->pub.rho)) ||
1301
1666
  !CBB_add_bytes(out, priv->k, sizeof(priv->k)) ||
1302
- !CBB_add_bytes(out, priv->public_key_hash,
1303
- sizeof(priv->public_key_hash))) {
1667
+ !CBB_add_bytes(out, priv->pub.public_key_hash,
1668
+ sizeof(priv->pub.public_key_hash))) {
1304
1669
  return 0;
1305
1670
  }
1306
1671
 
@@ -1310,46 +1675,59 @@ int mldsa_marshal_private_key(CBB *out, const struct private_key<K, L> *priv) {
1310
1675
  if (!CBB_add_space(out, &vectorl_output, scalar_bytes * L)) {
1311
1676
  return 0;
1312
1677
  }
1313
- vector_encode_signed(vectorl_output, &priv->s1, plus_minus_eta_bitlen<K>(),
1314
- eta<K>());
1678
+ vector_encode_signed_ntt<plus_minus_eta_bitlen<K>(), eta<K>()>(vectorl_output,
1679
+ &priv->s1_ntt);
1315
1680
 
1316
1681
  uint8_t *s2_output;
1317
1682
  if (!CBB_add_space(out, &s2_output, scalar_bytes * K)) {
1318
1683
  return 0;
1319
1684
  }
1320
- vector_encode_signed(s2_output, &priv->s2, plus_minus_eta_bitlen<K>(),
1321
- eta<K>());
1685
+ vector_encode_signed_ntt<plus_minus_eta_bitlen<K>(), eta<K>()>(s2_output,
1686
+ &priv->s2_ntt);
1322
1687
 
1323
1688
  uint8_t *t0_output;
1324
1689
  if (!CBB_add_space(out, &t0_output, 416 * K)) {
1325
1690
  return 0;
1326
1691
  }
1327
- vector_encode_signed(t0_output, &priv->t0, 13, 1 << 12);
1692
+ vector_encode_signed_ntt<13, (1 << 12)>(t0_output, &priv->t0_ntt);
1328
1693
 
1329
1694
  return 1;
1330
1695
  }
1331
1696
 
1332
- // FIPS 204, Algorithm 25 (`skDecode`).
1697
+ // FIPS 204, Algorithm 25 (`skDecode`). This is only used for testing. The
1698
+ // supported external way to construct ML-DSA keys is to use the input seed.
1333
1699
  template <int K, int L>
1334
- int mldsa_parse_private_key(struct private_key<K, L> *priv, CBS *in) {
1335
- CBS s1_bytes;
1336
- CBS s2_bytes;
1337
- CBS t0_bytes;
1700
+ inline int mldsa_parse_private_key(private_key<K, L> *priv, CBS *in) {
1701
+ CBS public_key_hash, s1_bytes, s2_bytes, t0_bytes;
1338
1702
  constexpr size_t scalar_bytes =
1339
1703
  (kDegree * plus_minus_eta_bitlen<K>() + 7) / 8;
1340
- if (!CBS_copy_bytes(in, priv->rho, sizeof(priv->rho)) ||
1704
+ if (!CBS_copy_bytes(in, priv->pub.rho, sizeof(priv->pub.rho)) ||
1341
1705
  !CBS_copy_bytes(in, priv->k, sizeof(priv->k)) ||
1342
- !CBS_copy_bytes(in, priv->public_key_hash,
1343
- sizeof(priv->public_key_hash)) ||
1706
+ !CBS_get_bytes(in, &public_key_hash, kTrBytes) ||
1344
1707
  !CBS_get_bytes(in, &s1_bytes, scalar_bytes * L) ||
1345
- !vector_decode_signed(&priv->s1, CBS_data(&s1_bytes),
1346
- plus_minus_eta_bitlen<K>(), eta<K>()) ||
1708
+ !vector_decode_signed<plus_minus_eta_bitlen<K>(), eta<K>()>(
1709
+ &priv->s1_ntt, CBS_data(&s1_bytes)) ||
1347
1710
  !CBS_get_bytes(in, &s2_bytes, scalar_bytes * K) ||
1348
- !vector_decode_signed(&priv->s2, CBS_data(&s2_bytes),
1349
- plus_minus_eta_bitlen<K>(), eta<K>()) ||
1350
- !CBS_get_bytes(in, &t0_bytes, 416 * K) ||
1351
- // Note: Decoding 13 bits into (-2^12, 2^12] cannot fail.
1352
- !vector_decode_signed(&priv->t0, CBS_data(&t0_bytes), 13, 1 << 12)) {
1711
+ !vector_decode_signed<plus_minus_eta_bitlen<K>(), eta<K>()>(
1712
+ &priv->s2_ntt, CBS_data(&s2_bytes)) ||
1713
+ !CBS_get_bytes(in, &t0_bytes, 416 * K)) {
1714
+ return 0;
1715
+ }
1716
+
1717
+ // Compute `t1`, which is not in the `skDecode` input. This also computes
1718
+ // `t0_ntt` and converts `s1_ntt` and `s2_ntt` to NTT form.
1719
+ uint8_t unused[public_key_bytes<K>()];
1720
+ if (!mldsa_finish_keygen(unused, priv)) {
1721
+ return 0;
1722
+ }
1723
+
1724
+ // As a side effect of computing `t1`, we also compute `t0` and
1725
+ // `public_key_hash`. Check they match the received bytes.
1726
+ uint8_t t0_computed[416 * K];
1727
+ vector_encode_signed_ntt<13, (1 << 12)>(t0_computed, &priv->t0_ntt);
1728
+ if (!CBS_mem_equal(&public_key_hash, priv->pub.public_key_hash,
1729
+ sizeof(priv->pub.public_key_hash)) ||
1730
+ !CBS_mem_equal(&t0_bytes, t0_computed, sizeof(t0_computed))) {
1353
1731
  return 0;
1354
1732
  }
1355
1733
 
@@ -1358,16 +1736,17 @@ int mldsa_parse_private_key(struct private_key<K, L> *priv, CBS *in) {
1358
1736
 
1359
1737
  // FIPS 204, Algorithm 26 (`sigEncode`).
1360
1738
  template <int K, int L>
1361
- int mldsa_marshal_signature(CBB *out, const struct signature<K, L> *sign) {
1739
+ inline int mldsa_marshal_signature(CBB *out, const signature<K, L> *sign) {
1362
1740
  if (!CBB_add_bytes(out, sign->c_tilde, sizeof(sign->c_tilde))) {
1363
1741
  return 0;
1364
1742
  }
1365
1743
 
1366
1744
  uint8_t *vectorl_output;
1367
- if (!CBB_add_space(out, &vectorl_output, 640 * L)) {
1745
+ if (!CBB_add_space(out, &vectorl_output, scalar_le_gamma1_bytes<K>() * L)) {
1368
1746
  return 0;
1369
1747
  }
1370
- vector_encode_signed(vectorl_output, &sign->z, 20, 1 << 19);
1748
+ vector_encode_signed<gamma1_bits<K>() + 1, gamma1<K>()>(vectorl_output,
1749
+ &sign->z);
1371
1750
 
1372
1751
  uint8_t *hint_output;
1373
1752
  if (!CBB_add_space(out, &hint_output, omega<K>() + K)) {
@@ -1380,13 +1759,14 @@ int mldsa_marshal_signature(CBB *out, const struct signature<K, L> *sign) {
1380
1759
 
1381
1760
  // FIPS 204, Algorithm 27 (`sigDecode`).
1382
1761
  template <int K, int L>
1383
- int mldsa_parse_signature(struct signature<K, L> *sign, CBS *in) {
1762
+ inline int mldsa_parse_signature(signature<K, L> *sign, CBS *in) {
1384
1763
  CBS z_bytes;
1385
1764
  CBS hint_bytes;
1386
1765
  if (!CBS_copy_bytes(in, sign->c_tilde, sizeof(sign->c_tilde)) ||
1387
- !CBS_get_bytes(in, &z_bytes, 640 * L) ||
1388
- // Note: Decoding 20 bits into (-2^19, 2^19] cannot fail.
1389
- !vector_decode_signed(&sign->z, CBS_data(&z_bytes), 20, 1 << 19) ||
1766
+ !CBS_get_bytes(in, &z_bytes, scalar_le_gamma1_bytes<K>() * L) ||
1767
+ // Note: Decoding b+1 bits into (-2^b, 2^b] cannot fail.
1768
+ !vector_decode_signed<gamma1_bits<K>() + 1, gamma1<K>()>(
1769
+ &sign->z, CBS_data(&z_bytes)) ||
1390
1770
  !CBS_get_bytes(in, &hint_bytes, omega<K>() + K) ||
1391
1771
  !hint_bit_unpack(&sign->h, CBS_data(&hint_bytes))) {
1392
1772
  return 0;
@@ -1395,143 +1775,107 @@ int mldsa_parse_signature(struct signature<K, L> *sign, CBS *in) {
1395
1775
  return 1;
1396
1776
  }
1397
1777
 
1398
- template <typename T>
1399
- struct DeleterFree {
1400
- void operator()(T *ptr) { OPENSSL_free(ptr); }
1401
- };
1402
-
1403
- // FIPS 204, Algorithm 6 (`ML-DSA.KeyGen_internal`). Returns 1 on success and 0
1404
- // on failure.
1778
+ // FIPS 204, Algorithm 6 (`ML-DSA.KeyGen_internal`), steps 3 and 5–11.
1779
+ // Returns 1 on success and 0 on failure.
1780
+ //
1781
+ // On input, `priv->s1_ntt` and `priv->s2_ntt` are not yet in NTT form. They are
1782
+ // converted to NTT form by this function.
1405
1783
  template <int K, int L>
1406
- int mldsa_generate_key_external_entropy_no_self_test(
1784
+ inline int mldsa_finish_keygen(
1407
1785
  uint8_t out_encoded_public_key[public_key_bytes<K>()],
1408
- struct private_key<K, L> *priv,
1409
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
1786
+ private_key<K, L> *priv) {
1410
1787
  // Intermediate values, allocated on the heap to allow use when there is a
1411
1788
  // limited amount of stack.
1412
- struct values_st {
1413
- struct public_key<K> pub;
1789
+ struct Values {
1790
+ enum { kAllowUniquePtr = true };
1414
1791
  matrix<K, L> a_ntt;
1415
- vector<L> s1_ntt;
1416
1792
  vector<K> t;
1417
1793
  };
1418
- std::unique_ptr<values_st, DeleterFree<values_st>> values(
1419
- reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
1420
- if (values == NULL) {
1794
+ auto values = MakeUnique<Values>();
1795
+ if (values == nullptr) {
1421
1796
  return 0;
1422
1797
  }
1423
1798
 
1424
- uint8_t augmented_entropy[BCM_MLDSA_SEED_BYTES + 2];
1425
- OPENSSL_memcpy(augmented_entropy, entropy, BCM_MLDSA_SEED_BYTES);
1426
- // The k and l parameters are appended to the seed.
1427
- augmented_entropy[BCM_MLDSA_SEED_BYTES] = K;
1428
- augmented_entropy[BCM_MLDSA_SEED_BYTES + 1] = L;
1429
- uint8_t expanded_seed[kRhoBytes + kSigmaBytes + kKBytes];
1430
- BORINGSSL_keccak(expanded_seed, sizeof(expanded_seed), augmented_entropy,
1431
- sizeof(augmented_entropy), boringssl_shake256);
1432
- const uint8_t *const rho = expanded_seed;
1433
- const uint8_t *const sigma = expanded_seed + kRhoBytes;
1434
- const uint8_t *const k = expanded_seed + kRhoBytes + kSigmaBytes;
1435
- // rho is public.
1436
- CONSTTIME_DECLASSIFY(rho, kRhoBytes);
1437
- OPENSSL_memcpy(values->pub.rho, rho, sizeof(values->pub.rho));
1438
- OPENSSL_memcpy(priv->rho, rho, sizeof(priv->rho));
1439
- OPENSSL_memcpy(priv->k, k, sizeof(priv->k));
1440
-
1441
- matrix_expand(&values->a_ntt, rho);
1442
- vector_expand_short(&priv->s1, &priv->s2, sigma);
1443
-
1444
- OPENSSL_memcpy(&values->s1_ntt, &priv->s1, sizeof(values->s1_ntt));
1445
- vector_ntt(&values->s1_ntt);
1799
+ // Step 3.
1800
+ matrix_expand(&values->a_ntt, priv->pub.rho);
1446
1801
 
1447
- matrix_mult(&values->t, &values->a_ntt, &values->s1_ntt);
1448
- vector_inverse_ntt(&values->t);
1449
- vector_add(&values->t, &values->t, &priv->s2);
1802
+ // Step 5. Note that, on input, `s1_ntt` and `s2_ntt` are not yet in NTT form,
1803
+ // but this function is responsible for converting them to NTT.
1804
+ vector_ntt(&priv->s1_ntt);
1805
+ matrix_mult_montgomery(&values->t, &values->a_ntt, &priv->s1_ntt);
1806
+ vector_inverse_ntt_montgomery(&values->t);
1807
+ vector_add(&values->t, &values->t, &priv->s2_ntt);
1808
+ vector_ntt(&priv->s2_ntt);
1450
1809
 
1451
- vector_power2_round(&values->pub.t1, &priv->t0, &values->t);
1810
+ // Step 6-7. We store t0 in NTT form.
1811
+ vector_power2_round(&priv->pub.t1, &priv->t0_ntt, &values->t);
1812
+ vector_ntt(&priv->t0_ntt);
1452
1813
  // t1 is public.
1453
- CONSTTIME_DECLASSIFY(&values->pub.t1, sizeof(values->pub.t1));
1814
+ CONSTTIME_DECLASSIFY(&priv->pub.t1, sizeof(priv->pub.t1));
1454
1815
 
1816
+ // Step 8.
1455
1817
  CBB cbb;
1456
1818
  CBB_init_fixed(&cbb, out_encoded_public_key, public_key_bytes<K>());
1457
- if (!mldsa_marshal_public_key(&cbb, &values->pub)) {
1819
+ if (!mldsa_marshal_public_key(&cbb, &priv->pub)) {
1458
1820
  return 0;
1459
1821
  }
1460
1822
  assert(CBB_len(&cbb) == public_key_bytes<K>());
1461
1823
 
1462
- BORINGSSL_keccak(priv->public_key_hash, sizeof(priv->public_key_hash),
1824
+ // Step 9-11.
1825
+ BORINGSSL_keccak(priv->pub.public_key_hash, sizeof(priv->pub.public_key_hash),
1463
1826
  out_encoded_public_key, public_key_bytes<K>(),
1464
1827
  boringssl_shake256);
1465
1828
 
1466
1829
  return 1;
1467
1830
  }
1468
1831
 
1832
+ // FIPS 204, Algorithm 6 (`ML-DSA.KeyGen_internal`). Returns 1 on success and 0
1833
+ // on failure.
1834
+ template <int K, int L>
1835
+ inline int mldsa_generate_key_external_entropy_no_self_test(
1836
+ uint8_t out_encoded_public_key[public_key_bytes<K>()],
1837
+ private_key<K, L> *priv, const uint8_t entropy[MLDSA_SEED_BYTES]) {
1838
+ // Step 1-2.
1839
+ uint8_t augmented_entropy[MLDSA_SEED_BYTES + 2];
1840
+ OPENSSL_memcpy(augmented_entropy, entropy, MLDSA_SEED_BYTES);
1841
+ // The k and l parameters are appended to the seed.
1842
+ augmented_entropy[MLDSA_SEED_BYTES] = K;
1843
+ augmented_entropy[MLDSA_SEED_BYTES + 1] = L;
1844
+ uint8_t expanded_seed[kRhoBytes + kSigmaBytes + kKBytes];
1845
+ BORINGSSL_keccak(expanded_seed, sizeof(expanded_seed), augmented_entropy,
1846
+ sizeof(augmented_entropy), boringssl_shake256);
1847
+ const uint8_t *const rho = expanded_seed;
1848
+ const uint8_t *const sigma = expanded_seed + kRhoBytes;
1849
+ const uint8_t *const k = expanded_seed + kRhoBytes + kSigmaBytes;
1850
+ // rho is public.
1851
+ CONSTTIME_DECLASSIFY(rho, kRhoBytes);
1852
+ OPENSSL_memcpy(priv->pub.rho, rho, sizeof(priv->pub.rho));
1853
+ OPENSSL_memcpy(priv->k, k, sizeof(priv->k));
1854
+ // Steps 4. This is independent of A (step 3) and can be done first.
1855
+ // `mldsa_finish_keygen` will convert `s1_ntt` and `s2_ntt` into NTT from.
1856
+ vector_expand_short(&priv->s1_ntt, &priv->s2_ntt, sigma);
1857
+ // Steps 3 and 5-11.
1858
+ return mldsa_finish_keygen(out_encoded_public_key, priv);
1859
+ }
1860
+
1469
1861
  template <int K, int L>
1470
- int mldsa_generate_key_external_entropy(
1862
+ inline int mldsa_generate_key_external_entropy(
1471
1863
  uint8_t out_encoded_public_key[public_key_bytes<K>()],
1472
- struct private_key<K, L> *priv,
1473
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
1864
+ private_key<K, L> *priv, const uint8_t entropy[MLDSA_SEED_BYTES]) {
1474
1865
  fips::ensure_keygen_self_test();
1475
1866
  return mldsa_generate_key_external_entropy_no_self_test(
1476
1867
  out_encoded_public_key, priv, entropy);
1477
1868
  }
1478
1869
 
1870
+ // FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`), using a pre-computed mu.
1871
+ // Returns 1 on success and 0 on failure.
1479
1872
  template <int K, int L>
1480
- int mldsa_public_from_private(struct public_key<K> *pub,
1481
- const struct private_key<K, L> *priv) {
1482
- // Intermediate values, allocated on the heap to allow use when there is a
1483
- // limited amount of stack.
1484
- struct values_st {
1485
- matrix<K, L> a_ntt;
1486
- vector<L> s1_ntt;
1487
- vector<K> t;
1488
- vector<K> t0;
1489
- };
1490
- std::unique_ptr<values_st, DeleterFree<values_st>> values(
1491
- reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
1492
- if (values == NULL) {
1493
- return 0;
1494
- }
1495
-
1496
- OPENSSL_memcpy(pub->rho, priv->rho, sizeof(pub->rho));
1497
- OPENSSL_memcpy(pub->public_key_hash, priv->public_key_hash,
1498
- sizeof(pub->public_key_hash));
1499
-
1500
- matrix_expand(&values->a_ntt, priv->rho);
1501
-
1502
- OPENSSL_memcpy(&values->s1_ntt, &priv->s1, sizeof(values->s1_ntt));
1503
- vector_ntt(&values->s1_ntt);
1504
-
1505
- matrix_mult(&values->t, &values->a_ntt, &values->s1_ntt);
1506
- vector_inverse_ntt(&values->t);
1507
- vector_add(&values->t, &values->t, &priv->s2);
1508
-
1509
- vector_power2_round(&pub->t1, &values->t0, &values->t);
1510
- // t1 is part of the public key and thus is public.
1511
- CONSTTIME_DECLASSIFY(&pub->t1, sizeof(pub->t1));
1512
- return 1;
1513
- }
1514
-
1515
- // FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`). Returns 1 on success and 0
1516
- // on failure.
1517
- template <int K, int L>
1518
- int mldsa_sign_internal_no_self_test(
1873
+ inline int mldsa_sign_mu_no_self_test(
1519
1874
  uint8_t out_encoded_signature[signature_bytes<K>()],
1520
- const struct private_key<K, L> *priv, const uint8_t *msg, size_t msg_len,
1521
- const uint8_t *context_prefix, size_t context_prefix_len,
1522
- const uint8_t *context, size_t context_len,
1875
+ const private_key<K, L> *priv, const uint8_t mu[kMuBytes],
1523
1876
  const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
1524
- uint8_t mu[kMuBytes];
1525
- struct BORINGSSL_keccak_st keccak_ctx;
1526
- BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1527
- BORINGSSL_keccak_absorb(&keccak_ctx, priv->public_key_hash,
1528
- sizeof(priv->public_key_hash));
1529
- BORINGSSL_keccak_absorb(&keccak_ctx, context_prefix, context_prefix_len);
1530
- BORINGSSL_keccak_absorb(&keccak_ctx, context, context_len);
1531
- BORINGSSL_keccak_absorb(&keccak_ctx, msg, msg_len);
1532
- BORINGSSL_keccak_squeeze(&keccak_ctx, mu, kMuBytes);
1533
-
1534
1877
  uint8_t rho_prime[kRhoPrimeBytes];
1878
+ BORINGSSL_keccak_st keccak_ctx;
1535
1879
  BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1536
1880
  BORINGSSL_keccak_absorb(&keccak_ctx, priv->k, sizeof(priv->k));
1537
1881
  BORINGSSL_keccak_absorb(&keccak_ctx, randomizer,
@@ -1541,11 +1885,9 @@ int mldsa_sign_internal_no_self_test(
1541
1885
 
1542
1886
  // Intermediate values, allocated on the heap to allow use when there is a
1543
1887
  // limited amount of stack.
1544
- struct values_st {
1545
- struct signature<K, L> sign;
1546
- vector<L> s1_ntt;
1547
- vector<K> s2_ntt;
1548
- vector<K> t0_ntt;
1888
+ struct Values {
1889
+ enum { kAllowUniquePtr = true };
1890
+ signature<K, L> sign;
1549
1891
  matrix<K, L> a_ntt;
1550
1892
  vector<L> y;
1551
1893
  vector<K> w;
@@ -1553,41 +1895,31 @@ int mldsa_sign_internal_no_self_test(
1553
1895
  vector<L> cs1;
1554
1896
  vector<K> cs2;
1555
1897
  };
1556
- std::unique_ptr<values_st, DeleterFree<values_st>> values(
1557
- reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
1558
- if (values == NULL) {
1898
+ auto values = MakeUnique<Values>();
1899
+ if (values == nullptr) {
1559
1900
  return 0;
1560
1901
  }
1561
- OPENSSL_memcpy(&values->s1_ntt, &priv->s1, sizeof(values->s1_ntt));
1562
- vector_ntt(&values->s1_ntt);
1563
-
1564
- OPENSSL_memcpy(&values->s2_ntt, &priv->s2, sizeof(values->s2_ntt));
1565
- vector_ntt(&values->s2_ntt);
1566
-
1567
- OPENSSL_memcpy(&values->t0_ntt, &priv->t0, sizeof(values->t0_ntt));
1568
- vector_ntt(&values->t0_ntt);
1569
-
1570
- matrix_expand(&values->a_ntt, priv->rho);
1902
+ matrix_expand(&values->a_ntt, priv->pub.rho);
1571
1903
 
1572
1904
  // kappa must not exceed 2**16/L = 13107. But the probability of it
1573
1905
  // exceeding even 1000 iterations is vanishingly small.
1574
1906
  for (size_t kappa = 0;; kappa += L) {
1575
- vector_expand_mask(&values->y, rho_prime, kappa);
1907
+ vector_expand_mask<K, L>(&values->y, rho_prime, kappa);
1576
1908
 
1577
1909
  vector<L> *y_ntt = &values->cs1;
1578
1910
  OPENSSL_memcpy(y_ntt, &values->y, sizeof(*y_ntt));
1579
1911
  vector_ntt(y_ntt);
1580
1912
 
1581
- matrix_mult(&values->w, &values->a_ntt, y_ntt);
1582
- vector_inverse_ntt(&values->w);
1913
+ matrix_mult_montgomery(&values->w, &values->a_ntt, y_ntt);
1914
+ vector_inverse_ntt_montgomery(&values->w);
1583
1915
 
1584
1916
  vector_high_bits(&values->w1, &values->w);
1585
- uint8_t w1_encoded[128 * K];
1917
+ uint8_t w1_encoded[w1_bytes<K>()];
1586
1918
  w1_encode(w1_encoded, &values->w1);
1587
1919
 
1588
1920
  BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1589
1921
  BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes);
1590
- BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K);
1922
+ BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes<K>());
1591
1923
  BORINGSSL_keccak_squeeze(&keccak_ctx, values->sign.c_tilde,
1592
1924
  2 * lambda_bytes<K>());
1593
1925
 
@@ -1596,10 +1928,10 @@ int mldsa_sign_internal_no_self_test(
1596
1928
  sizeof(values->sign.c_tilde), tau<K>());
1597
1929
  scalar_ntt(&c_ntt);
1598
1930
 
1599
- vector_mult_scalar(&values->cs1, &values->s1_ntt, &c_ntt);
1600
- vector_inverse_ntt(&values->cs1);
1601
- vector_mult_scalar(&values->cs2, &values->s2_ntt, &c_ntt);
1602
- vector_inverse_ntt(&values->cs2);
1931
+ vector_mult_scalar_montgomery(&values->cs1, &priv->s1_ntt, &c_ntt);
1932
+ vector_inverse_ntt_montgomery(&values->cs1);
1933
+ vector_mult_scalar_montgomery(&values->cs2, &priv->s2_ntt, &c_ntt);
1934
+ vector_inverse_ntt_montgomery(&values->cs2);
1603
1935
 
1604
1936
  vector_add(&values->sign.z, &values->y, &values->cs1);
1605
1937
 
@@ -1614,13 +1946,13 @@ int mldsa_sign_internal_no_self_test(
1614
1946
  // https://pq-crystals.org/dilithium/data/dilithium-specification-round3.pdf
1615
1947
  // describes this leak as OK. Note we leak less than what is described by
1616
1948
  // the paper; we do not reveal which coefficient violated the bound, and
1617
- // we hide which of the |z_max| or |r0_max| bound failed. See also
1949
+ // we hide which of the `z_max` or `r0_max` bound failed. See also
1618
1950
  // https://boringssl-review.googlesource.com/c/boringssl/+/67747/comment/2bbab0fa_d241d35a/
1619
1951
  uint32_t z_max = vector_max(&values->sign.z);
1620
1952
  uint32_t r0_max = vector_max_signed(r0);
1621
1953
  if (constant_time_declassify_w(
1622
1954
  constant_time_ge_w(z_max, gamma1<K>() - beta<K>()) |
1623
- constant_time_ge_w(r0_max, kGamma2 - beta<K>()))) {
1955
+ constant_time_ge_w(r0_max, gamma2<K>() - beta<K>()))) {
1624
1956
  #if defined(BORINGSSL_FIPS_BREAK_TESTS)
1625
1957
  // In order to show that our self-tests trigger both restart cases in
1626
1958
  // this loop, printf-logging is added when built in break-test mode.
@@ -1630,14 +1962,14 @@ int mldsa_sign_internal_no_self_test(
1630
1962
  }
1631
1963
 
1632
1964
  vector<K> *ct0 = &values->w1;
1633
- vector_mult_scalar(ct0, &values->t0_ntt, &c_ntt);
1634
- vector_inverse_ntt(ct0);
1965
+ vector_mult_scalar_montgomery(ct0, &priv->t0_ntt, &c_ntt);
1966
+ vector_inverse_ntt_montgomery(ct0);
1635
1967
  vector_make_hint(&values->sign.h, ct0, &values->cs2, &values->w);
1636
1968
 
1637
1969
  // See above.
1638
1970
  uint32_t ct0_max = vector_max(ct0);
1639
1971
  size_t h_ones = vector_count_ones(&values->sign.h);
1640
- if (constant_time_declassify_w(constant_time_ge_w(ct0_max, kGamma2) |
1972
+ if (constant_time_declassify_w(constant_time_ge_w(ct0_max, gamma2<K>()) |
1641
1973
  constant_time_lt_w(omega<K>(), h_ones))) {
1642
1974
  #if defined(BORINGSSL_FIPS_BREAK_TESTS)
1643
1975
  // In order to show that our self-tests trigger both restart cases in
@@ -1663,10 +1995,47 @@ int mldsa_sign_internal_no_self_test(
1663
1995
  }
1664
1996
  }
1665
1997
 
1998
+ // FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`), using a pre-computed mu.
1999
+ // Returns 1 on success and 0 on failure.
1666
2000
  template <int K, int L>
1667
- int mldsa_sign_internal(
2001
+ inline int mldsa_sign_mu(
1668
2002
  uint8_t out_encoded_signature[signature_bytes<K>()],
1669
- const struct private_key<K, L> *priv, const uint8_t *msg, size_t msg_len,
2003
+ const private_key<K, L> *priv, const uint8_t mu[kMuBytes],
2004
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2005
+ fips::ensure_sign_self_test();
2006
+ return mldsa_sign_mu_no_self_test(out_encoded_signature, priv, mu,
2007
+ randomizer);
2008
+ }
2009
+
2010
+ // FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`). Returns 1 on success and 0
2011
+ // on failure.
2012
+ template <int K, int L>
2013
+ inline int mldsa_sign_internal_no_self_test(
2014
+ uint8_t out_encoded_signature[signature_bytes<K>()],
2015
+ const private_key<K, L> *priv, const uint8_t *msg, size_t msg_len,
2016
+ const uint8_t *context_prefix, size_t context_prefix_len,
2017
+ const uint8_t *context, size_t context_len,
2018
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2019
+ uint8_t mu[kMuBytes];
2020
+ BORINGSSL_keccak_st keccak_ctx;
2021
+ BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
2022
+ BORINGSSL_keccak_absorb(&keccak_ctx, priv->pub.public_key_hash,
2023
+ sizeof(priv->pub.public_key_hash));
2024
+ BORINGSSL_keccak_absorb(&keccak_ctx, context_prefix, context_prefix_len);
2025
+ BORINGSSL_keccak_absorb(&keccak_ctx, context, context_len);
2026
+ BORINGSSL_keccak_absorb(&keccak_ctx, msg, msg_len);
2027
+ BORINGSSL_keccak_squeeze(&keccak_ctx, mu, kMuBytes);
2028
+
2029
+ return mldsa_sign_mu_no_self_test(out_encoded_signature, priv, mu,
2030
+ randomizer);
2031
+ }
2032
+
2033
+ // FIPS 204, Algorithm 7 (`ML-DSA.Sign_internal`). Returns 1 on success and 0
2034
+ // on failure.
2035
+ template <int K, int L>
2036
+ inline int mldsa_sign_internal(
2037
+ uint8_t out_encoded_signature[signature_bytes<K>()],
2038
+ const private_key<K, L> *priv, const uint8_t *msg, size_t msg_len,
1670
2039
  const uint8_t *context_prefix, size_t context_prefix_len,
1671
2040
  const uint8_t *context, size_t context_len,
1672
2041
  const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
@@ -1676,25 +2045,54 @@ int mldsa_sign_internal(
1676
2045
  context_prefix_len, context, context_len, randomizer);
1677
2046
  }
1678
2047
 
1679
- // FIPS 204, Algorithm 8 (`ML-DSA.Verify_internal`).
2048
+ struct prehash_context {
2049
+ BORINGSSL_keccak_st keccak_ctx;
2050
+ };
2051
+
2052
+ template <int K>
2053
+ inline void mldsa_prehash_init(prehash_context *out_prehash_ctx,
2054
+ const public_key<K> *pub,
2055
+ const uint8_t *context_prefix,
2056
+ size_t context_prefix_len,
2057
+ const uint8_t *context, size_t context_len) {
2058
+ BORINGSSL_keccak_init(&out_prehash_ctx->keccak_ctx, boringssl_shake256);
2059
+ BORINGSSL_keccak_absorb(&out_prehash_ctx->keccak_ctx, pub->public_key_hash,
2060
+ sizeof(pub->public_key_hash));
2061
+ BORINGSSL_keccak_absorb(&out_prehash_ctx->keccak_ctx, context_prefix,
2062
+ context_prefix_len);
2063
+ BORINGSSL_keccak_absorb(&out_prehash_ctx->keccak_ctx, context, context_len);
2064
+ }
2065
+
2066
+ inline void mldsa_prehash_update(prehash_context *inout_prehash_ctx,
2067
+ const uint8_t *msg, size_t msg_len) {
2068
+ BORINGSSL_keccak_absorb(&inout_prehash_ctx->keccak_ctx, msg, msg_len);
2069
+ }
2070
+
2071
+ inline void mldsa_prehash_finalize(uint8_t out_msg_rep[kMuBytes],
2072
+ prehash_context *inout_prehash_ctx) {
2073
+ BORINGSSL_keccak_squeeze(&inout_prehash_ctx->keccak_ctx, out_msg_rep,
2074
+ kMuBytes);
2075
+ }
2076
+
2077
+ // FIPS 204, Algorithm 8 (`ML-DSA.Verify_internal`), using a pre-computed mu.
2078
+ // Returns 1 on success and 0 on failure.
1680
2079
  template <int K, int L>
1681
- int mldsa_verify_internal_no_self_test(
1682
- const struct public_key<K> *pub,
1683
- const uint8_t encoded_signature[signature_bytes<K>()], const uint8_t *msg,
1684
- size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
1685
- const uint8_t *context, size_t context_len) {
2080
+ inline int mldsa_verify_mu_no_self_test(
2081
+ const public_key<K> *pub,
2082
+ const uint8_t encoded_signature[signature_bytes<K>()],
2083
+ const uint8_t mu[kMuBytes]) {
1686
2084
  // Intermediate values, allocated on the heap to allow use when there is a
1687
2085
  // limited amount of stack.
1688
- struct values_st {
1689
- struct signature<K, L> sign;
2086
+ struct Values {
2087
+ enum { kAllowUniquePtr = true };
2088
+ signature<K, L> sign;
1690
2089
  matrix<K, L> a_ntt;
1691
2090
  vector<L> z_ntt;
1692
2091
  vector<K> az_ntt;
1693
2092
  vector<K> ct1_ntt;
1694
2093
  };
1695
- std::unique_ptr<values_st, DeleterFree<values_st>> values(
1696
- reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
1697
- if (values == NULL) {
2094
+ auto values = MakeUnique<Values>();
2095
+ if (values == nullptr) {
1698
2096
  return 0;
1699
2097
  }
1700
2098
 
@@ -1706,16 +2104,6 @@ int mldsa_verify_internal_no_self_test(
1706
2104
 
1707
2105
  matrix_expand(&values->a_ntt, pub->rho);
1708
2106
 
1709
- uint8_t mu[kMuBytes];
1710
- struct BORINGSSL_keccak_st keccak_ctx;
1711
- BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1712
- BORINGSSL_keccak_absorb(&keccak_ctx, pub->public_key_hash,
1713
- sizeof(pub->public_key_hash));
1714
- BORINGSSL_keccak_absorb(&keccak_ctx, context_prefix, context_prefix_len);
1715
- BORINGSSL_keccak_absorb(&keccak_ctx, context, context_len);
1716
- BORINGSSL_keccak_absorb(&keccak_ctx, msg, msg_len);
1717
- BORINGSSL_keccak_squeeze(&keccak_ctx, mu, kMuBytes);
1718
-
1719
2107
  scalar c_ntt;
1720
2108
  scalar_sample_in_ball_vartime(&c_ntt, values->sign.c_tilde,
1721
2109
  sizeof(values->sign.c_tilde), tau<K>());
@@ -1724,25 +2112,26 @@ int mldsa_verify_internal_no_self_test(
1724
2112
  OPENSSL_memcpy(&values->z_ntt, &values->sign.z, sizeof(values->z_ntt));
1725
2113
  vector_ntt(&values->z_ntt);
1726
2114
 
1727
- matrix_mult(&values->az_ntt, &values->a_ntt, &values->z_ntt);
2115
+ matrix_mult_montgomery(&values->az_ntt, &values->a_ntt, &values->z_ntt);
1728
2116
 
1729
2117
  vector_scale_power2_round(&values->ct1_ntt, &pub->t1);
1730
2118
  vector_ntt(&values->ct1_ntt);
1731
2119
 
1732
- vector_mult_scalar(&values->ct1_ntt, &values->ct1_ntt, &c_ntt);
2120
+ vector_mult_scalar_montgomery(&values->ct1_ntt, &values->ct1_ntt, &c_ntt);
1733
2121
 
1734
2122
  vector<K> *const w1 = &values->az_ntt;
1735
2123
  vector_sub(w1, &values->az_ntt, &values->ct1_ntt);
1736
- vector_inverse_ntt(w1);
2124
+ vector_inverse_ntt_montgomery(w1);
1737
2125
 
1738
2126
  vector_use_hint_vartime(w1, &values->sign.h, w1);
1739
- uint8_t w1_encoded[128 * K];
2127
+ uint8_t w1_encoded[w1_bytes<K>()];
1740
2128
  w1_encode(w1_encoded, w1);
1741
2129
 
1742
2130
  uint8_t c_tilde[2 * lambda_bytes<K>()];
2131
+ BORINGSSL_keccak_st keccak_ctx;
1743
2132
  BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
1744
2133
  BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes);
1745
- BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K);
2134
+ BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes<K>());
1746
2135
  BORINGSSL_keccak_squeeze(&keccak_ctx, c_tilde, 2 * lambda_bytes<K>());
1747
2136
 
1748
2137
  uint32_t z_max = vector_max(&values->sign.z);
@@ -1750,87 +2139,170 @@ int mldsa_verify_internal_no_self_test(
1750
2139
  OPENSSL_memcmp(c_tilde, values->sign.c_tilde, 2 * lambda_bytes<K>()) ==
1751
2140
  0;
1752
2141
  }
2142
+
2143
+ // FIPS 204, Algorithm 8 (`ML-DSA.Verify_internal`), using a pre-computed mu.
2144
+ // Returns 1 on success and 0 on failure.
2145
+ template <int K, int L>
2146
+ inline int mldsa_verify_mu(
2147
+ const public_key<K> *pub,
2148
+ const uint8_t encoded_signature[signature_bytes<K>()],
2149
+ const uint8_t mu[kMuBytes]) {
2150
+ fips::ensure_verify_self_test();
2151
+ return mldsa_verify_mu_no_self_test<K, L>(pub, encoded_signature, mu);
2152
+ }
2153
+
2154
+ // FIPS 204, Algorithm 8 (`ML-DSA.Verify_internal`).
2155
+ template <int K, int L>
2156
+ inline int mldsa_verify_internal_no_self_test(
2157
+ const public_key<K> *pub,
2158
+ const uint8_t encoded_signature[signature_bytes<K>()], const uint8_t *msg,
2159
+ size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
2160
+ const uint8_t *context, size_t context_len) {
2161
+ uint8_t mu[kMuBytes];
2162
+ BORINGSSL_keccak_st keccak_ctx;
2163
+ BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256);
2164
+ BORINGSSL_keccak_absorb(&keccak_ctx, pub->public_key_hash,
2165
+ sizeof(pub->public_key_hash));
2166
+ BORINGSSL_keccak_absorb(&keccak_ctx, context_prefix, context_prefix_len);
2167
+ BORINGSSL_keccak_absorb(&keccak_ctx, context, context_len);
2168
+ BORINGSSL_keccak_absorb(&keccak_ctx, msg, msg_len);
2169
+ BORINGSSL_keccak_squeeze(&keccak_ctx, mu, kMuBytes);
2170
+
2171
+ return mldsa_verify_mu_no_self_test<K, L>(pub, encoded_signature, mu);
2172
+ }
2173
+
2174
+ // FIPS 204, Algorithm 8 (`ML-DSA.Verify_internal`).
1753
2175
  template <int K, int L>
1754
- int mldsa_verify_internal(const struct public_key<K> *pub,
1755
- const uint8_t encoded_signature[signature_bytes<K>()],
1756
- const uint8_t *msg, size_t msg_len,
1757
- const uint8_t *context_prefix,
1758
- size_t context_prefix_len, const uint8_t *context,
1759
- size_t context_len) {
2176
+ inline int mldsa_verify_internal(
2177
+ const public_key<K> *pub,
2178
+ const uint8_t encoded_signature[signature_bytes<K>()], const uint8_t *msg,
2179
+ size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
2180
+ const uint8_t *context, size_t context_len) {
1760
2181
  fips::ensure_verify_self_test();
1761
2182
  return mldsa_verify_internal_no_self_test<K, L>(
1762
2183
  pub, encoded_signature, msg, msg_len, context_prefix, context_prefix_len,
1763
2184
  context, context_len);
1764
2185
  }
1765
2186
 
1766
- struct private_key<6, 5> *private_key_from_external_65(
1767
- const struct BCM_mldsa65_private_key *external) {
1768
- static_assert(sizeof(struct BCM_mldsa65_private_key) ==
1769
- sizeof(struct private_key<6, 5>),
1770
- "MLDSA65 private key size incorrect");
1771
- static_assert(alignof(struct BCM_mldsa65_private_key) ==
1772
- alignof(struct private_key<6, 5>),
1773
- "MLDSA65 private key align incorrect");
1774
- return (struct private_key<6, 5> *)external;
1775
- }
1776
-
1777
- struct public_key<6> *public_key_from_external_65(
1778
- const struct BCM_mldsa65_public_key *external) {
1779
- static_assert(
1780
- sizeof(struct BCM_mldsa65_public_key) == sizeof(struct public_key<6>),
1781
- "MLDSA65 public key size incorrect");
1782
- static_assert(
1783
- alignof(struct BCM_mldsa65_public_key) == alignof(struct public_key<6>),
1784
- "MLDSA65 public key align incorrect");
1785
- return (struct public_key<6> *)external;
1786
- }
1787
-
1788
- struct private_key<8, 7> *private_key_from_external_87(
1789
- const struct BCM_mldsa87_private_key *external) {
1790
- static_assert(sizeof(struct BCM_mldsa87_private_key) ==
1791
- sizeof(struct private_key<8, 7>),
1792
- "MLDSA87 private key size incorrect");
1793
- static_assert(alignof(struct BCM_mldsa87_private_key) ==
1794
- alignof(struct private_key<8, 7>),
1795
- "MLDSA87 private key align incorrect");
1796
- return (struct private_key<8, 7> *)external;
1797
- }
1798
-
1799
- struct public_key<8> *public_key_from_external_87(
1800
- const struct BCM_mldsa87_public_key *external) {
1801
- static_assert(
1802
- sizeof(struct BCM_mldsa87_public_key) == sizeof(struct public_key<8>),
1803
- "MLDSA87 public key size incorrect");
1804
- static_assert(
1805
- alignof(struct BCM_mldsa87_public_key) == alignof(struct public_key<8>),
1806
- "MLDSA87 public key align incorrect");
1807
- return (struct public_key<8> *)external;
2187
+ static_assert(sizeof(MLDSA65_private_key) == sizeof(private_key<6, 5>));
2188
+ static_assert(alignof(MLDSA65_private_key) == alignof(private_key<6, 5>));
2189
+
2190
+ inline const private_key<6, 5> *private_key_from_external_65(
2191
+ const MLDSA65_private_key *external) {
2192
+ return reinterpret_cast<const private_key<6, 5> *>(external);
2193
+ }
2194
+ inline private_key<6, 5> *private_key_from_external_65(
2195
+ MLDSA65_private_key *external) {
2196
+ return reinterpret_cast<private_key<6, 5> *>(external);
2197
+ }
2198
+
2199
+ static_assert(sizeof(MLDSA65_public_key) == sizeof(public_key<6>));
2200
+ static_assert(alignof(MLDSA65_public_key) == alignof(public_key<6>));
2201
+
2202
+ inline const public_key<6> *public_key_from_external_65(
2203
+ const MLDSA65_public_key *external) {
2204
+ return reinterpret_cast<const public_key<6> *>(external);
2205
+ }
2206
+ inline public_key<6> *public_key_from_external_65(
2207
+ MLDSA65_public_key *external) {
2208
+ return reinterpret_cast<public_key<6> *>(external);
2209
+ }
2210
+
2211
+ inline prehash_context *prehash_context_from_external_65(
2212
+ MLDSA65_prehash *external) {
2213
+ static_assert(sizeof(MLDSA65_prehash) == sizeof(prehash_context));
2214
+ static_assert(alignof(MLDSA65_prehash) == alignof(prehash_context));
2215
+ return reinterpret_cast<prehash_context *>(external);
2216
+ }
2217
+
2218
+ static_assert(sizeof(MLDSA87_private_key) == sizeof(private_key<8, 7>));
2219
+ static_assert(alignof(MLDSA87_private_key) == alignof(private_key<8, 7>));
2220
+ inline const private_key<8, 7> *private_key_from_external_87(
2221
+ const MLDSA87_private_key *external) {
2222
+ return reinterpret_cast<const private_key<8, 7> *>(external);
2223
+ }
2224
+ inline private_key<8, 7> *private_key_from_external_87(
2225
+ MLDSA87_private_key *external) {
2226
+ return reinterpret_cast<private_key<8, 7> *>(external);
2227
+ }
2228
+
2229
+ static_assert(sizeof(MLDSA87_public_key) == sizeof(public_key<8>));
2230
+ static_assert(alignof(MLDSA87_public_key) == alignof(public_key<8>));
2231
+
2232
+ inline const public_key<8> *public_key_from_external_87(
2233
+ const MLDSA87_public_key *external) {
2234
+ return reinterpret_cast<const public_key<8> *>(external);
2235
+ }
2236
+ inline public_key<8> *public_key_from_external_87(
2237
+ MLDSA87_public_key *external) {
2238
+ return reinterpret_cast<public_key<8> *>(external);
2239
+ }
2240
+
2241
+ inline prehash_context *prehash_context_from_external_87(
2242
+ MLDSA87_prehash *external) {
2243
+ static_assert(sizeof(MLDSA87_prehash) == sizeof(prehash_context));
2244
+ static_assert(alignof(MLDSA87_prehash) == alignof(prehash_context));
2245
+ return reinterpret_cast<prehash_context *>(external);
2246
+ }
2247
+
2248
+ static_assert(sizeof(MLDSA44_private_key) == sizeof(private_key<4, 4>));
2249
+ static_assert(alignof(MLDSA44_private_key) == alignof(private_key<4, 4>));
2250
+
2251
+ inline const private_key<4, 4> *private_key_from_external_44(
2252
+ const MLDSA44_private_key *external) {
2253
+ return reinterpret_cast<const private_key<4, 4> *>(external);
2254
+ }
2255
+ inline private_key<4, 4> *private_key_from_external_44(
2256
+ MLDSA44_private_key *external) {
2257
+ return reinterpret_cast<private_key<4, 4> *>(external);
2258
+ }
2259
+
2260
+ static_assert(sizeof(MLDSA44_public_key) == sizeof(public_key<4>));
2261
+ static_assert(alignof(MLDSA44_public_key) == alignof(public_key<4>));
2262
+
2263
+ inline const public_key<4> *public_key_from_external_44(
2264
+ const MLDSA44_public_key *external) {
2265
+ return reinterpret_cast<const public_key<4> *>(external);
2266
+ }
2267
+ inline public_key<4> *public_key_from_external_44(
2268
+ MLDSA44_public_key *external) {
2269
+ return reinterpret_cast<public_key<4> *>(external);
2270
+ }
2271
+
2272
+ inline prehash_context *prehash_context_from_external_44(
2273
+ MLDSA44_prehash *external) {
2274
+ static_assert(sizeof(MLDSA44_prehash) == sizeof(prehash_context));
2275
+ static_assert(alignof(MLDSA44_prehash) == alignof(prehash_context));
2276
+ return reinterpret_cast<prehash_context *>(external);
1808
2277
  }
1809
2278
 
1810
2279
  namespace fips {
1811
2280
 
1812
2281
  #include "fips_known_values.inc"
1813
2282
 
1814
- static int keygen_self_test() {
1815
- private_key<6, 5> priv;
1816
- uint8_t pub_bytes[BCM_MLDSA65_PUBLIC_KEY_BYTES];
1817
- if (!mldsa_generate_key_external_entropy_no_self_test(pub_bytes, &priv,
1818
- kGenerateKeyEntropy)) {
2283
+ inline int keygen_self_test() {
2284
+ struct Values {
2285
+ enum { kAllowUniquePtr = true };
2286
+ private_key<6, 5> priv;
2287
+ uint8_t pub_bytes[MLDSA65_PUBLIC_KEY_BYTES];
2288
+ uint8_t priv_bytes[BCM_MLDSA65_PRIVATE_KEY_BYTES];
2289
+ };
2290
+ auto values = MakeUnique<Values>();
2291
+ if (values == nullptr ||
2292
+ !mldsa_generate_key_external_entropy_no_self_test(
2293
+ values->pub_bytes, &values->priv, kGenerateKeyEntropy)) {
1819
2294
  return 0;
1820
2295
  }
1821
2296
 
1822
- uint8_t priv_bytes[BCM_MLDSA65_PRIVATE_KEY_BYTES];
1823
2297
  CBB cbb;
1824
- CBB_init_fixed(&cbb, priv_bytes, sizeof(priv_bytes));
1825
- if (!mldsa_marshal_private_key(&cbb, &priv)) {
2298
+ CBB_init_fixed(&cbb, values->priv_bytes, sizeof(values->priv_bytes));
2299
+ if (!mldsa_marshal_private_key(&cbb, &values->priv)) {
1826
2300
  return 0;
1827
2301
  }
1828
2302
 
1829
- static_assert(sizeof(pub_bytes) == sizeof(kExpectedPublicKey));
1830
- static_assert(sizeof(priv_bytes) == sizeof(kExpectedPrivateKey));
1831
- if (!BORINGSSL_check_test(kExpectedPublicKey, pub_bytes, sizeof(pub_bytes),
2303
+ if (!BORINGSSL_check_test(kExpectedPublicKey, values->pub_bytes,
1832
2304
  "ML-DSA keygen public key") ||
1833
- !BORINGSSL_check_test(kExpectedPrivateKey, priv_bytes, sizeof(priv_bytes),
2305
+ !BORINGSSL_check_test(kExpectedPrivateKey, values->priv_bytes,
1834
2306
  "ML-DSA keygen private key")) {
1835
2307
  return 0;
1836
2308
  }
@@ -1838,36 +2310,42 @@ static int keygen_self_test() {
1838
2310
  return 1;
1839
2311
  }
1840
2312
 
1841
- static int sign_self_test() {
1842
- private_key<6, 5> priv;
1843
- uint8_t pub_bytes[BCM_MLDSA65_PUBLIC_KEY_BYTES];
1844
- if (!mldsa_generate_key_external_entropy(pub_bytes, &priv, kSignEntropy)) {
2313
+ inline int sign_self_test() {
2314
+ struct Values {
2315
+ enum { kAllowUniquePtr = true };
2316
+ private_key<6, 5> priv;
2317
+ uint8_t pub_bytes[MLDSA65_PUBLIC_KEY_BYTES];
2318
+ uint8_t sig[MLDSA65_SIGNATURE_BYTES];
2319
+ };
2320
+ auto values = MakeUnique<Values>();
2321
+ if (values == nullptr ||
2322
+ !mldsa_generate_key_external_entropy(values->pub_bytes, &values->priv,
2323
+ kSignEntropy)) {
1845
2324
  return 0;
1846
2325
  }
1847
2326
 
1848
2327
  const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES] = {};
1849
- uint8_t sig[BCM_MLDSA65_SIGNATURE_BYTES];
1850
2328
 
1851
2329
  // This message triggers the first restart case for signing.
1852
2330
  uint8_t message[4] = {0};
1853
- if (!mldsa_sign_internal_no_self_test(sig, &priv, message, sizeof(message),
1854
- nullptr, 0, nullptr, 0, randomizer)) {
2331
+ if (!mldsa_sign_internal_no_self_test(values->sig, &values->priv, message,
2332
+ sizeof(message), nullptr, 0, nullptr, 0,
2333
+ randomizer)) {
1855
2334
  return 0;
1856
2335
  }
1857
- static_assert(sizeof(kExpectedCase1Signature) == sizeof(sig));
1858
- if (!BORINGSSL_check_test(kExpectedCase1Signature, sig, sizeof(sig),
2336
+ if (!BORINGSSL_check_test(kExpectedCase1Signature, values->sig,
1859
2337
  "ML-DSA sign case 1")) {
1860
2338
  return 0;
1861
2339
  }
1862
2340
 
1863
2341
  // This message triggers the second restart case for signing.
1864
2342
  message[0] = 123;
1865
- if (!mldsa_sign_internal_no_self_test(sig, &priv, message, sizeof(message),
1866
- nullptr, 0, nullptr, 0, randomizer)) {
2343
+ if (!mldsa_sign_internal_no_self_test(values->sig, &values->priv, message,
2344
+ sizeof(message), nullptr, 0, nullptr, 0,
2345
+ randomizer)) {
1867
2346
  return 0;
1868
2347
  }
1869
- static_assert(sizeof(kExpectedCase2Signature) == sizeof(sig));
1870
- if (!BORINGSSL_check_test(kExpectedCase2Signature, sig, sizeof(sig),
2348
+ if (!BORINGSSL_check_test(kExpectedCase2Signature, values->sig,
1871
2349
  "ML-DSA sign case 2")) {
1872
2350
  return 0;
1873
2351
  }
@@ -1875,15 +2353,14 @@ static int sign_self_test() {
1875
2353
  return 1;
1876
2354
  }
1877
2355
 
1878
- static int verify_self_test() {
1879
- struct values_st {
2356
+ inline int verify_self_test() {
2357
+ struct Values {
2358
+ enum { kAllowUniquePtr = true };
1880
2359
  private_key<6, 5> priv;
1881
- public_key<6> pub;
1882
- uint8_t pub_bytes[BCM_MLDSA65_PUBLIC_KEY_BYTES];
2360
+ uint8_t pub_bytes[MLDSA65_PUBLIC_KEY_BYTES];
1883
2361
  };
1884
- std::unique_ptr<values_st, DeleterFree<values_st>> values(
1885
- reinterpret_cast<struct values_st *>(OPENSSL_malloc(sizeof(values_st))));
1886
- if (!values) {
2362
+ auto values = MakeUnique<Values>();
2363
+ if (values == nullptr) {
1887
2364
  return 0;
1888
2365
  }
1889
2366
 
@@ -1893,9 +2370,8 @@ static int verify_self_test() {
1893
2370
  }
1894
2371
 
1895
2372
  const uint8_t message[4] = {1, 0};
1896
- if (!mldsa_public_from_private(&values->pub, &values->priv) ||
1897
- !mldsa_verify_internal_no_self_test<6, 5>(
1898
- &values->pub, kExpectedVerifySignature, message, sizeof(message),
2373
+ if (!mldsa_verify_internal_no_self_test<6, 5>(
2374
+ &values->priv.pub, kExpectedVerifySignature, message, sizeof(message),
1899
2375
  nullptr, 0, nullptr, 0)) {
1900
2376
  return 0;
1901
2377
  }
@@ -1904,12 +2380,10 @@ static int verify_self_test() {
1904
2380
  }
1905
2381
 
1906
2382
  template <int K, int L>
1907
- int check_key(private_key<K, L> *priv) {
2383
+ inline int check_key(const private_key<K, L> *priv) {
1908
2384
  uint8_t sig[signature_bytes<K>()];
1909
2385
  uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES] = {};
1910
- mldsa::public_key<K> pub;
1911
- if (!mldsa_public_from_private(&pub, priv) ||
1912
- !mldsa_sign_internal_no_self_test(sig, priv, nullptr, 0, nullptr, 0,
2386
+ if (!mldsa_sign_internal_no_self_test(sig, priv, nullptr, 0, nullptr, 0,
1913
2387
  nullptr, 0, randomizer)) {
1914
2388
  return 0;
1915
2389
  }
@@ -1918,8 +2392,8 @@ int check_key(private_key<K, L> *priv) {
1918
2392
  sig[0] ^= 1;
1919
2393
  }
1920
2394
 
1921
- if (!mldsa_verify_internal_no_self_test<K, L>(&pub, sig, nullptr, 0, nullptr,
1922
- 0, nullptr, 0)) {
2395
+ if (!mldsa_verify_internal_no_self_test<K, L>(&priv->pub, sig, nullptr, 0,
2396
+ nullptr, 0, nullptr, 0)) {
1923
2397
  return 0;
1924
2398
  }
1925
2399
  return 1;
@@ -1927,9 +2401,7 @@ int check_key(private_key<K, L> *priv) {
1927
2401
 
1928
2402
  #if defined(BORINGSSL_FIPS)
1929
2403
 
1930
- DEFINE_STATIC_ONCE(g_mldsa_keygen_self_test_once)
1931
-
1932
- void ensure_keygen_self_test(void) {
2404
+ void ensure_keygen_self_test() {
1933
2405
  CRYPTO_once(g_mldsa_keygen_self_test_once_bss_get(), []() {
1934
2406
  if (!keygen_self_test()) {
1935
2407
  BORINGSSL_FIPS_abort();
@@ -1937,9 +2409,7 @@ void ensure_keygen_self_test(void) {
1937
2409
  });
1938
2410
  }
1939
2411
 
1940
- DEFINE_STATIC_ONCE(g_mldsa_sign_self_test_once)
1941
-
1942
- void ensure_sign_self_test(void) {
2412
+ void ensure_sign_self_test() {
1943
2413
  CRYPTO_once(g_mldsa_sign_self_test_once_bss_get(), []() {
1944
2414
  if (!sign_self_test()) {
1945
2415
  BORINGSSL_FIPS_abort();
@@ -1947,9 +2417,7 @@ void ensure_sign_self_test(void) {
1947
2417
  });
1948
2418
  }
1949
2419
 
1950
- DEFINE_STATIC_ONCE(g_mldsa_verify_self_test_once)
1951
-
1952
- void ensure_verify_self_test(void) {
2420
+ void ensure_verify_self_test() {
1953
2421
  CRYPTO_once(g_mldsa_verify_self_test_once_bss_get(), []() {
1954
2422
  if (!verify_self_test()) {
1955
2423
  BORINGSSL_FIPS_abort();
@@ -1959,9 +2427,9 @@ void ensure_verify_self_test(void) {
1959
2427
 
1960
2428
  #else
1961
2429
 
1962
- void ensure_keygen_self_test(void) {}
1963
- void ensure_sign_self_test(void) {}
1964
- void ensure_verify_self_test(void) {}
2430
+ void ensure_keygen_self_test() {}
2431
+ void ensure_sign_self_test() {}
2432
+ void ensure_verify_self_test() {}
1965
2433
 
1966
2434
  #endif
1967
2435
 
@@ -1973,65 +2441,62 @@ void ensure_verify_self_test(void) {}
1973
2441
 
1974
2442
  // ML-DSA-65 specific wrappers.
1975
2443
 
1976
- bcm_status BCM_mldsa65_parse_public_key(
1977
- struct BCM_mldsa65_public_key *public_key, CBS *in) {
2444
+ bcm_status bssl::BCM_mldsa65_parse_public_key(MLDSA65_public_key *public_key,
2445
+ CBS *in) {
1978
2446
  return bcm_as_approved_status(mldsa_parse_public_key(
1979
2447
  mldsa::public_key_from_external_65(public_key), in));
1980
2448
  }
1981
2449
 
1982
- bcm_status BCM_mldsa65_marshal_private_key(
1983
- CBB *out, const struct BCM_mldsa65_private_key *private_key) {
2450
+ bcm_status bssl::BCM_mldsa65_marshal_private_key(
2451
+ CBB *out, const MLDSA65_private_key *private_key) {
1984
2452
  return bcm_as_approved_status(mldsa_marshal_private_key(
1985
2453
  out, mldsa::private_key_from_external_65(private_key)));
1986
2454
  }
1987
2455
 
1988
- bcm_status BCM_mldsa65_parse_private_key(
1989
- struct BCM_mldsa65_private_key *private_key, CBS *in) {
2456
+ bcm_status bssl::BCM_mldsa65_parse_private_key(MLDSA65_private_key *private_key,
2457
+ CBS *in) {
1990
2458
  return bcm_as_approved_status(
1991
2459
  mldsa_parse_private_key(mldsa::private_key_from_external_65(private_key),
1992
2460
  in) &&
1993
2461
  CBS_len(in) == 0);
1994
2462
  }
1995
2463
 
1996
- bcm_status BCM_mldsa65_check_key_fips(
1997
- struct BCM_mldsa65_private_key *private_key) {
2464
+ bcm_status bssl::BCM_mldsa65_check_key_fips(MLDSA65_private_key *private_key) {
1998
2465
  return bcm_as_approved_status(
1999
2466
  mldsa::fips::check_key(mldsa::private_key_from_external_65(private_key)));
2000
2467
  }
2001
2468
 
2002
- // Calls |MLDSA_generate_key_external_entropy| with random bytes from
2003
- // |BCM_rand_bytes|.
2004
- bcm_status BCM_mldsa65_generate_key(
2005
- uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
2006
- uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
2007
- struct BCM_mldsa65_private_key *out_private_key) {
2008
- BCM_rand_bytes(out_seed, BCM_MLDSA_SEED_BYTES);
2009
- CONSTTIME_SECRET(out_seed, BCM_MLDSA_SEED_BYTES);
2469
+ // Calls `MLDSA_generate_key_external_entropy` with random bytes from
2470
+ // `BCM_rand_bytes`.
2471
+ bcm_status bssl::BCM_mldsa65_generate_key(
2472
+ uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
2473
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA65_private_key *out_private_key) {
2474
+ BCM_rand_bytes(out_seed, MLDSA_SEED_BYTES);
2475
+ CONSTTIME_SECRET(out_seed, MLDSA_SEED_BYTES);
2010
2476
  return BCM_mldsa65_generate_key_external_entropy(out_encoded_public_key,
2011
2477
  out_private_key, out_seed);
2012
2478
  }
2013
2479
 
2014
- bcm_status BCM_mldsa65_private_key_from_seed(
2015
- struct BCM_mldsa65_private_key *out_private_key,
2016
- const uint8_t seed[BCM_MLDSA_SEED_BYTES]) {
2017
- uint8_t public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES];
2480
+ bcm_status bssl::BCM_mldsa65_private_key_from_seed(
2481
+ MLDSA65_private_key *out_private_key,
2482
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
2483
+ uint8_t public_key[MLDSA65_PUBLIC_KEY_BYTES];
2018
2484
  return BCM_mldsa65_generate_key_external_entropy(public_key, out_private_key,
2019
2485
  seed);
2020
2486
  }
2021
2487
 
2022
- bcm_status BCM_mldsa65_generate_key_external_entropy(
2023
- uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
2024
- struct BCM_mldsa65_private_key *out_private_key,
2025
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
2488
+ bcm_status bssl::BCM_mldsa65_generate_key_external_entropy(
2489
+ uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
2490
+ MLDSA65_private_key *out_private_key,
2491
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2026
2492
  return bcm_as_not_approved_status(mldsa_generate_key_external_entropy(
2027
2493
  out_encoded_public_key,
2028
2494
  mldsa::private_key_from_external_65(out_private_key), entropy));
2029
2495
  }
2030
2496
 
2031
- bcm_status BCM_mldsa65_generate_key_fips(
2032
- uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
2033
- uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
2034
- struct BCM_mldsa65_private_key *out_private_key) {
2497
+ bcm_status bssl::BCM_mldsa65_generate_key_fips(
2498
+ uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
2499
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA65_private_key *out_private_key) {
2035
2500
  if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2036
2501
  return bcm_status::failure;
2037
2502
  }
@@ -2042,10 +2507,10 @@ bcm_status BCM_mldsa65_generate_key_fips(
2042
2507
  return BCM_mldsa65_check_key_fips(out_private_key);
2043
2508
  }
2044
2509
 
2045
- bcm_status BCM_mldsa65_generate_key_external_entropy_fips(
2046
- uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
2047
- struct BCM_mldsa65_private_key *out_private_key,
2048
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
2510
+ bcm_status bssl::BCM_mldsa65_generate_key_external_entropy_fips(
2511
+ uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES],
2512
+ MLDSA65_private_key *out_private_key,
2513
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2049
2514
  if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2050
2515
  return bcm_status::failure;
2051
2516
  }
@@ -2057,10 +2522,10 @@ bcm_status BCM_mldsa65_generate_key_external_entropy_fips(
2057
2522
  return BCM_mldsa65_check_key_fips(out_private_key);
2058
2523
  }
2059
2524
 
2060
- bcm_status BCM_mldsa65_private_key_from_seed_fips(
2061
- struct BCM_mldsa65_private_key *out_private_key,
2062
- const uint8_t seed[BCM_MLDSA_SEED_BYTES]) {
2063
- uint8_t public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES];
2525
+ bcm_status bssl::BCM_mldsa65_private_key_from_seed_fips(
2526
+ MLDSA65_private_key *out_private_key,
2527
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
2528
+ uint8_t public_key[MLDSA65_PUBLIC_KEY_BYTES];
2064
2529
  if (BCM_mldsa65_generate_key_external_entropy(public_key, out_private_key,
2065
2530
  seed) == bcm_status::failure) {
2066
2531
  return bcm_status::failure;
@@ -2068,18 +2533,25 @@ bcm_status BCM_mldsa65_private_key_from_seed_fips(
2068
2533
  return BCM_mldsa65_check_key_fips(out_private_key);
2069
2534
  }
2070
2535
 
2071
- bcm_status BCM_mldsa65_public_from_private(
2072
- struct BCM_mldsa65_public_key *out_public_key,
2073
- const struct BCM_mldsa65_private_key *private_key) {
2074
- return bcm_as_approved_status(mldsa_public_from_private(
2075
- mldsa::public_key_from_external_65(out_public_key),
2076
- mldsa::private_key_from_external_65(private_key)));
2536
+ bcm_status bssl::BCM_mldsa65_public_from_private(
2537
+ MLDSA65_public_key *out_public_key,
2538
+ const MLDSA65_private_key *private_key) {
2539
+ const auto *priv = mldsa::private_key_from_external_65(private_key);
2540
+ auto *out_pub = mldsa::public_key_from_external_65(out_public_key);
2541
+ *out_pub = priv->pub;
2542
+ return bcm_status::approved;
2077
2543
  }
2078
2544
 
2079
- bcm_status BCM_mldsa65_sign_internal(
2080
- uint8_t out_encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
2081
- const struct BCM_mldsa65_private_key *private_key, const uint8_t *msg,
2082
- size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
2545
+ const MLDSA65_public_key *bssl::BCM_mldsa65_public_of_private(
2546
+ const MLDSA65_private_key *private_key) {
2547
+ return reinterpret_cast<const MLDSA65_public_key *>(
2548
+ &mldsa::private_key_from_external_65(private_key)->pub);
2549
+ }
2550
+
2551
+ bcm_status bssl::BCM_mldsa65_sign_internal(
2552
+ uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES],
2553
+ const MLDSA65_private_key *private_key, const uint8_t *msg, size_t msg_len,
2554
+ const uint8_t *context_prefix, size_t context_prefix_len,
2083
2555
  const uint8_t *context, size_t context_len,
2084
2556
  const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2085
2557
  return bcm_as_approved_status(mldsa_sign_internal(
@@ -2088,12 +2560,22 @@ bcm_status BCM_mldsa65_sign_internal(
2088
2560
  randomizer));
2089
2561
  }
2090
2562
 
2563
+ bcm_status bssl::BCM_mldsa65_sign_mu_internal(
2564
+ uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES],
2565
+ const MLDSA65_private_key *private_key,
2566
+ const uint8_t msg_rep[MLDSA_MU_BYTES],
2567
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2568
+ return bcm_as_approved_status(mldsa_sign_mu(
2569
+ out_encoded_signature, mldsa::private_key_from_external_65(private_key),
2570
+ msg_rep, randomizer));
2571
+ }
2572
+
2091
2573
  // ML-DSA signature in randomized mode, filling the random bytes with
2092
- // |BCM_rand_bytes|.
2093
- bcm_status BCM_mldsa65_sign(
2094
- uint8_t out_encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
2095
- const struct BCM_mldsa65_private_key *private_key, const uint8_t *msg,
2096
- size_t msg_len, const uint8_t *context, size_t context_len) {
2574
+ // `BCM_rand_bytes`.
2575
+ bcm_status bssl::BCM_mldsa65_sign(
2576
+ uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES],
2577
+ const MLDSA65_private_key *private_key, const uint8_t *msg, size_t msg_len,
2578
+ const uint8_t *context, size_t context_len) {
2097
2579
  BSSL_CHECK(context_len <= 255);
2098
2580
  uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
2099
2581
  BCM_rand_bytes(randomizer, sizeof(randomizer));
@@ -2105,10 +2587,61 @@ bcm_status BCM_mldsa65_sign(
2105
2587
  sizeof(context_prefix), context, context_len, randomizer);
2106
2588
  }
2107
2589
 
2590
+ // ML-DSA pre-hashed API: initializing a pre-hashing context.
2591
+ void bssl::BCM_mldsa65_prehash_init(MLDSA65_prehash *out_prehash_ctx,
2592
+ const MLDSA65_public_key *public_key,
2593
+ const uint8_t *context,
2594
+ size_t context_len) {
2595
+ BSSL_CHECK(context_len <= 255);
2596
+
2597
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
2598
+ mldsa_prehash_init(mldsa::prehash_context_from_external_65(out_prehash_ctx),
2599
+ mldsa::public_key_from_external_65(public_key),
2600
+ context_prefix, sizeof(context_prefix), context,
2601
+ context_len);
2602
+ }
2603
+
2604
+ // ML-DSA pre-hashed API: updating a pre-hashing context with a message chunk.
2605
+ void bssl::BCM_mldsa65_prehash_update(MLDSA65_prehash *inout_prehash_ctx,
2606
+ const uint8_t *msg, size_t msg_len) {
2607
+ mldsa_prehash_update(
2608
+ mldsa::prehash_context_from_external_65(inout_prehash_ctx), msg, msg_len);
2609
+ }
2610
+
2611
+ // ML-DSA pre-hashed API: obtaining a message representative to sign.
2612
+ void bssl::BCM_mldsa65_prehash_finalize(uint8_t out_msg_rep[MLDSA_MU_BYTES],
2613
+ MLDSA65_prehash *inout_prehash_ctx) {
2614
+ mldsa_prehash_finalize(
2615
+ out_msg_rep, mldsa::prehash_context_from_external_65(inout_prehash_ctx));
2616
+ }
2617
+
2618
+ // ML-DSA pre-hashed API: signing a message representative.
2619
+ bcm_status bssl::BCM_mldsa65_sign_message_representative(
2620
+ uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES],
2621
+ const MLDSA65_private_key *private_key,
2622
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
2623
+ uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
2624
+ BCM_rand_bytes(randomizer, sizeof(randomizer));
2625
+ CONSTTIME_SECRET(randomizer, sizeof(randomizer));
2626
+
2627
+ return bcm_as_approved_status(mldsa_sign_mu(
2628
+ out_encoded_signature, mldsa::private_key_from_external_65(private_key),
2629
+ msg_rep, randomizer));
2630
+ }
2631
+
2632
+ // ML-DSA pre-hashed API: verifying a message representative.
2633
+ bcm_status bssl::BCM_mldsa65_verify_message_representative(
2634
+ const MLDSA65_public_key *public_key,
2635
+ const uint8_t signature[MLDSA65_SIGNATURE_BYTES],
2636
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
2637
+ return bcm_as_approved_status(mldsa::mldsa_verify_mu<6, 5>(
2638
+ mldsa::public_key_from_external_65(public_key), signature, msg_rep));
2639
+ }
2640
+
2108
2641
  // FIPS 204, Algorithm 3 (`ML-DSA.Verify`).
2109
- bcm_status BCM_mldsa65_verify(
2110
- const struct BCM_mldsa65_public_key *public_key,
2111
- const uint8_t signature[BCM_MLDSA65_SIGNATURE_BYTES], const uint8_t *msg,
2642
+ bcm_status bssl::BCM_mldsa65_verify(
2643
+ const MLDSA65_public_key *public_key,
2644
+ const uint8_t signature[MLDSA65_SIGNATURE_BYTES], const uint8_t *msg,
2112
2645
  size_t msg_len, const uint8_t *context, size_t context_len) {
2113
2646
  BSSL_CHECK(context_len <= 255);
2114
2647
  const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
@@ -2117,9 +2650,9 @@ bcm_status BCM_mldsa65_verify(
2117
2650
  context, context_len);
2118
2651
  }
2119
2652
 
2120
- bcm_status BCM_mldsa65_verify_internal(
2121
- const struct BCM_mldsa65_public_key *public_key,
2122
- const uint8_t encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
2653
+ bcm_status bssl::BCM_mldsa65_verify_internal(
2654
+ const MLDSA65_public_key *public_key,
2655
+ const uint8_t encoded_signature[MLDSA65_SIGNATURE_BYTES],
2123
2656
  const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
2124
2657
  size_t context_prefix_len, const uint8_t *context, size_t context_len) {
2125
2658
  return bcm_as_approved_status(mldsa::mldsa_verify_internal<6, 5>(
@@ -2127,73 +2660,83 @@ bcm_status BCM_mldsa65_verify_internal(
2127
2660
  msg_len, context_prefix, context_prefix_len, context, context_len));
2128
2661
  }
2129
2662
 
2130
- bcm_status BCM_mldsa65_marshal_public_key(
2131
- CBB *out, const struct BCM_mldsa65_public_key *public_key) {
2663
+ bcm_status bssl::BCM_mldsa65_marshal_public_key(
2664
+ CBB *out, const MLDSA65_public_key *public_key) {
2132
2665
  return bcm_as_approved_status(mldsa_marshal_public_key(
2133
2666
  out, mldsa::public_key_from_external_65(public_key)));
2134
2667
  }
2135
2668
 
2669
+ int bssl::BCM_mldsa65_public_keys_equal(const MLDSA65_public_key *a,
2670
+ const MLDSA65_public_key *b) {
2671
+ auto *a_pub = mldsa::public_key_from_external_65(a);
2672
+ auto *b_pub = mldsa::public_key_from_external_65(b);
2673
+ // It is sufficient to compare `public_key_hash`. When importing a public key,
2674
+ // the hash must be computed. When importing a private key in expanded form
2675
+ // (an internal testing-only API), the hash is provided, but we recompute it
2676
+ // and check for correctness.
2677
+ return OPENSSL_memcmp(a_pub->public_key_hash, b_pub->public_key_hash,
2678
+ sizeof(a_pub->public_key_hash)) == 0;
2679
+ }
2680
+
2136
2681
 
2137
2682
  // ML-DSA-87 specific wrappers.
2138
2683
 
2139
- bcm_status BCM_mldsa87_parse_public_key(
2140
- struct BCM_mldsa87_public_key *public_key, CBS *in) {
2684
+ bcm_status bssl::BCM_mldsa87_parse_public_key(MLDSA87_public_key *public_key,
2685
+ CBS *in) {
2141
2686
  return bcm_as_approved_status(mldsa_parse_public_key(
2142
2687
  mldsa::public_key_from_external_87(public_key), in));
2143
2688
  }
2144
2689
 
2145
- bcm_status BCM_mldsa87_marshal_private_key(
2146
- CBB *out, const struct BCM_mldsa87_private_key *private_key) {
2690
+ bcm_status bssl::BCM_mldsa87_marshal_private_key(
2691
+ CBB *out, const MLDSA87_private_key *private_key) {
2147
2692
  return bcm_as_approved_status(mldsa_marshal_private_key(
2148
2693
  out, mldsa::private_key_from_external_87(private_key)));
2149
2694
  }
2150
2695
 
2151
- bcm_status BCM_mldsa87_parse_private_key(
2152
- struct BCM_mldsa87_private_key *private_key, CBS *in) {
2696
+ bcm_status bssl::BCM_mldsa87_parse_private_key(MLDSA87_private_key *private_key,
2697
+ CBS *in) {
2153
2698
  return bcm_as_approved_status(
2154
2699
  mldsa_parse_private_key(mldsa::private_key_from_external_87(private_key),
2155
2700
  in) &&
2156
2701
  CBS_len(in) == 0);
2157
2702
  }
2158
2703
 
2159
- bcm_status BCM_mldsa87_check_key_fips(
2160
- struct BCM_mldsa87_private_key *private_key) {
2704
+ bcm_status bssl::BCM_mldsa87_check_key_fips(MLDSA87_private_key *private_key) {
2161
2705
  return bcm_as_approved_status(
2162
2706
  mldsa::fips::check_key(mldsa::private_key_from_external_87(private_key)));
2163
2707
  }
2164
2708
 
2165
- // Calls |MLDSA_generate_key_external_entropy| with random bytes from
2166
- // |BCM_rand_bytes|.
2167
- bcm_status BCM_mldsa87_generate_key(
2168
- uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
2169
- uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
2170
- struct BCM_mldsa87_private_key *out_private_key) {
2171
- BCM_rand_bytes(out_seed, BCM_MLDSA_SEED_BYTES);
2709
+ // Calls `MLDSA_generate_key_external_entropy` with random bytes from
2710
+ // `BCM_rand_bytes`.
2711
+ bcm_status bssl::BCM_mldsa87_generate_key(
2712
+ uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES],
2713
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA87_private_key *out_private_key) {
2714
+ BCM_rand_bytes(out_seed, MLDSA_SEED_BYTES);
2715
+ CONSTTIME_SECRET(out_seed, MLDSA_SEED_BYTES);
2172
2716
  return BCM_mldsa87_generate_key_external_entropy(out_encoded_public_key,
2173
2717
  out_private_key, out_seed);
2174
2718
  }
2175
2719
 
2176
- bcm_status BCM_mldsa87_private_key_from_seed(
2177
- struct BCM_mldsa87_private_key *out_private_key,
2178
- const uint8_t seed[BCM_MLDSA_SEED_BYTES]) {
2179
- uint8_t public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES];
2720
+ bcm_status bssl::BCM_mldsa87_private_key_from_seed(
2721
+ MLDSA87_private_key *out_private_key,
2722
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
2723
+ uint8_t public_key[MLDSA87_PUBLIC_KEY_BYTES];
2180
2724
  return BCM_mldsa87_generate_key_external_entropy(public_key, out_private_key,
2181
2725
  seed);
2182
2726
  }
2183
2727
 
2184
- bcm_status BCM_mldsa87_generate_key_external_entropy(
2185
- uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
2186
- struct BCM_mldsa87_private_key *out_private_key,
2187
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
2728
+ bcm_status bssl::BCM_mldsa87_generate_key_external_entropy(
2729
+ uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES],
2730
+ MLDSA87_private_key *out_private_key,
2731
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2188
2732
  return bcm_as_not_approved_status(mldsa_generate_key_external_entropy(
2189
2733
  out_encoded_public_key,
2190
2734
  mldsa::private_key_from_external_87(out_private_key), entropy));
2191
2735
  }
2192
2736
 
2193
- bcm_status BCM_mldsa87_generate_key_fips(
2194
- uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
2195
- uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
2196
- struct BCM_mldsa87_private_key *out_private_key) {
2737
+ bcm_status bssl::BCM_mldsa87_generate_key_fips(
2738
+ uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES],
2739
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA87_private_key *out_private_key) {
2197
2740
  if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2198
2741
  return bcm_status::failure;
2199
2742
  }
@@ -2204,10 +2747,10 @@ bcm_status BCM_mldsa87_generate_key_fips(
2204
2747
  return BCM_mldsa87_check_key_fips(out_private_key);
2205
2748
  }
2206
2749
 
2207
- bcm_status BCM_mldsa87_generate_key_external_entropy_fips(
2208
- uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
2209
- struct BCM_mldsa87_private_key *out_private_key,
2210
- const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) {
2750
+ bcm_status bssl::BCM_mldsa87_generate_key_external_entropy_fips(
2751
+ uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES],
2752
+ MLDSA87_private_key *out_private_key,
2753
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2211
2754
  if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2212
2755
  return bcm_status::failure;
2213
2756
  }
@@ -2219,10 +2762,10 @@ bcm_status BCM_mldsa87_generate_key_external_entropy_fips(
2219
2762
  return BCM_mldsa87_check_key_fips(out_private_key);
2220
2763
  }
2221
2764
 
2222
- bcm_status BCM_mldsa87_private_key_from_seed_fips(
2223
- struct BCM_mldsa87_private_key *out_private_key,
2224
- const uint8_t seed[BCM_MLDSA_SEED_BYTES]) {
2225
- uint8_t public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES];
2765
+ bcm_status bssl::BCM_mldsa87_private_key_from_seed_fips(
2766
+ MLDSA87_private_key *out_private_key,
2767
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
2768
+ uint8_t public_key[MLDSA87_PUBLIC_KEY_BYTES];
2226
2769
  if (BCM_mldsa87_generate_key_external_entropy(public_key, out_private_key,
2227
2770
  seed) == bcm_status::failure) {
2228
2771
  return bcm_status::failure;
@@ -2230,18 +2773,25 @@ bcm_status BCM_mldsa87_private_key_from_seed_fips(
2230
2773
  return BCM_mldsa87_check_key_fips(out_private_key);
2231
2774
  }
2232
2775
 
2233
- bcm_status BCM_mldsa87_public_from_private(
2234
- struct BCM_mldsa87_public_key *out_public_key,
2235
- const struct BCM_mldsa87_private_key *private_key) {
2236
- return bcm_as_approved_status(mldsa_public_from_private(
2237
- mldsa::public_key_from_external_87(out_public_key),
2238
- mldsa::private_key_from_external_87(private_key)));
2776
+ bcm_status bssl::BCM_mldsa87_public_from_private(
2777
+ MLDSA87_public_key *out_public_key,
2778
+ const MLDSA87_private_key *private_key) {
2779
+ const auto *priv = mldsa::private_key_from_external_87(private_key);
2780
+ auto *out_pub = mldsa::public_key_from_external_87(out_public_key);
2781
+ *out_pub = priv->pub;
2782
+ return bcm_status::approved;
2239
2783
  }
2240
2784
 
2241
- bcm_status BCM_mldsa87_sign_internal(
2242
- uint8_t out_encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
2243
- const struct BCM_mldsa87_private_key *private_key, const uint8_t *msg,
2244
- size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
2785
+ const MLDSA87_public_key *bssl::BCM_mldsa87_public_of_private(
2786
+ const MLDSA87_private_key *private_key) {
2787
+ return reinterpret_cast<const MLDSA87_public_key *>(
2788
+ &mldsa::private_key_from_external_87(private_key)->pub);
2789
+ }
2790
+
2791
+ bcm_status bssl::BCM_mldsa87_sign_internal(
2792
+ uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES],
2793
+ const MLDSA87_private_key *private_key, const uint8_t *msg, size_t msg_len,
2794
+ const uint8_t *context_prefix, size_t context_prefix_len,
2245
2795
  const uint8_t *context, size_t context_len,
2246
2796
  const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2247
2797
  return bcm_as_approved_status(mldsa_sign_internal(
@@ -2250,15 +2800,26 @@ bcm_status BCM_mldsa87_sign_internal(
2250
2800
  randomizer));
2251
2801
  }
2252
2802
 
2803
+ bcm_status bssl::BCM_mldsa87_sign_mu_internal(
2804
+ uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES],
2805
+ const MLDSA87_private_key *private_key,
2806
+ const uint8_t msg_rep[MLDSA_MU_BYTES],
2807
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
2808
+ return bcm_as_approved_status(mldsa_sign_mu(
2809
+ out_encoded_signature, mldsa::private_key_from_external_87(private_key),
2810
+ msg_rep, randomizer));
2811
+ }
2812
+
2253
2813
  // ML-DSA signature in randomized mode, filling the random bytes with
2254
- // |BCM_rand_bytes|.
2255
- bcm_status BCM_mldsa87_sign(
2256
- uint8_t out_encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
2257
- const struct BCM_mldsa87_private_key *private_key, const uint8_t *msg,
2258
- size_t msg_len, const uint8_t *context, size_t context_len) {
2814
+ // `BCM_rand_bytes`.
2815
+ bcm_status bssl::BCM_mldsa87_sign(
2816
+ uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES],
2817
+ const MLDSA87_private_key *private_key, const uint8_t *msg, size_t msg_len,
2818
+ const uint8_t *context, size_t context_len) {
2259
2819
  BSSL_CHECK(context_len <= 255);
2260
2820
  uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
2261
2821
  BCM_rand_bytes(randomizer, sizeof(randomizer));
2822
+ CONSTTIME_SECRET(randomizer, sizeof(randomizer));
2262
2823
 
2263
2824
  const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
2264
2825
  return BCM_mldsa87_sign_internal(
@@ -2266,11 +2827,63 @@ bcm_status BCM_mldsa87_sign(
2266
2827
  sizeof(context_prefix), context, context_len, randomizer);
2267
2828
  }
2268
2829
 
2830
+ // ML-DSA pre-hashed API: initializing a pre-hashing context.
2831
+ void bssl::BCM_mldsa87_prehash_init(MLDSA87_prehash *out_prehash_ctx,
2832
+ const MLDSA87_public_key *public_key,
2833
+ const uint8_t *context,
2834
+ size_t context_len) {
2835
+ BSSL_CHECK(context_len <= 255);
2836
+
2837
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
2838
+ mldsa_prehash_init(mldsa::prehash_context_from_external_87(out_prehash_ctx),
2839
+ mldsa::public_key_from_external_87(public_key),
2840
+ context_prefix, sizeof(context_prefix), context,
2841
+ context_len);
2842
+ }
2843
+
2844
+ // ML-DSA pre-hashed API: updating a pre-hashing context with a message chunk.
2845
+ void bssl::BCM_mldsa87_prehash_update(MLDSA87_prehash *inout_prehash_ctx,
2846
+ const uint8_t *msg, size_t msg_len) {
2847
+ mldsa_prehash_update(
2848
+ mldsa::prehash_context_from_external_87(inout_prehash_ctx), msg, msg_len);
2849
+ }
2850
+
2851
+ // ML-DSA pre-hashed API: obtaining a message representative to sign.
2852
+ void bssl::BCM_mldsa87_prehash_finalize(uint8_t out_msg_rep[MLDSA_MU_BYTES],
2853
+ MLDSA87_prehash *inout_prehash_ctx) {
2854
+ mldsa_prehash_finalize(
2855
+ out_msg_rep, mldsa::prehash_context_from_external_87(inout_prehash_ctx));
2856
+ }
2857
+
2858
+ // ML-DSA pre-hashed API: signing a message representative.
2859
+ bcm_status bssl::BCM_mldsa87_sign_message_representative(
2860
+ uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES],
2861
+ const MLDSA87_private_key *private_key,
2862
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
2863
+ uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
2864
+ BCM_rand_bytes(randomizer, sizeof(randomizer));
2865
+ CONSTTIME_SECRET(randomizer, sizeof(randomizer));
2866
+
2867
+ return bcm_as_approved_status(mldsa_sign_mu(
2868
+ out_encoded_signature, mldsa::private_key_from_external_87(private_key),
2869
+ msg_rep, randomizer));
2870
+ }
2871
+
2872
+ // ML-DSA pre-hashed API: verifying a message representative.
2873
+ bcm_status bssl::BCM_mldsa87_verify_message_representative(
2874
+ const MLDSA87_public_key *public_key,
2875
+ const uint8_t signature[MLDSA87_SIGNATURE_BYTES],
2876
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
2877
+ return bcm_as_approved_status(mldsa::mldsa_verify_mu<8, 7>(
2878
+ mldsa::public_key_from_external_87(public_key), signature, msg_rep));
2879
+ }
2880
+
2269
2881
  // FIPS 204, Algorithm 3 (`ML-DSA.Verify`).
2270
- bcm_status BCM_mldsa87_verify(const struct BCM_mldsa87_public_key *public_key,
2271
- const uint8_t *signature, const uint8_t *msg,
2272
- size_t msg_len, const uint8_t *context,
2273
- size_t context_len) {
2882
+ bcm_status bssl::BCM_mldsa87_verify(const MLDSA87_public_key *public_key,
2883
+ const uint8_t *signature,
2884
+ const uint8_t *msg, size_t msg_len,
2885
+ const uint8_t *context,
2886
+ size_t context_len) {
2274
2887
  BSSL_CHECK(context_len <= 255);
2275
2888
  const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
2276
2889
  return BCM_mldsa87_verify_internal(public_key, signature, msg, msg_len,
@@ -2278,9 +2891,9 @@ bcm_status BCM_mldsa87_verify(const struct BCM_mldsa87_public_key *public_key,
2278
2891
  context, context_len);
2279
2892
  }
2280
2893
 
2281
- bcm_status BCM_mldsa87_verify_internal(
2282
- const struct BCM_mldsa87_public_key *public_key,
2283
- const uint8_t encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
2894
+ bcm_status bssl::BCM_mldsa87_verify_internal(
2895
+ const MLDSA87_public_key *public_key,
2896
+ const uint8_t encoded_signature[MLDSA87_SIGNATURE_BYTES],
2284
2897
  const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
2285
2898
  size_t context_prefix_len, const uint8_t *context, size_t context_len) {
2286
2899
  return bcm_as_approved_status(mldsa::mldsa_verify_internal<8, 7>(
@@ -2288,13 +2901,266 @@ bcm_status BCM_mldsa87_verify_internal(
2288
2901
  msg_len, context_prefix, context_prefix_len, context, context_len));
2289
2902
  }
2290
2903
 
2291
- bcm_status BCM_mldsa87_marshal_public_key(
2292
- CBB *out, const struct BCM_mldsa87_public_key *public_key) {
2904
+ bcm_status bssl::BCM_mldsa87_marshal_public_key(
2905
+ CBB *out, const MLDSA87_public_key *public_key) {
2293
2906
  return bcm_as_approved_status(mldsa_marshal_public_key(
2294
2907
  out, mldsa::public_key_from_external_87(public_key)));
2295
2908
  }
2296
2909
 
2297
- int boringssl_self_test_mldsa() {
2910
+ int bssl::BCM_mldsa87_public_keys_equal(const MLDSA87_public_key *a,
2911
+ const MLDSA87_public_key *b) {
2912
+ auto *a_pub = mldsa::public_key_from_external_87(a);
2913
+ auto *b_pub = mldsa::public_key_from_external_87(b);
2914
+ // It is sufficient to compare `public_key_hash`. When importing a public key,
2915
+ // the hash must be computed. When importing a private key in expanded form
2916
+ // (an internal testing-only API), the hash is provided, but we recompute it
2917
+ // and check for correctness.
2918
+ return OPENSSL_memcmp(a_pub->public_key_hash, b_pub->public_key_hash,
2919
+ sizeof(a_pub->public_key_hash)) == 0;
2920
+ }
2921
+
2922
+
2923
+ // ML-DSA-44 specific wrappers.
2924
+
2925
+ bcm_status bssl::BCM_mldsa44_parse_public_key(MLDSA44_public_key *public_key,
2926
+ CBS *in) {
2927
+ return bcm_as_approved_status(mldsa_parse_public_key(
2928
+ mldsa::public_key_from_external_44(public_key), in));
2929
+ }
2930
+
2931
+ bcm_status bssl::BCM_mldsa44_marshal_private_key(
2932
+ CBB *out, const MLDSA44_private_key *private_key) {
2933
+ return bcm_as_approved_status(mldsa_marshal_private_key(
2934
+ out, mldsa::private_key_from_external_44(private_key)));
2935
+ }
2936
+
2937
+ bcm_status bssl::BCM_mldsa44_parse_private_key(MLDSA44_private_key *private_key,
2938
+ CBS *in) {
2939
+ return bcm_as_approved_status(
2940
+ mldsa_parse_private_key(mldsa::private_key_from_external_44(private_key),
2941
+ in) &&
2942
+ CBS_len(in) == 0);
2943
+ }
2944
+
2945
+ bcm_status bssl::BCM_mldsa44_check_key_fips(MLDSA44_private_key *private_key) {
2946
+ return bcm_as_approved_status(
2947
+ mldsa::fips::check_key(mldsa::private_key_from_external_44(private_key)));
2948
+ }
2949
+
2950
+ // Calls `MLDSA_generate_key_external_entropy` with random bytes from
2951
+ // `BCM_rand_bytes`.
2952
+ bcm_status bssl::BCM_mldsa44_generate_key(
2953
+ uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES],
2954
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA44_private_key *out_private_key) {
2955
+ BCM_rand_bytes(out_seed, MLDSA_SEED_BYTES);
2956
+ CONSTTIME_SECRET(out_seed, MLDSA_SEED_BYTES);
2957
+ return BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key,
2958
+ out_private_key, out_seed);
2959
+ }
2960
+
2961
+ bcm_status bssl::BCM_mldsa44_private_key_from_seed(
2962
+ MLDSA44_private_key *out_private_key,
2963
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
2964
+ uint8_t public_key[MLDSA44_PUBLIC_KEY_BYTES];
2965
+ return BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key,
2966
+ seed);
2967
+ }
2968
+
2969
+ bcm_status bssl::BCM_mldsa44_generate_key_external_entropy(
2970
+ uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES],
2971
+ MLDSA44_private_key *out_private_key,
2972
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2973
+ return bcm_as_not_approved_status(mldsa_generate_key_external_entropy(
2974
+ out_encoded_public_key,
2975
+ mldsa::private_key_from_external_44(out_private_key), entropy));
2976
+ }
2977
+
2978
+ bcm_status bssl::BCM_mldsa44_generate_key_fips(
2979
+ uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES],
2980
+ uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA44_private_key *out_private_key) {
2981
+ if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2982
+ return bcm_status::failure;
2983
+ }
2984
+ if (BCM_mldsa44_generate_key(out_encoded_public_key, out_seed,
2985
+ out_private_key) == bcm_status::failure) {
2986
+ return bcm_status::failure;
2987
+ }
2988
+ return BCM_mldsa44_check_key_fips(out_private_key);
2989
+ }
2990
+
2991
+ bcm_status bssl::BCM_mldsa44_generate_key_external_entropy_fips(
2992
+ uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES],
2993
+ MLDSA44_private_key *out_private_key,
2994
+ const uint8_t entropy[MLDSA_SEED_BYTES]) {
2995
+ if (out_encoded_public_key == nullptr || out_private_key == nullptr) {
2996
+ return bcm_status::failure;
2997
+ }
2998
+ if (BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key,
2999
+ out_private_key, entropy) ==
3000
+ bcm_status::failure) {
3001
+ return bcm_status::failure;
3002
+ }
3003
+ return BCM_mldsa44_check_key_fips(out_private_key);
3004
+ }
3005
+
3006
+ bcm_status bssl::BCM_mldsa44_private_key_from_seed_fips(
3007
+ MLDSA44_private_key *out_private_key,
3008
+ const uint8_t seed[MLDSA_SEED_BYTES]) {
3009
+ uint8_t public_key[MLDSA44_PUBLIC_KEY_BYTES];
3010
+ if (BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key,
3011
+ seed) == bcm_status::failure) {
3012
+ return bcm_status::failure;
3013
+ }
3014
+ return BCM_mldsa44_check_key_fips(out_private_key);
3015
+ }
3016
+
3017
+ bcm_status bssl::BCM_mldsa44_public_from_private(
3018
+ MLDSA44_public_key *out_public_key,
3019
+ const MLDSA44_private_key *private_key) {
3020
+ const auto *priv = mldsa::private_key_from_external_44(private_key);
3021
+ auto *out_pub = mldsa::public_key_from_external_44(out_public_key);
3022
+ *out_pub = priv->pub;
3023
+ return bcm_status::approved;
3024
+ }
3025
+
3026
+ const MLDSA44_public_key *bssl::BCM_mldsa44_public_of_private(
3027
+ const MLDSA44_private_key *private_key) {
3028
+ return reinterpret_cast<const MLDSA44_public_key *>(
3029
+ &mldsa::private_key_from_external_44(private_key)->pub);
3030
+ }
3031
+
3032
+ bcm_status bssl::BCM_mldsa44_sign_internal(
3033
+ uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES],
3034
+ const MLDSA44_private_key *private_key, const uint8_t *msg, size_t msg_len,
3035
+ const uint8_t *context_prefix, size_t context_prefix_len,
3036
+ const uint8_t *context, size_t context_len,
3037
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
3038
+ return bcm_as_approved_status(mldsa_sign_internal(
3039
+ out_encoded_signature, mldsa::private_key_from_external_44(private_key),
3040
+ msg, msg_len, context_prefix, context_prefix_len, context, context_len,
3041
+ randomizer));
3042
+ }
3043
+
3044
+ bcm_status bssl::BCM_mldsa44_sign_mu_internal(
3045
+ uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES],
3046
+ const MLDSA44_private_key *private_key,
3047
+ const uint8_t msg_rep[MLDSA_MU_BYTES],
3048
+ const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) {
3049
+ return bcm_as_approved_status(mldsa_sign_mu(
3050
+ out_encoded_signature, mldsa::private_key_from_external_44(private_key),
3051
+ msg_rep, randomizer));
3052
+ }
3053
+
3054
+ // ML-DSA signature in randomized mode, filling the random bytes with
3055
+ // `BCM_rand_bytes`.
3056
+ bcm_status bssl::BCM_mldsa44_sign(
3057
+ uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES],
3058
+ const MLDSA44_private_key *private_key, const uint8_t *msg, size_t msg_len,
3059
+ const uint8_t *context, size_t context_len) {
3060
+ BSSL_CHECK(context_len <= 255);
3061
+ uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
3062
+ BCM_rand_bytes(randomizer, sizeof(randomizer));
3063
+ CONSTTIME_SECRET(randomizer, sizeof(randomizer));
3064
+
3065
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
3066
+ return BCM_mldsa44_sign_internal(
3067
+ out_encoded_signature, private_key, msg, msg_len, context_prefix,
3068
+ sizeof(context_prefix), context, context_len, randomizer);
3069
+ }
3070
+
3071
+ // ML-DSA pre-hashed API: initializing a pre-hashing context.
3072
+ void bssl::BCM_mldsa44_prehash_init(MLDSA44_prehash *out_prehash_ctx,
3073
+ const MLDSA44_public_key *public_key,
3074
+ const uint8_t *context,
3075
+ size_t context_len) {
3076
+ BSSL_CHECK(context_len <= 255);
3077
+
3078
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
3079
+ mldsa_prehash_init(mldsa::prehash_context_from_external_44(out_prehash_ctx),
3080
+ mldsa::public_key_from_external_44(public_key),
3081
+ context_prefix, sizeof(context_prefix), context,
3082
+ context_len);
3083
+ }
3084
+
3085
+ // ML-DSA pre-hashed API: updating a pre-hashing context with a message chunk.
3086
+ void bssl::BCM_mldsa44_prehash_update(MLDSA44_prehash *inout_prehash_ctx,
3087
+ const uint8_t *msg, size_t msg_len) {
3088
+ mldsa_prehash_update(
3089
+ mldsa::prehash_context_from_external_44(inout_prehash_ctx), msg, msg_len);
3090
+ }
3091
+
3092
+ // ML-DSA pre-hashed API: obtaining a message representative to sign.
3093
+ void bssl::BCM_mldsa44_prehash_finalize(uint8_t out_msg_rep[MLDSA_MU_BYTES],
3094
+ MLDSA44_prehash *inout_prehash_ctx) {
3095
+ mldsa_prehash_finalize(
3096
+ out_msg_rep, mldsa::prehash_context_from_external_44(inout_prehash_ctx));
3097
+ }
3098
+
3099
+ // ML-DSA pre-hashed API: signing a message representative.
3100
+ bcm_status bssl::BCM_mldsa44_sign_message_representative(
3101
+ uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES],
3102
+ const MLDSA44_private_key *private_key,
3103
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
3104
+ uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES];
3105
+ BCM_rand_bytes(randomizer, sizeof(randomizer));
3106
+ CONSTTIME_SECRET(randomizer, sizeof(randomizer));
3107
+
3108
+ return bcm_as_approved_status(mldsa_sign_mu(
3109
+ out_encoded_signature, mldsa::private_key_from_external_44(private_key),
3110
+ msg_rep, randomizer));
3111
+ }
3112
+
3113
+ // ML-DSA pre-hashed API: verifying a message representative.
3114
+ bcm_status bssl::BCM_mldsa44_verify_message_representative(
3115
+ const MLDSA44_public_key *public_key,
3116
+ const uint8_t signature[MLDSA44_SIGNATURE_BYTES],
3117
+ const uint8_t msg_rep[MLDSA_MU_BYTES]) {
3118
+ return bcm_as_approved_status(mldsa::mldsa_verify_mu<4, 4>(
3119
+ mldsa::public_key_from_external_44(public_key), signature, msg_rep));
3120
+ }
3121
+
3122
+ // FIPS 204, Algorithm 3 (`ML-DSA.Verify`).
3123
+ bcm_status bssl::BCM_mldsa44_verify(const MLDSA44_public_key *public_key,
3124
+ const uint8_t *signature,
3125
+ const uint8_t *msg, size_t msg_len,
3126
+ const uint8_t *context,
3127
+ size_t context_len) {
3128
+ BSSL_CHECK(context_len <= 255);
3129
+ const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context_len)};
3130
+ return BCM_mldsa44_verify_internal(public_key, signature, msg, msg_len,
3131
+ context_prefix, sizeof(context_prefix),
3132
+ context, context_len);
3133
+ }
3134
+
3135
+ bcm_status bssl::BCM_mldsa44_verify_internal(
3136
+ const MLDSA44_public_key *public_key,
3137
+ const uint8_t encoded_signature[MLDSA44_SIGNATURE_BYTES],
3138
+ const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
3139
+ size_t context_prefix_len, const uint8_t *context, size_t context_len) {
3140
+ return bcm_as_approved_status(mldsa::mldsa_verify_internal<4, 4>(
3141
+ mldsa::public_key_from_external_44(public_key), encoded_signature, msg,
3142
+ msg_len, context_prefix, context_prefix_len, context, context_len));
3143
+ }
3144
+
3145
+ bcm_status bssl::BCM_mldsa44_marshal_public_key(
3146
+ CBB *out, const MLDSA44_public_key *public_key) {
3147
+ return bcm_as_approved_status(mldsa_marshal_public_key(
3148
+ out, mldsa::public_key_from_external_44(public_key)));
3149
+ }
3150
+
3151
+ int bssl::BCM_mldsa44_public_keys_equal(const MLDSA44_public_key *a,
3152
+ const MLDSA44_public_key *b) {
3153
+ auto *a_pub = mldsa::public_key_from_external_44(a);
3154
+ auto *b_pub = mldsa::public_key_from_external_44(b);
3155
+ // It is sufficient to compare `public_key_hash`. When importing a public key,
3156
+ // the hash must be computed. When importing a private key in expanded form
3157
+ // (an internal testing-only API), the hash is provided, but we recompute it
3158
+ // and check for correctness.
3159
+ return OPENSSL_memcmp(a_pub->public_key_hash, b_pub->public_key_hash,
3160
+ sizeof(a_pub->public_key_hash)) == 0;
3161
+ }
3162
+
3163
+ int bssl::boringssl_self_test_mldsa() {
2298
3164
  return mldsa::fips::keygen_self_test() && mldsa::fips::sign_self_test() &&
2299
3165
  mldsa::fips::verify_self_test();
2300
3166
  }