const elliptic = require('elliptic')
const secp256k1 = elliptic.ec('secp256k1')
const hash = require('hash.js')
const keypairs = require('ripple-keypairs')
const hexToDecimal = (x) => secp256k1.keyFromPrivate(x, 'hex').getPrivate().toString(10)
module.exports = {
sign (message, familySeed) {
const digest = hash.sha256().update(message).digest('hex').toUpperCase()
const keypair = keypairs.deriveKeypair(familySeed)
const signature = secp256k1.sign(digest, keypair.privateKey.substr(2))
return {
hash: digest,
signature: (signature.r.toJSON() + signature.s.toJSON() + signature.recoveryParam.toString(16)).toUpperCase()
}
},
unserializeSignature (signature) {
return {
r: signature.slice(0, 64).toLowerCase(),
s: signature.slice(64, 128).toLowerCase(),
recoveryParam: parseInt(signature.slice(128), 16)
}
},
deriveAddress (familySeed) {
const keypair = keypairs.deriveKeypair(familySeed)
return keypairs.deriveAddress(keypair.publicKey)
},
recoverPubKey (hash, signature) {
const unserializedSignature = this.unserializeSignature(signature)
const pubKeyRecovered = secp256k1.recoverPubKey(hexToDecimal(hash), unserializedSignature, unserializedSignature.recoveryParam, 'hex')
return pubKeyRecovered
},
recoverAddress (hash, signature) {
return keypairs.deriveAddress(this.recoverPubKey(hash, signature).encodeCompressed('hex'))
},
verify (message, signature) {
const digest = hash.sha256().update(message).digest('hex')
const unserializedSignature = this.unserializeSignature(signature)
return secp256k1.verify(digest, unserializedSignature, this.recoverPubKey(digest, signature))
}
}