wc_xmss.h (10518B)
1 /* wc_xmss.h 2 * 3 * Copyright (C) 2006-2025 wolfSSL Inc. 4 * 5 * This file is part of wolfSSL. 6 * 7 * wolfSSL is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * wolfSSL is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 20 */ 21 22 /* Based on: 23 * o RFC 8391 - XMSS: eXtended Merkle Signature Scheme 24 * o [HDSS] "Hash-based Digital Signature Schemes", Buchmann, Dahmen and Szydlo 25 * from "Post Quantum Cryptography", Springer 2009. 26 */ 27 28 #ifndef WC_XMSS_H 29 #define WC_XMSS_H 30 31 #ifdef WOLFSSL_HAVE_XMSS 32 #include <wolfssl/wolfcrypt/xmss.h> 33 #include <wolfssl/wolfcrypt/sha256.h> 34 #include <wolfssl/wolfcrypt/sha512.h> 35 #include <wolfssl/wolfcrypt/sha3.h> 36 37 #if !defined(WOLFSSL_WC_XMSS) 38 #error "This code is incompatible with external implementation of XMSS." 39 #endif 40 41 #if (defined(WC_XMSS_SHA512) || defined(WC_XMSS_SHAKE256)) && \ 42 (WOLFSSL_WC_XMSS_MAX_HASH_SIZE >= 512) 43 #define WC_XMSS_MAX_N 64 44 #define WC_XMSS_MAX_PADDING_LEN 64 45 #else 46 #define WC_XMSS_MAX_N 32 47 #define WC_XMSS_MAX_PADDING_LEN 32 48 #endif 49 #define WC_XMSS_MAX_MSG_PRE_LEN \ 50 (WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N) 51 #define WC_XMSS_MAX_TREE_HEIGHT 20 52 #define WC_XMSS_MAX_CSUM_BYTES 4 53 #define WC_XMSS_MAX_WOTS_LEN (8 * WC_XMSS_MAX_N / 4 + 3) 54 #define WC_XMSS_MAX_WOTS_SIG_LEN (WC_XMSS_MAX_WOTS_LEN * WC_XMSS_MAX_N) 55 #define WC_XMSS_MAX_STACK_LEN \ 56 ((WC_XMSS_MAX_TREE_HEIGHT + 1) * WC_XMSS_MAX_N) 57 #define WC_XMSS_MAX_D 12 58 #define WC_XMSS_MAX_BDS_STATES (2 * WC_XMSS_MAX_D - 1) 59 #define WC_XMSS_MAX_TREE_HASH \ 60 ((2 * WC_XMSS_MAX_D - 1) * WC_XMSS_MAX_TREE_HEIGHT) 61 #define WC_XMSS_MAX_BDS_K 0 62 63 #define WC_XMSS_ADDR_LEN 32 64 65 #define WC_XMSS_HASH_PRF_MAX_DATA_LEN \ 66 (WC_XMSS_MAX_PADDING_LEN + 2 * WC_XMSS_MAX_N + WC_XMSS_ADDR_LEN) 67 #define WC_XMSS_HASH_MAX_DATA_LEN \ 68 (WC_XMSS_MAX_PADDING_LEN + 3 * WC_XMSS_MAX_N) 69 70 71 #define WC_XMSS_SHA256_N 32 72 #define WC_XMSS_SHA256_PADDING_LEN 32 73 #define WC_XMSS_SHA256_WOTS_LEN 67 74 75 #define XMSS_OID_LEN 4 76 77 #define XMSS_MAX_HASH_LEN WC_SHA256_DIGEST_SIZE 78 79 #define XMSS_RETAIN_LEN(k, n) ((!!(k)) * ((1 << (k)) - (k) - 1) * (n)) 80 81 /* XMMS Algorithm OIDs 82 * Note: values are used in mathematical calculations in OID to parames. */ 83 #define WC_XMSS_OID_SHA2_10_256 0x01 84 #define WC_XMSS_OID_SHA2_16_256 0x02 85 #define WC_XMSS_OID_SHA2_20_256 0x03 86 #define WC_XMSS_OID_SHA2_10_512 0x04 87 #define WC_XMSS_OID_SHA2_16_512 0x05 88 #define WC_XMSS_OID_SHA2_20_512 0x06 89 #define WC_XMSS_OID_SHAKE_10_256 0x07 90 #define WC_XMSS_OID_SHAKE_16_256 0x08 91 #define WC_XMSS_OID_SHAKE_20_256 0x09 92 #define WC_XMSS_OID_SHAKE_10_512 0x0a 93 #define WC_XMSS_OID_SHAKE_16_512 0x0b 94 #define WC_XMSS_OID_SHAKE_20_512 0x0c 95 #define WC_XMSS_OID_SHA2_10_192 0x0d 96 #define WC_XMSS_OID_SHA2_16_192 0x0e 97 #define WC_XMSS_OID_SHA2_20_192 0x0f 98 #define WC_XMSS_OID_SHAKE256_10_256 0x10 99 #define WC_XMSS_OID_SHAKE256_16_256 0x11 100 #define WC_XMSS_OID_SHAKE256_20_256 0x12 101 #define WC_XMSS_OID_SHAKE256_10_192 0x13 102 #define WC_XMSS_OID_SHAKE256_16_192 0x14 103 #define WC_XMSS_OID_SHAKE256_20_192 0x15 104 #define WC_XMSS_OID_FIRST WC_XMSS_OID_SHA2_10_256 105 #define WC_XMSS_OID_LAST WC_XMSS_OID_SHAKE256_20_192 106 107 /* XMMS^MT Algorithm OIDs 108 * Note: values are used in mathematical calculations in OID to parames. */ 109 #define WC_XMSSMT_OID_SHA2_20_2_256 0x01 110 #define WC_XMSSMT_OID_SHA2_20_4_256 0x02 111 #define WC_XMSSMT_OID_SHA2_40_2_256 0x03 112 #define WC_XMSSMT_OID_SHA2_40_4_256 0x04 113 #define WC_XMSSMT_OID_SHA2_40_8_256 0x05 114 #define WC_XMSSMT_OID_SHA2_60_3_256 0x06 115 #define WC_XMSSMT_OID_SHA2_60_6_256 0x07 116 #define WC_XMSSMT_OID_SHA2_60_12_256 0x08 117 #define WC_XMSSMT_OID_SHA2_20_2_512 0x09 118 #define WC_XMSSMT_OID_SHA2_20_4_512 0x0a 119 #define WC_XMSSMT_OID_SHA2_40_2_512 0x0b 120 #define WC_XMSSMT_OID_SHA2_40_4_512 0x0c 121 #define WC_XMSSMT_OID_SHA2_40_8_512 0x0d 122 #define WC_XMSSMT_OID_SHA2_60_3_512 0x0e 123 #define WC_XMSSMT_OID_SHA2_60_6_512 0x0f 124 #define WC_XMSSMT_OID_SHA2_60_12_512 0x10 125 #define WC_XMSSMT_OID_SHAKE_20_2_256 0x11 126 #define WC_XMSSMT_OID_SHAKE_20_4_256 0x12 127 #define WC_XMSSMT_OID_SHAKE_40_2_256 0x13 128 #define WC_XMSSMT_OID_SHAKE_40_4_256 0x14 129 #define WC_XMSSMT_OID_SHAKE_40_8_256 0x15 130 #define WC_XMSSMT_OID_SHAKE_60_3_256 0x16 131 #define WC_XMSSMT_OID_SHAKE_60_6_256 0x17 132 #define WC_XMSSMT_OID_SHAKE_60_12_256 0x18 133 #define WC_XMSSMT_OID_SHAKE_20_2_512 0x19 134 #define WC_XMSSMT_OID_SHAKE_20_4_512 0x1a 135 #define WC_XMSSMT_OID_SHAKE_40_2_512 0x1b 136 #define WC_XMSSMT_OID_SHAKE_40_4_512 0x1c 137 #define WC_XMSSMT_OID_SHAKE_40_8_512 0x1d 138 #define WC_XMSSMT_OID_SHAKE_60_3_512 0x1e 139 #define WC_XMSSMT_OID_SHAKE_60_6_512 0x1f 140 #define WC_XMSSMT_OID_SHAKE_60_12_512 0x20 141 #define WC_XMSSMT_OID_SHA2_20_2_192 0x21 142 #define WC_XMSSMT_OID_SHA2_20_4_192 0x22 143 #define WC_XMSSMT_OID_SHA2_40_2_192 0x23 144 #define WC_XMSSMT_OID_SHA2_40_4_192 0x24 145 #define WC_XMSSMT_OID_SHA2_40_8_192 0x25 146 #define WC_XMSSMT_OID_SHA2_60_3_192 0x26 147 #define WC_XMSSMT_OID_SHA2_60_6_192 0x27 148 #define WC_XMSSMT_OID_SHA2_60_12_192 0x28 149 #define WC_XMSSMT_OID_SHAKE256_20_2_256 0x29 150 #define WC_XMSSMT_OID_SHAKE256_20_4_256 0x2a 151 #define WC_XMSSMT_OID_SHAKE256_40_2_256 0x2b 152 #define WC_XMSSMT_OID_SHAKE256_40_4_256 0x2c 153 #define WC_XMSSMT_OID_SHAKE256_40_8_256 0x2d 154 #define WC_XMSSMT_OID_SHAKE256_60_3_256 0x2e 155 #define WC_XMSSMT_OID_SHAKE256_60_6_256 0x2f 156 #define WC_XMSSMT_OID_SHAKE256_60_12_256 0x30 157 #define WC_XMSSMT_OID_SHAKE256_20_2_192 0x31 158 #define WC_XMSSMT_OID_SHAKE256_20_4_192 0x32 159 #define WC_XMSSMT_OID_SHAKE256_40_2_192 0x33 160 #define WC_XMSSMT_OID_SHAKE256_40_4_192 0x34 161 #define WC_XMSSMT_OID_SHAKE256_40_8_192 0x35 162 #define WC_XMSSMT_OID_SHAKE256_60_3_192 0x36 163 #define WC_XMSSMT_OID_SHAKE256_60_6_192 0x37 164 #define WC_XMSSMT_OID_SHAKE256_60_12_192 0x38 165 #define WC_XMSSMT_OID_FIRST WC_XMSSMT_OID_SHA2_20_2_256 166 #define WC_XMSSMT_OID_LAST WC_XMSSMT_OID_SHAKE256_60_12_192 167 168 169 /* Type for hash address. */ 170 typedef word32 HashAddress[8]; 171 172 /* XMSS/XMSS^MT fixed parameters. */ 173 typedef struct XmssParams { 174 /* Hash algorithm to use. */ 175 word8 hash; 176 /* Size of hash output. */ 177 word8 n; 178 /* Number of bytes of padding before rest of hash data. */ 179 word8 pad_len; 180 /* Number of values to chain = 2 * n + 3. */ 181 word8 wots_len; 182 /* Number of bytes in each WOTS+ signature. */ 183 word16 wots_sig_len; 184 /* Full height of tree. */ 185 word8 h; 186 /* Height of tree each subtree. */ 187 word8 sub_h; 188 /* Number of subtrees = h / sub_h. */ 189 word8 d; 190 /* Number of bytes to encode index into in private/secret key. */ 191 word8 idx_len; 192 /* Number of bytes in a signature. */ 193 word32 sig_len; 194 /* Number of bytes in a secret/private key. */ 195 word32 sk_len; 196 /* Number of bytes in a public key. */ 197 word8 pk_len; 198 /* BDS parameter for fast C implementation. */ 199 word8 bds_k; 200 } XmssParams; 201 202 struct XmssKey { 203 /* Public key. */ 204 unsigned char pk[2 * WC_XMSS_MAX_N]; 205 /* OID that identifies parameters. */ 206 word32 oid; 207 /* Indicates whether the parameters are for XMSS^MT. */ 208 int is_xmssmt; 209 /* XMSS/XMSS^MT parameters. */ 210 const XmssParams* params; 211 #ifndef WOLFSSL_XMSS_VERIFY_ONLY 212 /* Secret/private key. */ 213 unsigned char* sk; 214 /* Length of secret key. */ 215 word32 sk_len; 216 /* Callback to write/update key. */ 217 wc_xmss_write_private_key_cb write_private_key; 218 /* Callback to read key. */ 219 wc_xmss_read_private_key_cb read_private_key; 220 /* Context arg passed to callbacks. */ 221 void* context; 222 #endif /* ifndef WOLFSSL_XMSS_VERIFY_ONLY */ 223 /* State of key. */ 224 enum wc_XmssState state; 225 }; 226 227 typedef struct XmssState { 228 const XmssParams* params; 229 230 /* Digest is assumed to be at the end. */ 231 union { 232 #ifdef WC_XMSS_SHA256 233 wc_Sha256 sha256; 234 #endif 235 #ifdef WC_XMSS_SHA512 236 wc_Sha512 sha512; 237 #endif 238 #if defined(WC_XMSS_SHAKE128) || defined(WC_XMSS_SHAKE256) 239 wc_Shake shake; 240 #endif 241 } digest; 242 #if !defined(WOLFSSL_WC_XMSS_SMALL) && defined(WC_XMSS_SHA256) && \ 243 !defined(WC_XMSS_FULL_HASH) 244 ALIGN16 word32 dgst_state[WC_SHA256_DIGEST_SIZE / sizeof(word32)]; 245 #endif 246 ALIGN16 byte prf_buf[WC_XMSS_HASH_PRF_MAX_DATA_LEN]; 247 ALIGN16 byte buf[WC_XMSS_HASH_MAX_DATA_LEN]; 248 ALIGN16 byte pk[WC_XMSS_MAX_WOTS_SIG_LEN]; 249 #ifndef WOLFSSL_XMSS_VERIFY_ONLY 250 ALIGN16 byte stack[WC_XMSS_MAX_STACK_LEN]; 251 #else 252 ALIGN16 byte stack[WC_XMSS_ADDR_LEN]; 253 #endif 254 byte encMsg[WC_XMSS_MAX_WOTS_LEN]; 255 HashAddress addr; 256 257 int ret; 258 } XmssState; 259 260 #ifdef __cplusplus 261 extern "C" { 262 #endif 263 264 WOLFSSL_LOCAL int wc_xmssmt_keygen(XmssState *state, const unsigned char* seed, 265 unsigned char *sk, unsigned char *pk); 266 WOLFSSL_LOCAL int wc_xmss_keygen(XmssState *state, const unsigned char* seed, 267 unsigned char *sk, unsigned char *pk); 268 269 WOLFSSL_LOCAL int wc_xmssmt_sign(XmssState *state, const unsigned char *m, 270 word32 mlen, unsigned char *sk, unsigned char *sm); 271 WOLFSSL_LOCAL int wc_xmss_sign(XmssState *state, const unsigned char *m, 272 word32 mlen, unsigned char *sk, unsigned char *sm); 273 274 WOLFSSL_LOCAL int wc_xmss_sigsleft(const XmssParams* params, unsigned char* sk); 275 276 WOLFSSL_LOCAL int wc_xmssmt_verify(XmssState *state, const unsigned char *m, 277 word32 mlen, const unsigned char *sm, const unsigned char *pk); 278 279 #ifdef __cplusplus 280 } /* extern "C" */ 281 #endif 282 283 #endif /* WOLFSSL_HAVE_XMSS */ 284 #endif /* WC_XMSS_H */ 285