|
22 | 22 | #include <gmssl/sphincs.h> |
23 | 23 |
|
24 | 24 |
|
| 25 | + |
| 26 | + |
25 | 27 | static const SPHINCS_PARAMS sphincs_params[] = { |
26 | 28 | // n h d lg(t) k w siglen |
27 | 29 | { "SPHINCS+_128s", 16, 63, 7, 12, 14, 16, 133, 1, 7856 }, |
@@ -307,9 +309,20 @@ void sphincs_wots_sig_to_pk(const sphincs_wots_sig_t sig, |
307 | 309 | } |
308 | 310 |
|
309 | 311 | void sphincs_xmss_tree_hash(const sphincs_secret_t left_child, const sphincs_secret_t right_child, |
310 | | - const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 312 | + const sphincs_secret_t seed, const sphincs_adrs_t adrs, |
311 | 313 | hash256_t parent) |
312 | 314 | { |
| 315 | + HASH256_CTX ctx; |
| 316 | + hash256_t dgst; |
| 317 | + |
| 318 | + hash256_init(&ctx); |
| 319 | + hash256_update(&ctx, seed, sizeof(sphincs_secret_t)); |
| 320 | + hash256_update(&ctx, adrs, sizeof(sphincs_adrs_t)); |
| 321 | + hash256_update(&ctx, left_child, sizeof(sphincs_secret_t)); |
| 322 | + hash256_update(&ctx, right_child, sizeof(sphincs_secret_t)); |
| 323 | + hash256_finish(&ctx, dgst); |
| 324 | + |
| 325 | + memcpy(parent, dgst, sizeof(sphincs_secret_t)); |
313 | 326 | } |
314 | 327 |
|
315 | 328 | void sphincs_xmss_build_tree(const sphincs_secret_t secret, |
@@ -351,18 +364,110 @@ void sphincs_xmss_build_tree(const sphincs_secret_t secret, |
351 | 364 | } |
352 | 365 | } |
353 | 366 |
|
| 367 | +// auth_path[height] |
| 368 | +void sphincs_xmss_build_auth_path(const sphincs_secret_t *tree, size_t height, |
| 369 | + uint32_t tree_index, sphincs_secret_t *auth_path) |
| 370 | +{ |
| 371 | + size_t h; |
| 372 | + for (h = 0; h < height; h++) { |
| 373 | + memcpy(auth_path[h], tree[tree_index ^ 1], sizeof(sphincs_secret_t)); |
| 374 | + tree += (1 << (height - h)); |
| 375 | + tree_index >>= 1; |
| 376 | + } |
| 377 | +} |
| 378 | + |
| 379 | +void sphincs_xmss_build_root(const sphincs_secret_t wots_root, uint32_t tree_index, |
| 380 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 381 | + const sphincs_secret_t *auth_path, size_t height, |
| 382 | + hash256_t root) |
| 383 | +{ |
| 384 | + sphincs_adrs_t adrs; |
| 385 | + uint32_t h; |
| 386 | + |
| 387 | + sphincs_adrs_copy_layer_address(adrs, in_adrs); |
| 388 | + sphincs_adrs_copy_tree_address(adrs, in_adrs); |
| 389 | + sphincs_adrs_set_type(adrs, SPHINCS_ADRS_TYPE_HASHTREE); |
| 390 | + //sphincs_adrs_set_padding(adrs, 0); |
| 391 | + |
| 392 | + memcpy(root, wots_root, sizeof(sphincs_secret_t)); |
354 | 393 |
|
355 | 394 |
|
356 | | -void fors_tree_hash(const sphincs_secret_t seed, const sphincs_secret_t secret, |
357 | | - int start, int height, const sphincs_adrs_t adrs) |
| 395 | + for (h = 0; h < height; h++) { |
| 396 | + int right_child = tree_index & 1; |
| 397 | + tree_index >>= 1; |
| 398 | + sphincs_adrs_set_tree_height(adrs, h + 1); |
| 399 | + sphincs_adrs_set_tree_index(adrs, tree_index); |
| 400 | + |
| 401 | + if (right_child) |
| 402 | + sphincs_xmss_tree_hash(auth_path[h], root, seed, adrs, root); |
| 403 | + else sphincs_xmss_tree_hash(root, auth_path[h], seed, adrs, root); |
| 404 | + } |
| 405 | +} |
| 406 | + |
| 407 | +// TODO: index or tree_index? |
| 408 | +void sphincs_xmss_sign(const sphincs_secret_t secret, uint32_t index, |
| 409 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 410 | + const sphincs_secret_t dgst, SPHINCS_XMSS_SIGNATURE *sig) |
358 | 411 | { |
| 412 | + size_t height = SPHINCS_XMSS_HEIGHT; |
| 413 | + sphincs_adrs_t adrs; |
| 414 | + sphincs_wots_key_t wots_sk; |
| 415 | + sphincs_secret_t tree[(1 << (SPHINCS_XMSS_HEIGHT + 1)) - 1]; |
| 416 | + |
| 417 | + // generate wots_sig |
| 418 | + sphincs_wots_derive_sk(secret, seed, adrs, wots_sk); |
| 419 | + sphincs_wots_sign(wots_sk, seed, adrs, dgst, sig->wots_sig); |
| 420 | + |
| 421 | + // build xmss_tree, then build auth_path |
| 422 | + sphincs_xmss_build_tree(secret, seed, adrs, height, tree); |
| 423 | + sphincs_xmss_build_auth_path(tree, height, index, sig->auth_path); |
359 | 424 | } |
360 | 425 |
|
| 426 | +void sphincs_xmss_sig_to_root(const SPHINCS_XMSS_SIGNATURE *sig, |
| 427 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 428 | + const sphincs_secret_t dgst, sphincs_secret_t xmss_root) |
| 429 | +{ |
| 430 | + sphincs_adrs_t adrs; |
| 431 | + sphincs_wots_key_t wots_pk; |
| 432 | + sphincs_secret_t wots_root; |
| 433 | + size_t height = SPHINCS_XMSS_HEIGHT; |
| 434 | + |
361 | 435 |
|
| 436 | + sphincs_wots_sig_to_pk(sig->wots_sig, seed, adrs, dgst, wots_pk); |
| 437 | + sphincs_wots_pk_to_root(wots_pk, seed, adrs, wots_root); |
362 | 438 |
|
363 | 439 |
|
364 | | -void fors_derive_secret(const sphincs_secret_t seed, const sphincs_secret_t secret, |
365 | | - const sphincs_adrs_t in_adrs, uint32_t fors_index, sphincs_secret_t sk) |
| 440 | + sphincs_xmss_build_root(wots_root, sig->index, seed, adrs, |
| 441 | + sig->auth_path, height, |
| 442 | + xmss_root); |
| 443 | +} |
| 444 | + |
| 445 | +// generate the highest layer xmss_tree root |
| 446 | +void sphincs_hypertree_derive_root(const sphincs_secret_t secret, const sphincs_secret_t seed, |
| 447 | + sphincs_secret_t root) |
| 448 | +{ |
| 449 | + sphincs_adrs_t adrs; |
| 450 | + sphincs_secret_t tree[(1 << (SPHINCS_XMSS_HEIGHT + 1)) - 1]; |
| 451 | + sphincs_adrs_set_layer_address(adrs, SPHINCS_HYPERTREE_LAYERS - 1); |
| 452 | + sphincs_adrs_set_tree_address(adrs, 0); |
| 453 | + sphincs_xmss_build_tree(secret, seed, adrs, SPHINCS_XMSS_HEIGHT, tree); |
| 454 | + root = tree[(1 << (SPHINCS_XMSS_HEIGHT + 1)) - 2]; |
| 455 | +} |
| 456 | + |
| 457 | +// FIXME: uint64_t for leaf_index? |
| 458 | +void sphincs_hypertree_sign(const sphincs_secret_t secret, const sphincs_secret_t seed, |
| 459 | + uint32_t tree_index, uint32_t leaf_index, |
| 460 | + SPHINCS_XMSS_SIGNATURE sig[SPHINCS_HYPERTREE_LAYERS]) |
| 461 | +{ |
| 462 | + sphincs_adrs_t adrs = {0}; |
| 463 | + |
| 464 | +} |
| 465 | + |
| 466 | + |
| 467 | + |
| 468 | +void sphincs_fors_derive_sk(const sphincs_secret_t secret, |
| 469 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 470 | + uint32_t fors_index, sphincs_secret_t sk) |
366 | 471 | { |
367 | 472 | uint8_t block[HASH256_BLOCK_SIZE] = {0}; |
368 | 473 | sphincs_adrs_t adrs; |
@@ -394,96 +499,41 @@ void fors_derive_secret(const sphincs_secret_t seed, const sphincs_secret_t secr |
394 | 499 | gmssl_secure_clear(dgst, sizeof(dgst)); |
395 | 500 | } |
396 | 501 |
|
397 | | - |
398 | | - |
399 | | - |
400 | | - |
401 | | - |
402 | | -/* |
403 | | -int fors_derive_merkle_tree(const sphincs_hash_t sk_seed, const sphincs_adrs_t adrs, sphincs_hash_t *tree) |
| 502 | +void sphincs_fors_derive_root_ex(const sphincs_secret_t secret, |
| 503 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 504 | + size_t fors_height, size_t fors_trees, |
| 505 | + sphincs_secret_t root) |
404 | 506 | { |
405 | | - int r; |
406 | | -
|
407 | | - int a = 12; |
408 | | - int t = (1 << a); |
409 | | -
|
410 | | -
|
411 | | - uint8_t rbytes[4]; |
412 | | - HASH256_CTX ctx; |
413 | | - hash256_t x[34]; |
414 | | - hash256_t pub; |
415 | | - hash256_t *T = tree - 1; |
416 | | -
|
417 | | - for (r = 2*t - 1; r >= 1; r--) { |
418 | | -
|
419 | | - PUTU32(rbytes, r); |
420 | | -
|
421 | | - if (r >= t) { |
422 | | - int q = r - n; |
423 | | -
|
424 | | -
|
425 | | - sm3_lmots_derive_secrets(seed, I, q, x); |
426 | | - sm3_lmots_secrets_to_public_hash(I, q, x, pub); |
427 | | -
|
428 | | -
|
| 507 | +} |
429 | 508 |
|
430 | | - // H(I||u32str(r)||u16str(D_LEAF)||OTS_PUB_HASH[r-2^h]) |
431 | | - hash256_init(&ctx); |
432 | | - hash256_update(&ctx, I, 16); |
433 | | - hash256_update(&ctx, rbytes, 4); |
434 | | - hash256_update(&ctx, D_LEAF, 2); |
435 | | - hash256_update(&ctx, pub, 32); |
436 | | - hash256_finish(&ctx, T[r]); |
| 509 | +void sphincs_fors_derive_root(const sphincs_secret_t secret, |
| 510 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 511 | + sphincs_secret_t root) |
| 512 | +{ |
| 513 | + size_t fors_height = SPHINCS_FORS_HEIGHT; |
| 514 | + size_t fors_trees = SPHINCS_FORS_NUM_TREES; |
437 | 515 |
|
438 | | - } else { |
439 | | - // H(I||u32str(r)||u16str(D_INTR)||T[2*r]||T[2*r+1]) |
440 | | - hash256_init(&ctx); |
441 | | - hash256_update(&ctx, I, 16); |
442 | | - hash256_update(&ctx, rbytes, 4); |
443 | | - hash256_update(&ctx, D_INTR, 2); |
444 | | - hash256_update(&ctx, T[2*r], 32); |
445 | | - hash256_update(&ctx, T[2*r + 1], 32); |
446 | | - hash256_finish(&ctx, T[r]); |
447 | | - } |
448 | | - } |
| 516 | + sphincs_fors_derive_root_ex(secret, seed, in_adrs, fors_height, fors_trees, root); |
449 | 517 | } |
450 | 518 |
|
451 | 519 |
|
452 | | -
|
453 | | -int fors_derive_secrets(const sphincs_hash_t sk_seed, const sphincs_adrs_t adrs, uint32_t index, sphincs_hash_t sk[14 * 4096]) |
| 520 | +void sphincs_fors_sign(const sphincs_secret_t secret, |
| 521 | + const sphincs_secret_t seed, const sphincs_adrs_t in_adrs, |
| 522 | + const uint8_t dgst[SPHINCS_FORS_DIGEST_SIZE], |
| 523 | + SPHINCS_FORS_SIGNATURE *sig) |
454 | 524 | { |
455 | | - sphincs_adrs_t sk_adrs; |
456 | | - uint32_t i; |
| 525 | + sphincs_adrs_t adrs; |
| 526 | + sphincs_secret_t fors_sk; |
| 527 | + size_t i; |
457 | 528 |
|
458 | | - memcpy(sk_adrs, adrs, sizeof(sphincs_adrs_t)); |
459 | | - sphincs_adrs_set_type(sk_adrs, SPHINCSX_ADRS_TYPE_FORS_KEYGEN); |
460 | | - sphincs_adrs_set_tree_height(sk_adrs, 0); |
461 | | - sphincs_adrs_set_tree_index(sk_adrs, index); |
| 529 | + for (i = 0; i < SPHINCS_FORS_NUM_TREES; i++) { |
462 | 530 |
|
463 | | - for (i = 0; i < SPHINCSX_FORS_NUM_SK; i++) { |
464 | | - sphincs_adrs_set_keypair_addrss(sk_adrs, i); |
465 | | - sphincs_prf(sk_seed, sk_adrs, sk[i]); |
466 | | - } |
467 | 531 |
|
468 | | - return 1; |
469 | | -} |
| 532 | + //sphincs_fors_derive_sk(secret, seed, adrs, fors_index, fors_sk); |
470 | 533 |
|
471 | 534 |
|
472 | | -void fors_treehash(const sphincs_hash_t sk_seed, const sphincs_hash_t pk_seed) |
473 | | -{ |
474 | | -} |
475 | 535 |
|
476 | | -void fors_secrets_to_public_root(const sphincs_hash_t sk[SPHINCSX_FORS_NUM_SK], |
477 | | - const sphincs_adrs_t pk_seed, const sphincs_adrs_t adrs, |
478 | | - sphincs_hash_t pub) |
479 | | -{ |
480 | | -
|
481 | | -} |
| 536 | + } |
482 | 537 |
|
483 | | -int fors_treehash(const sphincs_adrs_t sk_seed, cosnt sphincs_adrs_t pk_seed, |
484 | | - unsigned int s, unsigned int z, const sphincs_adrs_t fors_adrs, |
485 | | - uint8_t out[16]) |
486 | | -{ |
487 | 538 | } |
488 | | -*/ |
489 | 539 |
|
0 commit comments