Skip to content

Commit

Permalink
Support curve25519 tentatively (#732)
Browse files Browse the repository at this point in the history
  • Loading branch information
kigawas authored Sep 3, 2023
1 parent b8634ae commit b6ee108
Show file tree
Hide file tree
Showing 19 changed files with 427 additions and 206 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish
name: CD

on:
release:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Build
name: CI

on:
push:
Expand Down
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

## 0.4.1 ~ 0.4.5

- Support curve25519 (x25519 and ed25519) tentatively
- Revamp browser compatibility
- Export config
- Fix symmetric encryption internal types
Expand All @@ -12,8 +13,8 @@

## 0.4.0

- Change secp256k1 library to [noble-curves](https://github.com/paulmillr/noble-curves), which is [audited](https://github.com/paulmillr/noble-curves/tree/main/audit)
- Change hash library to [noble-hashes](https://github.com/paulmillr/noble-hashes)
- Change secp256k1 library to audited [noble-curves](https://github.com/paulmillr/noble-curves)
- Change hash library to audited [noble-hashes](https://github.com/paulmillr/noble-hashes)
- Change test library to [jest](https://jestjs.io/)
- Bump dependencies
- Drop Node 14 support
Expand Down
57 changes: 44 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
[![CI](https://img.shields.io/github/actions/workflow/status/ecies/js/ci.yml)](https://github.com/ecies/js/actions)
[![Codecov](https://img.shields.io/codecov/c/github/ecies/js.svg)](https://codecov.io/gh/ecies/js)

Elliptic Curve Integrated Encryption Scheme for secp256k1 in TypeScript.
Elliptic Curve Integrated Encryption Scheme for secp256k1/curve25519 in TypeScript.

This is the JavaScript/TypeScript version of [eciespy](https://github.com/ecies/py) with a built-in class-like secp256k1 [API](#privatekey), you may go there for detailed documentation and learn the mechanism under the hood.
This is the JavaScript/TypeScript version of [eciespy](https://github.com/ecies/py) with a built-in class-like secp256k1/curve25519 [API](#privatekey), you may go there for detailed documentation and learn the mechanism under the hood.

If you want a WASM version to run directly in modern browsers or on some blockchains, check [`ecies-wasm`](https://github.com/ecies/rs-wasm).

Expand All @@ -30,13 +30,15 @@ Run the code below with `npx ts-node`.
'hello world🌍'
```

See [Configuration](#configuration) to control with more granularity.

## API

### `encrypt(receiverRawPK: string | Uint8Array, msg: Uint8Array): Buffer`

Parameters:

- **receiverRawPK** - Receiver's secp256k1 public key, hex string or buffer
- **receiverRawPK** - Receiver's public key, hex string or buffer
- **msg** - Data to encrypt

Returns: **Buffer**
Expand All @@ -45,7 +47,7 @@ Returns: **Buffer**

Parameters:

- **receiverRawSK** - Receiver's secp256k1 private key, hex string or buffer
- **receiverRawSK** - Receiver's private key, hex string or buffer
- **msg** - Data to decrypt

Returns: **Buffer**
Expand All @@ -66,8 +68,9 @@ equals(other: PrivateKey): boolean;
- Properties

```typescript
readonly secret: Buffer;
get secret(): Buffer;
readonly publicKey: PublicKey;
private readonly data;
```

### `PublicKey`
Expand All @@ -76,7 +79,7 @@ readonly publicKey: PublicKey;

```typescript
static fromHex(hex: string): PublicKey;
constructor(buffer: Uint8Array);
constructor(data: Uint8Array);
toHex(compressed?: boolean): string;
decapsulate(sk: PrivateKey): Uint8Array;
equals(other: PublicKey): boolean;
Expand All @@ -85,19 +88,30 @@ equals(other: PublicKey): boolean;
- Properties

```typescript
readonly uncompressed: Buffer;
readonly compressed: Buffer;
get uncompressed(): Buffer;
get compressed(): Buffer;
private readonly data;
```

## Configuration

Ephemeral key format in the payload and shared key in the key derivation can be configured as compressed or uncompressed format.
Following configurations are available.

- Elliptic curve: secp256k1 or curve25519 (x25519/ed25519)
- Ephemeral key format in the payload: compressed or uncompressed (only for secp256k1)
- Shared elliptic curve key format in the key derivation: compressed or uncompressed (only for secp256k1)
- Symmetric cipher algorithm: AES-256-GCM or XChaCha20-Poly1305
- Symmetric nonce length: 12 or 16 bytes (only for AES-256-GCM)

For compatibility, make sure different applications share the same configuration.

```ts
export type EllipticCurve = "secp256k1" | "x25519" | "ed25519";
export type SymmetricAlgorithm = "aes-256-gcm" | "xchacha20";
export type NonceLength = 12 | 16; // bytes. Only for aes-256-gcm
export type NonceLength = 12 | 16;

class Config {
ellipticCurve: EllipticCurve = "secp256k1";
isEphemeralKeyCompressed: boolean = false;
isHkdfKeyCompressed: boolean = false;
symmetricAlgorithm: SymmetricAlgorithm = "aes-256-gcm";
Expand All @@ -107,15 +121,32 @@ class Config {
export const ECIES_CONFIG = new Config();
```

For example, if you set `isEphemeralKeyCompressed = true`, the payload would be like: `33 Bytes + AES` instead of `65 Bytes + AES`.
### Elliptic curve configuration

If you set `ellipticCurve = "x25519"` or `ellipticCurve = "ed25519"`, x25519 (key exchange function on curve25519) or ed25519 (signature algorithm on curve25519) will be used for key exchange instead of secp256k1.

In this case, the payload would always be: `32 Bytes + AES` regardless of `isEphemeralKeyCompressed`.

> If you don't know how to choose between x25519 and ed25519, just use x25519 for efficiency.
### Secp256k1-specific configuration

If you set `isEphemeralKeyCompressed = true`, the payload would be: `33 Bytes + AES` instead of `65 Bytes + AES`.

If you set `isHkdfKeyCompressed = true`, the hkdf key would be derived from `ephemeral public key (compressed) + shared public key (compressed)` instead of `ephemeral public key (uncompressed) + shared public key (uncompressed)`.

### Symmetric cipher configuration

If you set `symmetricAlgorithm = "xchacha20"`, plaintext data will encrypted with XChaCha20-Poly1305.

If you set `symmetricNonceLength = 12`, then the nonce of aes-256-gcm would be 12 bytes. XChaCha20-Poly1305's nonce is always 24 bytes.
If you set `symmetricNonceLength = 12`, the nonce of AES-256-GCM would be 12 bytes. XChaCha20-Poly1305's nonce is always 24 bytes.

For compatibility, make sure different applications share the same configuration.
## Security Audit

Following dependencies are audited:

- [noble-curves](https://github.com/paulmillr/noble-curves/tree/main/audit)
- [noble-hashes](https://github.com/paulmillr/noble-hashes#security)

## Changelog

Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,13 @@
"test": "jest"
},
"dependencies": {
"@noble/ciphers": "^0.2.0",
"@noble/ciphers": "^0.3.0",
"@noble/curves": "^1.2.0",
"@noble/hashes": "^1.3.2"
},
"devDependencies": {
"@types/jest": "^29.5.4",
"@types/node": "^20.5.6",
"@types/node": "^20.5.8",
"@types/node-fetch": "^2.6.4",
"https-proxy-agent": "^7.0.1",
"jest": "^29.6.4",
Expand Down
Loading

0 comments on commit b6ee108

Please sign in to comment.