parent
ec0fd844e5
commit
0451d3b8fa
@ -0,0 +1,15 @@ |
||||
import EthUtil from 'ethereumjs-util'; |
||||
import { |
||||
web3 |
||||
} from './util'; |
||||
|
||||
/** |
||||
* generates the ethereum-adress of the publicKey |
||||
* We create the checksum-adress which is case-sensitive |
||||
* @returns {string} address |
||||
*/ |
||||
export default function addressByPublicKey(publicKey) { |
||||
const address = EthUtil.pubToAddress(publicKey).toString('hex'); |
||||
const checkSumAdress = web3.utils.toChecksumAddress(address); |
||||
return checkSumAdress; |
||||
} |
@ -1,6 +0,0 @@ |
||||
# bitcore-ecies |
||||
|
||||
This folder contains a copy of [bitcore-ecies](https://github.com/bitpay/bitcore-ecies). |
||||
We use this copy instead of the dependency so we can: |
||||
- change the imports to allow a better tree-shake. |
||||
- Hard-Pin the bitcore-lib version which causes some errors on imports |
@ -1,51 +0,0 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { |
||||
util as bitcoreUtil |
||||
} from 'bitcore-lib'; |
||||
const $ = bitcoreUtil.preconditions; |
||||
import aes from 'aes'; |
||||
|
||||
const AES = function AES() {}; |
||||
|
||||
export function encrypt(messagebuf, keybuf) { |
||||
const key = buf2words(keybuf); |
||||
const message = buf2words(messagebuf); |
||||
const a = new aes(key); |
||||
const enc = a.encrypt(message); |
||||
const encbuf = words2buf(enc); |
||||
return encbuf; |
||||
}; |
||||
|
||||
export function decrypt(encbuf, keybuf) { |
||||
const enc = buf2words(encbuf); |
||||
const key = buf2words(keybuf); |
||||
const a = new aes(key); |
||||
const message = a.decrypt(enc); |
||||
const messagebuf = words2buf(message); |
||||
return messagebuf; |
||||
}; |
||||
|
||||
export function buf2words(buf) { |
||||
$.checkArgument(buf); |
||||
$.checkArgument(buf.length % 4 === 0, 'buf length must be a multiple of 4'); |
||||
|
||||
const words = []; |
||||
|
||||
for (let i = 0; i < buf.length / 4; i++) |
||||
words.push(buf.readUInt32BE(i * 4)); |
||||
|
||||
return words; |
||||
}; |
||||
|
||||
export function words2buf(words) { |
||||
const buf = new Buffer(words.length * 4); |
||||
|
||||
for (let i = 0; i < words.length; i++) |
||||
buf.writeUInt32BE(words[i], i * 4); |
||||
|
||||
return buf; |
||||
}; |
@ -1,52 +0,0 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { |
||||
util as bitcoreUtil, |
||||
crypto as bitcoreCrypto |
||||
} from 'bitcore-lib'; |
||||
|
||||
const $ = bitcoreUtil.preconditions; |
||||
const Random = bitcoreCrypto.Random; |
||||
const Hash = bitcoreCrypto.Hash; |
||||
|
||||
import * as AES from './aes'; |
||||
import CBC from './cbc'; |
||||
|
||||
// Symmetric encryption with AES and CBC convenience class
|
||||
const AESCBC = function AESCBC() {}; |
||||
|
||||
export function encrypt(messagebuf, passwordstr) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(passwordstr); |
||||
const cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.encryptCipherkey(messagebuf, cipherkeybuf); |
||||
}; |
||||
|
||||
export function decrypt(encbuf, passwordstr) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(passwordstr); |
||||
const cipherkeybuf = Hash.sha256(new Buffer(passwordstr)); |
||||
return AESCBC.decryptCipherkey(encbuf, cipherkeybuf); |
||||
}; |
||||
|
||||
export function encryptCipherkey(messagebuf, cipherkeybuf, ivbuf) { |
||||
$.checkArgument(messagebuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
$.checkArgument(ivbuf); |
||||
ivbuf = ivbuf || Random.getRandomBuffer(128 / 8); |
||||
const ctbuf = CBC.encrypt(messagebuf, ivbuf, AES, cipherkeybuf); |
||||
const encbuf = Buffer.concat([ivbuf, ctbuf]); |
||||
return encbuf; |
||||
}; |
||||
|
||||
export function decryptCipherkey(encbuf, cipherkeybuf) { |
||||
$.checkArgument(encbuf); |
||||
$.checkArgument(cipherkeybuf); |
||||
const ivbuf = encbuf.slice(0, 128 / 8); |
||||
const ctbuf = encbuf.slice(128 / 8); |
||||
const messagebuf = CBC.decrypt(ctbuf, ivbuf, AES, cipherkeybuf); |
||||
return messagebuf; |
||||
}; |
@ -1,144 +0,0 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { |
||||
util as bitcoreUtil |
||||
} from 'bitcore-lib'; |
||||
const $ = bitcoreUtil.preconditions; |
||||
|
||||
import errors from './errors'; |
||||
|
||||
|
||||
// Cipher Block Chaining
|
||||
// http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Cipher-block_chaining_.28CBC.29
|
||||
const CBC = function CBC(blockcipher, cipherkeybuf, ivbuf) { |
||||
if (!(this instanceof CBC)) |
||||
return new CBC(blockcipher, cipherkeybuf, ivbuf); |
||||
|
||||
this.blockcipher = blockcipher; |
||||
this.cipherkeybuf = cipherkeybuf; |
||||
this.ivbuf = ivbuf; |
||||
}; |
||||
|
||||
CBC.buf2blockbufs = function(buf, blocksize) { |
||||
const bytesize = blocksize / 8; |
||||
const blockbufs = []; |
||||
|
||||
for (let i = 0; i <= buf.length / bytesize; i++) { |
||||
let blockbuf = buf.slice(i * bytesize, i * bytesize + bytesize); |
||||
|
||||
if (blockbuf.length < blocksize) |
||||
blockbuf = CBC.pkcs7pad(blockbuf, blocksize); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.blockbufs2buf = function(blockbufs) { |
||||
let last = blockbufs[blockbufs.length - 1]; |
||||
last = CBC.pkcs7unpad(last); |
||||
blockbufs[blockbufs.length - 1] = last; |
||||
|
||||
const buf = Buffer.concat(blockbufs); |
||||
|
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encrypt = function(messagebuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
const blocksize = ivbuf.length * 8; |
||||
const blockbufs = CBC.buf2blockbufs(messagebuf, blocksize); |
||||
const encbufs = CBC.encryptblocks(blockbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
const encbuf = Buffer.concat(encbufs); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decrypt = function(encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
const blocksize = ivbuf.length * 8; |
||||
const bytesize = ivbuf.length; |
||||
const encbufs = []; |
||||
for (let i = 0; i < encbuf.length / bytesize; i++) |
||||
encbufs.push(encbuf.slice(i * bytesize, i * bytesize + bytesize)); |
||||
|
||||
const blockbufs = CBC.decryptblocks(encbufs, ivbuf, blockcipher, cipherkeybuf); |
||||
const buf = CBC.blockbufs2buf(blockbufs, blocksize); |
||||
return buf; |
||||
}; |
||||
|
||||
CBC.encryptblock = function(blockbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
const xorbuf = CBC.xorbufs(blockbuf, ivbuf); |
||||
const encbuf = blockcipher.encrypt(xorbuf, cipherkeybuf); |
||||
return encbuf; |
||||
}; |
||||
|
||||
CBC.decryptblock = function(encbuf, ivbuf, blockcipher, cipherkeybuf) { |
||||
const xorbuf = blockcipher.decrypt(encbuf, cipherkeybuf); |
||||
const blockbuf = CBC.xorbufs(xorbuf, ivbuf); |
||||
return blockbuf; |
||||
}; |
||||
|
||||
CBC.encryptblocks = function(blockbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
const encbufs = []; |
||||
|
||||
for (let i = 0; i < blockbufs.length; i++) { |
||||
let blockbuf = blockbufs[i]; |
||||
let encbuf = CBC.encryptblock(blockbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
encbufs.push(encbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return encbufs; |
||||
}; |
||||
|
||||
CBC.decryptblocks = function(encbufs, ivbuf, blockcipher, cipherkeybuf) { |
||||
const blockbufs = []; |
||||
|
||||
for (let i = 0; i < encbufs.length; i++) { |
||||
let encbuf = encbufs[i]; |
||||
let blockbuf = CBC.decryptblock(encbuf, ivbuf, blockcipher, cipherkeybuf); |
||||
|
||||
blockbufs.push(blockbuf); |
||||
|
||||
ivbuf = encbuf; |
||||
} |
||||
|
||||
return blockbufs; |
||||
}; |
||||
|
||||
CBC.pkcs7pad = function(buf, blocksize) { |
||||
const bytesize = blocksize / 8; |
||||
const padbytesize = bytesize - buf.length; |
||||
const pad = new Buffer(padbytesize); |
||||
pad.fill(padbytesize); |
||||
const paddedbuf = Buffer.concat([buf, pad]); |
||||
return paddedbuf; |
||||
}; |
||||
|
||||
CBC.pkcs7unpad = function(paddedbuf) { |
||||
const padlength = paddedbuf[paddedbuf.length - 1]; |
||||
const padbuf = paddedbuf.slice(paddedbuf.length - padlength, paddedbuf.length); |
||||
const padbuf2 = new Buffer(padlength); |
||||
padbuf2.fill(padlength); |
||||
if (padbuf.toString('hex') !== padbuf2.toString('hex')) |
||||
throw new errors.InvalidPadding(padbuf.toString()); |
||||
|
||||
return paddedbuf.slice(0, paddedbuf.length - padlength); |
||||
}; |
||||
|
||||
CBC.xorbufs = function(buf1, buf2) { |
||||
$.checkArgument(buf1.length === buf2.length, 'bufs must have the same length'); |
||||
|
||||
const buf = new Buffer(buf1.length); |
||||
|
||||
for (let i = 0; i < buf1.length; i++) |
||||
buf[i] = buf1[i] ^ buf2[i]; |
||||
|
||||
return buf; |
||||
}; |
||||
|
||||
export default CBC; |
@ -1,147 +0,0 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { |
||||
PublicKey, |
||||
crypto as bitcoreCrypto, |
||||
util as bitcoreUtil |
||||
} from 'bitcore-lib'; |
||||
|
||||
const Hash = bitcoreCrypto.Hash; |
||||
const Random = bitcoreCrypto.Random; |
||||
const $ = bitcoreUtil.preconditions; |
||||
|
||||
import { |
||||
encryptCipherkey, |
||||
decryptCipherkey |
||||
} from './aescbc'; |
||||
|
||||
// http://en.wikipedia.org/wiki/Integrated_Encryption_Scheme
|
||||
const ECIES = function ECIES(opts) { |
||||
if (!(this instanceof ECIES)) |
||||
return new ECIES(); |
||||
this.opts = opts || {}; |
||||
}; |
||||
|
||||
ECIES.prototype.privateKey = function(privateKey) { |
||||
$.checkArgument(privateKey, 'no private key provided'); |
||||
|
||||
this._privateKey = privateKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
ECIES.prototype.publicKey = function(publicKey) { |
||||
$.checkArgument(publicKey, 'no public key provided'); |
||||
|
||||
this._publicKey = publicKey || null; |
||||
|
||||
return this; |
||||
}; |
||||
|
||||
const cachedProperty = function(name, getter) { |
||||
const cachedName = '_' + name; |
||||
Object.defineProperty(ECIES.prototype, name, { |
||||
configurable: false, |
||||
enumerable: true, |
||||
get: function() { |
||||
let value = this[cachedName]; |
||||
if (!value) |
||||
value = this[cachedName] = getter.apply(this); |
||||
return value; |
||||
} |
||||
}); |
||||
}; |
||||
|
||||
cachedProperty('Rbuf', function() { |
||||
return this._privateKey.publicKey.toDER(true); |
||||
}); |
||||
|
||||
cachedProperty('kEkM', function() { |
||||
const r = this._privateKey.bn; |
||||
const KB = this._publicKey.point; |
||||
const P = KB.mul(r); |
||||
const S = P.getX(); |
||||
const Sbuf = S.toBuffer({ |
||||
size: 32 |
||||
}); |
||||
return Hash.sha512(Sbuf); |
||||
}); |
||||
|
||||
cachedProperty('kE', function() { |
||||
return this.kEkM.slice(0, 32); |
||||
}); |
||||
|
||||
cachedProperty('kM', function() { |
||||
return this.kEkM.slice(32, 64); |
||||
}); |
||||
|
||||
// Encrypts the message (String or Buffer).
|
||||
// Optional `ivbuf` contains 16-byte Buffer to be used in AES-CBC.
|
||||
// By default, `ivbuf` is computed deterministically from message and private key using HMAC-SHA256.
|
||||
// Deterministic IV enables end-to-end test vectors for alternative implementations.
|
||||
// Note that identical messages have identical ciphertexts. If your protocol does not include some
|
||||
// kind of a sequence identifier inside the message *and* it is important to not allow attacker to learn
|
||||
// that message is repeated, then you should use custom IV.
|
||||
// For random IV, pass `Random.getRandomBuffer(16)` for the second argument.
|
||||
ECIES.prototype.encrypt = function(message, ivbuf) { |
||||
if (!Buffer.isBuffer(message)) message = new Buffer(message); |
||||
if (ivbuf === undefined) |
||||
ivbuf = Hash.sha256hmac(message, this._privateKey.toBuffer()).slice(0, 16); |
||||
|
||||
const c = encryptCipherkey(message, this.kE, ivbuf); |
||||
let d = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d = d.slice(0, 4); |
||||
let encbuf; |
||||
if (this.opts.noKey) |
||||
encbuf = Buffer.concat([c, d]); |
||||
else |
||||
encbuf = Buffer.concat([this.Rbuf, c, d]); |
||||
|
||||
return encbuf; |
||||
}; |
||||
|
||||
ECIES.prototype.decrypt = function(encbuf) { |
||||
$.checkArgument(encbuf); |
||||
let offset = 0; |
||||
let tagLength = 32; |
||||
if (this.opts.shortTag) |
||||
tagLength = 4; |
||||
|
||||
if (!this.opts.noKey) { |
||||
let pub; |
||||
switch (encbuf[0]) { |
||||
case 4: |
||||
pub = encbuf.slice(0, 65); |
||||
break; |
||||
case 3: |
||||
case 2: |
||||
pub = encbuf.slice(0, 33); |
||||
break; |
||||
default: |
||||
throw new Error('Invalid type: ' + encbuf[0]); |
||||
} |
||||
this._publicKey = PublicKey.fromDER(pub); |
||||
offset += pub.length; |
||||
} |
||||
|
||||
const c = encbuf.slice(offset, encbuf.length - tagLength); |
||||
const d = encbuf.slice(encbuf.length - tagLength, encbuf.length); |
||||
|
||||
let d2 = Hash.sha256hmac(c, this.kM); |
||||
if (this.opts.shortTag) d2 = d2.slice(0, 4); |
||||
|
||||
let equal = true; |
||||
for (let i = 0; i < d.length; i++) |
||||
equal &= (d[i] === d2[i]); |
||||
|
||||
if (!equal) |
||||
throw new Error('Invalid checksum'); |
||||
|
||||
|
||||
return decryptCipherkey(c, this.kE); |
||||
}; |
||||
|
||||
export default ECIES; |
@ -1,19 +0,0 @@ |
||||
/** |
||||
* copied from bitcore-ecies |
||||
* https://github.com/bitpay/bitcore-ecies
|
||||
*/ |
||||
|
||||
import { |
||||
errors as bitcoreErrors |
||||
} from 'bitcore-lib'; |
||||
|
||||
const spec = { |
||||
name: 'ECIES', |
||||
message: 'Internal Error on bitcore-ecies Module {0}', |
||||
errors: [{ |
||||
name: 'InvalidPadding', |
||||
message: 'Invalid padding: {0}' |
||||
}] |
||||
}; |
||||
|
||||
export default bitcoreErrors.extend(spec); |
@ -0,0 +1,20 @@ |
||||
import { |
||||
web3 |
||||
} from './util'; |
||||
import publicKeyByPrivateKey from './public-key-by-private-key'; |
||||
|
||||
/** |
||||
* creates a new object with |
||||
* private-, public-Key and address |
||||
*/ |
||||
export default function createIdentity() { |
||||
const account = web3.eth.accounts.create(); |
||||
|
||||
const identity = { |
||||
address: account.address, |
||||
privateKey: account.privateKey, |
||||
publicKey: publicKeyByPrivateKey(account.privateKey) |
||||
}; |
||||
|
||||
return identity; |
||||
} |
@ -0,0 +1,18 @@ |
||||
export default async function decryptWithPrivateKey(privateKey, encrypted) { |
||||
|
||||
// remove trailing '0x' from privateKey
|
||||
const twoStripped = privateKey.replace(/^.{2}/g, ''); |
||||
|
||||
const encryptedBuffer = { |
||||
iv: new Buffer(encrypted.iv, 'hex'), |
||||
ephemPublicKey: new Buffer(encrypted.ephemPublicKey, 'hex'), |
||||
ciphertext: new Buffer(encrypted.ciphertext, 'hex'), |
||||
mac: new Buffer(encrypted.mac, 'hex') |
||||
}; |
||||
|
||||
const decryptedBuffer = await eccrypto.decrypt( |
||||
new Buffer(twoStripped, 'hex'), |
||||
encryptedBuffer |
||||
); |
||||
return decryptedBuffer.toString(); |
||||
} |
@ -0,0 +1,17 @@ |
||||
import eccrypto from 'eccrypto'; |
||||
|
||||
export default async function encryptWithPublicKey(publicKey, message) { |
||||
|
||||
// re-add the compression-flag
|
||||
const pubString = '04' + publicKey; |
||||
|
||||
const encryptedBuffers = await eccrypto.encrypt(new Buffer(pubString, 'hex'), buf); |
||||
|
||||
const encrypted = { |
||||
iv: encryptedBuffers.iv.toString('hex'), |
||||
ephemPublicKey: encryptedBuffers.ephemPublicKey.toString('hex'), |
||||
ciphertext: encryptedBuffers.ciphertext.toString('hex'), |
||||
mac: encryptedBuffers.mac.toString('hex') |
||||
}; |
||||
return encrypted; |
||||
} |
@ -1,168 +1,28 @@ |
||||
import * as ethUtil from 'ethereumjs-util'; |
||||
import randombytes from 'randombytes'; |
||||
import * as secp256k1 from 'secp256k1'; |
||||
|
||||
import ECIES from './bitcore-ecies/ecies'; |
||||
import bitcore from 'bitcore-lib'; |
||||
import Web3 from 'web3'; |
||||
|
||||
import { |
||||
sha3_256 |
||||
} from 'js-sha3'; |
||||
|
||||
import { |
||||
ensureBuffer, |
||||
formatAddress |
||||
} from './util'; |
||||
|
||||
export const web3 = new Web3(); |
||||
|
||||
/** |
||||
* get the ethereum-address by the publicKey |
||||
* @param {string} publicKey |
||||
* @return {string} address |
||||
*/ |
||||
export function publicKeyToAddress(publicKey) { |
||||
publicKey = secp256k1 |
||||
.publicKeyConvert( |
||||
ensureBuffer(publicKey), |
||||
false |
||||
) |
||||
.slice(1); // slice(1) is to drop the type byte which is hardcoded as 04 ethereum
|
||||
return formatAddress( |
||||
ethUtil.publicToAddress(publicKey) |
||||
.toString('hex') |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* creates a new privateKey |
||||
* @return {string} privateKey as hex |
||||
*/ |
||||
export function createPrivateKey() { |
||||
const key = |
||||
new Buffer( |
||||
randombytes(32), // Ethereum requires private key to be 256 bit long
|
||||
'hex' |
||||
) |
||||
.toString('hex'); |
||||
return key; |
||||
} |
||||
|
||||
/** |
||||
* create the publicKey from the privateKey |
||||
* @param {string} privateKey as hex |
||||
* @return {string} publicKey as hex |
||||
*/ |
||||
export function publicKeyFromPrivateKey(privateKey) { |
||||
return secp256k1 |
||||
.publicKeyCreate( |
||||
ensureBuffer(privateKey) |
||||
) |
||||
.toString('hex'); |
||||
} |
||||
|
||||
/** |
||||
* creates a sha3_256 of the message |
||||
* @param {string} message |
||||
* @return {string} the hash |
||||
*/ |
||||
export function hash(message) { |
||||
return sha3_256(message); |
||||
} |
||||
|
||||
export function soliditySha3(...params) { |
||||
const hexHash = web3.utils.soliditySha3(...params); |
||||
return hexHash; |
||||
} |
||||
|
||||
/** |
||||
* signs the sha3_256-hash with the privateKey |
||||
* @param {string} privateKey |
||||
* @param {string} hash |
||||
* @return {string} signature as hex |
||||
*/ |
||||
export function signHash(privateKey, hash) { |
||||
const sigObj = secp256k1.sign( |
||||
ensureBuffer(hash), |
||||
ensureBuffer(privateKey) |
||||
); |
||||
return sigObj.signature.toString('hex'); |
||||
} |
||||
|
||||
/** |
||||
* check if signature of message is signed by the privateKey of the publicKey |
||||
* @param {string} publicKey |
||||
* @param {string} hash sha3_256-hash |
||||
* @param {string} signature |
||||
* @return {boolean} true if valid, false if not |
||||
*/ |
||||
export function verifyHashSignature(publicKey, hash, signature) { |
||||
return secp256k1.verify( |
||||
ensureBuffer(hash), |
||||
ensureBuffer(signature), |
||||
ensureBuffer(publicKey) |
||||
); |
||||
} |
||||
|
||||
const _encryptWithPublicKeyEciesCache = new Map(); |
||||
// this key is used as false sample, because bitcore would crash when alice has no privateKey
|
||||
const _encryptWithPublicKeyDefaultKey = new bitcore.PrivateKey('52435b1ff21b894da15d87399011841d5edec2de4552fdc29c8299574436925d'); |
||||
/** |
||||
* encrypts the message with the publicKey |
||||
* This is using aes256Cbc |
||||
* @param {string} publicKey |
||||
* @param {string} message |
||||
* @return {string} |
||||
*/ |
||||
export function encryptWithPublicKey(publicKey, message) { |
||||
// caching
|
||||
if (!_encryptWithPublicKeyEciesCache.has(publicKey)) { |
||||
const alice = ECIES() |
||||
.privateKey(_encryptWithPublicKeyDefaultKey) |
||||
.publicKey(new bitcore.PublicKey(publicKey)); |
||||
_encryptWithPublicKeyEciesCache.set( |
||||
publicKey, |
||||
alice |
||||
); |
||||
} |
||||
|
||||
const alice = _encryptWithPublicKeyEciesCache.get(publicKey); |
||||
const encrypted = alice.encrypt(message); |
||||
const ret = encrypted.toString('hex'); |
||||
return ret; |
||||
} |
||||
|
||||
const _decryptWithPrivateKeyEciesMap = new Map(); |
||||
/** |
||||
* decrypt the encrypted message with the privateKey |
||||
* @param {string} privateKey |
||||
* @param {string} encrypted |
||||
* @return {string} |
||||
*/ |
||||
export function decryptWithPrivateKey(privateKey, encrypted) { |
||||
// caching
|
||||
if (!_decryptWithPrivateKeyEciesMap.has(privateKey)) { |
||||
const privKey = new bitcore.PrivateKey(privateKey); |
||||
const alice = ECIES().privateKey(privKey); |
||||
_decryptWithPrivateKeyEciesMap.set(privateKey, alice); |
||||
} |
||||
|
||||
const alice = _decryptWithPrivateKeyEciesMap.get(privateKey); |
||||
const decryptMe = new Buffer(encrypted, 'hex'); |
||||
const decrypted = alice.decrypt(decryptMe); |
||||
const ret = decrypted.toString(); |
||||
return ret; |
||||
} |
||||
|
||||
import addressByPublicKey from './address-by-public-key'; |
||||
import createIdentity from './create-identity'; |
||||
import decryptWithPrivateKey from './decrypt-with-private-key'; |
||||
import encryptWithPublicKey from './encrypt-with-public-key'; |
||||
import publicKeyByPrivateKey from './public-key-by-private-key'; |
||||
import recover from './recover'; |
||||
import sign from './sign'; |
||||
import VRSBySignature from './v-r-s-by-signature'; |
||||
|
||||
export addressByPublicKey from './address-by-public-key'; |
||||
export createIdentity from './create-identity'; |
||||
export decryptWithPrivateKey from './decrypt-with-private-key'; |
||||
export encryptWithPublicKey from './encrypt-with-public-key'; |
||||
export publicKeyByPrivateKey from './public-key-by-private-key'; |
||||
export recover from './recover'; |
||||
export sign from './sign'; |
||||
export VRSBySignature from './v-r-s-by-signature'; |
||||
|
||||
export default { |
||||
publicKeyToAddress, |
||||
createPrivateKey, |
||||
publicKeyFromPrivateKey, |
||||
hash, |
||||
signHash, |
||||
verifyHashSignature, |
||||
addressByPublicKey, |
||||
createIdentity, |
||||
decryptWithPrivateKey, |
||||
encryptWithPublicKey, |
||||
decryptWithPrivateKey |
||||
publicKeyByPrivateKey, |
||||
recover, |
||||
sign, |
||||
VRSBySignature |
||||
}; |
||||
|
@ -0,0 +1,12 @@ |
||||
import EthUtil from 'ethereumjs-util'; |
||||
|
||||
/** |
||||
* Generate publicKey from the privateKey. |
||||
* This creates the uncompressed publicKey, |
||||
* where 04 has stripped from left |
||||
* @returns {string} |
||||
*/ |
||||
export default function publicKeyOfPrivateKey(privateKey) { |
||||
const publicKeyBuffer = EthUtil.privateToPublic(privateKey); |
||||
return publicKeyBuffer.toString('hex'); |
||||
} |
@ -0,0 +1,21 @@ |
||||
import { |
||||
web3 |
||||
} from './util'; |
||||
import VRSBySignature from './v-r-s-by-signature'; |
||||
|
||||
/** |
||||
* returns the adress with which the messageHash was signed |
||||
* @param {string} signature |
||||
* @param {string} messageHash |
||||
* @return {string} address |
||||
*/ |
||||
export default function recover(signature, messageHash) { |
||||
const vrs = VRSBySignature(signature); |
||||
const address = web3.eth.accounts.recover( |
||||
messageHash, |
||||
vrs.v, |
||||
vrs.r, |
||||
vrs.s |
||||
); |
||||
return address; |
||||
} |
@ -0,0 +1,15 @@ |
||||
import { |
||||
web3 |
||||
} from './util'; |
||||
|
||||
/** |
||||
* signs the given message |
||||
* @param {string} privateKey |
||||
* @param {string} message |
||||
* @return {string} signature |
||||
*/ |
||||
export default function sign(privateKey, message) { |
||||
const account = web3.eth.accounts.privateKeyToAccount(privateKey); |
||||
const sig = account.sign(message); |
||||
return sig.signature; |
||||
} |
@ -0,0 +1,7 @@ |
||||
export default function VRSBySignature(signature) { |
||||
return { |
||||
v: '', |
||||
r: '', |
||||
s: '' |
||||
}; |
||||
} |
Loading…
Reference in new issue