Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to WASM and Rust Node.js addon (N-API). #53

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
build/
coverage/
node_modules/
tests/bundle.js
/coverage
/node_modules
/target

lib/secp256k1.wasm
package-lock.json
tests/bundle.js
3 changes: 0 additions & 3 deletions .gitmodules

This file was deleted.

2 changes: 0 additions & 2 deletions .npmignore

This file was deleted.

1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
9 changes: 0 additions & 9 deletions .travis.yml

This file was deleted.

25 changes: 25 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[workspace]
members = [
"secp256k1-wasm",
]

[profile.release]
lto = true
codegen-units = 1
22 changes: 22 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
build-wasm-cp = cp -f target/wasm32-unknown-unknown/$(1)/tiny_secp256k1_wasm.wasm lib/secp256k1.wasm

build-wasm:
cargo build --target wasm32-unknown-unknown --release
$(call build-wasm-cp,release)
wasm-opt -O4 --output lib/secp256k1.wasm lib/secp256k1.wasm

build-wasm-debug:
cargo build --target wasm32-unknown-unknown
$(call build-wasm-cp,debug)

format:
cargo-fmt
npx prettier -w .

lint:
cargo fmt -- --check
cargo clippy
npx prettier -c .

test:
npx tape tests/index.js | npx tap-difflet -p
117 changes: 69 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
# tiny-secp256k1

[![Build Status](https://travis-ci.org/bitcoinjs/tiny-secp256k1.png?branch=master)](https://travis-ci.org/bitcoinjs/tiny-secp256k1)
[![NPM](https://img.shields.io/npm/v/tiny-secp256k1.svg)](https://www.npmjs.org/package/tiny-secp256k1)
[![js-standard-style](https://cdn.rawgit.com/feross/standard/master/badge.svg)](https://github.com/feross/standard)

This library is under development, and, like the [secp256k1](https://github.com/bitcoin-core/secp256k1) C library it depends on, this is a research effort to determine an optimal API for end-users of the bitcoinjs ecosystem.
This library is under development, and, like the [secp256k1](https://github.com/bitcoin-core/secp256k1) C library it depends on, this is a research effort to determine an optimal API for end-users of the bitcoinjs ecosystem.

## Installation

### npm

``` bash
```bash
npm install tiny-secp256k1
```

Expand All @@ -19,156 +20,176 @@ npm install tiny-secp256k1
yarn add tiny-secp256k1
```

If you are having problems, please read the guide at [secp256k1-node](https://github.com/cryptocoinjs/secp256k1-node#installation), as the build instructions should be exactly the same (and this module is a direct derivation).


## Documentation

### isPoint (A)
``` haskell

```haskell
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]`

- `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)
``` haskell

```haskell
isPointCompressed :: Buffer -> Bool
```
Returns `false` if the signature is **not** compressed.

Returns `false` if the signature is **not** compressed.

### isPrivate (d)
``` haskell

```haskell
isPrivate :: Buffer -> Bool
```

Returns `false` if
* `d` is not 256-bit, or
* `d` is not in `[1..order - 1]`

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

### pointAdd (A, B[, compressed])
``` haskell

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

Returns `null` if result is at infinity.

##### Throws:
* `Expected Point` if `!isPoint(A)`
* `Expected Point` if `!isPoint(B)`

- `Expected Point` if `!isPoint(A)`
- `Expected Point` if `!isPoint(B)`

### pointAddScalar (A, tweak[, compressed])
``` haskell

```haskell
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]`

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

### pointCompress (A, compressed)
``` haskell

```haskell
pointCompress :: Buffer -> Bool -> Buffer
```

##### Throws:
* `Expected Point` if `!isPoint(A)`

- `Expected Point` if `!isPoint(A)`

### pointFromScalar (d[, compressed])
``` haskell

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

Returns `null` if result is at infinity.

##### Throws:
* `Expected Private` if `!isPrivate(d)`

- `Expected Private` if `!isPrivate(d)`

### pointMultiply (A, tweak[, compressed])
``` haskell

```haskell
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]`

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

### privateAdd (d, tweak)
``` haskell

```haskell
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]`

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

### privateSub (d, tweak)
``` haskell

```haskell
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]`

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

### sign (h, d)
``` haskell

```haskell
sign :: Buffer -> Buffer -> Buffer
```

Returns normalized signatures, each of (r, s) values are guaranteed to less than `order / 2`.
Uses RFC6979.

##### Throws:
* `Expected Private` if `!isPrivate(d)`
* `Expected Scalar` if `h` is not 256-bit

- `Expected Private` if `!isPrivate(d)`
- `Expected Scalar` if `h` is not 256-bit

### signWithEntropy (h, d, e)
``` haskell

```haskell
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

- `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])
``` haskell

```haskell
verify :: Buffer -> Buffer -> Buffer -> Bool
```
Returns `false` if any of (r, s) values are equal to `0`, or if the signature is rejected.

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

- `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 is a partially derived work of https://github.com/cryptocoinjs/secp256k1-node, specifically [this commit](https://github.com/bitcoinjs/tiny-secp256k1/commit/03a1d0ab5d61dc05ab42a7e884cf37d628a10724).

This library uses the native library [secp256k1](https://github.com/bitcoin-core/secp256k1) by the bitcoin-core developers, including derivatives of its tests and test vectors.

This library uses the native library [secp256k1](https://github.com/bitcoin-core/secp256k1) by the bitcoin-core developers through Rust crate [secp256k1-sys](https://crates.io/crates/secp256k1-sys), including derivatives of its tests and test vectors.

# LICENSE [MIT](LICENSE)
Loading