Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries
Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries.
npm i gmp-wasm
It can also be used directly from HTML (via jsDelivr):
<!-- loads the full, minified library into the global `gmp` variable -->
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm"></script>
<!-- or loads the non-minified library -->
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm/dist/index.umd.js"></script>
<!-- or loads the minified library without Float/MPFR functions -->
<script src="https://cdn.jsdelivr.net/npm/gmp-wasm/dist/mini.umd.min.js"></script>
gmp-wasm also provides a high-level wrapper over the GMP functions. There are three major components:
g.Integer()
- Wraps integers (MPZ)g.Rational()
- Wraps rational numbers (MPQ)g.Float()
- Wraps floating-point numbers (MPFR)const gmp = require('gmp-wasm');
gmp.init().then(({ calculate }) => {
// calculate() automatically deallocates all objects created within the callback function
const result = calculate((g) => {
const six = g.Float(1).add(5);
return g.Pi().div(six).sin(); // sin(Pi/6) = 0.5
});
console.log(result);
});
It is also possible to delay deallocation through the getContext()
API:
const gmp = require('gmp-wasm');
gmp.init().then(({ getContext }) => {
const ctx = getContext();
let x = ctx.Integer(1);
for (let i = 2; i < 16; i++) {
x = x.add(i);
}
console.log(x.toString());
setTimeout(() => ctx.destroy(), 50);
});
The precision and the rounding modes can be set by passing a parameter to the context or to the Float constructor.
const roundingMode = gmp.FloatRoundingMode.ROUND_TOWARD_NEG_INF;
const options = { precisionBits: 10, roundingMode };
const result = calculate(g => g.Float(1).div(3), options);
// or
const result2 = calculate(g => g.Float(1, options).div(3));
// or
const ctx = getContext(options);
const result3 = ctx.Float(1).div(3).toString();
High-level wrapper can be combined with low-level functions:
const sum = calculate((g) => {
const a = g.Float(1);
const b = g.Float(2);
const c = g.Float(0);
// c = a + b
binding.mpfr_add(c.mpfr_t, a.mpfr_t, b.mpfr_t, 0);
return c;
});
If you want more control and performance you can use the original GMP / MPFR functions even without high-level wrappers.
const gmp = require('gmp-wasm');
gmp.init().then(({ binding }) => {
// Create first number and initialize it to 30
const num1Ptr = binding.mpz_t();
binding.mpz_init_set_si(num1Ptr, 30);
// Create second number from string. The string needs to be copied into WASM memory
const num2Ptr = binding.mpz_t();
const strPtr = binding.malloc_cstr('40');
binding.mpz_init_set_str(num2Ptr, strPtr, 10);
// Calculate num1Ptr + num2Ptr, store the result in num1Ptr
binding.mpz_add(num1Ptr, num1Ptr, num2Ptr);
// Get result as integer
console.log(binding.mpz_get_si(num1Ptr));
// Deallocate memory
binding.free(strPtr);
binding.mpz_clears(num1Ptr, num2Ptr);
binding.mpz_t_frees(num1Ptr, num2Ptr);
});
Sometimes, it's easier and faster to deallocate everything by reinitializing the WASM bindings:
// Deallocate all memory objects created by gmp-wasm
await binding.reset();
In some cases, this library can provide better performance than the built-in BigInt type.
For example, calculating 8000 digits of Pi using the following formula provides better results:
PI = 3
+ 3 * (1/2) * (1/3) * (1/4)
+ 3 * ((1 * 3)/(2 * 4)) * (1/5) * (1 / (4^2))
+ 3 * ((1 * 3 * 5) / (2 * 4 * 6)) * (1/7) * (1 / (4^3))
+ ...
Test | Avg. time | Speedup |
---|---|---|
With JS built-in BigInt type | 130.20 ms | 1x |
gmp-wasm Integer() high-level wrapper | 87.90 ms | 1.48x |
Same as previous with delayed memory deallocation | 78.88 ms | 1.65x |
gmp-wasm MPZ low-level functions | 53.93 ms | 2.41x |
decimal.js 10.3.1 with integer division | 426.99 ms | 0.30x |
big-integer 1.6.51 | 129.98 ms | 1x |
---------------------------- | -------- | -------- |
gmp-wasm Float() high-level wrapper | 198.31 ms | 0.66x |
Same as previous with delayed memory deallocation | 191.94 ms | 0.68x |
gmp-wasm MPFR low-level functions | 135.49 ms | 0.96x |
decimal.js 10.3.1 with float division | 764.15 ms | 0.17x |
---------------------------- | -------- | -------- |
gmp-wasm Float(1).atan().mul(4) | 0.65 ms | 200.31x |
gmp-wasm Float('0.5').asin().mul(6) | 17.21 ms | 7.57x |
* These measurements were made with Node.js v16.13
on an Intel Kaby Lake desktop CPU. Source code is here.
FAQs
Arbitrary-precision Integer, Rational and Float types based on the GMP and MPFR libraries
The npm package gmp-wasm receives a total of 50 weekly downloads. As such, gmp-wasm popularity was classified as not popular.
We found that gmp-wasm demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.