It is a project for Bytom Chrome extension JS SDK https://bytom.github.io/Bytom-JS-SDK
Révision | 779d37274b51a6c29871a854168637fb0037b9be (tree) |
---|---|
l'heure | 2020-09-09 10:52:01 |
Auteur | Zhiting Lin <zlin035@uott...> |
Commiter | Zhiting Lin |
update the sign transaction and sign message js function
@@ -5,6 +5,8 @@ import {encryptKey, decryptKey} from '../utils/key/keystore'; | ||
5 | 5 | import { restoreFromKeyStore } from '../utils/account'; |
6 | 6 | import { camelize } from '../utils/utils'; |
7 | 7 | import CryptoJS from 'crypto-js'; |
8 | +import {signMessage as signMJs} from '../utils/transaction/signMessage'; | |
9 | +import transactionSDK from './transaction'; | |
8 | 10 | |
9 | 11 | |
10 | 12 | function keysSDK() { |
@@ -357,7 +359,31 @@ keysSDK.prototype.signMessage = function(message, password, keystore) { | ||
357 | 359 | throw (error); |
358 | 360 | }); |
359 | 361 | |
362 | +}; | |
360 | 363 | |
364 | +/** | |
365 | + * Sign Message. | |
366 | + * | |
367 | + * @param {String} message - message. | |
368 | + * @param {String} password - password. | |
369 | + * @param {Object} address - address. | |
370 | + */ | |
371 | +keysSDK.prototype.signMessageJs = function(message, password, keystore) { | |
372 | + return signMJs(message, password, keystore); | |
373 | +}; | |
374 | + | |
375 | +keysSDK.prototype.signMessageJsPromise = function(message, password, keystore) { | |
376 | + let retPromise = new Promise((resolve, reject) => { | |
377 | + try{ | |
378 | + let result = this.signMessageJs(message, password, keystore); | |
379 | + resolve(result); | |
380 | + } | |
381 | + catch(error) { | |
382 | + reject(error); | |
383 | + } | |
384 | + }); | |
385 | + | |
386 | + return retPromise; | |
361 | 387 | }; |
362 | 388 | |
363 | 389 | export default keysSDK; |
\ No newline at end of file |
@@ -1,6 +1,9 @@ | ||
1 | 1 | import {convertArgument, signTransaction} from '../wasm/func'; |
2 | 2 | import { handleApiError, handleAxiosError } from '../utils/http'; |
3 | 3 | import { getDB } from '../db/db'; |
4 | +import {signTransaction as signJs} from '../utils/transaction/signTransaction'; | |
5 | +import { camelize } from '../utils/utils'; | |
6 | + | |
4 | 7 | |
5 | 8 | function transactionSDK(bytom) { |
6 | 9 | this.http = bytom.serverHttp; |
@@ -258,6 +261,26 @@ transactionSDK.prototype._signTransaction = function( transaction, password, key | ||
258 | 261 | }); |
259 | 262 | }; |
260 | 263 | |
264 | +transactionSDK.prototype._signTransactionJs = function( transaction, password, key) { | |
265 | + let tx = camelize(JSON.parse(transaction)); | |
266 | + | |
267 | + return signJs(tx, password, key); | |
268 | +}; | |
269 | + | |
270 | +transactionSDK.prototype._signTransactionJsPromise = function( transaction, password, key) { | |
271 | + let retPromise = new Promise((resolve, reject) => { | |
272 | + try{ | |
273 | + let result = this._signTransactionJs(transaction, password, key); | |
274 | + resolve(result); | |
275 | + } | |
276 | + catch(error) { | |
277 | + reject(error); | |
278 | + } | |
279 | + }); | |
280 | + | |
281 | + return retPromise; | |
282 | +}; | |
283 | + | |
261 | 284 | /** |
262 | 285 | * Convert arguement. |
263 | 286 | * |
@@ -1,7 +1,8 @@ | ||
1 | 1 | let createHmac = require('create-hmac'); |
2 | 2 | let ED25519 =require('../ed25519'); |
3 | 3 | let Curve25519 = new ED25519.Curve; |
4 | - | |
4 | +const ExpandedPrivateKeySize = 64 | |
5 | +const nacl = require('../nacl'); | |
5 | 6 | // If r is nil, crypto/rand.Reader is used. |
6 | 7 | |
7 | 8 | function scalarmult_base (q){ |
@@ -63,3 +64,154 @@ function pruneRootScalar(s) { | ||
63 | 64 | s[31] &= 31; // clear top 3 bits |
64 | 65 | s[31] |= 64; // set second highest bit |
65 | 66 | } |
67 | + | |
68 | +// Clears lowest 3 bits and highest 23 bits of `f`. | |
69 | +function pruneIntermediateScalar(f) { | |
70 | + f[0] &= 248; // clear bottom 3 bits | |
71 | + f[29] &= 1; // clear 7 high bits | |
72 | + f[30] = 0; // clear 8 bits | |
73 | + f[31] = 0; // clear 8 bits | |
74 | +} | |
75 | + | |
76 | +XPrv.prototype.Derive = function(path) { | |
77 | + let res = this; | |
78 | + for( let p of path ){ | |
79 | + res = res.Child(p, false); | |
80 | + } | |
81 | + return res; | |
82 | +}; | |
83 | + | |
84 | + | |
85 | +XPrv.prototype.Child = function(sel , hardened ) { | |
86 | + if (hardened) { | |
87 | + return this.hardenedChild(sel); | |
88 | + } | |
89 | + return this.nonhardenedChild(sel); | |
90 | +}; | |
91 | + | |
92 | + | |
93 | +XPrv.prototype.hardenedChild = function(sel) { | |
94 | + const r = this.xprv.slice(32); | |
95 | + const l = this.xprv.slice(0, 32); | |
96 | + let h = createHmac('sha512', r) | |
97 | + .update(Buffer.from('H', 'utf8')) | |
98 | + .update(l) | |
99 | + .update(sel) | |
100 | + .digest(); | |
101 | + | |
102 | + const hL = h.slice(0, 32); | |
103 | + const hR = h.slice(32); | |
104 | + | |
105 | + pruneRootScalar(hL); | |
106 | + | |
107 | + return new XPrv( Buffer.concat( [hL,hR]) ); | |
108 | +}; | |
109 | + | |
110 | +XPrv.prototype.nonhardenedChild = function(sel){ | |
111 | + const xpub = this.XPub(); | |
112 | + | |
113 | + const r = xpub.slice(32); | |
114 | + const l = xpub.slice(0, 32); | |
115 | + let h = createHmac('sha512', r) | |
116 | + .update(Buffer.from('N', 'utf8')) | |
117 | + .update(l) | |
118 | + .update(sel) | |
119 | + .digest(); | |
120 | + | |
121 | + | |
122 | + const hL = h.slice(0, 32); | |
123 | + const hR = h.slice(32); | |
124 | + | |
125 | + pruneIntermediateScalar(hL); | |
126 | + | |
127 | + let res = Buffer.concat( [hL,hR]); | |
128 | + | |
129 | + let sum = 0; | |
130 | + | |
131 | + sum = this.xprv[0] + res[0] + (sum >> 8); | |
132 | + res[0] = sum & 0xff; | |
133 | + sum = this.xprv[1] + res[1] + (sum >> 8); | |
134 | + res[1] = sum & 0xff; | |
135 | + sum = this.xprv[2] + res[2] + (sum >> 8); | |
136 | + res[2] = sum & 0xff; | |
137 | + sum = this.xprv[3] + res[3] + (sum >> 8); | |
138 | + res[3] = sum & 0xff; | |
139 | + sum = this.xprv[4] + res[4] + (sum >> 8); | |
140 | + res[4] = sum & 0xff; | |
141 | + sum = this.xprv[5] + res[5] + (sum >> 8); | |
142 | + res[5] = sum & 0xff; | |
143 | + sum = this.xprv[6] + res[6] + (sum >> 8); | |
144 | + res[6] = sum & 0xff; | |
145 | + sum = this.xprv[7] + res[7] + (sum >> 8); | |
146 | + res[7] = sum & 0xff; | |
147 | + sum = this.xprv[8] + res[8] + (sum >> 8); | |
148 | + res[8] = sum & 0xff; | |
149 | + sum = this.xprv[9] + res[9] + (sum >> 8); | |
150 | + res[9] = sum & 0xff; | |
151 | + sum = this.xprv[10] + res[10] + (sum >> 8); | |
152 | + res[10] = sum & 0xff; | |
153 | + sum = this.xprv[11] + res[11] + (sum >> 8); | |
154 | + res[11] = sum & 0xff; | |
155 | + sum = this.xprv[12] + res[12] + (sum >> 8); | |
156 | + res[12] = sum & 0xff; | |
157 | + sum = this.xprv[13] + res[13] + (sum >> 8); | |
158 | + res[13] = sum & 0xff; | |
159 | + sum = this.xprv[14] + res[14] + (sum >> 8); | |
160 | + res[14] = sum & 0xff; | |
161 | + sum = this.xprv[15] + res[15] + (sum >> 8); | |
162 | + res[15] = sum & 0xff; | |
163 | + sum = this.xprv[16] + res[16] + (sum >> 8); | |
164 | + res[16] = sum & 0xff; | |
165 | + sum = this.xprv[17] + res[17] + (sum >> 8); | |
166 | + res[17] = sum & 0xff; | |
167 | + sum = this.xprv[18] + res[18] + (sum >> 8); | |
168 | + res[18] = sum & 0xff; | |
169 | + sum = this.xprv[19] + res[19] + (sum >> 8); | |
170 | + res[19] = sum & 0xff; | |
171 | + sum = this.xprv[20] + res[20] + (sum >> 8); | |
172 | + res[20] = sum & 0xff; | |
173 | + sum = this.xprv[21] + res[21] + (sum >> 8); | |
174 | + res[21] = sum & 0xff; | |
175 | + sum = this.xprv[22] + res[22] + (sum >> 8); | |
176 | + res[22] = sum & 0xff; | |
177 | + sum = this.xprv[23] + res[23] + (sum >> 8); | |
178 | + res[23] = sum & 0xff; | |
179 | + sum = this.xprv[24] + res[24] + (sum >> 8); | |
180 | + res[24] = sum & 0xff; | |
181 | + sum = this.xprv[25] + res[25] + (sum >> 8); | |
182 | + res[25] = sum & 0xff; | |
183 | + sum = this.xprv[26] + res[26] + (sum >> 8); | |
184 | + res[26] = sum & 0xff; | |
185 | + sum = this.xprv[27] + res[27] + (sum >> 8); | |
186 | + res[27] = sum & 0xff; | |
187 | + sum = this.xprv[28] + res[28] + (sum >> 8); | |
188 | + res[28] = sum & 0xff; | |
189 | + sum = this.xprv[29] + res[29] + (sum >> 8); | |
190 | + res[29] = sum & 0xff; | |
191 | + sum = this.xprv[30] + res[30] + (sum >> 8); | |
192 | + res[30] = sum & 0xff; | |
193 | + sum = this.xprv[31] + res[31] + (sum >> 8); | |
194 | + res[31] = sum & 0xff; | |
195 | + | |
196 | + if ((sum >> 8) != 0) { | |
197 | + throw('sum does not fit in 256-bit int'); | |
198 | + } | |
199 | + return new XPrv(res); | |
200 | +}; | |
201 | + | |
202 | +XPrv.prototype.Sign = function(msg){ | |
203 | + const expKey = this.ExpandedPrivateKey() | |
204 | + | |
205 | + const publicKey = Buffer.from(scalarmult_base(expKey.slice(0, 32)),'hex'); | |
206 | + return nacl.innerSign(msg, expKey, publicKey); | |
207 | +}; | |
208 | + | |
209 | +XPrv.prototype.ExpandedPrivateKey = function() { | |
210 | + let h = createHmac('sha512', Buffer.from('Expand', 'utf8')) | |
211 | + .update(this.xprv) | |
212 | + .digest(); | |
213 | + const l = this.xprv.slice(0, 32); | |
214 | + const r = h.slice(32); | |
215 | + | |
216 | + return Buffer.concat( [l,r]); | |
217 | +}; |
@@ -0,0 +1,1231 @@ | ||
1 | +const crypto = require('crypto-browserify'); | |
2 | +const BN = require("bn.js"); | |
3 | + | |
4 | + | |
5 | +(function(nacl) { | |
6 | + 'use strict'; | |
7 | + | |
8 | + // Ported in 2014 by Dmitry Chestnykh and Devi Mandiri. | |
9 | + // Public domain. | |
10 | + // | |
11 | + // Implementation derived from TweetNaCl version 20140427. | |
12 | + // See for details: http://tweetnacl.cr.yp.to/ | |
13 | + | |
14 | + var u64 = function(h, l) { this.hi = h|0 >>> 0; this.lo = l|0 >>> 0; }; | |
15 | + var gf = function(init) { | |
16 | + var i, r = new Float64Array(16); | |
17 | + if (init) for (i = 0; i < init.length; i++) r[i] = init[i]; | |
18 | + return r; | |
19 | + }; | |
20 | + | |
21 | + // Pluggable, initialized in high-level API below. | |
22 | + var randombytes = function(/* x, n */) { throw new Error('no PRNG'); }; | |
23 | + | |
24 | + var _0 = new Uint8Array(16); | |
25 | + var _9 = new Uint8Array(32); _9[0] = 9; | |
26 | + | |
27 | + var gf0 = gf(), | |
28 | + gf1 = gf([1]), | |
29 | + _121665 = gf([0xdb41, 1]), | |
30 | + D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]), | |
31 | + D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]), | |
32 | + X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]), | |
33 | + Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]), | |
34 | + I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]); | |
35 | + | |
36 | + function L32(x, c) { return (x << c) | (x >>> (32 - c)); } | |
37 | + | |
38 | + function ld32(x, i) { | |
39 | + var u = x[i+3] & 0xff; | |
40 | + u = (u<<8)|(x[i+2] & 0xff); | |
41 | + u = (u<<8)|(x[i+1] & 0xff); | |
42 | + return (u<<8)|(x[i+0] & 0xff); | |
43 | + } | |
44 | + | |
45 | + function dl64(x, i) { | |
46 | + var h = (x[i] << 24) | (x[i+1] << 16) | (x[i+2] << 8) | x[i+3]; | |
47 | + var l = (x[i+4] << 24) | (x[i+5] << 16) | (x[i+6] << 8) | x[i+7]; | |
48 | + return new u64(h, l); | |
49 | + } | |
50 | + | |
51 | + function st32(x, j, u) { | |
52 | + var i; | |
53 | + for (i = 0; i < 4; i++) { x[j+i] = u & 255; u >>>= 8; } | |
54 | + } | |
55 | + | |
56 | + function ts64(x, i, u) { | |
57 | + x[i] = (u.hi >> 24) & 0xff; | |
58 | + x[i+1] = (u.hi >> 16) & 0xff; | |
59 | + x[i+2] = (u.hi >> 8) & 0xff; | |
60 | + x[i+3] = u.hi & 0xff; | |
61 | + x[i+4] = (u.lo >> 24) & 0xff; | |
62 | + x[i+5] = (u.lo >> 16) & 0xff; | |
63 | + x[i+6] = (u.lo >> 8) & 0xff; | |
64 | + x[i+7] = u.lo & 0xff; | |
65 | + } | |
66 | + | |
67 | + function vn(x, xi, y, yi, n) { | |
68 | + var i,d = 0; | |
69 | + for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i]; | |
70 | + return (1 & ((d - 1) >>> 8)) - 1; | |
71 | + } | |
72 | + | |
73 | + function crypto_verify_16(x, xi, y, yi) { | |
74 | + return vn(x,xi,y,yi,16); | |
75 | + } | |
76 | + | |
77 | + function crypto_verify_32(x, xi, y, yi) { | |
78 | + return vn(x,xi,y,yi,32); | |
79 | + } | |
80 | + | |
81 | + function core(out,inp,k,c,h) { | |
82 | + var w = new Uint32Array(16), x = new Uint32Array(16), | |
83 | + y = new Uint32Array(16), t = new Uint32Array(4); | |
84 | + var i, j, m; | |
85 | + | |
86 | + for (i = 0; i < 4; i++) { | |
87 | + x[5*i] = ld32(c, 4*i); | |
88 | + x[1+i] = ld32(k, 4*i); | |
89 | + x[6+i] = ld32(inp, 4*i); | |
90 | + x[11+i] = ld32(k, 16+4*i); | |
91 | + } | |
92 | + | |
93 | + for (i = 0; i < 16; i++) y[i] = x[i]; | |
94 | + | |
95 | + for (i = 0; i < 20; i++) { | |
96 | + for (j = 0; j < 4; j++) { | |
97 | + for (m = 0; m < 4; m++) t[m] = x[(5*j+4*m)%16]; | |
98 | + t[1] ^= L32((t[0]+t[3])|0, 7); | |
99 | + t[2] ^= L32((t[1]+t[0])|0, 9); | |
100 | + t[3] ^= L32((t[2]+t[1])|0,13); | |
101 | + t[0] ^= L32((t[3]+t[2])|0,18); | |
102 | + for (m = 0; m < 4; m++) w[4*j+(j+m)%4] = t[m]; | |
103 | + } | |
104 | + for (m = 0; m < 16; m++) x[m] = w[m]; | |
105 | + } | |
106 | + | |
107 | + if (h) { | |
108 | + for (i = 0; i < 16; i++) x[i] = (x[i] + y[i]) | 0; | |
109 | + for (i = 0; i < 4; i++) { | |
110 | + x[5*i] = (x[5*i] - ld32(c, 4*i)) | 0; | |
111 | + x[6+i] = (x[6+i] - ld32(inp, 4*i)) | 0; | |
112 | + } | |
113 | + for (i = 0; i < 4; i++) { | |
114 | + st32(out,4*i,x[5*i]); | |
115 | + st32(out,16+4*i,x[6+i]); | |
116 | + } | |
117 | + } else { | |
118 | + for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0); | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + function crypto_core_salsa20(out,inp,k,c) { | |
123 | + core(out,inp,k,c,false); | |
124 | + return 0; | |
125 | + } | |
126 | + | |
127 | + function crypto_core_hsalsa20(out,inp,k,c) { | |
128 | + core(out,inp,k,c,true); | |
129 | + return 0; | |
130 | + } | |
131 | + | |
132 | + var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]); | |
133 | + // "expand 32-byte k" | |
134 | + | |
135 | + function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) { | |
136 | + var z = new Uint8Array(16), x = new Uint8Array(64); | |
137 | + var u, i; | |
138 | + if (!b) return 0; | |
139 | + for (i = 0; i < 16; i++) z[i] = 0; | |
140 | + for (i = 0; i < 8; i++) z[i] = n[i]; | |
141 | + while (b >= 64) { | |
142 | + crypto_core_salsa20(x,z,k,sigma); | |
143 | + for (i = 0; i < 64; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i]; | |
144 | + u = 1; | |
145 | + for (i = 8; i < 16; i++) { | |
146 | + u = u + (z[i] & 0xff) | 0; | |
147 | + z[i] = u & 0xff; | |
148 | + u >>>= 8; | |
149 | + } | |
150 | + b -= 64; | |
151 | + cpos += 64; | |
152 | + if (m) mpos += 64; | |
153 | + } | |
154 | + if (b > 0) { | |
155 | + crypto_core_salsa20(x,z,k,sigma); | |
156 | + for (i = 0; i < b; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i]; | |
157 | + } | |
158 | + return 0; | |
159 | + } | |
160 | + | |
161 | + function crypto_stream_salsa20(c,cpos,d,n,k) { | |
162 | + return crypto_stream_salsa20_xor(c,cpos,null,0,d,n,k); | |
163 | + } | |
164 | + | |
165 | + function crypto_stream(c,cpos,d,n,k) { | |
166 | + var s = new Uint8Array(32); | |
167 | + crypto_core_hsalsa20(s,n,k,sigma); | |
168 | + return crypto_stream_salsa20(c,cpos,d,n.subarray(16),s); | |
169 | + } | |
170 | + | |
171 | + function crypto_stream_xor(c,cpos,m,mpos,d,n,k) { | |
172 | + var s = new Uint8Array(32); | |
173 | + crypto_core_hsalsa20(s,n,k,sigma); | |
174 | + return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,n.subarray(16),s); | |
175 | + } | |
176 | + | |
177 | + function add1305(h, c) { | |
178 | + var j, u = 0; | |
179 | + for (j = 0; j < 17; j++) { | |
180 | + u = (u + ((h[j] + c[j]) | 0)) | 0; | |
181 | + h[j] = u & 255; | |
182 | + u >>>= 8; | |
183 | + } | |
184 | + } | |
185 | + | |
186 | + var minusp = new Uint32Array([ | |
187 | + 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252 | |
188 | + ]); | |
189 | + | |
190 | + function crypto_onetimeauth(out, outpos, m, mpos, n, k) { | |
191 | + var s, i, j, u; | |
192 | + var x = new Uint32Array(17), r = new Uint32Array(17), | |
193 | + h = new Uint32Array(17), c = new Uint32Array(17), | |
194 | + g = new Uint32Array(17); | |
195 | + for (j = 0; j < 17; j++) r[j]=h[j]=0; | |
196 | + for (j = 0; j < 16; j++) r[j]=k[j]; | |
197 | + r[3]&=15; | |
198 | + r[4]&=252; | |
199 | + r[7]&=15; | |
200 | + r[8]&=252; | |
201 | + r[11]&=15; | |
202 | + r[12]&=252; | |
203 | + r[15]&=15; | |
204 | + | |
205 | + while (n > 0) { | |
206 | + for (j = 0; j < 17; j++) c[j] = 0; | |
207 | + for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[mpos+j]; | |
208 | + c[j] = 1; | |
209 | + mpos += j; n -= j; | |
210 | + add1305(h,c); | |
211 | + for (i = 0; i < 17; i++) { | |
212 | + x[i] = 0; | |
213 | + for (j = 0; j < 17; j++) x[i] = (x[i] + (h[j] * ((j <= i) ? r[i - j] : ((320 * r[i + 17 - j])|0))) | 0) | 0; | |
214 | + } | |
215 | + for (i = 0; i < 17; i++) h[i] = x[i]; | |
216 | + u = 0; | |
217 | + for (j = 0; j < 16; j++) { | |
218 | + u = (u + h[j]) | 0; | |
219 | + h[j] = u & 255; | |
220 | + u >>>= 8; | |
221 | + } | |
222 | + u = (u + h[16]) | 0; h[16] = u & 3; | |
223 | + u = (5 * (u >>> 2)) | 0; | |
224 | + for (j = 0; j < 16; j++) { | |
225 | + u = (u + h[j]) | 0; | |
226 | + h[j] = u & 255; | |
227 | + u >>>= 8; | |
228 | + } | |
229 | + u = (u + h[16]) | 0; h[16] = u; | |
230 | + } | |
231 | + | |
232 | + for (j = 0; j < 17; j++) g[j] = h[j]; | |
233 | + add1305(h,minusp); | |
234 | + s = (-(h[16] >>> 7) | 0); | |
235 | + for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j]); | |
236 | + | |
237 | + for (j = 0; j < 16; j++) c[j] = k[j + 16]; | |
238 | + c[16] = 0; | |
239 | + add1305(h,c); | |
240 | + for (j = 0; j < 16; j++) out[outpos+j] = h[j]; | |
241 | + return 0; | |
242 | + } | |
243 | + | |
244 | + function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) { | |
245 | + var x = new Uint8Array(16); | |
246 | + crypto_onetimeauth(x,0,m,mpos,n,k); | |
247 | + return crypto_verify_16(h,hpos,x,0); | |
248 | + } | |
249 | + | |
250 | + function crypto_secretbox(c,m,d,n,k) { | |
251 | + var i; | |
252 | + if (d < 32) return -1; | |
253 | + crypto_stream_xor(c,0,m,0,d,n,k); | |
254 | + crypto_onetimeauth(c, 16, c, 32, d - 32, c); | |
255 | + for (i = 0; i < 16; i++) c[i] = 0; | |
256 | + return 0; | |
257 | + } | |
258 | + | |
259 | + function crypto_secretbox_open(m,c,d,n,k) { | |
260 | + var i; | |
261 | + var x = new Uint8Array(32); | |
262 | + if (d < 32) return -1; | |
263 | + crypto_stream(x,0,32,n,k); | |
264 | + if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1; | |
265 | + crypto_stream_xor(m,0,c,0,d,n,k); | |
266 | + for (i = 0; i < 32; i++) m[i] = 0; | |
267 | + return 0; | |
268 | + } | |
269 | + | |
270 | + function set25519(r, a) { | |
271 | + var i; | |
272 | + for (i = 0; i < 16; i++) r[i] = a[i]|0; | |
273 | + } | |
274 | + | |
275 | + function car25519(o) { | |
276 | + var c; | |
277 | + var i; | |
278 | + for (i = 0; i < 16; i++) { | |
279 | + o[i] += 65536; | |
280 | + c = Math.floor(o[i] / 65536); | |
281 | + o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0); | |
282 | + o[i] -= (c * 65536); | |
283 | + } | |
284 | + } | |
285 | + | |
286 | + function sel25519(p, q, b) { | |
287 | + var t, c = ~(b-1); | |
288 | + for (var i = 0; i < 16; i++) { | |
289 | + t = c & (p[i] ^ q[i]); | |
290 | + p[i] ^= t; | |
291 | + q[i] ^= t; | |
292 | + } | |
293 | + } | |
294 | + | |
295 | + function pack25519(o, n) { | |
296 | + var i, j, b; | |
297 | + var m = gf(), t = gf(); | |
298 | + for (i = 0; i < 16; i++) t[i] = n[i]; | |
299 | + car25519(t); | |
300 | + car25519(t); | |
301 | + car25519(t); | |
302 | + for (j = 0; j < 2; j++) { | |
303 | + m[0] = t[0] - 0xffed; | |
304 | + for (i = 1; i < 15; i++) { | |
305 | + m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1); | |
306 | + m[i-1] &= 0xffff; | |
307 | + } | |
308 | + m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1); | |
309 | + b = (m[15]>>16) & 1; | |
310 | + m[14] &= 0xffff; | |
311 | + sel25519(t, m, 1-b); | |
312 | + } | |
313 | + for (i = 0; i < 16; i++) { | |
314 | + o[2*i] = t[i] & 0xff; | |
315 | + o[2*i+1] = t[i]>>8; | |
316 | + } | |
317 | + } | |
318 | + | |
319 | + function neq25519(a, b) { | |
320 | + var c = new Uint8Array(32), d = new Uint8Array(32); | |
321 | + pack25519(c, a); | |
322 | + pack25519(d, b); | |
323 | + return crypto_verify_32(c, 0, d, 0); | |
324 | + } | |
325 | + | |
326 | + function par25519(a) { | |
327 | + var d = new Uint8Array(32); | |
328 | + pack25519(d, a); | |
329 | + return d[0] & 1; | |
330 | + } | |
331 | + | |
332 | + function unpack25519(o, n) { | |
333 | + var i; | |
334 | + for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8); | |
335 | + o[15] &= 0x7fff; | |
336 | + } | |
337 | + | |
338 | + function A(o, a, b) { | |
339 | + var i; | |
340 | + for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0; | |
341 | + } | |
342 | + | |
343 | + function Z(o, a, b) { | |
344 | + var i; | |
345 | + for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0; | |
346 | + } | |
347 | + | |
348 | + function M(o, a, b) { | |
349 | + var i, j, t = new Float64Array(31); | |
350 | + for (i = 0; i < 31; i++) t[i] = 0; | |
351 | + for (i = 0; i < 16; i++) { | |
352 | + for (j = 0; j < 16; j++) { | |
353 | + t[i+j] += a[i] * b[j]; | |
354 | + } | |
355 | + } | |
356 | + for (i = 0; i < 15; i++) { | |
357 | + t[i] += 38 * t[i+16]; | |
358 | + } | |
359 | + for (i = 0; i < 16; i++) o[i] = t[i]; | |
360 | + car25519(o); | |
361 | + car25519(o); | |
362 | + } | |
363 | + | |
364 | + function S(o, a) { | |
365 | + M(o, a, a); | |
366 | + } | |
367 | + | |
368 | + function inv25519(o, i) { | |
369 | + var c = gf(); | |
370 | + var a; | |
371 | + for (a = 0; a < 16; a++) c[a] = i[a]; | |
372 | + for (a = 253; a >= 0; a--) { | |
373 | + S(c, c); | |
374 | + if(a !== 2 && a !== 4) M(c, c, i); | |
375 | + } | |
376 | + for (a = 0; a < 16; a++) o[a] = c[a]; | |
377 | + } | |
378 | + | |
379 | + function pow2523(o, i) { | |
380 | + var c = gf(); | |
381 | + var a; | |
382 | + for (a = 0; a < 16; a++) c[a] = i[a]; | |
383 | + for (a = 250; a >= 0; a--) { | |
384 | + S(c, c); | |
385 | + if(a !== 1) M(c, c, i); | |
386 | + } | |
387 | + for (a = 0; a < 16; a++) o[a] = c[a]; | |
388 | + } | |
389 | + | |
390 | + function crypto_scalarmult(q, n, p) { | |
391 | + var z = new Uint8Array(32); | |
392 | + var x = new Float64Array(80), r, i; | |
393 | + var a = gf(), b = gf(), c = gf(), | |
394 | + d = gf(), e = gf(), f = gf(); | |
395 | + for (i = 0; i < 31; i++) z[i] = n[i]; | |
396 | + z[31]=(n[31]&127)|64; | |
397 | + z[0]&=248; | |
398 | + unpack25519(x,p); | |
399 | + for (i = 0; i < 16; i++) { | |
400 | + b[i]=x[i]; | |
401 | + d[i]=a[i]=c[i]=0; | |
402 | + } | |
403 | + a[0]=d[0]=1; | |
404 | + for (i=254; i>=0; --i) { | |
405 | + r=(z[i>>>3]>>>(i&7))&1; | |
406 | + sel25519(a,b,r); | |
407 | + sel25519(c,d,r); | |
408 | + A(e,a,c); | |
409 | + Z(a,a,c); | |
410 | + A(c,b,d); | |
411 | + Z(b,b,d); | |
412 | + S(d,e); | |
413 | + S(f,a); | |
414 | + M(a,c,a); | |
415 | + M(c,b,e); | |
416 | + A(e,a,c); | |
417 | + Z(a,a,c); | |
418 | + S(b,a); | |
419 | + Z(c,d,f); | |
420 | + M(a,c,_121665); | |
421 | + A(a,a,d); | |
422 | + M(c,c,a); | |
423 | + M(a,d,f); | |
424 | + M(d,b,x); | |
425 | + S(b,e); | |
426 | + sel25519(a,b,r); | |
427 | + sel25519(c,d,r); | |
428 | + } | |
429 | + for (i = 0; i < 16; i++) { | |
430 | + x[i+16]=a[i]; | |
431 | + x[i+32]=c[i]; | |
432 | + x[i+48]=b[i]; | |
433 | + x[i+64]=d[i]; | |
434 | + } | |
435 | + var x32 = x.subarray(32); | |
436 | + var x16 = x.subarray(16); | |
437 | + inv25519(x32,x32); | |
438 | + M(x16,x16,x32); | |
439 | + pack25519(q,x16); | |
440 | + return 0; | |
441 | + } | |
442 | + | |
443 | + function crypto_scalarmult_base(q, n) { | |
444 | + return crypto_scalarmult(q, n, _9); | |
445 | + } | |
446 | + | |
447 | + function crypto_box_keypair(y, x) { | |
448 | + randombytes(x, 32); | |
449 | + return crypto_scalarmult_base(y, x); | |
450 | + } | |
451 | + | |
452 | + function crypto_box_beforenm(k, y, x) { | |
453 | + var s = new Uint8Array(32); | |
454 | + crypto_scalarmult(s, x, y); | |
455 | + return crypto_core_hsalsa20(k, _0, s, sigma); | |
456 | + } | |
457 | + | |
458 | + var crypto_box_afternm = crypto_secretbox; | |
459 | + var crypto_box_open_afternm = crypto_secretbox_open; | |
460 | + | |
461 | + function crypto_box(c, m, d, n, y, x) { | |
462 | + var k = new Uint8Array(32); | |
463 | + crypto_box_beforenm(k, y, x); | |
464 | + return crypto_box_afternm(c, m, d, n, k); | |
465 | + } | |
466 | + | |
467 | + function crypto_box_open(m, c, d, n, y, x) { | |
468 | + var k = new Uint8Array(32); | |
469 | + crypto_box_beforenm(k, y, x); | |
470 | + return crypto_box_open_afternm(m, c, d, n, k); | |
471 | + } | |
472 | + | |
473 | + function add64() { | |
474 | + var a = 0, b = 0, c = 0, d = 0, m16 = 65535, l, h, i; | |
475 | + for (i = 0; i < arguments.length; i++) { | |
476 | + l = arguments[i].lo; | |
477 | + h = arguments[i].hi; | |
478 | + a += (l & m16); b += (l >>> 16); | |
479 | + c += (h & m16); d += (h >>> 16); | |
480 | + } | |
481 | + | |
482 | + b += (a >>> 16); | |
483 | + c += (b >>> 16); | |
484 | + d += (c >>> 16); | |
485 | + | |
486 | + return new u64((c & m16) | (d << 16), (a & m16) | (b << 16)); | |
487 | + } | |
488 | + | |
489 | + function shr64(x, c) { | |
490 | + return new u64((x.hi >>> c), (x.lo >>> c) | (x.hi << (32 - c))); | |
491 | + } | |
492 | + | |
493 | + function xor64() { | |
494 | + var l = 0, h = 0, i; | |
495 | + for (i = 0; i < arguments.length; i++) { | |
496 | + l ^= arguments[i].lo; | |
497 | + h ^= arguments[i].hi; | |
498 | + } | |
499 | + return new u64(h, l); | |
500 | + } | |
501 | + | |
502 | + function R(x, c) { | |
503 | + var h, l, c1 = 32 - c; | |
504 | + if (c < 32) { | |
505 | + h = (x.hi >>> c) | (x.lo << c1); | |
506 | + l = (x.lo >>> c) | (x.hi << c1); | |
507 | + } else if (c < 64) { | |
508 | + h = (x.lo >>> c) | (x.hi << c1); | |
509 | + l = (x.hi >>> c) | (x.lo << c1); | |
510 | + } | |
511 | + return new u64(h, l); | |
512 | + } | |
513 | + | |
514 | + function Ch(x, y, z) { | |
515 | + var h = (x.hi & y.hi) ^ (~x.hi & z.hi), | |
516 | + l = (x.lo & y.lo) ^ (~x.lo & z.lo); | |
517 | + return new u64(h, l); | |
518 | + } | |
519 | + | |
520 | + function Maj(x, y, z) { | |
521 | + var h = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi), | |
522 | + l = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo); | |
523 | + return new u64(h, l); | |
524 | + } | |
525 | + | |
526 | + function Sigma0(x) { return xor64(R(x,28), R(x,34), R(x,39)); } | |
527 | + function Sigma1(x) { return xor64(R(x,14), R(x,18), R(x,41)); } | |
528 | + function sigma0(x) { return xor64(R(x, 1), R(x, 8), shr64(x,7)); } | |
529 | + function sigma1(x) { return xor64(R(x,19), R(x,61), shr64(x,6)); } | |
530 | + | |
531 | + var K = [ | |
532 | + new u64(0x428a2f98, 0xd728ae22), new u64(0x71374491, 0x23ef65cd), | |
533 | + new u64(0xb5c0fbcf, 0xec4d3b2f), new u64(0xe9b5dba5, 0x8189dbbc), | |
534 | + new u64(0x3956c25b, 0xf348b538), new u64(0x59f111f1, 0xb605d019), | |
535 | + new u64(0x923f82a4, 0xaf194f9b), new u64(0xab1c5ed5, 0xda6d8118), | |
536 | + new u64(0xd807aa98, 0xa3030242), new u64(0x12835b01, 0x45706fbe), | |
537 | + new u64(0x243185be, 0x4ee4b28c), new u64(0x550c7dc3, 0xd5ffb4e2), | |
538 | + new u64(0x72be5d74, 0xf27b896f), new u64(0x80deb1fe, 0x3b1696b1), | |
539 | + new u64(0x9bdc06a7, 0x25c71235), new u64(0xc19bf174, 0xcf692694), | |
540 | + new u64(0xe49b69c1, 0x9ef14ad2), new u64(0xefbe4786, 0x384f25e3), | |
541 | + new u64(0x0fc19dc6, 0x8b8cd5b5), new u64(0x240ca1cc, 0x77ac9c65), | |
542 | + new u64(0x2de92c6f, 0x592b0275), new u64(0x4a7484aa, 0x6ea6e483), | |
543 | + new u64(0x5cb0a9dc, 0xbd41fbd4), new u64(0x76f988da, 0x831153b5), | |
544 | + new u64(0x983e5152, 0xee66dfab), new u64(0xa831c66d, 0x2db43210), | |
545 | + new u64(0xb00327c8, 0x98fb213f), new u64(0xbf597fc7, 0xbeef0ee4), | |
546 | + new u64(0xc6e00bf3, 0x3da88fc2), new u64(0xd5a79147, 0x930aa725), | |
547 | + new u64(0x06ca6351, 0xe003826f), new u64(0x14292967, 0x0a0e6e70), | |
548 | + new u64(0x27b70a85, 0x46d22ffc), new u64(0x2e1b2138, 0x5c26c926), | |
549 | + new u64(0x4d2c6dfc, 0x5ac42aed), new u64(0x53380d13, 0x9d95b3df), | |
550 | + new u64(0x650a7354, 0x8baf63de), new u64(0x766a0abb, 0x3c77b2a8), | |
551 | + new u64(0x81c2c92e, 0x47edaee6), new u64(0x92722c85, 0x1482353b), | |
552 | + new u64(0xa2bfe8a1, 0x4cf10364), new u64(0xa81a664b, 0xbc423001), | |
553 | + new u64(0xc24b8b70, 0xd0f89791), new u64(0xc76c51a3, 0x0654be30), | |
554 | + new u64(0xd192e819, 0xd6ef5218), new u64(0xd6990624, 0x5565a910), | |
555 | + new u64(0xf40e3585, 0x5771202a), new u64(0x106aa070, 0x32bbd1b8), | |
556 | + new u64(0x19a4c116, 0xb8d2d0c8), new u64(0x1e376c08, 0x5141ab53), | |
557 | + new u64(0x2748774c, 0xdf8eeb99), new u64(0x34b0bcb5, 0xe19b48a8), | |
558 | + new u64(0x391c0cb3, 0xc5c95a63), new u64(0x4ed8aa4a, 0xe3418acb), | |
559 | + new u64(0x5b9cca4f, 0x7763e373), new u64(0x682e6ff3, 0xd6b2b8a3), | |
560 | + new u64(0x748f82ee, 0x5defb2fc), new u64(0x78a5636f, 0x43172f60), | |
561 | + new u64(0x84c87814, 0xa1f0ab72), new u64(0x8cc70208, 0x1a6439ec), | |
562 | + new u64(0x90befffa, 0x23631e28), new u64(0xa4506ceb, 0xde82bde9), | |
563 | + new u64(0xbef9a3f7, 0xb2c67915), new u64(0xc67178f2, 0xe372532b), | |
564 | + new u64(0xca273ece, 0xea26619c), new u64(0xd186b8c7, 0x21c0c207), | |
565 | + new u64(0xeada7dd6, 0xcde0eb1e), new u64(0xf57d4f7f, 0xee6ed178), | |
566 | + new u64(0x06f067aa, 0x72176fba), new u64(0x0a637dc5, 0xa2c898a6), | |
567 | + new u64(0x113f9804, 0xbef90dae), new u64(0x1b710b35, 0x131c471b), | |
568 | + new u64(0x28db77f5, 0x23047d84), new u64(0x32caab7b, 0x40c72493), | |
569 | + new u64(0x3c9ebe0a, 0x15c9bebc), new u64(0x431d67c4, 0x9c100d4c), | |
570 | + new u64(0x4cc5d4be, 0xcb3e42b6), new u64(0x597f299c, 0xfc657e2a), | |
571 | + new u64(0x5fcb6fab, 0x3ad6faec), new u64(0x6c44198c, 0x4a475817) | |
572 | + ]; | |
573 | + | |
574 | + function crypto_hashblocks(x, m, n) { | |
575 | + var z = [], b = [], a = [], w = [], t, i, j; | |
576 | + | |
577 | + for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8*i); | |
578 | + | |
579 | + var pos = 0; | |
580 | + while (n >= 128) { | |
581 | + for (i = 0; i < 16; i++) w[i] = dl64(m, 8*i+pos); | |
582 | + for (i = 0; i < 80; i++) { | |
583 | + for (j = 0; j < 8; j++) b[j] = a[j]; | |
584 | + t = add64(a[7], Sigma1(a[4]), Ch(a[4], a[5], a[6]), K[i], w[i%16]); | |
585 | + b[7] = add64(t, Sigma0(a[0]), Maj(a[0], a[1], a[2])); | |
586 | + b[3] = add64(b[3], t); | |
587 | + for (j = 0; j < 8; j++) a[(j+1)%8] = b[j]; | |
588 | + if (i%16 === 15) { | |
589 | + for (j = 0; j < 16; j++) { | |
590 | + w[j] = add64(w[j], w[(j+9)%16], sigma0(w[(j+1)%16]), sigma1(w[(j+14)%16])); | |
591 | + } | |
592 | + } | |
593 | + } | |
594 | + | |
595 | + for (i = 0; i < 8; i++) { | |
596 | + a[i] = add64(a[i], z[i]); | |
597 | + z[i] = a[i]; | |
598 | + } | |
599 | + | |
600 | + pos += 128; | |
601 | + n -= 128; | |
602 | + } | |
603 | + | |
604 | + for (i = 0; i < 8; i++) ts64(x, 8*i, z[i]); | |
605 | + return n; | |
606 | + } | |
607 | + | |
608 | + var iv = new Uint8Array([ | |
609 | + 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08, | |
610 | + 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b, | |
611 | + 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b, | |
612 | + 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1, | |
613 | + 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1, | |
614 | + 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f, | |
615 | + 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b, | |
616 | + 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79 | |
617 | + ]); | |
618 | + | |
619 | + function crypto_hash(out, m, n) { | |
620 | + var h = new Uint8Array(64), x = new Uint8Array(256); | |
621 | + var i, b = n; | |
622 | + | |
623 | + for (i = 0; i < 64; i++) h[i] = iv[i]; | |
624 | + | |
625 | + crypto_hashblocks(h, m, n); | |
626 | + n %= 128; | |
627 | + | |
628 | + for (i = 0; i < 256; i++) x[i] = 0; | |
629 | + for (i = 0; i < n; i++) x[i] = m[b-n+i]; | |
630 | + x[n] = 128; | |
631 | + | |
632 | + n = 256-128*(n<112?1:0); | |
633 | + x[n-9] = 0; | |
634 | + ts64(x, n-8, new u64((b / 0x20000000) | 0, b << 3)); | |
635 | + crypto_hashblocks(h, x, n); | |
636 | + | |
637 | + for (i = 0; i < 64; i++) out[i] = h[i]; | |
638 | + | |
639 | + return 0; | |
640 | + } | |
641 | + | |
642 | + function add(p, q) { | |
643 | + var a = gf(), b = gf(), c = gf(), | |
644 | + d = gf(), e = gf(), f = gf(), | |
645 | + g = gf(), h = gf(), t = gf(); | |
646 | + | |
647 | + Z(a, p[1], p[0]); | |
648 | + Z(t, q[1], q[0]); | |
649 | + M(a, a, t); | |
650 | + A(b, p[0], p[1]); | |
651 | + A(t, q[0], q[1]); | |
652 | + M(b, b, t); | |
653 | + M(c, p[3], q[3]); | |
654 | + M(c, c, D2); | |
655 | + M(d, p[2], q[2]); | |
656 | + A(d, d, d); | |
657 | + Z(e, b, a); | |
658 | + Z(f, d, c); | |
659 | + A(g, d, c); | |
660 | + A(h, b, a); | |
661 | + | |
662 | + M(p[0], e, f); | |
663 | + M(p[1], h, g); | |
664 | + M(p[2], g, f); | |
665 | + M(p[3], e, h); | |
666 | + } | |
667 | + | |
668 | + function cswap(p, q, b) { | |
669 | + var i; | |
670 | + for (i = 0; i < 4; i++) { | |
671 | + sel25519(p[i], q[i], b); | |
672 | + } | |
673 | + } | |
674 | + | |
675 | + function pack(r, p) { | |
676 | + var tx = gf(), ty = gf(), zi = gf(); | |
677 | + inv25519(zi, p[2]); | |
678 | + M(tx, p[0], zi); | |
679 | + M(ty, p[1], zi); | |
680 | + pack25519(r, ty); | |
681 | + r[31] ^= par25519(tx) << 7; | |
682 | + } | |
683 | + | |
684 | + function scalarmult(p, q, s) { | |
685 | + var b, i; | |
686 | + set25519(p[0], gf0); | |
687 | + set25519(p[1], gf1); | |
688 | + set25519(p[2], gf1); | |
689 | + set25519(p[3], gf0); | |
690 | + for (i = 255; i >= 0; --i) { | |
691 | + b = (s[(i/8)|0] >> (i&7)) & 1; | |
692 | + cswap(p, q, b); | |
693 | + add(q, p); | |
694 | + add(p, p); | |
695 | + cswap(p, q, b); | |
696 | + } | |
697 | + } | |
698 | + | |
699 | + function scalarbase(p, s) { | |
700 | + var q = [gf(), gf(), gf(), gf()]; | |
701 | + set25519(q[0], X); | |
702 | + set25519(q[1], Y); | |
703 | + set25519(q[2], gf1); | |
704 | + M(q[3], X, Y); | |
705 | + scalarmult(p, q, s); | |
706 | + } | |
707 | + | |
708 | + function crypto_sign_keypair(pk, sk, seeded) { | |
709 | + var d = new Uint8Array(64); | |
710 | + var p = [gf(), gf(), gf(), gf()]; | |
711 | + var i; | |
712 | + | |
713 | + if (!seeded) randombytes(sk, 32); | |
714 | + crypto_hash(d, sk, 32); | |
715 | + d[0] &= 248; | |
716 | + d[31] &= 127; | |
717 | + d[31] |= 64; | |
718 | + | |
719 | + scalarbase(p, d); | |
720 | + pack(pk, p); | |
721 | + | |
722 | + for (i = 0; i < 32; i++) sk[i+32] = pk[i]; | |
723 | + return 0; | |
724 | + } | |
725 | + | |
726 | + var L = new Float64Array([0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10]); | |
727 | + | |
728 | + function modL(r, x) { | |
729 | + var carry, i, j, k; | |
730 | + for (i = 63; i >= 32; --i) { | |
731 | + carry = 0; | |
732 | + for (j = i - 32, k = i - 12; j < k; ++j) { | |
733 | + x[j] += carry - 16 * x[i] * L[j - (i - 32)]; | |
734 | + carry = Math.floor((x[j] + 128) / 256); | |
735 | + x[j] -= carry * 256; | |
736 | + } | |
737 | + x[j] += carry; | |
738 | + x[i] = 0; | |
739 | + } | |
740 | + carry = 0; | |
741 | + for (j = 0; j < 32; j++) { | |
742 | + x[j] += carry - (x[31] >> 4) * L[j]; | |
743 | + carry = x[j] >> 8; | |
744 | + x[j] &= 255; | |
745 | + } | |
746 | + for (j = 0; j < 32; j++) x[j] -= carry * L[j]; | |
747 | + for (i = 0; i < 32; i++) { | |
748 | + x[i+1] += x[i] >> 8; | |
749 | + r[i] = x[i] & 255; | |
750 | + } | |
751 | + } | |
752 | + | |
753 | + function reduce(r) { | |
754 | + var x = new Float64Array(64), i; | |
755 | + for (i = 0; i < 64; i++) x[i] = r[i]; | |
756 | + for (i = 0; i < 64; i++) r[i] = 0; | |
757 | + modL(r, x); | |
758 | + } | |
759 | + | |
760 | + // Note: difference from C - smlen returned, not passed as argument. | |
761 | + function crypto_sign(sm, m, n, sk) { | |
762 | + var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64); | |
763 | + var i, j, x = new Float64Array(64); | |
764 | + var p = [gf(), gf(), gf(), gf()]; | |
765 | + | |
766 | + crypto_hash(d, sk, 32); | |
767 | + d[0] &= 248; | |
768 | + d[31] &= 127; | |
769 | + d[31] |= 64; | |
770 | + | |
771 | + var smlen = n + 64; | |
772 | + for (i = 0; i < n; i++) sm[64 + i] = m[i]; | |
773 | + for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i]; | |
774 | + | |
775 | + crypto_hash(r, sm.subarray(32), n+32); | |
776 | + reduce(r); | |
777 | + scalarbase(p, r); | |
778 | + pack(sm, p); | |
779 | + | |
780 | + for (i = 32; i < 64; i++) sm[i] = sk[i]; | |
781 | + crypto_hash(h, sm, n + 64); | |
782 | + reduce(h); | |
783 | + | |
784 | + for (i = 0; i < 64; i++) x[i] = 0; | |
785 | + for (i = 0; i < 32; i++) x[i] = r[i]; | |
786 | + for (i = 0; i < 32; i++) { | |
787 | + for (j = 0; j < 32; j++) { | |
788 | + x[i+j] += h[i] * d[j]; | |
789 | + } | |
790 | + } | |
791 | + | |
792 | + modL(sm.subarray(32), x); | |
793 | + return smlen; | |
794 | + } | |
795 | + | |
796 | + function crypto_inner_sign(sm, m, n, sk, publicKey) { | |
797 | + var p = [gf(), gf(), gf(), gf()]; | |
798 | + var i, j, s = new Float64Array(64); | |
799 | + let messageDigest = new Uint8Array(64), hramDigest = new Uint8Array(64); | |
800 | + messageDigest = crypto.createHash('sha512') | |
801 | + .update(sk.subarray(32)) | |
802 | + .update(m) | |
803 | + .digest(); | |
804 | + | |
805 | + let encodedR = new Uint8Array(32); | |
806 | + reduce(messageDigest); | |
807 | + const messageDigestReduced = messageDigest.subarray(0,32); | |
808 | + | |
809 | + scalarbase(p, messageDigestReduced); | |
810 | + pack(encodedR, p); | |
811 | + | |
812 | + hramDigest = crypto.createHash('sha512') | |
813 | + .update(encodedR) | |
814 | + .update(publicKey) | |
815 | + .update(m) | |
816 | + .digest(); | |
817 | + | |
818 | + reduce(hramDigest); | |
819 | + | |
820 | + let _sk = sk.subarray(0,32); | |
821 | + | |
822 | + for ( i = 0; i < 64; i++) s[i] = 0; | |
823 | + for ( i = 0; i < 32; i++) s[i] = messageDigest[i]; | |
824 | + for ( i = 0; i < 32; i++) { | |
825 | + for ( j = 0; j < 32; j++) { | |
826 | + s[i+j] += hramDigest[i] * _sk[j]; | |
827 | + } | |
828 | + } | |
829 | + | |
830 | + modL(sm.subarray(32), s); | |
831 | + for ( i = 0; i < 32; i++) sm[i] = encodedR[i]; | |
832 | + | |
833 | + } | |
834 | + | |
835 | + function unpackneg(r, p) { | |
836 | + var t = gf(), chk = gf(), num = gf(), | |
837 | + den = gf(), den2 = gf(), den4 = gf(), | |
838 | + den6 = gf(); | |
839 | + | |
840 | + set25519(r[2], gf1); | |
841 | + unpack25519(r[1], p); | |
842 | + S(num, r[1]); | |
843 | + M(den, num, D); | |
844 | + Z(num, num, r[2]); | |
845 | + A(den, r[2], den); | |
846 | + | |
847 | + S(den2, den); | |
848 | + S(den4, den2); | |
849 | + M(den6, den4, den2); | |
850 | + M(t, den6, num); | |
851 | + M(t, t, den); | |
852 | + | |
853 | + pow2523(t, t); | |
854 | + M(t, t, num); | |
855 | + M(t, t, den); | |
856 | + M(t, t, den); | |
857 | + M(r[0], t, den); | |
858 | + | |
859 | + S(chk, r[0]); | |
860 | + M(chk, chk, den); | |
861 | + if (neq25519(chk, num)) M(r[0], r[0], I); | |
862 | + | |
863 | + S(chk, r[0]); | |
864 | + M(chk, chk, den); | |
865 | + if (neq25519(chk, num)) return -1; | |
866 | + | |
867 | + if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]); | |
868 | + | |
869 | + M(r[3], r[0], r[1]); | |
870 | + return 0; | |
871 | + } | |
872 | + | |
873 | + function crypto_sign_open(m, sm, n, pk) { | |
874 | + var i; | |
875 | + var t = new Uint8Array(32), h = new Uint8Array(64); | |
876 | + var p = [gf(), gf(), gf(), gf()], | |
877 | + q = [gf(), gf(), gf(), gf()]; | |
878 | + | |
879 | + if (n < 64) return -1; | |
880 | + | |
881 | + if (unpackneg(q, pk)) return -1; | |
882 | + | |
883 | + for (i = 0; i < n; i++) m[i] = sm[i]; | |
884 | + for (i = 0; i < 32; i++) m[i+32] = pk[i]; | |
885 | + crypto_hash(h, m, n); | |
886 | + reduce(h); | |
887 | + scalarmult(p, q, h); | |
888 | + | |
889 | + scalarbase(q, sm.subarray(32)); | |
890 | + add(p, q); | |
891 | + pack(t, p); | |
892 | + | |
893 | + n -= 64; | |
894 | + if (crypto_verify_32(sm, 0, t, 0)) { | |
895 | + for (i = 0; i < n; i++) m[i] = 0; | |
896 | + return -1; | |
897 | + } | |
898 | + | |
899 | + for (i = 0; i < n; i++) m[i] = sm[i + 64]; | |
900 | + return n; | |
901 | + } | |
902 | + | |
903 | + var crypto_secretbox_KEYBYTES = 32, | |
904 | + crypto_secretbox_NONCEBYTES = 24, | |
905 | + crypto_secretbox_ZEROBYTES = 32, | |
906 | + crypto_secretbox_BOXZEROBYTES = 16, | |
907 | + crypto_scalarmult_BYTES = 32, | |
908 | + crypto_scalarmult_SCALARBYTES = 32, | |
909 | + crypto_box_PUBLICKEYBYTES = 32, | |
910 | + crypto_box_SECRETKEYBYTES = 32, | |
911 | + crypto_box_BEFORENMBYTES = 32, | |
912 | + crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES, | |
913 | + crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES, | |
914 | + crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES, | |
915 | + crypto_sign_BYTES = 64, | |
916 | + crypto_sign_PUBLICKEYBYTES = 32, | |
917 | + crypto_sign_SECRETKEYBYTES = 64, | |
918 | + crypto_sign_SEEDBYTES = 32, | |
919 | + crypto_hash_BYTES = 64; | |
920 | + | |
921 | + nacl.lowlevel = { | |
922 | + crypto_core_hsalsa20: crypto_core_hsalsa20, | |
923 | + crypto_stream_xor: crypto_stream_xor, | |
924 | + crypto_stream: crypto_stream, | |
925 | + crypto_stream_salsa20_xor: crypto_stream_salsa20_xor, | |
926 | + crypto_stream_salsa20: crypto_stream_salsa20, | |
927 | + crypto_onetimeauth: crypto_onetimeauth, | |
928 | + crypto_onetimeauth_verify: crypto_onetimeauth_verify, | |
929 | + crypto_verify_16: crypto_verify_16, | |
930 | + crypto_verify_32: crypto_verify_32, | |
931 | + crypto_secretbox: crypto_secretbox, | |
932 | + crypto_secretbox_open: crypto_secretbox_open, | |
933 | + crypto_scalarmult: crypto_scalarmult, | |
934 | + crypto_scalarmult_base: crypto_scalarmult_base, | |
935 | + crypto_box_beforenm: crypto_box_beforenm, | |
936 | + crypto_box_afternm: crypto_box_afternm, | |
937 | + crypto_box: crypto_box, | |
938 | + crypto_box_open: crypto_box_open, | |
939 | + crypto_box_keypair: crypto_box_keypair, | |
940 | + crypto_hash: crypto_hash, | |
941 | + crypto_sign: crypto_sign, | |
942 | + crypto_sign_keypair: crypto_sign_keypair, | |
943 | + crypto_sign_open: crypto_sign_open, | |
944 | + | |
945 | + crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES, | |
946 | + crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES, | |
947 | + crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES, | |
948 | + crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES, | |
949 | + crypto_scalarmult_BYTES: crypto_scalarmult_BYTES, | |
950 | + crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES, | |
951 | + crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES, | |
952 | + crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES, | |
953 | + crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES, | |
954 | + crypto_box_NONCEBYTES: crypto_box_NONCEBYTES, | |
955 | + crypto_box_ZEROBYTES: crypto_box_ZEROBYTES, | |
956 | + crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES, | |
957 | + crypto_sign_BYTES: crypto_sign_BYTES, | |
958 | + crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES, | |
959 | + crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES, | |
960 | + crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES, | |
961 | + crypto_hash_BYTES: crypto_hash_BYTES, | |
962 | + | |
963 | + gf: gf, | |
964 | + D: D, | |
965 | + L: L, | |
966 | + pack25519: pack25519, | |
967 | + unpack25519: unpack25519, | |
968 | + M: M, | |
969 | + A: A, | |
970 | + S: S, | |
971 | + Z: Z, | |
972 | + pow2523: pow2523, | |
973 | + add: add, | |
974 | + set25519: set25519, | |
975 | + modL: modL, | |
976 | + scalarmult: scalarmult, | |
977 | + scalarbase: scalarbase, | |
978 | + }; | |
979 | + | |
980 | + /* High-level API */ | |
981 | + | |
982 | + function checkLengths(k, n) { | |
983 | + if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size'); | |
984 | + if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size'); | |
985 | + } | |
986 | + | |
987 | + function checkBoxLengths(pk, sk) { | |
988 | + if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size'); | |
989 | + if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size'); | |
990 | + } | |
991 | + | |
992 | + function checkArrayTypes() { | |
993 | + for (var i = 0; i < arguments.length; i++) { | |
994 | + if (!(arguments[i] instanceof Uint8Array)) | |
995 | + throw new TypeError('unexpected type, use Uint8Array'); | |
996 | + } | |
997 | + } | |
998 | + | |
999 | + function cleanup(arr) { | |
1000 | + for (var i = 0; i < arr.length; i++) arr[i] = 0; | |
1001 | + } | |
1002 | + | |
1003 | + nacl.randomBytes = function(n) { | |
1004 | + var b = new Uint8Array(n); | |
1005 | + randombytes(b, n); | |
1006 | + return b; | |
1007 | + }; | |
1008 | + | |
1009 | + nacl.secretbox = function(msg, nonce, key) { | |
1010 | + checkArrayTypes(msg, nonce, key); | |
1011 | + checkLengths(key, nonce); | |
1012 | + var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length); | |
1013 | + var c = new Uint8Array(m.length); | |
1014 | + for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i]; | |
1015 | + crypto_secretbox(c, m, m.length, nonce, key); | |
1016 | + return c.subarray(crypto_secretbox_BOXZEROBYTES); | |
1017 | + }; | |
1018 | + | |
1019 | + nacl.secretbox.open = function(box, nonce, key) { | |
1020 | + checkArrayTypes(box, nonce, key); | |
1021 | + checkLengths(key, nonce); | |
1022 | + var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length); | |
1023 | + var m = new Uint8Array(c.length); | |
1024 | + for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i]; | |
1025 | + if (c.length < 32) return null; | |
1026 | + if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null; | |
1027 | + return m.subarray(crypto_secretbox_ZEROBYTES); | |
1028 | + }; | |
1029 | + | |
1030 | + nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES; | |
1031 | + nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES; | |
1032 | + nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES; | |
1033 | + | |
1034 | + nacl.scalarMult = function(n, p) { | |
1035 | + checkArrayTypes(n, p); | |
1036 | + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); | |
1037 | + if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size'); | |
1038 | + var q = new Uint8Array(crypto_scalarmult_BYTES); | |
1039 | + crypto_scalarmult(q, n, p); | |
1040 | + return q; | |
1041 | + }; | |
1042 | + | |
1043 | + nacl.scalarMult.base = function(n) { | |
1044 | + checkArrayTypes(n); | |
1045 | + if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size'); | |
1046 | + var q = new Uint8Array(crypto_scalarmult_BYTES); | |
1047 | + crypto_scalarmult_base(q, n); | |
1048 | + return q; | |
1049 | + }; | |
1050 | + | |
1051 | + nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES; | |
1052 | + nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES; | |
1053 | + | |
1054 | + nacl.box = function(msg, nonce, publicKey, secretKey) { | |
1055 | + var k = nacl.box.before(publicKey, secretKey); | |
1056 | + return nacl.secretbox(msg, nonce, k); | |
1057 | + }; | |
1058 | + | |
1059 | + nacl.box.before = function(publicKey, secretKey) { | |
1060 | + checkArrayTypes(publicKey, secretKey); | |
1061 | + checkBoxLengths(publicKey, secretKey); | |
1062 | + var k = new Uint8Array(crypto_box_BEFORENMBYTES); | |
1063 | + crypto_box_beforenm(k, publicKey, secretKey); | |
1064 | + return k; | |
1065 | + }; | |
1066 | + | |
1067 | + nacl.box.after = nacl.secretbox; | |
1068 | + | |
1069 | + nacl.box.open = function(msg, nonce, publicKey, secretKey) { | |
1070 | + var k = nacl.box.before(publicKey, secretKey); | |
1071 | + return nacl.secretbox.open(msg, nonce, k); | |
1072 | + }; | |
1073 | + | |
1074 | + nacl.box.open.after = nacl.secretbox.open; | |
1075 | + | |
1076 | + nacl.box.keyPair = function() { | |
1077 | + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); | |
1078 | + var sk = new Uint8Array(crypto_box_SECRETKEYBYTES); | |
1079 | + crypto_box_keypair(pk, sk); | |
1080 | + return {publicKey: pk, secretKey: sk}; | |
1081 | + }; | |
1082 | + | |
1083 | + nacl.box.keyPair.fromSecretKey = function(secretKey) { | |
1084 | + checkArrayTypes(secretKey); | |
1085 | + if (secretKey.length !== crypto_box_SECRETKEYBYTES) | |
1086 | + throw new Error('bad secret key size'); | |
1087 | + var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES); | |
1088 | + crypto_scalarmult_base(pk, secretKey); | |
1089 | + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; | |
1090 | + }; | |
1091 | + | |
1092 | + nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES; | |
1093 | + nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES; | |
1094 | + nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES; | |
1095 | + nacl.box.nonceLength = crypto_box_NONCEBYTES; | |
1096 | + nacl.box.overheadLength = nacl.secretbox.overheadLength; | |
1097 | + | |
1098 | + nacl.sign = function(msg, secretKey) { | |
1099 | + checkArrayTypes(msg, secretKey); | |
1100 | + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) | |
1101 | + throw new Error('bad secret key size'); | |
1102 | + var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length); | |
1103 | + crypto_sign(signedMsg, msg, msg.length, secretKey); | |
1104 | + return signedMsg; | |
1105 | + }; | |
1106 | + | |
1107 | + nacl.innerSign = function(msg, secretKey, publicKey) { | |
1108 | + checkArrayTypes(msg, secretKey); | |
1109 | + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) | |
1110 | + throw new Error('bad secret key size'); | |
1111 | + const _msg = Buffer.from(msg,'hex'); | |
1112 | + var signedMsg = new Uint8Array(crypto_sign_BYTES); | |
1113 | + crypto_inner_sign(signedMsg, _msg, _msg.length, secretKey, publicKey); | |
1114 | + return signedMsg; | |
1115 | + }; | |
1116 | + | |
1117 | + nacl.sign.open = function(signedMsg, publicKey) { | |
1118 | + checkArrayTypes(signedMsg, publicKey); | |
1119 | + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) | |
1120 | + throw new Error('bad public key size'); | |
1121 | + var tmp = new Uint8Array(signedMsg.length); | |
1122 | + var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey); | |
1123 | + if (mlen < 0) return null; | |
1124 | + var m = new Uint8Array(mlen); | |
1125 | + for (var i = 0; i < m.length; i++) m[i] = tmp[i]; | |
1126 | + return m; | |
1127 | + }; | |
1128 | + | |
1129 | + nacl.sign.detached = function(msg, secretKey) { | |
1130 | + var signedMsg = nacl.sign(msg, secretKey); | |
1131 | + var sig = new Uint8Array(crypto_sign_BYTES); | |
1132 | + for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i]; | |
1133 | + return sig; | |
1134 | + }; | |
1135 | + | |
1136 | + nacl.sign.detached.verify = function(msg, sig, publicKey) { | |
1137 | + checkArrayTypes(msg, sig, publicKey); | |
1138 | + if (sig.length !== crypto_sign_BYTES) | |
1139 | + throw new Error('bad signature size'); | |
1140 | + if (publicKey.length !== crypto_sign_PUBLICKEYBYTES) | |
1141 | + throw new Error('bad public key size'); | |
1142 | + var sm = new Uint8Array(crypto_sign_BYTES + msg.length); | |
1143 | + var m = new Uint8Array(crypto_sign_BYTES + msg.length); | |
1144 | + var i; | |
1145 | + for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i]; | |
1146 | + for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i]; | |
1147 | + return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0); | |
1148 | + }; | |
1149 | + | |
1150 | + nacl.sign.keyPair = function() { | |
1151 | + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); | |
1152 | + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); | |
1153 | + crypto_sign_keypair(pk, sk); | |
1154 | + return {publicKey: pk, secretKey: sk}; | |
1155 | + }; | |
1156 | + | |
1157 | + nacl.sign.keyPair.fromSecretKey = function(secretKey) { | |
1158 | + checkArrayTypes(secretKey); | |
1159 | + if (secretKey.length !== crypto_sign_SECRETKEYBYTES) | |
1160 | + throw new Error('bad secret key size'); | |
1161 | + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); | |
1162 | + for (var i = 0; i < pk.length; i++) pk[i] = secretKey[32+i]; | |
1163 | + return {publicKey: pk, secretKey: new Uint8Array(secretKey)}; | |
1164 | + }; | |
1165 | + | |
1166 | + nacl.sign.keyPair.fromSeed = function(seed) { | |
1167 | + checkArrayTypes(seed); | |
1168 | + if (seed.length !== crypto_sign_SEEDBYTES) | |
1169 | + throw new Error('bad seed size'); | |
1170 | + var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES); | |
1171 | + var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES); | |
1172 | + for (var i = 0; i < 32; i++) sk[i] = seed[i]; | |
1173 | + crypto_sign_keypair(pk, sk, true); | |
1174 | + return {publicKey: pk, secretKey: sk}; | |
1175 | + }; | |
1176 | + | |
1177 | + nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES; | |
1178 | + nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES; | |
1179 | + nacl.sign.seedLength = crypto_sign_SEEDBYTES; | |
1180 | + nacl.sign.signatureLength = crypto_sign_BYTES; | |
1181 | + | |
1182 | + nacl.hash = function(msg) { | |
1183 | + checkArrayTypes(msg); | |
1184 | + var h = new Uint8Array(crypto_hash_BYTES); | |
1185 | + crypto_hash(h, msg, msg.length); | |
1186 | + return h; | |
1187 | + }; | |
1188 | + | |
1189 | + nacl.hash.hashLength = crypto_hash_BYTES; | |
1190 | + | |
1191 | + nacl.verify = function(x, y) { | |
1192 | + checkArrayTypes(x, y); | |
1193 | + // Zero length arguments are considered not equal. | |
1194 | + if (x.length === 0 || y.length === 0) return false; | |
1195 | + if (x.length !== y.length) return false; | |
1196 | + return (vn(x, 0, y, 0, x.length) === 0) ? true : false; | |
1197 | + }; | |
1198 | + | |
1199 | + nacl.setPRNG = function(fn) { | |
1200 | + randombytes = fn; | |
1201 | + }; | |
1202 | + | |
1203 | + (function() { | |
1204 | + // Initialize PRNG if environment provides CSPRNG. | |
1205 | + // If not, methods calling randombytes will throw. | |
1206 | + var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null; | |
1207 | + if (crypto && crypto.getRandomValues) { | |
1208 | + // Browsers. | |
1209 | + var QUOTA = 65536; | |
1210 | + nacl.setPRNG(function(x, n) { | |
1211 | + var i, v = new Uint8Array(n); | |
1212 | + for (i = 0; i < n; i += QUOTA) { | |
1213 | + crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA))); | |
1214 | + } | |
1215 | + for (i = 0; i < n; i++) x[i] = v[i]; | |
1216 | + cleanup(v); | |
1217 | + }); | |
1218 | + } else if (typeof require !== 'undefined') { | |
1219 | + // Node.js. | |
1220 | + crypto = require('crypto'); | |
1221 | + if (crypto && crypto.randomBytes) { | |
1222 | + nacl.setPRNG(function(x, n) { | |
1223 | + var i, v = crypto.randomBytes(n); | |
1224 | + for (i = 0; i < n; i++) x[i] = v[i]; | |
1225 | + cleanup(v); | |
1226 | + }); | |
1227 | + } | |
1228 | + } | |
1229 | + })(); | |
1230 | + | |
1231 | +})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {})); | |
\ No newline at end of file |
@@ -0,0 +1,17 @@ | ||
1 | +import {SignData} from './signTransaction'; | |
2 | + | |
3 | +function signMessage(message, password, keyJSON) { | |
4 | + if (!(message) || !(password) || !(keyJSON) ){ | |
5 | + throw('Input args are empty'); | |
6 | + } | |
7 | + | |
8 | + let signData = SignData(keyJSON, null, Buffer.from(message, 'utf8'), password); | |
9 | + | |
10 | + let ret = {}; | |
11 | + ret.signature = (new Buffer(signData)).toString('hex') | |
12 | + return ret; | |
13 | +} | |
14 | + | |
15 | +export { | |
16 | + signMessage | |
17 | +}; | |
\ No newline at end of file |
@@ -0,0 +1,46 @@ | ||
1 | +import { decryptKey} from '../key/keystore'; | |
2 | +import {XPrv} from '../key/chainkd'; | |
3 | + | |
4 | + | |
5 | +function signTransaction(transaction, password, keyJSON) { | |
6 | + if (!(transaction) || !(password) || !(keyJSON) ){ | |
7 | + throw('Input args are empty'); | |
8 | + } | |
9 | + let tx = transaction; | |
10 | + let signRet = []; | |
11 | + | |
12 | + for(let k = 0; k<tx.signingInstructions.length; k++){ | |
13 | + const v = tx.signingInstructions[k]; | |
14 | + let path = []; | |
15 | + for(let i = 0; i< v.derivationPath.length; i++ ){ | |
16 | + path[i] = Buffer.from(v.derivationPath[i],"hex"); | |
17 | + } | |
18 | + for(let d of v.signData ){ | |
19 | + | |
20 | + const h = Buffer.from(d, 'hex'); | |
21 | + const signData = SignData(keyJSON, path, h, password); | |
22 | + if(signRet[k] == undefined) { | |
23 | + signRet[k] = []; | |
24 | + } | |
25 | + signRet[k] = signRet[k].concat( (new Buffer(signData)).toString('hex')); | |
26 | + } | |
27 | + } | |
28 | + let ret ={}; | |
29 | + ret.raw_transaction = tx.rawTransaction; | |
30 | + ret.signatures = signRet; | |
31 | + return ret; | |
32 | +} | |
33 | + | |
34 | +function SignData(keyJSON, path, data, password){ | |
35 | + const key = decryptKey(keyJSON, password); | |
36 | + let _xprv = new XPrv(key.xPrv); | |
37 | + if (path && path.length > 0) { | |
38 | + _xprv = _xprv.Derive(path); | |
39 | + } | |
40 | + return _xprv.Sign(data); | |
41 | +} | |
42 | + | |
43 | +export { | |
44 | + signTransaction, | |
45 | + SignData | |
46 | +}; |