jedisct1 / libsodium

A modern, portable, easy to use crypto library.

Home Page:https://libsodium.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Usage of `require` by `randombytes` does not work in ESM

jboillot opened this issue · comments

Hello,
As I was trying to use randombytes primitive into an ES module I encountered an error.
Indeed, in src/libsodium/randombytes/randombytes.c:69 there is a var crypto = require('crypto'); and require is not defined in ESM.
A solution would be to modify it to var crypto = await import('crypto'); (if require fails). It works but since the function is not async I had to modify it into:

import('crypto').then((crypto) => {
    var randomValueNodeJS = function() {
        var buf = crypto['randomBytes'](4);
        return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
    };
    randomValueNodeJS();
    Module.getRandomValue = randomValueNodeJS;
}).catch((e) => {
    throw 'No secure random number generator found';
});

However, the Module.getRandomValue is set asynchronously so I guess such a modification would not be accepted.

In conclusion, would you have any idea on how to make randombytes work both with CommonJS and ESM?
By the way, this is the only require occurrence in the entire library.

Thanks for reading,
Jérôme

I found a workaround: add by myself the definition of Module.getRandomValue before calling randombytes_stir:

const crypto = await import('crypto');
const randomValueNodeJS = () => {
    const buf = crypto.randomBytes(4);
    return (buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]) >>> 0;
};
randomValueNodeJS();
Module.getRandomValue = randomValueNodeJS;

However I guess it would still be interesting to fix compatibility with ESM in the library.