# Elliptic Curve Cryptography support for OpenPGPjs ## Description This work is to provide an implementation of [RFC 6637](http://www.ietf.org/rfc/rfc6637.txt) for OpenPGP.js. ## Compatibility with GnuPG In order to assure compatibility of the provided implementation with RFC 6637, the keys and messages were tested against GnuPG version v2.1.8, compiled with a beta version of libgcrypt v1.7.0-beta262. It was tested that keys, messages, and signatures generated by GnuPG were imported correctly. Also keys, messages and signatures generated by this implementation are correctly imported by GnuPG. ```txt > gpg2 --homedir ../home --version gpg (GnuPG) 2.1.8 libgcrypt 1.7.0-beta262 Copyright (C) 2015 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ../home Supported algorithms: Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB ``` ## Extra dependencies There are two new dependencies: * [Elliptic](https://github.com/indutny/elliptic/) for the elliptic curve cryptography. MIT license. * [Aes](https://github.com/cryptocoinjs/aes) required to implement RFC 3394 Key wrap and Key Unwrap functions. BSD License. ## Examples ### Generate new key ```js var openpgp = require('openpgp'); var options = { curve: 'secp256k1', userIds: {name: 'Hamlet', email: 'hamlet@example.net'}, passphrase: 'To be, or not to be: that is the question' }; openpgp.generateKey(options).then(function(key) { // success var privkey = key.privateKeyArmored; var pubkey = key.publicKeyArmored; }).catch(function(error) { // failure }); ``` ### Generate keypair from bitcoin key ```js var openpgp = require('openpgp'); var bs58check = require('bs58check'); var wif = 'KyiAchQgMKuXQu89j6k6UVZQj7brK6cM79JfmDvkNXPVW24L1thi'; var buff = bs58check.decode(wif); var privateKey = buff.slice(1, -1); privateKey = openpgp.util.bin2str(privateKey); var options = { curve: 'secp256k1', userIds: {name: 'Hamlet', email: 'hamlet@example.net'}, passphrase: 'To be, or not to be: that is the question', material: { key: privateKey, subkey: privateKey } }; openpgp.generateKey(options).then(function(key) { // success var privkey = key.privateKeyArmored; var pubkey = key.publicKeyArmored; }).catch(function(error) { // failure }); ``` ### Signature, encryption and decryption The normal operations: signature, encryption and decryption require no modifications. ```js var openpgp = require('openpgp'); var keyData = '-----BEGIN PGP PUBLIC KEY BLOCK ... END PGP PUBLIC KEY BLOCK-----'; var key = openpgp.key.readArmored(keyData); openpgp.encrypt({publicKeys: key.keys, data: 'Hello, World!'}).then(function(msg) { // success }).catch(function(error) { // failure }); ``` ## Possible improvements * The dependency with AES library can be eliminated, a suitable AES decrypt function is provided. It is only used by the wrap and unwrap functions in the crypto/rfc3394.js file. ## Note Although the example uses the same value to generate the main key, and the subkey, it is a recommended practice to use different keys. The main key is used for signature and the subkeys are used for encryption. ## Resources * Elliptic Curve Cryptography (ECC) in OpenPGP [RFC 6637](http://www.ietf.org/rfc/rfc6637.txt) * OpenPGP Message Format [RFC 4880](http://www.ietf.org/rfc/rfc4880.txt) * Advanced Encryption Standard (AES) Key Wrap Algorithm [RFC 3394](http://www.ietf.org/rfc/rfc3394.txt) * A JavaScript component for the Advanced Encryption Standard (AES) [AES](https://github.com/cryptocoinjs/aes) * Fast elliptic-curve cryptography in a plain javascript implementation [Elliptic](https://github.com/indutny/elliptic/)