25'ten fazla konu seçemezsiniz Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
 
 
 

98 satır
2.7 KiB

  1. /// @file utils_prng.c
  2. /// @brief The implementation of PRNG related functions.
  3. ///
  4. #include "utils_prng.h"
  5. #include "aes.h"
  6. #include "randombytes.h"
  7. #include "utils_hash.h"
  8. #include <stdlib.h>
  9. #include <string.h>
  10. static void prng_update(const unsigned char *provided_data,
  11. unsigned char *Key,
  12. unsigned char *V) {
  13. unsigned char temp[48];
  14. aes256ctx ctx;
  15. aes256_keyexp(&ctx, Key);
  16. for (int i = 0; i < 3; i++) {
  17. //increment V
  18. for (int j = 15; j >= 0; j--) {
  19. if (V[j] == 0xff) {
  20. V[j] = 0x00;
  21. } else {
  22. V[j]++;
  23. break;
  24. }
  25. }
  26. aes256_ecb(temp + 16 * i, V, 1, &ctx);
  27. }
  28. if (provided_data != NULL) {
  29. for (int i = 0; i < 48; i++) {
  30. temp[i] ^= provided_data[i];
  31. }
  32. }
  33. aes256_ctx_release(&ctx);
  34. memcpy(Key, temp, 32);
  35. memcpy(V, temp + 32, 16);
  36. }
  37. static void randombytes_init_with_state(prng_t *state,
  38. unsigned char *entropy_input_48bytes) {
  39. memset(state->Key, 0x00, 32);
  40. memset(state->V, 0x00, 16);
  41. prng_update(entropy_input_48bytes, state->Key, state->V);
  42. }
  43. static int randombytes_with_state(prng_t *state,
  44. unsigned char *x,
  45. size_t xlen) {
  46. unsigned char block[16];
  47. int i = 0;
  48. aes256ctx ctx;
  49. aes256_keyexp(&ctx, state->Key);
  50. while (xlen > 0) {
  51. //increment V
  52. for (int j = 15; j >= 0; j--) {
  53. if (state->V[j] == 0xff) {
  54. state->V[j] = 0x00;
  55. } else {
  56. state->V[j]++;
  57. break;
  58. }
  59. }
  60. aes256_ecb(block, state->V, 1, &ctx);
  61. if (xlen > 15) {
  62. memcpy(x + i, block, 16);
  63. i += 16;
  64. xlen -= 16;
  65. } else {
  66. memcpy(x + i, block, xlen);
  67. xlen = 0;
  68. }
  69. }
  70. aes256_ctx_release(&ctx);
  71. prng_update(NULL, state->Key, state->V);
  72. return 0;
  73. }
  74. int PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_set(prng_t *ctx, const void *prng_seed, unsigned long prng_seedlen) {
  75. unsigned char seed[48];
  76. if (prng_seedlen >= 48) {
  77. memcpy(seed, prng_seed, 48);
  78. } else {
  79. memcpy(seed, prng_seed, prng_seedlen);
  80. PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_hash_msg(seed + prng_seedlen, 48 - (unsigned)prng_seedlen, (const unsigned char *)prng_seed, prng_seedlen);
  81. }
  82. randombytes_init_with_state(ctx, seed);
  83. return 0;
  84. }
  85. int PQCLEAN_RAINBOWIACYCLICCOMPRESSED_CLEAN_prng_gen(prng_t *ctx, unsigned char *out, unsigned long outlen) {
  86. return randombytes_with_state(ctx, out, outlen);
  87. }