Skip to content

Conversation

@RReverser
Copy link
Collaborator

@RReverser RReverser commented Mar 23, 2023

  • Uses random filling directly into the destination when possible.
  • Fills up the entire block at once to avoid overhead of asking the underlying implementation to generate each byte separately.
  • Generates buffer chunks for / dev/{u,}random for the same reasons.

 - Uses random filling directly into the destination when possible.
 - Fills up the entire block at once to avoid overhead of asking the underlying implementation to generate each byte separately.
 - Generates buffer chunks for / dev/{u,}random for the same reasons.
@RReverser RReverser requested review from kripken and sbc100 March 23, 2023 21:34
@RReverser
Copy link
Collaborator Author

RReverser commented Mar 23, 2023

Non-scientific benchmark compiled with -O3 showing that it still works correctly & is indeed way faster:

#include <emscripten.h>
#include <unistd.h>
#include <stdio.h>

// 256-bit entropy buffer
// volatile just to prevent it from getting optimized out
volatile unsigned char entropy[32] = {0};

void print_entropy() {
  printf("Entropy value: ");
  for (int i = 0; i < 32; ++i) {
    printf("%02x", entropy[i]);
  }
  printf("\n");
}

int main() {
  print_entropy();
  double start = emscripten_get_now();
  // preheat
  for (int i = 0; i < 100; ++i) {
    getentropy((void*) entropy, sizeof(entropy));
  }
  // actual benchmark
  int n = 100000;
  for (int i = 0; i < n; ++i) {
    getentropy((void*) entropy, sizeof(entropy));
  }
  double end = emscripten_get_now();
  printf("Time per call: %fns\n", (end - start) * 1000 / n);
  print_entropy();
}

Old (Node.js):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 83.646909ns
Entropy value: eceacda315bc4aa0f4371b6b9b5f1266a999cd5fb3873bbdbbab5d5d514b7dd6

New (Node.js):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 2.514285ns
Entropy value: ab5a6870feb9c14a8323e1666e210ced0704b2d7f8d2ef7ccdddc0d3e6594431

Old (browser):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 24.255750ns
Entropy value: bf1902314e41ad063ecbdbe3235c3b81d4f8d45c74d10deee9684505ded5b4d4

New (browser):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 1.656000ns
Entropy value: c47ca65b8ac13439ce5df870f5281b285e2072041fd39eb9ae57861b13e63935

Old (browser + pthread):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 22.963799ns
Entropy value: 355a82b0790efe0c09c4f281bfdaf69bcad28a037733f2e2b994a2ae46c86a6f

New (browser + pthread):

Entropy value: 0000000000000000000000000000000000000000000000000000000000000000
Time per call: 2.961150ns
Entropy value: 26850aff38d2769714ede7ea0e0fddc834a10fb27acea21134236aa8a66e84ba

In fact, the new timing is pretty much constant-time whether you generate sizeof(int) or 256 bits like in my benchmark, but always faster than before.

@RReverser RReverser merged commit 3cf83fd into main Mar 24, 2023
@RReverser RReverser deleted the faster-entropy branch March 24, 2023 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants