# ecies-lite

A lightweight ECIES tool implemented in pure Node.JS

## Motivation

First of all, `eccrypto` is a great tool that supports many EC crypto functions. However, it was developed years ago, and the crypto library has evolved a lot since then. It seems that ECIES (Elliptic Curve Integrated Encryption Scheme) can be implemented in pure Node.JS, so I re-implemented it with the help of the latest crypto module released with Node.JS 10.x (according to my test, it runs pretty well with any node version after 6.x).

* Multiple Curves, KDF: SHA-256 (default & customizable), HMAC: MAC-WITH-SHA-256 (default & customizable), Multiple Cipher Algorithms

## API
```config(curveName, cipherAlgorithm, hmacAlgorithm, ivSize, cipherKeyGen, hmacKeyGen)```
 
 Config the default parameters for ecies-lite
 * @param curveName: string | object - the elliptic curve to use | the config object contains config items
 * @param cipherAlgorithm?: string - the cipher algorithm to use
 * @param hmacAlgorithm?: string - the hmac algorithm to use
 * @param ivSize?: number - the size (in bytes) of initialization vector (for cipher)
 * @param cipherKeyGen?: (Buffer) -> Buffer - the cipher key generator
 * @param hmacKeyGen?: (Buffer) -> Buffer - the hmac key generator
 * @return none

```encrypt(pk, msg, opts)```
 
 Encrypt a message using the recepient's public key
 * @param pk: Buffer - The recipient's public key
 * @param msg: Buffer - The message to encrypt
 * @param opts?: the same structure as the config object - you can use it to specify advanced options
 * @return {epk: Buffer, iv: Buffer, ct: Buffer, mac: Buffer} - the ecies-lite structured object with fields correspondingly stands for ephemeral public key, initialization vector, cipher text, mac code for above data, etc.

```decrypt(sk, body, opts)```
 
 Decrypt a message in ecies-lite defined format using the recipient's private key
 * @param sk: Buffer - the recepient's private key
 * @param body: ecies-lite structured object - the ecies-lite body (seen format in encrypt) to decrypt
 * @param opts?: the same structure as the config object - you can use it to specify advanced options
 * @return Buffer - the plain text decrypted from the Ecies-lite body
 * @throws when mac value is unmatched, it throws 'Corrupted Ecies-lite body: unmatched authentication code' error

## Usage

```js
const crypto = require('crypto'),
    ecies = require('ecies-lite');

let ecdh = crypto.createECDH('secp256k1');
ecdh.generateKeys();
let publicKey = ecdh.getPublicKey();
let body = ecies.encrypt(publicKey, Buffer.from('This message is for demo purpose'));
/** structure of ECIES body 
	epk: ephemeral public key;
	iv: initialization vector for the cipher algorithm;
	ct: cipher text with the derived encrypt key;
	mac: MAC value of the above fields using the derived MAC key;
**/ 
for (let [k, v] of Object.entries(body)) {
    console.log(`${k}(${v.length}B):`, v.toString('base64'));
}

let plain = ecies.decrypt(ecdh.getPrivateKey(), body);
console.log('Decrypted plain text:', plain.toString('utf-8'));

const curveName = 'prime256v1';
ecdh = crypto.createECDH(curveName);
ecdh.generateKeys();
const ephemEcdh = crypto.createECDH(curveName);
ephemEcdh.generateKeys();
const macKeyGen = (bytes) => {
    let buf = Buffer.from(bytes);
    for (let [index, value] of buf.entries()) {
        buf[index] = value ^ index;
    }
    return buf;    
}
ecies.config({curveName, macKeyGen});
body = ecies.encrypt(recEcdh.getPublicKey(), Buffer.from('This message is to demo advanced usage'), {esk: ephemEcdh.getPrivateKey()});
console.log(ecies.decrypt(recEcdh.getPrivateKey(), body).toString('utf-8'));
```

## Dependencies
`crypto` module shipped with Node later than 6.x

## License
ISC
Written in 2018 by tibetty <xihua.duan@gmail.com>
