· 4 years ago · Feb 18, 2021, 06:08 AM
1<!DOCTYPE html>
2<html>
3<head>
4 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
5 <title>MonKey Gen</title>
6 <style type='text/css'>
7 body { background-color: #dddddd; color: #000000; overflow-y: visible; }
8
9 .warning { font-weight: bold; color: #ff0000; }
10
11 #images { margin: 20px 0; }
12 #images a:visited { opacity: 0.3; display: inline-block; }
13 #images img { margin-right: 5px; border: 2px solid #000000; }
14 #images img:hover { border: 2px solid #ffffff; }
15
16 .buttona
17{
18 background:#436983;
19 border:2px solid #262728;
20 border-radius:4px;
21 color:#f6f6f6;
22 display:inline-block;
23 font-family:courier;
24 font-size:1.4em;
25 font-weight:700;
26 margin:.7em 0;
27 padding:.25em .4em;
28 padding:.33em .4em .25em .4em; /* shift down */
29 text-decoration:none;
30 vertical-align:center;
31}
32.buttona:hover
33{
34 background:#227ec4;
35 color: #f6f6f6;
36}
37 </style>
38</head>
39
40<!-- Styles your button (this is a black square with white text) -->
41<style>
42 .back-to-top {
43 background-color: #000000;
44 color: #FFFFFF;
45 opacity: 0;
46 transition: opacity .6s ease-in-out;
47 z-index: 999;
48 position: fixed;
49 right: 20px;
50 bottom: 20px;
51 width: 50px;
52 height: 50px;
53 box-sizing: border-box;
54 border-radius: 0%;
55 }
56
57 a.back-to-top {
58 font-weight: 1000;
59 letter-spacing: 2px;
60 font-size: 14px;
61 text-transform: uppercase;
62 text-align: center;
63 line-height: 1.6;
64 padding-left: 2px;
65 padding-top: 14px;
66 }
67
68 .back-to-top:hover, .back-to-top:focus, .back-to-top:visited {
69 color: #FFFFFF;
70 }
71
72 .back-to-top.show {
73 opacity: 1;
74 }
75</style>
76
77<!-- Adds the back to top link to your website -->
78<a href="#" id="back-to-top" class="back-to-top" style="display: inline;">Top</a>
79
80<!-- Fades in the button when you scroll down -->
81<script>
82 var link = document.getElementById("back-to-top");
83 var amountScrolled = 250;
84
85 window.addEventListener('scroll', function(e) {
86 if ( window.pageYOffset > amountScrolled ) {
87 link.classList.add('show');
88 } else {
89 link.className = 'back-to-top';
90 }
91 });
92
93<!-- Scrolls to Top -->
94 link.addEventListener('click', function(e) {
95 e.preventDefault();
96
97 var distance = 0 - window.pageYOffset;
98 var increments = distance/(500/16);
99 function animateScroll() {
100 window.scrollBy(0, increments);
101 if (window.pageYOffset <= document.body.offsetTop) {
102 clearInterval(runAnimation);
103 }
104 };
105 // Loop the animation function
106 var runAnimation = setInterval(animateScroll, 16);
107 });
108</script>
109
110<body>
111 <center>
112 <p style="visibility:hidden;height:0px;"><button id="random">Load images</button> <span class="warning">NSFW</span></p>
113 <form id="keyconverter"style="visibility:hidden;height:0px;">
114 <div id="errorboxred"></div>
115
116
117 <label for="fieldseed" style="font-weight:bold;">Seed</label><br />
118 <input type="text" id="fieldseed" onfocus="removedash(this)" oninput="sanitizeandconvert(this.value, this.id);" autocomplete="off" class="form64 copy" />
119 <br />
120
121 <span style="display:none;"
122 <label for="fieldindex" style="font-weight:bold;visibility;hidden;">index:</label>
123 <input type="number" min="0" max="4294967295" id="fieldindex" oninput="sanitizeandconvert(this.value, this.id);" autocomplete="off" class="form8" maxlength="10" value="0" /> (max 4,294,967,295) <br />
124
125
126 <label for="fieldprivatekey" style="font-weight:bold;">Account private key:</label>
127 <input type="text" id="fieldprivatekey" onfocus="removedash(this)" oninput="sanitizeandconvert(this.value, this.id);" autocomplete="off" class="form64 copy" />
128 <br />
129 <label for="fieldpublickey" style="font-weight:bold;">Account public key:</label>
130 <input type="text" id="fieldpublickey" onfocus="removedash(this)" oninput="sanitizeandconvert(this.value, this.id);" autocomplete="off" class="form64 copy" /> <br />
131
132 </span>
133 <label for="fieldaddress" style="font-weight:bold;">Account address:</label>
134 <input type="text" id="fieldaddress" onfocus="removedash(this)" oninput="sanitizeandconvert(this.value, this.id);" autocomplete="off" class="form64 copy" /> <br />
135
136 <label for="fieldseed" style="font-weight:bold;">MonKey</label><br />
137 <img id="monKey" src="https://monkey.banano.cc/api/v1/monkey/ban_364j7whujhdo7kbc4ebnmc9sa91edfw9on9ba1qi4nggieefz7abaxxgyghi?svc=banano.cc&background=true" width="200" height="200" /><br />
138
139 <a class="buttona buttonblue" href="#" role="button" onclick="randomseed(); return false;" >random seed</a>
140 <a class="buttona buttonred" href="#" role="button" onclick="document.getElementById('keyconverter').reset(); return false;" >Clear all fields</a> <br />
141
142
143 </form>
144 <a class="buttona buttonblue" href="#" role="button" onclick="randomseed(); return false;" >Get MonKeys!</a>
145 <p id="info"></p>
146
147 <div id="images" style="background-image: url(https://banano.cc/assets/bg-faucet.svg);"><table style=\"border: 1px solid black;\"></div>
148 </center>
149
150
151
152 <script type="text/javascript">//forked including z-base-32 PR https://github.com/termhn/rai-wallet/blob/8343d22b2709561c9d4d098af1ed0a0c95c6bbca/src/functions.js on 2018-03-06
153// general functions
154
155/*
156var blake = require('blakejs');
157var nanoBase32 = require('nano-base32')
158*/
159
160stringFromHex = function(hex) {
161 var hex = hex.toString();//force conversion
162 var str = '';
163 for (var i = 0; i < hex.length; i += 2)
164 str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
165 return str;
166}
167
168stringToHex = function (str) {
169 var hex = '';
170 for (var i = 0; i < str.length; i++) {
171 hex += '' + str.charCodeAt(i).toString(16);
172 }
173 return hex;
174}
175
176accountFromHexKey = function (hex) {
177 var key_bytes = hex_uint8(hex)
178 var checksum_bytes = blake2b(key_bytes, null, 5).reverse();
179 var checksum = encode(checksum_bytes);
180 var c_account = encode(key_bytes);
181 return 'xrb_' + c_account + checksum;
182};
183
184parseXRBAccount = function(str) {
185 var i = str.indexOf('xrb_');
186 if (i != -1) {
187 var acc = str.slice(i, i + 64);
188 try {
189 keyFromAccount(acc);
190 return acc;
191 } catch (e) {
192 return false;
193 }
194 }
195 return false;
196}
197
198
199dec2hex = function (str, bytes = null) {
200 var dec = str.toString().split(''), sum = [], hex = [], i, s
201 while (dec.length) {
202 s = 1 * dec.shift()
203 for (i = 0; s || i < sum.length; i++) {
204 s += (sum[i] || 0) * 10
205 sum[i] = s % 16
206 s = (s - sum[i]) / 16
207 }
208 }
209 while (sum.length) {
210 hex.push(sum.pop().toString(16));
211 }
212
213 hex = hex.join('');
214
215 if (hex.length % 2 != 0)
216 hex = "0" + hex;
217
218 if (bytes > hex.length / 2) {
219 var diff = bytes - hex.length / 2;
220 for (var i = 0; i < diff; i++)
221 hex = "00" + hex;
222 }
223
224 return hex;
225}
226
227hex2dec = function(s) {
228
229 function add(x, y) {
230 var c = 0, r = [];
231 var x = x.split('').map(Number);
232 var y = y.split('').map(Number);
233 while (x.length || y.length) {
234 var s = (x.pop() || 0) + (y.pop() || 0) + c;
235 r.unshift(s < 10 ? s : s - 10);
236 c = s < 10 ? 0 : 1;
237 }
238 if (c) r.unshift(c);
239 return r.join('');
240 }
241
242 var dec = '0';
243 s.split('').forEach(function (chr) {
244 var n = parseInt(chr, 16);
245 for (var t = 8; t; t >>= 1) {
246 dec = add(dec, dec);
247 if (n & t) dec = add(dec, '1');
248 }
249 });
250 return dec;
251}
252
253hex_uint8 = function (hex) {
254 var length = (hex.length / 2) | 0;
255 var uint8 = new Uint8Array(length);
256 for (let i = 0; i < length; i++) uint8[i] = parseInt(hex.substr(i * 2, 2), 16);
257 return uint8;
258}
259
260uint8_hex = function (uint8) {
261 var hex = "";
262 let aux;
263 for (let i = 0; i < uint8.length; i++) {
264 aux = uint8[i].toString(16).toUpperCase();
265 if (aux.length == 1)
266 aux = '0' + aux;
267 hex += aux;
268 aux = '';
269 }
270 return (hex);
271}
272
273uint4_hex = function (uint4) {
274 var hex = "";
275 for (let i = 0; i < uint4.length; i++) hex += uint4[i].toString(16).toUpperCase();
276 return (hex);
277}
278
279function equal_arrays(array1, array2) {
280 for (let i = 0; i < array1.length; i++) {
281 if (array1[i] != array2[i]) return false;
282 }
283 return true;
284}
285
286keyFromAccount = function(account) {
287 if (
288 ((account.startsWith('nano_1') || account.startsWith('nano_3')) && (account.length == 65)) ||
289 ((account.startsWith('ban_1') || account.startsWith('ban_3')) && (account.length == 64)) ||
290 ((account.startsWith('xrb_1') || account.startsWith('xrb_3')) && (account.length == 64))
291 ) {
292 var account_crop = account.slice(-60);
293 var isValid = /^[13456789abcdefghijkmnopqrstuwxyz]+$/.test(account_crop);
294 if (isValid) {
295 var key_bytes = decode(account_crop.substring(0, 52));
296 var hash_bytes = decode(account_crop.substring(52, 60));
297 var blake_hash = blake2b(key_bytes, null, 5).reverse();
298 if (equal_arrays(hash_bytes, blake_hash)) {
299 var key = uint8_hex(key_bytes).toUpperCase();
300 return key;
301 }
302 else
303 throw "Checksum incorrect. Typo?";
304 }
305 else
306 throw "Illegal characters found.";
307 }
308 throw "Invalid account.";
309}</script><script type="text/javascript">// BLAKE.js v1.0.1
310// Adaptation of https://github.com/dcposch/blakejs
311//
312// Blake2B in pure Javascript
313// Adapted from the reference implementation in RFC7693
314// Ported to Javascript by DC - https://github.com/dcposch
315
316var ERROR_MSG_INPUT = 'Input must be an string, Buffer or Uint8Array'
317
318// For convenience, let people hash a string, not just a Uint8Array
319function normalizeInput (input) {
320 var ret
321 if (input instanceof Uint8Array) {
322 ret = input
323 /*} else if (input instanceof Buffer) {
324 ret = new Uint8Array(input)
325 } else if (typeof (input) === 'string') {
326 ret = new Uint8Array(new Buffer(input, 'utf8'))*/
327 } else {
328 throw new Error(ERROR_MSG_INPUT)
329 }
330 return ret
331}
332
333// Converts a Uint8Array to a hexadecimal string
334// For example, toHex([255, 0, 255]) returns "ff00ff"
335function toHex (bytes) {
336 return Array.prototype.map.call(bytes, function (n) {
337 return (n < 16 ? '0' : '') + n.toString(16)
338 }).join('')
339}
340
341// Converts any value in [0...2^32-1] to an 8-character hex string
342function uint32ToHex (val) {
343 return (0x100000000 + val).toString(16).substring(1)
344}
345
346// 64-bit unsigned addition
347// Sets v[a,a+1] += v[b,b+1]
348// v should be a Uint32Array
349function ADD64AA (v, a, b) {
350 var o0 = v[a] + v[b]
351 var o1 = v[a + 1] + v[b + 1]
352 if (o0 >= 0x100000000) {
353 o1++
354 }
355 v[a] = o0
356 v[a + 1] = o1
357}
358
359// 64-bit unsigned addition
360// Sets v[a,a+1] += b
361// b0 is the low 32 bits of b, b1 represents the high 32 bits
362function ADD64AC (v, a, b0, b1) {
363 var o0 = v[a] + b0
364 if (b0 < 0) {
365 o0 += 0x100000000
366 }
367 var o1 = v[a + 1] + b1
368 if (o0 >= 0x100000000) {
369 o1++
370 }
371 v[a] = o0
372 v[a + 1] = o1
373}
374
375// Little-endian byte access
376function B2B_GET32 (arr, i) {
377 return (arr[i] ^
378 (arr[i + 1] << 8) ^
379 (arr[i + 2] << 16) ^
380 (arr[i + 3] << 24))
381}
382
383// G Mixing function
384// The ROTRs are inlined for speed
385function B2B_G (a, b, c, d, ix, iy) {
386 var x0 = m[ix]
387 var x1 = m[ix + 1]
388 var y0 = m[iy]
389 var y1 = m[iy + 1]
390
391 ADD64AA(v, a, b) // v[a,a+1] += v[b,b+1] ... in JS we must store a uint64 as two uint32s
392 ADD64AC(v, a, x0, x1) // v[a, a+1] += x ... x0 is the low 32 bits of x, x1 is the high 32 bits
393
394 // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated to the right by 32 bits
395 var xor0 = v[d] ^ v[a]
396 var xor1 = v[d + 1] ^ v[a + 1]
397 v[d] = xor1
398 v[d + 1] = xor0
399
400 ADD64AA(v, c, d)
401
402 // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 24 bits
403 xor0 = v[b] ^ v[c]
404 xor1 = v[b + 1] ^ v[c + 1]
405 v[b] = (xor0 >>> 24) ^ (xor1 << 8)
406 v[b + 1] = (xor1 >>> 24) ^ (xor0 << 8)
407
408 ADD64AA(v, a, b)
409 ADD64AC(v, a, y0, y1)
410
411 // v[d,d+1] = (v[d,d+1] xor v[a,a+1]) rotated right by 16 bits
412 xor0 = v[d] ^ v[a]
413 xor1 = v[d + 1] ^ v[a + 1]
414 v[d] = (xor0 >>> 16) ^ (xor1 << 16)
415 v[d + 1] = (xor1 >>> 16) ^ (xor0 << 16)
416
417 ADD64AA(v, c, d)
418
419 // v[b,b+1] = (v[b,b+1] xor v[c,c+1]) rotated right by 63 bits
420 xor0 = v[b] ^ v[c]
421 xor1 = v[b + 1] ^ v[c + 1]
422 v[b] = (xor1 >>> 31) ^ (xor0 << 1)
423 v[b + 1] = (xor0 >>> 31) ^ (xor1 << 1)
424}
425
426// Initialization Vector
427var BLAKE2B_IV32 = new Uint32Array([
428 0xF3BCC908, 0x6A09E667, 0x84CAA73B, 0xBB67AE85,
429 0xFE94F82B, 0x3C6EF372, 0x5F1D36F1, 0xA54FF53A,
430 0xADE682D1, 0x510E527F, 0x2B3E6C1F, 0x9B05688C,
431 0xFB41BD6B, 0x1F83D9AB, 0x137E2179, 0x5BE0CD19
432])
433
434var SIGMA8 = [
435 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
436 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
437 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
438 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
439 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
440 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
441 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
442 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
443 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
444 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
445 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
446 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
447]
448
449// These are offsets into a uint64 buffer.
450// Multiply them all by 2 to make them offsets into a uint32 buffer,
451// because this is Javascript and we don't have uint64s
452var SIGMA82 = new Uint8Array(SIGMA8.map(function (x) { return x * 2 }))
453
454// Compression function. 'last' flag indicates last block.
455// Note we're representing 16 uint64s as 32 uint32s
456var v = new Uint32Array(32)
457var m = new Uint32Array(32)
458function blake2bCompress (ctx, last) {
459 var i = 0
460
461 // init work variables
462 for (i = 0; i < 16; i++) {
463 v[i] = ctx.h[i]
464 v[i + 16] = BLAKE2B_IV32[i]
465 }
466
467 // low 64 bits of offset
468 v[24] = v[24] ^ ctx.t
469 v[25] = v[25] ^ (ctx.t / 0x100000000)
470 // high 64 bits not supported, offset may not be higher than 2**53-1
471
472 // last block flag set ?
473 if (last) {
474 v[28] = ~v[28]
475 v[29] = ~v[29]
476 }
477
478 // get little-endian words
479 for (i = 0; i < 32; i++) {
480 m[i] = B2B_GET32(ctx.b, 4 * i)
481 }
482
483 // twelve rounds of mixing
484 // uncomment the DebugPrint calls to log the computation
485 // and match the RFC sample documentation
486 // util.debugPrint(' m[16]', m, 64)
487 for (i = 0; i < 12; i++) {
488 // util.debugPrint(' (i=' + (i < 10 ? ' ' : '') + i + ') v[16]', v, 64)
489 B2B_G(0, 8, 16, 24, SIGMA82[i * 16 + 0], SIGMA82[i * 16 + 1])
490 B2B_G(2, 10, 18, 26, SIGMA82[i * 16 + 2], SIGMA82[i * 16 + 3])
491 B2B_G(4, 12, 20, 28, SIGMA82[i * 16 + 4], SIGMA82[i * 16 + 5])
492 B2B_G(6, 14, 22, 30, SIGMA82[i * 16 + 6], SIGMA82[i * 16 + 7])
493 B2B_G(0, 10, 20, 30, SIGMA82[i * 16 + 8], SIGMA82[i * 16 + 9])
494 B2B_G(2, 12, 22, 24, SIGMA82[i * 16 + 10], SIGMA82[i * 16 + 11])
495 B2B_G(4, 14, 16, 26, SIGMA82[i * 16 + 12], SIGMA82[i * 16 + 13])
496 B2B_G(6, 8, 18, 28, SIGMA82[i * 16 + 14], SIGMA82[i * 16 + 15])
497 }
498 // util.debugPrint(' (i=12) v[16]', v, 64)
499
500 for (i = 0; i < 16; i++) {
501 ctx.h[i] = ctx.h[i] ^ v[i] ^ v[i + 16]
502 }
503 // util.debugPrint('h[8]', ctx.h, 64)
504}
505
506// Creates a BLAKE2b hashing context
507// Requires an output length between 1 and 64 bytes
508// Takes an optional Uint8Array key
509function blake2bInit (outlen, key) {
510 if (outlen === 0 || outlen > 64) {
511 throw new Error('Illegal output length, expected 0 < length <= 64')
512 }
513 if (key && key.length > 64) {
514 throw new Error('Illegal key, expected Uint8Array with 0 < length <= 64')
515 }
516
517 // state, 'param block'
518 var ctx = {
519 b: new Uint8Array(128),
520 h: new Uint32Array(16),
521 t: 0, // input count
522 c: 0, // pointer within buffer
523 outlen: outlen // output length in bytes
524 }
525
526 // initialize hash state
527 for (var i = 0; i < 16; i++) {
528 ctx.h[i] = BLAKE2B_IV32[i]
529 }
530 var keylen = key ? key.length : 0
531 ctx.h[0] ^= 0x01010000 ^ (keylen << 8) ^ outlen
532
533 // key the hash, if applicable
534 if (key) {
535 blake2bUpdate(ctx, key)
536 // at the end
537 ctx.c = 128
538 }
539
540 return ctx
541}
542
543// Updates a BLAKE2b streaming hash
544// Requires hash context and Uint8Array (byte array)
545function blake2bUpdate (ctx, input) {
546 for (var i = 0; i < input.length; i++) {
547 if (ctx.c === 128) { // buffer full ?
548 ctx.t += ctx.c // add counters
549 blake2bCompress(ctx, false) // compress (not last)
550 ctx.c = 0 // counter to zero
551 }
552 ctx.b[ctx.c++] = input[i]
553 }
554}
555
556// Completes a BLAKE2b streaming hash
557// Returns a Uint8Array containing the message digest
558function blake2bFinal (ctx) {
559 ctx.t += ctx.c // mark last block offset
560
561 while (ctx.c < 128) { // fill up with zeros
562 ctx.b[ctx.c++] = 0
563 }
564 blake2bCompress(ctx, true) // final block flag = 1
565
566 // little endian convert and store
567 var out = new Uint8Array(ctx.outlen)
568 for (var i = 0; i < ctx.outlen; i++) {
569 out[i] = ctx.h[i >> 2] >> (8 * (i & 3))
570 }
571 return out
572}
573
574// Computes the BLAKE2B hash of a string or byte array, and returns a Uint8Array
575//
576// Returns a n-byte Uint8Array
577//
578// Parameters:
579// - input - the input bytes, as a string, Buffer or Uint8Array
580// - key - optional key Uint8Array, up to 64 bytes
581// - outlen - optional output length in bytes, default 64
582function blake2b (input, key, outlen) {
583 // preprocess inputs
584 outlen = outlen || 64
585 input = normalizeInput(input)
586
587 // do the math
588 var ctx = blake2bInit(outlen, key)
589 blake2bUpdate(ctx, input)
590 return blake2bFinal(ctx)
591}
592
593// Computes the BLAKE2B hash of a string or byte array
594//
595// Returns an n-byte hash in hex, all lowercase
596//
597// Parameters:
598// - input - the input bytes, as a string, Buffer, or Uint8Array
599// - key - optional key Uint8Array, up to 64 bytes
600// - outlen - optional output length in bytes, default 64
601function blake2bHex (input, key, outlen) {
602 var output = blake2b(input, key, outlen)
603 return toHex(output)
604}
605
606</script><script type="text/javascript">// forked from https://github.com/jaimehgb/tweetnacl-js/blob/master/nacl.js on 2018-03-06
607
608(function(nacl) {
609'use strict';
610
611
612// Ported in 2014 by Dmitry Chestnykh and Devi Mandiri.
613// Public domain.
614//
615// Implementation derived from TweetNaCl version 20140427.
616// See for details: http://tweetnacl.cr.yp.to/
617
618var u64 = function(h, l) { this.hi = h|0 >>> 0; this.lo = l|0 >>> 0; };
619var gf = function(init) {
620 var i, r = new Float64Array(16);
621 if (init) for (i = 0; i < init.length; i++) r[i] = init[i];
622 return r;
623};
624
625// Pluggable, initialized in high-level API below.
626var randombytes = function(/* x, n */) { throw new Error('no PRNG'); };
627
628
629var _0 = new Uint8Array(16);
630var _9 = new Uint8Array(32); _9[0] = 9;
631
632var gf0 = gf(),
633 gf1 = gf([1]),
634 _121665 = gf([0xdb41, 1]),
635 D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203]),
636 D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406]),
637 X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169]),
638 Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666]),
639 I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83]);
640
641function L32(x, c) { return (x << c) | (x >>> (32 - c)); }
642
643function ld32(x, i) {
644 var u = x[i+3] & 0xff;
645 u = (u<<8)|(x[i+2] & 0xff);
646 u = (u<<8)|(x[i+1] & 0xff);
647 return (u<<8)|(x[i+0] & 0xff);
648}
649
650function dl64(x, i) {
651 var h = (x[i] << 24) | (x[i+1] << 16) | (x[i+2] << 8) | x[i+3];
652 var l = (x[i+4] << 24) | (x[i+5] << 16) | (x[i+6] << 8) | x[i+7];
653 return new u64(h, l);
654}
655
656function st32(x, j, u) {
657 var i;
658 for (i = 0; i < 4; i++) { x[j+i] = u & 255; u >>>= 8; }
659}
660
661function ts64(x, i, u) {
662 x[i] = (u.hi >> 24) & 0xff;
663 x[i+1] = (u.hi >> 16) & 0xff;
664 x[i+2] = (u.hi >> 8) & 0xff;
665 x[i+3] = u.hi & 0xff;
666 x[i+4] = (u.lo >> 24) & 0xff;
667 x[i+5] = (u.lo >> 16) & 0xff;
668 x[i+6] = (u.lo >> 8) & 0xff;
669 x[i+7] = u.lo & 0xff;
670}
671
672function vn(x, xi, y, yi, n) {
673 var i,d = 0;
674 for (i = 0; i < n; i++) d |= x[xi+i]^y[yi+i];
675 return (1 & ((d - 1) >>> 8)) - 1;
676}
677
678function crypto_verify_16(x, xi, y, yi) {
679 return vn(x,xi,y,yi,16);
680}
681
682function crypto_verify_32(x, xi, y, yi) {
683 return vn(x,xi,y,yi,32);
684}
685
686function core(out,inp,k,c,h) {
687 var w = new Uint32Array(16), x = new Uint32Array(16),
688 y = new Uint32Array(16), t = new Uint32Array(4);
689 var i, j, m;
690
691 for (i = 0; i < 4; i++) {
692 x[5*i] = ld32(c, 4*i);
693 x[1+i] = ld32(k, 4*i);
694 x[6+i] = ld32(inp, 4*i);
695 x[11+i] = ld32(k, 16+4*i);
696 }
697
698 for (i = 0; i < 16; i++) y[i] = x[i];
699
700 for (i = 0; i < 20; i++) {
701 for (j = 0; j < 4; j++) {
702 for (m = 0; m < 4; m++) t[m] = x[(5*j+4*m)%16];
703 t[1] ^= L32((t[0]+t[3])|0, 7);
704 t[2] ^= L32((t[1]+t[0])|0, 9);
705 t[3] ^= L32((t[2]+t[1])|0,13);
706 t[0] ^= L32((t[3]+t[2])|0,18);
707 for (m = 0; m < 4; m++) w[4*j+(j+m)%4] = t[m];
708 }
709 for (m = 0; m < 16; m++) x[m] = w[m];
710 }
711
712 if (h) {
713 for (i = 0; i < 16; i++) x[i] = (x[i] + y[i]) | 0;
714 for (i = 0; i < 4; i++) {
715 x[5*i] = (x[5*i] - ld32(c, 4*i)) | 0;
716 x[6+i] = (x[6+i] - ld32(inp, 4*i)) | 0;
717 }
718 for (i = 0; i < 4; i++) {
719 st32(out,4*i,x[5*i]);
720 st32(out,16+4*i,x[6+i]);
721 }
722 } else {
723 for (i = 0; i < 16; i++) st32(out, 4 * i, (x[i] + y[i]) | 0);
724 }
725}
726
727function crypto_core_salsa20(out,inp,k,c) {
728 core(out,inp,k,c,false);
729 return 0;
730}
731
732function crypto_core_hsalsa20(out,inp,k,c) {
733 core(out,inp,k,c,true);
734 return 0;
735}
736
737var sigma = new Uint8Array([101, 120, 112, 97, 110, 100, 32, 51, 50, 45, 98, 121, 116, 101, 32, 107]);
738 // "expand 32-byte k"
739
740function crypto_stream_salsa20_xor(c,cpos,m,mpos,b,n,k) {
741 var z = new Uint8Array(16), x = new Uint8Array(64);
742 var u, i;
743 if (!b) return 0;
744 for (i = 0; i < 16; i++) z[i] = 0;
745 for (i = 0; i < 8; i++) z[i] = n[i];
746 while (b >= 64) {
747 crypto_core_salsa20(x,z,k,sigma);
748 for (i = 0; i < 64; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];
749 u = 1;
750 for (i = 8; i < 16; i++) {
751 u = u + (z[i] & 0xff) | 0;
752 z[i] = u & 0xff;
753 u >>>= 8;
754 }
755 b -= 64;
756 cpos += 64;
757 if (m) mpos += 64;
758 }
759 if (b > 0) {
760 crypto_core_salsa20(x,z,k,sigma);
761 for (i = 0; i < b; i++) c[cpos+i] = (m?m[mpos+i]:0) ^ x[i];
762 }
763 return 0;
764}
765
766function crypto_stream_salsa20(c,cpos,d,n,k) {
767 return crypto_stream_salsa20_xor(c,cpos,null,0,d,n,k);
768}
769
770function crypto_stream(c,cpos,d,n,k) {
771 var s = new Uint8Array(32);
772 crypto_core_hsalsa20(s,n,k,sigma);
773 return crypto_stream_salsa20(c,cpos,d,n.subarray(16),s);
774}
775
776function crypto_stream_xor(c,cpos,m,mpos,d,n,k) {
777 var s = new Uint8Array(32);
778 crypto_core_hsalsa20(s,n,k,sigma);
779 return crypto_stream_salsa20_xor(c,cpos,m,mpos,d,n.subarray(16),s);
780}
781
782function add1305(h, c) {
783 var j, u = 0;
784 for (j = 0; j < 17; j++) {
785 u = (u + ((h[j] + c[j]) | 0)) | 0;
786 h[j] = u & 255;
787 u >>>= 8;
788 }
789}
790
791var minusp = new Uint32Array([
792 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
793]);
794
795function crypto_onetimeauth(out, outpos, m, mpos, n, k) {
796 var s, i, j, u;
797 var x = new Uint32Array(17), r = new Uint32Array(17),
798 h = new Uint32Array(17), c = new Uint32Array(17),
799 g = new Uint32Array(17);
800 for (j = 0; j < 17; j++) r[j]=h[j]=0;
801 for (j = 0; j < 16; j++) r[j]=k[j];
802 r[3]&=15;
803 r[4]&=252;
804 r[7]&=15;
805 r[8]&=252;
806 r[11]&=15;
807 r[12]&=252;
808 r[15]&=15;
809
810 while (n > 0) {
811 for (j = 0; j < 17; j++) c[j] = 0;
812 for (j = 0; (j < 16) && (j < n); ++j) c[j] = m[mpos+j];
813 c[j] = 1;
814 mpos += j; n -= j;
815 add1305(h,c);
816 for (i = 0; i < 17; i++) {
817 x[i] = 0;
818 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;
819 }
820 for (i = 0; i < 17; i++) h[i] = x[i];
821 u = 0;
822 for (j = 0; j < 16; j++) {
823 u = (u + h[j]) | 0;
824 h[j] = u & 255;
825 u >>>= 8;
826 }
827 u = (u + h[16]) | 0; h[16] = u & 3;
828 u = (5 * (u >>> 2)) | 0;
829 for (j = 0; j < 16; j++) {
830 u = (u + h[j]) | 0;
831 h[j] = u & 255;
832 u >>>= 8;
833 }
834 u = (u + h[16]) | 0; h[16] = u;
835 }
836
837 for (j = 0; j < 17; j++) g[j] = h[j];
838 add1305(h,minusp);
839 s = (-(h[16] >>> 7) | 0);
840 for (j = 0; j < 17; j++) h[j] ^= s & (g[j] ^ h[j]);
841
842 for (j = 0; j < 16; j++) c[j] = k[j + 16];
843 c[16] = 0;
844 add1305(h,c);
845 for (j = 0; j < 16; j++) out[outpos+j] = h[j];
846 return 0;
847}
848
849function crypto_onetimeauth_verify(h, hpos, m, mpos, n, k) {
850 var x = new Uint8Array(16);
851 crypto_onetimeauth(x,0,m,mpos,n,k);
852 return crypto_verify_16(h,hpos,x,0);
853}
854
855function crypto_secretbox(c,m,d,n,k) {
856 var i;
857 if (d < 32) return -1;
858 crypto_stream_xor(c,0,m,0,d,n,k);
859 crypto_onetimeauth(c, 16, c, 32, d - 32, c);
860 for (i = 0; i < 16; i++) c[i] = 0;
861 return 0;
862}
863
864function crypto_secretbox_open(m,c,d,n,k) {
865 var i;
866 var x = new Uint8Array(32);
867 if (d < 32) return -1;
868 crypto_stream(x,0,32,n,k);
869 if (crypto_onetimeauth_verify(c, 16,c, 32,d - 32,x) !== 0) return -1;
870 crypto_stream_xor(m,0,c,0,d,n,k);
871 for (i = 0; i < 32; i++) m[i] = 0;
872 return 0;
873}
874
875function set25519(r, a) {
876 var i;
877 for (i = 0; i < 16; i++) r[i] = a[i]|0;
878}
879
880function car25519(o) {
881 var c;
882 var i;
883 for (i = 0; i < 16; i++) {
884 o[i] += 65536;
885 c = Math.floor(o[i] / 65536);
886 o[(i+1)*(i<15?1:0)] += c - 1 + 37 * (c-1) * (i===15?1:0);
887 o[i] -= (c * 65536);
888 }
889}
890
891function sel25519(p, q, b) {
892 var t, c = ~(b-1);
893 for (var i = 0; i < 16; i++) {
894 t = c & (p[i] ^ q[i]);
895 p[i] ^= t;
896 q[i] ^= t;
897 }
898}
899
900function pack25519(o, n) {
901 var i, j, b;
902 var m = gf(), t = gf();
903 for (i = 0; i < 16; i++) t[i] = n[i];
904 car25519(t);
905 car25519(t);
906 car25519(t);
907 for (j = 0; j < 2; j++) {
908 m[0] = t[0] - 0xffed;
909 for (i = 1; i < 15; i++) {
910 m[i] = t[i] - 0xffff - ((m[i-1]>>16) & 1);
911 m[i-1] &= 0xffff;
912 }
913 m[15] = t[15] - 0x7fff - ((m[14]>>16) & 1);
914 b = (m[15]>>16) & 1;
915 m[14] &= 0xffff;
916 sel25519(t, m, 1-b);
917 }
918 for (i = 0; i < 16; i++) {
919 o[2*i] = t[i] & 0xff;
920 o[2*i+1] = t[i]>>8;
921 }
922}
923
924function neq25519(a, b) {
925 var c = new Uint8Array(32), d = new Uint8Array(32);
926 pack25519(c, a);
927 pack25519(d, b);
928 return crypto_verify_32(c, 0, d, 0);
929}
930
931function par25519(a) {
932 var d = new Uint8Array(32);
933 pack25519(d, a);
934 return d[0] & 1;
935}
936
937function unpack25519(o, n) {
938 var i;
939 for (i = 0; i < 16; i++) o[i] = n[2*i] + (n[2*i+1] << 8);
940 o[15] &= 0x7fff;
941}
942
943function A(o, a, b) {
944 var i;
945 for (i = 0; i < 16; i++) o[i] = (a[i] + b[i])|0;
946}
947
948function Z(o, a, b) {
949 var i;
950 for (i = 0; i < 16; i++) o[i] = (a[i] - b[i])|0;
951}
952
953function M(o, a, b) {
954 var i, j, t = new Float64Array(31);
955 for (i = 0; i < 31; i++) t[i] = 0;
956 for (i = 0; i < 16; i++) {
957 for (j = 0; j < 16; j++) {
958 t[i+j] += a[i] * b[j];
959 }
960 }
961 for (i = 0; i < 15; i++) {
962 t[i] += 38 * t[i+16];
963 }
964 for (i = 0; i < 16; i++) o[i] = t[i];
965 car25519(o);
966 car25519(o);
967}
968
969function S(o, a) {
970 M(o, a, a);
971}
972
973function inv25519(o, i) {
974 var c = gf();
975 var a;
976 for (a = 0; a < 16; a++) c[a] = i[a];
977 for (a = 253; a >= 0; a--) {
978 S(c, c);
979 if(a !== 2 && a !== 4) M(c, c, i);
980 }
981 for (a = 0; a < 16; a++) o[a] = c[a];
982}
983
984function pow2523(o, i) {
985 var c = gf();
986 var a;
987 for (a = 0; a < 16; a++) c[a] = i[a];
988 for (a = 250; a >= 0; a--) {
989 S(c, c);
990 if(a !== 1) M(c, c, i);
991 }
992 for (a = 0; a < 16; a++) o[a] = c[a];
993}
994
995function crypto_scalarmult(q, n, p) {
996 var z = new Uint8Array(32);
997 var x = new Float64Array(80), r, i;
998 var a = gf(), b = gf(), c = gf(),
999 d = gf(), e = gf(), f = gf();
1000 for (i = 0; i < 31; i++) z[i] = n[i];
1001 z[31]=(n[31]&127)|64;
1002 z[0]&=248;
1003 unpack25519(x,p);
1004 for (i = 0; i < 16; i++) {
1005 b[i]=x[i];
1006 d[i]=a[i]=c[i]=0;
1007 }
1008 a[0]=d[0]=1;
1009 for (i=254; i>=0; --i) {
1010 r=(z[i>>>3]>>>(i&7))&1;
1011 sel25519(a,b,r);
1012 sel25519(c,d,r);
1013 A(e,a,c);
1014 Z(a,a,c);
1015 A(c,b,d);
1016 Z(b,b,d);
1017 S(d,e);
1018 S(f,a);
1019 M(a,c,a);
1020 M(c,b,e);
1021 A(e,a,c);
1022 Z(a,a,c);
1023 S(b,a);
1024 Z(c,d,f);
1025 M(a,c,_121665);
1026 A(a,a,d);
1027 M(c,c,a);
1028 M(a,d,f);
1029 M(d,b,x);
1030 S(b,e);
1031 sel25519(a,b,r);
1032 sel25519(c,d,r);
1033 }
1034 for (i = 0; i < 16; i++) {
1035 x[i+16]=a[i];
1036 x[i+32]=c[i];
1037 x[i+48]=b[i];
1038 x[i+64]=d[i];
1039 }
1040 var x32 = x.subarray(32);
1041 var x16 = x.subarray(16);
1042 inv25519(x32,x32);
1043 M(x16,x16,x32);
1044 pack25519(q,x16);
1045 return 0;
1046}
1047
1048function crypto_scalarmult_base(q, n) {
1049 return crypto_scalarmult(q, n, _9);
1050}
1051
1052function crypto_box_keypair(y, x) {
1053 randombytes(x, 32);
1054 return crypto_scalarmult_base(y, x);
1055}
1056
1057function crypto_box_beforenm(k, y, x) {
1058 var s = new Uint8Array(32);
1059 crypto_scalarmult(s, x, y);
1060 return crypto_core_hsalsa20(k, _0, s, sigma);
1061}
1062
1063var crypto_box_afternm = crypto_secretbox;
1064var crypto_box_open_afternm = crypto_secretbox_open;
1065
1066function crypto_box(c, m, d, n, y, x) {
1067 var k = new Uint8Array(32);
1068 crypto_box_beforenm(k, y, x);
1069 return crypto_box_afternm(c, m, d, n, k);
1070}
1071
1072function crypto_box_open(m, c, d, n, y, x) {
1073 var k = new Uint8Array(32);
1074 crypto_box_beforenm(k, y, x);
1075 return crypto_box_open_afternm(m, c, d, n, k);
1076}
1077
1078function add64() {
1079 var a = 0, b = 0, c = 0, d = 0, m16 = 65535, l, h, i;
1080 for (i = 0; i < arguments.length; i++) {
1081 l = arguments[i].lo;
1082 h = arguments[i].hi;
1083 a += (l & m16); b += (l >>> 16);
1084 c += (h & m16); d += (h >>> 16);
1085 }
1086
1087 b += (a >>> 16);
1088 c += (b >>> 16);
1089 d += (c >>> 16);
1090
1091 return new u64((c & m16) | (d << 16), (a & m16) | (b << 16));
1092}
1093
1094function shr64(x, c) {
1095 return new u64((x.hi >>> c), (x.lo >>> c) | (x.hi << (32 - c)));
1096}
1097
1098function xor64() {
1099 var l = 0, h = 0, i;
1100 for (i = 0; i < arguments.length; i++) {
1101 l ^= arguments[i].lo;
1102 h ^= arguments[i].hi;
1103 }
1104 return new u64(h, l);
1105}
1106
1107function R(x, c) {
1108 var h, l, c1 = 32 - c;
1109 if (c < 32) {
1110 h = (x.hi >>> c) | (x.lo << c1);
1111 l = (x.lo >>> c) | (x.hi << c1);
1112 } else if (c < 64) {
1113 h = (x.lo >>> c) | (x.hi << c1);
1114 l = (x.hi >>> c) | (x.lo << c1);
1115 }
1116 return new u64(h, l);
1117}
1118
1119function Ch(x, y, z) {
1120 var h = (x.hi & y.hi) ^ (~x.hi & z.hi),
1121 l = (x.lo & y.lo) ^ (~x.lo & z.lo);
1122 return new u64(h, l);
1123}
1124
1125function Maj(x, y, z) {
1126 var h = (x.hi & y.hi) ^ (x.hi & z.hi) ^ (y.hi & z.hi),
1127 l = (x.lo & y.lo) ^ (x.lo & z.lo) ^ (y.lo & z.lo);
1128 return new u64(h, l);
1129}
1130
1131function Sigma0(x) { return xor64(R(x,28), R(x,34), R(x,39)); }
1132function Sigma1(x) { return xor64(R(x,14), R(x,18), R(x,41)); }
1133function sigma0(x) { return xor64(R(x, 1), R(x, 8), shr64(x,7)); }
1134function sigma1(x) { return xor64(R(x,19), R(x,61), shr64(x,6)); }
1135
1136var K = [
1137 new u64(0x428a2f98, 0xd728ae22), new u64(0x71374491, 0x23ef65cd),
1138 new u64(0xb5c0fbcf, 0xec4d3b2f), new u64(0xe9b5dba5, 0x8189dbbc),
1139 new u64(0x3956c25b, 0xf348b538), new u64(0x59f111f1, 0xb605d019),
1140 new u64(0x923f82a4, 0xaf194f9b), new u64(0xab1c5ed5, 0xda6d8118),
1141 new u64(0xd807aa98, 0xa3030242), new u64(0x12835b01, 0x45706fbe),
1142 new u64(0x243185be, 0x4ee4b28c), new u64(0x550c7dc3, 0xd5ffb4e2),
1143 new u64(0x72be5d74, 0xf27b896f), new u64(0x80deb1fe, 0x3b1696b1),
1144 new u64(0x9bdc06a7, 0x25c71235), new u64(0xc19bf174, 0xcf692694),
1145 new u64(0xe49b69c1, 0x9ef14ad2), new u64(0xefbe4786, 0x384f25e3),
1146 new u64(0x0fc19dc6, 0x8b8cd5b5), new u64(0x240ca1cc, 0x77ac9c65),
1147 new u64(0x2de92c6f, 0x592b0275), new u64(0x4a7484aa, 0x6ea6e483),
1148 new u64(0x5cb0a9dc, 0xbd41fbd4), new u64(0x76f988da, 0x831153b5),
1149 new u64(0x983e5152, 0xee66dfab), new u64(0xa831c66d, 0x2db43210),
1150 new u64(0xb00327c8, 0x98fb213f), new u64(0xbf597fc7, 0xbeef0ee4),
1151 new u64(0xc6e00bf3, 0x3da88fc2), new u64(0xd5a79147, 0x930aa725),
1152 new u64(0x06ca6351, 0xe003826f), new u64(0x14292967, 0x0a0e6e70),
1153 new u64(0x27b70a85, 0x46d22ffc), new u64(0x2e1b2138, 0x5c26c926),
1154 new u64(0x4d2c6dfc, 0x5ac42aed), new u64(0x53380d13, 0x9d95b3df),
1155 new u64(0x650a7354, 0x8baf63de), new u64(0x766a0abb, 0x3c77b2a8),
1156 new u64(0x81c2c92e, 0x47edaee6), new u64(0x92722c85, 0x1482353b),
1157 new u64(0xa2bfe8a1, 0x4cf10364), new u64(0xa81a664b, 0xbc423001),
1158 new u64(0xc24b8b70, 0xd0f89791), new u64(0xc76c51a3, 0x0654be30),
1159 new u64(0xd192e819, 0xd6ef5218), new u64(0xd6990624, 0x5565a910),
1160 new u64(0xf40e3585, 0x5771202a), new u64(0x106aa070, 0x32bbd1b8),
1161 new u64(0x19a4c116, 0xb8d2d0c8), new u64(0x1e376c08, 0x5141ab53),
1162 new u64(0x2748774c, 0xdf8eeb99), new u64(0x34b0bcb5, 0xe19b48a8),
1163 new u64(0x391c0cb3, 0xc5c95a63), new u64(0x4ed8aa4a, 0xe3418acb),
1164 new u64(0x5b9cca4f, 0x7763e373), new u64(0x682e6ff3, 0xd6b2b8a3),
1165 new u64(0x748f82ee, 0x5defb2fc), new u64(0x78a5636f, 0x43172f60),
1166 new u64(0x84c87814, 0xa1f0ab72), new u64(0x8cc70208, 0x1a6439ec),
1167 new u64(0x90befffa, 0x23631e28), new u64(0xa4506ceb, 0xde82bde9),
1168 new u64(0xbef9a3f7, 0xb2c67915), new u64(0xc67178f2, 0xe372532b),
1169 new u64(0xca273ece, 0xea26619c), new u64(0xd186b8c7, 0x21c0c207),
1170 new u64(0xeada7dd6, 0xcde0eb1e), new u64(0xf57d4f7f, 0xee6ed178),
1171 new u64(0x06f067aa, 0x72176fba), new u64(0x0a637dc5, 0xa2c898a6),
1172 new u64(0x113f9804, 0xbef90dae), new u64(0x1b710b35, 0x131c471b),
1173 new u64(0x28db77f5, 0x23047d84), new u64(0x32caab7b, 0x40c72493),
1174 new u64(0x3c9ebe0a, 0x15c9bebc), new u64(0x431d67c4, 0x9c100d4c),
1175 new u64(0x4cc5d4be, 0xcb3e42b6), new u64(0x597f299c, 0xfc657e2a),
1176 new u64(0x5fcb6fab, 0x3ad6faec), new u64(0x6c44198c, 0x4a475817)
1177];
1178
1179function crypto_hashblocks(x, m, n) {
1180 var z = [], b = [], a = [], w = [], t, i, j;
1181
1182 for (i = 0; i < 8; i++) z[i] = a[i] = dl64(x, 8*i);
1183
1184 var pos = 0;
1185 while (n >= 128) {
1186 for (i = 0; i < 16; i++) w[i] = dl64(m, 8*i+pos);
1187 for (i = 0; i < 80; i++) {
1188 for (j = 0; j < 8; j++) b[j] = a[j];
1189 t = add64(a[7], Sigma1(a[4]), Ch(a[4], a[5], a[6]), K[i], w[i%16]);
1190 b[7] = add64(t, Sigma0(a[0]), Maj(a[0], a[1], a[2]));
1191 b[3] = add64(b[3], t);
1192 for (j = 0; j < 8; j++) a[(j+1)%8] = b[j];
1193 if (i%16 === 15) {
1194 for (j = 0; j < 16; j++) {
1195 w[j] = add64(w[j], w[(j+9)%16], sigma0(w[(j+1)%16]), sigma1(w[(j+14)%16]));
1196 }
1197 }
1198 }
1199
1200 for (i = 0; i < 8; i++) {
1201 a[i] = add64(a[i], z[i]);
1202 z[i] = a[i];
1203 }
1204
1205 pos += 128;
1206 n -= 128;
1207 }
1208
1209 for (i = 0; i < 8; i++) ts64(x, 8*i, z[i]);
1210 return n;
1211}
1212
1213var iv = new Uint8Array([
1214 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
1215 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
1216 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
1217 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
1218 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
1219 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
1220 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
1221 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
1222]);
1223
1224function crypto_hash(out, m, n) {
1225 var h = new Uint8Array(64), x = new Uint8Array(256);
1226 var i, b = n;
1227
1228 for (i = 0; i < 64; i++) h[i] = iv[i];
1229
1230 crypto_hashblocks(h, m, n);
1231 n %= 128;
1232
1233 for (i = 0; i < 256; i++) x[i] = 0;
1234 for (i = 0; i < n; i++) x[i] = m[b-n+i];
1235 x[n] = 128;
1236
1237 n = 256-128*(n<112?1:0);
1238 x[n-9] = 0;
1239 ts64(x, n-8, new u64((b / 0x20000000) | 0, b << 3));
1240 crypto_hashblocks(h, x, n);
1241
1242 for (i = 0; i < 64; i++) out[i] = h[i];
1243
1244 return 0;
1245}
1246
1247function add(p, q) {
1248 var a = gf(), b = gf(), c = gf(),
1249 d = gf(), e = gf(), f = gf(),
1250 g = gf(), h = gf(), t = gf();
1251
1252 Z(a, p[1], p[0]);
1253 Z(t, q[1], q[0]);
1254 M(a, a, t);
1255 A(b, p[0], p[1]);
1256 A(t, q[0], q[1]);
1257 M(b, b, t);
1258 M(c, p[3], q[3]);
1259 M(c, c, D2);
1260 M(d, p[2], q[2]);
1261 A(d, d, d);
1262 Z(e, b, a);
1263 Z(f, d, c);
1264 A(g, d, c);
1265 A(h, b, a);
1266
1267 M(p[0], e, f);
1268 M(p[1], h, g);
1269 M(p[2], g, f);
1270 M(p[3], e, h);
1271}
1272
1273function cswap(p, q, b) {
1274 var i;
1275 for (i = 0; i < 4; i++) {
1276 sel25519(p[i], q[i], b);
1277 }
1278}
1279
1280function pack(r, p) {
1281 var tx = gf(), ty = gf(), zi = gf();
1282 inv25519(zi, p[2]);
1283 M(tx, p[0], zi);
1284 M(ty, p[1], zi);
1285 pack25519(r, ty);
1286 r[31] ^= par25519(tx) << 7;
1287}
1288
1289function scalarmult(p, q, s) {
1290 var b, i;
1291 set25519(p[0], gf0);
1292 set25519(p[1], gf1);
1293 set25519(p[2], gf1);
1294 set25519(p[3], gf0);
1295 for (i = 255; i >= 0; --i) {
1296 b = (s[(i/8)|0] >> (i&7)) & 1;
1297 cswap(p, q, b);
1298 add(q, p);
1299 add(p, p);
1300 cswap(p, q, b);
1301 }
1302}
1303
1304function scalarbase(p, s) {
1305 var q = [gf(), gf(), gf(), gf()];
1306 set25519(q[0], X);
1307 set25519(q[1], Y);
1308 set25519(q[2], gf1);
1309 M(q[3], X, Y);
1310 scalarmult(p, q, s);
1311}
1312
1313function crypto_sign_keypair(pk, sk, seeded) {
1314 var d = new Uint8Array(64);
1315 var p = [gf(), gf(), gf(), gf()];
1316 var i;
1317
1318 if (!seeded) randombytes(sk, 32);
1319
1320 var context = blake2bInit(64);
1321 blake2bUpdate(context, sk);
1322 d = blake2bFinal(context);
1323
1324 d[0] &= 248;
1325 d[31] &= 127;
1326 d[31] |= 64;
1327
1328 scalarbase(p, d);
1329 pack(pk, p);
1330
1331 return 0;
1332}
1333
1334function derivePublicFromSecret(sk)
1335{
1336 var d = new Uint8Array(64);
1337 var p = [gf(), gf(), gf(), gf()];
1338 var i;
1339 var pk = new Uint8Array(32);
1340 var context = blake2bInit(64);
1341 blake2bUpdate(context, sk);
1342 d = blake2bFinal(context);
1343
1344 d[0] &= 248;
1345 d[31] &= 127;
1346 d[31] |= 64;
1347
1348 scalarbase(p, d);
1349 pack(pk, p);
1350 return pk;
1351}
1352
1353var 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]);
1354
1355function modL(r, x) {
1356 var carry, i, j, k;
1357 for (i = 63; i >= 32; --i) {
1358 carry = 0;
1359 for (j = i - 32, k = i - 12; j < k; ++j) {
1360 x[j] += carry - 16 * x[i] * L[j - (i - 32)];
1361 carry = (x[j] + 128) >> 8;
1362 x[j] -= carry * 256;
1363 }
1364 x[j] += carry;
1365 x[i] = 0;
1366 }
1367 carry = 0;
1368 for (j = 0; j < 32; j++) {
1369 x[j] += carry - (x[31] >> 4) * L[j];
1370 carry = x[j] >> 8;
1371 x[j] &= 255;
1372 }
1373 for (j = 0; j < 32; j++) x[j] -= carry * L[j];
1374 for (i = 0; i < 32; i++) {
1375 x[i+1] += x[i] >> 8;
1376 r[i] = x[i] & 255;
1377 }
1378}
1379
1380function reduce(r) {
1381 var x = new Float64Array(64), i;
1382 for (i = 0; i < 64; i++) x[i] = r[i];
1383 for (i = 0; i < 64; i++) r[i] = 0;
1384 modL(r, x);
1385}
1386
1387// Note: difference from C - smlen returned, not passed as argument.
1388function crypto_sign(sm, m, n, sk) {
1389 var d = new Uint8Array(64), h = new Uint8Array(64), r = new Uint8Array(64);
1390 var i, j, x = new Float64Array(64);
1391 var p = [gf(), gf(), gf(), gf()];
1392
1393 var pk = derivePublicFromSecret(sk);
1394
1395 var context = blake2bInit(64, null);
1396 blake2bUpdate(context, sk);
1397 d = blake2bFinal(context);
1398 d[0] &= 248;
1399 d[31] &= 127;
1400 d[31] |= 64;
1401
1402 var smlen = n + 64;
1403 for (i = 0; i < n; i++) sm[64 + i] = m[i];
1404 for (i = 0; i < 32; i++) sm[32 + i] = d[32 + i];
1405
1406 context = blake2bInit(64, null);
1407 blake2bUpdate(context, sm.subarray(32));
1408 r = blake2bFinal(context);
1409
1410 reduce(r);
1411 scalarbase(p, r);
1412 pack(sm, p);
1413
1414 for (i = 32; i < 64; i++) sm[i] = pk[i-32];
1415
1416 context = blake2bInit(64, null);
1417 blake2bUpdate(context, sm);
1418 h = blake2bFinal(context);
1419
1420 reduce(h);
1421
1422 for (i = 0; i < 64; i++) x[i] = 0;
1423 for (i = 0; i < 32; i++) x[i] = r[i];
1424 for (i = 0; i < 32; i++) {
1425 for (j = 0; j < 32; j++) {
1426 x[i+j] += h[i] * d[j];
1427 }
1428 }
1429
1430 modL(sm.subarray(32), x);
1431 return smlen;
1432}
1433
1434function unpackneg(r, p) {
1435 var t = gf(), chk = gf(), num = gf(),
1436 den = gf(), den2 = gf(), den4 = gf(),
1437 den6 = gf();
1438
1439 set25519(r[2], gf1);
1440 unpack25519(r[1], p);
1441 S(num, r[1]);
1442 M(den, num, D);
1443 Z(num, num, r[2]);
1444 A(den, r[2], den);
1445
1446 S(den2, den);
1447 S(den4, den2);
1448 M(den6, den4, den2);
1449 M(t, den6, num);
1450 M(t, t, den);
1451
1452 pow2523(t, t);
1453 M(t, t, num);
1454 M(t, t, den);
1455 M(t, t, den);
1456 M(r[0], t, den);
1457
1458 S(chk, r[0]);
1459 M(chk, chk, den);
1460 if (neq25519(chk, num)) M(r[0], r[0], I);
1461
1462 S(chk, r[0]);
1463 M(chk, chk, den);
1464 if (neq25519(chk, num)) return -1;
1465
1466 if (par25519(r[0]) === (p[31]>>7)) Z(r[0], gf0, r[0]);
1467
1468 M(r[3], r[0], r[1]);
1469 return 0;
1470}
1471
1472function crypto_sign_open(m, sm, n, pk) {
1473 var i, mlen;
1474 var t = new Uint8Array(32), h = new Uint8Array(64);
1475 var p = [gf(), gf(), gf(), gf()],
1476 q = [gf(), gf(), gf(), gf()];
1477
1478 mlen = -1;
1479 if (n < 64) return -1;
1480
1481 if (unpackneg(q, pk)) return -1;
1482
1483 for (i = 0; i < n; i++) m[i] = sm[i];
1484 for (i = 0; i < 32; i++) m[i+32] = pk[i];
1485 //crypto_hash(h, m, n);
1486
1487 var context = blake2bInit(64, null);
1488 blake2bUpdate(context, m);
1489 h = blake2bFinal(context);
1490
1491 reduce(h);
1492 scalarmult(p, q, h);
1493
1494 scalarbase(q, sm.subarray(32));
1495 add(p, q);
1496 pack(t, p);
1497
1498 n -= 64;
1499 if (crypto_verify_32(sm, 0, t, 0)) {
1500 for (i = 0; i < n; i++) m[i] = 0;
1501 return -1;
1502 }
1503
1504 for (i = 0; i < n; i++) m[i] = sm[i + 64];
1505 mlen = n;
1506 return mlen;
1507}
1508
1509var crypto_secretbox_KEYBYTES = 32,
1510 crypto_secretbox_NONCEBYTES = 24,
1511 crypto_secretbox_ZEROBYTES = 32,
1512 crypto_secretbox_BOXZEROBYTES = 16,
1513 crypto_scalarmult_BYTES = 32,
1514 crypto_scalarmult_SCALARBYTES = 32,
1515 crypto_box_PUBLICKEYBYTES = 32,
1516 crypto_box_SECRETKEYBYTES = 32,
1517 crypto_box_BEFORENMBYTES = 32,
1518 crypto_box_NONCEBYTES = crypto_secretbox_NONCEBYTES,
1519 crypto_box_ZEROBYTES = crypto_secretbox_ZEROBYTES,
1520 crypto_box_BOXZEROBYTES = crypto_secretbox_BOXZEROBYTES,
1521 crypto_sign_BYTES = 64,
1522 crypto_sign_PUBLICKEYBYTES = 32,
1523 crypto_sign_SECRETKEYBYTES = 32,
1524 crypto_sign_SEEDBYTES = 32,
1525 crypto_hash_BYTES = 64;
1526
1527nacl.lowlevel = {
1528 crypto_core_hsalsa20: crypto_core_hsalsa20,
1529 crypto_stream_xor: crypto_stream_xor,
1530 crypto_stream: crypto_stream,
1531 crypto_stream_salsa20_xor: crypto_stream_salsa20_xor,
1532 crypto_stream_salsa20: crypto_stream_salsa20,
1533 crypto_onetimeauth: crypto_onetimeauth,
1534 crypto_onetimeauth_verify: crypto_onetimeauth_verify,
1535 crypto_verify_16: crypto_verify_16,
1536 crypto_verify_32: crypto_verify_32,
1537 crypto_secretbox: crypto_secretbox,
1538 crypto_secretbox_open: crypto_secretbox_open,
1539 crypto_scalarmult: crypto_scalarmult,
1540 crypto_scalarmult_base: crypto_scalarmult_base,
1541 crypto_box_beforenm: crypto_box_beforenm,
1542 crypto_box_afternm: crypto_box_afternm,
1543 crypto_box: crypto_box,
1544 crypto_box_open: crypto_box_open,
1545 crypto_box_keypair: crypto_box_keypair,
1546 crypto_hash: crypto_hash,
1547 crypto_sign: crypto_sign,
1548 crypto_sign_keypair: crypto_sign_keypair,
1549 crypto_sign_open: crypto_sign_open,
1550
1551 crypto_secretbox_KEYBYTES: crypto_secretbox_KEYBYTES,
1552 crypto_secretbox_NONCEBYTES: crypto_secretbox_NONCEBYTES,
1553 crypto_secretbox_ZEROBYTES: crypto_secretbox_ZEROBYTES,
1554 crypto_secretbox_BOXZEROBYTES: crypto_secretbox_BOXZEROBYTES,
1555 crypto_scalarmult_BYTES: crypto_scalarmult_BYTES,
1556 crypto_scalarmult_SCALARBYTES: crypto_scalarmult_SCALARBYTES,
1557 crypto_box_PUBLICKEYBYTES: crypto_box_PUBLICKEYBYTES,
1558 crypto_box_SECRETKEYBYTES: crypto_box_SECRETKEYBYTES,
1559 crypto_box_BEFORENMBYTES: crypto_box_BEFORENMBYTES,
1560 crypto_box_NONCEBYTES: crypto_box_NONCEBYTES,
1561 crypto_box_ZEROBYTES: crypto_box_ZEROBYTES,
1562 crypto_box_BOXZEROBYTES: crypto_box_BOXZEROBYTES,
1563 crypto_sign_BYTES: crypto_sign_BYTES,
1564 crypto_sign_PUBLICKEYBYTES: crypto_sign_PUBLICKEYBYTES,
1565 crypto_sign_SECRETKEYBYTES: crypto_sign_SECRETKEYBYTES,
1566 crypto_sign_SEEDBYTES: crypto_sign_SEEDBYTES,
1567 crypto_hash_BYTES: crypto_hash_BYTES
1568};
1569
1570/* High-level API */
1571
1572function checkLengths(k, n) {
1573 if (k.length !== crypto_secretbox_KEYBYTES) throw new Error('bad key size');
1574 if (n.length !== crypto_secretbox_NONCEBYTES) throw new Error('bad nonce size');
1575}
1576
1577function checkBoxLengths(pk, sk) {
1578 if (pk.length !== crypto_box_PUBLICKEYBYTES) throw new Error('bad public key size');
1579 if (sk.length !== crypto_box_SECRETKEYBYTES) throw new Error('bad secret key size');
1580}
1581
1582function checkArrayTypes() {
1583 for (var i = 0; i < arguments.length; i++) {
1584 if (!(arguments[i] instanceof Uint8Array))
1585 throw new TypeError('unexpected type, use Uint8Array');
1586 }
1587}
1588
1589function cleanup(arr) {
1590 for (var i = 0; i < arr.length; i++) arr[i] = 0;
1591}
1592
1593nacl.randomBytes = function(n) {
1594 var b = new Uint8Array(n);
1595 randombytes(b, n);
1596 return b;
1597};
1598
1599nacl.secretbox = function(msg, nonce, key) {
1600 checkArrayTypes(msg, nonce, key);
1601 checkLengths(key, nonce);
1602 var m = new Uint8Array(crypto_secretbox_ZEROBYTES + msg.length);
1603 var c = new Uint8Array(m.length);
1604 for (var i = 0; i < msg.length; i++) m[i+crypto_secretbox_ZEROBYTES] = msg[i];
1605 crypto_secretbox(c, m, m.length, nonce, key);
1606 return c.subarray(crypto_secretbox_BOXZEROBYTES);
1607};
1608
1609nacl.secretbox.open = function(box, nonce, key) {
1610 checkArrayTypes(box, nonce, key);
1611 checkLengths(key, nonce);
1612 var c = new Uint8Array(crypto_secretbox_BOXZEROBYTES + box.length);
1613 var m = new Uint8Array(c.length);
1614 for (var i = 0; i < box.length; i++) c[i+crypto_secretbox_BOXZEROBYTES] = box[i];
1615 if (c.length < 32) return null;
1616 if (crypto_secretbox_open(m, c, c.length, nonce, key) !== 0) return null;
1617 return m.subarray(crypto_secretbox_ZEROBYTES);
1618};
1619
1620nacl.secretbox.keyLength = crypto_secretbox_KEYBYTES;
1621nacl.secretbox.nonceLength = crypto_secretbox_NONCEBYTES;
1622nacl.secretbox.overheadLength = crypto_secretbox_BOXZEROBYTES;
1623
1624nacl.scalarMult = function(n, p) {
1625 checkArrayTypes(n, p);
1626 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
1627 if (p.length !== crypto_scalarmult_BYTES) throw new Error('bad p size');
1628 var q = new Uint8Array(crypto_scalarmult_BYTES);
1629 crypto_scalarmult(q, n, p);
1630 return q;
1631};
1632
1633nacl.scalarMult.base = function(n) {
1634 checkArrayTypes(n);
1635 if (n.length !== crypto_scalarmult_SCALARBYTES) throw new Error('bad n size');
1636 var q = new Uint8Array(crypto_scalarmult_BYTES);
1637 crypto_scalarmult_base(q, n);
1638 return q;
1639};
1640
1641nacl.scalarMult.scalarLength = crypto_scalarmult_SCALARBYTES;
1642nacl.scalarMult.groupElementLength = crypto_scalarmult_BYTES;
1643
1644nacl.box = function(msg, nonce, publicKey, secretKey) {
1645 var k = nacl.box.before(publicKey, secretKey);
1646 return nacl.secretbox(msg, nonce, k);
1647};
1648
1649nacl.box.before = function(publicKey, secretKey) {
1650 checkArrayTypes(publicKey, secretKey);
1651 checkBoxLengths(publicKey, secretKey);
1652 var k = new Uint8Array(crypto_box_BEFORENMBYTES);
1653 crypto_box_beforenm(k, publicKey, secretKey);
1654 return k;
1655};
1656
1657nacl.box.after = nacl.secretbox;
1658
1659nacl.box.open = function(msg, nonce, publicKey, secretKey) {
1660 var k = nacl.box.before(publicKey, secretKey);
1661 return nacl.secretbox.open(msg, nonce, k);
1662};
1663
1664nacl.box.open.after = nacl.secretbox.open;
1665
1666nacl.box.keyPair = function() {
1667 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1668 var sk = new Uint8Array(crypto_box_SECRETKEYBYTES);
1669 crypto_box_keypair(pk, sk);
1670 return {publicKey: pk, secretKey: sk};
1671};
1672
1673nacl.box.keyPair.fromSecretKey = function(secretKey) {
1674 checkArrayTypes(secretKey);
1675 if (secretKey.length !== crypto_box_SECRETKEYBYTES)
1676 throw new Error('bad secret key size');
1677 var pk = new Uint8Array(crypto_box_PUBLICKEYBYTES);
1678 crypto_scalarmult_base(pk, secretKey);
1679 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1680};
1681
1682nacl.box.publicKeyLength = crypto_box_PUBLICKEYBYTES;
1683nacl.box.secretKeyLength = crypto_box_SECRETKEYBYTES;
1684nacl.box.sharedKeyLength = crypto_box_BEFORENMBYTES;
1685nacl.box.nonceLength = crypto_box_NONCEBYTES;
1686nacl.box.overheadLength = nacl.secretbox.overheadLength;
1687
1688nacl.sign = function(msg, secretKey) {
1689 checkArrayTypes(msg, secretKey);
1690 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1691 throw new Error('bad secret key size');
1692 var signedMsg = new Uint8Array(crypto_sign_BYTES+msg.length);
1693 crypto_sign(signedMsg, msg, msg.length, secretKey);
1694 return signedMsg;
1695};
1696
1697nacl.sign.open = function(signedMsg, publicKey) {
1698 checkArrayTypes(signedMsg, publicKey);
1699 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1700 throw new Error('bad public key size');
1701 var tmp = new Uint8Array(signedMsg.length);
1702 var mlen = crypto_sign_open(tmp, signedMsg, signedMsg.length, publicKey);
1703 if (mlen < 0) return null;
1704 var m = new Uint8Array(mlen);
1705 for (var i = 0; i < m.length; i++) m[i] = tmp[i];
1706 return m;
1707};
1708
1709nacl.sign.detached = function(msg, secretKey) {
1710 var signedMsg = nacl.sign(msg, secretKey);
1711 var sig = new Uint8Array(crypto_sign_BYTES);
1712 for (var i = 0; i < sig.length; i++) sig[i] = signedMsg[i];
1713 return sig;
1714};
1715
1716nacl.sign.detached.verify = function(msg, sig, publicKey) {
1717 checkArrayTypes(msg, sig, publicKey);
1718 if (sig.length !== crypto_sign_BYTES)
1719 throw new Error('bad signature size');
1720 if (publicKey.length !== crypto_sign_PUBLICKEYBYTES)
1721 throw new Error('bad public key size');
1722 var sm = new Uint8Array(crypto_sign_BYTES + msg.length);
1723 var m = new Uint8Array(crypto_sign_BYTES + msg.length);
1724 var i;
1725 for (i = 0; i < crypto_sign_BYTES; i++) sm[i] = sig[i];
1726 for (i = 0; i < msg.length; i++) sm[i+crypto_sign_BYTES] = msg[i];
1727 return (crypto_sign_open(m, sm, sm.length, publicKey) >= 0);
1728};
1729
1730nacl.sign.keyPair = function() {
1731 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1732 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1733 crypto_sign_keypair(pk, sk);
1734 return {publicKey: pk, secretKey: sk};
1735};
1736
1737nacl.sign.keyPair.fromSecretKey = function(secretKey) {
1738 checkArrayTypes(secretKey);
1739 if (secretKey.length !== crypto_sign_SECRETKEYBYTES)
1740 throw new Error('bad secret key size');
1741 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1742 pk = derivePublicFromSecret(secretKey);
1743 return {publicKey: pk, secretKey: new Uint8Array(secretKey)};
1744};
1745
1746nacl.sign.keyPair.fromSeed = function(seed) {
1747 checkArrayTypes(seed);
1748 if (seed.length !== crypto_sign_SEEDBYTES)
1749 throw new Error('bad seed size');
1750 var pk = new Uint8Array(crypto_sign_PUBLICKEYBYTES);
1751 var sk = new Uint8Array(crypto_sign_SECRETKEYBYTES);
1752 for (var i = 0; i < 32; i++) sk[i] = seed[i];
1753 crypto_sign_keypair(pk, sk, true);
1754 return {publicKey: pk, secretKey: sk};
1755};
1756
1757nacl.sign.publicKeyLength = crypto_sign_PUBLICKEYBYTES;
1758nacl.sign.secretKeyLength = crypto_sign_SECRETKEYBYTES;
1759nacl.sign.seedLength = crypto_sign_SEEDBYTES;
1760nacl.sign.signatureLength = crypto_sign_BYTES;
1761
1762nacl.hash = function(msg) {
1763 checkArrayTypes(msg);
1764 var h = new Uint8Array(crypto_hash_BYTES);
1765 crypto_hash(h, msg, msg.length);
1766 return h;
1767};
1768
1769nacl.hash.hashLength = crypto_hash_BYTES;
1770
1771nacl.verify = function(x, y) {
1772 checkArrayTypes(x, y);
1773 // Zero length arguments are considered not equal.
1774 if (x.length === 0 || y.length === 0) return false;
1775 if (x.length !== y.length) return false;
1776 return (vn(x, 0, y, 0, x.length) === 0) ? true : false;
1777};
1778
1779nacl.setPRNG = function(fn) {
1780 randombytes = fn;
1781};
1782
1783(function() {
1784 // Initialize PRNG if environment provides CSPRNG.
1785 // If not, methods calling randombytes will throw.
1786 var crypto = typeof self !== 'undefined' ? (self.crypto || self.msCrypto) : null;
1787 if (crypto && crypto.getRandomValues) {
1788 // Browsers.
1789 var QUOTA = 65536;
1790 nacl.setPRNG(function(x, n) {
1791 var i, v = new Uint8Array(n);
1792 for (i = 0; i < n; i += QUOTA) {
1793 crypto.getRandomValues(v.subarray(i, i + Math.min(n - i, QUOTA)));
1794 }
1795 for (i = 0; i < n; i++) x[i] = v[i];
1796 cleanup(v);
1797 });
1798 } else if (typeof require !== 'undefined') {
1799 // Node.js.
1800 crypto = require('crypto');
1801 if (crypto && crypto.randomBytes) {
1802 nacl.setPRNG(function(x, n) {
1803 var i, v = crypto.randomBytes(n);
1804 for (i = 0; i < n; i++) x[i] = v[i];
1805 cleanup(v);
1806 });
1807 }
1808
1809 }
1810})();
1811
1812})(typeof module !== 'undefined' && module.exports ? module.exports : (self.nacl = self.nacl || {}));
1813 </script><script type="text/javascript">// forked from https://cdn.rawgit.com/termhn/nano-base32/master/index.js on 2018-03-06
1814
1815const alphabet = '13456789abcdefghijkmnopqrstuwxyz'
1816
1817/**
1818 * Encode provided Uint8Array using the Nano-specific Base-32 implementeation.
1819 * @param {Uint8Array} view Input buffer formatted as a Uint8Array
1820 * @returns {string}
1821 */
1822function encode (view) {
1823 if (view.constructor !== Uint8Array) {
1824 throw new Error('View must be a Uint8Array!')
1825 }
1826 const length = view.length
1827 const leftover = (length * 8) % 5
1828 const offset = leftover === 0 ? 0 : 5 - leftover
1829
1830 let value = 0
1831 let output = ''
1832 let bits = 0
1833
1834 for (var i = 0; i < length; i++) {
1835 value = (value << 8) | view[i]
1836 bits += 8
1837
1838 while (bits >= 5) {
1839 output += alphabet[(value >>> (bits + offset - 5)) & 31]
1840 bits -= 5
1841 }
1842 }
1843
1844 if (bits > 0) {
1845 output += alphabet[(value << (5 - (bits + offset))) & 31]
1846 }
1847
1848 return output
1849}
1850
1851function readChar (char) {
1852 var idx = alphabet.indexOf(char)
1853
1854 if (idx === -1) {
1855 throw new Error('Invalid character found: ' + char)
1856 }
1857
1858 return idx
1859}
1860
1861/**
1862 * Decodes a Nano-implementation Base32 encoded string into a Uint8Array
1863 * @param {string} input A Nano-Base32 encoded string
1864 * @returns {Uint8Array}
1865 */
1866function decode (input) {
1867 if (typeof input !== 'string') {
1868 throw new Error('Input must be a string!')
1869 }
1870 var length = input.length
1871 const leftover = (length * 5) % 8
1872 const offset = leftover === 0 ? 0 : 8 - leftover
1873
1874 var bits = 0
1875 var value = 0
1876
1877 var index = 0
1878 var output = new Uint8Array(Math.ceil(length * 5 / 8))
1879
1880 for (var i = 0; i < length; i++) {
1881 value = (value << 5) | readChar(input[i])
1882 bits += 5
1883
1884 if (bits >= 8) {
1885 output[index++] = (value >>> (bits + offset - 8)) & 255
1886 bits -= 8
1887 }
1888 }
1889 if (bits > 0) {
1890 output[index++] = (value << (bits + offset - 8)) & 255
1891 }
1892
1893 if (leftover !== 0) {
1894 output = output.slice(1)
1895 }
1896 return output
1897}
1898 </script><script type="text/javascript">// this section will add "copy" buttons next to each element that has a "copy" class. It is backwards compatible to most browsers. It will check if the element has an ID already, otherwise it will assign one.
1899function copyToClipboard(fieldindex,copybutton,target) {
1900//fieldindex is unused now
1901//📋clipboard 🗍empty pages 🗐pages ✓ checkmark
1902var docelement = document.getElementById(target);
1903var htmltag = docelement.tagName.toLowerCase();
1904//alert(htmltag);
1905if( htmltag == 'code' || htmltag == 'textarea' || htmltag == 'pre' || htmltag == 'a' || htmltag == 'span' || htmltag == 'div' ) {var text = docelement.innerHTML ; }
1906if( htmltag == 'input') {var text = docelement.value ; }
1907if(text == '' || text == '-') {
1908text = '-';
1909// alert('Field is empty! Nothing to copy!'); return;
1910copybutton.innerHTML = 'X';
1911copybutton.style.color = "#ec001c";
1912
1913} else {
1914copybutton.innerHTML = '✓';
1915copybutton.style.color = "#9aff5d";
1916if (navigator.clipboard) {
1917 navigator.clipboard.writeText(text);
1918} else {
1919 var inp = document.createElement('input');
1920 document.body.appendChild(inp)
1921 inp.value = text;
1922 inp.select();
1923 document.execCommand('copy',false);
1924 inp.remove();
1925}
1926}
1927setTimeout(function(){
1928copybutton.innerHTML = ' ';
1929}, 800);
1930}
1931
1932function loadCopyHelper() {
1933var copyelements = document.getElementsByClassName('copy');
1934var i; for (i = 0; i < copyelements.length; i++) {
1935
1936if(copyelements[i].id) {
1937 var target = copyelements[i].id;
1938}
1939else {
1940 var target = "copy" + i ;
1941 copyelements[i].id = target; //works only with unreferenced html tags
1942}
1943
1944document.getElementById(target).insertAdjacentHTML('afterend', '<span class="copybutton" id="copybutton' + i + '" onclick="copyToClipboard(\'' + i + '\',this,\'' + target + '\')" title="copy to clipboard"> </span>');
1945}
1946}</script>
1947
1948
1949
1950
1951
1952
1953
1954 <script type="text/javascript">
1955
1956
1957function hexToBytes(hex) { // why is this here? probably duplicate of hex_uint8
1958 for (var bytes = [], c = 0; c < hex.length; c += 2)
1959 bytes.push(parseInt(hex.substr(c, 2), 16));
1960 return bytes;
1961}
1962
1963// generates a new random seed and proceed to convert
1964function randomseed() {
1965 images_el = $("#images");
1966 $(images_el).empty();
1967 for(x = 0; x < 100; x++) {
1968 var seed = nacl.randomBytes(32);
1969 var seedhex = uint8_hex(seed);
1970 document.getElementById("fieldseed").value = seedhex;
1971 sanitizeandconvert(seedhex,'fieldseed');
1972 }
1973}
1974
1975// generates a new random private key and proceed to convert
1976function randomprivatekey() {
1977 var privatekey = nacl.randomBytes(32);
1978 var privatekeyhex = uint8_hex(privatekey);
1979 document.getElementById("fieldprivatekey").value = privatekeyhex;
1980 sanitizeandconvert(privatekeyhex,'fieldprivatekey');
1981}
1982
1983// generates a new random public key and proceed to convert
1984function randompublickey() {
1985 var publickey = nacl.randomBytes(32);
1986 var publickeyhex = uint8_hex(publickey);
1987 document.getElementById("fieldpublickey").value = publickeyhex;
1988 sanitizeandconvert(publickeyhex,'fieldpublickey');
1989}
1990
1991
1992//this is where the conversion magic happens.
1993function convert(string, field) {
1994 if (field == 'fieldseed' || field == 'fieldindex') {
1995 if(document.getElementById("fieldseed").value.length == 64) { // will be skipped if only a index number has been entered
1996 var seed = document.getElementById("fieldseed").value; //will take each 2 HEX chars each and make it a byte from 0-255.
1997 seed = hex_uint8(seed); //will take each 2 HEX chars each and make it a byte from 0-255.
1998 var index = document.getElementById("fieldindex").value;
1999 var indexbytes = hex_uint8(dec2hex(index, 4));
2000 var context = blake2bInit(32);
2001 blake2bUpdate(context, seed);
2002 blake2bUpdate(context, indexbytes);
2003 var resultingprivkey = blake2bFinal(context);
2004 document.getElementById("fieldprivatekey").value = uint8_hex(resultingprivkey);
2005 field = 'fieldprivatekey';
2006 }
2007 } // end seed input conversion
2008
2009
2010 if (field == 'fieldprivatekey') {
2011 var privatekey = document.getElementById("fieldprivatekey").value;
2012 var privatekeyuint8 = hex_uint8(privatekey);
2013 var publickeyhex = uint8_hex(nacl.sign.keyPair.fromSecretKey(privatekeyuint8).publicKey);
2014 document.getElementById("fieldpublickey").value = publickeyhex;
2015 var account = accountFromHexKey(publickeyhex).replace("xrb_","ban_");
2016 document.getElementById("fieldaddress").value = account;
2017 images_el = $("#images");
2018 $(images_el).append("<hr> <a href=\"https://monkey.banano.cc/api/v1/monkey/" + account + "?svc=banano.cc&background=true\" target=\"_blank\" rel=\"noreferrer\"><img src=\"https://monkey.banano.cc/api/v1/monkey/" + account + "?svc=banano.cc&background=true\" height=\"200\" width=\"200\" /></a><p>" + privatekey + "<br />" + account + "</p>");
2019
2020 //document.getElementById("monKey").src = "https://monkey.banano.cc/api/v1/monkey/" + account + "?svc=banano.cc&background=true";
2021 }
2022
2023
2024 if (field == 'fieldpublickey') {
2025 document.getElementById("fieldprivatekey").value = '-';
2026 var publickeyhex = document.getElementById("fieldpublickey").value;
2027 try {
2028 var account = accountFromHexKey(publickeyhex).replace("xrb_","ban_");
2029 document.getElementById("fieldaddress").value = account;
2030 } catch (err) {
2031 alert('Input error in public key field: ' + err);
2032 }
2033 }
2034
2035 if (field == 'fieldaddress') {
2036 document.getElementById("fieldprivatekey").value = '-';
2037 var address = document.getElementById("fieldaddress").value;
2038
2039 try {
2040 document.getElementById("fieldpublickey").value = keyFromAccount(address);
2041 } catch (err) {
2042 alert('Input error in address field: ' + err);
2043 }
2044 }
2045
2046}
2047
2048// automatic remove of dash on focus
2049function removedash(fieldobject) {
2050 if(fieldobject.value == '-') {fieldobject.value='';}
2051}
2052
2053// this function is optional and does nothing else than make some input sanitation and change visuals for errors. It's a horrible mess, some operations are even redundant, so don't bother looking at it. It works as intended at least. If the app behaviour seems odd to you, then it's not a bug, it's my way of thinking UX.
2054function sanitizeandconvert(string, field) {
2055 if (field == 'fieldseed' || field == 'fieldprivatekey' || field == 'fieldpublickey') {
2056 document.getElementById(field).value = document.getElementById(field).value.replace(/[^0-9A-F]/gi, '').toUpperCase().substr(0,64) ;; // delete everything non-hex and simulate maxlength(64) but allow bigger inputs in case someone has additional spaces
2057 }
2058 if (field == 'fieldseed' && !(parseInt(document.getElementById("fieldindex").value, 10) >= 0)) {
2059 document.getElementById("fieldindex").value = 0;
2060 }
2061 if (field == 'fieldindex') {
2062 index = document.getElementById("fieldindex").value.replace(/[^0-9\.]/g, ''); // delete all non-digits and then leading zeroes with parseint
2063 if (parseInt(index, 10) > 4294967295) {
2064 document.getElementById("fieldindex").value = 4294967295;
2065 } else if (parseInt(index, 10) == index) {
2066
2067 document.getElementById("fieldindex").value = parseInt(index, 10); // parseint only if no chars entered to not wipe the whole fielst
2068 } else {
2069 document.getElementById("fieldindex").value = index;
2070 }
2071 if (document.getElementById("fieldseed").value.length != 64) {
2072 document.getElementById("fieldprivatekey").value = '-';
2073 document.getElementById("fieldpublickey").value = '-';
2074 document.getElementById("fieldaddress").value = '-';
2075 }
2076 }
2077 if (field != 'fieldseed' && field != 'fieldindex') {
2078 document.getElementById("fieldseed").value = '-';
2079 document.getElementById("fieldindex").value = '-';
2080 }
2081 // if (string == '') { bugfix 240418
2082 if (document.getElementById(field).value == '') {
2083 return; // don't do anything in case the whole field was cleared. To do: Wipe other fields
2084 }
2085 if (document.getElementById("fieldseed").value.length == 64 || document.getElementById("fieldseed").value == '-') { // fix
2086 document.getElementById('fieldseed').classList.remove("inputerrorborder");
2087 document.getElementById('fieldprivatekey').classList.remove("inputerrorborder"); //test
2088 document.getElementById('fieldpublickey').classList.remove("inputerrorborder"); //test
2089 }
2090 if (field == 'fieldseed' && document.getElementById('fieldseed').value.length != 64) {
2091 document.getElementById('fieldseed').classList.add("inputerrorborder");
2092 document.getElementById("fieldprivatekey").value = '-';
2093 document.getElementById("fieldpublickey").value = '-';
2094 document.getElementById("fieldaddress").value = '-';
2095 } else if (field == 'fieldseed' && document.getElementById('fieldseed').value.length == 64) {
2096 document.getElementById('fieldseed').classList.remove("inputerrorborder");
2097 }
2098 if (field == 'fieldindex' && document.getElementById('fieldseed').value.length != 64) {
2099 document.getElementById('fieldseed').classList.add("inputerrorborder");
2100 document.getElementById("fieldprivatekey").value = '-';
2101 document.getElementById("fieldpublickey").value = '-';
2102 document.getElementById("fieldaddress").value = '-';
2103 return;
2104 } else if (field == 'fieldindex' && document.getElementById('fieldseed').value.length == 64) {
2105 document.getElementById('fieldseed').classList.remove("inputerrorborder");
2106 }
2107 if (field == 'fieldprivatekey' && document.getElementById('fieldprivatekey').value.length != 64) {
2108 document.getElementById('fieldprivatekey').classList.add("inputerrorborder");
2109 document.getElementById("fieldpublickey").value = '-';
2110 document.getElementById("fieldaddress").value = '-';
2111 } else {
2112 document.getElementById('fieldprivatekey').classList.remove("inputerrorborder");
2113 }
2114 if (field == 'fieldpublickey' && document.getElementById('fieldpublickey').value.length != 64) {
2115 document.getElementById('fieldpublickey').classList.add("inputerrorborder");
2116 document.getElementById("fieldprivatekey").value = '-';
2117 document.getElementById("fieldaddress").value = '-';
2118 } else {
2119 document.getElementById('fieldpublickey').classList.remove("inputerrorborder");
2120 }
2121
2122 if ( field == 'fieldaddress' ) {
2123 document.getElementById('fieldaddress').value = document.getElementById('fieldaddress').value.toLowerCase();
2124 var rawaccount = document.getElementById('fieldaddress').value;
2125 if (
2126 ((rawaccount.startsWith('nano_1') || rawaccount.startsWith('nano_3')) && (rawaccount.length == 65)) ||
2127 ((rawaccount.startsWith('ban_1') || rawaccount.startsWith('ban_3')) && (rawaccount.length == 64)) ||
2128 ((rawaccount.startsWith('xrb_1') || rawaccount.startsWith('xrb_3')) && (rawaccount.length == 64))
2129 ) {
2130 document.getElementById('fieldaddress').classList.remove("inputerrorborder");
2131 } else {
2132 document.getElementById('fieldaddress').classList.add("inputerrorborder");
2133 document.getElementById("fieldseed").value = '-';
2134 document.getElementById("fieldprivatekey").value = '-';
2135 document.getElementById("fieldpublickey").value = '-';
2136 return;
2137
2138 } }
2139 if (field != 'fieldindex' && field != 'fieldaddress' && document.getElementById(field).value.length != 64) {
2140 return;
2141 }
2142 document.getElementById(field).classList.remove("inputerrorborder");
2143 convert(document.getElementById(field).value, field);
2144}
2145
2146
2147window.onload = function () { loadCopyHelper(); }
2148
2149// last bugfixes and improvements:
2150// always use real field value, not function argument
2151// allow paste of more than 64 chars before sanitation
2152// remove dashes on focus
2153// add copy buttons
2154
2155</script>
2156
2157 <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
2158
2159</body>
2160</html>
2161