const pub = encBuf.slice(4, 37)
const fromPubKey = PubKey.fromDer(pub)
const { iv, kE, kM } = Ecies.ivkEkM(toPrivKey, fromPubKey)
const ciphertext = encBuf.slice(37, encBuf.length - tagLength)
const hmac = encBuf.slice(encBuf.length - tagLength, encBuf.length)
const hmac2 = Hash.sha256Hmac(encBuf.slice(0, encBuf.length - tagLength), kM)
if (!hmac.equals(hmac2)) {
throw new Error('Invalid checksum')
}
return Aescbc.decrypt(ciphertext, kE, iv)
}
Ecies.bitcoreEncrypt = function (messageBuf, toPubKey, fromKeyPair, ivBuf) {
if (!fromKeyPair) {
fromKeyPair = KeyPair.fromRandom()
}
const r = fromKeyPair.privKey.bn
const RPubKey = fromKeyPair.pubKey
const RBuf = RPubKey.toDer(true)
const KB = toPubKey.point
const P = KB.mul(r)
const S = P.getX()
const Sbuf = S.toBuffer({ size: 32 })
const kEkM = Hash.sha512(Sbuf)
const kE = kEkM.slice(0, 32)
const kM = kEkM.slice(32, 64)
const c = Aescbc.encrypt(messageBuf, kE, ivBuf)
const d = Hash.sha256Hmac(c, kM)
const encBuf = Buffer.concat([RBuf, c, d])
return encBuf
}
Ecies.asyncBitcoreEncrypt = async function (
messageBuf,
toPubKey,
fromKeyPair,
ivBuf
) {
if (!fromKeyPair) {
fromKeyPair = await KeyPair.asyncFromRandom()
}
if (!ivBuf) {
ivBuf = Random.getRandomBuffer(128 / 8)
}
const args = [messageBuf, toPubKey, fromKeyPair, ivBuf]
const workersResult = await Workers.asyncClassMethod(Ecies, 'bitcoreEncrypt', args)
return workersResult.resbuf
}
Ecies.bitcoreDecrypt = function (encBuf, toPrivKey) {
const kB = toPrivKey.bn
const fromPubKey = PubKey.fromDer(encBuf.slice(0, 33))
const R = fromPubKey.point
const P = R.mul(kB)
if (P.eq(new Point())) {
throw new Error('P equals 0')
}
const S = P.getX()
const Sbuf = S.toBuffer({ size: 32 })
const kEkM = Hash.sha512(Sbuf)
const kE = kEkM.slice(0, 32)
const kM = kEkM.slice(32, 64)
const c = encBuf.slice(33, encBuf.length - 32)
const d = encBuf.slice(encBuf.length - 32, encBuf.length)
const d2 = Hash.sha256Hmac(c, kM)
if (!cmp(d, d2)) {
throw new Error('Invalid checksum')
}
const messageBuf = Aescbc.decrypt(c, kE)
return messageBuf
}
Ecies.asyncBitcoreDecrypt = async function (encBuf, toPrivKey) {
const args = [encBuf, toPrivKey]
const workersResult = await Workers.asyncClassMethod(Ecies, 'bitcoreDecrypt', args)
return workersResult.resbuf
}
export { Ecies }
Ecies