You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

72 lines
3.1 KiB

  1. /* Based on the public domain implementation in
  2. * crypto_hash/sha512/ref/ from http://bench.cr.yp.to/supercop.html
  3. * by D. J. Bernstein */
  4. #include <stddef.h>
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include "sha2.h"
  8. #include "sha256.h"
  9. #include "utils.h"
  10. /*
  11. * Compresses an address to a 22-byte sequence.
  12. * This reduces the number of required SHA256 compression calls, as the last
  13. * block of input is padded with at least 65 bits.
  14. */
  15. void PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_compress_address(unsigned char *out, const uint32_t addr[8]) {
  16. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out, 1, addr[0]); /* drop 3 bytes of the layer field */
  17. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 1, 4, addr[2]); /* drop the highest tree address word */
  18. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 5, 4, addr[3]);
  19. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 9, 1, addr[4]); /* drop 3 bytes of the type field */
  20. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 10, 4, addr[5]);
  21. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 14, 4, addr[6]);
  22. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(out + 18, 4, addr[7]);
  23. }
  24. /**
  25. * Requires 'input_plus_four_bytes' to have 'inlen' + 4 bytes, so that the last
  26. * four bytes can be used for the counter. Typically 'input' is merely a seed.
  27. * Outputs outlen number of bytes
  28. */
  29. void PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_mgf1(
  30. unsigned char *out, unsigned long outlen,
  31. unsigned char *input_plus_four_bytes, unsigned long inlen) {
  32. unsigned char outbuf[PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_OUTPUT_BYTES];
  33. unsigned long i;
  34. /* While we can fit in at least another full block of SHA256 output.. */
  35. for (i = 0; (i + 1)*PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_OUTPUT_BYTES <= outlen; i++) {
  36. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(input_plus_four_bytes + inlen, 4, i);
  37. sha256(out, input_plus_four_bytes, inlen + 4);
  38. out += PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_OUTPUT_BYTES;
  39. }
  40. /* Until we cannot anymore, and we fill the remainder. */
  41. if (outlen > i * PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_OUTPUT_BYTES) {
  42. PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_ull_to_bytes(input_plus_four_bytes + inlen, 4, i);
  43. sha256(outbuf, input_plus_four_bytes, inlen + 4);
  44. memcpy(out, outbuf, outlen - i * PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_OUTPUT_BYTES);
  45. }
  46. }
  47. /**
  48. * Absorb the constant pub_seed using one round of the compression function
  49. * This initializes hash_state_seeded, which can then be reused in thash
  50. **/
  51. void PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_seed_state(sha256ctx *hash_state_seeded, const unsigned char *pub_seed) {
  52. uint8_t block[PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_BLOCK_BYTES];
  53. size_t i;
  54. for (i = 0; i < PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_N; ++i) {
  55. block[i] = pub_seed[i];
  56. }
  57. for (i = PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_N; i < PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_SHA256_BLOCK_BYTES; ++i) {
  58. block[i] = 0;
  59. }
  60. sha256_inc_init(hash_state_seeded);
  61. sha256_inc_blocks(hash_state_seeded, block, 1);
  62. }