mldsa_gh 0.1.0

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 (128) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +88 -0
  4. data/ext/mldsa_gh_native/extconf.rb +14 -0
  5. data/ext/mldsa_gh_native/mldsa_gh_native.c +222 -0
  6. data/ext/mldsa_gh_native/mldsa_gh_native_all.c +24 -0
  7. data/ext/mldsa_gh_native/mldsa_gh_native_all.h +26 -0
  8. data/ext/mldsa_gh_native/vendor/mldsa-native/BUILDING.md +108 -0
  9. data/ext/mldsa_gh_native/vendor/mldsa-native/LICENSE +305 -0
  10. data/ext/mldsa_gh_native/vendor/mldsa-native/README.md +247 -0
  11. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/README.md +23 -0
  12. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.c +803 -0
  13. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native.h +956 -0
  14. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_asm.S +830 -0
  15. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/mldsa_native_config.h +855 -0
  16. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/cbmc.h +233 -0
  17. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/common.h +301 -0
  18. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/context.h +152 -0
  19. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.c +21 -0
  20. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/ct.h +373 -0
  21. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.c +75 -0
  22. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/debug.h +125 -0
  23. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.c +270 -0
  24. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202.h +224 -0
  25. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.c +187 -0
  26. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/fips202x4.h +125 -0
  27. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.c +510 -0
  28. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/keccakf1600.h +110 -0
  29. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/auto.h +85 -0
  30. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/fips202_native_aarch64.h +69 -0
  31. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_scalar_aarch64_asm.S +378 -0
  32. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x1_v84a_aarch64_asm.S +207 -0
  33. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x2_v84a_aarch64_asm.S +262 -0
  34. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_scalar_hybrid_aarch64_asm.S +1080 -0
  35. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccak_f1600_x4_v8a_v84a_scalar_hybrid_aarch64_asm.S +990 -0
  36. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/src/keccakf1600_round_constants.c +47 -0
  37. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_scalar.h +27 -0
  38. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x1_v84a.h +36 -0
  39. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x2_v84a.h +40 -0
  40. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_scalar.h +32 -0
  41. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/aarch64/x4_v8a_v84a_scalar.h +37 -0
  42. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/api.h +129 -0
  43. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/README.md +10 -0
  44. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/mve.h +67 -0
  45. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/fips202_native_armv81m.h +37 -0
  46. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.S +717 -0
  47. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_mve.c +42 -0
  48. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_extract_bytes_mve.S +334 -0
  49. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccak_f1600_x4_state_xor_bytes_mve.S +355 -0
  50. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/armv81m/src/keccakf1600_round_constants.c +53 -0
  51. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/auto.h +35 -0
  52. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/keccak_f1600_x4_avx2.h +34 -0
  53. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/fips202_native_x86_64.h +45 -0
  54. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccak_f1600_x4_avx2_asm.S +488 -0
  55. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/fips202/native/x86_64/src/keccakf1600_constants.c +52 -0
  56. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/meta.h +314 -0
  57. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/aarch64_zetas.c +248 -0
  58. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/arith_native_aarch64.h +367 -0
  59. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_intt_aarch64_asm.S +786 -0
  60. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_ntt_aarch64_asm.S +686 -0
  61. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_pointwise_montgomery_aarch64_asm.S +106 -0
  62. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_caddq_aarch64_asm.S +69 -0
  63. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_chknorm_aarch64_asm.S +76 -0
  64. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_32_aarch64_asm.S +108 -0
  65. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_decompose_88_aarch64_asm.S +108 -0
  66. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_32_aarch64_asm.S +125 -0
  67. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_poly_use_hint_88_aarch64_asm.S +133 -0
  68. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l4_aarch64_asm.S +157 -0
  69. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l5_aarch64_asm.S +173 -0
  70. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyvecl_pointwise_acc_montgomery_l7_aarch64_asm.S +205 -0
  71. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_17_aarch64_asm.S +103 -0
  72. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_polyz_unpack_19_aarch64_asm.S +100 -0
  73. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_aarch64_asm.S +222 -0
  74. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta2_aarch64_asm.S +170 -0
  75. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/mldsa_rej_uniform_eta4_aarch64_asm.S +163 -0
  76. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/polyz_unpack_table.c +52 -0
  77. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_eta_table.c +547 -0
  78. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/aarch64/src/rej_uniform_table.c +63 -0
  79. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/api.h +617 -0
  80. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/meta.h +24 -0
  81. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/meta.h +323 -0
  82. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/arith_native_x86_64.h +330 -0
  83. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.c +157 -0
  84. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/consts.h +27 -0
  85. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_intt_avx2_asm.S +2333 -0
  86. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_ntt_avx2_asm.S +2405 -0
  87. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_nttunpack_avx2_asm.S +254 -0
  88. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l4_avx2_asm.S +173 -0
  89. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l5_avx2_asm.S +189 -0
  90. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_acc_l7_avx2_asm.S +221 -0
  91. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_pointwise_avx2_asm.S +158 -0
  92. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_caddq_avx2_asm.S +199 -0
  93. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_chknorm_avx2_asm.S +176 -0
  94. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_32_avx2_asm.S +490 -0
  95. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_decompose_88_avx2_asm.S +489 -0
  96. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_32_avx2_asm.S +123 -0
  97. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_poly_use_hint_88_avx2_asm.S +125 -0
  98. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_17_avx2_asm.S +355 -0
  99. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_polyz_unpack_19_avx2_asm.S +355 -0
  100. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_avx2_asm.S +132 -0
  101. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta2_avx2_asm.S +205 -0
  102. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/mldsa_rej_uniform_eta4_avx2_asm.S +176 -0
  103. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/native/x86_64/src/rej_uniform_table.c +161 -0
  104. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.c +213 -0
  105. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/packing.h +277 -0
  106. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/params.h +153 -0
  107. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.c +1066 -0
  108. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly.h +464 -0
  109. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.c +910 -0
  110. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/poly_kl.h +367 -0
  111. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.c +509 -0
  112. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec.h +435 -0
  113. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.c +311 -0
  114. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/polyvec_lazy.h +652 -0
  115. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/randombytes.h +26 -0
  116. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/reduce.h +144 -0
  117. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/rounding.h +265 -0
  118. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.c +1720 -0
  119. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sign.h +850 -0
  120. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/symmetric.h +68 -0
  121. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/sys.h +327 -0
  122. data/ext/mldsa_gh_native/vendor/mldsa-native/mldsa/src/zetas.inc +55 -0
  123. data/lib/mldsa/parameter_set.rb +82 -0
  124. data/lib/mldsa/signing_key.rb +147 -0
  125. data/lib/mldsa/verify_key.rb +72 -0
  126. data/lib/mldsa/version.rb +7 -0
  127. data/lib/mldsa_gh.rb +93 -0
  128. metadata +225 -0
@@ -0,0 +1,956 @@
1
+ /*
2
+ * Copyright (c) The mldsa-native project authors
3
+ * SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
4
+ */
5
+
6
+ /* References
7
+ * ==========
8
+ *
9
+ * - [FIPS204]
10
+ * FIPS 204 Module-Lattice-Based Digital Signature Standard
11
+ * National Institute of Standards and Technology
12
+ * https://csrc.nist.gov/pubs/fips/204/final
13
+ */
14
+
15
+ #ifndef MLD_H
16
+ #define MLD_H
17
+
18
+ /*
19
+ * Public API for mldsa-native
20
+ *
21
+ * This header defines the public API of a single build of mldsa-native.
22
+ *
23
+ * Make sure the configuration file is in the include path
24
+ * (this is "mldsa_native_config.h" by default, or MLD_CONFIG_FILE if defined).
25
+ *
26
+ * # API conventions
27
+ *
28
+ * Conventions shared by all functions below (return values, pointer validity,
29
+ * output buffers on error) are documented in API-CONVENTIONS.md.
30
+ *
31
+ * # Multi-level builds
32
+ *
33
+ * This header specifies a build of mldsa-native for a fixed security level.
34
+ * If you need multiple security levels, leave the security level unspecified
35
+ * in the configuration file and include this header multiple times, setting
36
+ * MLD_CONFIG_PARAMETER_SET accordingly for each, and #undef'ing the MLD_H
37
+ * guard to allow multiple inclusions.
38
+ */
39
+
40
+ /******************************* Key sizes ************************************/
41
+
42
+ /* Sizes of cryptographic material, per parameter set */
43
+ /* See mldsa/src/params.h for the arithmetic expressions giving rise to these */
44
+ /* check-magic: off */
45
+ #define MLDSA44_SECRETKEYBYTES 2560
46
+ #define MLDSA44_PUBLICKEYBYTES 1312
47
+ #define MLDSA44_BYTES 2420
48
+
49
+ #define MLDSA65_SECRETKEYBYTES 4032
50
+ #define MLDSA65_PUBLICKEYBYTES 1952
51
+ #define MLDSA65_BYTES 3309
52
+
53
+ #define MLDSA87_SECRETKEYBYTES 4896
54
+ #define MLDSA87_PUBLICKEYBYTES 2592
55
+ #define MLDSA87_BYTES 4627
56
+ /* check-magic: on */
57
+
58
+ /* Size of seed and randomness in bytes (level-independent) */
59
+ #define MLDSA_SEEDBYTES 32
60
+ #define MLDSA44_SEEDBYTES MLDSA_SEEDBYTES
61
+ #define MLDSA65_SEEDBYTES MLDSA_SEEDBYTES
62
+ #define MLDSA87_SEEDBYTES MLDSA_SEEDBYTES
63
+
64
+ /* Size of CRH output in bytes (level-independent) */
65
+ #define MLDSA_CRHBYTES 64
66
+ #define MLDSA44_CRHBYTES MLDSA_CRHBYTES
67
+ #define MLDSA65_CRHBYTES MLDSA_CRHBYTES
68
+ #define MLDSA87_CRHBYTES MLDSA_CRHBYTES
69
+
70
+ /* Size of TR in bytes (level-independent)
71
+ *
72
+ * TR = SHAKE256(pk, 64) is the hash of the public key. Callers of the
73
+ * external-mu API (signature_extmu / verify_extmu) that compute the message
74
+ * representative mu = SHAKE256(TR || M', MLDSA_CRHBYTES) themselves -- e.g. to
75
+ * sign or verify a message that is too large or streamed to hold in memory --
76
+ * need this constant to size the TR buffer. */
77
+ #define MLDSA_TRBYTES 64
78
+ #define MLDSA44_TRBYTES MLDSA_TRBYTES
79
+ #define MLDSA65_TRBYTES MLDSA_TRBYTES
80
+ #define MLDSA87_TRBYTES MLDSA_TRBYTES
81
+
82
+ /* Size of randomness for signing in bytes (level-independent) */
83
+ #define MLDSA_RNDBYTES 32
84
+ #define MLDSA44_RNDBYTES MLDSA_RNDBYTES
85
+ #define MLDSA65_RNDBYTES MLDSA_RNDBYTES
86
+ #define MLDSA87_RNDBYTES MLDSA_RNDBYTES
87
+
88
+ /* Sizes of cryptographic material, as a function of LVL=44,65,87 */
89
+ #define MLDSA_SECRETKEYBYTES_(LVL) MLDSA##LVL##_SECRETKEYBYTES
90
+ #define MLDSA_PUBLICKEYBYTES_(LVL) MLDSA##LVL##_PUBLICKEYBYTES
91
+ #define MLDSA_BYTES_(LVL) MLDSA##LVL##_BYTES
92
+ #define MLDSA_SECRETKEYBYTES(LVL) MLDSA_SECRETKEYBYTES_(LVL)
93
+ #define MLDSA_PUBLICKEYBYTES(LVL) MLDSA_PUBLICKEYBYTES_(LVL)
94
+ #define MLDSA_BYTES(LVL) MLDSA_BYTES_(LVL)
95
+
96
+ /****************************** Error codes ***********************************/
97
+
98
+ /* Generic failure condition, reserved for failures not covered by a more
99
+ * specific error code. */
100
+ #define MLD_ERR_FAIL (-1)
101
+ /* An allocation failed. This can only happen if MLD_CONFIG_CUSTOM_ALLOC_FREE
102
+ * is defined and the provided MLD_CUSTOM_ALLOC can fail. */
103
+ #define MLD_ERR_OUT_OF_MEMORY (-2)
104
+ /* An RNG failure occurred. Might be due to insufficient entropy or
105
+ * system misconfiguration. */
106
+ #define MLD_ERR_RNG_FAIL (-3)
107
+ /* The signing rejection-sampling loop exceeded
108
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS iterations without producing a valid
109
+ * signature. With a FIPS 204 Appendix C compliant bound (>= 821) this
110
+ * has probability < 2^-256. */
111
+ #define MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED (-4)
112
+ /* Signing was paused before completing, at the request of a caller-provided
113
+ * MLD_CONFIG_SIGN_HOOK_ATTEMPT hook (see mldsa_native_config.h). The caller
114
+ * resumes by re-invoking signing with the same inputs; the attempt hook,
115
+ * together with MLD_CONFIG_SIGN_HOOK_RESUME, decides where to continue. */
116
+ #define MLD_ERR_SIGNING_PAUSED (-5)
117
+ /* Signature verification failed: the signature is not valid for the given
118
+ * message and public key. Returned by the verification API. */
119
+ #define MLD_ERR_INVALID_SIGNATURE (-6)
120
+ /* Secret key validation failed: the secret key is malformed or internally
121
+ * inconsistent. Returned by pk_from_sk. */
122
+ #define MLD_ERR_INVALID_KEY (-7)
123
+ /* The Pairwise Consistency Test failed. Only possible when
124
+ * MLD_CONFIG_KEYGEN_PCT is enabled; signals that the freshly generated key
125
+ * pair failed its sign/verify self-test. */
126
+ #define MLD_ERR_PCT_FAIL (-8)
127
+ /* An argument was invalid, e.g. an unsupported pre-hash algorithm or a context
128
+ * string longer than 255 bytes. */
129
+ #define MLD_ERR_INVALID_ARG (-9)
130
+
131
+ /********************* Namespacing and Qualifiers *****************************/
132
+
133
+ #define MLD_API_CONCAT_(x, y) x##y
134
+ #define MLD_API_CONCAT(x, y) MLD_API_CONCAT_(x, y)
135
+ #define MLD_API_CONCAT_UNDERSCORE(x, y) MLD_API_CONCAT(MLD_API_CONCAT(x, _), y)
136
+
137
+ /* You need to make sure the config file is in the include path. */
138
+ #if defined(MLD_CONFIG_FILE)
139
+ #include MLD_CONFIG_FILE
140
+ #else
141
+ #include "mldsa_native_config.h"
142
+ #endif
143
+
144
+ /* Namespace prefix for the public API symbols. For multi-level builds, the
145
+ * parameter set is appended to disambiguate the security levels. */
146
+ #if defined(MLD_CONFIG_MULTILEVEL_BUILD)
147
+ #define MLD_API_NAMESPACE_PREFIX \
148
+ MLD_API_CONCAT(MLD_CONFIG_NAMESPACE_PREFIX, MLD_CONFIG_PARAMETER_SET)
149
+ #else
150
+ #define MLD_API_NAMESPACE_PREFIX MLD_CONFIG_NAMESPACE_PREFIX
151
+ #endif
152
+
153
+ #define MLD_API_NAMESPACE(sym) \
154
+ MLD_API_CONCAT_UNDERSCORE(MLD_API_NAMESPACE_PREFIX, sym)
155
+
156
+ #if defined(__GNUC__) || defined(__clang__)
157
+ #define MLD_API_MUST_CHECK_RETURN_VALUE __attribute__((warn_unused_result))
158
+ #else
159
+ #define MLD_API_MUST_CHECK_RETURN_VALUE
160
+ #endif
161
+
162
+ #if defined(MLD_CONFIG_EXTERNAL_API_QUALIFIER)
163
+ #define MLD_API_QUALIFIER MLD_CONFIG_EXTERNAL_API_QUALIFIER
164
+ #else
165
+ #define MLD_API_QUALIFIER
166
+ #endif
167
+
168
+ /* Hash algorithm constants for domain separation */
169
+ #define MLD_PREHASH_NONE 0
170
+ #define MLD_PREHASH_SHA2_224 1
171
+ #define MLD_PREHASH_SHA2_256 2
172
+ #define MLD_PREHASH_SHA2_384 3
173
+ #define MLD_PREHASH_SHA2_512 4
174
+ #define MLD_PREHASH_SHA2_512_224 5
175
+ #define MLD_PREHASH_SHA2_512_256 6
176
+ #define MLD_PREHASH_SHA3_224 7
177
+ #define MLD_PREHASH_SHA3_256 8
178
+ #define MLD_PREHASH_SHA3_384 9
179
+ #define MLD_PREHASH_SHA3_512 10
180
+ #define MLD_PREHASH_SHAKE_128 11
181
+ #define MLD_PREHASH_SHAKE_256 12
182
+
183
+ /* Maximum formatted domain separation message length */
184
+ #define MLD_DOMAIN_SEPARATION_MAX_BYTES (2 + 255 + 11 + 64)
185
+
186
+ /****************************** Function API **********************************/
187
+
188
+ #if !defined(MLD_CONFIG_CONSTANTS_ONLY)
189
+
190
+ #include <stddef.h>
191
+ #include <stdint.h>
192
+
193
+ #ifdef __cplusplus
194
+ extern "C"
195
+ {
196
+ #endif
197
+
198
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
199
+ /**
200
+ * Generate a public-private key pair from a seed.
201
+ *
202
+ * When MLD_CONFIG_KEYGEN_PCT is set, performs a Pairwise Consistency Test
203
+ * (PCT) as required by FIPS 140-3 IG.
204
+ *
205
+ * @warning The seed must be generated by a cryptographically secure random
206
+ * number generator.
207
+ *
208
+ * @spec{Implements @[FIPS204, Algorithm 6, ML-DSA.KeyGen_internal].}
209
+ *
210
+ * @param[out] pk Output public key.
211
+ * @param[out] sk Output private key.
212
+ * @param[in] seed Input random seed.
213
+ * @param context Application context. Only present when
214
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
215
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
216
+ *
217
+ * @retval 0 Success.
218
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
219
+ * used and an allocation via
220
+ * MLD_CUSTOM_ALLOC returned NULL.
221
+ * @retval MLD_ERR_RNG_FAIL Random number generation failed
222
+ * during the PCT. Only possible when
223
+ * MLD_CONFIG_KEYGEN_PCT is enabled.
224
+ * @retval MLD_ERR_SIGNING_PAUSED The PCT's signing step was paused by
225
+ * a MLD_CONFIG_SIGN_HOOK_ATTEMPT hook.
226
+ * This should currently never happen:
227
+ * signing hooks require
228
+ * MLD_CONFIG_NO_RANDOMIZED_API, which
229
+ * is incompatible with
230
+ * MLD_CONFIG_KEYGEN_PCT, so the two
231
+ * cannot be enabled simultaneously.
232
+ * @retval MLD_ERR_PCT_FAIL MLD_CONFIG_KEYGEN_PCT is enabled and
233
+ * the PCT check failed.
234
+ */
235
+ MLD_API_QUALIFIER
236
+ MLD_API_MUST_CHECK_RETURN_VALUE
237
+ int MLD_API_NAMESPACE(keypair_internal)(
238
+ uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
239
+ uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
240
+ const uint8_t seed[MLDSA_SEEDBYTES]
241
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
242
+ ,
243
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
244
+ #endif
245
+ );
246
+
247
+ #if !defined(MLD_CONFIG_CORE_API_ONLY)
248
+ #if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
249
+ /**
250
+ * Generate a public-private key pair.
251
+ *
252
+ * When MLD_CONFIG_KEYGEN_PCT is set, performs a Pairwise Consistency Test
253
+ * (PCT) as required by FIPS 140-3 IG.
254
+ *
255
+ * @spec{Implements @[FIPS204, Algorithm 1, ML-DSA.KeyGen].}
256
+ *
257
+ * @param[out] pk Output public key.
258
+ * @param[out] sk Output private key.
259
+ * @param context Application context. Only present when
260
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
261
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
262
+ *
263
+ * @retval 0 Success.
264
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
265
+ * used and an allocation via
266
+ * MLD_CUSTOM_ALLOC returned NULL.
267
+ * @retval MLD_ERR_RNG_FAIL Random number generation failed.
268
+ * @retval MLD_ERR_SIGNING_PAUSED The PCT's signing step was paused by
269
+ * a MLD_CONFIG_SIGN_HOOK_ATTEMPT hook.
270
+ * This should currently never happen:
271
+ * signing hooks require
272
+ * MLD_CONFIG_NO_RANDOMIZED_API, which
273
+ * is incompatible with
274
+ * MLD_CONFIG_KEYGEN_PCT, so the two
275
+ * cannot be enabled simultaneously.
276
+ * @retval MLD_ERR_PCT_FAIL MLD_CONFIG_KEYGEN_PCT is enabled and
277
+ * the PCT check failed.
278
+ */
279
+ MLD_API_QUALIFIER
280
+ MLD_API_MUST_CHECK_RETURN_VALUE
281
+ int MLD_API_NAMESPACE(keypair)(
282
+ uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
283
+ uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
284
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
285
+ ,
286
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
287
+ #endif
288
+ );
289
+ #endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
290
+ #endif /* !MLD_CONFIG_CORE_API_ONLY */
291
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
292
+
293
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
294
+ /**
295
+ * Compute signature using a caller-supplied random seed and prefix.
296
+ *
297
+ * On error (non-zero return value), the signature buffer sig is zeroized.
298
+ *
299
+ * @spec{Implements @[FIPS204, Algorithm 7, ML-DSA.Sign_internal].}
300
+ *
301
+ * @warning This function does not perform secret key validation.
302
+ * Callers importing serialized keys can use pk_from_sk
303
+ * to validate them before signing.
304
+ *
305
+ * @param[out] sig Pointer to buffer to hold the generated signature of
306
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
307
+ * @param[in] m Pointer to message to be signed (when
308
+ * externalmu == 0), or to a precomputed
309
+ * message representative mu (when externalmu != 0).
310
+ * @param mlen Length of m. Must equal MLDSA_CRHBYTES when
311
+ * externalmu != 0.
312
+ * @param[in] pre Pointer to prefix string. Ignored when
313
+ * externalmu != 0.
314
+ * @param prelen Length of prefix string. Ignored when
315
+ * externalmu != 0.
316
+ * @param[in] rnd Random seed.
317
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
318
+ * @param externalmu 0: m/mlen is the raw message; mu = H(tr, pre, m) is
319
+ * computed internally.
320
+ * non-zero: m points to a precomputed mu of
321
+ * MLDSA_CRHBYTES bytes; pre/prelen unused.
322
+ * @param context Application context. Only present when
323
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
324
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
325
+ *
326
+ * @retval 0 Success.
327
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
328
+ * used and an allocation via
329
+ * MLD_CUSTOM_ALLOC returned NULL.
330
+ * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
331
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
332
+ * iterations.
333
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
334
+ * paused signing; re-invoke to resume.
335
+ */
336
+ MLD_API_QUALIFIER
337
+ MLD_API_MUST_CHECK_RETURN_VALUE
338
+ int MLD_API_NAMESPACE(signature_internal)(
339
+ uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
340
+ size_t mlen, const uint8_t *pre, size_t prelen,
341
+ const uint8_t rnd[MLDSA_RNDBYTES],
342
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
343
+ int externalmu
344
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
345
+ ,
346
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
347
+ #endif
348
+ );
349
+
350
+ #if !defined(MLD_CONFIG_CORE_API_ONLY)
351
+ #if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
352
+ /**
353
+ * Compute signature. This function implements the randomized variant of
354
+ * ML-DSA. If you require the deterministic variant, use
355
+ * signature_internal directly.
356
+ *
357
+ * @spec{Implements @[FIPS204, Algorithm 2, ML-DSA.Sign].}
358
+ *
359
+ * @warning This function does not perform secret key validation.
360
+ * Callers importing serialized keys can use pk_from_sk
361
+ * to validate them before signing.
362
+ *
363
+ * @param[out] sig Pointer to buffer to hold the generated signature of
364
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
365
+ * @param[in] m Pointer to message to be signed. May be NULL if
366
+ * mlen == 0.
367
+ * @param mlen Length of message.
368
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
369
+ * @param ctxlen Length of context string. Should be <= 255.
370
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
371
+ * @param context Application context. Only present when
372
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
373
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
374
+ *
375
+ * @retval 0 Success.
376
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
377
+ * used and an allocation via
378
+ * MLD_CUSTOM_ALLOC returned NULL.
379
+ * @retval MLD_ERR_RNG_FAIL Random number generation failed.
380
+ * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
381
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
382
+ * iterations.
383
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
384
+ * paused signing; re-invoke to resume.
385
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255
386
+ * bytes.
387
+ */
388
+ MLD_API_QUALIFIER
389
+ MLD_API_MUST_CHECK_RETURN_VALUE
390
+ int MLD_API_NAMESPACE(signature)(
391
+ uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
392
+ size_t mlen, const uint8_t *ctx, size_t ctxlen,
393
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
394
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
395
+ ,
396
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
397
+ #endif
398
+ );
399
+
400
+ /**
401
+ * Compute signature in "external mu" mode: the caller has already computed
402
+ * the message representative mu = SHAKE256(tr || M', 64), where
403
+ * tr = SHAKE256(pk, 64) and M' is the FIPS 204 formatted message (e.g.
404
+ * 0x00 || ctxlen || ctx || msg for pure ML-DSA). This is useful when the
405
+ * message is large or streamed and cannot be held in memory.
406
+ *
407
+ * @spec{Implements @[FIPS204, Algorithm 2, ML-DSA.Sign external mu variant].}
408
+ *
409
+ * @warning This function does not perform secret key validation.
410
+ * Callers importing serialized keys can use pk_from_sk
411
+ * to validate them before signing.
412
+ *
413
+ * @param[out] sig Pointer to buffer to hold the generated signature of
414
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
415
+ * @param[in] mu Precomputed message representative.
416
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
417
+ * @param context Application context. Only present when
418
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
419
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
420
+ *
421
+ * @retval 0 Success.
422
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
423
+ * used and an allocation via
424
+ * MLD_CUSTOM_ALLOC returned NULL.
425
+ * @retval MLD_ERR_RNG_FAIL Random number generation failed.
426
+ * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
427
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
428
+ * iterations.
429
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
430
+ * paused signing; re-invoke to resume.
431
+ */
432
+ MLD_API_QUALIFIER
433
+ MLD_API_MUST_CHECK_RETURN_VALUE
434
+ int MLD_API_NAMESPACE(signature_extmu)(
435
+ uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)],
436
+ const uint8_t mu[MLDSA_CRHBYTES],
437
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
438
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
439
+ ,
440
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
441
+ #endif
442
+ );
443
+
444
+ #endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
445
+ #endif /* !MLD_CONFIG_CORE_API_ONLY */
446
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
447
+
448
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
449
+ /**
450
+ * Verify signature. Internal API.
451
+ *
452
+ * @spec{Implements @[FIPS204, Algorithm 8, ML-DSA.Verify_internal].}
453
+ *
454
+ * @param[in] sig Pointer to input signature of
455
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
456
+ * @param[in] m Pointer to message (when externalmu == 0), or to a
457
+ * precomputed message representative mu (when
458
+ * externalmu != 0).
459
+ * @param mlen Length of m. Must equal MLDSA_CRHBYTES when
460
+ * externalmu != 0.
461
+ * @param[in] pre Pointer to prefix string. Ignored when externalmu != 0.
462
+ * @param prelen Length of prefix string. Ignored when externalmu != 0.
463
+ * @param[in] pk Bit-packed public key.
464
+ * @param externalmu 0: m/mlen is the raw message; mu = H(H(pk), pre, m) is
465
+ * computed internally.
466
+ * non-zero: m points to a precomputed mu of
467
+ * MLDSA_CRHBYTES bytes; pre/prelen unused.
468
+ * @param context Application context. Only present when
469
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
470
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
471
+ *
472
+ * @retval 0 Success.
473
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
474
+ * used and an allocation via
475
+ * MLD_CUSTOM_ALLOC returned NULL.
476
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
477
+ */
478
+ MLD_API_QUALIFIER
479
+ MLD_API_MUST_CHECK_RETURN_VALUE
480
+ int MLD_API_NAMESPACE(verify_internal)(
481
+ const uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
482
+ size_t mlen, const uint8_t *pre, size_t prelen,
483
+ const uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
484
+ int externalmu
485
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
486
+ ,
487
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
488
+ #endif
489
+ );
490
+
491
+ #if !defined(MLD_CONFIG_CORE_API_ONLY)
492
+ /**
493
+ * Verify signature.
494
+ *
495
+ * @spec{Implements @[FIPS204, Algorithm 3, ML-DSA.Verify].}
496
+ *
497
+ * @param[in] sig Pointer to input signature of
498
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
499
+ * @param[in] m Pointer to message. May be NULL if mlen == 0.
500
+ * @param mlen Length of message.
501
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
502
+ * @param ctxlen Length of context string.
503
+ * @param[in] pk Bit-packed public key.
504
+ * @param context Application context. Only present when
505
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
506
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
507
+ *
508
+ * @retval 0 Success.
509
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
510
+ * used and an allocation via
511
+ * MLD_CUSTOM_ALLOC returned NULL.
512
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
513
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255 bytes.
514
+ */
515
+ MLD_API_QUALIFIER
516
+ MLD_API_MUST_CHECK_RETURN_VALUE
517
+ int MLD_API_NAMESPACE(verify)(
518
+ const uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
519
+ size_t mlen, const uint8_t *ctx, size_t ctxlen,
520
+ const uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
521
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
522
+ ,
523
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
524
+ #endif
525
+ );
526
+
527
+ /**
528
+ * Verify signature in "external mu" mode: the caller has already computed
529
+ * the message representative mu = SHAKE256(tr || M', 64), where
530
+ * tr = SHAKE256(pk, 64) and M' is the FIPS 204 formatted message (e.g.
531
+ * 0x00 || ctxlen || ctx || msg for pure ML-DSA). The same mu must have
532
+ * been used at signing time.
533
+ *
534
+ * @spec{Implements @[FIPS204, Algorithm 3, ML-DSA.Verify external mu variant].}
535
+ *
536
+ * @param[in] sig Pointer to input signature of
537
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
538
+ * @param[in] mu Precomputed message representative.
539
+ * @param[in] pk Bit-packed public key.
540
+ * @param context Application context. Only present when
541
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
542
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
543
+ *
544
+ * @retval 0 Success.
545
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
546
+ * used and an allocation via
547
+ * MLD_CUSTOM_ALLOC returned NULL.
548
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
549
+ */
550
+ MLD_API_QUALIFIER
551
+ MLD_API_MUST_CHECK_RETURN_VALUE
552
+ int MLD_API_NAMESPACE(verify_extmu)(
553
+ const uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)],
554
+ const uint8_t mu[MLDSA_CRHBYTES],
555
+ const uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
556
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
557
+ ,
558
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
559
+ #endif
560
+ );
561
+
562
+ #endif /* !MLD_CONFIG_CORE_API_ONLY */
563
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
564
+
565
+ #if !defined(MLD_CONFIG_CORE_API_ONLY)
566
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
567
+ /**
568
+ * Compute signature with pre-hashed message.
569
+ *
570
+ * @spec{Implements @[FIPS204, Algorithm 4, HashML-DSA.Sign].}
571
+ *
572
+ * Supported hash algorithm constants:
573
+ * MLD_PREHASH_SHA2_224, MLD_PREHASH_SHA2_256, MLD_PREHASH_SHA2_384,
574
+ * MLD_PREHASH_SHA2_512, MLD_PREHASH_SHA2_512_224, MLD_PREHASH_SHA2_512_256,
575
+ * MLD_PREHASH_SHA3_224, MLD_PREHASH_SHA3_256, MLD_PREHASH_SHA3_384,
576
+ * MLD_PREHASH_SHA3_512, MLD_PREHASH_SHAKE_128, MLD_PREHASH_SHAKE_256.
577
+ *
578
+ * MLD_PREHASH_NONE is rejected by this API.
579
+ *
580
+ * @warning This is an unstable API that may change in the future. If you need
581
+ * a stable API use signature_pre_hash_shake256.
582
+ *
583
+ * @warning This function does not perform secret key validation.
584
+ * Callers importing serialized keys can use pk_from_sk
585
+ * to validate them before signing.
586
+ *
587
+ * @param[out] sig Pointer to buffer to hold the generated signature of
588
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
589
+ * @param[in] ph Pointer to pre-hashed message.
590
+ * @param phlen Length of pre-hashed message. Must match the output
591
+ * length of hashalg (the digest size for SHA-2/SHA-3,
592
+ * 32 bytes for MLD_PREHASH_SHAKE_128, 64 bytes for
593
+ * MLD_PREHASH_SHAKE_256).
594
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
595
+ * @param ctxlen Length of context string.
596
+ * @param[in] rnd Random seed.
597
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
598
+ * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*).
599
+ * @param context Application context. Only present when
600
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
601
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
602
+ *
603
+ * @retval 0 Success.
604
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
605
+ * used and an allocation via
606
+ * MLD_CUSTOM_ALLOC returned NULL.
607
+ * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
608
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
609
+ * iterations.
610
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
611
+ * paused signing; re-invoke to resume.
612
+ * @retval MLD_ERR_INVALID_ARG The pre-hash algorithm was
613
+ * MLD_PREHASH_NONE or unsupported,
614
+ * phlen did not match the output
615
+ * length of hashalg, or the context
616
+ * string exceeded 255 bytes.
617
+ */
618
+ MLD_API_QUALIFIER
619
+ MLD_API_MUST_CHECK_RETURN_VALUE
620
+ int MLD_API_NAMESPACE(signature_pre_hash_internal)(
621
+ uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *ph,
622
+ size_t phlen, const uint8_t *ctx, size_t ctxlen,
623
+ const uint8_t rnd[MLDSA_RNDBYTES],
624
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
625
+ int hashalg
626
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
627
+ ,
628
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
629
+ #endif
630
+ );
631
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
632
+
633
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
634
+ /**
635
+ * Verifies signature with pre-hashed message.
636
+ *
637
+ * @spec{Implements @[FIPS204, Algorithm 5, HashML-DSA.Verify].}
638
+ *
639
+ * Supported hash algorithm constants:
640
+ * MLD_PREHASH_SHA2_224, MLD_PREHASH_SHA2_256, MLD_PREHASH_SHA2_384,
641
+ * MLD_PREHASH_SHA2_512, MLD_PREHASH_SHA2_512_224, MLD_PREHASH_SHA2_512_256,
642
+ * MLD_PREHASH_SHA3_224, MLD_PREHASH_SHA3_256, MLD_PREHASH_SHA3_384,
643
+ * MLD_PREHASH_SHA3_512, MLD_PREHASH_SHAKE_128, MLD_PREHASH_SHAKE_256.
644
+ *
645
+ * MLD_PREHASH_NONE is rejected by this API.
646
+ *
647
+ * @warning This is an unstable API that may change in the future. If you need
648
+ * a stable API use verify_pre_hash_shake256.
649
+ *
650
+ * @param[in] sig Pointer to input signature of
651
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
652
+ * @param[in] ph Pointer to pre-hashed message.
653
+ * @param phlen Length of pre-hashed message. Must match the output
654
+ * length of hashalg (the digest size for SHA-2/SHA-3,
655
+ * 32 bytes for MLD_PREHASH_SHAKE_128, 64 bytes for
656
+ * MLD_PREHASH_SHAKE_256).
657
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
658
+ * @param ctxlen Length of context string.
659
+ * @param[in] pk Bit-packed public key.
660
+ * @param hashalg Hash algorithm constant (one of MLD_PREHASH_*).
661
+ * @param context Application context. Only present when
662
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
663
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
664
+ *
665
+ * @retval 0 Success.
666
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
667
+ * used and an allocation via
668
+ * MLD_CUSTOM_ALLOC returned NULL.
669
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
670
+ * @retval MLD_ERR_INVALID_ARG The pre-hash algorithm was
671
+ * MLD_PREHASH_NONE or unsupported, phlen
672
+ * did not match the output length of
673
+ * hashalg, or the context string exceeded
674
+ * 255 bytes.
675
+ */
676
+ MLD_API_QUALIFIER
677
+ MLD_API_MUST_CHECK_RETURN_VALUE
678
+ int MLD_API_NAMESPACE(verify_pre_hash_internal)(
679
+ const uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *ph,
680
+ size_t phlen, const uint8_t *ctx, size_t ctxlen,
681
+ const uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
682
+ int hashalg
683
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
684
+ ,
685
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
686
+ #endif
687
+ );
688
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
689
+
690
+ #if !defined(MLD_CONFIG_NO_SIGN_API)
691
+ /**
692
+ * Compute signature with pre-hashed message using SHAKE256. This function
693
+ * computes the SHAKE256 hash of the message internally.
694
+ *
695
+ * @spec{Implements @[FIPS204, Algorithm 4, HashML-DSA.Sign] with SHAKE256 as
696
+ * the pre-hash.}
697
+ *
698
+ * @warning This function does not perform secret key validation.
699
+ * Callers importing serialized keys can use pk_from_sk
700
+ * to validate them before signing.
701
+ *
702
+ * @param[out] sig Pointer to buffer to hold the generated signature of
703
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
704
+ * @param[in] m Pointer to message to be hashed and signed. May be
705
+ * NULL if mlen == 0.
706
+ * @param mlen Length of message.
707
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
708
+ * @param ctxlen Length of context string.
709
+ * @param[in] rnd Random seed.
710
+ * @param[in] sk Bit-packed secret key; assumed to be valid.
711
+ * @param context Application context. Only present when
712
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
713
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
714
+ *
715
+ * @retval 0 Success.
716
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
717
+ * used and an allocation via
718
+ * MLD_CUSTOM_ALLOC returned NULL.
719
+ * @retval MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED The rejection-sampling loop exceeded
720
+ * MLD_CONFIG_MAX_SIGNING_ATTEMPTS
721
+ * iterations.
722
+ * @retval MLD_ERR_SIGNING_PAUSED A MLD_CONFIG_SIGN_HOOK_ATTEMPT hook
723
+ * paused signing; re-invoke to resume.
724
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255
725
+ * bytes.
726
+ */
727
+ MLD_API_QUALIFIER
728
+ MLD_API_MUST_CHECK_RETURN_VALUE
729
+ int MLD_API_NAMESPACE(signature_pre_hash_shake256)(
730
+ uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
731
+ size_t mlen, const uint8_t *ctx, size_t ctxlen,
732
+ const uint8_t rnd[MLDSA_RNDBYTES],
733
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
734
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
735
+ ,
736
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
737
+ #endif
738
+ );
739
+ #endif /* !MLD_CONFIG_NO_SIGN_API */
740
+
741
+ #if !defined(MLD_CONFIG_NO_VERIFY_API)
742
+ /**
743
+ * Verify signature with pre-hashed message using SHAKE256. This function
744
+ * computes the SHAKE256 hash of the message internally.
745
+ *
746
+ * @spec{Implements @[FIPS204, Algorithm 5, HashML-DSA.Verify] with SHAKE256 as
747
+ * the pre-hash.}
748
+ *
749
+ * @param[in] sig Pointer to input signature of
750
+ * MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET) bytes.
751
+ * @param[in] m Pointer to message to be hashed and verified. May be
752
+ * NULL if mlen == 0.
753
+ * @param mlen Length of message.
754
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
755
+ * @param ctxlen Length of context string.
756
+ * @param[in] pk Bit-packed public key.
757
+ * @param context Application context. Only present when
758
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
759
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
760
+ *
761
+ * @retval 0 Success.
762
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was
763
+ * used and an allocation via
764
+ * MLD_CUSTOM_ALLOC returned NULL.
765
+ * @retval MLD_ERR_INVALID_SIGNATURE Signature verification failed.
766
+ * @retval MLD_ERR_INVALID_ARG The context string exceeded 255 bytes.
767
+ */
768
+ MLD_API_QUALIFIER
769
+ MLD_API_MUST_CHECK_RETURN_VALUE
770
+ int MLD_API_NAMESPACE(verify_pre_hash_shake256)(
771
+ const uint8_t sig[MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)], const uint8_t *m,
772
+ size_t mlen, const uint8_t *ctx, size_t ctxlen,
773
+ const uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
774
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
775
+ ,
776
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
777
+ #endif
778
+ );
779
+ #endif /* !MLD_CONFIG_NO_VERIFY_API */
780
+ #endif /* !MLD_CONFIG_CORE_API_ONLY */
781
+
782
+ #if !defined(MLD_CONFIG_CORE_API_ONLY)
783
+ /**
784
+ * Prepare domain separation prefix for ML-DSA signing.
785
+ *
786
+ * For pure ML-DSA (hashalg == MLD_PREHASH_NONE):
787
+ * Format: 0x00 || ctxlen (1 byte) || ctx.
788
+ *
789
+ * For HashML-DSA (hashalg != MLD_PREHASH_NONE):
790
+ * Format: 0x01 || ctxlen (1 byte) || ctx || oid (11 bytes) || ph.
791
+ *
792
+ * This function is useful for building incremental signing APIs.
793
+ *
794
+ * @spec{For HashML-DSA (hashalg != MLD_PREHASH_NONE), implements
795
+ * @[FIPS204, Algorithm 4, line 23]. For Pure ML-DSA
796
+ * (hashalg == MLD_PREHASH_NONE), implements
797
+ * ```
798
+ * M' <- BytesToBits(IntegerToBytes(0, 1)
799
+ * || IntegerToBytes(|ctx|, 1)
800
+ * || ctx
801
+ * ```
802
+ * which is part of @[FIPS204, Algorithm 2, ML-DSA.Sign, line 10] and
803
+ * @[FIPS204, Algorithm 3, ML-DSA.Verify, line 5].}
804
+ *
805
+ * @param[out] prefix Output domain separation prefix buffer.
806
+ * @param[in] ph Pointer to pre-hashed message (ignored for pure
807
+ * ML-DSA).
808
+ * @param phlen Length of pre-hashed message; must match the output
809
+ * length of hashalg (ignored for pure ML-DSA).
810
+ * @param[in] ctx Pointer to context string. May be NULL if ctxlen == 0.
811
+ * @param ctxlen Length of context string.
812
+ * @param hashalg Hash algorithm constant (MLD_PREHASH_NONE for pure
813
+ * ML-DSA, or MLD_PREHASH_* for HashML-DSA).
814
+ *
815
+ * @return The total length of the formatted prefix, or 0 on error.
816
+ * Errors are:
817
+ * - The context string exceeded 255 bytes.
818
+ * - For HashML-DSA: hashalg was unsupported, ph was NULL, or phlen
819
+ * did not match the output length of hashalg.
820
+ */
821
+ MLD_API_QUALIFIER
822
+ MLD_API_MUST_CHECK_RETURN_VALUE
823
+ size_t MLD_API_NAMESPACE(prepare_domain_separation_prefix)(
824
+ uint8_t prefix[MLD_DOMAIN_SEPARATION_MAX_BYTES], const uint8_t *ph,
825
+ size_t phlen, const uint8_t *ctx, size_t ctxlen, int hashalg);
826
+
827
+ #if !defined(MLD_CONFIG_NO_KEYPAIR_API)
828
+ /**
829
+ * Perform basic validity checks on secret key, and derive public key.
830
+ *
831
+ * Referring to the decoding of the secret key `sk=(rho, K, tr, s1, s2, t0)`
832
+ * (cf. @[FIPS204, Algorithm 25, skDecode]), the following checks are
833
+ * performed:
834
+ * - Check that s1 and s2 have coefficients in [-MLDSA_ETA, MLDSA_ETA].
835
+ * - Check that t0 and tr stored in sk match recomputed values.
836
+ *
837
+ * @note This function leaks whether the secret key is valid or invalid
838
+ * through its return value and timing.
839
+ *
840
+ * @param[out] pk Output public key.
841
+ * @param[in] sk Input secret key.
842
+ * @param context Application context. Only present when
843
+ * MLD_CONFIG_CONTEXT_PARAMETER is defined; type set by
844
+ * MLD_CONFIG_CONTEXT_PARAMETER_TYPE.
845
+ *
846
+ * @retval 0 Success.
847
+ * @retval MLD_ERR_OUT_OF_MEMORY MLD_CONFIG_CUSTOM_ALLOC_FREE was used and an
848
+ * allocation via MLD_CUSTOM_ALLOC returned NULL.
849
+ * @retval MLD_ERR_INVALID_KEY Secret key validation failed.
850
+ */
851
+ MLD_API_QUALIFIER
852
+ MLD_API_MUST_CHECK_RETURN_VALUE
853
+ int MLD_API_NAMESPACE(pk_from_sk)(
854
+ uint8_t pk[MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)],
855
+ const uint8_t sk[MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)]
856
+ #ifdef MLD_CONFIG_CONTEXT_PARAMETER
857
+ ,
858
+ MLD_CONFIG_CONTEXT_PARAMETER_TYPE context
859
+ #endif
860
+ );
861
+ #endif /* !MLD_CONFIG_NO_KEYPAIR_API */
862
+ #endif /* !MLD_CONFIG_CORE_API_ONLY */
863
+
864
+ #ifdef __cplusplus
865
+ }
866
+ #endif
867
+
868
+ #undef MLD_API_NAMESPACE_PREFIX
869
+
870
+ #endif /* !MLD_CONFIG_CONSTANTS_ONLY */
871
+
872
+ /***************************** Memory Usage **********************************/
873
+
874
+ /*
875
+ * By default mldsa-native performs all memory allocations on the stack.
876
+ * Alternatively, mldsa-native supports custom allocation of large structures
877
+ * through the `MLD_CONFIG_CUSTOM_ALLOC_FREE` configuration option.
878
+ * See mldsa_native_config.h for details.
879
+ *
880
+ * `MLD_TOTAL_ALLOC_{44,65,87}_{KEYPAIR,SIGN,VERIFY}` indicates the maximum
881
+ * (accumulative) allocation via MLD_ALLOC for each parameter set and operation.
882
+ * Note that some stack allocation remains even
883
+ * when using custom allocators, so these values are lower than total stack
884
+ * usage with the default stack-only allocation.
885
+ *
886
+ * These constants may be used to implement custom allocations using a
887
+ * fixed-sized buffer and a simple allocator (e.g., bump allocator).
888
+ */
889
+ /* check-magic: off */
890
+ #if !defined(MLD_CONFIG_REDUCE_RAM)
891
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR_NO_PCT 26912
892
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR_PCT 48480
893
+ #define MLD_TOTAL_ALLOC_44_PK_FROM_SK 28480
894
+ #define MLD_TOTAL_ALLOC_44_SIGN 44704
895
+ #define MLD_TOTAL_ALLOC_44_VERIFY 24448
896
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR_NO_PCT 44320
897
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR_PCT 74624
898
+ #define MLD_TOTAL_ALLOC_65_PK_FROM_SK 46720
899
+ #define MLD_TOTAL_ALLOC_65_SIGN 69312
900
+ #define MLD_TOTAL_ALLOC_65_VERIFY 39872
901
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR_NO_PCT 75040
902
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR_PCT 115488
903
+ #define MLD_TOTAL_ALLOC_87_PK_FROM_SK 78272
904
+ #define MLD_TOTAL_ALLOC_87_SIGN 108224
905
+ #define MLD_TOTAL_ALLOC_87_VERIFY 68800
906
+ #else /* !MLD_CONFIG_REDUCE_RAM */
907
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR_NO_PCT 11584
908
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR_PCT 16896
909
+ #define MLD_TOTAL_ALLOC_44_PK_FROM_SK 13152
910
+ #define MLD_TOTAL_ALLOC_44_SIGN 13120
911
+ #define MLD_TOTAL_ALLOC_44_VERIFY 9120
912
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR_NO_PCT 14656
913
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR_PCT 22560
914
+ #define MLD_TOTAL_ALLOC_65_PK_FROM_SK 17056
915
+ #define MLD_TOTAL_ALLOC_65_SIGN 17248
916
+ #define MLD_TOTAL_ALLOC_65_VERIFY 10208
917
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR_NO_PCT 18752
918
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR_PCT 28608
919
+ #define MLD_TOTAL_ALLOC_87_PK_FROM_SK 21984
920
+ #define MLD_TOTAL_ALLOC_87_SIGN 21344
921
+ #define MLD_TOTAL_ALLOC_87_VERIFY 12512
922
+ #endif /* MLD_CONFIG_REDUCE_RAM */
923
+ /* check-magic: on */
924
+
925
+ /*
926
+ * MLD_TOTAL_ALLOC_*_KEYPAIR adapts based on MLD_CONFIG_KEYGEN_PCT.
927
+ */
928
+ #if defined(MLD_CONFIG_KEYGEN_PCT)
929
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR MLD_TOTAL_ALLOC_44_KEYPAIR_PCT
930
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR MLD_TOTAL_ALLOC_65_KEYPAIR_PCT
931
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR MLD_TOTAL_ALLOC_87_KEYPAIR_PCT
932
+ #else
933
+ #define MLD_TOTAL_ALLOC_44_KEYPAIR MLD_TOTAL_ALLOC_44_KEYPAIR_NO_PCT
934
+ #define MLD_TOTAL_ALLOC_65_KEYPAIR MLD_TOTAL_ALLOC_65_KEYPAIR_NO_PCT
935
+ #define MLD_TOTAL_ALLOC_87_KEYPAIR MLD_TOTAL_ALLOC_87_KEYPAIR_NO_PCT
936
+ #endif
937
+
938
+ #define MLD_MAX3_(a, b, c) \
939
+ ((a) > (b) ? ((a) > (c) ? (a) : (c)) : ((b) > (c) ? (b) : (c)))
940
+ #define MLD_MAX4_(a, b, c, d) MLD_MAX3_((a), (b), MLD_MAX3_((c), (d), (d)))
941
+
942
+ /*
943
+ * `MLD_TOTAL_ALLOC_{44,65,87}` is the maximum across standard API operations
944
+ * (keygen, sign, verify) for each parameter set.
945
+ */
946
+ #define MLD_TOTAL_ALLOC_44 \
947
+ MLD_MAX4_(MLD_TOTAL_ALLOC_44_KEYPAIR, MLD_TOTAL_ALLOC_44_PK_FROM_SK, \
948
+ MLD_TOTAL_ALLOC_44_SIGN, MLD_TOTAL_ALLOC_44_VERIFY)
949
+ #define MLD_TOTAL_ALLOC_65 \
950
+ MLD_MAX4_(MLD_TOTAL_ALLOC_65_KEYPAIR, MLD_TOTAL_ALLOC_65_PK_FROM_SK, \
951
+ MLD_TOTAL_ALLOC_65_SIGN, MLD_TOTAL_ALLOC_65_VERIFY)
952
+ #define MLD_TOTAL_ALLOC_87 \
953
+ MLD_MAX4_(MLD_TOTAL_ALLOC_87_KEYPAIR, MLD_TOTAL_ALLOC_87_PK_FROM_SK, \
954
+ MLD_TOTAL_ALLOC_87_SIGN, MLD_TOTAL_ALLOC_87_VERIFY)
955
+
956
+ #endif /* !MLD_H */