@openclawcash/bigint-buffer 1.1.6-security.0 → 1.1.6-security.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.js +16 -30
- package/dist/node.js +16 -39
- package/package.json +9 -7
- package/.travis.yml +0 -51
- package/binding.gyp +0 -8
- package/karma.conf.js +0 -62
- package/rollup.config.js +0 -13
- package/src/bigint-buffer.c +0 -203
- package/src/index.bench.ts +0 -207
- package/src/index.spec.ts +0 -288
- package/src/index.ts +0 -86
- package/tsconfig.json +0 -19
package/dist/browser.js
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
let converter;
|
|
5
4
|
/**
|
|
6
5
|
* Convert a little-endian buffer into a BigInt.
|
|
7
6
|
* @param buf The little-endian buffer to convert
|
|
8
7
|
* @returns A BigInt with the little-endian representation of buf.
|
|
9
8
|
*/
|
|
10
9
|
function toBigIntLE(buf) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return BigInt(0);
|
|
17
|
-
}
|
|
18
|
-
return BigInt(`0x${hex}`);
|
|
10
|
+
const reversed = Buffer.from(buf);
|
|
11
|
+
reversed.reverse();
|
|
12
|
+
const hex = reversed.toString('hex');
|
|
13
|
+
if (hex.length === 0) {
|
|
14
|
+
return BigInt(0);
|
|
19
15
|
}
|
|
20
|
-
return
|
|
16
|
+
return BigInt(`0x${hex}`);
|
|
21
17
|
}
|
|
22
18
|
exports.toBigIntLE = toBigIntLE;
|
|
23
19
|
/**
|
|
@@ -26,14 +22,11 @@ exports.toBigIntLE = toBigIntLE;
|
|
|
26
22
|
* @returns A BigInt with the big-endian representation of buf.
|
|
27
23
|
*/
|
|
28
24
|
function toBigIntBE(buf) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return BigInt(0);
|
|
33
|
-
}
|
|
34
|
-
return BigInt(`0x${hex}`);
|
|
25
|
+
const hex = buf.toString('hex');
|
|
26
|
+
if (hex.length === 0) {
|
|
27
|
+
return BigInt(0);
|
|
35
28
|
}
|
|
36
|
-
return
|
|
29
|
+
return BigInt(`0x${hex}`);
|
|
37
30
|
}
|
|
38
31
|
exports.toBigIntBE = toBigIntBE;
|
|
39
32
|
/**
|
|
@@ -43,14 +36,10 @@ exports.toBigIntBE = toBigIntBE;
|
|
|
43
36
|
* @returns A little-endian buffer representation of num.
|
|
44
37
|
*/
|
|
45
38
|
function toBufferLE(num, width) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
return buffer;
|
|
51
|
-
}
|
|
52
|
-
// Allocation is done here, since it is slower using napi in C
|
|
53
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), false);
|
|
39
|
+
const hex = num.toString(16);
|
|
40
|
+
const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
41
|
+
buffer.reverse();
|
|
42
|
+
return buffer;
|
|
54
43
|
}
|
|
55
44
|
exports.toBufferLE = toBufferLE;
|
|
56
45
|
/**
|
|
@@ -60,10 +49,7 @@ exports.toBufferLE = toBufferLE;
|
|
|
60
49
|
* @returns A big-endian buffer representation of num.
|
|
61
50
|
*/
|
|
62
51
|
function toBufferBE(num, width) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
66
|
-
}
|
|
67
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), true);
|
|
52
|
+
const hex = num.toString(16);
|
|
53
|
+
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
68
54
|
}
|
|
69
55
|
exports.toBufferBE = toBufferBE;
|
package/dist/node.js
CHANGED
|
@@ -1,32 +1,19 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
let converter;
|
|
5
|
-
const nativeBindingsEnabled = process.env && process.env.BIGINT_BUFFER_NATIVE === '1';
|
|
6
|
-
if (nativeBindingsEnabled) {
|
|
7
|
-
try {
|
|
8
|
-
converter = require('bindings')('bigint_buffer');
|
|
9
|
-
}
|
|
10
|
-
catch (e) {
|
|
11
|
-
console.warn('bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)');
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
4
|
/**
|
|
15
5
|
* Convert a little-endian buffer into a BigInt.
|
|
16
6
|
* @param buf The little-endian buffer to convert
|
|
17
7
|
* @returns A BigInt with the little-endian representation of buf.
|
|
18
8
|
*/
|
|
19
9
|
function toBigIntLE(buf) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return BigInt(0);
|
|
26
|
-
}
|
|
27
|
-
return BigInt(`0x${hex}`);
|
|
10
|
+
const reversed = Buffer.from(buf);
|
|
11
|
+
reversed.reverse();
|
|
12
|
+
const hex = reversed.toString('hex');
|
|
13
|
+
if (hex.length === 0) {
|
|
14
|
+
return BigInt(0);
|
|
28
15
|
}
|
|
29
|
-
return
|
|
16
|
+
return BigInt(`0x${hex}`);
|
|
30
17
|
}
|
|
31
18
|
exports.toBigIntLE = toBigIntLE;
|
|
32
19
|
/**
|
|
@@ -35,14 +22,11 @@ exports.toBigIntLE = toBigIntLE;
|
|
|
35
22
|
* @returns A BigInt with the big-endian representation of buf.
|
|
36
23
|
*/
|
|
37
24
|
function toBigIntBE(buf) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return BigInt(0);
|
|
42
|
-
}
|
|
43
|
-
return BigInt(`0x${hex}`);
|
|
25
|
+
const hex = buf.toString('hex');
|
|
26
|
+
if (hex.length === 0) {
|
|
27
|
+
return BigInt(0);
|
|
44
28
|
}
|
|
45
|
-
return
|
|
29
|
+
return BigInt(`0x${hex}`);
|
|
46
30
|
}
|
|
47
31
|
exports.toBigIntBE = toBigIntBE;
|
|
48
32
|
/**
|
|
@@ -52,14 +36,10 @@ exports.toBigIntBE = toBigIntBE;
|
|
|
52
36
|
* @returns A little-endian buffer representation of num.
|
|
53
37
|
*/
|
|
54
38
|
function toBufferLE(num, width) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return buffer;
|
|
60
|
-
}
|
|
61
|
-
// Allocation is done here, since it is slower using napi in C
|
|
62
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), false);
|
|
39
|
+
const hex = num.toString(16);
|
|
40
|
+
const buffer = Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
41
|
+
buffer.reverse();
|
|
42
|
+
return buffer;
|
|
63
43
|
}
|
|
64
44
|
exports.toBufferLE = toBufferLE;
|
|
65
45
|
/**
|
|
@@ -69,10 +49,7 @@ exports.toBufferLE = toBufferLE;
|
|
|
69
49
|
* @returns A big-endian buffer representation of num.
|
|
70
50
|
*/
|
|
71
51
|
function toBufferBE(num, width) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
75
|
-
}
|
|
76
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), true);
|
|
52
|
+
const hex = num.toString(16);
|
|
53
|
+
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
77
54
|
}
|
|
78
55
|
exports.toBufferBE = toBufferBE;
|
package/package.json
CHANGED
|
@@ -1,25 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclawcash/bigint-buffer",
|
|
3
|
-
"version": "1.1.6-security.
|
|
4
|
-
"description": "bigint to buffer conversion
|
|
3
|
+
"version": "1.1.6-security.1",
|
|
4
|
+
"description": "bigint to buffer conversion (pure JS, native addon removed for security)",
|
|
5
5
|
"main": "dist/node.js",
|
|
6
6
|
"browser": {
|
|
7
7
|
"./dist/node.js": "./dist/browser.js"
|
|
8
8
|
},
|
|
9
9
|
"types": "dist/index.d.ts",
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/**",
|
|
12
|
+
"helper/**/*.d.ts",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
10
16
|
"scripts": {
|
|
11
17
|
"test": "npm run test:node && npm run test:browser",
|
|
12
18
|
"coverage": "istanbul cover ./test/index.js",
|
|
13
19
|
"coveralls": "npm run coverage && coveralls <coverage/lcov.info",
|
|
14
20
|
"lint": "gts check",
|
|
15
|
-
"install": "npm run rebuild || echo \"Couldn't build bindings. Non-native version used.\"",
|
|
16
21
|
"prepare": "npm run compile",
|
|
17
22
|
"prepublishOnly": "rm -rf build/Release; rm -f build/Makefile build/gyp-* build/*.mk build/*.Makefile *.tgz",
|
|
18
23
|
"test:browser": "cross-env NODE_OPTIONS=--openssl-legacy-provider karma start karma.conf.js",
|
|
19
24
|
"test:node": "mocha -r ts-node/register src/**/*.spec.ts --timeout 40000",
|
|
20
25
|
"benchmark": "node -r ts-node/register src/index.bench.ts",
|
|
21
26
|
"typedoc": "typedoc --out docs $(pwd)/src $(pwd)/helper --target es6 --mode file --tsconfig ./tsconfig.json --excludePrivate --excludeProtected --excludeNotExported --exclude '**/*+(spec|bench).ts'",
|
|
22
|
-
"rebuild": "node-gyp rebuild",
|
|
23
27
|
"check": "gts check",
|
|
24
28
|
"clean": "gts clean",
|
|
25
29
|
"compile": "mkdirp dist && tsc -p . && rollup -c > dist/node.js && cross-env BROWSER=true rollup -c > dist/browser.js && cpx \"build/src/*.d.ts\" dist",
|
|
@@ -41,9 +45,7 @@
|
|
|
41
45
|
"napi"
|
|
42
46
|
],
|
|
43
47
|
"license": "Apache-2.0",
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"bindings": "^1.3.0"
|
|
46
|
-
},
|
|
48
|
+
"dependencies": {},
|
|
47
49
|
"devDependencies": {
|
|
48
50
|
"@types/benchmark": "^1.0.31",
|
|
49
51
|
"@types/bn.js": "^4.11.2",
|
package/.travis.yml
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
language: node_js
|
|
2
|
-
node_js:
|
|
3
|
-
- node
|
|
4
|
-
- '10'
|
|
5
|
-
sudo : false
|
|
6
|
-
env:
|
|
7
|
-
global:
|
|
8
|
-
- DISPLAY=:99.0
|
|
9
|
-
- secure: SQDlqZZTkrbRW/wYLPgEwFQpkSrs65MiF0JgO+cwSCAG1m0c7EuBTzvttAXzKK+coZXjd2+QJcAOBi6YUP84OdSf31PojIy4/SLuZxuFQa0sGey+8oSDqgMntpSthO9nom0s6u2vB61IVfcRVIUNv5L3J5i5ZIGlKGgC2MIBzsnhx0L//eyh/bLszR27ajCT7RG+pnqpk010eaDtRabOJTtO0C2kbBQoW2SvJIisDsRj5zqVyl03pZJQQAJeseiNlLokucrgitDWENE+tEJ2w1x1yl+901tgU+BIi4iLQTezcSAxnF149U/Nof7LpCba+1Y+PPh1SRpO4100CT6O46qW0O1keVfTmZL/R3ghBM6H0AtV1s48k/XCpHV9CGwxjBHoCN1kKvSO9B1BJuAdlmgobOEdze+X81nilSBhBmYMI1XPLbXqTo2ImfaFeDzveuPJH6+HMCc+8sDlhgLcrOiteAsY8RsI0ngBkutsWWv7QcRq29e4VX2eBy0j1VJZNf0FPAcKpWF8eIaPw7Z0CuWMs2hM0v0ns58jDcOL+1k4kKyJ10OOmANqNX+NZYRJJ05dd/VMrlh37teARI64PFSG6eIoCniW0GtrUcpX4KhqpaRSUDpsKvncXNdNydumMyMQjeQqyHqahvIE2ONVXXELD2T/EV6TpazDR5KSSo0=
|
|
10
|
-
- secure: ZwKAlaNZ8liLknkAfFN+TztrILi8Q06AknHUj0Zd+9PjzD5n6tpzp5g1nE0MEvF9bqkGkwf6vwWJVKcSXWM9J4a2pfoLe9wsVcjq+AkmWnZG0zV26ie3UPoa8d/PezRtxz+4vErvQcOqnESVPJAqeWCt0fH1WvnEcjaY3BYyyDbWwAPamWr/v9c4ZLKxJqJmgtczMCrRahd6Dz+HGGJ9BehhOXtse+rT5qFI6w2SMXaisDzk2twMu0fK1I66G2IsesIKErPigCeEPahsP2yu831+S18YvxJtao7tXpluMBf+RNhD9eI1evUu6IxpF419ANDJ7BpJ8uGfRVzIz9kQIAmcy/1s7g3otT633XngUfNYDisUeLJ39plclOHw+sVeLL49Xa9k+/U0CzlOThNlCj0hY2uJW3Ot9NjvKDjdR/UkgEBCl6nIDAnRQk9xSJ4ws1f9Yp5CgEXcXvu7077i6O8vG7+k08qHDSkxEEwQjB2PwjhcPfg9ieAwafblM3szYwzblL4UpROp/L/XmmzjR/cOVrS93RIpeLqDr2CCMKGd0GoOFtDse7u43SJMIAZ+O5DNtNpqIQ22V13p4P3L2C1RV3cjE55luEYVR1JZ7AzaxD+hZu2zcU2301MuSgFLTKMEu43HV1tPJ6QtCcSf+kH/LK/TPfTLveW23xkkZM0=
|
|
11
|
-
matrix:
|
|
12
|
-
- TEST_SUITE=test:node
|
|
13
|
-
addons:
|
|
14
|
-
chrome: stable
|
|
15
|
-
services:
|
|
16
|
-
- xvfb
|
|
17
|
-
cache:
|
|
18
|
-
directories:
|
|
19
|
-
- $HOME/.npm
|
|
20
|
-
matrix:
|
|
21
|
-
fast_finish: true
|
|
22
|
-
include:
|
|
23
|
-
- os: linux
|
|
24
|
-
node_js: '10'
|
|
25
|
-
env: TEST_SUITE=test:browser
|
|
26
|
-
- os: windows
|
|
27
|
-
node_js: '10'
|
|
28
|
-
env: TEST_SUITE=test:node
|
|
29
|
-
script: npm run $TEST_SUITE
|
|
30
|
-
before_deploy:
|
|
31
|
-
- npm pack
|
|
32
|
-
deploy:
|
|
33
|
-
- provider: releases
|
|
34
|
-
api_key: "$GITHUB_TOKEN"
|
|
35
|
-
file_glob: true
|
|
36
|
-
file: bigint-buffer-*.tgz
|
|
37
|
-
skip_cleanup: true
|
|
38
|
-
on:
|
|
39
|
-
branch: master
|
|
40
|
-
node: '10'
|
|
41
|
-
condition: "$TEST_SUITE = test:node"
|
|
42
|
-
tags: true
|
|
43
|
-
- provider: npm
|
|
44
|
-
api_key: "$NPM_TOKEN"
|
|
45
|
-
skip_cleanup: true
|
|
46
|
-
email: mwei@cs.ucsd.edu
|
|
47
|
-
on:
|
|
48
|
-
branch: master
|
|
49
|
-
node: '10'
|
|
50
|
-
condition: "$TEST_SUITE = test:node"
|
|
51
|
-
tags: true
|
package/binding.gyp
DELETED
package/karma.conf.js
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
const webpack = require('webpack')
|
|
2
|
-
module.exports = function (config) {
|
|
3
|
-
const configuration = {
|
|
4
|
-
browserNoActivityTimeout: 120000,
|
|
5
|
-
frameworks: ['mocha'],
|
|
6
|
-
files: [
|
|
7
|
-
'./build/src/*.spec.js'
|
|
8
|
-
],
|
|
9
|
-
preprocessors: {
|
|
10
|
-
'./build/src//*.spec.js': ['webpack', 'env']
|
|
11
|
-
},
|
|
12
|
-
webpack : {
|
|
13
|
-
mode: "production",
|
|
14
|
-
devtool: 'inline-source-map',
|
|
15
|
-
module: {
|
|
16
|
-
// Suppress warning from mocha: "Critical dependency: the request of a dependency is an expression"
|
|
17
|
-
// @see https://webpack.js.org/configuration/module/#module-contexts
|
|
18
|
-
exprContextCritical: false
|
|
19
|
-
},
|
|
20
|
-
// Suppress fatal error: Cannot resolve module 'fs'
|
|
21
|
-
// @relative https://github.com/pugjs/pug-loader/issues/8
|
|
22
|
-
// @see https://github.com/webpack/docs/wiki/Configuration#node
|
|
23
|
-
node: {
|
|
24
|
-
fs: 'empty',
|
|
25
|
-
bindings: 'empty'
|
|
26
|
-
},
|
|
27
|
-
resolve: {
|
|
28
|
-
extensions: ['.ts', '.js', '.json']
|
|
29
|
-
}, plugins: [ new webpack.NormalModuleReplacementPlugin(
|
|
30
|
-
/\.\/index/,
|
|
31
|
-
'./build/src/bromwser.js'
|
|
32
|
-
),
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
singleRun: true,
|
|
36
|
-
reporters: ['mocha'],
|
|
37
|
-
plugins: [
|
|
38
|
-
'karma-chrome-launcher',
|
|
39
|
-
'karma-env-preprocessor',
|
|
40
|
-
'karma-webpack',
|
|
41
|
-
'karma-mocha',
|
|
42
|
-
'karma-mocha-reporter'
|
|
43
|
-
],
|
|
44
|
-
mime: {
|
|
45
|
-
'text/x-typescript': ['ts','tsx']
|
|
46
|
-
},
|
|
47
|
-
browsers: ['Chrome'],
|
|
48
|
-
customLaunchers: {
|
|
49
|
-
Chrome_travis_ci: {
|
|
50
|
-
base: 'Chrome',
|
|
51
|
-
flags: ['--no-sandbox']
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
if(process.env.TRAVIS) {
|
|
57
|
-
configuration.browsers = ['Chrome_travis_ci'];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
config.set(configuration);
|
|
61
|
-
}
|
|
62
|
-
|
package/rollup.config.js
DELETED
package/src/bigint-buffer.c
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
#define NAPI_EXPERIMENTAL
|
|
3
|
-
#include <node_api.h>
|
|
4
|
-
#include <stdio.h>
|
|
5
|
-
#include <stdlib.h>
|
|
6
|
-
#include <string.h>
|
|
7
|
-
#include <assert.h>
|
|
8
|
-
#include <limits.h>
|
|
9
|
-
|
|
10
|
-
#define BIT_MASK(n) (~( ((~0ull) << ((n)-1)) << 1 ))
|
|
11
|
-
|
|
12
|
-
// The maximum size we'll store on the stack. If we need a larger temporary
|
|
13
|
-
// buffer malloc will be called.
|
|
14
|
-
#define BUFFER_STACK_SIZE 32
|
|
15
|
-
|
|
16
|
-
#if defined(_WIN16) || defined(_WIN32) || defined(_WIN64)
|
|
17
|
-
#define bswap64(x) _byteswap_uint64(x)
|
|
18
|
-
#else
|
|
19
|
-
#define bswap64(x) __builtin_bswap64(x)
|
|
20
|
-
#endif
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Converts a Buffer to bigint.
|
|
24
|
-
* node param 0: buffer
|
|
25
|
-
* node param 1: big_endian (optional boolean)
|
|
26
|
-
*
|
|
27
|
-
* returns bigint
|
|
28
|
-
*/
|
|
29
|
-
napi_value toBigInt (napi_env env, napi_callback_info info) {
|
|
30
|
-
napi_value argv[2];
|
|
31
|
-
napi_status status;
|
|
32
|
-
size_t argc = 2;
|
|
33
|
-
|
|
34
|
-
status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
35
|
-
assert(status == napi_ok);
|
|
36
|
-
|
|
37
|
-
if (argc < 1) {
|
|
38
|
-
napi_throw_error(env, "EINVAL", "Too few arguments");
|
|
39
|
-
return NULL;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
bool big_endian;
|
|
43
|
-
status = napi_get_value_bool(env, argv[1], &big_endian);
|
|
44
|
-
if (status == napi_boolean_expected) { big_endian = false; }
|
|
45
|
-
|
|
46
|
-
uint8_t* buffer;
|
|
47
|
-
size_t len;
|
|
48
|
-
status = napi_get_buffer_info(env, argv[0], (void**) &buffer, &len);
|
|
49
|
-
assert(status == napi_ok);
|
|
50
|
-
|
|
51
|
-
// If len is not divisible by 8 bytes, we'll need to copy
|
|
52
|
-
bool not_64_aligned = (len & 7) != 0;
|
|
53
|
-
size_t overflow_len = not_64_aligned ? 8 - (len & 0x7) : 0;
|
|
54
|
-
// Buffer is managed by VM, so copy it out (TODO: perhaps we can increase refcount?)
|
|
55
|
-
size_t aligned_len = len + overflow_len;
|
|
56
|
-
size_t len_in_words = not_64_aligned ? (len >> 3) + 1 : (len >> 3);
|
|
57
|
-
bool fits_in_stack = aligned_len <= BUFFER_STACK_SIZE;
|
|
58
|
-
|
|
59
|
-
uint8_t copy[BUFFER_STACK_SIZE];
|
|
60
|
-
uint8_t* bufTemp = fits_in_stack ? copy : malloc(aligned_len);
|
|
61
|
-
if (overflow_len > 0) {
|
|
62
|
-
memset(bufTemp + len, 0, overflow_len);
|
|
63
|
-
}
|
|
64
|
-
memcpy(bufTemp, buffer, len);
|
|
65
|
-
uint64_t* as_64_aligned = (uint64_t*) bufTemp;
|
|
66
|
-
size_t overflow_in_bits = overflow_len << 3; // == overflow_len * 8
|
|
67
|
-
|
|
68
|
-
napi_value out;
|
|
69
|
-
// swap
|
|
70
|
-
if (big_endian) {
|
|
71
|
-
if (len_in_words == 1) {
|
|
72
|
-
as_64_aligned[0] = not_64_aligned ? bswap64(as_64_aligned[0]) >> overflow_in_bits : bswap64(as_64_aligned[0]);
|
|
73
|
-
} else {
|
|
74
|
-
uint64_t temp;
|
|
75
|
-
size_t last_word = len_in_words - 1;
|
|
76
|
-
size_t end_ptr = last_word;
|
|
77
|
-
int32_t offset;
|
|
78
|
-
for (offset = 0; offset < (int32_t)(len_in_words / 2); offset++) {
|
|
79
|
-
temp = as_64_aligned[offset];
|
|
80
|
-
as_64_aligned[offset] = as_64_aligned[end_ptr];
|
|
81
|
-
as_64_aligned[end_ptr] = temp;
|
|
82
|
-
end_ptr--;
|
|
83
|
-
}
|
|
84
|
-
uint64_t prev_overflow = 0;
|
|
85
|
-
for (offset = last_word; offset >= 0; offset--) {
|
|
86
|
-
uint64_t as_little_endian = bswap64(as_64_aligned[offset]);
|
|
87
|
-
uint64_t overflow = as_little_endian & BIT_MASK(overflow_in_bits);
|
|
88
|
-
as_64_aligned[offset] = not_64_aligned ? (as_little_endian >> overflow_in_bits) | prev_overflow : as_little_endian;
|
|
89
|
-
prev_overflow = overflow << (64 - overflow_in_bits);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
status = napi_create_bigint_words(env, 0, len_in_words, as_64_aligned , &out);
|
|
95
|
-
assert(status == napi_ok);
|
|
96
|
-
|
|
97
|
-
if (!fits_in_stack) {
|
|
98
|
-
free(bufTemp);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return out;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Converts a BigInt to a Buffer
|
|
106
|
-
* node param 0: BigInt
|
|
107
|
-
* node param 1: buffer
|
|
108
|
-
* node param 2: big_endian (optional boolean)
|
|
109
|
-
*
|
|
110
|
-
* returns bigint
|
|
111
|
-
*/
|
|
112
|
-
napi_value fromBigInt (napi_env env, napi_callback_info info) {
|
|
113
|
-
napi_value argv[3];
|
|
114
|
-
napi_status status;
|
|
115
|
-
size_t argc = 3;
|
|
116
|
-
|
|
117
|
-
status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
|
|
118
|
-
assert(status == napi_ok);
|
|
119
|
-
|
|
120
|
-
if (argc < 1) {
|
|
121
|
-
napi_throw_error(env, "EINVAL", "Too few arguments");
|
|
122
|
-
return NULL;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
size_t byte_width;
|
|
126
|
-
bool big_endian;
|
|
127
|
-
status = napi_get_value_bool(env, argv[2], &big_endian);
|
|
128
|
-
if (status == napi_boolean_expected) { big_endian = false; }
|
|
129
|
-
|
|
130
|
-
size_t word_count;
|
|
131
|
-
status = napi_get_value_bigint_words(env, argv[0], NULL, &word_count, NULL);
|
|
132
|
-
assert(status == napi_ok);
|
|
133
|
-
|
|
134
|
-
uint8_t* raw_buffer;
|
|
135
|
-
status = napi_get_buffer_info(env, argv[1], (void**) &raw_buffer, &byte_width);
|
|
136
|
-
assert(status == napi_ok);
|
|
137
|
-
|
|
138
|
-
if (word_count == 0) {
|
|
139
|
-
memset(raw_buffer, 0, byte_width);
|
|
140
|
-
return argv[1];
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
int sign_bit = 0;
|
|
144
|
-
|
|
145
|
-
bool not_64_aligned = (byte_width & 7) != 0;
|
|
146
|
-
size_t overflow_len = not_64_aligned ? 8 - (byte_width & 0x7) : 0;
|
|
147
|
-
size_t word_width = (byte_width >> 3) + (not_64_aligned ? 1 : 0);
|
|
148
|
-
size_t original_word_width = word_width;
|
|
149
|
-
if (word_count > word_width) {
|
|
150
|
-
word_count = word_width;
|
|
151
|
-
}
|
|
152
|
-
size_t word_width_bytes = (word_count << 3);
|
|
153
|
-
bool fits_in_stack = word_width_bytes <= BUFFER_STACK_SIZE;
|
|
154
|
-
|
|
155
|
-
uint64_t* conv_buffer = (uint64_t*) raw_buffer;
|
|
156
|
-
uint64_t stack_buffer[BUFFER_STACK_SIZE];
|
|
157
|
-
if (not_64_aligned) {
|
|
158
|
-
conv_buffer = fits_in_stack ? stack_buffer : malloc(byte_width + overflow_len);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
memset(conv_buffer, 0, byte_width + overflow_len);
|
|
162
|
-
status = napi_get_value_bigint_words(env, argv[0], &sign_bit, &word_count, conv_buffer);
|
|
163
|
-
assert(status == napi_ok);
|
|
164
|
-
|
|
165
|
-
if (big_endian) {
|
|
166
|
-
uint64_t temp;
|
|
167
|
-
size_t conv_words = original_word_width;
|
|
168
|
-
size_t last_word = conv_words - 1;
|
|
169
|
-
size_t end_ptr = last_word;
|
|
170
|
-
int32_t offset;
|
|
171
|
-
for (offset = 0; offset < (int32_t)(conv_words / 2); offset++) {
|
|
172
|
-
temp = bswap64(conv_buffer[offset]);
|
|
173
|
-
conv_buffer[offset] = bswap64(conv_buffer[end_ptr]);
|
|
174
|
-
conv_buffer[end_ptr] = temp;
|
|
175
|
-
end_ptr--;
|
|
176
|
-
}
|
|
177
|
-
if (conv_words & 1) {
|
|
178
|
-
conv_buffer[conv_words / 2] = bswap64(conv_buffer[conv_words / 2]);;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
if (not_64_aligned) {
|
|
182
|
-
memcpy(raw_buffer, big_endian ? (uint64_t*)(((uint8_t*)conv_buffer) + (8-(byte_width & 7))) : conv_buffer, byte_width);
|
|
183
|
-
if (!fits_in_stack) {
|
|
184
|
-
free(conv_buffer);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return argv[1];
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
napi_value init_all (napi_env env, napi_value exports) {
|
|
191
|
-
napi_value bigint_fn;
|
|
192
|
-
napi_value frombigint_fn;
|
|
193
|
-
|
|
194
|
-
napi_create_function(env, NULL, 0, toBigInt, NULL, &bigint_fn);
|
|
195
|
-
napi_create_function(env, NULL, 0, fromBigInt, NULL, &frombigint_fn);
|
|
196
|
-
|
|
197
|
-
napi_set_named_property(env, exports, "toBigInt", bigint_fn);
|
|
198
|
-
napi_set_named_property(env, exports, "fromBigInt", frombigint_fn);
|
|
199
|
-
|
|
200
|
-
return exports;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
NAPI_MODULE(NODE_GYP_MODULE_NAME, init_all);
|
package/src/index.bench.ts
DELETED
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import * as benchmark from 'benchmark';
|
|
3
|
-
|
|
4
|
-
import {toBigIntBE, toBigIntLE, toBufferBE, toBufferLE} from './index';
|
|
5
|
-
|
|
6
|
-
const BN = require('bn.js');
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// This file contains the benchmark test suite. It includes the benchmark and
|
|
10
|
-
// some lightweight boilerplate code for running benchmark.js. To
|
|
11
|
-
// run the benchmarks, execute `npm run benchmark` from the package directory.
|
|
12
|
-
const suite = new benchmark.Suite();
|
|
13
|
-
|
|
14
|
-
interface BenchmarkRun {
|
|
15
|
-
name: string;
|
|
16
|
-
hz: number;
|
|
17
|
-
stats: benchmark.Stats;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// Tests the performance of a no-op.
|
|
21
|
-
suite.add('no-op', () => {});
|
|
22
|
-
|
|
23
|
-
// Test small strings (unaligned)
|
|
24
|
-
const smallHex = 'deadbeef';
|
|
25
|
-
const smallString = `0x${smallHex}`;
|
|
26
|
-
const smallBuf: Buffer = Buffer.from(smallHex, 'hex');
|
|
27
|
-
suite.add('bigint from hex string (small)', () => {
|
|
28
|
-
return BigInt(smallString);
|
|
29
|
-
});
|
|
30
|
-
suite.add('bigint from hex string from buffer (small)', () => {
|
|
31
|
-
return BigInt(`0x${smallBuf.toString('hex')}`);
|
|
32
|
-
});
|
|
33
|
-
suite.add('BN from hex string from buffer (small)', () => {
|
|
34
|
-
return new BN(smallBuf.toString('hex'), 16);
|
|
35
|
-
});
|
|
36
|
-
suite.add('LE bigint-buffer ToBigInt (small)', () => {
|
|
37
|
-
return toBigIntLE(smallBuf);
|
|
38
|
-
});
|
|
39
|
-
suite.add('BE bigint-buffer ToBigInt (small)', () => {
|
|
40
|
-
return toBigIntBE(smallBuf);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// Test mid strings (aligned)
|
|
44
|
-
const midHex = 'badc0ffee0ddf00d';
|
|
45
|
-
const midString = `0x${midHex}`;
|
|
46
|
-
const midBuf: Buffer = Buffer.from(midHex, 'hex');
|
|
47
|
-
suite.add('bigint from hex string (mid, aligned)', () => {
|
|
48
|
-
return BigInt(midString);
|
|
49
|
-
});
|
|
50
|
-
suite.add('bigint from hex string from buffer (mid, aligned)', () => {
|
|
51
|
-
return BigInt(`0x${midBuf.toString('hex')}`);
|
|
52
|
-
});
|
|
53
|
-
suite.add('BN from hex string from buffer (mid, aligned)', () => {
|
|
54
|
-
return new BN(midBuf.toString('hex'), 16);
|
|
55
|
-
});
|
|
56
|
-
suite.add('LE bigint-buffer ToBigInt (mid, aligned)', () => {
|
|
57
|
-
return toBigIntLE(midBuf);
|
|
58
|
-
});
|
|
59
|
-
suite.add('BE bigint-buffer ToBigInt (mid, aligned)', () => {
|
|
60
|
-
return toBigIntBE(midBuf);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// Test huge strings
|
|
64
|
-
const hugeHex =
|
|
65
|
-
'badc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00d';
|
|
66
|
-
const hugeString = `0x${hugeHex}`;
|
|
67
|
-
const hugeBuf: Buffer = Buffer.from(hugeHex, 'hex');
|
|
68
|
-
suite.add('bigint from hex string (huge)', () => {
|
|
69
|
-
return BigInt(hugeString);
|
|
70
|
-
});
|
|
71
|
-
suite.add('bigint from hex string from buffer (huge)', () => {
|
|
72
|
-
return BigInt(`0x${hugeBuf.toString('hex')}`);
|
|
73
|
-
});
|
|
74
|
-
suite.add('BN from hex string from buffer (huge)', () => {
|
|
75
|
-
return new BN(hugeBuf.toString('hex'), 16);
|
|
76
|
-
});
|
|
77
|
-
suite.add('LE bigint-buffer ToBigInt (huge)', () => {
|
|
78
|
-
return toBigIntLE(hugeBuf);
|
|
79
|
-
});
|
|
80
|
-
suite.add('BE bigint-buffer ToBigInt (huge)', () => {
|
|
81
|
-
return toBigIntBE(hugeBuf);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
const bigIntToBufferWithStringBE = (int: bigint, width: number): Buffer => {
|
|
85
|
-
const hex = int.toString(16);
|
|
86
|
-
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const bigIntToBufferWithStringLE = (int: bigint, width: number): Buffer => {
|
|
90
|
-
const hex = int.toString(16);
|
|
91
|
-
const buffer =
|
|
92
|
-
Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
93
|
-
buffer.reverse();
|
|
94
|
-
return buffer;
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
// Test small toBuffer
|
|
98
|
-
const smallValue = 12345678n;
|
|
99
|
-
suite.add('LE bigint to hex string to buffer (small)', () => {
|
|
100
|
-
return bigIntToBufferWithStringLE(smallValue, 8);
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
suite.add('BE bigint to hex string to buffer (small)', () => {
|
|
104
|
-
return bigIntToBufferWithStringBE(smallValue, 8);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
const bnSmallValue = new BN('12345678', 10);
|
|
108
|
-
suite.add('BN to buffer (small)', () => {
|
|
109
|
-
return bnSmallValue.toBuffer(8);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
suite.add('LE bigint-buffer to buffer (small)', () => {
|
|
113
|
-
return toBufferLE(smallValue, 8);
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
suite.add('BE bigint-buffer to buffer (small)', () => {
|
|
117
|
-
return toBufferBE(smallValue, 8);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// Test large toBuffer
|
|
122
|
-
const largeValue =
|
|
123
|
-
0xbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dn;
|
|
124
|
-
suite.add('LE bigint to hex string to buffer (large)', () => {
|
|
125
|
-
return bigIntToBufferWithStringLE(largeValue, 24);
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
suite.add('BE bigint to hex string to buffer (large)', () => {
|
|
129
|
-
return bigIntToBufferWithStringBE(largeValue, 24);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const bnLargeValue = new BN(
|
|
133
|
-
'badc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00dbadc0ffee0ddf00d',
|
|
134
|
-
16);
|
|
135
|
-
suite.add('BN to buffer (large)', () => {
|
|
136
|
-
return bnLargeValue.toBuffer(24);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
suite.add('LE bigint-buffer to buffer (large)', () => {
|
|
140
|
-
return toBufferLE(largeValue, 24);
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
suite.add('BE bigint-buffer to buffer (large)', () => {
|
|
144
|
-
return toBufferBE(largeValue, 24);
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
suite.add('LE bigint to hex string to buffer (large)', () => {
|
|
148
|
-
return bigIntToBufferWithStringLE(largeValue, 8);
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
suite.add('BE bigint to hex string to buffer (large)', () => {
|
|
152
|
-
return bigIntToBufferWithStringBE(largeValue, 8);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
suite.add('LE bigint-buffer to buffer (large, truncated)', () => {
|
|
156
|
-
return toBufferLE(largeValue, 8);
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
suite.add('BE bigint-buffer to buffer (large, truncated)', () => {
|
|
160
|
-
return toBufferBE(largeValue, 8);
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const b1 = Buffer.from('0123456789ABCDEF0123456789ABCDEF', 'hex');
|
|
164
|
-
const b2 = Buffer.from('0123456789ABCDEF0123456789ABCDEF', 'hex');
|
|
165
|
-
const bn1 = new BN('0123456789ABCDEF0123456789ABCDEF', 'hex');
|
|
166
|
-
const bn2 = new BN('0123456789ABCDEF0123456789ABCDEF', 'hex');
|
|
167
|
-
const n1 = 0x0123456789ABCDEF0123456789ABCDEFn;
|
|
168
|
-
const n2 = 0x0123456789ABCDEF0123456789ABCDEFn;
|
|
169
|
-
suite.add('Buffer equality comparison', () => {
|
|
170
|
-
return b1.compare(b2) === 0;
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
suite.add('BN equality comparison', () => {
|
|
174
|
-
return bn1.eq(bn2);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
suite.add('bigint equality comparison', () => {
|
|
178
|
-
return n1 === n2;
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
suite.add('BN multiply', () => {
|
|
182
|
-
return bn1.mul(bn2);
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
suite.add('bigint multiply', () => {
|
|
186
|
-
return n1 * n2;
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
//#endregion
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
// Reporter for each benchmark
|
|
193
|
-
suite.on('cycle', (event: benchmark.Event) => {
|
|
194
|
-
const benchmarkRun: BenchmarkRun = event.target as BenchmarkRun;
|
|
195
|
-
const stats = benchmarkRun.stats as benchmark.Stats;
|
|
196
|
-
const meanInNanos = (stats.mean * 1000000000).toFixed(2);
|
|
197
|
-
const stdDevInNanos = (stats.deviation * 1000000000).toFixed(3);
|
|
198
|
-
const runs = stats.sample.length;
|
|
199
|
-
const ops = benchmarkRun.hz.toFixed(benchmarkRun.hz < 100 ? 2 : 0);
|
|
200
|
-
const err = stats.rme.toFixed(2);
|
|
201
|
-
|
|
202
|
-
console.log(`${benchmarkRun.name}: ${ops}±${err}% ops/s ${meanInNanos}±${
|
|
203
|
-
stdDevInNanos} ns/op (${runs} run${runs === 0 ? '' : 's'})`);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
// Runs the test suite
|
|
207
|
-
suite.run();
|
package/src/index.spec.ts
DELETED
|
@@ -1,288 +0,0 @@
|
|
|
1
|
-
import 'mocha';
|
|
2
|
-
declare var process: {browser: boolean;};
|
|
3
|
-
|
|
4
|
-
import * as chai from 'chai';
|
|
5
|
-
import * as path from 'path';
|
|
6
|
-
|
|
7
|
-
const lib = process.browser ? require('../../dist/browser') :
|
|
8
|
-
require(path.join(__dirname, '../dist/node'));
|
|
9
|
-
const toBigIntBE = lib.toBigIntBE;
|
|
10
|
-
const toBigIntLE = lib.toBigIntLE;
|
|
11
|
-
const toBufferBE = lib.toBufferBE;
|
|
12
|
-
const toBufferLE = lib.toBufferLE;
|
|
13
|
-
|
|
14
|
-
// Needed for should.not.be.undefined.
|
|
15
|
-
/* tslint:disable:no-unused-expression */
|
|
16
|
-
|
|
17
|
-
chai.should();
|
|
18
|
-
const should = chai.should();
|
|
19
|
-
|
|
20
|
-
const assertEquals = (n0: BigInt, n1: BigInt) => {
|
|
21
|
-
n0.toString(16).should.equal(n1.toString(16));
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
describe('Try buffer conversion (little endian)', () => {
|
|
25
|
-
it('0 should equal 0n', () => {
|
|
26
|
-
assertEquals(toBigIntLE(Buffer.from([0])), BigInt('0'));
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
it('1 should equal 1n', async () => {
|
|
30
|
-
assertEquals(toBigIntLE(Buffer.from([1])), BigInt('1'));
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it('0xdead should equal 0xdeadn', async () => {
|
|
34
|
-
assertEquals(toBigIntLE(Buffer.from([0xad, 0xde])), BigInt(`0xdead`));
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it('0xdeadbeef should equal 0xdeadbeefn', async () => {
|
|
38
|
-
assertEquals(
|
|
39
|
-
toBigIntLE(Buffer.from([0xef, 0xbe, 0xad, 0xde])),
|
|
40
|
-
BigInt(`0xdeadbeef`));
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it('0xbadc0ffee0 should equal 0xbadc0ffee0n', async () => {
|
|
44
|
-
assertEquals(
|
|
45
|
-
toBigIntLE(Buffer.from([0xe0, 0xfe, 0x0f, 0xdc, 0xba])),
|
|
46
|
-
BigInt(`0xbadc0ffee0`));
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it('0xbadc0ffee0dd should equal 0xbadc0ffee0ddn', async () => {
|
|
50
|
-
assertEquals(
|
|
51
|
-
toBigIntLE(Buffer.from([0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba])),
|
|
52
|
-
BigInt(`0xbadc0ffee0dd`));
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('0xbadc0ffee0ddf0 should equal 0xbadc0ffee0ddf0n', async () => {
|
|
56
|
-
assertEquals(
|
|
57
|
-
toBigIntLE(Buffer.from([0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba])),
|
|
58
|
-
BigInt(`0xbadc0ffee0ddf0`));
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('0xbadc0ffee0ddf00d should equal 0xbadc0ffee0ddf00dn', async () => {
|
|
62
|
-
assertEquals(
|
|
63
|
-
toBigIntLE(
|
|
64
|
-
Buffer.from([0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba])),
|
|
65
|
-
BigInt(`0xbadc0ffee0ddf00d`));
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('0xbadc0ffee0ddf00ddeadbeef should equal 0xbadc0ffee0ddf00ddeadbeefn',
|
|
69
|
-
async () => {
|
|
70
|
-
assertEquals(
|
|
71
|
-
toBigIntLE(Buffer.from([
|
|
72
|
-
0xef, 0xbe, 0xad, 0xde, 0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc,
|
|
73
|
-
0xba
|
|
74
|
-
])),
|
|
75
|
-
BigInt(`0xbadc0ffee0ddf00ddeadbeef`));
|
|
76
|
-
});
|
|
77
|
-
it('0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef should equal 0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefn',
|
|
78
|
-
async () => {
|
|
79
|
-
assertEquals(
|
|
80
|
-
toBigIntLE(Buffer.from([
|
|
81
|
-
0xef, 0xbe, 0xad, 0xde, 0x0d, 0xf0, 0xdd, 0xe0,
|
|
82
|
-
0xfe, 0x0f, 0xdc, 0xba, 0xef, 0xbe, 0xad, 0xde,
|
|
83
|
-
0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba
|
|
84
|
-
])),
|
|
85
|
-
BigInt(`0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef`));
|
|
86
|
-
});
|
|
87
|
-
it('0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefbeef should equal 0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefbeefn',
|
|
88
|
-
async () => {
|
|
89
|
-
assertEquals(
|
|
90
|
-
toBigIntLE(Buffer.from([
|
|
91
|
-
0xef, 0xbe, 0xef, 0xbe, 0xad, 0xde, 0x0d, 0xf0, 0xdd,
|
|
92
|
-
0xe0, 0xfe, 0x0f, 0xdc, 0xba, 0xef, 0xbe, 0xad, 0xde,
|
|
93
|
-
0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba
|
|
94
|
-
])),
|
|
95
|
-
BigInt(`0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefbeef`));
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
describe('Try buffer conversion (big endian)', () => {
|
|
100
|
-
it('0 should equal 0n', () => {
|
|
101
|
-
assertEquals(toBigIntBE(Buffer.from([0])), BigInt(`0`));
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('1 should equal 1n', async () => {
|
|
105
|
-
assertEquals(toBigIntBE(Buffer.from([1])), BigInt(`1`));
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('0xdead should equal 0xdeadn', async () => {
|
|
109
|
-
assertEquals(toBigIntBE(Buffer.from([0xde, 0xad])), BigInt(`0xdead`));
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
it('0xdeadbeef should equal 0xdeadbeefn', async () => {
|
|
113
|
-
assertEquals(
|
|
114
|
-
toBigIntBE(Buffer.from([0xde, 0xad, 0xbe, 0xef])),
|
|
115
|
-
BigInt(`0xdeadbeef`));
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('0xbadc0ffee0 should equal 0xbadc0ffee0n', async () => {
|
|
119
|
-
assertEquals(
|
|
120
|
-
toBigIntBE(Buffer.from([0xba, 0xdc, 0x0f, 0xfe, 0xe0])),
|
|
121
|
-
BigInt(`0xbadc0ffee0`));
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it('0xbadc0ffee0dd should equal 0xbadc0ffee0ddn', async () => {
|
|
125
|
-
assertEquals(
|
|
126
|
-
toBigIntBE(Buffer.from([0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd])),
|
|
127
|
-
BigInt(`0xbadc0ffee0dd`));
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('0xbadc0ffee0ddf0 should equal 0xbadc0ffee0ddf0n', async () => {
|
|
131
|
-
assertEquals(
|
|
132
|
-
toBigIntBE(Buffer.from([0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0])),
|
|
133
|
-
BigInt(`0xbadc0ffee0ddf0`));
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('0xbadc0ffee0ddf00d should equal 0xbadc0ffee0ddf00dn', async () => {
|
|
137
|
-
assertEquals(
|
|
138
|
-
toBigIntBE(
|
|
139
|
-
Buffer.from([0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0, 0x0d])),
|
|
140
|
-
BigInt(`0xbadc0ffee0ddf00d`));
|
|
141
|
-
});
|
|
142
|
-
|
|
143
|
-
it('0xbadc0ffee0ddf00ddeadbeef should equal 0xbadc0ffee0ddf00ddeadbeefn',
|
|
144
|
-
async () => {
|
|
145
|
-
assertEquals(
|
|
146
|
-
toBigIntBE(Buffer.from([
|
|
147
|
-
0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0, 0x0d, 0xde, 0xad, 0xbe,
|
|
148
|
-
0xef
|
|
149
|
-
])),
|
|
150
|
-
BigInt(`0xbadc0ffee0ddf00ddeadbeef`));
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
it('long value should equal long val', async () => {
|
|
154
|
-
assertEquals(
|
|
155
|
-
toBigIntBE(Buffer.from(
|
|
156
|
-
'badc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef',
|
|
157
|
-
'hex')),
|
|
158
|
-
BigInt(
|
|
159
|
-
`0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef`));
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('other long value should equal long val', async () => {
|
|
163
|
-
assertEquals(
|
|
164
|
-
toBigIntBE(Buffer.from(
|
|
165
|
-
'd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544',
|
|
166
|
-
'hex')),
|
|
167
|
-
BigInt(
|
|
168
|
-
`0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544`));
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
describe('Try bigint conversion (little endian)', () => {
|
|
173
|
-
it('0 should equal 0n', () => {
|
|
174
|
-
toBufferLE(BigInt(`0`), 8).should.deep.equal(Buffer.from([
|
|
175
|
-
0, 0, 0, 0, 0, 0, 0, 0
|
|
176
|
-
]));
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
it('1 should equal 1n', async () => {
|
|
180
|
-
toBufferLE(BigInt(`1`), 8).should.deep.equal(Buffer.from([
|
|
181
|
-
1, 0, 0, 0, 0, 0, 0, 0
|
|
182
|
-
]));
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
it('1 should equal 1n (32 byte)', async () => {
|
|
187
|
-
toBufferLE(BigInt(`1`), 32)
|
|
188
|
-
.should.deep.equal(Buffer.from(
|
|
189
|
-
'0100000000000000000000000000000000000000000000000000000000000000',
|
|
190
|
-
'hex'));
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('0xdead should equal 0xdeadn (6 byte)', async () => {
|
|
194
|
-
toBufferLE(BigInt(`0xdead`), 6).should.deep.equal(Buffer.from([
|
|
195
|
-
0xad, 0xde, 0, 0, 0, 0
|
|
196
|
-
]));
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
it('0xdeadbeef should equal 0xdeadbeef0000000000n (9 byte)', async () => {
|
|
200
|
-
toBufferLE(BigInt(`0xdeadbeef`), 9).should.deep.equal(Buffer.from([
|
|
201
|
-
0xef, 0xbe, 0xad, 0xde, 0, 0, 0, 0, 0
|
|
202
|
-
]));
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('0xbadc0ffee0ddf00d should equal 0xbadc0ffee0ddf00dn (8 byte)',
|
|
206
|
-
async () => {
|
|
207
|
-
toBufferLE(BigInt(`0xbadc0ffee0ddf00d`), 8)
|
|
208
|
-
.should.deep.equal(
|
|
209
|
-
Buffer.from([0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba]));
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it('0xbadc0ffee0ddf00ddeadbeef should equal 0xbadc0ffee0ddf00ddeadbeefn',
|
|
213
|
-
async () => {
|
|
214
|
-
toBufferLE(BigInt(`0xbadc0ffee0ddf00ddeadbeef`), 12)
|
|
215
|
-
.should.deep.equal(Buffer.from([
|
|
216
|
-
0xef, 0xbe, 0xad, 0xde, 0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc,
|
|
217
|
-
0xba
|
|
218
|
-
]));
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
it('long value should equal long val', async () => {
|
|
222
|
-
toBufferLE(BigInt(`0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef`), 24)
|
|
223
|
-
.should.deep.equal(Buffer.from([
|
|
224
|
-
0xef, 0xbe, 0xad, 0xde, 0x0d, 0xf0, 0xdd, 0xe0,
|
|
225
|
-
0xfe, 0x0f, 0xdc, 0xba, 0xef, 0xbe, 0xad, 0xde,
|
|
226
|
-
0x0d, 0xf0, 0xdd, 0xe0, 0xfe, 0x0f, 0xdc, 0xba
|
|
227
|
-
]));
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
describe('Try bigint conversion (big endian)', () => {
|
|
233
|
-
it('0 should equal 0n', () => {
|
|
234
|
-
toBufferBE(BigInt(`0`), 8).should.deep.equal(Buffer.from([
|
|
235
|
-
0, 0, 0, 0, 0, 0, 0, 0
|
|
236
|
-
]));
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
it('1 should equal 1n', async () => {
|
|
240
|
-
toBufferBE(BigInt(`1`), 8).should.deep.equal(Buffer.from([
|
|
241
|
-
0, 0, 0, 0, 0, 0, 0, 1
|
|
242
|
-
]));
|
|
243
|
-
});
|
|
244
|
-
|
|
245
|
-
it('1 should equal 1n (32 byte)', async () => {
|
|
246
|
-
toBufferBE(BigInt(`1`), 32)
|
|
247
|
-
.should.deep.equal(Buffer.from(
|
|
248
|
-
'0000000000000000000000000000000000000000000000000000000000000001',
|
|
249
|
-
'hex'));
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
it('0xdead should equal 0xdeadn (6 byte)', async () => {
|
|
253
|
-
toBufferBE(BigInt(`0xdead`), 6).should.deep.equal(Buffer.from([
|
|
254
|
-
0, 0, 0, 0, 0xde, 0xad
|
|
255
|
-
]));
|
|
256
|
-
});
|
|
257
|
-
|
|
258
|
-
it('0xdeadbeef should equal 0xdeadbeef0000000000n (9 byte)', async () => {
|
|
259
|
-
toBufferBE(BigInt(`0xdeadbeef`), 9).should.deep.equal(Buffer.from([
|
|
260
|
-
0, 0, 0, 0, 0, 0xde, 0xad, 0xbe, 0xef
|
|
261
|
-
]));
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
it('0xbadc0ffee0ddf00d should equal 0xbadc0ffee0ddf00dn (8 byte)',
|
|
265
|
-
async () => {
|
|
266
|
-
toBufferBE(BigInt(`0xbadc0ffee0ddf00d`), 8)
|
|
267
|
-
.should.deep.equal(
|
|
268
|
-
Buffer.from([0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0, 0x0d]));
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
it('0xbadc0ffee0ddf00ddeadbeef should equal 0xbadc0ffee0ddf00ddeadbeefn',
|
|
272
|
-
async () => {
|
|
273
|
-
toBufferBE(BigInt(`0xbadc0ffee0ddf00ddeadbeef`), 12)
|
|
274
|
-
.should.deep.equal(Buffer.from([
|
|
275
|
-
0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0, 0x0d, 0xde, 0xad, 0xbe,
|
|
276
|
-
0xef
|
|
277
|
-
]));
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
it('long value should equal long val', async () => {
|
|
281
|
-
toBufferBE(BigInt(`0xbadc0ffee0ddf00ddeadbeefbadc0ffee0ddf00ddeadbeef`), 24)
|
|
282
|
-
.should.deep.equal(Buffer.from([
|
|
283
|
-
0xba, 0xdc, 0x0f, 0xfe, 0xe0, 0xdd, 0xf0, 0x0d,
|
|
284
|
-
0xde, 0xad, 0xbe, 0xef, 0xba, 0xdc, 0x0f, 0xfe,
|
|
285
|
-
0xe0, 0xdd, 0xf0, 0x0d, 0xde, 0xad, 0xbe, 0xef
|
|
286
|
-
]));
|
|
287
|
-
});
|
|
288
|
-
});
|
package/src/index.ts
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
interface ConverterInterface {
|
|
3
|
-
toBigInt(buf: Buffer, bigEndian?: boolean): bigint;
|
|
4
|
-
fromBigInt(num: BigInt, buf: Buffer, bigEndian?: boolean): Buffer;
|
|
5
|
-
}
|
|
6
|
-
|
|
7
|
-
declare var process: {browser: boolean; env?: {[key: string]: string | undefined}};
|
|
8
|
-
|
|
9
|
-
let converter: ConverterInterface;
|
|
10
|
-
const nativeBindingsEnabled =
|
|
11
|
-
!process.browser && process.env && process.env.BIGINT_BUFFER_NATIVE === '1';
|
|
12
|
-
|
|
13
|
-
if (nativeBindingsEnabled) {
|
|
14
|
-
try {
|
|
15
|
-
converter = require('bindings')('bigint_buffer');
|
|
16
|
-
} catch (e) {
|
|
17
|
-
console.warn(
|
|
18
|
-
'bigint: Failed to load bindings, pure JS will be used (try npm run rebuild?)');
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Convert a little-endian buffer into a BigInt.
|
|
24
|
-
* @param buf The little-endian buffer to convert
|
|
25
|
-
* @returns A BigInt with the little-endian representation of buf.
|
|
26
|
-
*/
|
|
27
|
-
export function toBigIntLE(buf: Buffer): bigint {
|
|
28
|
-
if (process.browser || converter === undefined) {
|
|
29
|
-
const reversed = Buffer.from(buf);
|
|
30
|
-
reversed.reverse();
|
|
31
|
-
const hex = reversed.toString('hex');
|
|
32
|
-
if (hex.length === 0) {
|
|
33
|
-
return BigInt(0);
|
|
34
|
-
}
|
|
35
|
-
return BigInt(`0x${hex}`);
|
|
36
|
-
}
|
|
37
|
-
return converter.toBigInt(buf, false);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Convert a big-endian buffer into a BigInt
|
|
42
|
-
* @param buf The big-endian buffer to convert.
|
|
43
|
-
* @returns A BigInt with the big-endian representation of buf.
|
|
44
|
-
*/
|
|
45
|
-
export function toBigIntBE(buf: Buffer): bigint {
|
|
46
|
-
if (process.browser || converter === undefined) {
|
|
47
|
-
const hex = buf.toString('hex');
|
|
48
|
-
if (hex.length === 0) {
|
|
49
|
-
return BigInt(0);
|
|
50
|
-
}
|
|
51
|
-
return BigInt(`0x${hex}`);
|
|
52
|
-
}
|
|
53
|
-
return converter.toBigInt(buf, true);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Convert a BigInt to a little-endian buffer.
|
|
58
|
-
* @param num The BigInt to convert.
|
|
59
|
-
* @param width The number of bytes that the resulting buffer should be.
|
|
60
|
-
* @returns A little-endian buffer representation of num.
|
|
61
|
-
*/
|
|
62
|
-
export function toBufferLE(num: bigint, width: number): Buffer {
|
|
63
|
-
if (process.browser || converter === undefined) {
|
|
64
|
-
const hex = num.toString(16);
|
|
65
|
-
const buffer =
|
|
66
|
-
Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
67
|
-
buffer.reverse();
|
|
68
|
-
return buffer;
|
|
69
|
-
}
|
|
70
|
-
// Allocation is done here, since it is slower using napi in C
|
|
71
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), false);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Convert a BigInt to a big-endian buffer.
|
|
76
|
-
* @param num The BigInt to convert.
|
|
77
|
-
* @param width The number of bytes that the resulting buffer should be.
|
|
78
|
-
* @returns A big-endian buffer representation of num.
|
|
79
|
-
*/
|
|
80
|
-
export function toBufferBE(num: bigint, width: number): Buffer {
|
|
81
|
-
if (process.browser || converter === undefined) {
|
|
82
|
-
const hex = num.toString(16);
|
|
83
|
-
return Buffer.from(hex.padStart(width * 2, '0').slice(0, width * 2), 'hex');
|
|
84
|
-
}
|
|
85
|
-
return converter.fromBigInt(num, Buffer.allocUnsafe(width), true);
|
|
86
|
-
}
|
package/tsconfig.json
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./node_modules/gts/tsconfig-google.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"rootDir": ".",
|
|
5
|
-
"outDir": "build",
|
|
6
|
-
"target" : "esnext",
|
|
7
|
-
"lib" : [ "esnext" ],
|
|
8
|
-
"sourceMap": true
|
|
9
|
-
},
|
|
10
|
-
"include": [
|
|
11
|
-
"src/*.ts",
|
|
12
|
-
"src/**/*.ts",
|
|
13
|
-
"test/*.ts",
|
|
14
|
-
"test/**/*.ts"
|
|
15
|
-
],
|
|
16
|
-
"exclude": [
|
|
17
|
-
"node_modules"
|
|
18
|
-
]
|
|
19
|
-
}
|