You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

用Emscripten编译ed25519_randombytes为Wasm的熵源及运行机制

Ed25519_randombytes函数在Wasm环境下的熵源与运行原理

原C语言实现代码

static inline void ed25519_randombytes(unsigned char *x,unsigned long long xlen)
{
  int i;

  if (ed25519_random_fd == -1) {
    for (;;) {
      ed25519_random_fd = open("/dev/urandom",O_RDONLY);
      if (ed25519_random_fd != -1) break;
      sleep(1);
    }
  }

  while (xlen > 0) {
    if (xlen < 1048576) i = xlen; else i = 1048576;

    i = read(ed25519_random_fd,x,i);
    if (i < 1) {
      sleep(1);
      continue;
    }

    x += i;
    xlen -= i;
  }
}

问题背景

上述ed25519_randombytes函数原本通过读取Linux系统的/dev/urandom设备文件获取随机字节,但使用emcc编译为Wasm后,在Node.js或浏览器环境中仍能正常生成随机字节。需要明确该场景下的熵源及运行原理。

解答

核心机制:Emscripten的系统调用模拟

Emscripten(emcc是其编译工具)在将C代码转为Wasm时,会对Linux风格的系统调用(如open、read、sleep)做模拟实现,不会在非Linux环境中直接访问/dev/urandom物理设备。


1. Node.js环境

熵源

Node.js内置crypto模块提供的加密安全随机数生成器,底层依赖操作系统原生熵源:

  • Linux:getrandom系统调用
  • macOS:SecRandomCopyBytes接口
  • Windows:CryptGenRandom API

运行逻辑

  • 当Wasm代码调用open("/dev/urandom")时,Emscripten的模拟层会识别这个特殊路径,不会真的打开文件,仅标记后续read操作需获取随机字节。
  • 执行read调用时,Emscripten会调用Node.js的crypto.randomBytes()接口生成指定长度的随机数据,返回给Wasm缓冲区。
  • 代码中的sleep(1)会被模拟为Node.js的setTimeout,实现延迟重试逻辑。

2. 浏览器环境

熵源

浏览器Web Crypto API的crypto.getRandomValues()方法,底层依赖:

  • 操作系统原生安全随机数生成器
  • 部分浏览器会额外结合用户输入(鼠标移动、键盘敲击等)补充熵源

运行逻辑

  • Emscripten拦截open("/dev/urandom")调用,无需实际打开设备文件。
  • 执行read时,Emscripten调用浏览器的crypto.getRandomValues()生成随机字节,传递给Wasm中的目标缓冲区。
  • sleep(1)被模拟为浏览器的setTimeout,实现循环重试逻辑。

关键注意点

  • Emscripten仅对/dev/urandom做特殊适配,其他文件路径不会映射到随机数接口。
  • 生成的随机数属于加密安全级别,和原生Linux环境读取/dev/urandom的安全性一致,因为底层依赖的都是操作系统提供的正规熵源。

内容的提问来源于stack exchange,提问作者Milos Mirkovic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 21:50:16