ed2curve.js
===========

Convert Ed25519 signing key pair into Curve25519 key pair suitable for
Diffie-Hellman key exchange. This means that by exchanging only 32-byte
Ed25519 public keys users can both sign and encrypt with NaCl.

Note that there's currently [no proof](http://crypto.stackexchange.com/a/3311/291)
that this is safe to do. It is safer to share both Ed25519 and Curve25519
public keys (their concatenation is 64 bytes long).

Written by Dmitry Chestnykh in 2014-2016, using public domain code from
[TweetNaCl.js](https://github.com/dchest/tweetnacl-js). Public domain.
No warranty.

Thanks to [@CodesInChaos](https://github.com/CodesInChaos) and
[@nightcracker](https://github.com/nightcracker) for showing how to
convert Edwards coordinates to Montgomery coordinates.

[![Build Status](https://travis-ci.org/dchest/ed2curve-js.svg?branch=master)
](https://travis-ci.org/dchest/ed2curve-js)


Installation
------------

Via NPM:

    $ npm install ed2curve

or just download `ed2curve.js` or `ed2curve.min.js` and include it after
[TweetNaCl.js](https://github.com/dchest/tweetnacl-js):

```html
<script src="nacl.min.js"></script>
<script src="ed2curve.min.js"></script>
```

Usage
-----

### ed2curve.convertKeyPair(keyPair) -> convertedKeyPair | null

Converts the given key pair as generated by
[TweetNaCl.js](https://github.com/dchest/tweetnacl-js)'s `nacl.sign.keyPair`
into a key pair suitable for operations which accept key pairs generated by
`nacl.box.keyPair`. This function is a combination of `convertPublicKey`
and `convertSecretKey`.

Returns `null` if the public key in the given key pair is not a valid
Ed25519 public key.

### ed2curve.convertPublicKey(edPublicKey) -> curvePublicKey | null

Converts a 32-byte Ed25519 public key into a 32-byte Curve25519 public key
and returns it.

Returns `null` if the given public key in not a valid Ed25519 public key.

### ed2curve.convertSecretKey(edSecretKey) -> curveSecretKey

Converts a 64-byte Ed25519 secret key (or just the first 32-byte part of it,
which is the secret value) into a 32-byte Curve25519 secret key and returns it.


Example
-------

(Note: example uses [tweetnacl-util](https://github.com/dchest/tweetnacl-util-js)
to convert bytes)

```javascript
// Generate new sign key pair.
var myKeyPair = nacl.sign.keyPair();

// Share public key with a peer.
console.log(myKeyPair.publicKey);

// Receive peer's public key.
var theirPublicKey = // ... receive

// Sign a message.
var message = nacl.util.decodeUTF8('Hello!');
var signedMessage = nacl.sign(message, myKeyPair.secretKey);

// Send message to peer. They can now verify it using
// the previously shared public key (myKeyPair.publicKey).
// ...

// Receive a signed message from peer and verify it using their public key.
var theirSignedMessage = // ... receive
var theirMessage = nacl.sign.open(theirSignedMessage, theirPublicKey);
if (theirMessage) {
  // ... we got the message ...
}

// Encrypt a message to their public key.
// But first, we need to convert our secret key and their public key
// from Ed25519 into the format accepted by Curve25519.
//
// Note that peers are not involved in this conversion -- all they need
// to know is the signing public key that we already shared with them.

var theirDHPublicKey = ed2curve.convertPublicKey(theirPublicKey);
var myDHSecretKey = ed2curve.convertSecretKey(myKeyPair.secretKey);

var anotherMessage = nacl.util.decodeUTF8('Keep silence');
var encryptedMessage = nacl.box(anotherMessage, nonce, theirDHPublicKey, myDHSecretKey);

// When we receive encrypted messages from peers,
// we need to use converted keys to open them.

var theirEncryptedMessage = // ... receive
var decryptedMessage = nacl.box.open(theirEncryptedMessage, nonce, theirDHPublicKey, myDHSecretKey);
```

Requirements
------------

* Requires [TweetNaCl.js](https://github.com/dchest/tweetnacl-js)
* Works in the same enviroments as it.


Other libraries
---------------

Some other libraries that can use a single Ed/Curve25519 key:

* [agl/../extra25519](https://github.com/agl/ed25519/blob/master/extra25519/extra25519.go) - Go
  (compatible with ed2curve)
* [CodesInChaos/../MontgomeryCurve25519](https://github.com/CodesInChaos/Chaos.NaCl/blob/master/Chaos.NaCl/MontgomeryCurve25519.cs) - C#
  (compatible with ed2curve)
* [nightcracker/ed25519](https://github.com/nightcracker/ed25519/blob/master/src/key_exchange.c) - C
  (compatible with ed2curve)
* [libsodium](https://github.com/jedisct1/libsodium) - C
  (compatible with ed2curve)
* [trevp/../curve_sigs](https://github.com/trevp/ref10_extract/blob/master/ed25519/additions/curve_sigs.c) - C
  (incompatible, as it converts the opposite way, and stores a sign bit of signing public key in a signature)
