Skip to content

Conversation

@prasincs
Copy link

@prasincs prasincs commented Jul 4, 2025

I wanted to use this on a mac and noticed that the RNG was openssl based. I'm not sure if this can be generalized to use other enclaves but building this on a mac to have RNG be generated from secure enclave is relatively straightforward. If there's a more generic way to get RNG with other hardware targets beyond Apple M{1-4}, ideally that are available on phones, etc I'd be happy to make modifications for that

Changes Made

  • Add conditional compilation support for Apple Secure Enclave random number generation on macOS
  • Introduce USE_SECURE_ENCLAVE_RNG CMake option (default: OFF) to enable hardware-backed entropy
  • Add is_secure_enclave_active() API for runtime verification of Secure Enclave usage
  • Maintain full backward compatibility - no changes to existing rand_bytes() API
  • Cross-platform support: Secure Enclave on macOS, OpenSSL fallback on other platforms
  • Security framework automatically linked when enabled

When USE_SECURE_ENCLAVE_RNG=ON is set on macOS with Apple silicon, all cryptographic random
number generation in zero-knowledge proof construction uses hardware-backed entropy from
Apple's Secure Enclave instead of OpenSSL's software RNG.

  * Add conditional compilation support for Apple Secure Enclave random number generation on
  macOS
  * Introduce USE_SECURE_ENCLAVE_RNG CMake option (default: OFF) to enable hardware-backed
  entropy
  * Add is_secure_enclave_active() API for runtime verification of Secure Enclave usage
  * Maintain full backward compatibility - no changes to existing rand_bytes() API
  * Cross-platform support: Secure Enclave on macOS, OpenSSL fallback on other platforms
  * Security framework automatically linked when enabled

  When USE_SECURE_ENCLAVE_RNG=ON is set on macOS with Apple silicon, all cryptographic random
  number generation in zero-knowledge proof construction uses hardware-backed entropy from
  Apple's Secure Enclave instead of OpenSSL's software RNG.
@google-cla
Copy link

google-cla bot commented Jul 4, 2025

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@matteo-frigo
Copy link
Collaborator

Can you hold off with this PR for a few days/weeks? We are currently not set up to accept PRs. The code you are looking at is the one used internally by Google, pushed to github via automatic tools. Roughly speaking, the plan is to create another "google" branch where we maintain a pristine copy of our internal codebase, and push our updates to that. The current main branch would become a branch that accepts contributions, with regular contributions from the "google" branch. However, if I accept your patch today, the next push from Google would overwrite it.

@prasincs
Copy link
Author

prasincs commented Jul 4, 2025

Can you hold off with this PR for a few days/weeks? We are currently not set up to accept PRs. The code you are looking at is the one used internally by Google, pushed to github via automatic tools. Roughly speaking, the plan is to create another "google" branch where we maintain a pristine copy of our internal codebase, and push our updates to that. The current main branch would become a branch that accepts contributions, with regular contributions from the "google" branch. However, if I accept your patch today, the next push from Google would overwrite it.

Ah got it, I can easily change this to different base branch when you're ready. I'm only experimenting here, so I don't have any urgency

@jaromil
Copy link

jaromil commented Jul 4, 2025

Hi @prasincs while we wait, I'd be grateful if you can have a look at PR #4 where I meant to do a similar thing for embedded systems as well WASM target.

Now also considering your case and probably more to come, I wonder if the best approach here would be to expose callback functions that can be configured at runtime. This way you could provide a function pointer to the ASE RNG and others do their own business. I wonder about this knowing that build-time macros can quickly grow into chaos. Open to hear your opinion!

@prasincs
Copy link
Author

prasincs commented Jul 4, 2025

Hi @prasincs while we wait, I'd be grateful if you can have a look at PR #4 where I meant to do a similar thing for embedded systems as well WASM target.

Now also considering your case and probably more to come, I wonder if the best approach here would be to expose callback functions that can be configured at runtime. This way you could provide a function pointer to the ASE RNG and others do their own business. I wonder about this knowing that build-time macros can quickly grow into chaos. Open to hear your opinion!

Ah yes, now I see they're somewhat related. I'm not a very active C++ developer, so there might be more modern ways to handle this that I'm not aware of. It seems @abhvious is also looking at the same design space too. I prefer to make a compile-time enforceable interface so that you have control over what library or interface you use for RNG, I think that should work.. Something like this is (likely) enough.

 class RngBackend {
 public:
     static RngStatus Initialize();
     static const RngInfo& GetInfo();
     static RngStatus GenerateBytes(uint8_t* buf, size_t n);
     static void Cleanup();
}

Then every backend would get a compile-time flag to bake in the correct libraries, headers, etc. I prefer to fail at runtime if the correct backend isn't used. WASM case should work fine here too because it'd just be another backend to compile in and it'd be up to the WASM/WASI runtime to do proper wiring for the RNG.

@jaromil
Copy link

jaromil commented Jul 4, 2025

Reading you comes to mind the C++ idiomatic solution of a pure virtual class. It should then have a class definition activated at build time by platform dependent switches, similar to the ones I have here. But it will fail already at build time if none is provided.

It will be important to have literally a pure virtual class, else runtime resolution of methods (polymorphism) adds a lot of computation overhead.

Cheers

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