-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
70 lines (57 loc) · 2.19 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
var bs58check = require('bs58check')
var bufferEquals = require('buffer-equals')
var createHash = require('create-hash')
var secp256k1 = require('secp256k1')
var varuint = require('varuint-ravencoin')
function sha256 (b) {
return createHash('sha256').update(b).digest()
}
function hash256 (buffer) {
return sha256(sha256(buffer))
}
function hash160 (buffer) {
return createHash('ripemd160').update(sha256(buffer)).digest()
}
function encodeSignature (signature, recovery, compressed) {
if (compressed) recovery += 4
return Buffer.concat([Buffer.alloc(1, recovery + 27), signature])
}
function decodeSignature (buffer) {
if (buffer.length !== 65) throw new Error('Invalid signature length')
var flagByte = buffer.readUInt8(0) - 27
if (flagByte > 7) throw new Error('Invalid signature parameter')
return {
compressed: !!(flagByte & 4),
recovery: flagByte & 3,
signature: buffer.slice(1)
}
}
function magicHash (message, messagePrefix) {
messagePrefix = messagePrefix || '\x1aRavencoin Signed Message:\n'
if (!Buffer.isBuffer(messagePrefix)) messagePrefix = Buffer.from(messagePrefix, 'utf8')
var messageVISize = varuint.encodingLength(message.length)
var buffer = Buffer.allocUnsafe(messagePrefix.length + messageVISize + message.length)
messagePrefix.copy(buffer, 0)
varuint.encode(message.length, buffer, messagePrefix.length)
buffer.write(message, messagePrefix.length + messageVISize)
return hash256(buffer)
}
function sign (message, privateKey, compressed, messagePrefix) {
var hash = magicHash(message, messagePrefix)
var sigObj = secp256k1.sign(hash, privateKey)
return encodeSignature(sigObj.signature, sigObj.recovery, compressed)
}
function verify (message, address, signature, messagePrefix) {
if (!Buffer.isBuffer(signature)) signature = Buffer.from(signature, 'base64')
var parsed = decodeSignature(signature)
var hash = magicHash(message, messagePrefix)
var publicKey = secp256k1.recover(hash, parsed.signature, parsed.recovery, parsed.compressed)
var actual = hash160(publicKey)
var expected = bs58check.decode(address).slice(1)
return bufferEquals(actual, expected)
}
module.exports = {
magicHash: magicHash,
sign: sign,
verify: verify
}