Skip to content

Commit be75748

Browse files
committed
chore: update docs
1 parent fca30ba commit be75748

File tree

1 file changed

+96
-67
lines changed

1 file changed

+96
-67
lines changed

README.md

Lines changed: 96 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ JavaScript Elliptic curve cryptography library for both browserify and node.
1010

1111
## Motivation
1212

13-
There is currently no any isomorphic ECC library which provides ECDSA, ECDH and ECIES for both Node.js and Browser and uses the fastest implementation available (e.g. [secp256k1-node](https://github.com/wanderer/secp256k1-node) is much faster than other libraries but can be used only on Node.js). So `eccrypto` is an attempt to create one.
13+
- ECDSA (sign/verify)
14+
- ECDH (key agreement)
15+
- ECIES (encrypt/decrypt)
16+
- secp256k1 curve support
17+
- Compressed and uncompressed public key support
18+
- Works in both Node.js and browsers
19+
- Uses `Uint8Array` for all binary data
1420

1521
## Implementation details
1622

17-
With the help of browserify `eccrypto` provides different implementations for Browser and Node.js with the same API. Because WebCryptoAPI defines asynchronous promise-driven API, implementation for Node needs to use promises too.
23+
This library uses [`@noble/curves`](https://github.com/paulmillr/noble-curves) for elliptic curve operations, which provides:
1824

1925
- Use Node.js crypto module/library bindings where possible
2026
- Use WebCryptoAPI where possible
@@ -26,92 +32,115 @@ With the help of browserify `eccrypto` provides different implementations for Br
2632

2733
#### crypto
2834

29-
ECDH only works in Node 0.11+ (see https://github.com/joyent/node/pull/5854), ECDSA only supports keys in PEM format (see https://github.com/joyent/node/issues/6904) and ECIES is not supported at all.
35+
```bash
36+
npm install @toruslabs/eccrypto
37+
```
3038

3139
#### WebCryptoAPI
3240

3341
ECDSA and ECDH are supported in Chrome [only on Windows](https://sites.google.com/a/chromium.org/dev/blink/webcrypto#TOC-Supported-algorithms-as-of-Chrome-41-) (see also [bug 338883](https://code.google.com/p/chromium/issues/detail?id=338883)), aren't supported by Firefox (fixed only in 36.0+, see [bug 1034854](https://bugzilla.mozilla.org/show_bug.cgi?id=1034854); see also [feature matrix](https://docs.google.com/spreadsheet/ccc?key=0AiAcidBZRLxndE9LWEs2R1oxZ0xidUVoU3FQbFFobkE#gid=1)) and ECIES is not defined at all in WebCryptoAPI draft. Also WebCryptoAPI [currently defines](http://www.w3.org/TR/WebCryptoAPI/#EcKeyGenParams-dictionary) only curves recommended by NIST meaning that secp256k1 (K-256) curve is not supported (see also: [[1]](http://lists.w3.org/Archives/Public/public-webcrypto-comments/2013Dec/0001.html), [[2]](https://bugzilla.mozilla.org/show_bug.cgi?id=1051509)).
3442

35-
So we use [seck256k1](https://www.npmjs.com/package/secp256k1) library in Node for ECDSA, [elliptic](https://www.npmjs.com/package/elliptic) in Browser for ECDSA and ECDH and implement ECIES manually with the help of native crypto API.
43+
```ts
44+
import * as eccrypto from "@toruslabs/eccrypto";
3645

37-
## Possible future goals
46+
// Generate a new random 32-byte private key
47+
const privateKey = eccrypto.generatePrivate();
3848

39-
- Support other curves/KDF/MAC/symmetric encryption schemes
49+
// Get the corresponding public key (65 bytes uncompressed)
50+
const publicKey = eccrypto.getPublic(privateKey);
4051

41-
## Usage
52+
// Or get compressed public key (33 bytes)
53+
const compressedPublicKey = eccrypto.getPublicCompressed(privateKey);
4254

43-
### ECDSA
55+
// Message must be 32 bytes or less (typically a hash)
56+
const msgHash = new Uint8Array(32); // Your message hash here
4457

45-
```js
46-
var crypto = require("crypto");
47-
var eccrypto = require("eccrypto");
58+
// Sign the message
59+
const signature = await eccrypto.sign(privateKey, msgHash);
60+
console.log("Signature (DER format):", signature);
4861

49-
// A new random 32-byte private key.
50-
var privateKey = eccrypto.generatePrivate();
51-
// Corresponding uncompressed (65-byte) public key.
52-
var publicKey = eccrypto.getPublic(privateKey);
62+
// Verify the signature
63+
try {
64+
await eccrypto.verify(publicKey, msgHash, signature);
65+
console.log("Signature is valid");
66+
} catch (e) {
67+
console.log("Signature is invalid");
68+
}
69+
```
5370

54-
var str = "message to sign";
55-
// Always hash you message to sign!
56-
var msg = crypto.createHash("sha256").update(str).digest();
71+
### ECDH (Key Agreement)
5772

58-
eccrypto.sign(privateKey, msg).then(function (sig) {
59-
console.log("Signature in DER format:", sig);
60-
eccrypto
61-
.verify(publicKey, msg, sig)
62-
.then(function () {
63-
console.log("Signature is OK");
64-
})
65-
.catch(function () {
66-
console.log("Signature is BAD");
67-
});
68-
});
69-
```
73+
```ts
74+
import * as eccrypto from "@toruslabs/eccrypto";
7075

71-
### ECDH
76+
const privateKeyA = eccrypto.generatePrivate();
77+
const publicKeyA = eccrypto.getPublic(privateKeyA);
7278

73-
```js
74-
var eccrypto = require("eccrypto");
79+
const privateKeyB = eccrypto.generatePrivate();
80+
const publicKeyB = eccrypto.getPublic(privateKeyB);
7581

76-
var privateKeyA = eccrypto.generatePrivate();
77-
var publicKeyA = eccrypto.getPublic(privateKeyA);
78-
var privateKeyB = eccrypto.generatePrivate();
79-
var publicKeyB = eccrypto.getPublic(privateKeyB);
82+
// Both parties derive the same shared secret
83+
const sharedSecretA = await eccrypto.derive(privateKeyA, publicKeyB);
84+
const sharedSecretB = await eccrypto.derive(privateKeyB, publicKeyA);
8085

81-
eccrypto.derive(privateKeyA, publicKeyB).then(function (sharedKey1) {
82-
eccrypto.derive(privateKeyB, publicKeyA).then(function (sharedKey2) {
83-
console.log("Both shared keys are equal:", sharedKey1, sharedKey2);
84-
});
85-
});
86+
// sharedSecretA and sharedSecretB are equal
87+
console.log("Shared secrets match:", sharedSecretA.toString() === sharedSecretB.toString());
8688
```
8789

88-
### ECIES
89-
90-
```js
91-
var eccrypto = require("eccrypto");
92-
93-
var privateKeyA = eccrypto.generatePrivate();
94-
var publicKeyA = eccrypto.getPublic(privateKeyA);
95-
var privateKeyB = eccrypto.generatePrivate();
96-
var publicKeyB = eccrypto.getPublic(privateKeyB);
97-
98-
// Encrypting the message for B.
99-
eccrypto.encrypt(publicKeyB, Buffer.from("msg to b")).then(function (encrypted) {
100-
// B decrypting the message.
101-
eccrypto.decrypt(privateKeyB, encrypted).then(function (plaintext) {
102-
console.log("Message to part B:", plaintext.toString());
103-
});
104-
});
105-
106-
// Encrypting the message for A.
107-
eccrypto.encrypt(publicKeyA, Buffer.from("msg to a")).then(function (encrypted) {
108-
// A decrypting the message.
109-
eccrypto.decrypt(privateKeyA, encrypted).then(function (plaintext) {
110-
console.log("Message to part A:", plaintext.toString());
111-
});
112-
});
90+
### ECIES (Encrypt/Decrypt)
91+
92+
```ts
93+
import * as eccrypto from "@toruslabs/eccrypto";
94+
95+
const privateKeyA = eccrypto.generatePrivate();
96+
const publicKeyA = eccrypto.getPublic(privateKeyA);
97+
98+
const privateKeyB = eccrypto.generatePrivate();
99+
const publicKeyB = eccrypto.getPublic(privateKeyB);
100+
101+
// Encrypt a message for B
102+
const message = new TextEncoder().encode("Hello, World!");
103+
const encrypted = await eccrypto.encrypt(publicKeyB, message);
104+
105+
// B decrypts the message
106+
const decrypted = await eccrypto.decrypt(privateKeyB, encrypted);
107+
console.log("Decrypted:", new TextDecoder().decode(decrypted));
113108
```
114109

110+
## API
111+
112+
### `generatePrivate(): Uint8Array`
113+
114+
Generate a new random 32-byte private key.
115+
116+
### `getPublic(privateKey: Uint8Array): Uint8Array`
117+
118+
Get the 65-byte uncompressed public key from a private key.
119+
120+
### `getPublicCompressed(privateKey: Uint8Array): Uint8Array`
121+
122+
Get the 33-byte compressed public key from a private key.
123+
124+
### `sign(privateKey: Uint8Array, msg: Uint8Array): Promise<Uint8Array>`
125+
126+
Sign a message (max 32 bytes) with a private key. Returns DER-encoded signature.
127+
128+
### `verify(publicKey: Uint8Array, msg: Uint8Array, sig: Uint8Array): Promise<null>`
129+
130+
Verify a signature. Throws an error if the signature is invalid.
131+
132+
### `derive(privateKey: Uint8Array, publicKey: Uint8Array): Promise<Uint8Array>`
133+
134+
Derive a shared secret using ECDH.
135+
136+
### `encrypt(publicKey: Uint8Array, msg: Uint8Array, opts?): Promise<Ecies>`
137+
138+
Encrypt a message using ECIES. Returns an object with `iv`, `ephemPublicKey`, `ciphertext`, and `mac`.
139+
140+
### `decrypt(privateKey: Uint8Array, opts: Ecies): Promise<Uint8Array>`
141+
142+
Decrypt an ECIES encrypted message.
143+
115144
## License
116145

117146
eccrypto - JavaScript Elliptic curve cryptography library

0 commit comments

Comments
 (0)