git ssb

1+

Dominic / ssb-keys



Tree: ceaabdc05ea7cb746df59f258d3ae7885b2fa9f3

Files: ceaabdc05ea7cb746df59f258d3ae7885b2fa9f3 / index.js

3816 bytesRaw
1var deepEqual = require('deep-equal')
2
3var sodium = require('chloride')
4var ssbref = require('ssb-ref')
5
6var pb = require('private-box')
7
8var u = require('./util')
9
10var isBuffer = Buffer.isBuffer
11
12function isString (s) {
13 return 'string' === typeof s
14}
15//UTILS
16
17function clone (obj) {
18 var _obj = {}
19 for(var k in obj) {
20 if(Object.hasOwnProperty.call(obj, k))
21 _obj[k] = obj[k]
22 }
23 return _obj
24}
25
26var isLink = ssbref.isLink
27var isFeedId = ssbref.isFeedId
28
29var hmac = sodium.crypto_auth
30
31exports.hash = u.hash
32
33exports.getTag = u.getTag
34
35function isObject (o) {
36 return 'object' === typeof o
37}
38
39function isFunction (f) {
40 return 'function' === typeof f
41}
42
43function isString(s) {
44 return 'string' === typeof s
45}
46
47var curves = {}
48curves.ed25519 = require('./sodium')
49
50function getCurve(keys) {
51 var curve = keys.curve
52
53 if(!keys.curve && isString(keys.public))
54 keys = keys.public
55
56 if(!curve && isString(keys))
57 curve = u.getTag(keys)
58
59 if(!curves[curve]) {
60 throw new Error(
61 'unkown curve:' + curve +
62 ' expected: '+Object.keys(curves)
63 )
64 }
65
66 return curve
67}
68
69//this should return a key pair:
70// {curve: curve, public: Buffer, private: Buffer}
71
72exports.generate = function (curve, seed) {
73 curve = curve || 'ed25519'
74
75 if(!curves[curve])
76 throw new Error('unknown curve:'+curve)
77
78 return u.keysToJSON(curves[curve].generate(seed), curve)
79}
80
81//import functions for loading/saving keys from storage
82var storage = require('./storage')(exports.generate)
83for(var key in storage) exports[key] = storage[key]
84
85
86exports.loadOrCreate = function (filename, cb) {
87 exports.load(filename, function (err, keys) {
88 if(!err) return cb(null, keys)
89 exports.create(filename, cb)
90 })
91}
92
93exports.loadOrCreateSync = function (filename) {
94 try {
95 return exports.loadSync(filename)
96 } catch (err) {
97 return exports.createSync(filename)
98 }
99}
100
101
102//takes a public key and a hash and returns a signature.
103//(a signature must be a node buffer)
104
105function sign (keys, msg) {
106 if(isString(msg))
107 msg = new Buffer(msg)
108 if(!isBuffer(msg))
109 throw new Error('msg should be buffer')
110 var curve = getCurve(keys)
111
112 return curves[curve]
113 .sign(u.toBuffer(keys.private || keys), msg)
114 .toString('base64')+'.sig.'+curve
115
116}
117
118//takes a public key, signature, and a hash
119//and returns true if the signature was valid.
120function verify (keys, sig, msg) {
121 if(isObject(sig))
122 throw new Error('signature should be base64 string, did you mean verifyObj(public, signed_obj)')
123 return curves[getCurve(keys)].verify(
124 u.toBuffer(keys.public || keys),
125 u.toBuffer(sig),
126 isBuffer(msg) ? msg : new Buffer(msg)
127 )
128}
129
130// OTHER CRYTPO FUNCTIONS
131
132exports.signObj = function (keys, hmac_key, obj) {
133 if(!obj) obj = hmac_key, hmac_key = null
134 var _obj = clone(obj)
135 var b = new Buffer(JSON.stringify(_obj, null, 2))
136 if(hmac_key) b = hmac(b, hmac_key)
137 _obj.signature = sign(keys, b)
138 return _obj
139}
140
141exports.verifyObj = function (keys, hmac_key, obj) {
142 if(!obj) obj = hmac_key, hmac_key = null
143 obj = clone(obj)
144 var sig = obj.signature
145 delete obj.signature
146 var b = new Buffer(JSON.stringify(obj, null, 2))
147 if(hmac_key) b = hmac(b, hmac_key)
148 return verify(keys, sig, b)
149}
150
151exports.box = function (msg, recipients) {
152 msg = new Buffer(JSON.stringify(msg))
153
154 recipients = recipients.map(function (keys) {
155 var public = keys.public || keys
156 return sodium.crypto_sign_ed25519_pk_to_curve25519(u.toBuffer(public))
157 })
158
159 return pb.multibox(msg, recipients).toString('base64')+'.box'
160}
161
162exports.unbox = function (boxed, keys) {
163 boxed = u.toBuffer(boxed)
164 var sk = sodium.crypto_sign_ed25519_sk_to_curve25519(u.toBuffer(keys.private || keys))
165
166 var msg = pb.multibox_open(boxed, sk)
167 if(msg) return JSON.parse(''+msg)
168}
169
170
171
172
173
174

Built with git-ssb-web