Reference implementations of PQC
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 

104 行
2.5 KiB

  1. //
  2. // rng.c
  3. //
  4. // Created by Bassham, Lawrence E (Fed) on 8/29/17.
  5. // Copyright © 2017 Bassham, Lawrence E (Fed). All rights reserved.
  6. // Modified for PQClean by Sebastian Verschoor
  7. //
  8. #include "nistseedexpander.h"
  9. #include "aes.h"
  10. #include <string.h>
  11. /*
  12. seedexpander_init()
  13. ctx - stores the current state of an instance of the seed expander
  14. seed - a 32 byte random value
  15. diversifier - an 8 byte diversifier
  16. maxlen - maximum number of bytes (less than 2**32) generated under this seed and diversifier
  17. */
  18. int
  19. seedexpander_init(AES_XOF_struct *ctx,
  20. const uint8_t *seed,
  21. const uint8_t *diversifier,
  22. size_t maxlen)
  23. {
  24. ctx->length_remaining = maxlen;
  25. memcpy(ctx->key, seed, 32);
  26. memcpy(ctx->ctr, diversifier, 8);
  27. ctx->ctr[11] = maxlen % 256;
  28. maxlen >>= 8;
  29. ctx->ctr[10] = maxlen % 256;
  30. maxlen >>= 8;
  31. ctx->ctr[9] = maxlen % 256;
  32. maxlen >>= 8;
  33. ctx->ctr[8] = maxlen % 256;
  34. memset(ctx->ctr+12, 0x00, 4);
  35. ctx->buffer_pos = 16;
  36. memset(ctx->buffer, 0x00, 16);
  37. return RNG_SUCCESS;
  38. }
  39. static void AES256_ECB(uint8_t *key, uint8_t *ctr, uint8_t *buffer) {
  40. aes256ctx ctx;
  41. aes256_ecb_keyexp(&ctx, key);
  42. aes256_ecb(buffer, ctr, 1, &ctx);
  43. aes256_ctx_release(&ctx);
  44. }
  45. /*
  46. seedexpander()
  47. ctx - stores the current state of an instance of the seed expander
  48. x - returns the XOF data
  49. xlen - number of bytes to return
  50. */
  51. int
  52. seedexpander(AES_XOF_struct *ctx, uint8_t *x, size_t xlen)
  53. {
  54. size_t offset;
  55. if ( x == NULL ) {
  56. return RNG_BAD_OUTBUF;
  57. }
  58. if ( xlen >= ctx->length_remaining ) {
  59. return RNG_BAD_REQ_LEN;
  60. }
  61. ctx->length_remaining -= xlen;
  62. offset = 0;
  63. while ( xlen > 0 ) {
  64. if ( xlen <= (16-ctx->buffer_pos) ) { // buffer has what we need
  65. memcpy(x+offset, ctx->buffer+ctx->buffer_pos, xlen);
  66. ctx->buffer_pos += xlen;
  67. return RNG_SUCCESS;
  68. }
  69. // take what's in the buffer
  70. memcpy(x+offset, ctx->buffer+ctx->buffer_pos, 16-ctx->buffer_pos);
  71. xlen -= 16-ctx->buffer_pos;
  72. offset += 16-ctx->buffer_pos;
  73. AES256_ECB(ctx->key, ctx->ctr, ctx->buffer);
  74. ctx->buffer_pos = 0;
  75. //increment the counter
  76. for (size_t i=15; i>=12; i--) {
  77. if ( ctx->ctr[i] == 0xff ) {
  78. ctx->ctr[i] = 0x00;
  79. } else {
  80. ctx->ctr[i]++;
  81. break;
  82. }
  83. }
  84. }
  85. return RNG_SUCCESS;
  86. }