Reference implementations of PQC
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.
 
 
 
 

157 lines
5.5 KiB

  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include "sp800-185.h"
  4. static size_t left_encode(uint8_t *encbuf, size_t value) {
  5. size_t n, i, v;
  6. for (v = value, n = 0; v && (n < sizeof(size_t)); n++, v >>= 8) {
  7. ; /* empty */
  8. }
  9. if (n == 0) {
  10. n = 1;
  11. }
  12. for (i = 1; i <= n; i++) {
  13. encbuf[i] = (uint8_t)(value >> (8 * (n-i)));
  14. }
  15. encbuf[0] = (uint8_t)n;
  16. return n + 1;
  17. }
  18. void cshake128_inc_init(shake128incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen) {
  19. uint8_t encbuf[sizeof(size_t)+1];
  20. shake128_inc_init(state);
  21. shake128_inc_absorb(state, encbuf, left_encode(encbuf, SHAKE128_RATE));
  22. shake128_inc_absorb(state, encbuf, left_encode(encbuf, namelen * 8));
  23. shake128_inc_absorb(state, name, namelen);
  24. shake128_inc_absorb(state, encbuf, left_encode(encbuf, cstmlen * 8));
  25. shake128_inc_absorb(state, cstm, cstmlen);
  26. if (state->ctx[25] != 0) {
  27. state->ctx[25] = SHAKE128_RATE - 1;
  28. encbuf[0] = 0;
  29. shake128_inc_absorb(state, encbuf, 1);
  30. }
  31. }
  32. void cshake128_inc_absorb(shake128incctx *state, const uint8_t *input, size_t inlen) {
  33. shake128_inc_absorb(state, input, inlen);
  34. }
  35. void cshake128_inc_finalize(shake128incctx *state) {
  36. state->ctx[state->ctx[25] >> 3] ^= (uint64_t)0x04 << (8 * (state->ctx[25] & 0x07));
  37. state->ctx[(SHAKE128_RATE - 1) >> 3] ^= (uint64_t)128 << (8 * ((SHAKE128_RATE - 1) & 0x07));
  38. state->ctx[25] = 0;
  39. }
  40. void cshake128_inc_squeeze(uint8_t *output, size_t outlen, shake128incctx *state) {
  41. shake128_inc_squeeze(output, outlen, state);
  42. }
  43. void cshake128_inc_ctx_release(shake128incctx *state) {
  44. shake128_inc_ctx_release(state);
  45. }
  46. void cshake128_inc_ctx_clone(shake128incctx *dest, const shake128incctx *src) {
  47. shake128_inc_ctx_clone(dest, src);
  48. }
  49. void cshake256_inc_init(shake256incctx *state, const uint8_t *name, size_t namelen, const uint8_t *cstm, size_t cstmlen) {
  50. uint8_t encbuf[sizeof(size_t)+1];
  51. shake256_inc_init(state);
  52. shake256_inc_absorb(state, encbuf, left_encode(encbuf, SHAKE256_RATE));
  53. shake256_inc_absorb(state, encbuf, left_encode(encbuf, namelen * 8));
  54. shake256_inc_absorb(state, name, namelen);
  55. shake256_inc_absorb(state, encbuf, left_encode(encbuf, cstmlen * 8));
  56. shake256_inc_absorb(state, cstm, cstmlen);
  57. if (state->ctx[25] != 0) {
  58. state->ctx[25] = SHAKE256_RATE - 1;
  59. encbuf[0] = 0;
  60. shake256_inc_absorb(state, encbuf, 1);
  61. }
  62. }
  63. void cshake256_inc_absorb(shake256incctx *state, const uint8_t *input, size_t inlen) {
  64. shake256_inc_absorb(state, input, inlen);
  65. }
  66. void cshake256_inc_finalize(shake256incctx *state) {
  67. state->ctx[state->ctx[25] >> 3] ^= (uint64_t)0x04 << (8 * (state->ctx[25] & 0x07));
  68. state->ctx[(SHAKE256_RATE - 1) >> 3] ^= (uint64_t)128 << (8 * ((SHAKE256_RATE - 1) & 0x07));
  69. state->ctx[25] = 0;
  70. }
  71. void cshake256_inc_squeeze(uint8_t *output, size_t outlen, shake256incctx *state) {
  72. shake256_inc_squeeze(output, outlen, state);
  73. }
  74. void cshake256_inc_ctx_release(shake256incctx *state) {
  75. shake256_inc_ctx_release(state);
  76. }
  77. void cshake256_inc_ctx_clone(shake256incctx *dest, const shake256incctx *src) {
  78. shake256_inc_ctx_clone(dest, src);
  79. }
  80. /*************************************************
  81. * Name: cshake128
  82. *
  83. * Description: cSHAKE128 XOF with non-incremental API
  84. *
  85. * Arguments: - uint8_t *output: pointer to output
  86. * - size_t outlen: requested output length in bytes
  87. * - const uint8_t *name: pointer to function-name string
  88. * - size_t namelen: length of function-name string in bytes
  89. * - const uint8_t *cstm: pointer to non-empty customization string
  90. * - size_t cstmlen: length of customization string in bytes
  91. * - const uint8_t *input: pointer to input
  92. * - size_t inlen: length of input in bytes
  93. **************************************************/
  94. void cshake128(uint8_t *output, size_t outlen,
  95. const uint8_t *name, size_t namelen,
  96. const uint8_t *cstm, size_t cstmlen,
  97. const uint8_t *input, size_t inlen) {
  98. shake128incctx state;
  99. cshake128_inc_init(&state, name, namelen, cstm, cstmlen);
  100. cshake128_inc_absorb(&state, input, inlen);
  101. cshake128_inc_finalize(&state);
  102. cshake128_inc_squeeze(output, outlen, &state);
  103. cshake128_inc_ctx_release(&state);
  104. }
  105. /*************************************************
  106. * Name: cshake256
  107. *
  108. * Description: cSHAKE256 XOF with non-incremental API
  109. *
  110. * Arguments: - uint8_t *output: pointer to output
  111. * - size_t outlen: requested output length in bytes
  112. * - const uint8_t *name: pointer to function-name string
  113. * - size_t namelen: length of function-name string in bytes
  114. * - const uint8_t *cstm: pointer to non-empty customization string
  115. * - size_t cstmlen: length of customization string in bytes
  116. * - const uint8_t *input: pointer to input
  117. * - size_t inlen: length of input in bytes
  118. **************************************************/
  119. void cshake256(uint8_t *output, size_t outlen,
  120. const uint8_t *name, size_t namelen,
  121. const uint8_t *cstm, size_t cstmlen,
  122. const uint8_t *input, size_t inlen) {
  123. shake256incctx state;
  124. cshake256_inc_init(&state, name, namelen, cstm, cstmlen);
  125. cshake256_inc_absorb(&state, input, inlen);
  126. cshake256_inc_finalize(&state);
  127. cshake256_inc_squeeze(output, outlen, &state);
  128. cshake256_inc_ctx_release(&state);
  129. }