Code Monkey home page Code Monkey logo

tiny-secp256k1's Introduction

tiny-secp256k1

NPM

This library is under development, and, like the secp256k1 C library (through secp256k1-sys Rust crate) it depends on, this is a research effort to determine an optimal API for end-users of the bitcoinjs ecosystem.

Installation

npm

npm install tiny-secp256k1

yarn

yarn add tiny-secp256k1

WebAssembly and Node.js version

Previous version of tiny-secp256k1 implement C++ addon through NAN (Native Abstractions for Node.js) and elliptic as fallback when addon can not be built or in browser-like environement.

Current version use Rust crate (which use C library) compiled to WebAssembly. With Wasm same code executed in any environment. Wasm is faster than elliptic but slower than node bindings (results in PR or you can run own benchmark in benches directory).

Tools like webpack, environments like React Native, and a large part of the JavaScript/TypeScript ecosystem has support for WASM based libraries. However, it usually involves special config settings which might be difficult to figure out. We have examples in the examples folder that uses webpack to create a demo website.

However, there are also alternative implementations of the interface of this library.

Alternatives

  1. @bitcoinjs-lib/tiny-secp256k1-asmjs - This library uses wasm2js to convert this library into pure JS. It is about 10x ~ 20x slower than WASM and 3x ~ 10x slower than our old v1 JS implementation.
  2. @bitcoinerlab/secp256k1 - This library uses noble/secp256k1, and therefore it uses JS native BigInt. If you can support BigInt it is much faster than ASM.JS, however, this is not maintained by this library's maintainers, so there's no guarantee that they will keep up with any interface changes in the future. Please check before using. It is about 1.5x ~ 5x slower than WASM.

Building

For building locally you need C/C++ toolchain, Rust version >=1.50.0 and wasm-opt from binaryen.

rustup is a recommended way to install Rust. You also will need wasm32-unknown-unknown target.

rustup toolchain install stable --target wasm32-unknown-unknown --component clippy --component rustfmt

After installing development dependencies with npm you can build Wasm:

make build-wasm

or run tests:

make test

Alternative way is to use Docker:

% docker build -t tiny-secp256k1 .
% docker run -it --rm -v `pwd`:/tiny-secp256k1 -w /tiny-secp256k1 tiny-secp256k1
# make build

Examples

tiny-secp256k1 includes two examples. First is simple script for Node.js which generate random data and print arguments and methods results. Second is React app.

React app is builded in GitHub Actions on each commit to master branch and uploaded to gh-pages branch, which is always available online: https://bitcoinjs.github.io/tiny-secp256k1/

Documentation

isPoint (A)

isPoint :: Buffer -> Bool

Returns false if

  • A is not encoded with a sequence tag of 0x02, 0x03 or 0x04
  • A.x is not in [1...p - 1]
  • A.y is not in [1...p - 1]

isPointCompressed (A)

isPointCompressed :: Buffer -> Bool

Returns false if the pubkey is not compressed.

isXOnlyPoint (A)

isXOnlyPoint :: Buffer -> Bool

Returns false if the pubkey is not an xOnlyPubkey.

isPrivate (d)

isPrivate :: Buffer -> Bool

Returns false if

  • d is not 256-bit, or
  • d is not in [1..order - 1]

pointAdd (A, B[, compressed])

pointAdd :: Buffer -> Buffer [-> Bool] -> Maybe Buffer

Returns null if result is at infinity.

Throws:
  • Expected Point if !isPoint(A)
  • Expected Point if !isPoint(B)

pointAddScalar (A, tweak[, compressed])

pointAddScalar :: Buffer -> Buffer [-> Bool] -> Maybe Buffer

Returns null if result is at infinity.

Throws:
  • Expected Point if !isPoint(A)
  • Expected Tweak if tweak is not in [0...order - 1]

pointCompress (A, compressed)

pointCompress :: Buffer -> Bool -> Buffer
Throws:
  • Expected Point if !isPoint(A)

pointFromScalar (d[, compressed])

pointFromScalar :: Buffer [-> Bool] -> Maybe Buffer

Returns null if result is at infinity.

Throws:
  • Expected Private if !isPrivate(d)

xOnlyPointFromScalar (d)

xOnlyPointFromScalar :: Buffer -> Buffer

Returns the xOnlyPubkey for a given private key

Throws:
  • Expected Private if !isPrivate(d)

xOnlyPointFromPoint (p)

xOnlyPointFromPoint :: Buffer -> Buffer

Returns the xOnlyPubkey for a given DER public key

Throws:
  • Expected Point if !isPoint(p)

pointMultiply (A, tweak[, compressed])

pointMultiply :: Buffer -> Buffer [-> Bool] -> Maybe Buffer

Returns null if result is at infinity.

Throws:
  • Expected Point if !isPoint(A)
  • Expected Tweak if tweak is not in [0...order - 1]

privateAdd (d, tweak)

privateAdd :: Buffer -> Buffer -> Maybe Buffer

Returns null if result is equal to 0.

Throws:
  • Expected Private if !isPrivate(d)
  • Expected Tweak if tweak is not in [0...order - 1]

privateSub (d, tweak)

privateSub :: Buffer -> Buffer -> Maybe Buffer

Returns null if result is equal to 0.

Throws:
  • Expected Private if !isPrivate(d)
  • Expected Tweak if tweak is not in [0...order - 1]

privateNegate (d)

privateNegate :: Buffer -> Buffer

Returns the negation of d on the order n (n - d)

Throws:
  • Expected Private if !isPrivate(d)

xOnlyPointAddTweak (p, tweak)

xOnlyPointAddTweak :: Buffer -> Buffer -> { parity: 1 | 0; xOnlyPubkey: Buffer; }

Returns the tweaked xOnlyPubkey along with the parity bit (number type of 1|0)

Throws:
  • Expected Point if !isXOnlyPoint(p)
  • Expected Tweak if !isXOnlyPoint(tweak)

xOnlyPointAddTweakCheck (p1, p2, tweak[, tweakParity])

xOnlyPointAddTweakCheck :: Buffer -> Buffer -> Buffer [-> 1 | 0] -> Bool

Checks the tweaked pubkey (p2) against the original pubkey (p1) and tweak. This is slightly slower if you include tweakParity, tweakParity will make it faster for aggregation later on.

Throws:
  • Expected Point if !isXOnlyPoint(p1)
  • Expected Point if !isXOnlyPoint(p2)
  • Expected Tweak if !isXOnlyPoint(tweak)
  • Expected Parity if tweakParity is not 1 or 0

sign (h, d[, e])

sign :: Buffer -> Buffer [-> Buffer] -> Buffer

Returns normalized signatures, each of (r, s) values are guaranteed to less than order / 2. Uses RFC6979. Adds e as Added Entropy to the deterministic k generation.

Throws:
  • Expected Private if !isPrivate(d)
  • Expected Scalar if h is not 256-bit
  • Expected Extra Data (32 bytes) if e is not 256-bit

signRecoverable (h, d[, e])

signRecoverable :: Buffer -> Buffer [-> Buffer] -> { recoveryId: 0 | 1 | 2 | 3; signature: Buffer; }

Returns normalized signatures and recovery Id, each of (r, s) values are guaranteed to less than order / 2. Uses RFC6979. Adds e as Added Entropy to the deterministic k generation.

Throws:
  • Expected Private if !isPrivate(d)
  • Expected Scalar if h is not 256-bit
  • Expected Extra Data (32 bytes) if e is not 256-bit

signSchnorr (h, d[, e])

signSchnorr :: Buffer -> Buffer [-> Buffer] -> Buffer

Returns normalized schnorr signature. Uses BIP340 nonce generation. Adds e as Added Entropy.

Throws:
  • Expected Private if !isPrivate(d)
  • Expected Scalar if h is not 256-bit
  • Expected Extra Data (32 bytes) if e is not 256-bit

verify (h, Q, signature[, strict = false])

verify :: Buffer -> Buffer -> Buffer [-> Bool] -> Bool

Returns false if any of (r, s) values are equal to 0, or if the signature is rejected.

If strict is true, valid signatures with any of (r, s) values greater than order / 2 are rejected.

Throws:
  • Expected Point if !isPoint(Q)
  • Expected Signature if signature has any (r, s) values not in range [0...order - 1]
  • Expected Scalar if h is not 256-bit

recover (h, signature, recoveryId[, compressed = false])

verify :: Buffer -> Buffer -> Number [-> Bool] -> Maybe Buffer

Returns the ECDSA public key from a signature if it can be recovered, null otherwise.

Throws:
  • Expected Signature if signature has any (r, s) values not in range (0...order - 1]
  • Bad Recovery Id if recid & 2 !== 0 and signature has any r value not in range (0...P - N - 1]
  • Expected Hash if h is not 256-bit

verifySchnorr (h, Q, signature)

verifySchnorr :: Buffer -> Buffer -> Buffer -> Bool

Returns false if any of (r, s) values are equal to 0, or if the signature is rejected.

Throws:
  • Expected Point if !isPoint(Q)
  • Expected Signature if signature has any (r, s) values not in range [0...order - 1]
  • Expected Scalar if h is not 256-bit

Credit

This library uses the native library secp256k1 by the bitcoin-core developers through Rust crate secp256k1-sys, including derivatives of its tests and test vectors.

LICENSE MIT

tiny-secp256k1's People

Contributors

dcousens avatar dependabot[bot] avatar dignifiedquire avatar fanatid avatar jack-works avatar junderw avatar landabaso avatar motorina0 avatar pierreneter avatar robin-hoodie avatar shamoilarsi avatar victoryeo avatar xmader avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

tiny-secp256k1's Issues

Cannot load wasm on Windows

 ENOENT: no such file or directory, open '/C:/Users/Jack/Workspace/Mask/node_modules/.pnpm/[email protected]/node_modules/tiny-secp256k1/lib/secp256k1.wasm'

Note: You cannot pass new URL(...).pathname to fs.readFileSync because it creates an invalid path on Windows.

The correct way to do this is:

import { fileURLToPath } from 'url'
const __dirname = fileURLToPath(new URL('.', import.meta.url))
console.log(__dirname)

Unable to build tiny-secp256k1

Hello,

I cloned the project and tried to run the following command make build-wasm and received he following error in the console:

RUSTFLAGS="-C link-args=-zstack-size=655360" cargo build --target wasm32-unknown-unknown --release
'RUSTFLAGS' is not recognized as an internal or external command,
operable program or batch file.
make: *** [build-wasm] Error 1

Running in a windows machine

Issue following the examples in a react app

Hello,

I'm developing a BTC wallet using bitcoinjs-lib. Following the examples this peace of code breaks my FE:

import * as assert from 'assert';
import BIP32Factory from 'bip32';
import * as ecc from 'tiny-secp256k1';

const bip32 = BIP32Factory(ecc);

I receive the following error in the console:

image

Please let me know if you need more information, I just tried to add the minimum necessary info in order to avoid unecessary noise.

Thanks in advance.

Doesn't work on NodeJS 12

I specified NodeJS Stable on Travis CI, but yesterday the pipelines broke on tiny-secp256k1. More context on travis-ci.org/GetEpona/Epona-js.

[4/4] Building fresh packages...
error /home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments: 
Directory: /home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1
Output:
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | linux | x64
gyp http GET https://nodejs.org/download/release/v12.0.0/node-v12.0.0-headers.tar.gz
gyp http 200 https://nodejs.org/download/release/v12.0.0/node-v12.0.0-headers.tar.gz
gyp http GET https://nodejs.org/download/release/v12.0.0/SHASUMS256.txt
gyp http 200 https://nodejs.org/download/release/v12.0.0/SHASUMS256.txt
gyp info spawn /opt/pyenv/shims/python2
gyp info spawn args [
gyp info spawn args   '/home/travis/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
gyp info spawn args   'binding.gyp',
gyp info spawn args   '-f',
gyp info spawn args   'make',
gyp info spawn args   '-I',
gyp info spawn args   '/home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1/build/config.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/home/travis/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
gyp info spawn args   '-I',
gyp info spawn args   '/home/travis/.node-gyp/12.0.0/include/node/common.gypi',
gyp info spawn args   '-Dlibrary=shared_library',
gyp info spawn args   '-Dvisibility=default',
gyp info spawn args   '-Dnode_root_dir=/home/travis/.node-gyp/12.0.0',
gyp info spawn args   '-Dnode_gyp_dir=/home/travis/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp',
gyp info spawn args   '-Dnode_lib_file=/home/travis/.node-gyp/12.0.0/<(target_arch)/node.lib',
gyp info spawn args   '-Dmodule_root_dir=/home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1',
gyp info spawn args   '-Dnode_engine=v8',
gyp info spawn args   '--depth=.',
gyp info spawn args   '--no-parallel',
gyp info spawn args   '--generator-output',
gyp info spawn args   'build',
gyp info spawn args   '-Goutput_dir=.'
gyp info spawn args ]
gyp info spawn make
gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
make: Entering directory '/home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1/build'
  CXX(target) Release/obj.target/secp256k1/native/addon.o
../native/addon.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE ecdsaVerify(Nan::NAN_METHOD_ARGS_TYPE)’:
../native/addon.cpp:320:34: error: no matching function for call to ‘v8::Value::BooleanValue()’
   strict = info[3]->BooleanValue();
                                  ^
In file included from /home/travis/.node-gyp/12.0.0/include/node/node.h:63:0,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note: candidate: bool v8::Value::BooleanValue(v8::Isolate*) const
   bool BooleanValue(Isolate* isolate) const;
        ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note:   candidate expects 1 argument, 0 provided
In file included from /home/travis/.node-gyp/12.0.0/include/node/v8-internal.h:14:0,
                 from /home/travis/.node-gyp/12.0.0/include/node/v8.h:25,
                 from /home/travis/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note: candidate: v8::Maybe<bool> v8::Value::BooleanValue(v8::Local<v8::Context>) const
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note:   candidate expects 1 argument, 0 provided
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
../native/addon.cpp: In instantiation of ‘unsigned int {anonymous}::assumeCompression(const I&, const A&) [with long unsigned int index = 2ul; I = Nan::FunctionCallbackInfo<v8::Value>; A = v8::Local<v8::Object>]’:
../native/addon.cpp:142:50:   required from here
../native/addon.cpp:80:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (info.Length() <= index) return __isPointCompressed(p) ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
                     ^
../native/addon.cpp:82:38: error: no matching function for call to ‘v8::Value::BooleanValue()’
   return info[index]->BooleanValue() ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
                                      ^
In file included from /home/travis/.node-gyp/12.0.0/include/node/node.h:63:0,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note: candidate: bool v8::Value::BooleanValue(v8::Isolate*) const
   bool BooleanValue(Isolate* isolate) const;
        ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note:   candidate expects 1 argument, 0 provided
In file included from /home/travis/.node-gyp/12.0.0/include/node/v8-internal.h:14:0,
                 from /home/travis/.node-gyp/12.0.0/include/node/v8.h:25,
                 from /home/travis/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note: candidate: v8::Maybe<bool> v8::Value::BooleanValue(v8::Local<v8::Context>) const
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note:   candidate expects 1 argument, 0 provided
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
../native/addon.cpp: In instantiation of ‘unsigned int {anonymous}::assumeCompression(const I&, const A&) [with long unsigned int index = 1ul; I = Nan::FunctionCallbackInfo<v8::Value>; A = v8::Local<v8::Object>]’:
../native/addon.cpp:174:49:   required from here
../native/addon.cpp:80:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (info.Length() <= index) return __isPointCompressed(p) ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
                     ^
../native/addon.cpp:82:38: error: no matching function for call to ‘v8::Value::BooleanValue()’
   return info[index]->BooleanValue() ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
                                      ^
In file included from /home/travis/.node-gyp/12.0.0/include/node/node.h:63:0,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note: candidate: bool v8::Value::BooleanValue(v8::Isolate*) const
   bool BooleanValue(Isolate* isolate) const;
        ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note:   candidate expects 1 argument, 0 provided
In file included from /home/travis/.node-gyp/12.0.0/include/node/v8-internal.h:14:0,
                 from /home/travis/.node-gyp/12.0.0/include/node/v8.h:25,
                 from /home/travis/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note: candidate: v8::Maybe<bool> v8::Value::BooleanValue(v8::Local<v8::Context>) const
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note:   candidate expects 1 argument, 0 provided
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
../native/addon.cpp: In instantiation of ‘unsigned int {anonymous}::assumeCompression(const I&) [with long unsigned int index = 1ul; I = Nan::FunctionCallbackInfo<v8::Value>]’:
../native/addon.cpp:189:46:   required from here
../native/addon.cpp:87:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
   if (info.Length() <= index) return SECP256K1_EC_COMPRESSED;
                     ^
../native/addon.cpp:89:38: error: no matching function for call to ‘v8::Value::BooleanValue()’
   return info[index]->BooleanValue() ? SECP256K1_EC_COMPRESSED : SECP256K1_EC_UNCOMPRESSED;
                                      ^
In file included from /home/travis/.node-gyp/12.0.0/include/node/node.h:63:0,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note: candidate: bool v8::Value::BooleanValue(v8::Isolate*) const
   bool BooleanValue(Isolate* isolate) const;
        ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2559:8: note:   candidate expects 1 argument, 0 provided
In file included from /home/travis/.node-gyp/12.0.0/include/node/v8-internal.h:14:0,
                 from /home/travis/.node-gyp/12.0.0/include/node/v8.h:25,
                 from /home/travis/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../../nan/nan.h:53,
                 from ../native/addon.cpp:4:
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note: candidate: v8::Maybe<bool> v8::Value::BooleanValue(v8::Local<v8::Context>) const
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
/home/travis/.node-gyp/12.0.0/include/node/v8.h:2562:51: note:   candidate expects 1 argument, 0 provided
                 V8_WARN_UNUSED_RESULT Maybe<bool> BooleanValue(
                                                   ^
/home/travis/.node-gyp/12.0.0/include/node/v8config.h:307:3: note: in definition of macro ‘V8_DEPRECATED’
   declarator __attribute__((deprecated(message)))
   ^
../native/addon.cpp: In function ‘Nan::NAN_METHOD_RETURN_TYPE eccPrivateSub(Nan::NAN_METHOD_ARGS_TYPE)’:
../native/addon.cpp:240:53: warning: ignoring return value of ‘int secp256k1_ec_privkey_negate(const secp256k1_context*, unsigned char*)’, declared with attribute warn_unused_result [-Wunused-result]
  secp256k1_ec_privkey_negate(context, tweak_negated); // returns 1 always
                                                     ^
secp256k1.target.mk:149: recipe for target 'Release/obj.target/secp256k1/native/addon.o' failed
make: Leaving directory '/home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1/build'
make: *** [Release/obj.target/secp256k1/native/addon.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/travis/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:196:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:256:12)
gyp ERR! System Linux 4.15.0-1028-gcp
gyp ERR! command "/home/travis/.nvm/versions/node/v12.0.0/bin/node" "/home/travis/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/travis/build/GetEpona/Epona-js/node_modules/tiny-secp256k1
gyp ERR! node -v v12.0.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok

Buffer is not defined error in browser

rfc6979.js:3 Uncaught ReferenceError: Buffer is not defined
    at Object../node_modules/tiny-secp256k1/rfc6979.js (rfc6979.js:3)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/tiny-secp256k1/js.js (js.js:4)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/bip32/src/bip32.js (bip32.js:5)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/bip32/src/index.js (index.js:3)
    at __webpack_require__ (bootstrap:79)
    at Object../node_modules/bitcoinjs-lib/src/index.js (index.js:3)
    at __webpack_require__ (bootstrap:79)

Is this even supposed to work in the browser? :)

tiny-secp compilation in swift and java

Hi I need to use this library in react-native, but it is tied with wasm that is not supported in react-native environment.
Is it possible to compile your rust source file in java and swift so that it can be called natively from react-native?

The older version of this lib (1.1.6) that didn't make use of wasm is no longer usable in my application because one of my deps is calling a method that is implemented only in your newer versions (privateNegate)

Difference between native and js of isPoint

From my repl session:

$ node
> const ecc = require('tiny-secp256k1')
undefined
> const ecc2 = require('tiny-secp256k1/ecurve')
undefined
> b = Buffer.from('020045400697100007000037899988826500030092003000016366806305909050','hex')
<Buffer 02 00 45 40 06 97 10 00 07 00 00 37 89 99 88 82 65 00 03 00 92 00 30 00 01 63 66 80 63 05 90 90 50>
> ecc.isPoint(b)
false
> ecc2.isPoint(b)
true

lots of warning during `npm install tiny-secp256k1`

In the empty project, I do npm install tiny-secp256k1 and get lots of warnings:

$ npm i npm install tiny-secp256k1

> [email protected] install /Users/<username>/programming/learning_blockchain/blockchain_basics/node_modules/tiny-secp256k1
> node-gyp rebuild

gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
gyp WARN download NVM_NODEJS_ORG_MIRROR is deprecated and will be removed in node-gyp v4, please use NODEJS_ORG_MIRROR
  CXX(target) Release/obj.target/secp256k1/native/addon.o
../native/addon.cpp:22:3: warning: suggest braces around initialization of
      subobject [-Wmissing-braces]
  ...0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     {
../native/addon.cpp:239:2: warning: ignoring return value of function declared
      with 'warn_unused_result' attribute [-Wunused-result]
        secp256k1_ec_privkey_negate(context, tweak_negated); // returns 1 always
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
../native/addon.cpp:79:21: warning: comparison of integers of different signs:
      'int' and 'unsigned long' [-Wsign-compare]
                if (info.Length() <= index) return __isPointCompressed(p...
                    ~~~~~~~~~~~~~ ^  ~~~~~
../native/addon.cpp:141:21: note: in instantiation of function template
      specialization '(anonymous namespace)::assumeCompression<2,
      Nan::FunctionCallbackInfo<v8::Value>, v8::Local<v8::Object> >' requested
      here
        const auto flags = assumeCompression<2>(info, pA);
                           ^
../native/addon.cpp:79:21: warning: comparison of integers of different signs:
      'int' and 'unsigned long' [-Wsign-compare]
                if (info.Length() <= index) return __isPointCompressed(p...
                    ~~~~~~~~~~~~~ ^  ~~~~~
../native/addon.cpp:173:21: note: in instantiation of function template
      specialization '(anonymous namespace)::assumeCompression<1,
      Nan::FunctionCallbackInfo<v8::Value>, v8::Local<v8::Object> >' requested
      here
        const auto flags = assumeCompression<1>(info, p);
                           ^
../native/addon.cpp:86:21: warning: comparison of integers of different signs:
      'int' and 'unsigned long' [-Wsign-compare]
                if (info.Length() <= index) return SECP256K1_EC_COMPRESSED;
                    ~~~~~~~~~~~~~ ^  ~~~~~
../native/addon.cpp:188:21: note: in instantiation of function template
      specialization '(anonymous namespace)::assumeCompression<1,
      Nan::FunctionCallbackInfo<v8::Value> >' requested here
        const auto flags = assumeCompression<1>(info);
                           ^
../native/addon.cpp:20:32: warning: unused variable 'ZERO'
      [-Wunused-const-variable]
        const std::array<uint8_t, 32> ZERO = {};
                                      ^
6 warnings generated.
  CC(target) Release/obj.target/secp256k1/native/secp256k1/src/secp256k1.o
In file included from ../native/secp256k1/src/secp256k1.c:13:
../native/secp256k1/src/group_impl.h:686:12: warning: unused function
      'secp256k1_gej_has_quad_y_var' [-Wunused-function]
static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) {
           ^
../native/secp256k1/src/group_impl.h:113:13: warning: unused function
      'secp256k1_ge_set_gej_var' [-Wunused-function]
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
            ^
../native/secp256k1/src/group_impl.h:267:12: warning: unused function
      'secp256k1_gej_is_valid_var' [-Wunused-function]
static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) {
           ^
In file included from ../native/secp256k1/src/secp256k1.c:15:
../native/secp256k1/src/ecmult_const_impl.h:123:13: warning: unused function
      'secp256k1_ecmult_const' [-Wunused-function]
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge ...
            ^
4 warnings generated.
  SOLINK_MODULE(target) Release/secp256k1.node
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
npm WARN [email protected] No license field.

+ [email protected]
+ [email protected]
+ [email protected]
added 427 packages from 794 contributors, updated 1 package and audited 33497 packages in 29.903s
found 2 vulnerabilities (1 low, 1 moderate)
  run `npm audit fix` to fix them, or `npm audit` for details
  • is it possible to fix that?
    Surprisingly, so many projects I work with, start from bitcoinjs-lib finish by ready to use wallets pull this warnings.

wasm.memory is undefined

TypeError: Cannot read properties of undefined (reading 'buffer').

const WASM_BUFFER = new Uint8Array(wasm.memory.buffer);

at src_ts/index.ts line 5

Running this in a create react app with webpack v5.65.0

webpack: {
    alias: {
      assert: "assert",
      buffer: "buffer",
      crypto: "crypto-browserify",
      http: "stream-http",
      https: "https-browserify",
      os: "os-browserify/browser",
      process: "process/browser",
      stream: "stream-browserify",
      util: "util",
    },
    plugins: {
      add: [
        new webpack.ProvidePlugin({
          process: "process/browser",
          Buffer: ["buffer", "Buffer"],
        }),
      ],
    },
    configure: {
      experiments: {
        asyncWebAssembly: true,
      },
    },
  },

Here is the repo. If you have a ledger you can repro. Let me know and I can outline steps

Pure-js backport of `xOnlyPointFromPoint()`..?

For a project utilizing ver 1.1.6 Id like to use xOnlyPointFromPoint() which is available only on higher versions.
Cant bumptiny because it doenst work in my environment (React Native).

xOnlyPointFromPointis needed by BIP47 (payment codes).

Is there any way to hack a pure-js implementation, or backport it to v1 branch..?

Thanks!

Split off native code

Into a new module tiny-secp256k1-native, and have it as an optional dependency for this module. (with automatic pull-in if it exists)
This should resolve a lot of the issues users are facing upstream in compiling it and/or isolating it from their projects.

And it supports better modularity, at the expense of merely defaulting to the JS implementation.

Thoughts?
Breaking change.

Bug when using browserify

node: v16.18.1
npm: 7.12.0
browserify: v17.0.0

I only run browserify file.js -o bundle.js with it:

const ecc = require('tiny-secp256k1')

Screenshot from 2022-12-08 10-42-04

Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/bindings/bindings.js 81:43-53
Critical dependency: the request of a dependency is an expression
@ ./node_modules/tiny-secp256k1/index.js
@ ./node_modules/bip32/index.js
@ ./node_modules/oip-hdmw/lib/Coin.js
@ ./node_modules/oip-hdmw/lib/index.js
@ ./node_modules/oip-account/lib/Account.js
@ ./node_modules/oip-account/lib/index.js
@ ./src/App.js
@ ./src/index.js
@ multi (webpack)-dev-server/client?http://127.0.0.1:9156 ./src/index.js

Is there anything wrong in this export?

//tiny-secp256k1/index.js
'use strict'

try 
  module.exports = require('bindings')('secp256k1')
} catch (err) {
  module.exports = require('./ecurve')
}

Re-introduce privateKeyNegate

It was not needed pre-taproot... but since it looks like we will need to negate private keys a lot when they are odd-y (0x03) pubkeys, this is probably needed moving forward.

Compatibility: `tiny-secp256k1` vs. `secp256k1-node`

  • How can private/public keys be generated with tiny-secp256k1?

secp256k1-node provides functions (See below) for verifying private keys (privateKeyVerify) and generating public keys from them (publicKeyCreate). Are there tiny-secp256k1 equivalents?

// generate privKey
let privKey
do {
  privKey = randomBytes(32)
} while (!secp256k1.privateKeyVerify(privKey))

// get the public key in a compressed format
const pubKey = secp256k1.publicKeyCreate(privKey)
  • Can the pricate/public keys generated with tiny-secp256k1 or secp256k1-node be used with the other (e.g., generate private/public key using secp256k1-node and used it with sign (h, d)/verify (h, Q, signature[, strict = false]) of tiny-secp256k1?

Must use import to load ES Module

Upgrading to 3.0.0 of https://github.com/bitcoinjs/bip32 in a project that uses ESM is causing some issues when using the suggested tiny-secp256k1. When running tests via node --experimental-vm-modules node_modules/jest/bin/jest.js --forceExit "source/public-key.service.test.ts" an error about Must use import to load ES Module is thrown.

This seems to be caused by tiny-secp256k1 having declared its type as module in package.json since 2.0.0 which means you can no longer require it with certain tooling because they'll throw exceptions if you try to require anything that is declared as a module.

Is the suggested solution to stay on 1.0.0 of tiny-secp256k1 if you don't want to encounter this error? I saw there have been various bug fixes on 2.0.0 so it seems like an upgrade would be sensible.

 FAIL  source/public-key.service.test.ts
  ● Test suite failed to run

    Must use import to load ES Module: /Users/brianfaust/Work/sdk/common/temp/node_modules/.pnpm/[email protected]/node_modules/tiny-secp256k1/lib/index.js

      2 |
      3 | import BIP32Factory, { BIP32Interface } from "bip32";
    > 4 | import * as ecc from "tiny-secp256k1";
        | ^
      5 |
      6 | import { BIP39 } from "./bip39";
      7 |

      at Runtime.requireModule (../../common/temp/node_modules/.pnpm/[email protected]/node_modules/jest-runtime/build/index.js:972:21)
      at Object.<anonymous> (../cryptography/source/bip32.ts:4:1)
      at Object.<anonymous> (../cryptography/source/index.ts:7:1)

building native.cpp fails

npm install git+https://github.com/bitcoinjs/tiny-secp256k1 yields the following error. I

 g++ '-DNODE_GYP_MODULE_NAME=secp256k1' '-DUSING_UV_SHARED=1' '-DUSING_V8_SHARED=1' '-DV8_DEPRECATION_WARNINGS=1' '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DUSE_NUM_NONE=1' '-DUSE_FIELD_INV_BUILTIN=1' '-
DUSE_SCALAR_INV_BUILTIN=1' '-DHAVE___INT128=1' '-DUSE_ASM_X86_64=1' '-DUSE_FIELD_5X52=1' '-DUSE_FIELD_5X52_INT128=1' '-DUSE_SCALAR_4X64=1' '-DBUILDING_NODE_EXTENSION' -I/home/marko/.node-gyp/6.12.3/include/node 
-I/home/marko/.node-gyp/6.12.3/src -I/home/marko/.node-gyp/6.12.3/deps/uv/include -I/home/marko/.node-gyp/6.12.3/deps/v8/include -I/usr/local/include -I../native/secp256k1 -I../native/secp256k1/contrib -I../nati
ve/secp256k1/include -I../native/secp256k1/src -I../../nan  -fPIC -pthread -Wall -Wextra -Wno-unused-parameter -m64 -Wall -Wno-maybe-uninitialized -Wno-uninitialized -Wno-unused-function -Wextra -O3 -fno-omit-fr
ame-pointer -std=c++11 -fno-rtti -fno-exceptions -std=gnu++0x -MMD -MF ./Release/.deps/Release/obj.target/secp256k1/native/addon.o.d.raw   -c -o Release/obj.target/secp256k1/native/addon.o ../native/addon.cpp
../native/addon.cpp:19:13: error: ‘array’ in namespace ‘std’ does not name a template type
  const std::array<uint8_t, 32> ZERO = {};
             ^

My compiler version:

$ g++ --version
g++ (Ubuntu 7.3.0-16ubuntu3~16.04.1) 7.3.0

expose recover() function

  • bitcoin-message lib is using secp256k1.recover()
  • this function is not exposed by tiny-secp256k1

Related discussion: bitcoinjs/ecpair#3 (comment)

 function verify (message,...
    ...
    const publicKey = secp256k1.recover(
      hash,
      parsed.signature,
      parsed.recovery,
      parsed.compressed
    )

Cannot use import statement outside a module when importing this package using Jest

This results in the following error

({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { compare } from "uint8array-tools";

SyntaxError: Cannot use import statement outside a module

import { pointMultiply, pointAdd } from "tiny-secp256k1";
^

It seems the compare import from "uint8array-tools" is the culprit here

Downgrading to version 1.1.6 resolves the issue

Happy to create a repro or help out if necessary

Failing to install on macOS 10.14.2

Node version: v8.12.0
yarn version: v1.12.3

Originally discovered when attempting ot install js-ipfs. Issue for that is open here.

Failing to install. npm i tiny-secp256k1 outputs:

module.js:550
    throw err;
    ^
Error: Cannot find module '../lib/utils/unsupported.js'
    at Function.Module._resolveFilename (module.js:548:15)
    at Function.Module._load (module.js:475:25)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
    at /usr/local/lib/node_modules/npm/bin/npm-cli.js:19:21
    at Object.<anonymous> (/usr/local/lib/node_modules/npm/bin/npm-cli.js:153:3)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)

Wrong path when bundling tiny-secp256k1 with Electron

Hello,

First off thank you for making this library. Secondly, we are having issues bundling this with Electron and Electron Builder. The issue is that during the bundling process the following file:

wasm_path.js uses import.meta.url.

Using webpack, when it is packaged and built, it uses the path of the wasm file on the build machine. Instead of the where it is relative to where it running on the target machine. Disabling that behavior in webpack using:

 module: {
        parser: {
            javascript : { importMeta: false }
        }
    }

Does not seem to work because it then throws another error that import.meta.url cannot be used outside of a module. I have a feeling others will run into this issue. For now, we have copied the wasm file out and patched the file to look for it relative to the installation path. Any help here appreciated. Happy to help debug.

How do I import?

I have run

npm install tiny-secp256k1

How do I then import it into a typescript file? This does not work.

import * as secp256k1 from "secp256k1";

This does not work either:

import * as any from "tiny-secp256k1";

Finally, I have tried

npm i --save-dev @types/tiny-secp256k1

but it outputs: npm WARN deprecated @types/[email protected]: This is a stub types definition. tiny-secp256k1 provides its own type definitions, so you do not need this installed.

After bumping ReactNative project from 1.1.6 to 2.0.0 builds for Android fail

warning: the transform cache was reset.
                    Welcome to Metro!
              Fast - Scalable - Integrated


error Unable to resolve module ./secp256k1.wasm from /home/ghost/Documents/BlueWallet/node_modules/tiny-secp256k1/lib/wasm_loader.browser.js: ./secp256k1.wasm could not be found within the project or in these directories:
Error: Unable to resolve module ./secp256k1.wasm from /home/ghost/Documents/BlueWallet/node_modules/tiny-secp256k1/lib/wasm_loader.browser.js: ./secp256k1.wasm could not be found within the project or in these directories:
  node_modules
  node_modules


If you are sure the module exists, try these steps:
If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules and run yarn install
 2. Delete node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*
 4. Remove the cache: rm -rf /tmp/metro-*
> 1 | // Suppress TS2792: Cannot find module './secp256k1.wasm'.
> 1 | // Suppress TS2792: Cannot find module './secp256k1.wasm'.
    |                                         ^
    |                                         ^
  2 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  2 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  3 | // @ts-ignore
  3 | // @ts-ignore
  4 | import * as wasm from "./secp256k1.wasm";
  4 | import * as wasm from "./secp256k1.wasm";.
    at ModuleResolver.resolveDependency (/home/ghost/Documents/BlueWallet/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:129:15)
    at DependencyGraph.resolveDependency (/home/ghost/Documents/BlueWallet/node_modules/metro/src/node-haste/DependencyGraph.js:288:43)
    at Object.resolve (/home/ghost/Documents/BlueWallet/node_modules/metro/src/lib/transformHelpers.js:129:24)
    at resolve (/home/ghost/Documents/BlueWallet/node_modules/metro/src/DeltaBundler/traverseDependencies.js:396:33)
    at /home/ghost/Documents/BlueWallet/node_modules/metro/src/DeltaBundler/traverseDependencies.js:412:26
    at Array.reduce (<anonymous>)
    at resolveDependencies (/home/ghost/Documents/BlueWallet/node_modules/metro/src/DeltaBundler/traverseDependencies.js:411:33)
    at processModule (/home/ghost/Documents/BlueWallet/node_modules/metro/src/DeltaBundler/traverseDependencies.js:140:31)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async addDependency (/home/ghost/Documents/BlueWallet/node_modules/metro/src/DeltaBundler/traverseDependencies.js:230:18)
info Run CLI with --verbose flag for more details.

> Task :app:bundleReleaseJsAndAssets FAILED

FAILURE: Build failed with an exception.

image

I looked through closed issues, and saw mentions of webpack & asyncWebAssembly for ReactNative, but iirc RN switched its bundler to Metro some time ago.

Relevant PR: BlueWallet/BlueWallet#5048

How do we get the recid / v from a signature, or produce a signature with one?

The bitcoinjs-message library use the standard secp256k1 library, which returns R/S/V as parameters as part of the signature.

However, the tiny-secp256k1 library, used in bitcoinjs, doesn't appear to return the V or Recid from signatures. This creates some issues when passing bitcoinjs Signers into bitcoinjs-message, as bitcoinjs-message needs a recovery param (I presume this is the Recid).

If there a cryptographic method by which we can use this library to get a V/Recid value from a signature + hash, or to get the V/Recid whilst performing a signing?

Thanks!

`WebAssembly.Compile` is disallowed on the main thread, if the buffer size is larger than 4KB.

Currently the WebAssembly part is loaded synchronously:

const mod = new WebAssembly.Module(binary);
const instance = new WebAssembly.Instance(mod, imports);

This results in the following error:
WebAssembly.Compile is disallowed on the main thread, if the buffer size is larger than 4KB. Use WebAssembly.compile, or compile on a worker thread.

However the async version of the methods cannot be run on the top-level file AFAIK.
Any ideas how to fix this?

Cannot run react-app example

After running npm install, i run npm start, but it is not possible to run the react app due to missing file. The file ../../lib/index.js is not found.

vic@vic-Lenovo-Legion-5-15ARH05:~/workspace/tiny-secp256k1/examples/react-app$ npm start

[email protected] start /home/vic/workspace/tiny-secp256k1/examples/react-app
webpack serve

[webpack-dev-server] Project is running at:
[webpack-dev-server] Loopback: http://localhost:8080/
[webpack-dev-server] On Your Network (IPv4): http://192.168.100.5:8080/
[webpack-dev-server] On Your Network (IPv6): http://[fe80::7557:b6b6:ad8e:a85c]:8080/
[webpack-dev-server] Content not from webpack is served from '/home/vic/workspace/tiny-secp256k1/examples/react-app/dist' directory
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
asset bundle.js 2.25 MiB [emitted] (name: main)
orphan modules 3.62 MiB [orphan] 5860 modules
runtime modules 27.1 KiB 13 modules
cacheable modules 1.79 MiB 170 modules

ERROR in ../random-in-node/index.js 2:0-48
Module not found: Error: Can't resolve '../../lib/index.js' in '/home/vic/workspace/tiny-secp256k1/examples/random-in-node'
resolve '../../lib/index.js' in '/home/vic/workspace/tiny-secp256k1/examples/random-in-node'
using description file: /home/vic/workspace/tiny-secp256k1/examples/random-in-node/package.json (relative path: .)
using description file: /home/vic/workspace/tiny-secp256k1/package.json (relative path: ./lib/index.js)
/home/vic/workspace/tiny-secp256k1/lib/index.js doesn't exist
@ ./index.js 9:0-54 152:17-25

ERROR in ./index.js 8:0-49
Module not found: Error: Can't resolve '../../lib/index.js' in '/home/vic/workspace/tiny-secp256k1/examples/react-app'
resolve '../../lib/index.js' in '/home/vic/workspace/tiny-secp256k1/examples/react-app'
using description file: /home/vic/workspace/tiny-secp256k1/examples/react-app/package.json (relative path: .)
Field 'browser' doesn't contain a valid alias configuration
using description file: /home/vic/workspace/tiny-secp256k1/package.json (relative path: ./lib/index.js)
/home/vic/workspace/tiny-secp256k1/lib/index.js doesn't exist

webpack 5.58.2 compiled with 2 errors in 4450 ms

[NOTE] Regarding packaging trust

Github Actions CI is building the packages on npm

  • Starting with recent versions (I think v2.2.0)
  • Github Actions CI logs for the tagged commit will show the npm pack command output.
  • There you can verify the package hash etc. matches the integrity hash on your lock file.
  • I have not automated the publishing. I will be downloading the artifact from Github, then publishing it directly from my local PC. (verifying the hash before entering my 2FA)

I want to use this in react-native app but it failed with this error

This is the code snippet I used tiny-secp256k1

스크린샷 2022-04-25 오후 7 22 26


When I run this app, below error occurred.

error: Error: While trying to resolve module tiny-secp256k1 from file /Users/eunjilim/AssetController.ts, the package /Users/app/node_modules/tiny-secp256k1/package.json was successfully found. However, this package itself specifies a main module field that could not be resolved (/Users/app/node_modules/tiny-secp256k1/lib/cjs/index.cjs. Indeed, none of these files exist:

  • /Users/app/node_modules/tiny-secp256k1/lib/cjs/index.cjs(.native|.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.svg|.native.svg|.svg)
  • /Users/app/node_modules/tiny-secp256k1/lib/cjs/index.cjs/index(.native|.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.svg|.native.svg|.svg)
    at DependencyGraph.resolveDependency (/Users/app/node_modules/metro/src/node-haste/DependencyGraph.js:243:17)
    at Object.resolve (/Users/app/node_modules/metro/src/lib/transformHelpers.js:129:24)
    at resolve (/Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:396:33)
    at /Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:412:26
    at Array.reduce ()
    at resolveDependencies (/Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:411:33)
    at processModule (/Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:140:31)
    at async addDependency (/Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:230:18)
    at async Promise.all (index 5)
    at async processModule (/Users/app/node_modules/metro/src/DeltaBundler/traverseDependencies.js:198:5)

and when try to run application this warning show up

스크린샷 2022-04-25 오후 7 00 38

Pre-compile native binaries

Is there a way to pre-compile the native binaries for use in node builds? The deployment service I'm trying to use (zeit/now.2) doesn't have a C++ compiler/builder and this package can't compile. I'm new to node C++ addons and looking into it, but would appreciate any *pointers.

Thank you

react app example fails to compile

Tried locally, and in a fresh node docker container. Both produce the following:

root@6ece77020054:/tiny-secp256k1/examples/react-app# npm install
npm WARN deprecated [email protected]: Please see https://github.com/lydell/urix#deprecated
npm WARN deprecated [email protected]: https://github.com/lydell/resolve-url#deprecated
npm WARN deprecated [email protected]: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies.

added 643 packages, and audited 644 packages in 12s

34 packages are looking for funding
  run `npm fund` for details

28 vulnerabilities (10 moderate, 18 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.
npm notice 
npm notice New minor version of npm available! 8.0.0 -> 8.1.0
npm notice Changelog: https://github.com/npm/cli/releases/tag/v8.1.0
npm notice Run npm install -g [email protected] to update!
npm notice 
root@6ece77020054:/tiny-secp256k1/examples/react-app# npm start

> [email protected] start
> webpack serve

ℹ 「wds」: Project is running at http://localhost:8080/
ℹ 「wds」: webpack output is served from /
ℹ 「wds」: Content not from webpack is served from /tiny-secp256k1/examples/react-app/dist
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db

Why you should do it regularly:
https://github.com/browserslist/browserslist#browsers-data-updating
✖ 「wdm」: asset bundle.js 3.42 MiB [emitted] (name: main)
orphan modules 3.6 MiB [orphan] 5855 modules
runtime modules 1.25 KiB 6 modules
built modules 2.92 MiB [built]
  modules by path ./node_modules/ 2.88 MiB
    javascript modules 2.87 MiB 292 modules
    json modules 12.7 KiB
      modules by path ./node_modules/browserify-sign/browser/*.json 2.23 KiB
        ./node_modules/browserify-sign/browser/algorithms.json 2.07 KiB [built] [code generated]
        ./node_modules/browserify-sign/browser/curves.json 162 bytes [built] [code generated]
      4 modules
  optional modules 120 bytes [optional] 8 modules
  ./index.js 31.9 KiB [built] [code generated]
  ../random-in-node/index.js 1.98 KiB [built] [code generated]
  util (ignored) 15 bytes [built] [code generated]
  util (ignored) 15 bytes [built] [code generated]

ERROR in ../random-in-node/index.js 2:0-48
Module not found: Error: Can't resolve '../../lib/index.js' in '/tiny-secp256k1/examples/random-in-node'
 @ ./index.js 9:0-54 147:17-25

ERROR in ./index.js 3:0-32
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }

ERROR in ./index.js 8:0-49
Module not found: Error: Can't resolve '../../lib/index.js' in '/tiny-secp256k1/examples/react-app'

ERROR in ./node_modules/browserify-sign/node_modules/safe-buffer/index.js 3:13-30
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/browserify-sign/node_modules/safe-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/browserify-sign/browser/index.js 1:13-42
 @ ./node_modules/crypto-browserify/index.js 39:11-37
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/hash-base/node_modules/safe-buffer/index.js 3:13-30
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/hash-base/node_modules/safe-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/hash-base/index.js 2:13-42
 @ ./node_modules/md5.js/index.js 3:15-35
 @ ./node_modules/create-hash/browser.js 3:10-27
 @ ./node_modules/crypto-browserify/index.js 4:21-58
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/readable-stream/lib/_stream_readable.js 46:13-37
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/readable-stream/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/readable-stream/readable-browser.js 1:10-63
 @ ./node_modules/browserify-sign/browser/index.js 3:13-39
 @ ./node_modules/crypto-browserify/index.js 39:11-37
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/readable-stream/lib/_stream_writable.js 70:13-37
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/readable-stream/lib'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/readable-stream/readable-browser.js 4:0-55
 @ ./node_modules/browserify-sign/browser/index.js 3:13-39
 @ ./node_modules/crypto-browserify/index.js 39:11-37
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/readable-stream/lib/internal/streams/buffer_list.js 15:15-32
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/readable-stream/lib/internal/streams'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/readable-stream/lib/_stream_readable.js 72:17-58
 @ ./node_modules/readable-stream/readable-browser.js 1:10-63
 @ ./node_modules/browserify-sign/browser/index.js 3:13-39
 @ ./node_modules/crypto-browserify/index.js 39:11-37
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/ripemd160/index.js 2:13-37
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/ripemd160'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/create-hmac/browser.js 7:16-36
 @ ./node_modules/crypto-browserify/index.js 5:21-58
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/safe-buffer/index.js 2:13-30
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/safe-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/create-hmac/browser.js 5:13-42
 @ ./node_modules/crypto-browserify/index.js 5:21-58
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/safer-buffer/safer.js 5:13-30
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/safer-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/asn1.js/lib/asn1/base/buffer.js 5:15-45
 @ ./node_modules/asn1.js/lib/asn1/base/index.js 6:21-54 7:21-54
 @ ./node_modules/asn1.js/lib/asn1.js 8:12-34
 @ ./node_modules/parse-asn1/asn1.js 5:11-29
 @ ./node_modules/parse-asn1/index.js 1:11-28
 @ ./node_modules/browserify-sign/browser/sign.js 7:16-37
 @ ./node_modules/browserify-sign/browser/index.js 5:11-28
 @ ./node_modules/crypto-browserify/index.js 39:11-37
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

ERROR in ./node_modules/string_decoder/node_modules/safe-buffer/index.js 3:13-30
Module not found: Error: Can't resolve 'buffer' in '/tiny-secp256k1/examples/react-app/node_modules/string_decoder/node_modules/safe-buffer'

BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.

If you want to include a polyfill, you need to:
	- add a fallback 'resolve.fallback: { "buffer": require.resolve("buffer/") }'
	- install 'buffer'
If you don't want to include a polyfill, you can use an empty module like this:
	resolve.fallback: { "buffer": false }
 @ ./node_modules/string_decoder/lib/string_decoder.js 26:13-42
 @ ./node_modules/cipher-base/index.js 3:20-59
 @ ./node_modules/create-hmac/browser.js 4:11-33
 @ ./node_modules/crypto-browserify/index.js 5:21-58
 @ ../random-in-node/index.js 1:0-37 12:34-45 13:35-46 14:32-43 21:28-39 23:30-41
 @ ./index.js 9:0-54 147:17-25

12 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.27.2 compiled with 12 errors in 6123 ms
ℹ 「wdm」: Failed to compile.

Warnings on install

installing on OSX 10.14.6 (Mojave) I get the following warnings. The "unused function" warnings I guess are just a matter of cleaning up the code but the integer comparisons I would think are of concern. I'm guessing that's a platform dependent thing. is there some way to tweak the meaning of "int" to "unsigned long"? this should get cleaned up no?

~/dev $ npm i bitcoinjs-lib

[email protected] install /Users/ekkis/dev/node_modules/tiny-secp256k1
npm run build || echo "secp256k1 bindings compilation fail. Pure JS implementation will be used."

[email protected] build /Users/ekkis/dev/node_modules/tiny-secp256k1
node-gyp rebuild

CXX(target) Release/obj.target/secp256k1/native/addon.o
../native/addon.cpp:240:2: warning: ignoring return value of function declared with 'warn_unused_result'
attribute [-Wunused-result]
secp256k1_ec_privkey_negate(context, tweak_negated); // returns 1 always
^~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
../native/addon.cpp:80:21: warning: comparison of integers of different signs: 'int' and 'unsigned long'
[-Wsign-compare]
if (info.Length() <= index) return __isPointCompressed(p) ? SECP256K1_EC_COMPRESSED : S...
~~~~~~~~~~~~~ ^ ~~~~~
../native/addon.cpp:142:21: note: in instantiation of function template specialization '(anonymous
namespace)::assumeCompression<2, Nan::FunctionCallbackInfov8::Value, v8::Localv8::Object >' requested
here
const auto flags = assumeCompression<2>(info, pA);
^
../native/addon.cpp:80:21: warning: comparison of integers of different signs: 'int' and 'unsigned long'
[-Wsign-compare]
if (info.Length() <= index) return __isPointCompressed(p) ? SECP256K1_EC_COMPRESSED : S...
~~~~~~~~~~~~~ ^ ~~~~~
../native/addon.cpp:174:21: note: in instantiation of function template specialization '(anonymous
namespace)::assumeCompression<1, Nan::FunctionCallbackInfov8::Value, v8::Localv8::Object >' requested
here
const auto flags = assumeCompression<1>(info, p);
^
../native/addon.cpp:87:21: warning: comparison of integers of different signs: 'int' and 'unsigned long'
[-Wsign-compare]
if (info.Length() <= index) return SECP256K1_EC_COMPRESSED;
~~~~~~~~~~~~~ ^ ~~~~~
../native/addon.cpp:189:21: note: in instantiation of function template specialization '(anonymous
namespace)::assumeCompression<1, Nan::FunctionCallbackInfov8::Value >' requested here
const auto flags = assumeCompression<1>(info);
^
../native/addon.cpp:21:32: warning: unused variable 'ZERO' [-Wunused-const-variable]
const std::array<uint8_t, 32> ZERO = {};
^
5 warnings generated.
CC(target) Release/obj.target/secp256k1/native/secp256k1/src/secp256k1.o
In file included from ../native/secp256k1/src/secp256k1.c:13:
../native/secp256k1/src/group_impl.h:686:12: warning: unused function 'secp256k1_gej_has_quad_y_var'
[-Wunused-function]
static int secp256k1_gej_has_quad_y_var(const secp256k1_gej *a) {
^
../native/secp256k1/src/group_impl.h:113:13: warning: unused function 'secp256k1_ge_set_gej_var'
[-Wunused-function]
static void secp256k1_ge_set_gej_var(secp256k1_ge *r, secp256k1_gej *a) {
^
../native/secp256k1/src/group_impl.h:267:12: warning: unused function 'secp256k1_gej_is_valid_var'
[-Wunused-function]
static int secp256k1_gej_is_valid_var(const secp256k1_gej *a) {
^
In file included from ../native/secp256k1/src/secp256k1.c:15:
../native/secp256k1/src/ecmult_const_impl.h:123:13: warning: unused function 'secp256k1_ecmult_const'
[-Wunused-function]
static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *scalar) {
^
4 warnings generated.
SOLINK_MODULE(target) Release/secp256k1.node
npm WARN [email protected] No repository field.

  • [email protected]
    added 36 packages from 47 contributors and audited 328 packages in 8.87s
    found 0 vulnerabilities

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.