summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md27
-rw-r--r--index.html19
-rw-r--r--sjcl-front.js264
-rw-r--r--sjcl.js59
4 files changed, 369 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a2eb441
--- /dev/null
+++ b/README.md
@@ -0,0 +1,27 @@
1# Simple AES-256-CCM-PSK drop in front end script for the sjcl library
2
3This script is intended to be just included in any HTML document via a simple <script src="sjcl-front.js"></script>
4and provide ad-hoc group crypto for that site.
5
6The script walks through all text nodes and checks for the sjcl-front signature sjcl://
7and tries to retrieve a key from localStorage or sessionStorage whose name matches the
8one encoded as associated data in the encoded sjcl dictionary. If it can decrypt the
9string, the text node's content is replaced by the plaintext and a class sjcl-decrypted
10is added to its parent node.
11
12If the respective key can not be found, the class sjcl-undecrypted is added to the
13parent node, which also receives a copy of the ciphertext, before the text node is
14replaced by an informative message. A click handler for sjcl-undecrypted objects allows
15to later re-decrypt the text by providing a key.
16
17During initialisation, the script also walks through all TEXTAREA nodes and injects a
18hook revealing a contextual drop down menu that allows encrypting the TEXTAREA's content,
19decrypting it and adding/deleting keys in localStorage. Future versions may allow adding
20that hook to text input fields or filtering by class or id.
21
22Finally the script injects CSS to the document's head to get the injected nodes working.
23
24You can try the script at [https://erdgeist.org/webcrypto/].
25
26The library that does the heavy lifting can be found here: https://github.com/bitwiseshiftleft/sjcl
27
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..edf8f38
--- /dev/null
+++ b/index.html
@@ -0,0 +1,19 @@
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <title>title</title>
6 <script src="sjcl.js"></script>
7 <script src="sjcl-front.js"></script>
8 </script>
9 </head>
10 <body>
11 <textarea rows="4" id="dest"></textarea>
12
13 <div><b>Hint: </b> passphrase for the key named Schlüssel =&gt; Insgeheim, Schlüssel2 =&gt; Nochgeheimer</div>
14 <div>sjcl://{"iv":"7EZ8MFvT0UQe7PPF8R1X8w==","v":1,"iter":1000,"ks":256,"ts":128,"mode":"ccm","adata":"U2NobMO8c3NlbA==","cipher":"aes","salt":"O7XZXQtj0U8=","ct":"NBKhmDDDJtiimILFoJm2CDY3lqnb"}</div>
15 <div>sjcl://{"iv":"MshCIxkW8VnzCw9DNKXrzw==","v":1,"iter":1000,"ks":256,"ts":128,"mode":"ccm","adata":"U2NobMO8c3NlbDI=","cipher":"aes","salt":"PfGQ9go1EUM=","ct":"nGA0OFDq5xSfLTHTE8QLqw+IjbIr2g=="}</div>
16 <div>sjcl://{"iv":"rj3F/Y3D6+h7aPUjYTdFfQ==","v":1,"iter":1000,"ks":256,"ts":128,"mode":"ccm","adata":"U2NobMO8c3NlbA==","cipher":"aes","salt":"O7XZXQtj0U8=","ct":"509+BfGlvASJqYGCVdae1kqdXm76+e4kxKfeOw=="}</div>
17
18 </body>
19</html>
diff --git a/sjcl-front.js b/sjcl-front.js
new file mode 100644
index 0000000..1a67d64
--- /dev/null
+++ b/sjcl-front.js
@@ -0,0 +1,264 @@
1function inject_css() {
2 var s = document.createElement('style');
3 s.setAttribute('type', 'text/css');
4 s.appendChild(document.createTextNode("\
5@font-face { \n\
6font-family: 'fontello'; src: url('data:application/octet-stream;base64,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') format('woff'); } \n\
7.sjcl-undecrypted { background-color: rgba(255, 0, 0, 0.2); cursor: pointer; } \n\
8.sjcl-decrypted { background-color: rgba(0, 255, 0, 0.2); } \n\
9.sjcl-hook { display: inline-block; position: relative; vertical-align: top; } \n\
10.sjcl-hook:before, .sjcl-decrypted:before, .sjcl-undecrypted:before { content: '\\e801 '; font-family: 'fontello'; opacity: 0.5; font-size: 1.1em; padding: 0 0.3em 0 0.3em; margin-right: 0.2em; box-shadow: 0 0 0.3em currentColor; border-radius: 50%; } \n\
11.sjcl-dropdown, .sjcl-addkey-sub { display: none; border-radius: 0.4em; } \n\
12.sjcl-hook:hover .sjcl-dropdown { display: block; position: absolute; min-width: 300px; background-color: #f9f9f9; box-shadow: 0px 1em 2em 0 rgba(0,0,0,0.2); color: black; } \n\
13.sjcl-decrypt, .sjcl-usekey, .sjcl-addkey { padding: 2px 3px 2px 6px; cursor: pointer; border-radius: 0 0 0.4em 0.4em; } \n\
14.sjcl-decrypt:hover, .sjcl-usekey:hover, .sjcl-addkey:hover { border-radius: 0.4em; background-color: #f1f1f1; } \n\
15.sjcl-addkey:hover .sjcl-addkey-sub { display: block; } \n\
16.sjcl-addkey-sub label { display: inline-block !important; width: 40%; } \n\
17.sjcl-addkey-button, .sjcl-delkey-button { display: inline-block; text-align: center; margin-right: 6px; width: 40%; border-radius: 0.4em; border: solid 0.1em lime; } \n\
18.sjcl-delkey-button { border: solid 0.1em red; } \n\
19.sjcl-addkey-button:hover { background-color: lime; } \n\
20.sjcl-delkey-button:hover { background-color: red; } \
21"));
22 document.getElementsByTagName('head')[0].appendChild(s);
23}
24
25function inject_textarea_hook() {
26 // Get rid of old hooks
27 var hooks = document.getElementsByClassName("sjcl-hook");
28 for(var i = hooks.length - 1; i >= 0; i--) {
29 var n = hooks.item(i);
30 n.parentNode.removeChild(n);
31 }
32 // And insert new hooks
33 var walk=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,null,false);
34 while(n = walk.nextNode())
35 if (n.type == 'textarea') {
36 var keys = list_keys();
37 var h = document.createElement('div');
38 h.className='sjcl-hook';
39 var dd = '<div class="sjcl-dropdown">'
40 for (var i in keys)
41 dd += '<div class="sjcl-usekey" keyname="'+keys[i]+'">Encrypt with: "'+keys[i]+'"</div>';
42 h.innerHTML = dd + '<div class="sjcl-decrypt">Decrypt</div><hr/><div class="sjcl-addkey">Manage keys<div class="sjcl-addkey-sub"><label>Name:</label><input class="sjcl-addkey-name" type="text"/><label>Key:</label><input class="sjcl-addkey-key" type="password"/><div class="sjcl-addkey-button">add!</div><div class="sjcl-delkey-button">delete!</div></div></div></div>';
43 n.parentNode.insertBefore(h,n.nextSibling);
44 }
45}
46
47function decrypt_string(text, target_node, do_prompt) {
48 var rp, ct, plain, key_name, key, do_store = false;
49
50 /* Clear sjcl classes from target node */
51 target_node.className = target_node.className.replace(/(^| )sjcl-[a-z]+($| )/, '');
52
53 /* Check sjcl signature and bail out */
54 if (text.substring(0,7) != 'sjcl://')
55 throw 'Text is not encrypted.';
56
57 /* Skip signature */
58 text = text.substring(7);
59 /* Retrieve key name */
60 try {
61 ct = JSON.parse(text);
62 } catch (e) {
63 target_node.className += ' sjcl-garbled';
64 throw 'Cipher text is garbled.';
65 }
66 try {
67 key_name = sjcl.codec.utf8String.fromBits(sjcl.codec.base64.toBits(ct.adata));
68 } catch(e) {
69 target_node.className += ' sjcl-garbled';
70 throw 'Can not extract key name';
71 }
72
73 key = retrieve_key(key_name);
74 if (!key && do_prompt) {
75 key = prompt( 'Enter password for the key ' + key_name);
76 do_store = true;
77 }
78 if (!key) {
79 target_node.className += ' sjcl-undecrypted';
80 throw 'You need the key "' + key_name + '" to decrypt.';
81 }
82 try {
83 plain = sjcl.decrypt(key, text, {}, rp);
84 } catch (e) {
85 if (do_store)
86 alert('Could not decrypt');
87 target_node.className += ' sjcl-undecrytable';
88 throw 'Your key "' + key_name + '" can not decrypt.';
89 }
90 if (do_store)
91 store_key(key_name, key);
92
93 target_node.className += ' sjcl-decrypted';
94 return plain.replace(/\s+$/gm,'');
95}
96
97function decrypt_element(n) {
98 try {
99 n.data = decrypt_string(n.data, n.parentElement, false);
100 } catch(e) {
101 n.parentElement.ciphertext = n.data;
102 n.parentElement.ciphertext_node = n;
103 n.data = e;
104 }
105}
106
107function decrypt_undecrypted(n) {
108 if(!n.ciphertext || n.ciphertext_node==null)
109 return;
110 try {
111 n.ciphertext_node.data = decrypt_string(n.ciphertext, n, true);
112 inject_textarea_hook();
113 find_undecrypted_nodes();
114 } catch(e) {
115 n.ciphertext_node.data = e;
116 }
117}
118
119function decrypt_textarea(n) {
120 try {
121 n.value = decrypt_string(n.value, n, false);
122 } catch(e) {
123 alert(e);
124 }
125}
126
127function encrypt_textarea(n,name,key) {
128 var t = n.value + (" ".repeat(17 + Math.floor((Math.random() * 64))));
129 var p = {adata:name, iter:1000, mode:'ccm', ts:128, ks:256, iter: 1000 };
130 n.value = 'sjcl://'+sjcl.encrypt(key, t || '', p);
131 n.className = n.className.replace(/(^| )sjcl-[a-z]+($| )/, '')+' sjcl-undecrypted';
132}
133
134/* Auto node operation */
135function find_encrypted_nodes() {
136 var n, walk = document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,null,false);
137 while(n = walk.nextNode())
138 if (n.data.substring(0,7) == 'sjcl://')
139 decrypt_element(n, false);
140}
141
142function find_undecrypted_nodes() {
143 var undec = document.getElementsByClassName("sjcl-undecrypted");
144 for(var i = 0; i < undec.length; i++)
145 decrypt_undecrypted(undec.item(i), false);
146}
147
148/* Passphrase accessors */
149function manage_key(n, do_add) {
150 var name = n.parentNode.getElementsByClassName('sjcl-addkey-name')[0];
151 var key = n.parentNode.getElementsByClassName('sjcl-addkey-key')[0];
152 if (!name.value)
153 alert( 'Missing key name.');
154 else
155 store_key(name.value, do_add ? key.value : '');
156 inject_textarea_hook();
157}
158
159/* Try to use the most logliving method to store key array */
160function store_key(name, key) {
161 /* Collect keys from all storage methods */
162 var obj = {};
163 try {
164 obj = JSON.parse(localStorage['frab-sjcl']);
165 } catch(e) {}
166 try {
167 var sso = JSON.parse(sessionStorage['frab-sjcl']);
168 for (var k in sso) { obj[k] = sso[k]; }
169 delete sessionStorage['frab-sjcl'];
170 } catch(e) {}
171 try {
172 wo = JSON.parse(window['frab-sjcl']);
173 for (var k in wo) { obj[k] = wo[k]; }
174 delete window['frab-sjcl'];
175 } catch(e) {}
176
177 if (key)
178 obj[name] = key;
179 else
180 delete obj[name];
181 var out = JSON.stringify(obj);
182
183 /* Try to store in local/sessionStorage and fall back to
184 the window object, so at least we can decrypt all elements
185 locally */
186 try {
187 localStorage['frab-sjcl'] = out;
188 if (localStorage['frab-sjcl'] != out)
189 throw 0;
190 return;
191 } catch(e) {}
192 try {
193 sessionStorage['frab-sjcl'] = out;
194 if (sessionStorage['frab-sjcl'] != out)
195 throw 0;
196 return;
197 } catch(e) {}
198
199 window['frab-sjcl'] = out;
200}
201
202function retrieve_key(name) {
203 try {
204 var obj = JSON.parse(localStorage['frab-sjcl'] || '{}');
205 if (obj && obj[name])
206 return obj[name];
207 } catch(e) {}
208 try {
209 var obj = JSON.parse(sessionStorage['frab-sjcl'] || '{}');
210 if (obj && obj[name])
211 return obj[name];
212 } catch(e) {}
213 try {
214 var obj = JSON.parse(window['frab-sjcl'] || '{}');
215 if (obj && obj[name])
216 return obj[name];
217 } catch(e) {}
218 return '';
219}
220
221function list_keys() {
222 var key_list = [];
223 try {
224 key_list = (Object.keys(JSON.parse(localStorage['frab-sjcl'])));
225 } catch(e) {}
226 try {
227 key_list = key_list.concat(Object.keys(JSON.parse(sessionStorage['frab-sjcl'])));
228 } catch(e) {}
229 try {
230 key_list = key_list.concat(Object.keys(JSON.parse(window['frab-sjcl'])));
231 } catch(e) {}
232 return key_list;
233}
234
235/* Event handler plumbing */
236function click_body(e) {
237 var n = e.target;
238
239 if (n.className=='sjcl-usekey') {
240 var name = n.getAttribute('keyname');
241 encrypt_textarea(n.parentNode.parentNode.previousSibling, name, retrieve_key(name));
242 }
243 if (n.className=='sjcl-decrypt')
244 decrypt_textarea(n.parentNode.parentNode.previousSibling);
245 if ((' '+n.className+' ').indexOf(' sjcl-undecrypted ') > -1)
246 decrypt_undecrypted(n);
247 if (n.className=='sjcl-addkey-button')
248 manage_key(n,true);
249 if (n.className=='sjcl-delkey-button')
250 manage_key(n,false);
251}
252
253function loaded() {
254 sjcl.random.startCollectors();
255 document.body.addEventListener("click", click_body)
256
257 inject_css();
258 inject_textarea_hook();
259
260 /* Try to decrypt all encrypted nodes */
261 find_encrypted_nodes();
262}
263
264window.addEventListener('load', loaded);
diff --git a/sjcl.js b/sjcl.js
new file mode 100644
index 0000000..6f7668e
--- /dev/null
+++ b/sjcl.js
@@ -0,0 +1,59 @@
1"use strict";var sjcl={cipher:{},hash:{},keyexchange:{},mode:{},misc:{},codec:{},exception:{corrupt:function(a){this.toString=function(){return"CORRUPT: "+this.message};this.message=a},invalid:function(a){this.toString=function(){return"INVALID: "+this.message};this.message=a},bug:function(a){this.toString=function(){return"BUG: "+this.message};this.message=a},notReady:function(a){this.toString=function(){return"NOT READY: "+this.message};this.message=a}}};
2"undefined"!==typeof module&&module.exports&&(module.exports=sjcl);"function"===typeof define&&define([],function(){return sjcl});
3sjcl.cipher.aes=function(a){this.s[0][0][0]||this.O();var b,c,d,e,g=this.s[0][4],f=this.s[1];b=a.length;var h=1;if(4!==b&&6!==b&&8!==b)throw new sjcl.exception.invalid("invalid aes key size");this.b=[d=a.slice(0),e=[]];for(a=b;a<4*b+28;a++){c=d[a-1];if(0===a%b||8===b&&4===a%b)c=g[c>>>24]<<24^g[c>>16&255]<<16^g[c>>8&255]<<8^g[c&255],0===a%b&&(c=c<<8^c>>>24^h<<24,h=h<<1^283*(h>>7));d[a]=d[a-b]^c}for(b=0;a;b++,a--)c=d[b&3?a:a-4],e[b]=4>=a||4>b?c:f[0][g[c>>>24]]^f[1][g[c>>16&255]]^f[2][g[c>>8&255]]^f[3][g[c&
4255]]};
5sjcl.cipher.aes.prototype={encrypt:function(a){return u(this,a,0)},decrypt:function(a){return u(this,a,1)},s:[[[],[],[],[],[]],[[],[],[],[],[]]],O:function(){var a=this.s[0],b=this.s[1],c=a[4],d=b[4],e,g,f,h=[],l=[],k,m,n,p;for(e=0;0x100>e;e++)l[(h[e]=e<<1^283*(e>>7))^e]=e;for(g=f=0;!c[g];g^=k||1,f=l[f]||1)for(n=f^f<<1^f<<2^f<<3^f<<4,n=n>>8^n&255^99,c[g]=n,d[n]=g,m=h[e=h[k=h[g]]],p=0x1010101*m^0x10001*e^0x101*k^0x1010100*g,m=0x101*h[n]^0x1010100*n,e=0;4>e;e++)a[e][g]=m=m<<24^m>>>8,b[e][n]=p=p<<24^p>>>8;for(e=
60;5>e;e++)a[e]=a[e].slice(0),b[e]=b[e].slice(0)}};
7function u(a,b,c){if(4!==b.length)throw new sjcl.exception.invalid("invalid aes block size");var d=a.b[c],e=b[0]^d[0],g=b[c?3:1]^d[1],f=b[2]^d[2];b=b[c?1:3]^d[3];var h,l,k,m=d.length/4-2,n,p=4,r=[0,0,0,0];h=a.s[c];a=h[0];var q=h[1],t=h[2],w=h[3],x=h[4];for(n=0;n<m;n++)h=a[e>>>24]^q[g>>16&255]^t[f>>8&255]^w[b&255]^d[p],l=a[g>>>24]^q[f>>16&255]^t[b>>8&255]^w[e&255]^d[p+1],k=a[f>>>24]^q[b>>16&255]^t[e>>8&255]^w[g&255]^d[p+2],b=a[b>>>24]^q[e>>16&255]^t[g>>8&255]^w[f&255]^d[p+3],p+=4,e=h,g=l,f=k;for(n=
80;4>n;n++)r[c?3&-n:n]=x[e>>>24]<<24^x[g>>16&255]<<16^x[f>>8&255]<<8^x[b&255]^d[p++],h=e,e=g,g=f,f=b,b=h;return r}
9sjcl.bitArray={bitSlice:function(a,b,c){a=sjcl.bitArray.$(a.slice(b/32),32-(b&31)).slice(1);return void 0===c?a:sjcl.bitArray.clamp(a,c-b)},extract:function(a,b,c){var d=Math.floor(-b-c&31);return((b+c-1^b)&-32?a[b/32|0]<<32-d^a[b/32+1|0]>>>d:a[b/32|0]>>>d)&(1<<c)-1},concat:function(a,b){if(0===a.length||0===b.length)return a.concat(b);var c=a[a.length-1],d=sjcl.bitArray.getPartial(c);return 32===d?a.concat(b):sjcl.bitArray.$(b,d,c|0,a.slice(0,a.length-1))},bitLength:function(a){var b=a.length;return 0===
10b?0:32*(b-1)+sjcl.bitArray.getPartial(a[b-1])},clamp:function(a,b){if(32*a.length<b)return a;a=a.slice(0,Math.ceil(b/32));var c=a.length;b=b&31;0<c&&b&&(a[c-1]=sjcl.bitArray.partial(b,a[c-1]&2147483648>>b-1,1));return a},partial:function(a,b,c){return 32===a?b:(c?b|0:b<<32-a)+0x10000000000*a},getPartial:function(a){return Math.round(a/0x10000000000)||32},equal:function(a,b){if(sjcl.bitArray.bitLength(a)!==sjcl.bitArray.bitLength(b))return!1;var c=0,d;for(d=0;d<a.length;d++)c|=a[d]^b[d];return 0===
11c},$:function(a,b,c,d){var e;e=0;for(void 0===d&&(d=[]);32<=b;b-=32)d.push(c),c=0;if(0===b)return d.concat(a);for(e=0;e<a.length;e++)d.push(c|a[e]>>>b),c=a[e]<<32-b;e=a.length?a[a.length-1]:0;a=sjcl.bitArray.getPartial(e);d.push(sjcl.bitArray.partial(b+a&31,32<b+a?c:d.pop(),1));return d},i:function(a,b){return[a[0]^b[0],a[1]^b[1],a[2]^b[2],a[3]^b[3]]},byteswapM:function(a){var b,c;for(b=0;b<a.length;++b)c=a[b],a[b]=c>>>24|c>>>8&0xff00|(c&0xff00)<<8|c<<24;return a}};
12sjcl.codec.utf8String={fromBits:function(a){var b="",c=sjcl.bitArray.bitLength(a),d,e;for(d=0;d<c/8;d++)0===(d&3)&&(e=a[d/4]),b+=String.fromCharCode(e>>>24),e<<=8;return decodeURIComponent(escape(b))},toBits:function(a){a=unescape(encodeURIComponent(a));var b=[],c,d=0;for(c=0;c<a.length;c++)d=d<<8|a.charCodeAt(c),3===(c&3)&&(b.push(d),d=0);c&3&&b.push(sjcl.bitArray.partial(8*(c&3),d));return b}};
13sjcl.codec.hex={fromBits:function(a){var b="",c;for(c=0;c<a.length;c++)b+=((a[c]|0)+0xf00000000000).toString(16).substr(4);return b.substr(0,sjcl.bitArray.bitLength(a)/4)},toBits:function(a){var b,c=[],d;a=a.replace(/\s|0x/g,"");d=a.length;a=a+"00000000";for(b=0;b<a.length;b+=8)c.push(parseInt(a.substr(b,8),16)^0);return sjcl.bitArray.clamp(c,4*d)}};
14sjcl.codec.base32={B:"ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",X:"0123456789ABCDEFGHIJKLMNOPQRSTUV",BITS:32,BASE:5,REMAINING:27,fromBits:function(a,b,c){var d=sjcl.codec.base32.BASE,e=sjcl.codec.base32.REMAINING,g="",f=0,h=sjcl.codec.base32.B,l=0,k=sjcl.bitArray.bitLength(a);c&&(h=sjcl.codec.base32.X);for(c=0;g.length*d<k;)g+=h.charAt((l^a[c]>>>f)>>>e),f<d?(l=a[c]<<d-f,f+=e,c++):(l<<=d,f-=d);for(;g.length&7&&!b;)g+="=";return g},toBits:function(a,b){a=a.replace(/\s|=/g,"").toUpperCase();var c=sjcl.codec.base32.BITS,
15d=sjcl.codec.base32.BASE,e=sjcl.codec.base32.REMAINING,g=[],f,h=0,l=sjcl.codec.base32.B,k=0,m,n="base32";b&&(l=sjcl.codec.base32.X,n="base32hex");for(f=0;f<a.length;f++){m=l.indexOf(a.charAt(f));if(0>m){if(!b)try{return sjcl.codec.base32hex.toBits(a)}catch(p){}throw new sjcl.exception.invalid("this isn't "+n+"!");}h>e?(h-=e,g.push(k^m>>>h),k=m<<c-h):(h+=d,k^=m<<c-h)}h&56&&g.push(sjcl.bitArray.partial(h&56,k,1));return g}};
16sjcl.codec.base32hex={fromBits:function(a,b){return sjcl.codec.base32.fromBits(a,b,1)},toBits:function(a){return sjcl.codec.base32.toBits(a,1)}};
17sjcl.codec.base64={B:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",fromBits:function(a,b,c){var d="",e=0,g=sjcl.codec.base64.B,f=0,h=sjcl.bitArray.bitLength(a);c&&(g=g.substr(0,62)+"-_");for(c=0;6*d.length<h;)d+=g.charAt((f^a[c]>>>e)>>>26),6>e?(f=a[c]<<6-e,e+=26,c++):(f<<=6,e-=6);for(;d.length&3&&!b;)d+="=";return d},toBits:function(a,b){a=a.replace(/\s|=/g,"");var c=[],d,e=0,g=sjcl.codec.base64.B,f=0,h;b&&(g=g.substr(0,62)+"-_");for(d=0;d<a.length;d++){h=g.indexOf(a.charAt(d));
18if(0>h)throw new sjcl.exception.invalid("this isn't base64!");26<e?(e-=26,c.push(f^h>>>e),f=h<<32-e):(e+=6,f^=h<<32-e)}e&56&&c.push(sjcl.bitArray.partial(e&56,f,1));return c}};sjcl.codec.base64url={fromBits:function(a){return sjcl.codec.base64.fromBits(a,1,1)},toBits:function(a){return sjcl.codec.base64.toBits(a,1)}};sjcl.hash.sha256=function(a){this.b[0]||this.O();a?(this.F=a.F.slice(0),this.A=a.A.slice(0),this.l=a.l):this.reset()};sjcl.hash.sha256.hash=function(a){return(new sjcl.hash.sha256).update(a).finalize()};
19sjcl.hash.sha256.prototype={blockSize:512,reset:function(){this.F=this.Y.slice(0);this.A=[];this.l=0;return this},update:function(a){"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));var b,c=this.A=sjcl.bitArray.concat(this.A,a);b=this.l;a=this.l=b+sjcl.bitArray.bitLength(a);for(b=512+b&-512;b<=a;b+=512)v(this,c.splice(0,16));return this},finalize:function(){var a,b=this.A,c=this.F,b=sjcl.bitArray.concat(b,[sjcl.bitArray.partial(1,1)]);for(a=b.length+2;a&15;a++)b.push(0);b.push(Math.floor(this.l/
204294967296));for(b.push(this.l|0);b.length;)v(this,b.splice(0,16));this.reset();return c},Y:[],b:[],O:function(){function a(a){return 0x100000000*(a-Math.floor(a))|0}var b=0,c=2,d;a:for(;64>b;c++){for(d=2;d*d<=c;d++)if(0===c%d)continue a;8>b&&(this.Y[b]=a(Math.pow(c,.5)));this.b[b]=a(Math.pow(c,1/3));b++}}};
21function v(a,b){var c,d,e,g=b.slice(0),f=a.F,h=a.b,l=f[0],k=f[1],m=f[2],n=f[3],p=f[4],r=f[5],q=f[6],t=f[7];for(c=0;64>c;c++)16>c?d=g[c]:(d=g[c+1&15],e=g[c+14&15],d=g[c&15]=(d>>>7^d>>>18^d>>>3^d<<25^d<<14)+(e>>>17^e>>>19^e>>>10^e<<15^e<<13)+g[c&15]+g[c+9&15]|0),d=d+t+(p>>>6^p>>>11^p>>>25^p<<26^p<<21^p<<7)+(q^p&(r^q))+h[c],t=q,q=r,r=p,p=n+d|0,n=m,m=k,k=l,l=d+(k&m^n&(k^m))+(k>>>2^k>>>13^k>>>22^k<<30^k<<19^k<<10)|0;f[0]=f[0]+l|0;f[1]=f[1]+k|0;f[2]=f[2]+m|0;f[3]=f[3]+n|0;f[4]=f[4]+p|0;f[5]=f[5]+r|0;f[6]=
22f[6]+q|0;f[7]=f[7]+t|0}
23sjcl.mode.ccm={name:"ccm",G:[],listenProgress:function(a){sjcl.mode.ccm.G.push(a)},unListenProgress:function(a){a=sjcl.mode.ccm.G.indexOf(a);-1<a&&sjcl.mode.ccm.G.splice(a,1)},fa:function(a){var b=sjcl.mode.ccm.G.slice(),c;for(c=0;c<b.length;c+=1)b[c](a)},encrypt:function(a,b,c,d,e){var g,f=b.slice(0),h=sjcl.bitArray,l=h.bitLength(c)/8,k=h.bitLength(f)/8;e=e||64;d=d||[];if(7>l)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(g=2;4>g&&k>>>8*g;g++);g<15-l&&(g=15-l);c=h.clamp(c,
248*(15-g));b=sjcl.mode.ccm.V(a,b,c,d,e,g);f=sjcl.mode.ccm.C(a,f,c,b,e,g);return h.concat(f.data,f.tag)},decrypt:function(a,b,c,d,e){e=e||64;d=d||[];var g=sjcl.bitArray,f=g.bitLength(c)/8,h=g.bitLength(b),l=g.clamp(b,h-e),k=g.bitSlice(b,h-e),h=(h-e)/8;if(7>f)throw new sjcl.exception.invalid("ccm: iv must be at least 7 bytes");for(b=2;4>b&&h>>>8*b;b++);b<15-f&&(b=15-f);c=g.clamp(c,8*(15-b));l=sjcl.mode.ccm.C(a,l,c,k,e,b);a=sjcl.mode.ccm.V(a,l.data,c,d,e,b);if(!g.equal(l.tag,a))throw new sjcl.exception.corrupt("ccm: tag doesn't match");
25return l.data},na:function(a,b,c,d,e,g){var f=[],h=sjcl.bitArray,l=h.i;d=[h.partial(8,(b.length?64:0)|d-2<<2|g-1)];d=h.concat(d,c);d[3]|=e;d=a.encrypt(d);if(b.length)for(c=h.bitLength(b)/8,65279>=c?f=[h.partial(16,c)]:0xffffffff>=c&&(f=h.concat([h.partial(16,65534)],[c])),f=h.concat(f,b),b=0;b<f.length;b+=4)d=a.encrypt(l(d,f.slice(b,b+4).concat([0,0,0])));return d},V:function(a,b,c,d,e,g){var f=sjcl.bitArray,h=f.i;e/=8;if(e%2||4>e||16<e)throw new sjcl.exception.invalid("ccm: invalid tag length");
26if(0xffffffff<d.length||0xffffffff<b.length)throw new sjcl.exception.bug("ccm: can't deal with 4GiB or more data");c=sjcl.mode.ccm.na(a,d,c,e,f.bitLength(b)/8,g);for(d=0;d<b.length;d+=4)c=a.encrypt(h(c,b.slice(d,d+4).concat([0,0,0])));return f.clamp(c,8*e)},C:function(a,b,c,d,e,g){var f,h=sjcl.bitArray;f=h.i;var l=b.length,k=h.bitLength(b),m=l/50,n=m;c=h.concat([h.partial(8,g-1)],c).concat([0,0,0]).slice(0,4);d=h.bitSlice(f(d,a.encrypt(c)),0,e);if(!l)return{tag:d,data:[]};for(f=0;f<l;f+=4)f>m&&(sjcl.mode.ccm.fa(f/
27l),m+=n),c[3]++,e=a.encrypt(c),b[f]^=e[0],b[f+1]^=e[1],b[f+2]^=e[2],b[f+3]^=e[3];return{tag:d,data:h.clamp(b,k)}}};
28sjcl.mode.ocb2={name:"ocb2",encrypt:function(a,b,c,d,e,g){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");var f,h=sjcl.mode.ocb2.S,l=sjcl.bitArray,k=l.i,m=[0,0,0,0];c=h(a.encrypt(c));var n,p=[];d=d||[];e=e||64;for(f=0;f+4<b.length;f+=4)n=b.slice(f,f+4),m=k(m,n),p=p.concat(k(c,a.encrypt(k(c,n)))),c=h(c);n=b.slice(f);b=l.bitLength(n);f=a.encrypt(k(c,[0,0,0,b]));n=l.clamp(k(n.concat([0,0,0]),f),b);m=k(m,k(n.concat([0,0,0]),f));m=a.encrypt(k(m,k(c,h(c))));
29d.length&&(m=k(m,g?d:sjcl.mode.ocb2.pmac(a,d)));return p.concat(l.concat(n,l.clamp(m,e)))},decrypt:function(a,b,c,d,e,g){if(128!==sjcl.bitArray.bitLength(c))throw new sjcl.exception.invalid("ocb iv must be 128 bits");e=e||64;var f=sjcl.mode.ocb2.S,h=sjcl.bitArray,l=h.i,k=[0,0,0,0],m=f(a.encrypt(c)),n,p,r=sjcl.bitArray.bitLength(b)-e,q=[];d=d||[];for(c=0;c+4<r/32;c+=4)n=l(m,a.decrypt(l(m,b.slice(c,c+4)))),k=l(k,n),q=q.concat(n),m=f(m);p=r-32*c;n=a.encrypt(l(m,[0,0,0,p]));n=l(n,h.clamp(b.slice(c),p).concat([0,
300,0]));k=l(k,n);k=a.encrypt(l(k,l(m,f(m))));d.length&&(k=l(k,g?d:sjcl.mode.ocb2.pmac(a,d)));if(!h.equal(h.clamp(k,e),h.bitSlice(b,r)))throw new sjcl.exception.corrupt("ocb: tag doesn't match");return q.concat(h.clamp(n,p))},pmac:function(a,b){var c,d=sjcl.mode.ocb2.S,e=sjcl.bitArray,g=e.i,f=[0,0,0,0],h=a.encrypt([0,0,0,0]),h=g(h,d(d(h)));for(c=0;c+4<b.length;c+=4)h=d(h),f=g(f,a.encrypt(g(h,b.slice(c,c+4))));c=b.slice(c);128>e.bitLength(c)&&(h=g(h,d(h)),c=e.concat(c,[-2147483648,0,0,0]));f=g(f,c);
31return a.encrypt(g(d(g(h,d(h))),f))},S:function(a){return[a[0]<<1^a[1]>>>31,a[1]<<1^a[2]>>>31,a[2]<<1^a[3]>>>31,a[3]<<1^135*(a[0]>>>31)]}};
32sjcl.mode.gcm={name:"gcm",encrypt:function(a,b,c,d,e){var g=b.slice(0);b=sjcl.bitArray;d=d||[];a=sjcl.mode.gcm.C(!0,a,g,d,c,e||128);return b.concat(a.data,a.tag)},decrypt:function(a,b,c,d,e){var g=b.slice(0),f=sjcl.bitArray,h=f.bitLength(g);e=e||128;d=d||[];e<=h?(b=f.bitSlice(g,h-e),g=f.bitSlice(g,0,h-e)):(b=g,g=[]);a=sjcl.mode.gcm.C(!1,a,g,d,c,e);if(!f.equal(a.tag,b))throw new sjcl.exception.corrupt("gcm: tag doesn't match");return a.data},ka:function(a,b){var c,d,e,g,f,h=sjcl.bitArray.i;e=[0,0,
330,0];g=b.slice(0);for(c=0;128>c;c++){(d=0!==(a[Math.floor(c/32)]&1<<31-c%32))&&(e=h(e,g));f=0!==(g[3]&1);for(d=3;0<d;d--)g[d]=g[d]>>>1|(g[d-1]&1)<<31;g[0]>>>=1;f&&(g[0]^=-0x1f000000)}return e},j:function(a,b,c){var d,e=c.length;b=b.slice(0);for(d=0;d<e;d+=4)b[0]^=0xffffffff&c[d],b[1]^=0xffffffff&c[d+1],b[2]^=0xffffffff&c[d+2],b[3]^=0xffffffff&c[d+3],b=sjcl.mode.gcm.ka(b,a);return b},C:function(a,b,c,d,e,g){var f,h,l,k,m,n,p,r,q=sjcl.bitArray;n=c.length;p=q.bitLength(c);r=q.bitLength(d);h=q.bitLength(e);
34f=b.encrypt([0,0,0,0]);96===h?(e=e.slice(0),e=q.concat(e,[1])):(e=sjcl.mode.gcm.j(f,[0,0,0,0],e),e=sjcl.mode.gcm.j(f,e,[0,0,Math.floor(h/0x100000000),h&0xffffffff]));h=sjcl.mode.gcm.j(f,[0,0,0,0],d);m=e.slice(0);d=h.slice(0);a||(d=sjcl.mode.gcm.j(f,h,c));for(k=0;k<n;k+=4)m[3]++,l=b.encrypt(m),c[k]^=l[0],c[k+1]^=l[1],c[k+2]^=l[2],c[k+3]^=l[3];c=q.clamp(c,p);a&&(d=sjcl.mode.gcm.j(f,h,c));a=[Math.floor(r/0x100000000),r&0xffffffff,Math.floor(p/0x100000000),p&0xffffffff];d=sjcl.mode.gcm.j(f,d,a);l=b.encrypt(e);
35d[0]^=l[0];d[1]^=l[1];d[2]^=l[2];d[3]^=l[3];return{tag:q.bitSlice(d,0,g),data:c}}};sjcl.misc.hmac=function(a,b){this.W=b=b||sjcl.hash.sha256;var c=[[],[]],d,e=b.prototype.blockSize/32;this.w=[new b,new b];a.length>e&&(a=b.hash(a));for(d=0;d<e;d++)c[0][d]=a[d]^909522486,c[1][d]=a[d]^1549556828;this.w[0].update(c[0]);this.w[1].update(c[1]);this.R=new b(this.w[0])};
36sjcl.misc.hmac.prototype.encrypt=sjcl.misc.hmac.prototype.mac=function(a){if(this.aa)throw new sjcl.exception.invalid("encrypt on already updated hmac called!");this.update(a);return this.digest(a)};sjcl.misc.hmac.prototype.reset=function(){this.R=new this.W(this.w[0]);this.aa=!1};sjcl.misc.hmac.prototype.update=function(a){this.aa=!0;this.R.update(a)};sjcl.misc.hmac.prototype.digest=function(){var a=this.R.finalize(),a=(new this.W(this.w[1])).update(a).finalize();this.reset();return a};
37sjcl.misc.pbkdf2=function(a,b,c,d,e){c=c||1E3;if(0>d||0>c)throw sjcl.exception.invalid("invalid params to pbkdf2");"string"===typeof a&&(a=sjcl.codec.utf8String.toBits(a));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));e=e||sjcl.misc.hmac;a=new e(a);var g,f,h,l,k=[],m=sjcl.bitArray;for(l=1;32*k.length<(d||1);l++){e=g=a.encrypt(m.concat(b,[l]));for(f=1;f<c;f++)for(g=a.encrypt(g),h=0;h<g.length;h++)e[h]^=g[h];k=k.concat(e)}d&&(k=m.clamp(k,d));return k};
38sjcl.prng=function(a){this.c=[new sjcl.hash.sha256];this.m=[0];this.P=0;this.H={};this.N=0;this.U={};this.Z=this.f=this.o=this.ha=0;this.b=[0,0,0,0,0,0,0,0];this.h=[0,0,0,0];this.L=void 0;this.M=a;this.D=!1;this.K={progress:{},seeded:{}};this.u=this.ga=0;this.I=1;this.J=2;this.ca=0x10000;this.T=[0,48,64,96,128,192,0x100,384,512,768,1024];this.da=3E4;this.ba=80};
39sjcl.prng.prototype={randomWords:function(a,b){var c=[],d;d=this.isReady(b);var e;if(d===this.u)throw new sjcl.exception.notReady("generator isn't seeded");if(d&this.J){d=!(d&this.I);e=[];var g=0,f;this.Z=e[0]=(new Date).valueOf()+this.da;for(f=0;16>f;f++)e.push(0x100000000*Math.random()|0);for(f=0;f<this.c.length&&(e=e.concat(this.c[f].finalize()),g+=this.m[f],this.m[f]=0,d||!(this.P&1<<f));f++);this.P>=1<<this.c.length&&(this.c.push(new sjcl.hash.sha256),this.m.push(0));this.f-=g;g>this.o&&(this.o=
40g);this.P++;this.b=sjcl.hash.sha256.hash(this.b.concat(e));this.L=new sjcl.cipher.aes(this.b);for(d=0;4>d&&(this.h[d]=this.h[d]+1|0,!this.h[d]);d++);}for(d=0;d<a;d+=4)0===(d+1)%this.ca&&y(this),e=z(this),c.push(e[0],e[1],e[2],e[3]);y(this);return c.slice(0,a)},setDefaultParanoia:function(a,b){if(0===a&&"Setting paranoia=0 will ruin your security; use it only for testing"!==b)throw"Setting paranoia=0 will ruin your security; use it only for testing";this.M=a},addEntropy:function(a,b,c){c=c||"user";
41var d,e,g=(new Date).valueOf(),f=this.H[c],h=this.isReady(),l=0;d=this.U[c];void 0===d&&(d=this.U[c]=this.ha++);void 0===f&&(f=this.H[c]=0);this.H[c]=(this.H[c]+1)%this.c.length;switch(typeof a){case "number":void 0===b&&(b=1);this.c[f].update([d,this.N++,1,b,g,1,a|0]);break;case "object":c=Object.prototype.toString.call(a);if("[object Uint32Array]"===c){e=[];for(c=0;c<a.length;c++)e.push(a[c]);a=e}else for("[object Array]"!==c&&(l=1),c=0;c<a.length&&!l;c++)"number"!==typeof a[c]&&(l=1);if(!l){if(void 0===
42b)for(c=b=0;c<a.length;c++)for(e=a[c];0<e;)b++,e=e>>>1;this.c[f].update([d,this.N++,2,b,g,a.length].concat(a))}break;case "string":void 0===b&&(b=a.length);this.c[f].update([d,this.N++,3,b,g,a.length]);this.c[f].update(a);break;default:l=1}if(l)throw new sjcl.exception.bug("random: addEntropy only supports number, array of numbers or string");this.m[f]+=b;this.f+=b;h===this.u&&(this.isReady()!==this.u&&A("seeded",Math.max(this.o,this.f)),A("progress",this.getProgress()))},isReady:function(a){a=this.T[void 0!==
43a?a:this.M];return this.o&&this.o>=a?this.m[0]>this.ba&&(new Date).valueOf()>this.Z?this.J|this.I:this.I:this.f>=a?this.J|this.u:this.u},getProgress:function(a){a=this.T[a?a:this.M];return this.o>=a?1:this.f>a?1:this.f/a},startCollectors:function(){if(!this.D){this.a={loadTimeCollector:B(this,this.ma),mouseCollector:B(this,this.oa),keyboardCollector:B(this,this.la),accelerometerCollector:B(this,this.ea),touchCollector:B(this,this.qa)};if(window.addEventListener)window.addEventListener("load",this.a.loadTimeCollector,
44!1),window.addEventListener("mousemove",this.a.mouseCollector,!1),window.addEventListener("keypress",this.a.keyboardCollector,!1),window.addEventListener("devicemotion",this.a.accelerometerCollector,!1),window.addEventListener("touchmove",this.a.touchCollector,!1);else if(document.attachEvent)document.attachEvent("onload",this.a.loadTimeCollector),document.attachEvent("onmousemove",this.a.mouseCollector),document.attachEvent("keypress",this.a.keyboardCollector);else throw new sjcl.exception.bug("can't attach event");
45this.D=!0}},stopCollectors:function(){this.D&&(window.removeEventListener?(window.removeEventListener("load",this.a.loadTimeCollector,!1),window.removeEventListener("mousemove",this.a.mouseCollector,!1),window.removeEventListener("keypress",this.a.keyboardCollector,!1),window.removeEventListener("devicemotion",this.a.accelerometerCollector,!1),window.removeEventListener("touchmove",this.a.touchCollector,!1)):document.detachEvent&&(document.detachEvent("onload",this.a.loadTimeCollector),document.detachEvent("onmousemove",
46this.a.mouseCollector),document.detachEvent("keypress",this.a.keyboardCollector)),this.D=!1)},addEventListener:function(a,b){this.K[a][this.ga++]=b},removeEventListener:function(a,b){var c,d,e=this.K[a],g=[];for(d in e)e.hasOwnProperty(d)&&e[d]===b&&g.push(d);for(c=0;c<g.length;c++)d=g[c],delete e[d]},la:function(){C(1)},oa:function(a){var b,c;try{b=a.x||a.clientX||a.offsetX||0,c=a.y||a.clientY||a.offsetY||0}catch(d){c=b=0}0!=b&&0!=c&&sjcl.random.addEntropy([b,c],2,"mouse");C(0)},qa:function(a){a=
47a.touches[0]||a.changedTouches[0];sjcl.random.addEntropy([a.pageX||a.clientX,a.pageY||a.clientY],1,"touch");C(0)},ma:function(){C(2)},ea:function(a){a=a.accelerationIncludingGravity.x||a.accelerationIncludingGravity.y||a.accelerationIncludingGravity.z;if(window.orientation){var b=window.orientation;"number"===typeof b&&sjcl.random.addEntropy(b,1,"accelerometer")}a&&sjcl.random.addEntropy(a,2,"accelerometer");C(0)}};
48function A(a,b){var c,d=sjcl.random.K[a],e=[];for(c in d)d.hasOwnProperty(c)&&e.push(d[c]);for(c=0;c<e.length;c++)e[c](b)}function C(a){"undefined"!==typeof window&&window.performance&&"function"===typeof window.performance.now?sjcl.random.addEntropy(window.performance.now(),a,"loadtime"):sjcl.random.addEntropy((new Date).valueOf(),a,"loadtime")}function y(a){a.b=z(a).concat(z(a));a.L=new sjcl.cipher.aes(a.b)}
49function z(a){for(var b=0;4>b&&(a.h[b]=a.h[b]+1|0,!a.h[b]);b++);return a.L.encrypt(a.h)}function B(a,b){return function(){b.apply(a,arguments)}}sjcl.random=new sjcl.prng(6);
50a:try{var D,E,F,G;if(G="undefined"!==typeof module&&module.exports){var H;try{H=require("crypto")}catch(a){H=null}G=E=H}if(G&&E.randomBytes)D=E.randomBytes(128),D=new Uint32Array((new Uint8Array(D)).buffer),sjcl.random.addEntropy(D,1024,"crypto['randomBytes']");else if("undefined"!==typeof window&&"undefined"!==typeof Uint32Array){F=new Uint32Array(32);if(window.crypto&&window.crypto.getRandomValues)window.crypto.getRandomValues(F);else if(window.msCrypto&&window.msCrypto.getRandomValues)window.msCrypto.getRandomValues(F);
51else break a;sjcl.random.addEntropy(F,1024,"crypto['getRandomValues']")}}catch(a){"undefined"!==typeof window&&window.console&&(console.log("There was an error collecting entropy from the browser:"),console.log(a))}
52sjcl.json={defaults:{v:1,iter:1E3,ks:128,ts:64,mode:"ccm",adata:"",cipher:"aes"},ja:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json,g=e.g({iv:sjcl.random.randomWords(4,0)},e.defaults),f;e.g(g,c);c=g.adata;"string"===typeof g.salt&&(g.salt=sjcl.codec.base64.toBits(g.salt));"string"===typeof g.iv&&(g.iv=sjcl.codec.base64.toBits(g.iv));if(!sjcl.mode[g.mode]||!sjcl.cipher[g.cipher]||"string"===typeof a&&100>=g.iter||64!==g.ts&&96!==g.ts&&128!==g.ts||128!==g.ks&&192!==g.ks&&0x100!==g.ks||2>g.iv.length||
534<g.iv.length)throw new sjcl.exception.invalid("json encrypt: invalid parameters");"string"===typeof a?(f=sjcl.misc.cachedPbkdf2(a,g),a=f.key.slice(0,g.ks/32),g.salt=f.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.publicKey&&(f=a.kem(),g.kemtag=f.tag,a=f.key.slice(0,g.ks/32));"string"===typeof b&&(b=sjcl.codec.utf8String.toBits(b));"string"===typeof c&&(g.adata=c=sjcl.codec.utf8String.toBits(c));f=new sjcl.cipher[g.cipher](a);e.g(d,g);d.key=a;g.ct="ccm"===g.mode&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&
54b instanceof ArrayBuffer?sjcl.arrayBuffer.ccm.encrypt(f,b,g.iv,c,g.ts):sjcl.mode[g.mode].encrypt(f,b,g.iv,c,g.ts);return g},encrypt:function(a,b,c,d){var e=sjcl.json,g=e.ja.apply(e,arguments);return e.encode(g)},ia:function(a,b,c,d){c=c||{};d=d||{};var e=sjcl.json;b=e.g(e.g(e.g({},e.defaults),b),c,!0);var g,f;g=b.adata;"string"===typeof b.salt&&(b.salt=sjcl.codec.base64.toBits(b.salt));"string"===typeof b.iv&&(b.iv=sjcl.codec.base64.toBits(b.iv));if(!sjcl.mode[b.mode]||!sjcl.cipher[b.cipher]||"string"===
55typeof a&&100>=b.iter||64!==b.ts&&96!==b.ts&&128!==b.ts||128!==b.ks&&192!==b.ks&&0x100!==b.ks||!b.iv||2>b.iv.length||4<b.iv.length)throw new sjcl.exception.invalid("json decrypt: invalid parameters");"string"===typeof a?(f=sjcl.misc.cachedPbkdf2(a,b),a=f.key.slice(0,b.ks/32),b.salt=f.salt):sjcl.ecc&&a instanceof sjcl.ecc.elGamal.secretKey&&(a=a.unkem(sjcl.codec.base64.toBits(b.kemtag)).slice(0,b.ks/32));"string"===typeof g&&(g=sjcl.codec.utf8String.toBits(g));f=new sjcl.cipher[b.cipher](a);g="ccm"===
56b.mode&&sjcl.arrayBuffer&&sjcl.arrayBuffer.ccm&&b.ct instanceof ArrayBuffer?sjcl.arrayBuffer.ccm.decrypt(f,b.ct,b.iv,b.tag,g,b.ts):sjcl.mode[b.mode].decrypt(f,b.ct,b.iv,g,b.ts);e.g(d,b);d.key=a;return 1===c.raw?g:sjcl.codec.utf8String.fromBits(g)},decrypt:function(a,b,c,d){var e=sjcl.json;return e.ia(a,e.decode(b),c,d)},encode:function(a){var b,c="{",d="";for(b in a)if(a.hasOwnProperty(b)){if(!b.match(/^[a-z0-9]+$/i))throw new sjcl.exception.invalid("json encode: invalid property name");c+=d+'"'+
57b+'":';d=",";switch(typeof a[b]){case "number":case "boolean":c+=a[b];break;case "string":c+='"'+escape(a[b])+'"';break;case "object":c+='"'+sjcl.codec.base64.fromBits(a[b],0)+'"';break;default:throw new sjcl.exception.bug("json encode: unsupported type");}}return c+"}"},decode:function(a){a=a.replace(/\s/g,"");if(!a.match(/^\{.*\}$/))throw new sjcl.exception.invalid("json decode: this isn't json!");a=a.replace(/^\{|\}$/g,"").split(/,/);var b={},c,d;for(c=0;c<a.length;c++){if(!(d=a[c].match(/^\s*(?:(["']?)([a-z][a-z0-9]*)\1)\s*:\s*(?:(-?\d+)|"([a-z0-9+\/%*_.@=\-]*)"|(true|false))$/i)))throw new sjcl.exception.invalid("json decode: this isn't json!");
58null!=d[3]?b[d[2]]=parseInt(d[3],10):null!=d[4]?b[d[2]]=d[2].match(/^(ct|adata|salt|iv)$/)?sjcl.codec.base64.toBits(d[4]):unescape(d[4]):null!=d[5]&&(b[d[2]]="true"===d[5])}return b},g:function(a,b,c){void 0===a&&(a={});if(void 0===b)return a;for(var d in b)if(b.hasOwnProperty(d)){if(c&&void 0!==a[d]&&a[d]!==b[d])throw new sjcl.exception.invalid("required parameter overridden");a[d]=b[d]}return a},sa:function(a,b){var c={},d;for(d in a)a.hasOwnProperty(d)&&a[d]!==b[d]&&(c[d]=a[d]);return c},ra:function(a,
59b){var c={},d;for(d=0;d<b.length;d++)void 0!==a[b[d]]&&(c[b[d]]=a[b[d]]);return c}};sjcl.encrypt=sjcl.json.encrypt;sjcl.decrypt=sjcl.json.decrypt;sjcl.misc.pa={};sjcl.misc.cachedPbkdf2=function(a,b){var c=sjcl.misc.pa,d;b=b||{};d=b.iter||1E3;c=c[a]=c[a]||{};d=c[d]=c[d]||{firstSalt:b.salt&&b.salt.length?b.salt.slice(0):sjcl.random.randomWords(2,0)};c=void 0===b.salt?d.firstSalt:b.salt;d[c]=d[c]||sjcl.misc.pbkdf2(a,c,b.iter);return{key:d[c].slice(0),salt:c.slice(0)}};