diff --git a/react/change.log b/react/change.log
index 65eee02..5ee34f5 100644
--- a/react/change.log
+++ b/react/change.log
@@ -16,6 +16,10 @@ UI:
 - qr code generator / scan
 - basilisk send form reset fix
 - added native wallet info button
+- added coqui assetchain
+- jumblr
+- zcashparams folder check
+- claim interest modal
 
 v0.2.0.21a-beta
 --------------
diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js
index 69d451c..5919f83 100644
--- a/react/src/actions/actionCreators.js
+++ b/react/src/actions/actionCreators.js
@@ -27,6 +27,7 @@ import {
   DASHBOARD_ACTIVE_COIN_NATIVE_TXHISTORY,
   DISPLAY_LOGIN_SETTINGS_MODAL,
   DISPLAY_COIND_DOWN_MODAL,
+  DISPLAY_CLAIM_INTEREST_MODAL,
   START_INTERVAL,
   STOP_INTERVAL
 } from './storeType';
@@ -68,6 +69,8 @@ export * from './actions/basiliskTxHistory';
 export * from './actions/iguanaHelpers';
 export * from './actions/cli';
 export * from './actions/update';
+export * from './actions/jumblr';
+export * from './actions/interest';
 
 export function changeActiveAddress(address) {
   return {
@@ -366,4 +369,11 @@ export function toggleLoginSettingsModal(display) {
     type: DISPLAY_LOGIN_SETTINGS_MODAL,
     displayLoginSettingsModal: display,
   }
+}
+
+export function toggleClaimInterestModal(display) {
+  return {
+    type: DISPLAY_CLAIM_INTEREST_MODAL,
+    displayClaimInterestModal: display,
+  }
 }
\ No newline at end of file
diff --git a/react/src/actions/actions/copyAddress.js b/react/src/actions/actions/copyAddress.js
index 9bf15fe..9accd3b 100644
--- a/react/src/actions/actions/copyAddress.js
+++ b/react/src/actions/actions/copyAddress.js
@@ -14,4 +14,18 @@ export function copyCoinAddress(address) {
       )
     );
   }
+}
+
+export function copyString(string, message) {
+  const _result = copyToClipboard(string);
+
+  return dispatch => {
+    dispatch(
+      triggerToaster(
+        message,
+        translate('TOASTR.COIN_NOTIFICATION'),
+        _result ? 'success' : 'error'
+      )
+    );
+  }
 }
\ No newline at end of file
diff --git a/react/src/actions/actions/interest.js b/react/src/actions/actions/interest.js
new file mode 100644
index 0000000..1dd95c6
--- /dev/null
+++ b/react/src/actions/actions/interest.js
@@ -0,0 +1,86 @@
+import {
+  triggerToaster
+} from '../actionCreators';
+import {
+  logGuiHttp,
+  guiLogState
+} from './log';
+import Config from '../../config';
+
+export function getListUnspent(coin) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'listunspent',
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'getListUnspent',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json.result ? json.result : json);
+    })
+  });
+}
+
+export function getRawTransaction(coin, txid) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'getrawtransaction',
+      params: [
+        txid,
+        1
+      ],
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'getTransaction',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json.result ? json.result : json);
+    })
+  });
+}
\ No newline at end of file
diff --git a/react/src/actions/actions/jumblr.js b/react/src/actions/actions/jumblr.js
new file mode 100644
index 0000000..c734c07
--- /dev/null
+++ b/react/src/actions/actions/jumblr.js
@@ -0,0 +1,164 @@
+import {
+  triggerToaster,
+  getNewKMDAddresses
+} from '../actionCreators';
+import {
+  logGuiHttp,
+  guiLogState
+} from './log';
+import Config from '../../config';
+
+function getNewAddress(coin) { // TODO: remove(?)
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'getnewaddress'
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'genJumblrAddress + getKMDAddressesNative',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json.result ? json.result : json);
+    })
+  });
+}
+
+export function setJumblrAddress(coin, type, address) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: type === 'deposit' ? 'jumblr_deposit' : 'jumblr_secret',
+      params: [address],
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'setJumblrAddress',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json);
+    });
+  });
+}
+
+function dumpPrivkey(coin, key) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'dumpprivkey',
+      params: [key],
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'dumpPrivkey ',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json.result ? json.result : json);
+    })
+  });
+}
+
+export function importPrivkey(coin, key) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'importprivkey',
+      params: [
+        key,
+        '',
+        false
+      ],
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'importPrivkey ',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json.result ? json.result : json);
+    })
+  });
+}
\ No newline at end of file
diff --git a/react/src/actions/actions/log.js b/react/src/actions/actions/log.js
index ca42d5b..c53f402 100644
--- a/react/src/actions/actions/log.js
+++ b/react/src/actions/actions/log.js
@@ -41,7 +41,6 @@ export function getAgamaLog(type) {
       );
     })
     .then(response => response.json())
-    .then()
   }
 }
 
diff --git a/react/src/actions/actions/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js
index 4bd4088..e3f9821 100644
--- a/react/src/actions/actions/nativeNewAddress.js
+++ b/react/src/actions/actions/nativeNewAddress.js
@@ -10,21 +10,7 @@ import {
   guiLogState
 } from './log';
 
-function handleGetNewKMDAddresses(pubpriv, coin, dispatch, json) {
-  dispatch(
-    triggerToaster(
-      json.result ? json.result : json,
-      translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
-      'info',
-      false
-    )
-  );
-  dispatch(getKMDAddressesNative(coin));
-
-  return {};
-}
-
-export function getNewKMDAddresses(coin, pubpriv) {
+export function getNewKMDAddresses(coin, pubpriv, mode) {
   let payload;
   let ajaxFunctionInput = pubpriv === 'public' ? 'getnewaddress' : 'z_getnewaddress';
 
@@ -115,22 +101,25 @@ export function getNewKMDAddresses(coin, pubpriv) {
         }));
       }
       dispatch(
-        handleGetNewKMDAddresses(
-          pubpriv,
-          coin,
-          dispatch,
-          json
+        triggerToaster(
+          json.result ? json.result : json,
+          translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
+          'info',
+          false
         )
       );
+      dispatch(getKMDAddressesNative(coin, mode));
     })
     .catch(function(ex) {
       dispatch(
-        handleGetNewKMDAddresses(
-          pubpriv,
-          coin,
-          dispatch
+        triggerToaster(
+          json.result ? json.result : json,
+          translate('KMD_NATIVE.NEW_ADDR_GENERATED'),
+          'info',
+          false
         )
       );
+      dispatch(getKMDAddressesNative(coin, mode));
     });
   }
 }
\ No newline at end of file
diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js
index 0f788c8..fc3e3e2 100644
--- a/react/src/actions/actions/nativeSend.js
+++ b/react/src/actions/actions/nativeSend.js
@@ -195,7 +195,7 @@ export function getKMDOPID(opid, coin) {
           passthruAgent = getPassthruAgent(coin),
           tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`;
 
-      if (passthruAgent == 'iguana') {
+      if (passthruAgent === 'iguana') {
         payload = {
           'userpass': tmpIguanaRPCAuth,
           'agent': passthruAgent,
@@ -284,4 +284,48 @@ export function getKMDOPID(opid, coin) {
       })
     })
   }
+}
+
+export function sendToAddressPromise(coin, address, amount) {
+  return new Promise((resolve, reject) => {
+    const payload = {
+      mode: null,
+      chain: coin,
+      cmd: 'sendtoaddress',
+      params: [
+        address,
+        amount,
+        'KMD interest claim request',
+        'KMD interest claim request',
+        true
+      ]
+    };
+
+    const _fetchConfig = {
+      method: 'POST',
+      headers: {
+        'Content-Type': 'application/json',
+      },
+      body: JSON.stringify({ 'payload': payload }),
+    };
+
+    fetch(
+      `http://127.0.0.1:${Config.agamaPort}/shepherd/cli`,
+      _fetchConfig
+    )
+    .catch(function(error) {
+      console.log(error);
+      dispatch(
+        triggerToaster(
+          'sendToAddress',
+          'Error',
+          'error'
+        )
+      );
+    })
+    .then(response => response.json())
+    .then(json => {
+      resolve(json);
+    })
+  });
 }
\ No newline at end of file
diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js
index 8260128..009c190 100644
--- a/react/src/actions/actions/nativeSyncInfo.js
+++ b/react/src/actions/actions/nativeSyncInfo.js
@@ -11,9 +11,9 @@ import {
 } from './log';
 import Config from '../../config';
 
-export function getSyncInfoNativeKMD(skipDebug) {
+export function getSyncInfoNativeKMD(skipDebug, json) {
   const coin = 'KMD';
-
+  // https://www.kmd.host/
   return dispatch => {
     const _timestamp = Date.now();
     if (Config.debug) {
@@ -40,13 +40,15 @@ export function getSyncInfoNativeKMD(skipDebug) {
           'response': error,
         }));
       }
-      dispatch(
+      /*dispatch(
         triggerToaster(
           'getSyncInfoNativeKMD',
           'Error',
           'error'
         )
-      );
+      );*/
+    console.warn('remote kmd node fetch failed', true);
+      dispatch(getSyncInfoNativeState({ 'remoteKMDNode': null }));
     })
     .then(response => response.json())
     .then(json => {
@@ -72,7 +74,7 @@ function getSyncInfoNativeState(json, coin, skipDebug) {
       json &&
       json.error &&
       json.error.message.indexOf('Activating best') === -1) {
-    return getSyncInfoNativeKMD(skipDebug);
+    return getSyncInfoNativeKMD(skipDebug, json);
   } else {
     if (json &&
         json.error &&
@@ -161,41 +163,60 @@ export function getSyncInfoNative(coin, skipDebug) {
       return _response;
     })
     .then(json => {
-      if (!json &&
-        Config.cli.default) {
+      if (json === 'Work queue depth exceeded') {
         dispatch(
-          triggerToaster(
-            'Komodod is down',
-            'Critical Error',
-            'error',
-            true
+          getSyncInfoNativeState(
+            { result: 'daemon is busy', error: null, id: null },
+            coin,
+            skipDebug
           )
         );
-        dispatch(getDebugLog('komodo', 50));
-        dispatch(toggleCoindDownModal(true));
       } else {
-        json = JSON.parse(json);
-      }
+        if (!json &&
+          Config.cli.default) {
+          dispatch(
+            triggerToaster(
+              'Komodod is down',
+              'Critical Error',
+              'error',
+              true
+            )
+          );
 
-      if (json.error &&
-          json.error.message.indexOf('Activating best') === -1) {
-        dispatch(getDebugLog('komodo', 1));
-      }
+          if (coin === 'KMD') {
+            dispatch(getDebugLog('komodo', 50));
+          } else {
+            dispatch(getDebugLog('komodo', 50, coin));
+          }
+          dispatch(toggleCoindDownModal(true));
+        } else {
+          json = JSON.parse(json);
+        }
 
-      if (Config.debug) {
-        dispatch(logGuiHttp({
-          'timestamp': _timestamp,
-          'status': 'success',
-          'response': json,
-        }));
+        if (json.error &&
+            json.error.message.indexOf('Activating best') === -1) {
+          if (coin === 'KMD') {
+            dispatch(getDebugLog('komodo', 1));
+          } else {
+            dispatch(getDebugLog('komodo', 1, coin));
+          }
+        }
+
+        if (Config.debug) {
+          dispatch(logGuiHttp({
+            'timestamp': _timestamp,
+            'status': 'success',
+            'response': json,
+          }));
+        }
+        dispatch(
+          getSyncInfoNativeState(
+            json,
+            coin,
+            skipDebug
+          )
+        );
       }
-      dispatch(
-        getSyncInfoNativeState(
-          json,
-          coin,
-          skipDebug
-        )
-      );
     })
   }
 }
\ No newline at end of file
diff --git a/react/src/actions/actions/settings.js b/react/src/actions/actions/settings.js
index f38adfa..2b53637 100644
--- a/react/src/actions/actions/settings.js
+++ b/react/src/actions/actions/settings.js
@@ -167,12 +167,16 @@ function getDebugLogState(json) {
   }
 }
 
-export function getDebugLog(target, linesCount) {
+export function getDebugLog(target, linesCount, acName) {
   const payload = {
     'herdname': target,
     'lastLines': linesCount
   };
 
+  if (acName) {
+    payload['ac'] = acName;
+  }
+
   return dispatch => {
     return fetch(`http://127.0.0.1:${Config.agamaPort}/shepherd/debuglog`, {
       method: 'POST',
diff --git a/react/src/actions/storeType.js b/react/src/actions/storeType.js
index 23deb33..1e4c8af 100644
--- a/react/src/actions/storeType.js
+++ b/react/src/actions/storeType.js
@@ -45,4 +45,5 @@ export const LOG_GUI_HTTP = 'LOG_GUI_HTTP';
 export const CLI = 'CLI';
 export const LOGOUT = 'LOGOUT';
 export const DISPLAY_COIND_DOWN_MODAL = 'DISPLAY_COIND_DOWN_MODAL';
-export const DISPLAY_LOGIN_SETTINGS_MODAL = 'DISPLAY_LOGIN_SETTINGS_MODAL';
\ No newline at end of file
+export const DISPLAY_LOGIN_SETTINGS_MODAL = 'DISPLAY_LOGIN_SETTINGS_MODAL';
+export const DISPLAY_CLAIM_INTEREST_MODAL = 'DISPLAY_CLAIM_INTEREST_MODAL';
\ No newline at end of file
diff --git a/react/src/assets/images/cryptologo/AUD.png b/react/src/assets/images/cryptologo/aud.png
similarity index 100%
rename from react/src/assets/images/cryptologo/AUD.png
rename to react/src/assets/images/cryptologo/aud.png
diff --git a/react/src/assets/images/cryptologo/BET.png b/react/src/assets/images/cryptologo/bet.png
similarity index 100%
rename from react/src/assets/images/cryptologo/BET.png
rename to react/src/assets/images/cryptologo/bet.png
diff --git a/react/src/assets/images/cryptologo/BGN.png b/react/src/assets/images/cryptologo/bgn.png
similarity index 100%
rename from react/src/assets/images/cryptologo/BGN.png
rename to react/src/assets/images/cryptologo/bgn.png
diff --git a/react/src/assets/images/cryptologo/BOTS.png b/react/src/assets/images/cryptologo/bots.png
similarity index 100%
rename from react/src/assets/images/cryptologo/BOTS.png
rename to react/src/assets/images/cryptologo/bots.png
diff --git a/react/src/assets/images/cryptologo/BRL.png b/react/src/assets/images/cryptologo/brl.png
similarity index 100%
rename from react/src/assets/images/cryptologo/BRL.png
rename to react/src/assets/images/cryptologo/brl.png
diff --git a/react/src/assets/images/cryptologo/CAD.png b/react/src/assets/images/cryptologo/cad.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CAD.png
rename to react/src/assets/images/cryptologo/cad.png
diff --git a/react/src/assets/images/cryptologo/CEAL.png b/react/src/assets/images/cryptologo/ceal.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CEAL.png
rename to react/src/assets/images/cryptologo/ceal.png
diff --git a/react/src/assets/images/cryptologo/CHF.png b/react/src/assets/images/cryptologo/chf.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CHF.png
rename to react/src/assets/images/cryptologo/chf.png
diff --git a/react/src/assets/images/cryptologo/CNY.png b/react/src/assets/images/cryptologo/cny.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CNY.png
rename to react/src/assets/images/cryptologo/cny.png
diff --git a/react/src/assets/images/cryptologo/coqui.png b/react/src/assets/images/cryptologo/coqui.png
new file mode 100644
index 0000000..59f61a8
Binary files /dev/null and b/react/src/assets/images/cryptologo/coqui.png differ
diff --git a/react/src/assets/images/cryptologo/CRYPTO.png b/react/src/assets/images/cryptologo/crypto.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CRYPTO.png
rename to react/src/assets/images/cryptologo/crypto.png
diff --git a/react/src/assets/images/cryptologo/CZK.png b/react/src/assets/images/cryptologo/czk.png
similarity index 100%
rename from react/src/assets/images/cryptologo/CZK.png
rename to react/src/assets/images/cryptologo/czk.png
diff --git a/react/src/assets/images/cryptologo/DKK.png b/react/src/assets/images/cryptologo/dkk.png
similarity index 100%
rename from react/src/assets/images/cryptologo/DKK.png
rename to react/src/assets/images/cryptologo/dkk.png
diff --git a/react/src/assets/images/cryptologo/EUR.png b/react/src/assets/images/cryptologo/eur.png
similarity index 100%
rename from react/src/assets/images/cryptologo/EUR.png
rename to react/src/assets/images/cryptologo/eur.png
diff --git a/react/src/assets/images/cryptologo/GAME.png b/react/src/assets/images/cryptologo/game.png
similarity index 100%
rename from react/src/assets/images/cryptologo/GAME.png
rename to react/src/assets/images/cryptologo/game.png
diff --git a/react/src/assets/images/cryptologo/GBP.png b/react/src/assets/images/cryptologo/gbp.png
similarity index 100%
rename from react/src/assets/images/cryptologo/GBP.png
rename to react/src/assets/images/cryptologo/gbp.png
diff --git a/react/src/assets/images/cryptologo/HKD.png b/react/src/assets/images/cryptologo/hkd.png
similarity index 100%
rename from react/src/assets/images/cryptologo/HKD.png
rename to react/src/assets/images/cryptologo/hkd.png
diff --git a/react/src/assets/images/cryptologo/HODL.png b/react/src/assets/images/cryptologo/hodl.png
similarity index 100%
rename from react/src/assets/images/cryptologo/HODL.png
rename to react/src/assets/images/cryptologo/hodl.png
diff --git a/react/src/assets/images/cryptologo/HRK.png b/react/src/assets/images/cryptologo/hrk.png
similarity index 100%
rename from react/src/assets/images/cryptologo/HRK.png
rename to react/src/assets/images/cryptologo/hrk.png
diff --git a/react/src/assets/images/cryptologo/HUF.png b/react/src/assets/images/cryptologo/huf.png
similarity index 100%
rename from react/src/assets/images/cryptologo/HUF.png
rename to react/src/assets/images/cryptologo/huf.png
diff --git a/react/src/assets/images/cryptologo/IDR.png b/react/src/assets/images/cryptologo/idr.png
similarity index 100%
rename from react/src/assets/images/cryptologo/IDR.png
rename to react/src/assets/images/cryptologo/idr.png
diff --git a/react/src/assets/images/cryptologo/ILS.png b/react/src/assets/images/cryptologo/ils.png
similarity index 100%
rename from react/src/assets/images/cryptologo/ILS.png
rename to react/src/assets/images/cryptologo/ils.png
diff --git a/react/src/assets/images/cryptologo/INR.png b/react/src/assets/images/cryptologo/inr.png
similarity index 100%
rename from react/src/assets/images/cryptologo/INR.png
rename to react/src/assets/images/cryptologo/inr.png
diff --git a/react/src/assets/images/cryptologo/JPY.png b/react/src/assets/images/cryptologo/jpy.png
similarity index 100%
rename from react/src/assets/images/cryptologo/JPY.png
rename to react/src/assets/images/cryptologo/jpy.png
diff --git a/react/src/assets/images/cryptologo/JUMBLR.png b/react/src/assets/images/cryptologo/jumblr.png
similarity index 100%
rename from react/src/assets/images/cryptologo/JUMBLR.png
rename to react/src/assets/images/cryptologo/jumblr.png
diff --git a/react/src/assets/images/cryptologo/komodo.png b/react/src/assets/images/cryptologo/kmd.png
similarity index 100%
rename from react/src/assets/images/cryptologo/komodo.png
rename to react/src/assets/images/cryptologo/kmd.png
diff --git a/react/src/assets/images/cryptologo/KRW.png b/react/src/assets/images/cryptologo/krw.png
similarity index 100%
rename from react/src/assets/images/cryptologo/KRW.png
rename to react/src/assets/images/cryptologo/krw.png
diff --git a/react/src/assets/images/cryptologo/KV.png b/react/src/assets/images/cryptologo/kv.png
similarity index 100%
rename from react/src/assets/images/cryptologo/KV.png
rename to react/src/assets/images/cryptologo/kv.png
diff --git a/react/src/assets/images/cryptologo/MESH.png b/react/src/assets/images/cryptologo/mesh.png
similarity index 100%
rename from react/src/assets/images/cryptologo/MESH.png
rename to react/src/assets/images/cryptologo/mesh.png
diff --git a/react/src/assets/images/cryptologo/MGW.png b/react/src/assets/images/cryptologo/mgw.png
similarity index 100%
rename from react/src/assets/images/cryptologo/MGW.png
rename to react/src/assets/images/cryptologo/mgw.png
diff --git a/react/src/assets/images/cryptologo/MVP.png b/react/src/assets/images/cryptologo/mvp.png
similarity index 100%
rename from react/src/assets/images/cryptologo/MVP.png
rename to react/src/assets/images/cryptologo/mvp.png
diff --git a/react/src/assets/images/cryptologo/MXN.png b/react/src/assets/images/cryptologo/mxn.png
similarity index 100%
rename from react/src/assets/images/cryptologo/MXN.png
rename to react/src/assets/images/cryptologo/mxn.png
diff --git a/react/src/assets/images/cryptologo/MYR.png b/react/src/assets/images/cryptologo/myr.png
similarity index 100%
rename from react/src/assets/images/cryptologo/MYR.png
rename to react/src/assets/images/cryptologo/myr.png
diff --git a/react/src/assets/images/cryptologo/NOK.png b/react/src/assets/images/cryptologo/nok.png
similarity index 100%
rename from react/src/assets/images/cryptologo/NOK.png
rename to react/src/assets/images/cryptologo/nok.png
diff --git a/react/src/assets/images/cryptologo/NZD.png b/react/src/assets/images/cryptologo/nzd.png
similarity index 100%
rename from react/src/assets/images/cryptologo/NZD.png
rename to react/src/assets/images/cryptologo/nzd.png
diff --git a/react/src/assets/images/cryptologo/PANGEA.png b/react/src/assets/images/cryptologo/pangea.png
similarity index 100%
rename from react/src/assets/images/cryptologo/PANGEA.png
rename to react/src/assets/images/cryptologo/pangea.png
diff --git a/react/src/assets/images/cryptologo/PHP.png b/react/src/assets/images/cryptologo/php.png
similarity index 100%
rename from react/src/assets/images/cryptologo/PHP.png
rename to react/src/assets/images/cryptologo/php.png
diff --git a/react/src/assets/images/cryptologo/PLN.png b/react/src/assets/images/cryptologo/pln.png
similarity index 100%
rename from react/src/assets/images/cryptologo/PLN.png
rename to react/src/assets/images/cryptologo/pln.png
diff --git a/react/src/assets/images/cryptologo/REVS.png b/react/src/assets/images/cryptologo/revs.png
similarity index 100%
rename from react/src/assets/images/cryptologo/REVS.png
rename to react/src/assets/images/cryptologo/revs.png
diff --git a/react/src/assets/images/cryptologo/RON.png b/react/src/assets/images/cryptologo/ron.png
similarity index 100%
rename from react/src/assets/images/cryptologo/RON.png
rename to react/src/assets/images/cryptologo/ron.png
diff --git a/react/src/assets/images/cryptologo/RUB.png b/react/src/assets/images/cryptologo/rub.png
similarity index 100%
rename from react/src/assets/images/cryptologo/RUB.png
rename to react/src/assets/images/cryptologo/rub.png
diff --git a/react/src/assets/images/cryptologo/SEK.png b/react/src/assets/images/cryptologo/sek.png
similarity index 100%
rename from react/src/assets/images/cryptologo/SEK.png
rename to react/src/assets/images/cryptologo/sek.png
diff --git a/react/src/assets/images/cryptologo/SGD.png b/react/src/assets/images/cryptologo/sgd.png
similarity index 100%
rename from react/src/assets/images/cryptologo/SGD.png
rename to react/src/assets/images/cryptologo/sgd.png
diff --git a/react/src/assets/images/cryptologo/SHARK.png b/react/src/assets/images/cryptologo/shark.png
similarity index 100%
rename from react/src/assets/images/cryptologo/SHARK.png
rename to react/src/assets/images/cryptologo/shark.png
diff --git a/react/src/assets/images/cryptologo/SUPERNET.png b/react/src/assets/images/cryptologo/supernet.png
similarity index 100%
rename from react/src/assets/images/cryptologo/SUPERNET.png
rename to react/src/assets/images/cryptologo/supernet.png
diff --git a/react/src/assets/images/cryptologo/THB.png b/react/src/assets/images/cryptologo/thb.png
similarity index 100%
rename from react/src/assets/images/cryptologo/THB.png
rename to react/src/assets/images/cryptologo/thb.png
diff --git a/react/src/assets/images/cryptologo/TRY.png b/react/src/assets/images/cryptologo/try.png
similarity index 100%
rename from react/src/assets/images/cryptologo/TRY.png
rename to react/src/assets/images/cryptologo/try.png
diff --git a/react/src/assets/images/cryptologo/WLC.png b/react/src/assets/images/cryptologo/wlc.png
similarity index 100%
rename from react/src/assets/images/cryptologo/WLC.png
rename to react/src/assets/images/cryptologo/wlc.png
diff --git a/react/src/assets/images/cryptologo/ZAR.png b/react/src/assets/images/cryptologo/zar.png
similarity index 100%
rename from react/src/assets/images/cryptologo/ZAR.png
rename to react/src/assets/images/cryptologo/zar.png
diff --git a/react/src/components/addcoin/addcoinOptionsAC.js b/react/src/components/addcoin/addcoinOptionsAC.js
index f47202c..020a097 100644
--- a/react/src/components/addcoin/addcoinOptionsAC.js
+++ b/react/src/components/addcoin/addcoinOptionsAC.js
@@ -8,6 +8,7 @@ class AddCoinOptionsAC extends React.Component {
         <option value="BET|basilisk|native">BET (BET)</option>
         <option value="BOTS|basilisk|native">BOTS (BOTS)</option>
         <option value="CEAL|basilisk|native">CEAL NET (CEAL)</option>
+        <option value="COQUI|basilisk|native">COQUI (COQUI)</option>
         <option value="CRYPTO|basilisk|native">CRYPTO (CRYPTO)</option>
         <option value="HOD|basilisk|native">HODL (HODL)</option>
         <option value="DEX|basilisk|native">InstantDEX (DEX)</option>
diff --git a/react/src/components/addcoin/payload.js b/react/src/components/addcoin/payload.js
index 7ea2ef3..7e727f6 100644
--- a/react/src/components/addcoin/payload.js
+++ b/react/src/components/addcoin/payload.js
@@ -1,4 +1,5 @@
 // TODO: merge check functions
+//			 move to nodejs
 
 export function checkAC(coinVal) {
 	if (coinVal === 'SUPERNET' ||
@@ -9,6 +10,7 @@ export function checkAC(coinVal) {
 			coinVal === 'JUMBLR' ||
 			coinVal === 'BET' ||
 			coinVal === 'CRYPTO' ||
+			coinVal === 'COQUI' ||
 			coinVal === 'HODL' ||
 			coinVal === 'SHARK' ||
 			coinVal === 'BOTS' ||
@@ -98,6 +100,7 @@ export function checkCoinType(coin) {
 			coin === 'JUMBLR' ||
 			coin === 'BET' ||
 			coin === 'CRYPTO' ||
+			coin === 'COQUI' ||
 			coin === 'HODL' ||
 			coin === 'SHARK' ||
 			coin === 'BOTS' ||
@@ -131,10 +134,10 @@ export function checkCoinType(coin) {
 }
 
 export function startCrypto(confpath, coin, mode) {
-	let tmpinternval = 0,
-			AddCoinData = {},
-			tmpPendValue = 1, // TODO: hook up to shepherd sysinfo
-			tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`;
+	let tmpinternval = 0;
+	let AddCoinData = {};
+	let tmpPendValue = 1; // TODO: hook up to shepherd sysinfo
+	let tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`;
 
 	if (coin !== 'BTC' &&
       coin !== 'LTC' &&
@@ -176,9 +179,9 @@ export function startCrypto(confpath, coin, mode) {
 }
 
 export function startCurrencyAssetChain(confpath, coin, mode) {
-	let AddCoinDataPayload = {},
-			tmpPendValue = 1,
-			tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`;
+	let AddCoinDataPayload = {};
+	let tmpPendValue = 1;
+	let tmpIguanaRPCAuth = `tmpIgRPCUser@${sessionStorage.getItem('IguanaRPCAuth')}`;
 
 	if (coin !== 'BTC' &&
       coin !== 'LTC' &&
@@ -702,7 +705,7 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) {
 		},
 		'DEX': {
 			'name': 'DEX',
-			'supply': 1300000,
+			'supply': 999999,
 			'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"DEX","conf":"DEX.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":9502,"rpc":9503}) : {},
 			'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"DEX","name":"DEX","netmagic":"f2ae0516","p2p":9502,"rpc":9503})
 		},
@@ -726,7 +729,7 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) {
 		},
 		'HODL': {
 			'name': 'HODL',
-			'supply': 999999,
+			'supply': 9999999,
 			'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"HODL","conf":"HODL.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":8009,"rpc":8010}) : {},
 			'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"HODL","name":"HODL","netmagic":"9b13fb5f","p2p":8009,"rpc":8010})
 		},
@@ -756,7 +759,7 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) {
 		},
 		'KV': {
 			'name': 'KV',
-			'supply': 999999,
+			'supply': 1000000,
 			'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"KV","conf":"KV.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":9746,"rpc":9747}) : {},
 			'AddCoinDataVar': Object.assign(_acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"KV","name":"KV","netmagic":"b09a2d65","p2p":9746,"rpc":9747})
 		},
@@ -768,9 +771,15 @@ export function startAssetChain(confpath, coin, mode, getSuppyOnly) {
 		},
 		'MESH': {
 			'name': 'MESH',
-			'supply': 1000000,
+			'supply': 1000007,
 			'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"MESH","conf":"MESH.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":8399,"rpc":8400}) : {},
 			'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"MESH","name":"MESH","netmagic":"f0265c67","p2p":8399,"rpc":8400})
+		},
+		'COQUI': {
+			'name': 'COQUI',
+			'supply': 72000000,
+			'AddCoinData': confpath ? Object.assign({}, _acPayloadOrigin, {"coin":"COQUI","conf":"COQUI.conf","path":confpath,"RELAY":-1,"VALIDATE":1,"startpend":4,"endpend":4,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":14275,"rpc":14276}) : {},
+			'AddCoinDataVar': Object.assign({}, _acPayloadOrigin, {'userpass':tmpIguanaRPCAuth,"RELAY":mode,"VALIDATE":mode,"startpend":tmpPendValue,"endpend":tmpPendValue,"maxpeers":8,"newcoin":"COQUI","name":"COQUI","netmagic":"4cbd5ef4","p2p":14275,"rpc":14276})
 		}
 	};
 
diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js
new file mode 100755
index 0000000..94e05f5
--- /dev/null
+++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js
@@ -0,0 +1,136 @@
+import React from 'react';
+import ReactDOM from 'react-dom';
+import Store from '../../../store';
+import {
+  toggleClaimInterestModal,
+  getListUnspent,
+  getRawTransaction,
+  copyString,
+  sendToAddressPromise,
+  triggerToaster
+} from '../../../actions/actionCreators';
+import { translate } from '../../../translate/translate';
+import {
+  ClaimInterestModalRender,
+  _ClaimInterestTableRender
+} from './claimInterestModal.render';
+
+class ClaimInterestModal extends React.Component {
+  constructor(props) {
+    super(props);
+    this.state = {
+      open: false,
+      isLoading: true,
+      transactionsList: [],
+      showZeroInterest: true,
+    };
+    this.claimInterestTableRender = this.claimInterestTableRender.bind(this);
+    this.toggleZeroInterest = this.toggleZeroInterest.bind(this);
+    this.loadListUnspent = this.loadListUnspent.bind(this);
+    this.checkTransactionsListLength = this.checkTransactionsListLength.bind(this);
+  }
+
+  componentWillMount() {
+    this.loadListUnspent();
+  }
+
+  loadListUnspent() {
+    let _transactionsList = [];
+
+    getListUnspent(this.props.ActiveCoin.coin)
+    .then((json) => {
+      if (json &&
+          json.length) {
+        for (let i = 0; i < json.length; i++) {
+          getRawTransaction(this.props.ActiveCoin.coin, json[i].txid)
+          .then((_json) => {
+            _transactionsList.push({
+              address: json[i].address,
+              locktime: _json.locktime,
+              amount: json[i].amount,
+              interest: json[i].interest,
+              txid: json[i].txid,
+            });
+
+            if (i === json.length - 1) {
+              this.setState({
+                transactionsList: _transactionsList,
+                isLoading: false,
+              });
+            }
+          });
+        }
+      }
+    });
+  }
+
+  claimInterest(address, amount) {
+    sendToAddressPromise(this.props.ActiveCoin.coin, this.state.transactionsList[0].address, this.props.ActiveCoin.balance.transparent)
+    .then((json) => {
+      if (json.error &&
+          json.error.code) {
+        Store.dispatch(
+          triggerToaster(
+            json.error.message,
+            'Error',
+            'error'
+          )
+        );
+      } else if (json.result && json.result.length && json.result.length === 64) {
+        Store.dispatch(
+          triggerToaster(
+            `Your full balance is sent to address ${this.state.transactionsList[0].address}. Check back your new balance in a few minutes.`,
+            translate('TOASTR.WALLET_NOTIFICATION'),
+            'success',
+            false
+          )
+        );
+      }
+    });
+  }
+
+  checkTransactionsListLength() {
+    if (this.state.transactionsList && this.state.transactionsList.length) {
+      return true;
+    } else if (!this.state.transactionsList || !this.state.transactionsList.length) {
+      return false;
+    }
+  }
+
+  toggleZeroInterest() {
+    this.setState({
+      showZeroInterest: !this.state.showZeroInterest,
+    });
+  }
+
+  copyTxId(txid) {
+    Store.dispatch(copyString(txid, 'Transaction ID copied'));
+  }
+
+  claimInterestTableRender() {
+    return _ClaimInterestTableRender.call(this);
+  }
+
+  componentWillReceiveProps(props) {
+    if (props.Dashboard.displayClaimInterestModal !== this.state.open) {
+      this.setState({
+        open: props.Dashboard.displayClaimInterestModal,
+      });
+    }
+
+    if (!this.state.open &&
+        props.Dashboard.displayClaimInterestModal) {
+      this.loadListUnspent();
+    }
+  }
+
+  closeModal() {
+    Store.dispatch(toggleClaimInterestModal(false));
+  }
+
+  render() {
+    return ClaimInterestModalRender.call(this);
+  }
+}
+
+export default ClaimInterestModal;
\ No newline at end of file
diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js
new file mode 100644
index 0000000..8754965
--- /dev/null
+++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js
@@ -0,0 +1,132 @@
+import React from 'react';
+import { translate } from '../../../translate/translate';
+
+const MIN_INTEREST_THRESHOLD = 0.001;
+
+export const _ClaimInterestTableRender = function() {
+  const _transactionsList = this.state.transactionsList;
+  let _items = [];
+
+  for (let i = 0; i < _transactionsList.length; i++) {
+    if ((_transactionsList[i].interest === 0 && this.state.showZeroInterest) || (_transactionsList[i].amount > 0 && _transactionsList[i].interest > 0)) {
+      _items.push(
+        <tr key={ `${_transactionsList[i].txid}${_transactionsList[i].address}` }>
+          <td>
+            <button
+              className="btn btn-default btn-xs clipboard-edexaddr copy-string-btn"
+              title={ translate('INDEX.COPY_TO_CLIPBOARD') }
+              onClick={ () => this.copyTxId(_transactionsList[i].txid) }>
+                <i className="icon wb-copy"></i> { translate('INDEX.COPY') }
+            </button>
+          </td>
+          <td>{ _transactionsList[i].address }</td>
+          <td className={ _transactionsList[i].amount > 10 ? 'green bold' : '' }>{ _transactionsList[i].amount }</td>
+          <td>{ _transactionsList[i].interest }</td>
+          <td className="locktime center">
+            { _transactionsList[i].locktime &&
+              <i className="fa-check-circle green"></i>
+            }
+            { !_transactionsList[i].locktime &&
+              <i className="fa-exclamation-circle red"></i>
+            }
+          </td>
+        </tr>
+      );
+    }
+  }
+
+  return (
+    <span>
+      <div className="padding-bottom-20">
+        <strong>Requirements to accrue interest:</strong> locktime field is set and amount is greater than <strong>10 KMD</strong>
+      </div>
+      <div className="text-left padding-top-10 padding-bottom-10">
+        <label className="switch">
+          <input
+            type="checkbox"
+            checked={ this.state.showZeroInterest } />
+          <div
+            className="slider"
+            onClick={ this.toggleZeroInterest }></div>
+        </label>
+        <div
+          className="toggle-label margin-right-15 pointer"
+          onClick={ this.toggleZeroInterest }>
+          Show zero interest
+        </div>
+      </div>
+      <button
+        type="button"
+        className="btn btn-success waves-effect waves-light claim-btn"
+        onClick={ () => this.claimInterest() }>
+        <i className="icon fa-dollar"></i> Claim interest
+      </button>
+      <div className="table-scroll">
+        <table className="table table-hover dataTable table-striped">
+          <thead>
+            <tr>
+              <th></th>
+              <th>Address</th>
+              <th>Amount</th>
+              <th>Interest</th>
+              <th>Locktime</th>
+            </tr>
+          </thead>
+          <tbody>
+          { _items }
+          </tbody>
+          <tfoot>
+            <tr>
+              <th></th>
+              <th>Address</th>
+              <th>Amount</th>
+              <th>Interest</th>
+              <th>Locktime</th>
+            </tr>
+          </tfoot>
+        </table>
+      </div>
+    </span>
+  );
+};
+
+export const ClaimInterestModalRender = function() {
+  return (
+    <span>
+      <div className={ 'modal modal-claim-interest modal-3d-sign ' + (this.state.open ? 'show in' : 'fade hide') }>
+        <div className="modal-dialog modal-center modal-sm">
+          <div className="modal-content">
+            <div className="modal-header bg-orange-a400 wallet-send-header">
+              <button
+                type="button"
+                className="close white"
+                onClick={ this.closeModal }>
+                <span>×</span>
+              </button>
+              <h4 className="modal-title white text-left">Claim interest</h4>
+            </div>
+            <div className="modal-body">
+              <i
+                className="icon fa-refresh pointer refresh-icon"
+                onClick={ this.loadListUnspent }></i>
+              <div className="animsition vertical-align fade-in">
+                <div className="page-content vertical-align-middle full-width">
+                  { this.state.isLoading &&
+                    <span>Loading interest data...</span>
+                  }
+                  { !this.state.isLoading && this.checkTransactionsListLength() &&
+                    <div>{ this.claimInterestTableRender() }</div>
+                  }
+                  { !this.state.isLoading && !this.checkTransactionsListLength() &&
+                    <div>No data</div>
+                  }
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div className={ 'modal-backdrop ' + (this.state.open ? 'show in' : 'fade hide') }></div>
+    </span>
+  );
+};
\ No newline at end of file
diff --git a/react/src/components/dashboard/coinTile/coinTileItem.js b/react/src/components/dashboard/coinTile/coinTileItem.js
index e270774..b43c1d1 100644
--- a/react/src/components/dashboard/coinTile/coinTileItem.js
+++ b/react/src/components/dashboard/coinTile/coinTileItem.js
@@ -111,6 +111,11 @@ class CoinTileItem extends React.Component {
       setTimeout(() => {
         this.dispatchCoinActions(coin, mode);
       }, 100);
+      if (mode === 'native') { // faster coin data load if fully synced
+        setTimeout(() => {
+          this.dispatchCoinActions(coin, mode);
+        }, 1000);
+      }
 
       Store.dispatch(
         stopInterval(
@@ -141,7 +146,7 @@ class CoinTileItem extends React.Component {
       if (mode === 'native') {
         const _iguanaActiveHandle = setInterval(() => {
           this.dispatchCoinActions(coin, mode);
-        }, coin === 'KMD' ? IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE : IGUNA_ACTIVE_HANDLE_TIMEOUT);
+        }, IGUNA_ACTIVE_HANDLE_TIMEOUT_KMD_NATIVE);
 
         Store.dispatch(startInterval('sync', _iguanaActiveHandle));
       }
diff --git a/react/src/components/dashboard/coinTile/coinTileItem.render.js b/react/src/components/dashboard/coinTile/coinTileItem.render.js
index 832dd4a..b669c6c 100644
--- a/react/src/components/dashboard/coinTile/coinTileItem.render.js
+++ b/react/src/components/dashboard/coinTile/coinTileItem.render.js
@@ -12,7 +12,7 @@ const CoinTileItemRender = function() {
           <a className="avatar margin-bottom-5">
             <img
               className="img-responsive"
-              src={ `assets/images/cryptologo/${item.coinlogo}.png` }
+              src={ `assets/images/cryptologo/${item.coinlogo.toLowerCase()}.png` }
               alt={ item.coinname }/>
             <span className={ `badge up badge-${item.modecolor}` }>
               { item.modecode }
diff --git a/react/src/components/dashboard/coindDownModal/coindDownModal.render.js b/react/src/components/dashboard/coindDownModal/coindDownModal.render.js
index 548e661..3787039 100644
--- a/react/src/components/dashboard/coindDownModal/coindDownModal.render.js
+++ b/react/src/components/dashboard/coindDownModal/coindDownModal.render.js
@@ -16,7 +16,7 @@ const CoindDownModalRender = function () {
                 onClick={ this.dismiss }>
                 <span>×</span>
               </button>
-              <h4 className="modal-title white">Komodod is down!</h4>
+              <h4 className="modal-title white">{ this.props.ActiveCoin.coin === 'KMD' ? 'Komodod' : `Komodod / ${this.props.ActiveCoin.coin}` } is down!</h4>
             </div>
             <div className="modal-body">
               <div className="vertical-align text-center">
diff --git a/react/src/components/dashboard/jumblr/jumblr.js b/react/src/components/dashboard/jumblr/jumblr.js
index 4ae03a0..a69dbd1 100755
--- a/react/src/components/dashboard/jumblr/jumblr.js
+++ b/react/src/components/dashboard/jumblr/jumblr.js
@@ -1,14 +1,391 @@
 import React from 'react';
 import { translate } from '../../../translate/translate';
+import {
+  dashboardChangeActiveCoin,
+  getKMDAddressesNative,
+  startInterval,
+  stopInterval,
+  triggerToaster,
+  setJumblrAddress,
+  importPrivkey,
+  copyCoinAddress,
+  copyString
+} from '../../../actions/actionCreators';
+import Store from '../../../store';
+import Config from '../../../config';
+import {
+  JumblrRender,
+  JumblrRenderSecretAddressList
+} from './jumblr.render';
+import { PassPhraseGenerator } from '../../../util/crypto/passphrasegenerator';
 
-import JumblrRender from './jumblr.render';
+// import gen komodo keys utils
+import '../../../util/crypto/gen/array.map.js';
+import '../../../util/crypto/gen/cryptojs.js';
+import '../../../util/crypto/gen/cryptojs.sha256.js';
+import '../../../util/crypto/gen/cryptojs.pbkdf2.js';
+import '../../../util/crypto/gen/cryptojs.hmac.js';
+import '../../../util/crypto/gen/cryptojs.aes.js';
+import '../../../util/crypto/gen/cryptojs.blockmodes.js';
+import '../../../util/crypto/gen/cryptojs.ripemd160.js';
+import '../../../util/crypto/gen/securerandom.js';
+import '../../../util/crypto/gen/ellipticcurve.js';
+import '../../../util/crypto/gen/biginteger.js';
+import '../../../util/crypto/gen/crypto-scrypt.js';
+import { Bitcoin } from '../../../util/crypto/gen/bitcoin.js';
+
+if (!window.jumblrPasshrase) { // gen jumblr passphrase
+  window.jumblrPasshrase = 'jumblr ' + PassPhraseGenerator.generatePassPhrase(256);
+}
 
 class Jumblr extends React.Component {
   constructor(props) {
     super(props);
     this.state = {
       activeTab: 0,
+      randomSeed: window.jumblrPasshrase,
+      jumblrDepositAddress: null,
+      jumblrDepositAddressPBased: true,
+      jumblrSecretAddressShow: true,
+      jumblrSecretAddress: [],
+      jumblrSecretAddressImport: [],
+      jumblrSecretAddressCountImport: 0,
+      jumblrSecretAddressShowImport: true,
+      jumblrSecretAddressCount: 0,
+      jumblrMode: 'public',
+      secretAddressCount: 1,
+      secretAddressCountImport: 1,
+      jumblrPassphraseImport: '',
+    };
+    this.generateJumblrDepositAddress = this.generateJumblrDepositAddress.bind(this);
+    this.generateJumblrSecretAddress = this.generateJumblrSecretAddress.bind(this);
+    this.checkJumblrSecretAddressListLength = this.checkJumblrSecretAddressListLength.bind(this);
+    this.returnPassphrase = this.returnPassphrase.bind(this);
+    this.generateKeys = this.generateKeys.bind(this);
+    this._copyCoinAddress = this._copyCoinAddress.bind(this);
+    this.copyPassphrase = this.copyPassphrase.bind(this);
+    this.checkPassphraseValid = this.checkPassphraseValid.bind(this);
+    this.importJumblrSecretAddress = this.importJumblrSecretAddress.bind(this);
+    this.onChange = this.onChange.bind(this);
+  }
+
+  generateKeys(passphrase) {
+    if (!passphrase) {
+      const key = new Bitcoin.ECKey(false).setCompressed(true);
+      const kmdAddress = key.getBitcoinAddress();
+      const wifAddress = key.getBitcoinWalletImportFormat();
+
+      return {
+        address: kmdAddress,
+        wif: wifAddress,
+      };
+    } else {
+      const bytes = Crypto.SHA256(passphrase, { asBytes: true });
+      const btcKey = new Bitcoin.ECKey(bytes).setCompressed(true);
+      const kmdAddress = btcKey.getBitcoinAddress();
+      const wifAddress = btcKey.getBitcoinWalletImportFormat();
+
+      return {
+        address: kmdAddress,
+        wif: wifAddress,
+      };
+    }
+  }
+
+  _JumblrRenderSecretAddressList(type) {
+    return JumblrRenderSecretAddressList.call(this, type);
+  }
+
+  onChange(e) {
+    const regex = /^[0-9\b]+$/;
+
+    if (e.target.value === '' ||
+        regex.test(e.target.value)) {
+      this.setState({
+        [e.target.name]: e.target.value,
+      });
+    }
+  }
+
+  passphraseOnChange(e) {
+    this.setState({
+      [e.target.name]: e.target.value,
+    });
+  }
+
+  returnPassphrase() {
+    this.setState({
+      randomSeed: window.jumblrPasshrase,
+    });
+  }
+
+  toggle(prop) {
+    const _prop = this.state[prop];
+
+    this.setState({
+      [prop]: !_prop,
+    });
+  }
+
+  /*toggleAddressGenMod() {
+    this.setState({
+      jumblrDepositAddressPBased: !this.state.jumblrDepositAddressPBased,
+    });
+  }*/
+
+  generateJumblrSecretAddress() {
+    let _jumblrSecretAddress = [];
+    let _apiSuccessCount = 0;
+
+    if (this.state.secretAddressCount === '') {
+      Store.dispatch(
+        triggerToaster(
+          'Enter a correct address count value',
+          'Jumblr',
+          'error'
+        )
+      );
+    } else {
+      for (let i = 0; i < this.state.secretAddressCount; i++) {
+        let _genKeys;
+
+        if (this.state.jumblrDepositAddressPBased) {
+          let _postfix;
+
+          if (i < 9) {
+            _postfix = `00${i + 1}`;
+          } else if (i > 10 && i < 100) {
+            _postfix = `0${i + 1}`;
+          }
+          _genKeys = this.generateKeys(`${this.state.randomSeed} ${_postfix}`);
+          // console.warn(`${this.state.randomSeed} ${_postfix}`);
+        } else {
+          _genKeys = this.generateKeys();
+        }
+
+        setJumblrAddress(this.props.ActiveCoin.coin, 'secret', _genKeys.address)
+        .then((json) => {
+          if (json.error &&
+              json.error.code) {
+            Store.dispatch(
+              triggerToaster(
+                json.error.message,
+                'Error',
+                'error'
+              )
+            );
+          } else if (json.result && json.result.result && json.result.result === 'success') {
+            _jumblrSecretAddress.push(_genKeys);
+            this.setState(Object.assign({}, this.state, {
+              jumblrSecretAddress: _jumblrSecretAddress,
+            }));
+
+            if (_apiSuccessCount === this.state.secretAddressCount - 1) {
+              Store.dispatch(
+                triggerToaster(
+                  this.state.secretAddressCount > 1 ? 'Jumblr secret addresses are set' : 'Jumblr secret address is set',
+                  'Jumblr',
+                  'success'
+                )
+              );
+            }
+            _apiSuccessCount++;
+          }
+        });
+      }
+    }
+  }
+
+  checkPassphraseValid() { // test passphrase validity
+    const _passphrase = this.state.jumblrPassphraseImport;
+    const _jumblrPrefix = _passphrase.substring(0, 6);
+    const _passphraseWords = _passphrase.substring(6, _passphrase.length);
+    let _errors = {
+      prefix: false, // jumblr
+      length: false, // 24
     };
+
+    if (_jumblrPrefix !== 'jumblr') {
+      _errors.prefix = true;
+    }
+
+    try {
+      const _passphraseWordsSplit = _passphraseWords.split(' ');
+      let _correctWords = 0;
+
+      if (_passphraseWordsSplit &&
+          _passphraseWordsSplit.length) {
+        for (let i = 0; i < _passphraseWordsSplit.length; i++) {
+          if (_passphraseWordsSplit[i].length > 2) {
+            _correctWords++;
+          }
+        }
+
+        if (_correctWords !== _passphraseWordsSplit.length - 1 || _correctWords !== 24) {
+          _errors.length = true;
+        }
+      } else {
+        _errors.length = true;
+      }
+    } catch(e) {
+      _errors.length = true;
+    }
+
+
+    if (_errors.length ||
+        _errors.prefix) {
+      Store.dispatch(
+        triggerToaster(
+          'Provided passphrase has wrong format',
+          'Jumblr',
+          'error',
+          false
+        )
+      );
+
+      return false;
+    }
+
+    return true;
+  }
+
+  importJumblrSecretAddress() {
+    let _jumblrSecretAddress = [];
+    let _apiSuccessCount = 0;
+
+    if (this.state.secretAddressCountImport === '') {
+      Store.dispatch(
+        triggerToaster(
+          'Enter a correct address count value',
+          'Jumblr',
+          'error'
+        )
+      );
+    } else {
+      if (this.checkPassphraseValid()) {
+        for (let i = 0; i < this.state.secretAddressCountImport; i++) {
+          let _genKeys;
+
+          if (this.state.jumblrDepositAddressPBased) {
+            let _postfix;
+
+            if (i < 9) {
+              _postfix = `00${i + 1}`;
+            } else if (i > 10 && i < 100) {
+              _postfix = `0${i + 1}`;
+            }
+            _genKeys = this.generateKeys(`${this.state.jumblrPassphraseImport} ${_postfix}`);
+          } else {
+            _genKeys = this.generateKeys();
+          }
+
+          importPrivkey(this.props.ActiveCoin.coin, _genKeys.wif)
+          .then((json) => {
+            if (!json.id && !json.result && !json.error) {
+              _jumblrSecretAddress.push(_genKeys);
+              this.setState(Object.assign({}, this.state, {
+                jumblrSecretAddressImport: _jumblrSecretAddress,
+              }));
+              if (_apiSuccessCount === this.state.secretAddressCountImport - 1) {
+                Store.dispatch(
+                  triggerToaster(
+                    this.state.secretAddressCountImport > 1 ? 'Jumblr secret addresses imported' : 'Jumblr secret address imported',
+                    'Jumblr',
+                    'success'
+                  )
+                );
+              }
+              _apiSuccessCount++;
+            } else {
+              Store.dispatch(
+                triggerToaster(
+                  json.error.message,
+                  'Error',
+                  'error'
+                )
+              );
+            }
+          });
+        }
+      }
+    }
+  }
+
+  checkJumblrSecretAddressListLength(type) {
+    if (type === 'gen') {
+      if (this.state.jumblrSecretAddress &&
+          this.state.jumblrSecretAddress.length) {
+        return true;
+      } else {
+        return false;
+      }
+    } else {
+      if (this.state.jumblrSecretAddressImport &&
+          this.state.jumblrSecretAddressImport.length) {
+        return true;
+      } else {
+        return false;
+      }
+    }
+  }
+
+  generateJumblrDepositAddress() {
+    let _genKeys;
+
+    if (this.state.jumblrDepositAddressPBased) {
+      _genKeys = this.generateKeys(this.state.randomSeed);
+    } else {
+      _genKeys = this.generateKeys();
+    }
+
+    importPrivkey(this.props.ActiveCoin.coin, _genKeys.wif)
+    .then((json) => {
+      if (!json.id && !json.result && !json.error) {
+        // console.warn('importPrivkey', json);
+        setJumblrAddress(this.props.ActiveCoin.coin, 'deposit', _genKeys.address)
+        .then((json) => {
+          if (json.error &&
+              json.error.code) {
+            Store.dispatch(
+              triggerToaster(
+                json.error.message,
+                'Error',
+                'error'
+              )
+            );
+          } else if (json.result && json.result.result === 0) {
+            this.setState(Object.assign({}, this.state, {
+              jumblrDepositAddress: {
+                address: _genKeys.address,
+                wif: _genKeys.wif,
+              },
+            }));
+            Store.dispatch(
+              triggerToaster(
+                'Jumblr deposit address is set',
+                'Jumblr',
+                'success'
+              )
+            );
+          }
+        });
+      } else {
+        Store.dispatch(
+          triggerToaster(
+            json.error.message,
+            'Error',
+            'error'
+          )
+        );
+      }
+    });
+  }
+
+  switchJumblrMode(mode) {
+    this.setState(Object.assign({}, this.state, {
+      jumblrMode: mode,
+      activeTab: 0,
+    }));
   }
 
   openTab(tab) {
@@ -17,6 +394,14 @@ class Jumblr extends React.Component {
     }));
   }
 
+  _copyCoinAddress(address) {
+    Store.dispatch(copyCoinAddress(address));
+  }
+
+  copyPassphrase() {
+    Store.dispatch(copyString(this.state.randomSeed, 'Passphrase copied'));
+  }
+
   renderLB(_translationID) {
     const _translationComponents = translate(_translationID).split('<br>');
 
diff --git a/react/src/components/dashboard/jumblr/jumblr.render.js b/react/src/components/dashboard/jumblr/jumblr.render.js
index 846400d..fe060f7 100644
--- a/react/src/components/dashboard/jumblr/jumblr.render.js
+++ b/react/src/components/dashboard/jumblr/jumblr.render.js
@@ -2,10 +2,52 @@ import React from 'react';
 import { translate } from '../../../translate/translate';
 
 import WalletsHeader from '../walletsHeader/walletsHeader';
+import WalletsNativeSend from '../walletsNativeSend/walletsNativeSend';
+import ReceiveCoin from '../receiveCoin/receiveCoin';
 
-const JumblrRender = function() {
+export const JumblrRenderSecretAddressList = function(type) {
+  const _jumblrAddressList = type === 'gen' ? this.state.jumblrSecretAddress : this.state.jumblrSecretAddressImport;
+  let _items = [];
+
+  if (_jumblrAddressList &&
+      _jumblrAddressList.length) {
+    for (let i = 0; i < _jumblrAddressList.length; i++) {
+      _items.push(
+        <tr key={ `jumblr-secret-address-${i}` }>
+          <td>{ _jumblrAddressList[i].address }</td>
+          <td>{ _jumblrAddressList[i].wif }</td>
+        </tr>
+      );
+    }
+    return _items;
+  } else {
+    return null;
+  }
+};
+
+/* passphrase toggle
+  <div className={ 'toggle-box padding-top-20 padding-bottom-' + (this.state.jumblrDepositAddressPBased ? '10' : '30') }>
+    <span className="pointer">
+      <label className="switch">
+        <input
+          type="checkbox"
+          checked={ this.state.jumblrDepositAddressPBased } />
+        <div
+          className="slider"
+          onClick={ () => this.toggleAddressGenMod() }></div>
+      </label>
+      <div
+        className="toggle-label"
+        onClick={ () => this.toggleAddressGenMod() }>
+          Passphrase based address
+      </div>
+    </span>
+  </div>
+*/
+
+export const JumblrRender = function() {
   return (
-    <div className="page margin-left-0">
+    <div className="page margin-left-0 jumblr">
       <WalletsHeader activeSection="jumblr" />
       <div className="page-content margin-top-30">
         <div className="row">
@@ -32,87 +74,135 @@ const JumblrRender = function() {
                 <span>×</span>
               </button>
               <span className="jumblr-header">
-                <i className="icon fa-paw"></i> { translate('JUMBLR.NEED_NATIVE') }
+                <i className="icon fa-paw"></i> About Jumblr
               </span>
               <br />
-              { translate('JUMBLR.TO_USE_JUMBLR') }
-              <br />
-              { translate('JUMBLR.IF_YOU_ALREADY_RUNNING') }
+              <p>
+                Jumblr functions all locally which means no middle man is required to jumble your funds. You take control over the whole process.
+              </p>
+              <p>
+                <strong>Tip:</strong> to achive maximum anonimity setup Jumblr node on a dedicated piece of hardware (laptop or VPS), use a separate IP address for main Jumblr node.
+              </p>
             </div>
           </div>
 
-          <div className="col-xlg-12 col-md-12">
-            <p>{ translate('JUMBLR.THIS_SCREEN_DOESNT_REFRESH') }</p>
+          <div className="col-xlg-12 col-md-12 padding-top-20 padding-bottom-30">
+            <div
+              className="form-group col-lg-2 col-md-2 col-sm-2 col-xs-2"
+              style={{ padding: 0 }}>
+              <input
+                type="radio"
+                className="to-labelauty labelauty"
+                name={ `mode-public` }
+                id={ `mode-public` }
+                checked={ this.state.jumblrMode === 'public' ? true : false } />
+              <label
+                htmlFor={ `mode-public` }
+                style={{ margin: 0 }}
+                onClick={ () => this.switchJumblrMode('public') }>
+                <span
+                  className="labelauty-unchecked-image"
+                  style={{ display: this.state.jumblrMode === 'public' ? 'none' : 'inline-block' }}></span>
+                <span
+                  className="labelauty-unchecked"
+                  style={{ display: this.state.jumblrMode === 'public' ? 'none' : 'inline-block' }}>
+                    Public node
+                </span>
+                <span
+                  className="labelauty-checked-image"
+                  style={{ display: this.state.jumblrMode === 'public' ? 'inline-block' : 'none' }}></span>
+                <span
+                  className="labelauty-checked"
+                  style={{ display: this.state.jumblrMode === 'public' ? 'inline-block' : 'none' }}>
+                    Public node
+                </span>
+              </label>
+            </div>
+
+            <div
+              className="form-group col-lg-2 col-md-2 col-sm-2 col-xs-2"
+              style={{ padding: 0 }}>
+              <input
+                type="radio"
+                className="to-labelauty labelauty"
+                name={ `mode-private` }
+                id={ `mode-private` }
+                checked={ this.state.jumblrMode === 'private' ? true : false } />
+              <label
+                htmlFor={ `mode-private` }
+                style={{ margin: 0 }}
+                onClick={ () => this.switchJumblrMode('private') }>
+                <span
+                  className="labelauty-unchecked-image"
+                  style={{ display: this.state.jumblrMode === 'private' ? 'none' : 'inline-block' }}></span>
+                <span
+                  className="labelauty-unchecked"
+                  style={{ display: this.state.jumblrMode === 'private' ? 'none' : 'inline-block' }}>
+                    Private node
+                </span>
+                <span
+                  className="labelauty-checked-image"
+                  style={{ display: this.state.jumblrMode === 'private' ? 'inline-block' : 'none' }}></span>
+                <span
+                  className="labelauty-checked"
+                  style={{ display: this.state.jumblrMode === 'private' ? 'inline-block' : 'none' }}>
+                    Private node
+                </span>
+              </label>
+            </div>
           </div>
 
-          <div className="col-xs-12">
-            <div className="panel-group">
-              <div className="panel">
-                <div
-                  className="panel-heading"
-                  onClick={ () => this.openTab(0) }>
-                  <a className={ this.state.activeTab === 0 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.FEW_SECURITY_NOTES') }</a>
-                </div>
-                <div className={ this.state.activeTab === 0 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
-                  <div className="panel-body">
-                    <ul>
-                      <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }</li>
-                      <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }</li>
-                      <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }</li>
-                      <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }</li>
-                      <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }</li>
-                    </ul>
-                  </div>
-                </div>
-              </div>
-              <div className="panel">
-                <div
-                  className="panel-heading"
-                  onClick={ () => this.openTab(1) }>
-                  <a className={ this.state.activeTab === 1 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.ACCESS_JUMBLR_FUNDS') }</a>
-                </div>
-                <div className={ this.state.activeTab === 1 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
-                  <div className="panel-body">
-                    <p>{ translate('JUMBLR.ADDRESS_ACCESSIBLE_EASILY') }</p>
-                    <ul>
-                      <code>duck dog cat donkey</code>
-                    </ul>
-                    <ol>
-                      <li>{ translate('JUMBLR.TO_ACCESS') }</li>
-                      <li>{ translate('JUMBLR.CLOSE_IAPP') }</li>
-                      <li>{ translate('JUMBLR.START_IAPP') }</li>
-                      <li>{ translate('JUMBLR.START_KMD') }</li>
-                      <li>{ translate('JUMBLR.ACCESS_JUMBLR_FUNDS') }
-                        <ul>
-                          <li>{ translate('JUMBLR.SMALL_LETTERS') }</li>
-                          <li>{ translate('JUMBLR.WHITE_SPACE') }</li>
-                        </ul>
-                      </li>
-                      <li>
-                        { translate('JUMBLR.PER_EXAMPLE') }
-                        <br />
-                        <code>jumblr duck dog cat donkey</code>
-                      </li>
-                      <li>{ translate('JUMBLR.LOGIN_WITH_JUMBLR') }</li>
-                    </ol>
-                    <h4>{ translate('JUMBLR.AGAIN_DONT_SHARE') }</h4>
-                  </div>
-                </div>
-              </div>
-              <div className="panel">
-                <div
-                  className="panel-heading"
-                  onClick={ () => this.openTab(2) }>
-                  <a className={ this.state.activeTab === 2 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.USING_JUMBLR') }</a>
+          <div className="col-xlg-12 col-md-12">
+            { this.state.jumblrMode === 'public' &&
+              <div className="jumblr-mode-selector nav-tabs-horizontal nav-tabs-inverse">
+                <div className="img-responsive">
+                  <span className="coin">{ this.props.ActiveCoin.coin }</span>
+                  <img
+                    className="image"
+                    src={ `assets/images/cryptologo/${this.props.ActiveCoin.coin.toLowerCase()}.png` }
+                    alt={ this.props.ActiveCoin.coin }/>
                 </div>
-                <div className={ this.state.activeTab === 2 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
-                  <div className="panel-body">
+                <ul className="nav nav-tabs">
+                  <li
+                    className={ this.state.activeTab === 0 ? 'active' : '' }
+                    onClick={ () => this.openTab(0) }>
+                    <a>
+                      { translate('JUMBLR.USING_JUMBLR') }
+                    </a>
+                  </li>
+                  <li
+                    className={ this.state.activeTab === 1 ? 'active' : '' }
+                    onClick={ () => this.openTab(1) }>
+                    <a>
+                      Deposit address
+                    </a>
+                  </li>
+                  <li
+                    className={ this.state.activeTab === 2 ? 'active' : '' }
+                    onClick={ () => this.openTab(2) }>
+                    <a>
+                      Secret address
+                    </a>
+                  </li>
+                  <li
+                    className={ this.state.activeTab === 3 ? 'active' : '' }
+                    onClick={ () => this.openTab(3) }>
+                    <a>
+                      Deposit funds
+                    </a>
+                  </li>
+                </ul>
+                <div className="tab-content padding-20">
+                  <div className={ 'tab-pane' + (this.state.activeTab === 0 ? ' active' : '') }>
+                    <button
+                      type="button"
+                      className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
+                      onClick={ () => this.openTab(1) }>Next</button>
+                    <h5>How to use Jumblr</h5>
                     <ul>
-                      <li>{ translate('JUMBLR.RUN_KMD') }</li>
-                      <li>{ translate('JUMBLR.LOGIN_KMD') }</li>
-                      <li>{ translate('JUMBLR.GO_TO') }</li>
-                      <li>{ translate('JUMBLR.FIND_DEPOSIT_ADDR') }</li>
-                      <li>{ translate('JUMBLR.YOU_SEND_FUNDS') }</li>
+                      <li>Create deposit address</li>
+                      <li>Create secret address</li>
+                      <li>Send funds to deposit address</li>
                       <li>{ translate('JUMBLR.KEEP_WALLET_OPEN') }</li>
                       <li>{ translate('JUMBLR.IMPORTANT_FUNDS') }</li>
                       <li>{ translate('JUMBLR.LARGE_LOT') }</li>
@@ -122,105 +212,276 @@ const JumblrRender = function() {
                     <p>{ translate('JUMBLR.TO_CLEAR_THEM') }</p>
                     <p>{ translate('JUMBLR.WHEN_IT_TOTALS') }</p>
                   </div>
-                </div>
-              </div>
-            </div>
-          </div>
-
-          <div className="col-xlg-12 col-md-12">
-            <h4 className="font-size-14 text-uppercase">{ translate('JUMBLR.JADDR') }</h4>
-            <div className="panel">
-              <div className="table-responsive">
-                <table className="table table-striped">
-                  <tbody>
-                    <tr>
-                      <td width="20%">{ translate('JUMBLR.BTC_DEPOSIT') }</td>
-                      <td>
-                        <span></span>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td>BTC Jumblr</td>
-                      <td>
+                  <div className={ 'tab-pane' + (this.state.activeTab === 1 ? ' active' : '') }>
+                    <button
+                      type="button"
+                      className="btn btn-success waves-effect waves-light btn-next"
+                      onClick={ () => this.openTab(2) }>Next</button>
+                    <h5>{ translate('JUMBLR.FEW_SECURITY_NOTES') }</h5>
+                    <div className="col-xs-12 nofloat">
+                      <ul className="padding-bottom-20">
+                        <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }</li>
+                        <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }</li>
+                        <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }</li>
+                        <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }</li>
+                        <li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }</li>
+                      </ul>
+                    </div>
+                    { this.state.jumblrDepositAddressPBased &&
+                      <div className="padding-bottom-30">
+                        <div className="padding-bottom-20">
+                          <p>
+                            <strong>Please write down your Jumblr passphrase and keept it safe.</strong>
+                          </p>
+                          <p>This is your main recovery passphrase.</p>
+                          <p>All Jumblr addresses can be regenrated based on it.</p>
+                          <p>
+                            <strong>Tip:</strong> do not use smart editors to store your passphrase as they tend to add extra characters.<br />This may result in passphrase mismatch with the original passphrase.
+                          </p>
+                        </div>
+                        <label>Passphrase</label>
+                        <input
+                          type="text"
+                          className="form-control"
+                          name="loginPassphrase"
+                          onChange={ this.returnPassphrase }
+                          value={ this.state.randomSeed } />
                         <button
-                          type="button"
-                          className="btn btn-animate btn-animate-side btn-default btn-sm waves-effect waves-light">
-                          <span>
-                            <i className="icon fa-eye"></i> { translate('JUMBLR.SHOW_HIDE') }
-                          </span>
+                          className="btn btn-default btn-xs clipboard-edexaddr copy-string-btn"
+                          title={ translate('INDEX.COPY_TO_CLIPBOARD') }
+                          onClick={ () => this.copyPassphrase() }>
+                            <i className="icon wb-copy"></i> { translate('INDEX.COPY') }
                         </button>
-                        <span className="label label-lg label-outline label-success hide"></span>
-                        <span className="label label-lg label-outline label-default">{ translate('JUMBLR.HIDDEN') }</span>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.KMD_DEPOSIT') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>KMD Jumblr</td>
-                      <td>
+                      </div>
+                    }
+                    <button
+                      type="button"
+                      className="btn btn-info waves-effect waves-light"
+                      onClick={ this.generateJumblrDepositAddress }>Create Jumblr deposit address</button>
+                    { this.state.jumblrDepositAddress && this.state.jumblrDepositAddress.address &&
+                      <div className="padding-top-40">
+                        <strong>Your Jumblr deposit address:</strong>
+                        <p>
+                          { this.state.jumblrDepositAddress.address }
+                          <button
+                            className="btn btn-default btn-xs clipboard-edexaddr margin-left-10"
+                            title={ translate('INDEX.COPY_TO_CLIPBOARD') }
+                            onClick={ () => this._copyCoinAddress(this.state.jumblrDepositAddress.address) }>
+                              <i className="icon wb-copy"></i> { translate('INDEX.COPY') }
+                          </button>
+                        </p>
+                        <p>
+                          { this.state.jumblrDepositAddress.wif }
+                          <button
+                            className="btn btn-default btn-xs clipboard-edexaddr margin-left-10"
+                            title={ translate('INDEX.COPY_TO_CLIPBOARD') }
+                            onClick={ () => this._copyCoinAddress(this.state.jumblrDepositAddress.wif) }>
+                              <i className="icon wb-copy"></i> { translate('INDEX.COPY') }
+                          </button>
+                        </p>
+                      </div>
+                    }
+                  </div>
+                  <div className={ 'tab-pane' + (this.state.activeTab === 2 ? ' active' : '') }>
+                    <button
+                      type="button"
+                      className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
+                      onClick={ () => this.openTab(3) }>Next</button>
+                    <p>Jumblr secret addresses are used for the final z -> t transactions.</p>
+                    <p>In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported.</p>
+                    <p>Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected.</p>
+                    <p>To add a new set of secret addresses enter address count below. The passphrase below is exactly the same you saw on the previous step.</p>
+                    <p>Your Jumblr secret address recovery passphrase will have the following pattern <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer XXX</code>. Where XXX any number from 001 to 777.</p>
+
+                    { this.state.jumblrDepositAddressPBased &&
+                      <div className="padding-bottom-20 padding-top-20">
+                        <label>Passphrase</label>
+                        <input
+                          type="text"
+                          className="form-control"
+                          name="jumblrPassphrase"
+                          onChange={ this.returnPassphrase }
+                          value={ this.state.randomSeed } />
                         <button
-                          type="button"
-                          className="btn btn-animate btn-animate-side btn-default btn-sm waves-effect waves-light">
-                          <span>
-                            <i className="icon fa-eye"></i> { translate('JUMBLR.SHOW_HIDE') }
-                          </span>
+                          className="btn btn-default btn-xs clipboard-edexaddr copy-string-btn"
+                          title={ translate('INDEX.COPY_TO_CLIPBOARD') }
+                          onClick={ () => this.copyPassphrase() }>
+                            <i className="icon wb-copy"></i> { translate('INDEX.COPY') }
                         </button>
-                        <span className="label label-lg label-outline label-success hide"></span>
-                        <span className="label label-lg label-outline label-default">
-                          { translate('JUMBLR.HIDDEN') }
-                        </span>
-                      </td>
-                    </tr>
-                  </tbody>
-                </table>
+                      </div>
+                    }
+                    <div className="col-xs-2 nofloat padding-top-30">Number of secret addresses</div>
+                    <div className="col-xs-2 nofloat padding-left-10">
+                      <input
+                        type="text"
+                        pattern="[0-9]*"
+                        className="form-control"
+                        name="secretAddressCount"
+                        min="1"
+                        max="777"
+                        onChange={ this.onChange }
+                        value={ this.state.secretAddressCount } />
+                    </div>
+                    <div className="col-xs-2 nofloat">
+                      <button
+                        type="button"
+                        className="btn btn-info waves-effect waves-light"
+                        onClick={ this.generateJumblrSecretAddress }>Create Jumblr secret address(es)</button>
+                    </div>
+                    <div className="toggle-box padding-top-20">
+                      <span className="pointer">
+                        <label className="switch">
+                          <input
+                            type="checkbox"
+                            checked={ this.state.jumblrSecretAddressShow } />
+                          <div
+                            className="slider"
+                            onClick={ () => this.toggle('jumblrSecretAddressShow') }></div>
+                        </label>
+                        <div
+                          className="toggle-label"
+                          onClick={ () => this.toggle('jumblrSecretAddressShow') }>
+                            Show address list
+                        </div>
+                      </span>
+                    </div>
+                    <div className="col-xlg-12 col-md-12 padding-top-20 nofloat">
+                      { this.state.jumblrSecretAddressShow && this.checkJumblrSecretAddressListLength('gen') &&
+                        <table className="table table-hover dataTable table-striped">
+                          <thead>
+                            <tr>
+                              <td>
+                                <strong>Address</strong>
+                              </td>
+                              <td>
+                                <strong>Wif</strong>
+                              </td>
+                            </tr>
+                          </thead>
+                          <tbody>
+                          { this._JumblrRenderSecretAddressList('gen') }
+                          </tbody>
+                        </table>
+                      }
+                    </div>
+                  </div>
+                  <div className={ 'tab-pane' + (this.state.activeTab === 3 ? ' active' : '') }>
+                    <p>Use the form below to send funds to your jumblr deposit address.</p>
+                    <p className="padding-bottom-20">You can also send funds to deposit address from an external service or another wallet.</p>
+                    <WalletsNativeSend
+                      {...this.props}
+                      renderFormOnly="true"
+                      activeSection="send" />
+                  </div>
+                </div>
               </div>
-            </div>
-          </div>
+            }
+            { this.state.jumblrMode === 'private' &&
+              <div className="jumblr-mode-selector nav-tabs-horizontal nav-tabs-inverse">
+                <ul className="nav nav-tabs">
+                  <li
+                    className={ this.state.activeTab === 0 ? 'active' : '' }
+                    onClick={ () => this.openTab(0) }>
+                    <a>
+                      Import secret address
+                    </a>
+                  </li>
+                  <li
+                    className={ this.state.activeTab === 1 ? 'active' : '' }
+                    onClick={ () => this.openTab(1) }>
+                    <a>
+                      Check funds
+                    </a>
+                  </li>
+                </ul>
+                <div className="tab-content padding-20">
+                  <div className={ 'tab-pane' + (this.state.activeTab === 0 ? ' active' : '') }>
+                    <button
+                      type="button"
+                      className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
+                      onClick={ () => this.openTab(1) }>Next</button>
+                    <div className="col-xlg-12 col-md-12 nofloat">
+                      <p>Enter your Jumblr passphrase you got previously during Public node configuration to import secret address.</p>
+                      <p>Passphrase example: <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer</code>.</p>
+                      <p>The form below will "regenerate" Jumblr secret address based on passphrase provided.</p>
+                      <p>After this final step expect to see funds processed and credited to your address after 2 days period.</p>
 
-          <div className="col-xlg-12 col-md-12">
-            <h4 className="font-size-14 text-uppercase">
-              { translate('JUMBLR.JSTATUS') }
-            </h4>
-            <div className="panel">
-              <div className="table-responsive">
-                <table className="table table-striped">
-                  <tbody>
-                    <tr>
-                      <td width="20%">{ translate('JUMBLR.RESULT') }</td>
-                      <td>
-                        <span className="label label-success"></span>
-                      </td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.DEPOSITED') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.PUB_TO_PRIV') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.PRIV_TO_PRIV') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.PRIV_TO_PUB') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.FINISHED') }</td>
-                      <td></td>
-                    </tr>
-                    <tr>
-                      <td>{ translate('JUMBLR.PENDING') }</td>
-                      <td></td>
-                    </tr>
-                  </tbody>
-                </table>
+                      { this.state.jumblrDepositAddressPBased &&
+                        <div className="padding-bottom-20 padding-top-20">
+                          <label>Passphrase</label>
+                          <input
+                            type="text"
+                            className="form-control"
+                            name="jumblrPassphraseImport"
+                            onChange={ (event) => this.passphraseOnChange(event) }
+                            value={ this.state.jumblrPassphraseImport } />
+                        </div>
+                      }
+                      <div className="col-xs-2 nofloat padding-top-30">Number of secret addresses</div>
+                      <div className="col-xs-2 nofloat padding-left-10">
+                        <input
+                          type="text"
+                          pattern="[0-9]*"
+                          className="form-control"
+                          name="secretAddressCountImport"
+                          min="1"
+                          max="777"
+                          onChange={ this.onChange }
+                          value={ this.state.secretAddressCountImport } />
+                      </div>
+                      <div className="col-xs-2 nofloat">
+                        <button
+                          type="button"
+                          className="btn btn-info waves-effect waves-light"
+                          onClick={ this.importJumblrSecretAddress }>Import Jumblr secret address(es)</button>
+                      </div>
+                      <div className="toggle-box padding-top-20">
+                        <span className="pointer">
+                          <label className="switch">
+                            <input
+                              type="checkbox"
+                              checked={ this.state.jumblrSecretAddressShowImport } />
+                            <div
+                              className="slider"
+                              onClick={ () => this.toggle('jumblrSecretAddressShowImport') }></div>
+                          </label>
+                          <div
+                            className="toggle-label"
+                            onClick={ () => this.toggle('jumblrSecretAddressShowImport') }>
+                              Show address list
+                          </div>
+                        </span>
+                      </div>
+                      <div className="col-xlg-12 col-md-12 padding-top-20 nofloat">
+                        { this.state.jumblrSecretAddressShowImport && this.checkJumblrSecretAddressListLength('import') &&
+                          <table className="table table-hover dataTable table-striped">
+                            <thead>
+                              <tr>
+                                <td>
+                                  <strong>Address</strong>
+                                </td>
+                                <td>
+                                  <strong>Wif</strong>
+                                </td>
+                              </tr>
+                            </thead>
+                            <tbody>
+                            { this._JumblrRenderSecretAddressList('import') }
+                            </tbody>
+                          </table>
+                        }
+                      </div>
+                    </div>
+                  </div>
+                  <div className={ 'tab-pane' + (this.state.activeTab === 1 ? ' active' : '') }>
+                    <ReceiveCoin
+                      {...this.props.ActiveCoin}
+                      activeSection="receive"
+                      renderTableOnly="true" />
+                  </div>
+                </div>
               </div>
-            </div>
+            }
           </div>
         </div>
       </div>
diff --git a/react/src/components/dashboard/navbar/navbar.js b/react/src/components/dashboard/navbar/navbar.js
index 6480b97..dfacb44 100755
--- a/react/src/components/dashboard/navbar/navbar.js
+++ b/react/src/components/dashboard/navbar/navbar.js
@@ -10,6 +10,7 @@ import {
 } from '../../../actions/actionCreators';
 import Store from '../../../store';
 import Config from '../../../config';
+import { checkAC } from '../../addcoin/payload';
 
 import NavbarRender from './navbar.render';
 
@@ -23,6 +24,7 @@ class Navbar extends React.Component {
     this.openDropMenu = this.openDropMenu.bind(this);
     this.logout = this.logout.bind(this);
     this.handleClickOutside = this.handleClickOutside.bind(this);
+    this._checkAC = this._checkAC.bind(this);
   }
 
   componentWillMount() {
@@ -67,6 +69,10 @@ class Navbar extends React.Component {
     Store.dispatch(dashboardChangeSection(sectionName));
   }
 
+  _checkAC() {
+    return checkAC(this.props.ActiveCoin.coin);
+  }
+
   logout() {
     Store.dispatch(
       stopInterval(
diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js
index a3d80ff..4449f5f 100644
--- a/react/src/components/dashboard/navbar/navbar.render.js
+++ b/react/src/components/dashboard/navbar/navbar.render.js
@@ -57,11 +57,13 @@ const NavbarRender = function() {
                 <i className="site-menu-icon"></i> BarterDEX
               </a>
             </li>
-            <li className={ 'hide ' + (this.isSectionActive('jumblr') ? 'active nav-top-menu' : 'nav-top-menu') }>
-              <a onClick={ () => this.dashboardChangeSection('jumblr') }>
-                <i className="site-menu-icon"></i> Jumblr
-              </a>
-            </li>
+            { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && (this._checkAC() || this.props.ActiveCoin.coin === 'KMD') &&
+              <li className={ this.isSectionActive('jumblr') ? 'active nav-top-menu' : 'nav-top-menu' }>
+                <a onClick={ () => this.dashboardChangeSection('jumblr') }>
+                  <i className="site-menu-icon"></i> Jumblr
+                </a>
+              </li>
+            }
             <li className={ this.state.nativeOnly ? 'hide' : (this.isSectionActive('atomic') ? 'active nav-top-menu' : 'nav-top-menu') }>
               <a onClick={ () => this.dashboardChangeSection('atomic') }>
                 <i className="site-menu-icon"></i> Atomic Explorer
diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js
index 1c13748..2038f55 100644
--- a/react/src/components/dashboard/receiveCoin/receiveCoin.js
+++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js
@@ -10,7 +10,8 @@ import {
   AddressActionsBasiliskModeRender,
   AddressActionsNonBasiliskModeRender,
   AddressItemRender,
-  ReceiveCoinRender
+  ReceiveCoinRender,
+  _ReceiveCoinTableRender
 } from './receiveCoin.render';
 
 // TODO: implement balance/interest sorting
@@ -28,6 +29,11 @@ class ReceiveCoin extends React.Component {
     this.handleClickOutside = this.handleClickOutside.bind(this);
     this.toggleVisibleAddress = this.toggleVisibleAddress.bind(this);
     this.checkTotalBalance = this.checkTotalBalance.bind(this);
+    this.ReceiveCoinTableRender = _ReceiveCoinTableRender.bind(this);
+  }
+
+  ReceiveCoinTableRender() {
+    return this._ReceiveCoinTableRender();
   }
 
   componentWillMount() {
@@ -108,7 +114,7 @@ class ReceiveCoin extends React.Component {
   }
 
   getNewAddress(type) {
-    Store.dispatch(getNewKMDAddresses(this.props.coin, type));
+    Store.dispatch(getNewKMDAddresses(this.props.coin, type, this.props.mode));
   }
 
   toggleVisibleAddress() {
@@ -181,7 +187,7 @@ class ReceiveCoin extends React.Component {
         }
 
         if (this.state.hideZeroAddresses) {
-          if (!this.hasNoAmount) {
+          if (!this.hasNoAmount(address)) {
             items.push(
               AddressItemRender.call(this, address, type)
             );
@@ -200,10 +206,10 @@ class ReceiveCoin extends React.Component {
   }
 
   render() {
-    // TODO nativeActiveSection === 'receive' should be removed when native mode is fully merged
+    // TODO activeSection === 'receive' should be removed when native mode is fully merged
     // into the rest of the components
     if (this.props &&
-       (this.props.receive || (this.isNativeMode() && this.props.nativeActiveSection === 'receive'))) {
+       (this.props.receive || (this.isNativeMode() && this.props.activeSection === 'receive'))) {
       return ReceiveCoinRender.call(this);
     }
 
diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js
index 788988c..038ea1c 100644
--- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js
+++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js
@@ -61,105 +61,119 @@ export const AddressItemRender = function(address, type) {
   );
 };
 
-export const ReceiveCoinRender = function() {
+export const _ReceiveCoinTableRender = function() {
   return (
-    <div>
-      <div className="col-xs-12 margin-top-20">
-        <div className="panel nav-tabs-horizontal">
-          <div>
-            <div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
-              <div className="panel">
-                <header className="panel-heading">
-                  {this.isNativeMode() &&
-                    <div className="panel-actions">
-                      <div
-                        className={ 'dropdown' + (this.state.openDropMenu ? ' open' : '') }
-                        onClick={ this.openDropMenu }>
-                        <a className="dropdown-toggle white btn btn-warning">
-                          <i className="icon md-arrows margin-right-10"></i> { translate('INDEX.GET_NEW_ADDRESS') }
-                          <span className="caret"></span>
-                        </a>
-                        <ul
-                          className="dropdown-menu dropdown-menu-right">
-                          <li>
-                            <a onClick={ () => this.getNewAddress('public') }>
-                              <i className="icon fa-eye"></i> { translate('INDEX.TRANSPARENT_ADDRESS') }
-                            </a>
-                          </li>
-                          <li>
-                            <a onClick={ () => this.getNewAddress('private') }>
-                              <i className="icon fa-eye-slash"></i> { translate('INDEX.PRIVATE_Z_ADDRESS') }
-                            </a>
-                          </li>
-                        </ul>
-                      </div>
-                    </div>
-                  }
-                  <h4 className="panel-title">{ translate('INDEX.RECEIVING_ADDRESS') }</h4>
-                </header>
-                <div className="panel-body">
-                  { this.checkTotalBalance() === 0 &&
-                    <div className="text-left padding-top-10 padding-bottom-10">
-                      <div
-                        className="toggle-label margin-right-15 pointer"
-                        onClick={ this.toggleVisibleAddress }>
-                        { translate('INDEX.TOGGLE_ZERO_ADDRESSES') }
-                      </div>
-                      <label className="switch">
-                        <input
-                          type="checkbox"
-                          checked={ this.state.hideZeroAddresses } />
+    <span>
+      { this.checkTotalBalance() !== 0 &&
+        <div className="text-left padding-top-10 padding-bottom-10">
+          <label className="switch">
+            <input
+              type="checkbox"
+              checked={ this.state.hideZeroAddresses } />
+            <div
+              className="slider"
+              onClick={ this.toggleVisibleAddress }></div>
+          </label>
+          <div
+            className="toggle-label margin-right-15 pointer"
+            onClick={ this.toggleVisibleAddress }>
+            { translate('INDEX.TOGGLE_ZERO_ADDRESSES') }
+          </div>
+        </div>
+      }
+      <table className="table table-hover dataTable table-striped">
+        <thead>
+        { this.isNativeMode() ?
+          <tr>
+            <th>{ translate('INDEX.TYPE') }</th>
+            <th>{ translate('INDEX.ADDRESS') }</th>
+            <th>{ translate('INDEX.AMOUNT') }</th>
+          </tr>
+          :
+          <tr>
+            <th>{ translate('INDEX.TYPE') }</th>
+            <th>{ translate('INDEX.ADDRESS') }</th>
+            <th>{ translate('INDEX.BALANCE') }</th>
+            <th> {translate('INDEX.INTEREST') }</th>
+          </tr>
+        }
+        </thead>
+        <tbody>
+          { this.renderAddressList('public') }
+          { this.isNativeMode() && this.renderAddressList('private') }
+        </tbody>
+        <tfoot>
+        { this.isNativeMode() ?
+          <tr>
+            <th>{ translate('INDEX.TYPE') }</th>
+            <th>{ translate('INDEX.ADDRESS') }</th>
+            <th>{ translate('INDEX.AMOUNT') }</th>
+          </tr>
+          :
+          <tr>
+            <th>{ translate('INDEX.TYPE') }</th>
+            <th>{ translate('INDEX.ADDRESS') }</th>
+            <th>{ translate('INDEX.BALANCE') }</th>
+            <th>{ translate('INDEX.INTEREST') }</th>
+          </tr>
+        }
+        </tfoot>
+      </table>
+    </span>
+  );
+};
+
+export const ReceiveCoinRender = function() {
+  if (this.props.renderTableOnly) {
+    return (
+      <div>{ this.ReceiveCoinTableRender() }</div>
+    );
+  } else {
+    return (
+      <div>
+        <div className="col-xs-12 margin-top-20">
+          <div className="panel nav-tabs-horizontal">
+            <div>
+              <div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
+                <div className="panel">
+                  <header className="panel-heading">
+                    { this.isNativeMode() &&
+                      <div className="panel-actions">
                         <div
-                          className="slider"
-                          onClick={ this.toggleVisibleAddress }></div>
-                      </label>
-                    </div>
-                  }
-                  <table className="table table-hover dataTable table-striped">
-                    <thead>
-                    { this.isNativeMode() ?
-                      <tr>
-                        <th>{ translate('INDEX.TYPE') }</th>
-                        <th>{ translate('INDEX.ADDRESS') }</th>
-                        <th>{ translate('INDEX.AMOUNT') }</th>
-                      </tr>
-                      :
-                      <tr>
-                        <th>{ translate('INDEX.TYPE') }</th>
-                        <th>{ translate('INDEX.ADDRESS') }</th>
-                        <th>{ translate('INDEX.BALANCE') }</th>
-                        <th> {translate('INDEX.INTEREST') }</th>
-                      </tr>
-                    }
-                    </thead>
-                    <tbody>
-                      { this.renderAddressList('public') }
-                      { this.isNativeMode() && this.renderAddressList('private') }
-                    </tbody>
-                    <tfoot>
-                    { this.isNativeMode() ?
-                      <tr>
-                        <th>{ translate('INDEX.TYPE') }</th>
-                        <th>{ translate('INDEX.ADDRESS') }</th>
-                        <th>{ translate('INDEX.AMOUNT') }</th>
-                      </tr>
-                      :
-                      <tr>
-                        <th>{ translate('INDEX.TYPE') }</th>
-                        <th>{ translate('INDEX.ADDRESS') }</th>
-                        <th>{ translate('INDEX.BALANCE') }</th>
-                        <th>{ translate('INDEX.INTEREST') }</th>
-                      </tr>
+                          className={ 'dropdown' + (this.state.openDropMenu ? ' open' : '') }
+                          onClick={ this.openDropMenu }>
+                          <a className="dropdown-toggle white btn btn-warning">
+                            <i className="icon md-arrows margin-right-10"></i> { translate('INDEX.GET_NEW_ADDRESS') }
+                            <span className="caret"></span>
+                          </a>
+                          <ul
+                            className="dropdown-menu dropdown-menu-right">
+                            <li>
+                              <a onClick={ () => this.getNewAddress('public') }>
+                                <i className="icon fa-eye"></i> { translate('INDEX.TRANSPARENT_ADDRESS') }
+                              </a>
+                            </li>
+                            <li>
+                              <a onClick={ () => this.getNewAddress('private') }>
+                                <i className="icon fa-eye-slash"></i> { translate('INDEX.PRIVATE_Z_ADDRESS') }
+                              </a>
+                            </li>
+                          </ul>
+                        </div>
+                      </div>
                     }
-                    </tfoot>
-                  </table>
+                    <h4 className="panel-title">{ translate('INDEX.RECEIVING_ADDRESS') }</h4>
+                  </header>
+                  <div className="panel-body">
+                  { this.ReceiveCoinTableRender() }
+                  </div>
                 </div>
               </div>
             </div>
           </div>
         </div>
       </div>
-    </div>
-  );
+    );
+  }
 };
 
diff --git a/react/src/components/dashboard/walletsBalance/walletsBalance.js b/react/src/components/dashboard/walletsBalance/walletsBalance.js
index 72a4e43..b492df0 100755
--- a/react/src/components/dashboard/walletsBalance/walletsBalance.js
+++ b/react/src/components/dashboard/walletsBalance/walletsBalance.js
@@ -167,7 +167,7 @@ class WalletsBalance extends React.Component {
   }
 
   isNativeBalanceActive() {
-    return this.isNativeMode() && this.props.ActiveCoin.nativeActiveSection === 'default';
+    return this.isNativeMode() && this.props.ActiveCoin.activeSection === 'default';
   }
 
   isNonNativeBalanceActive() {
diff --git a/react/src/components/dashboard/walletsData/pagination.js b/react/src/components/dashboard/walletsData/pagination.js
index a3ff832..dba569d 100644
--- a/react/src/components/dashboard/walletsData/pagination.js
+++ b/react/src/components/dashboard/walletsData/pagination.js
@@ -4,42 +4,43 @@ import PaginationRender from './pagination.render';
 export default class TablePaginationRenderer extends Component {
   constructor (props) {
     super();
-
-    this.getSafePage = this.getSafePage.bind(this);
-    this.changePage = this.changePage.bind(this);
-    this.applyPage = this.applyPage.bind(this);
-
     this.state = {
       page: props.page
     }
+    this.getSafePage = this.getSafePage.bind(this);
+    this.changePage = this.changePage.bind(this);
+    this.applyPage = this.applyPage.bind(this);
   }
 
-  componentWillReceiveProps (nextProps) {
+  componentWillReceiveProps(nextProps) {
     this.setState({ page: nextProps.page });
   }
 
-  getSafePage (page) {
+  getSafePage(page) {
     if (isNaN(page)) {
       page = this.props.page;
     }
+
     return Math.min(Math.max(page, 0), this.props.pages - 1);
   }
 
-  changePage (page) {
+  changePage(page) {
     page = this.getSafePage(page);
     this.setState({ page });
+
     if (this.props.page !== page) {
       this.props.onPageChange(page);
     }
   }
 
-  applyPage (e) {
-    e && e.preventDefault();
+  applyPage(e) {
     const page = this.state.page;
+
+    e && e.preventDefault();
     this.changePage(page === '' ? this.props.page : page);
   }
 
-  render () {
+  render() {
     return PaginationRender.call(this);
   }
 }
\ No newline at end of file
diff --git a/react/src/components/dashboard/walletsData/pagination.render.js b/react/src/components/dashboard/walletsData/pagination.render.js
index f90af8a..e7535de 100644
--- a/react/src/components/dashboard/walletsData/pagination.render.js
+++ b/react/src/components/dashboard/walletsData/pagination.render.js
@@ -27,71 +27,67 @@ const PaginationRender = function() {
   return (
     <div
       className={classnames(className, '-pagination')}
-      style={this.props.paginationStyle}
-    >
-      <div className='-previous'>
+      style={this.props.paginationStyle}>
+      <div className="-previous">
         <PreviousComponent
           onClick={e => {
             if (!canPrevious) return;
             this.changePage(page - 1)
           }}
-          disabled={!canPrevious}
-        >
+          disabled={!canPrevious}>
           {this.props.previousText}
         </PreviousComponent>
       </div>
-      <div className='-center'>
-          <span className='-pageInfo'>
-            {this.props.pageText}{' '}
-            {showPageJump
-              ?
-              <div className='-pageJump'>
-                <input
-                  type={this.state.page === '' ? 'text' : 'number'}
-                  onChange={e => {
-                    const val = e.target.value;
-                    this.changePage(val - 1);
-                  }}
-                  value={this.state.page === '' ? '' : this.state.page + 1}
-                  onBlur={this.applyPage}
-                  onKeyPress={e => {
-                    if (e.which === 13 || e.keyCode === 13) {
-                      this.applyPage();
-                    }
-                  }}
-                />
-              </div>
-              :
-              <span className='-currentPage'>
-                {page + 1}
-              </span>}{' '}
-            {this.props.ofText}{' '}
-            <span className='-totalPages'>{pages || 1}</span>
+      <div className="-center">
+        <span className="-pageInfo">
+          {this.props.pageText}{' '}
+          {showPageJump
+            ?
+            <div className="-pageJump">
+              <input
+                type={this.state.page === '' ? 'text' : 'number'}
+                onChange={e => {
+                  const val = e.target.value;
+                  this.changePage(val - 1);
+                }}
+                value={this.state.page === '' ? '' : this.state.page + 1}
+                onBlur={this.applyPage}
+                onKeyPress={e => {
+                  if (e.which === 13 || e.keyCode === 13) {
+                    this.applyPage();
+                  }
+                }} />
+            </div>
+            :
+            <span className="-currentPage">
+              {page + 1}
+            </span>}{' '}
+          {this.props.ofText}{' '}
+          <span className="-totalPages">{pages || 1}</span>
+        </span>
+        { showPageSizeOptions &&
+          <span className="select-wrap -pageSizeOptions">
+            <select
+              onChange={e => onPageSizeChange(Number(e.target.value))}
+              value={pageSize}>
+              { pageSizeOptions.map((option, i) => {
+                return (
+                  <option key={i} value={option}>
+                    {option} {this.props.rowsText}
+                  </option>
+                );
+              })}
+            </select>
           </span>
-        {showPageSizeOptions &&
-        <span className='select-wrap -pageSizeOptions'>
-              <select
-                onChange={e => onPageSizeChange(Number(e.target.value))}
-                value={pageSize}
-              >
-                {pageSizeOptions.map((option, i) => {
-                  return (
-                    <option key={i} value={option}>
-                      {option} {this.props.rowsText}
-                    </option>
-                  )
-                })}
-              </select>
-            </span>}
+        }
       </div>
-      <div className='-next'>
+      <div className="-next">
         <NextComponent
           onClick={e => {
             if (!canNext) return;
             this.changePage(page + 1)
           }}
-          disabled={!canNext}
-        >
+          disabled={!canNext}>
           {this.props.nextText}
         </NextComponent>
       </div>
diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js
index b5fcd8b..2480162 100644
--- a/react/src/components/dashboard/walletsData/walletsData.js
+++ b/react/src/components/dashboard/walletsData/walletsData.js
@@ -53,7 +53,7 @@ class WalletsData extends React.Component {
       totalStackLength: 0,
       useCache: true,
       itemsListColumns: this.generateItemsListColumns(),
-      pageSize: 20,
+      pageSize: 10,
       showPagination: false,
       searchTerm: null,
       coin: null,
@@ -117,6 +117,9 @@ class WalletsData extends React.Component {
       id: 'direction',
       Header: translate('INDEX.DIRECTION'),
       Footer: translate('INDEX.DIRECTION'),
+      className: 'colum--direction',
+      headerClassName: 'colum--direction',
+      footerClassName: 'colum--direction',
       accessor: (tx) => TxTypeRender.call(this, tx.category || tx.type)
     },
     {
@@ -158,15 +161,15 @@ class WalletsData extends React.Component {
       });
     }
 
-    const txDetailColumnCssClasses = this.isBasiliskMode() ? 'hidden-xs hidden-sm text-center' : 'hidden-xs hidden-sm';
+    // const txDetailColumnCssClasses = this.isBasiliskMode() ? 'hidden-xs hidden-sm' : 'hidden-xs hidden-sm';
 
     columns.push({
       id: 'tx-detail',
       Header: translate('INDEX.TX_DETAIL'),
       Footer: translate('INDEX.TX_DETAIL'),
-      headerClassName: txDetailColumnCssClasses,
-      footerClassName: txDetailColumnCssClasses,
-      className: txDetailColumnCssClasses,
+      className: 'colum--txinfo',
+      headerClassName: 'colum--txinfo',
+      footerClassName: 'colum--txinfo',
       Cell: props => TransactionDetailRender.call(this, props.index)
     });
 
@@ -389,15 +392,21 @@ class WalletsData extends React.Component {
 
   // TODO: add basilisk first run check, display no data if second run
   renderTxHistoryList() {
-    if (this.state.itemsList === 'loading') {
-      if (!this.isNativeMode() || this.isFullySynced()) {
+    if (this.state.itemsList === 'loading' || this.state.itemsList.length == 0) {
+      if (this.isFullySynced()) {
         return (
           <tr className="hover--none">
             <td colSpan="7">{ translate('INDEX.LOADING_HISTORY') }...</td>
           </tr>
         );
+      } else {
+        return (
+          <tr className="hover--none">
+            <td colSpan="7">Synchronization is in progress...</td>
+          </tr>
+        );
       }
-    } else if (this.state.itemsList === 'no data' || this.state.itemsList.length == 0) {
+    } else if (this.state.itemsList === 'no data') {
       return (
         <tr className="hover--none">
           <td colSpan="7">{ translate('INDEX.NO_DATA') }</td>
@@ -413,7 +422,7 @@ class WalletsData extends React.Component {
   onPageSizeChange(pageSize, pageIndex) {
     this.setState(Object.assign({}, this.state, {
       pageSize: pageSize,
-      showPagination: this.state.itemsList && this.state.itemsList.length >= pageSize
+      showPagination: this.state.itemsList && this.state.itemsList.length >= pageSize,
     }))
   }
 
@@ -547,6 +556,7 @@ class WalletsData extends React.Component {
   }
 
   shouldDisplayAddressList() {
+    //return true;
     return this.props.Dashboard &&
         this.props.Dashboard.activeHandle &&
         this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin];
@@ -613,7 +623,7 @@ class WalletsData extends React.Component {
           !this.props.ActiveCoin.receive
         ) || (
           this.props.ActiveCoin.mode === 'native' &&
-          this.props.ActiveCoin.nativeActiveSection === 'default'
+          this.props.ActiveCoin.activeSection === 'default'
         )) {
       return WalletsDataRender.call(this);
     } else {
diff --git a/react/src/components/dashboard/walletsData/walletsData.render.js b/react/src/components/dashboard/walletsData/walletsData.render.js
index 121c21b..9c19aa6 100644
--- a/react/src/components/dashboard/walletsData/walletsData.render.js
+++ b/react/src/components/dashboard/walletsData/walletsData.render.js
@@ -13,11 +13,11 @@ import Config from '../../../config';
 
 export const AddressTypeRender = function() {
   return (
-    <td>
+    <span>
       <span className="label label-default">
         <i className="icon fa-eye"></i> { translate('IAPI.PUBLIC_SM') }
       </span>
-    </td>
+    </span>
   );
 };
 
@@ -49,8 +49,9 @@ export const AddressRender = function(tx) {
 
 export const AddressItemRender = function(address, type, amount, coin) {
   return (
-    <li key={address}
-        className={ address === this.state.currentAddress ? 'selected' : '' }>
+    <li
+      key={address}
+      className={ address === this.state.currentAddress ? 'selected' : '' }>
       <a onClick={ () => this.updateAddressSelection(address) }>
         <i className={ 'icon fa-eye' + (type === 'public' ? '' : '-slash') }></i>&nbsp;&nbsp;
         <span className="text">[ { amount } { coin } ]  { address }</span>
@@ -98,37 +99,37 @@ export const TxTypeRender = function(category) {
     category === 'sent') {
     return (
       <span className="label label-danger">
-          <i className="icon fa-arrow-circle-left"></i> <span>{ translate('DASHBOARD.OUT') }</span>
-        </span>
+        <i className="icon fa-arrow-circle-left"></i> <span>{ translate('DASHBOARD.OUT') }</span>
+      </span>
     );
   }
   if (category === 'receive' ||
     category === 'received') {
     return (
       <span className="label label-success">
-          <i className="icon fa-arrow-circle-right"></i> <span>{ translate('DASHBOARD.IN') }</span>
-        </span>
+        <i className="icon fa-arrow-circle-right"></i> <span>{ translate('DASHBOARD.IN') }</span>
+      </span>
     );
   }
   if (category === 'generate') {
     return (
       <span>
-          <i className="icon fa-cogs"></i> <span>{ translate('DASHBOARD.MINED') }</span>
-        </span>
+        <i className="icon fa-cogs"></i> <span>{ translate('DASHBOARD.MINED') }</span>
+      </span>
     );
   }
   if (category === 'immature') {
     return (
       <span>
-          <i className="icon fa-clock-o"></i> <span>{ translate('DASHBOARD.IMMATURE') }</span>
-        </span>
+        <i className="icon fa-clock-o"></i> <span>{ translate('DASHBOARD.IMMATURE') }</span>
+      </span>
     );
   }
   if (category === 'unknown') {
     return (
       <span>
-          <i className="icon fa-meh-o"></i> <span>{ translate('DASHBOARD.UNKNOWN') }</span>
-        </span>
+        <i className="icon fa-meh-o"></i> <span>{ translate('DASHBOARD.UNKNOWN') }</span>
+      </span>
     );
   }
 };
@@ -136,12 +137,12 @@ export const TxTypeRender = function(category) {
 export const TxAmountRender = function (tx) {
   if (Config.roundValues) {
     return (
-      <td title={ tx.amount }>{ formatValue('round', tx.amount, -6) || translate('DASHBOARD.UNKNOWN') }</td>
+      <span title={ tx.amount }>{ formatValue('round', tx.amount, -6) || translate('DASHBOARD.UNKNOWN') }</span>
     );
   }
 
   return (
-    <td>{ tx.amount || translate('DASHBOARD.UNKNOWN') }</td>
+    <span>{ tx.amount || translate('DASHBOARD.UNKNOWN') }</span>
   );
 };
 
@@ -151,15 +152,14 @@ export const TxHistoryListRender = function() {
       data={this.state.filteredItemsList}
       columns={this.state.itemsListColumns}
       sortable={true}
-      className='-striped -highlight'
+      className="-striped -highlight"
       PaginationComponent={TablePaginationRenderer}
       nextText={translate('INDEX.NEXT_PAGE')}
       previousText={translate('INDEX.PREVIOUS_PAGE')}
       showPaginationBottom={this.state.showPagination}
       showPaginationTop={this.state.showPagination}
       pageSize={this.pageSize}
-      onPageSizeChange={(pageSize, pageIndex) => this.onPageSizeChange(pageSize, pageIndex)}
-    />
+      onPageSizeChange={(pageSize, pageIndex) => this.onPageSizeChange(pageSize, pageIndex)} />
   );
 };
 
@@ -240,22 +240,23 @@ export const WalletsDataRender = function() {
                         null
                       }
                     </div>
-                    <h4 className='panel-title'>{ translate('INDEX.TRANSACTION_HISTORY') }</h4>
+                    <h4 className="panel-title">{ translate('INDEX.TRANSACTION_HISTORY') }</h4>
                   </header>
-                  <div className='panel-body'>
-                    <div className='row padding-bottom-20'>
-                      {this.shouldDisplayAddressList() &&
-                        <div className='col-sm-8'>
+                  <div className="panel-body">
+                    <div className="row padding-bottom-20">
+                      { this.shouldDisplayAddressList() &&
+                        <div className="col-sm-8">
                           {this.renderAddressList()}
                         </div>
                       }
-                      <div className='col-sm-4'>
-                        <input className="form-control"
-                               onChange={e => this.onSearchTermChange(e.target.value)}
-                               placeholder='Search' />
+                      <div className="col-sm-4">
+                        <input
+                          className="form-control"
+                          onChange={e => this.onSearchTermChange(e.target.value)}
+                          placeholder="Search" />
                       </div>
                     </div>
-                    <div className='row'>
+                    <div className="row">
                       { this.renderTxHistoryList() }
                     </div>
                   </div>
diff --git a/react/src/components/dashboard/walletsInfo/walletsInfo.js b/react/src/components/dashboard/walletsInfo/walletsInfo.js
new file mode 100644
index 0000000..c3e1e81
--- /dev/null
+++ b/react/src/components/dashboard/walletsInfo/walletsInfo.js
@@ -0,0 +1,28 @@
+import React from 'react';
+import WalletsNativeInfoRender from './walletsInfo.render';
+import { toggleClaimInterestModal } from '../../../actions/actionCreators';
+import Store from '../../../store';
+
+class WalletsNativeInfo extends React.Component {
+  constructor(props) {
+    super(props);
+    this.openClaimInterestModal = this.openClaimInterestModal.bind(this);
+  }
+
+  openClaimInterestModal() {
+    Store.dispatch(toggleClaimInterestModal(true));
+  }
+
+  render() {
+    if (this.props &&
+        this.props.Dashboard &&
+        this.props.Dashboard.progress &&
+        this.props.ActiveCoin.activeSection === 'settings') {
+      return WalletsNativeInfoRender.call(this);
+    }
+
+    return null;
+  }
+}
+
+export default WalletsNativeInfo;
diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js
similarity index 90%
rename from react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js
rename to react/src/components/dashboard/walletsInfo/walletsInfo.render.js
index 07bd784..5b8dbd6 100644
--- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js
+++ b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js
@@ -1,7 +1,8 @@
 import React from 'react';
 import { translate } from '../../../translate/translate';
+import ClaimInterestModal from '../claimInterestModal/claimInterestModal';
 
-const WalletsNativeInfoRender = function() {
+const WalletsInfoRender = function() {
   return (
     <div>
       <div className="col-xlg-6 col-md-4">
@@ -40,6 +41,15 @@ const WalletsNativeInfoRender = function() {
             </table>
           </div>
         </div>
+        { this.props.ActiveCoin.coin === 'KMD' &&
+          <div>
+            <button
+              type="button"
+              className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
+              onClick={ () => this.openClaimInterestModal() }>Claim interest</button>
+            <ClaimInterestModal {...this.props} />
+          </div>
+        }
       </div>
 
       <div className="col-xlg-6 col-md-8">
@@ -146,4 +156,4 @@ const WalletsNativeInfoRender = function() {
   );
 };
 
-export default WalletsNativeInfoRender;
\ No newline at end of file
+export default WalletsInfoRender;
\ No newline at end of file
diff --git a/react/src/components/dashboard/walletsNative/walletsNative.js b/react/src/components/dashboard/walletsNative/walletsNative.js
index 764a55e..793ff9d 100644
--- a/react/src/components/dashboard/walletsNative/walletsNative.js
+++ b/react/src/components/dashboard/walletsNative/walletsNative.js
@@ -2,6 +2,7 @@ import React from 'react';
 import WalletsNativeRender from './walletsNative.render';
 import { translate } from '../../../translate/translate';
 import { triggerToaster } from '../../../actions/actionCreators';
+import { getCoinTitle } from '../../../util/coinHelper';
 import Config from '../../../config';
 import Store from '../../../store';
 
@@ -13,6 +14,10 @@ const socket = io.connect(`http://127.0.0.1:${Config.agamaPort}`);
 class WalletsNative extends React.Component {
   constructor(props) {
     super(props);
+    this.state = {
+      nativeOnly: Config.iguanaLessMode,
+    };
+    this.getCoinStyle = this.getCoinStyle.bind(this);
     socket.on('service', msg => this.updateSocketsData(msg));
   }
 
@@ -35,11 +40,21 @@ class WalletsNative extends React.Component {
     }
   }
 
-  defaultBG() {
-    if (this.props.ActiveCoin.coin === 'REVS') {
-      return 'supernet';
-    } else {
-      return this.props.ActiveCoin.coin.toLowerCase();
+  getCoinStyle(type) {
+    if (type === 'transparent') {
+      if (getCoinTitle(this.props.ActiveCoin.coin).transparentBG && getCoinTitle().logo) {
+        return { 'backgroundImage': `url("assets/images/bg/${getCoinTitle().logo.toLowerCase()}_transparent_header_bg.png")` };
+      }
+    } else if (type === 'title') {
+      let _iconPath;
+
+      if (getCoinTitle(this.props.ActiveCoin.coin).titleBG) {
+        _iconPath = `assets/images/native/${getCoinTitle(this.props.ActiveCoin.coin).logo.toLowerCase()}_header_title_logo.png`;
+      } else if (!getCoinTitle(this.props.ActiveCoin.coin).titleBG && getCoinTitle(this.props.ActiveCoin.coin).logo) {
+        _iconPath = `assets/images/cryptologo/${getCoinTitle(this.props.ActiveCoin.coin).logo.toLowerCase()}.png`;
+      }
+
+      return _iconPath;
     }
   }
 
diff --git a/react/src/components/dashboard/walletsNative/walletsNative.render.js b/react/src/components/dashboard/walletsNative/walletsNative.render.js
index 15d5be5..e9202c2 100644
--- a/react/src/components/dashboard/walletsNative/walletsNative.render.js
+++ b/react/src/components/dashboard/walletsNative/walletsNative.render.js
@@ -1,6 +1,6 @@
 import React from 'react';
 import WalletsBalance from '../walletsBalance/walletsBalance';
-import WalletsNativeInfo from '../walletsNativeInfo/walletsNativeInfo';
+import WalletsInfo from '../walletsInfo/walletsInfo';
 import WalletsNativeSend from '../walletsNativeSend/walletsNativeSend';
 import WalletsProgress from '../walletsProgress/walletsProgress';
 import WalletsData from '../walletsData/walletsData';
@@ -13,12 +13,14 @@ const WalletsNativeRender = function() {
         <div
           id="easydex-header-div"
           className="background-color-white"
-          style={{ 'backgroundImage': `url("assets/images/bg/${this.defaultBG()}_transparent_header_bg.png")` }}>
-          <ol className="breadcrumb">
+          style={ this.getCoinStyle('transparent') }>
+          <ol className={ (!this.state.nativeOnly ? 'breadcrumb breadcrumb--normal' : 'breadcrumb') + (this.props.ActiveCoin.coin === 'KMD' || this.props.ActiveCoin.coin === 'JUMBLR' || this.props.ActiveCoin.coin === 'MESH' || this.props.ActiveCoin.coin === 'MVP' ? ' coin-logo-wide' : '') + (this.state.nativeOnly ? ' native-coin-logo' : '') }>
             <li className="header-easydex-section">
-              <img src={ `assets/images/native/${this.defaultBG()}_header_title_logo.png` } />
+              { this.getCoinStyle('title') &&
+                <img src={ this.getCoinStyle('title') } />
+              }
               <span
-                className={ `easydex-section-image ${(this.props.ActiveCoin.coin === 'KMD' ? 'hide' : '')}` }
+                className={ `easydex-section-image ${(this.props.ActiveCoin.coin === 'KMD' || this.props.ActiveCoin.coin === 'JUMBLR' || this.props.ActiveCoin.coin === 'MESH' || this.props.ActiveCoin.coin === 'MVP' ? 'hide' : '')}` }
                 style={{ marginLeft: '20px' }}>
                 { this.props.ActiveCoin.coin }
               </span>
@@ -32,7 +34,7 @@ const WalletsNativeRender = function() {
             <ReceiveCoin {...this.props.ActiveCoin} />
             <WalletsData {...this.props} />
             <WalletsNativeSend {...this.props} />
-            <WalletsNativeInfo {...this.props} />
+            <WalletsInfo {...this.props} />
           </div>
         </div>
       </div>
diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js
deleted file mode 100644
index 6e025e1..0000000
--- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js
+++ /dev/null
@@ -1,21 +0,0 @@
-import React from 'react';
-import WalletsNativeInfoRender from './walletsNativeInfo.render';
-
-class WalletsNativeInfo extends React.Component {
-  constructor(props) {
-    super(props);
-  }
-
-  render() {
-    if (this.props &&
-        this.props.Dashboard &&
-        this.props.Dashboard.progress &&
-        this.props.ActiveCoin.nativeActiveSection === 'settings') {
-      return WalletsNativeInfoRender.call(this);
-    }
-
-    return null;
-  }
-}
-
-export default WalletsNativeInfo;
diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
index d9a601e..0c89e11 100644
--- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
+++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
@@ -12,7 +12,9 @@ import Store from '../../../store';
 import {
   AddressListRender,
   OASendUIRender,
-  WalletsNativeSendRender
+  WalletsNativeSendRender,
+  WalletsNativeSendFormRender,
+  _WalletsNativeSendFormRender
 } from './walletsNativeSend.render';
 
 class WalletsNativeSend extends React.Component {
@@ -37,6 +39,11 @@ class WalletsNativeSend extends React.Component {
     this.checkZAddressCount = this.checkZAddressCount.bind(this);
     this.setRecieverFromScan = this.setRecieverFromScan.bind(this);
     this.renderOPIDListCheck = this.renderOPIDListCheck.bind(this);
+    this.WalletsNativeSendFormRender = _WalletsNativeSendFormRender.bind(this);
+  }
+
+  WalletsNativeSendFormRender() {
+    return this._WalletsNativeSendFormRender();
   }
 
   componentWillMount() {
@@ -344,7 +351,7 @@ class WalletsNativeSend extends React.Component {
   render() {
     if (this.props &&
         this.props.ActiveCoin &&
-        this.props.ActiveCoin.nativeActiveSection === 'send') {
+        (this.props.ActiveCoin.activeSection === 'send' || this.props.activeSection === 'send')) {
       return WalletsNativeSendRender.call(this);
     }
 
diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js
index fb9203f..d11ce18 100644
--- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js
+++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js
@@ -65,151 +65,163 @@ export const OASendUIRender = function() {
   );
 };
 
-export const WalletsNativeSendRender = function() {
+export const _WalletsNativeSendFormRender = function() {
   return (
-    <div id="kmd_wallet_send">
-      <div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12">
-        <div
-          className="panel"
-          id="projects">
-          <div className="panel-heading">
-            <h3 className="panel-title">
-              { translate('INDEX.SEND') } { this.props.ActiveCoin.coin }
-            </h3>
-          </div>
-          <div className="qr-modal-send-block">
-            <QRModal
-              mode="scan"
-              setRecieverFromScan={ this.setRecieverFromScan } />
-          </div>
-          <div className="panel-body container-fluid">
-            <form
-              className="extcoin-send-form"
-              method="post"
-              autoComplete="off">
-              { this.state.renderAddressDropdown &&
-                <div className="row">
-                  <div className="col-xlg-12 form-group form-material">
-                    <label className="control-label">{ translate('INDEX.SEND_FROM') }</label>
-                    { this.renderAddressList() }
-                  </div>
-                </div>
-              }
-              { this.renderOASendUI() }
-              <div className="row">
-                <div className="col-xlg-12 form-group form-material">
-                  <label
-                    className="control-label"
-                    htmlFor="kmdWalletSendTo">{ translate('INDEX.SEND_TO') }</label>
-                  <input
-                    type="text"
-                    className="form-control"
-                    name="sendTo"
-                    onChange={ this.updateInput }
-                    value={ this.state.sendTo }
-                    id="kmdWalletSendTo"
-                    placeholder={ translate('SEND.ENTER_T_OR_Z_ADDR') }
-                    autoComplete="off"
-                    required />
-                </div>
-                <div className="col-lg-12 form-group form-material">
-                  <label
-                    className="control-label"
-                    htmlFor="kmdWalletAmount">
-                    { translate('INDEX.AMOUNT') }
-                  </label>
-                  <input
-                    type="text"
-                    className="form-control"
-                    name="amount"
-                    value={ this.state.amount !== 0 ? this.state.amount : '' }
-                    onChange={ this.updateInput }
-                    id="kmdWalletAmount"
-                    placeholder="0.000"
-                    autoComplete="off" />
-                </div>
-                <div className="col-lg-6 form-group form-material hide">
-                  <label
-                    className="control-label"
-                    htmlFor="kmdWalletFee">
-                    { translate('INDEX.FEE') }
-                  </label>
-                  <input
-                    type="text"
-                    className="form-control"
-                    name="fee"
-                    onChange={ this.updateInput }
-                    id="kmdWalletFee"
-                    placeholder="0.000"
-                    value={ this.state.fee !== 0 ? this.state.fee : '' }
-                    autoComplete="off" />
-                </div>
-                <div className="col-lg-12 hide">
-                  <span>
-                    <strong>{ translate('INDEX.TOTAL') }:</strong>&nbsp;
-                    { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }&nbsp;
-                    { this.props.ActiveCoin.coin }
-                  </span>
-                </div>
-                <div className="col-lg-12">
-                  <button
-                    type="button"
-                    className="btn btn-primary waves-effect waves-light pull-right"
-                    onClick={ this.handleSubmit }
-                    disabled={ !this.state.sendTo || !this.state.amount }>
-                    { translate('INDEX.SEND') } { this.state.amount } { this.props.ActiveCoin.coin }
-                  </button>
-                </div>
-              </div>
-            </form>
+    <form
+      className="extcoin-send-form"
+      method="post"
+      autoComplete="off">
+      { this.state.renderAddressDropdown &&
+        <div className="row">
+          <div className="col-xlg-12 form-group form-material">
+            <label className="control-label">{ translate('INDEX.SEND_FROM') }</label>
+            { this.renderAddressList() }
           </div>
         </div>
+      }
+      { this.renderOASendUI() }
+      <div className="row">
+        <div className="col-xlg-12 form-group form-material">
+          <label
+            className="control-label"
+            htmlFor="kmdWalletSendTo">{ translate('INDEX.SEND_TO') }</label>
+          <input
+            type="text"
+            className="form-control"
+            name="sendTo"
+            onChange={ this.updateInput }
+            value={ this.state.sendTo }
+            id="kmdWalletSendTo"
+            placeholder={ translate('SEND.ENTER_T_OR_Z_ADDR') }
+            autoComplete="off"
+            required />
+        </div>
+        <div className="col-lg-12 form-group form-material">
+          <label
+            className="control-label"
+            htmlFor="kmdWalletAmount">
+            { translate('INDEX.AMOUNT') }
+          </label>
+          <input
+            type="text"
+            className="form-control"
+            name="amount"
+            value={ this.state.amount !== 0 ? this.state.amount : '' }
+            onChange={ this.updateInput }
+            id="kmdWalletAmount"
+            placeholder="0.000"
+            autoComplete="off" />
+        </div>
+        <div className="col-lg-6 form-group form-material hide">
+          <label
+            className="control-label"
+            htmlFor="kmdWalletFee">
+            { translate('INDEX.FEE') }
+          </label>
+          <input
+            type="text"
+            className="form-control"
+            name="fee"
+            onChange={ this.updateInput }
+            id="kmdWalletFee"
+            placeholder="0.000"
+            value={ this.state.fee !== 0 ? this.state.fee : '' }
+            autoComplete="off" />
+        </div>
+        <div className="col-lg-12 hide">
+          <span>
+            <strong>{ translate('INDEX.TOTAL') }:</strong>&nbsp;
+            { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }&nbsp;
+            { this.props.ActiveCoin.coin }
+          </span>
+        </div>
+        <div className="col-lg-12">
+          <button
+            type="button"
+            className="btn btn-primary waves-effect waves-light pull-right"
+            onClick={ this.handleSubmit }
+            disabled={ !this.state.sendTo || !this.state.amount }>
+            { translate('INDEX.SEND') } { this.state.amount } { this.props.ActiveCoin.coin }
+          </button>
+        </div>
       </div>
+    </form>
+  );
+}
 
-      { this.renderOPIDListCheck() &&
-        <div className="col-xs-12">
-          <div className="row">
-            <div className="panel nav-tabs-horizontal">
-              <div>
-                <div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
-                  <div className="panel">
-                    <header className="panel-heading">
-                      <h3 className="panel-title">
-                        { translate('INDEX.OPERATIONS_STATUSES') }
-                      </h3>
-                    </header>
-                    <div className="panel-body">
-                      <table
-                        className="table table-hover dataTable table-striped"
-                        width="100%">
-                        <thead>
-                          <tr>
-                            <th>{ translate('INDEX.STATUS') }</th>
-                            <th>ID</th>
-                            <th>{ translate('INDEX.TIME') }</th>
-                            <th>{ translate('INDEX.RESULT') }</th>
-                          </tr>
-                        </thead>
-                        <tbody>
-                          { this.renderOPIDList() }
-                        </tbody>
-                        <tfoot>
-                          <tr>
-                            <th>{ translate('INDEX.STATUS') }</th>
-                            <th>ID</th>
-                            <th>{ translate('INDEX.TIME') }</th>
-                            <th>{ translate('INDEX.RESULT') }</th>
-                          </tr>
-                        </tfoot>
-                      </table>
+export const WalletsNativeSendRender = function() {
+  if (this.props.renderFormOnly) {
+    return (
+      <div>{ this.WalletsNativeSendFormRender() }</div>
+    );
+  } else {
+    return (
+      <div id="kmd_wallet_send">
+        <div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12">
+          <div
+            className="panel"
+            id="projects">
+            <div className="panel-heading">
+              <h3 className="panel-title">
+                { translate('INDEX.SEND') } { this.props.ActiveCoin.coin }
+              </h3>
+            </div>
+            <div className="qr-modal-send-block">
+              <QRModal
+                mode="scan"
+                setRecieverFromScan={ this.setRecieverFromScan } />
+            </div>
+            <div className="panel-body container-fluid">
+            { this.WalletsNativeSendFormRender() }
+            </div>
+          </div>
+        </div>
+
+        { this.renderOPIDListCheck() &&
+          <div className="col-xs-12">
+            <div className="row">
+              <div className="panel nav-tabs-horizontal">
+                <div>
+                  <div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
+                    <div className="panel">
+                      <header className="panel-heading">
+                        <h3 className="panel-title">
+                          { translate('INDEX.OPERATIONS_STATUSES') }
+                        </h3>
+                      </header>
+                      <div className="panel-body">
+                        <table
+                          className="table table-hover dataTable table-striped"
+                          width="100%">
+                          <thead>
+                            <tr>
+                              <th>{ translate('INDEX.STATUS') }</th>
+                              <th>ID</th>
+                              <th>{ translate('INDEX.TIME') }</th>
+                              <th>{ translate('INDEX.RESULT') }</th>
+                            </tr>
+                          </thead>
+                          <tbody>
+                            { this.renderOPIDList() }
+                          </tbody>
+                          <tfoot>
+                            <tr>
+                              <th>{ translate('INDEX.STATUS') }</th>
+                              <th>ID</th>
+                              <th>{ translate('INDEX.TIME') }</th>
+                              <th>{ translate('INDEX.RESULT') }</th>
+                            </tr>
+                          </tfoot>
+                        </table>
+                      </div>
                     </div>
                   </div>
                 </div>
               </div>
             </div>
           </div>
-        </div>
-      }
-    </div>
-  );
+        }
+      </div>
+    );
+  }
 };
\ No newline at end of file
diff --git a/react/src/components/dashboard/walletsNav/walletsNav.js b/react/src/components/dashboard/walletsNav/walletsNav.js
index 4b17767..702e236 100644
--- a/react/src/components/dashboard/walletsNav/walletsNav.js
+++ b/react/src/components/dashboard/walletsNav/walletsNav.js
@@ -73,7 +73,7 @@ class WalletsNav extends React.Component {
     if (this.props.ActiveCoin.mode === 'native') {
       Store.dispatch(
         toggleDashboardActiveSection(
-          this.props.ActiveCoin.nativeActiveSection === 'settings' ? 'default' : 'settings'
+          this.props.ActiveCoin.activeSection === 'settings' ? 'default' : 'settings'
         )
       );
     } else {
@@ -93,7 +93,7 @@ class WalletsNav extends React.Component {
     if (this.props.ActiveCoin.mode === 'native') {
       Store.dispatch(
         toggleDashboardActiveSection(
-          this.props.ActiveCoin.nativeActiveSection === 'send' ? 'default' : 'send'
+          this.props.ActiveCoin.activeSection === 'send' ? 'default' : 'send'
         )
       );
     } else {
@@ -105,7 +105,7 @@ class WalletsNav extends React.Component {
     if (this.props.ActiveCoin.mode === 'native') {
       Store.dispatch(
         toggleDashboardActiveSection(
-          this.props.ActiveCoin.nativeActiveSection === 'receive' ? 'default' : 'receive'
+          this.props.ActiveCoin.activeSection === 'receive' ? 'default' : 'receive'
         )
       );
     } else {
diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js
index 67d43a7..b17f82d 100644
--- a/react/src/components/dashboard/walletsNav/walletsNav.render.js
+++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js
@@ -24,9 +24,9 @@ export const WalletsNavWithWalletRender = function() {
   return (
     <div>
       <div
-        className={ 'page-header page-header-bordered header-easydex padding-bottom-' + (this.state.nativeOnly ? '40' : '20') }
+        className={ 'page-header page-header-bordered header-easydex padding-bottom-' + (this.state.nativeOnly ? '40 page-header--native' : '20') }
         id="header-dashboard"
-        style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : '0' }}>
+        style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30px' : '0') }}>
         <ol className={ this.state.nativeOnly ? 'hide' : 'breadcrumb' }>
           <strong>{ translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: </strong>
           { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' }
diff --git a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js
index 2ee27b8..0a5b07d 100644
--- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js
+++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js
@@ -43,7 +43,7 @@ class WalletsTxInfo extends React.Component {
         // TODO the conditions below should be merged once the native mode components are fully merged
         // into the rest of the components
         (!this.isNativeMode() ||
-         (this.isNativeMode() && this.props.ActiveCoin.nativeActiveSection === 'default'))) {
+         (this.isNativeMode() && this.props.ActiveCoin.activeSection === 'default'))) {
       const txInfo = sortByDate(this.props.ActiveCoin.txhistory)[this.props.ActiveCoin.showTransactionInfoTxIndex];
       return WalletsTxInfoRender.call(this, txInfo);
     }
diff --git a/react/src/components/main/main.js b/react/src/components/main/main.js
index 88f66c3..6394888 100644
--- a/react/src/components/main/main.js
+++ b/react/src/components/main/main.js
@@ -5,7 +5,8 @@ import Store from '../../store';
 import {
   Config,
   getDexCoins,
-  iguanaActiveHandle
+  iguanaActiveHandle,
+  triggerToaster
 } from '../../actions/actionCreators';
 
 const IGUANA_ACTIVE_HANDLE_TIMEOUT = 30000;
@@ -24,15 +25,28 @@ class Main extends React.Component {
 
   componentDidMount() {
     let appVersion;
+    let zcashParamsExist;
 
     try {
       appVersion = window.require('electron').remote.getCurrentWindow().appBasicInfo;
+      zcashParamsExist = window.require('electron').remote.getCurrentWindow().zcashParamsExist;
     } catch (e) {}
 
     if (appVersion) {
       document.title = `${appVersion.name} (v${appVersion.version.replace('version=', '')}-beta)`;
     }
 
+    if (!zcashParamsExist) {
+      Store.dispatch(
+        triggerToaster(
+          'Zcash params are missing',
+          'Komodo',
+          'error',
+          false
+        )
+      );
+    }
+
     Store.dispatch(iguanaActiveHandle());
     const _iguanaActiveHandle = setInterval(function() {
       Store.dispatch(iguanaActiveHandle());
diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss
index a3cb152..3b9c82a 100644
--- a/react/src/components/overrides.scss
+++ b/react/src/components/overrides.scss
@@ -94,7 +94,8 @@ body {
   display: block;
 }
 
-.collapse-active {
+.collapse-active,
+.panel>:not(.panel-loading):not(.collapsing) {
   transition: height 0.3s ease-out;
 }
 
@@ -628,12 +629,19 @@ select{
     > div {
       height: 100%;
     }
+    .form-group {
+      &.form-material {
+        &.floating {
+          height: 80%;
+        }
+      }
+    }
     .page-content {
       width: 90%;
       height: 100%;
 
       textarea {
-        min-height: 200px;
+        height: 100%;
       }
     }
   }
@@ -684,4 +692,237 @@ select{
       }
     }
   }
+}
+
+.breadcrumb {
+  padding: 8px 30px 0;
+  position: relative;
+  top: -10px;
+}
+
+.header-easydex-section {
+  img {
+    max-width: 60px;
+  }
+}
+
+.coin-logo-wide {
+  padding: 8px 30px 0;
+  position: relative;
+  top: 0;
+
+  .header-easydex-section {
+    img {
+      width: inherit;
+      max-width: inherit;
+      position: relative;
+      top: -5px;
+    }
+  }
+}
+
+.native-coin-logo {
+  float: left;
+  position: absolute;
+  top: -105px;
+  z-index: 100;
+
+  .header-easydex-section {
+    img {
+      width: 60px;
+    }
+  }
+}
+
+.coin-logo-wide {
+  &.native-coin-logo {
+    top: -93px;
+
+    .header-easydex-section img {
+      width: inherit;
+    }
+  }
+}
+
+.page-header--native {
+  height: 75px;
+}
+
+#toast-container {
+  > div {
+    opacity: 1;
+  }
+}
+
+/* jumblr */
+.jumblr {
+  p {
+    width: calc(100% - 100px);
+  }
+  .breadcrumb {
+    padding: 8px 30px;
+    position: relative;
+    top: 0;
+  }
+  .img-responsive {
+    position: absolute;
+    top: -28px;
+    right: 18px;
+
+    .coin {
+      font-size: 30px;
+      position: relative;
+      left: -18px;
+      top: 4px;
+    }
+    .image {
+      width: 60px;
+    }
+  }
+  .header-easydex-section {
+    img {
+      max-width: inherit;
+    }
+  }
+  .copy-string-btn {
+    position: absolute;
+    right: 36px;
+    margin-top: -68px;
+  }
+  .btn-next {
+    position: absolute;
+    top: 60px;
+    right: 32px;
+  }
+  input.labelauty+label,
+  input.labelauty+label {
+    background: #d6d5d5;
+    color: #504e4e;
+  }
+  input.labelauty:checked+label {
+    color: #fff;
+    background-color: #3949ab;
+  }
+  input.labelauty + label:hover .labelauty-unchecked,
+  input.labelauty + label .labelauty-unchecked {
+    color: #504e4e;
+  }
+  .nofloat {
+    float: none;
+    display: inline-block;
+    padding-left: 0;
+  }
+}
+
+.jumblr-mode-selector {
+  .nav-tabs {
+    li {
+      cursor: pointer;
+
+      &.active {
+        > a {
+          cursor: pointer;
+          color: #fff;
+          background-color: #62a8ea;
+          border-color: transparent;
+          border-bottom-color: #62a8ea;
+        }
+      }
+    }
+  }
+
+  .panel-heading {
+    background: #f3f3f3;
+    cursor: pointer;
+  }
+  .panel-title {
+    color: #676767;
+  }
+  .jumblr-addresses-list {
+    .col-xs-3 {
+      padding: 0;
+    }
+  }
+}
+
+.modal-claim-interest {
+  .modal-dialog {
+    width: 70%;
+
+    .table > tbody > tr > td,
+    .table > tbody > tr > th,
+    .table > tfoot > tr > td,
+    .table > tfoot > tr > th,
+    .table > thead > tr > td,
+    .table > thead > tr > th {
+      padding: 8px 30px 8px 0;
+    }
+
+    .claim-btn {
+      position: absolute;
+      right: 29px;
+      top: 66px;
+    }
+    .table-scroll {
+      height: 366px;
+      overflow-y: auto;
+      overflow-x: hidden;
+      width: 100%;
+    }
+    .bold {
+      font-weight: bold;
+    }
+    .green {
+      color: #66bb6a;
+    }
+    .red {
+      color: #f96868;
+    }
+    .locktime {
+      i {
+        font-size: 20px;
+        line-height: 1.1;
+      }
+    }
+
+    .refresh-icon {
+      position: absolute;
+      right: 20px;
+      font-size: 20px;
+      z-index: 100;
+    }
+  }
+}
+
+.ReactTable {
+  border: none;
+
+  .pagination-top {
+    display: none;
+  }
+  .rt-td {
+    text-align: center;
+  }
+  .ReactTable .rt-thead .rt-th,
+  .ReactTable .rt-thead .rt-td {
+    padding: 10px 5px;
+  }
+  .rt-table {
+    border: 1px solid rgba(0, 0, 0, 0.1);
+  }
+  .rt-tfoot {
+    border-top: 1px solid rgba(0, 0, 0, 0.1);
+  }
+  .rt-thead {
+    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+  }
+  .rt-thead .rt-th,
+  .rt-thead .rt-td {
+    padding: 10px 5px;
+  }
+  .colum--direction {
+    width: 40px !important;
+    flex: 40 0 auto !important;
+    padding-right: 10px;
+  }
 }
\ No newline at end of file
diff --git a/react/src/reducers/activeCoin.js b/react/src/reducers/activeCoin.js
index ec0dee3..0a976a6 100644
--- a/react/src/reducers/activeCoin.js
+++ b/react/src/reducers/activeCoin.js
@@ -27,7 +27,7 @@ export function ActiveCoin(state = {
   send: false,
   receive: false,
   balance: 0,
-  nativeActiveSection: 'default',
+  activeSection: 'default',
   showTransactionInfo: false,
   showTransactionInfoTxIndex: null,
   txhistory: [],
@@ -53,7 +53,7 @@ export function ActiveCoin(state = {
           receive: state.receive,
           showTransactionInfo: state.showTransactionInfo,
           showTransactionInfoTxIndex: state.showTransactionInfoTxIndex,
-          nativeActiveSection: state.nativeActiveSection,
+          activeSection: state.activeSection,
           lastSendToResponse: state.lastSendToResponse,
           mainBasiliskAddress: state.mainBasiliskAddress,
           opids: state.opids,
@@ -73,7 +73,7 @@ export function ActiveCoin(state = {
           receive: _coinData.receive,
           showTransactionInfo: _coinData.showTransactionInfo,
           showTransactionInfoTxIndex: _coinData.showTransactionInfoTxIndex,
-          nativeActiveSection: _coinData.nativeActiveSection,
+          activeSection: _coinData.activeSection,
           lastSendToResponse: _coinData.lastSendToResponse,
           mainBasiliskAddress: _coinData.mainBasiliskAddress,
           opids: _coinData.opids,
@@ -91,7 +91,7 @@ export function ActiveCoin(state = {
             receive: state.receive,
             showTransactionInfo: state.showTransactionInfo,
             showTransactionInfoTxIndex: state.showTransactionInfoTxIndex,
-            nativeActiveSection: state.nativeActiveSection,
+            activeSection: state.activeSection,
             lastSendToResponse: state.lastSendToResponse,
             mainBasiliskAddress: state.mainBasiliskAddress,
             opids: state.opids,
@@ -110,7 +110,7 @@ export function ActiveCoin(state = {
             receive: false,
             showTransactionInfo: false,
             showTransactionInfoTxIndex: null,
-            nativeActiveSection: 'default',
+            activeSection: 'default',
           });
         } else {
           return Object.assign({}, state, {
@@ -122,7 +122,7 @@ export function ActiveCoin(state = {
             receive: false,
             showTransactionInfo: false,
             showTransactionInfoTxIndex: null,
-            nativeActiveSection: 'default',
+            activeSection: 'default',
           });
         }
       }
@@ -151,7 +151,7 @@ export function ActiveCoin(state = {
       });
     case DASHBOARD_ACTIVE_SECTION:
       return Object.assign({}, state, {
-        nativeActiveSection: action.section,
+        activeSection: action.section,
       });
     case DASHBOARD_ACTIVE_TXINFO_MODAL:
       return Object.assign({}, state, {
diff --git a/react/src/reducers/dashboard.js b/react/src/reducers/dashboard.js
index 98df82e..54e2e63 100644
--- a/react/src/reducers/dashboard.js
+++ b/react/src/reducers/dashboard.js
@@ -9,14 +9,15 @@ import {
   VIEW_CACHE_DATA,
   LOG_GUI_HTTP,
   TOGGLE_NOTIFICATIONS_MODAL,
-  DISPLAY_COIND_DOWN_MODAL
+  DISPLAY_COIND_DOWN_MODAL,
+  DISPLAY_CLAIM_INTEREST_MODAL
 } from '../actions/storeType';
 
 const HTTP_STACK_MAX_ENTRIES = 150; // limit stack mem length to N records per type
 
 const trimHTTPLogs = (logObject) => {
   const logObjectArray = Object.keys(logObject);
-  
+
   if (logObjectArray.length - HTTP_STACK_MAX_ENTRIES === 1) {
     delete logObject[logObjectArray.shift()];
   }
@@ -38,6 +39,7 @@ export function Dashboard(state = {
   },
   guiLog: {},
   displayCoindDownModal: false,
+  displayClaimInterestModal: false,
 }, action) {
   switch (action.type) {
     case DASHBOARD_SECTION_CHANGE:
@@ -95,7 +97,7 @@ export function Dashboard(state = {
         const logItem = { [actionTS]: action.log };
         newLogState = trimHTTPLogs(Object.assign({}, logState, logItem));
       }
-      
+
       return Object.assign({}, state, {
         guiLog: newLogState,
       });
@@ -104,6 +106,11 @@ export function Dashboard(state = {
         displayCoindDownModal: action.displayCoindDownModal,
       });
       break;
+    case DISPLAY_CLAIM_INTEREST_MODAL:
+      return Object.assign({}, state, {
+        displayClaimInterestModal: action.displayClaimInterestModal,
+      });
+      break;
     default:
       return state;
   }
diff --git a/react/src/translate/en.js b/react/src/translate/en.js
index 9779a73..c3032d6 100644
--- a/react/src/translate/en.js
+++ b/react/src/translate/en.js
@@ -281,15 +281,15 @@ export const _lang = {
     },
     'JUMBLR': {
       'NOTICE': 'EXPERIMENTAL TEST VERSION ONLY',
-      'DESCRIPTION': 'Jumblr feature is very experimental and for now, is Only enabled for testing and debugging.' +
+      'DESCRIPTION': 'Jumblr feature is very experimental and for now, is Only enabled for testing and debugging. ' +
                      'Please use the current version of Jumblr only with small amounts if you are participating in testing this feature.',
       'NEED_NATIVE': 'Need Native Mode Komodo',
       'TO_USE_JUMBLR': 'To use Jumblr feature, you need to activate Komodo in Native Mode.',
       'IF_YOU_ALREADY_RUNNING': 'If you are already running Komodo in either Basilisk Mode or Full Mode, close the wallet and restart again to start Komodo In Native Mode.',
       'THIS_SCREEN_DOESNT_REFRESH': 'This screen does not auto refresh. ' +
-                'You will need to hit the Refresh button on the top right corner of the screen to get latest Jumblr data.',
+                                    'You will need to hit the Refresh button on the top right corner of the screen to get latest Jumblr data.',
       'FEW_SECURITY_NOTES': 'Few Security Notes for your Privacy and Anonymity of funds',
-      'FEW_SECURITY_NOTES_DESC1': 'Jumblr addresses (BTC Jumbler and KMD Jumbler) addresses are your Private Addresses.',
+      'FEW_SECURITY_NOTES_DESC1': 'Jumblr addresses addresses are your Private Addresses.',
       'FEW_SECURITY_NOTES_DESC2': 'DO NOT SHARE your Jumblr addresses with anyone.',
       'FEW_SECURITY_NOTES_DESC3': 'Jumblr addresses are like YOUR PASSWORD. Keep them safe, secure and hidden.',
       'FEW_SECURITY_NOTES_DESC4': 'Only YOU should know your Jumblr Address. Nobody else.',
diff --git a/react/src/util/coinHelper.js b/react/src/util/coinHelper.js
index 216795f..9ee30c1 100644
--- a/react/src/util/coinHelper.js
+++ b/react/src/util/coinHelper.js
@@ -1,6 +1,9 @@
 export function getCoinTitle(coin) {
-  let coinlogo,
-      coinname;
+  let coinlogo;
+  let coinname;
+  let transparentBG = false;
+  let titleBG = false;
+  let hideTitle = false;
 
   switch (coin) {
     case 'BTC':
@@ -56,7 +59,10 @@ export function getCoinTitle(coin) {
       coinname = 'Zetacoin';
       break;
     case 'KMD':
-      coinlogo = 'komodo';
+      hideTitle = true;
+      titleBG = true;
+      transparentBG = true;
+      coinlogo = 'kmd';
       coinname = 'Komodo';
       break;
     case 'BTM':
@@ -80,6 +86,7 @@ export function getCoinTitle(coin) {
       coinname = 'GameCredits';
       break;
     case 'SUPERNET':
+      titleBG = true;
       coinlogo = 'SUPERNET';
       coinname = 'SUPERNET';
       break;
@@ -88,14 +95,20 @@ export function getCoinTitle(coin) {
       coinname = 'REVS';
       break;
     case 'WLC':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'WLC';
       coinname = 'WIRELESS';
       break;
     case 'PANGEA':
+      titleBG = true;
       coinlogo = 'PANGEA';
       coinname = 'PANGEA';
       break;
     case 'JUMBLR':
+      titleBG = true;
+      transparentBG = true;
+      hideTitle = true;
       coinlogo = 'JUMBLR';
       coinname = 'JUMBLR';
       break;
@@ -124,6 +137,9 @@ export function getCoinTitle(coin) {
       coinname = 'MultiGateway';
       break;
     case 'MVP':
+      hideTitle = true;
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'MVP';
       coinname = 'MVP Lineup';
       break;
@@ -132,138 +148,197 @@ export function getCoinTitle(coin) {
       coinname = 'KV';
       break;
     case 'CEAL':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'CEAL';
       coinname = 'CEAL NET';
       break;
+    case 'COQUI':
+      coinlogo = 'COQUI';
+      coinname = 'COQUI';
+      break;
     case 'MESH':
+      hideTitle = true;
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'MESH';
       coinname = 'SpaceMesh';
       break;
     case 'USD':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'usd';
       coinname = 'US Dollar';
       break;
     case 'RON':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'RON';
       coinname = 'Romanian Leu';
       break;
     case 'EUR':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'EUR';
       coinname = 'Euro';
       break;
     case 'JPY':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'JPY';
       coinname = 'Japanese Yen';
       break;
     case 'GBP':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'GBP';
       coinname = 'British Pound';
       break;
     case 'AUD':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'AUD';
       coinname = 'Australian Dollar';
       break;
     case 'CAD':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'CAD';
       coinname = 'Canadian Dollar';
       break;
     case 'CHF':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'CHF';
       coinname = 'Swiss Franc';
       break;
     case 'NZD':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'NZD';
       coinname = 'New Zealand Dollar';
       break;
     case 'CNY':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'CNY';
       coinname = 'Chinese Yuan';
       break;
     case 'RUB':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'RUB';
       coinname = 'Russian Ruble';
       break;
     case 'MXN':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'MXN';
       coinname = 'Mexican peso';
       break;
     case 'BRL':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'BRL';
       coinname = 'Brazilian Real';
       break;
     case 'INR':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'INR';
       coinname = 'Indian Rupee';
       break;
     case 'HKD':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'HKD';
       coinname = 'Hong Kong Dollar';
       break;
     case 'TRY':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'TRY';
       coinname = 'Turkish Lira';
       break;
     case 'ZAR':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'ZAR';
       coinname = 'South African Rand';
       break;
     case 'PLN':
+      titleBG = true;
+      transparentBG = true;
       coinlogo = 'PLN';
       coinname = 'Polish Zloty';
       break;
     case 'NOK':
+      titleBG = true;
       coinlogo = 'NOK';
       coinname = 'Norwegian Krone';
       break;
     case 'SEK':
+      titleBG = true;
       coinlogo = 'SEK';
       coinname = 'Swedish Krona';
       break;
     case 'DKK':
+      titleBG = true;
       coinlogo = 'DKK';
       coinname = 'Danish Krone';
       break;
     case 'CZK':
+      titleBG = true;
       coinlogo = 'CZK';
       coinname = 'Czech Koruna';
       break;
     case 'HUF':
+      titleBG = true;
       coinlogo = 'HUF';
       coinname = 'Hungarian Forint';
       break;
     case 'ILS':
+      titleBG = true;
       coinlogo = 'ILS';
       coinname = 'Israeli Shekel';
       break;
     case 'KRW':
+      titleBG = true;
       coinlogo = 'KRW';
       coinname = 'Korean Won';
       break;
     case 'MYR':
+      titleBG = true;
       coinlogo = 'MYR';
       coinname = 'Malaysian Ringgit';
       break;
     case 'PHP':
+      titleBG = true;
       coinlogo = 'PHP';
       coinname = 'Philippine Peso';
       break;
     case 'SGD':
+      titleBG = true;
       coinlogo = 'SGD';
       coinname = 'Singapore Dollar';
       break;
     case 'THB':
+      titleBG = true;
       coinlogo = 'THB';
       coinname = 'Thai Baht';
       break;
     case 'BGN':
+      titleBG = true;
       coinlogo = 'BGN';
       coinname = 'Bulgarian Lev';
       break;
     case 'IDR':
+      titleBG = true;
       coinlogo = 'IDR';
       coinname = 'Indonesian Rupiah';
       break;
     case 'HRK':
+      titleBG = true;
       coinlogo = 'HRK';
       coinname = 'Croatian Kuna';
       break;
@@ -271,14 +346,16 @@ export function getCoinTitle(coin) {
 
   return {
     'logo': coinlogo,
-    'name': coinname
+    'name': coinname,
+    titleBG,
+    transparentBG,
   };
 }
 
 export function getModeInfo(mode) {
-  let modecode,
-      modetip,
-      modecolor;
+  let modecode;
+  let modetip;
+  let modecolor;
 
   switch (mode) {
     case 'native':
diff --git a/react/src/util/crypto/gen/array.map.js b/react/src/util/crypto/gen/array.map.js
new file mode 100755
index 0000000..d1b362f
--- /dev/null
+++ b/react/src/util/crypto/gen/array.map.js
@@ -0,0 +1,57 @@
+// Array.prototype.map function is in the public domain.
+// Production steps of ECMA-262, Edition 5, 15.4.4.19  
+// Reference: http://es5.github.com/#x15.4.4.19  
+if (!Array.prototype.map) {
+	Array.prototype.map = function (callback, thisArg) {
+		var T, A, k;
+		if (this == null) {
+			throw new TypeError(" this is null or not defined");
+		}
+		// 1. Let O be the result of calling ToObject passing the |this| value as the argument.  
+		var O = Object(this);
+		// 2. Let lenValue be the result of calling the Get internal method of O with the argument "length".  
+		// 3. Let len be ToUint32(lenValue).  
+		var len = O.length >>> 0;
+		// 4. If IsCallable(callback) is false, throw a TypeError exception.  
+		// See: http://es5.github.com/#x9.11  
+		if ({}.toString.call(callback) != "[object Function]") {
+			throw new TypeError(callback + " is not a function");
+		}
+		// 5. If thisArg was supplied, let T be thisArg; else let T be undefined.  
+		if (thisArg) {
+			T = thisArg;
+		}
+		// 6. Let A be a new array created as if by the expression new Array(len) where Array is  
+		// the standard built-in constructor with that name and len is the value of len.  
+		A = new Array(len);
+		// 7. Let k be 0  
+		k = 0;
+		// 8. Repeat, while k < len  
+		while (k < len) {
+			var kValue, mappedValue;
+			// a. Let Pk be ToString(k).  
+			//   This is implicit for LHS operands of the in operator  
+			// b. Let kPresent be the result of calling the HasProperty internal method of O with argument Pk.  
+			//   This step can be combined with c  
+			// c. If kPresent is true, then  
+			if (k in O) {
+				// i. Let kValue be the result of calling the Get internal method of O with argument Pk.  
+				kValue = O[k];
+				// ii. Let mappedValue be the result of calling the Call internal method of callback  
+				// with T as the this value and argument list containing kValue, k, and O.  
+				mappedValue = callback.call(T, kValue, k, O);
+				// iii. Call the DefineOwnProperty internal method of A with arguments  
+				// Pk, Property Descriptor {Value: mappedValue, Writable: true, Enumerable: true, Configurable: true},  
+				// and false.  
+				// In browsers that support Object.defineProperty, use the following:  
+				// Object.defineProperty(A, Pk, { value: mappedValue, writable: true, enumerable: true, configurable: true });  
+				// For best browser support, use the following:  
+				A[k] = mappedValue;
+			}
+			// d. Increase k by 1.  
+			k++;
+		}
+		// 9. return A  
+		return A;
+	};
+}
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/biginteger.js b/react/src/util/crypto/gen/biginteger.js
new file mode 100755
index 0000000..4d9c4ef
--- /dev/null
+++ b/react/src/util/crypto/gen/biginteger.js
@@ -0,0 +1,1271 @@
+/*!
+* Basic JavaScript BN library - subset useful for RSA encryption. v1.3
+* 
+* Copyright (c) 2005  Tom Wu
+* All Rights Reserved.
+* BSD License
+* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
+*
+* Copyright Stephan Thomas
+* Copyright bitaddress.org
+*/
+
+(function () {
+
+	// (public) Constructor function of Global BigInteger object
+	var BigInteger = window.BigInteger = function BigInteger(a, b, c) {
+		if (a != null)
+			if ("number" == typeof a) this.fromNumber(a, b, c);
+			else if (b == null && "string" != typeof a) this.fromString(a, 256);
+			else this.fromString(a, b);
+	};
+
+	// Bits per digit
+	var dbits;
+
+	// JavaScript engine analysis
+	var canary = 0xdeadbeefcafe;
+	var j_lm = ((canary & 0xffffff) == 0xefcafe);
+
+	// return new, unset BigInteger
+	function nbi() { return new BigInteger(null); }
+
+	// am: Compute w_j += (x*this_i), propagate carries,
+	// c is initial carry, returns final carry.
+	// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+	// We need to select the fastest one that works in this environment.
+
+	// am1: use a single mult and divide to get the high bits,
+	// max digit bits should be 26 because
+	// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+	function am1(i, x, w, j, c, n) {
+		while (--n >= 0) {
+			var v = x * this[i++] + w[j] + c;
+			c = Math.floor(v / 0x4000000);
+			w[j++] = v & 0x3ffffff;
+		}
+		return c;
+	}
+	// am2 avoids a big mult-and-extract completely.
+	// Max digit bits should be <= 30 because we do bitwise ops
+	// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+	function am2(i, x, w, j, c, n) {
+		var xl = x & 0x7fff, xh = x >> 15;
+		while (--n >= 0) {
+			var l = this[i] & 0x7fff;
+			var h = this[i++] >> 15;
+			var m = xh * l + h * xl;
+			l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
+			c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
+			w[j++] = l & 0x3fffffff;
+		}
+		return c;
+	}
+	// Alternately, set max digit bits to 28 since some
+	// browsers slow down when dealing with 32-bit numbers.
+	function am3(i, x, w, j, c, n) {
+		var xl = x & 0x3fff, xh = x >> 14;
+		while (--n >= 0) {
+			var l = this[i] & 0x3fff;
+			var h = this[i++] >> 14;
+			var m = xh * l + h * xl;
+			l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
+			c = (l >> 28) + (m >> 14) + xh * h;
+			w[j++] = l & 0xfffffff;
+		}
+		return c;
+	}
+	if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+		BigInteger.prototype.am = am2;
+		dbits = 30;
+	}
+	else if (j_lm && (navigator.appName != "Netscape")) {
+		BigInteger.prototype.am = am1;
+		dbits = 26;
+	}
+	else { // Mozilla/Netscape seems to prefer am3
+		BigInteger.prototype.am = am3;
+		dbits = 28;
+	}
+
+	BigInteger.prototype.DB = dbits;
+	BigInteger.prototype.DM = ((1 << dbits) - 1);
+	BigInteger.prototype.DV = (1 << dbits);
+
+	var BI_FP = 52;
+	BigInteger.prototype.FV = Math.pow(2, BI_FP);
+	BigInteger.prototype.F1 = BI_FP - dbits;
+	BigInteger.prototype.F2 = 2 * dbits - BI_FP;
+
+	// Digit conversions
+	var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+	var BI_RC = new Array();
+	var rr, vv;
+	rr = "0".charCodeAt(0);
+	for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+	rr = "a".charCodeAt(0);
+	for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+	rr = "A".charCodeAt(0);
+	for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+	function int2char(n) { return BI_RM.charAt(n); }
+	function intAt(s, i) {
+		var c = BI_RC[s.charCodeAt(i)];
+		return (c == null) ? -1 : c;
+	}
+
+
+
+	// return bigint initialized to value
+	function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+
+	// returns bit length of the integer x
+	function nbits(x) {
+		var r = 1, t;
+		if ((t = x >>> 16) != 0) { x = t; r += 16; }
+		if ((t = x >> 8) != 0) { x = t; r += 8; }
+		if ((t = x >> 4) != 0) { x = t; r += 4; }
+		if ((t = x >> 2) != 0) { x = t; r += 2; }
+		if ((t = x >> 1) != 0) { x = t; r += 1; }
+		return r;
+	}
+
+
+
+
+
+
+
+	// (protected) copy this to r
+	BigInteger.prototype.copyTo = function (r) {
+		for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
+		r.t = this.t;
+		r.s = this.s;
+	};
+
+
+	// (protected) set from integer value x, -DV <= x < DV
+	BigInteger.prototype.fromInt = function (x) {
+		this.t = 1;
+		this.s = (x < 0) ? -1 : 0;
+		if (x > 0) this[0] = x;
+		else if (x < -1) this[0] = x + this.DV;
+		else this.t = 0;
+	};
+
+	// (protected) set from string and radix
+	BigInteger.prototype.fromString = function (s, b) {
+		var k;
+		if (b == 16) k = 4;
+		else if (b == 8) k = 3;
+		else if (b == 256) k = 8; // byte array
+		else if (b == 2) k = 1;
+		else if (b == 32) k = 5;
+		else if (b == 4) k = 2;
+		else { this.fromRadix(s, b); return; }
+		this.t = 0;
+		this.s = 0;
+		var i = s.length, mi = false, sh = 0;
+		while (--i >= 0) {
+			var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
+			if (x < 0) {
+				if (s.charAt(i) == "-") mi = true;
+				continue;
+			}
+			mi = false;
+			if (sh == 0)
+				this[this.t++] = x;
+			else if (sh + k > this.DB) {
+				this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
+				this[this.t++] = (x >> (this.DB - sh));
+			}
+			else
+				this[this.t - 1] |= x << sh;
+			sh += k;
+			if (sh >= this.DB) sh -= this.DB;
+		}
+		if (k == 8 && (s[0] & 0x80) != 0) {
+			this.s = -1;
+			if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
+		}
+		this.clamp();
+		if (mi) BigInteger.ZERO.subTo(this, this);
+	};
+
+
+	// (protected) clamp off excess high words
+	BigInteger.prototype.clamp = function () {
+		var c = this.s & this.DM;
+		while (this.t > 0 && this[this.t - 1] == c) --this.t;
+	};
+
+	// (protected) r = this << n*DB
+	BigInteger.prototype.dlShiftTo = function (n, r) {
+		var i;
+		for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
+		for (i = n - 1; i >= 0; --i) r[i] = 0;
+		r.t = this.t + n;
+		r.s = this.s;
+	};
+
+	// (protected) r = this >> n*DB
+	BigInteger.prototype.drShiftTo = function (n, r) {
+		for (var i = n; i < this.t; ++i) r[i - n] = this[i];
+		r.t = Math.max(this.t - n, 0);
+		r.s = this.s;
+	};
+
+
+	// (protected) r = this << n
+	BigInteger.prototype.lShiftTo = function (n, r) {
+		var bs = n % this.DB;
+		var cbs = this.DB - bs;
+		var bm = (1 << cbs) - 1;
+		var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i;
+		for (i = this.t - 1; i >= 0; --i) {
+			r[i + ds + 1] = (this[i] >> cbs) | c;
+			c = (this[i] & bm) << bs;
+		}
+		for (i = ds - 1; i >= 0; --i) r[i] = 0;
+		r[ds] = c;
+		r.t = this.t + ds + 1;
+		r.s = this.s;
+		r.clamp();
+	};
+
+
+	// (protected) r = this >> n
+	BigInteger.prototype.rShiftTo = function (n, r) {
+		r.s = this.s;
+		var ds = Math.floor(n / this.DB);
+		if (ds >= this.t) { r.t = 0; return; }
+		var bs = n % this.DB;
+		var cbs = this.DB - bs;
+		var bm = (1 << bs) - 1;
+		r[0] = this[ds] >> bs;
+		for (var i = ds + 1; i < this.t; ++i) {
+			r[i - ds - 1] |= (this[i] & bm) << cbs;
+			r[i - ds] = this[i] >> bs;
+		}
+		if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
+		r.t = this.t - ds;
+		r.clamp();
+	};
+
+
+	// (protected) r = this - a
+	BigInteger.prototype.subTo = function (a, r) {
+		var i = 0, c = 0, m = Math.min(a.t, this.t);
+		while (i < m) {
+			c += this[i] - a[i];
+			r[i++] = c & this.DM;
+			c >>= this.DB;
+		}
+		if (a.t < this.t) {
+			c -= a.s;
+			while (i < this.t) {
+				c += this[i];
+				r[i++] = c & this.DM;
+				c >>= this.DB;
+			}
+			c += this.s;
+		}
+		else {
+			c += this.s;
+			while (i < a.t) {
+				c -= a[i];
+				r[i++] = c & this.DM;
+				c >>= this.DB;
+			}
+			c -= a.s;
+		}
+		r.s = (c < 0) ? -1 : 0;
+		if (c < -1) r[i++] = this.DV + c;
+		else if (c > 0) r[i++] = c;
+		r.t = i;
+		r.clamp();
+	};
+
+
+	// (protected) r = this * a, r != this,a (HAC 14.12)
+	// "this" should be the larger one if appropriate.
+	BigInteger.prototype.multiplyTo = function (a, r) {
+		var x = this.abs(), y = a.abs();
+		var i = x.t;
+		r.t = i + y.t;
+		while (--i >= 0) r[i] = 0;
+		for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
+		r.s = 0;
+		r.clamp();
+		if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
+	};
+
+
+	// (protected) r = this^2, r != this (HAC 14.16)
+	BigInteger.prototype.squareTo = function (r) {
+		var x = this.abs();
+		var i = r.t = 2 * x.t;
+		while (--i >= 0) r[i] = 0;
+		for (i = 0; i < x.t - 1; ++i) {
+			var c = x.am(i, x[i], r, 2 * i, 0, 1);
+			if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
+				r[i + x.t] -= x.DV;
+				r[i + x.t + 1] = 1;
+			}
+		}
+		if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
+		r.s = 0;
+		r.clamp();
+	};
+
+
+
+	// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+	// r != q, this != m.  q or r may be null.
+	BigInteger.prototype.divRemTo = function (m, q, r) {
+		var pm = m.abs();
+		if (pm.t <= 0) return;
+		var pt = this.abs();
+		if (pt.t < pm.t) {
+			if (q != null) q.fromInt(0);
+			if (r != null) this.copyTo(r);
+			return;
+		}
+		if (r == null) r = nbi();
+		var y = nbi(), ts = this.s, ms = m.s;
+		var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
+		if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); }
+		else { pm.copyTo(y); pt.copyTo(r); }
+		var ys = y.t;
+		var y0 = y[ys - 1];
+		if (y0 == 0) return;
+		var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
+		var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
+		var i = r.t, j = i - ys, t = (q == null) ? nbi() : q;
+		y.dlShiftTo(j, t);
+		if (r.compareTo(t) >= 0) {
+			r[r.t++] = 1;
+			r.subTo(t, r);
+		}
+		BigInteger.ONE.dlShiftTo(ys, t);
+		t.subTo(y, y); // "negative" y so we can replace sub with am later
+		while (y.t < ys) y[y.t++] = 0;
+		while (--j >= 0) {
+			// Estimate quotient digit
+			var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
+			if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {	// Try it out
+				y.dlShiftTo(j, t);
+				r.subTo(t, r);
+				while (r[i] < --qd) r.subTo(t, r);
+			}
+		}
+		if (q != null) {
+			r.drShiftTo(ys, q);
+			if (ts != ms) BigInteger.ZERO.subTo(q, q);
+		}
+		r.t = ys;
+		r.clamp();
+		if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
+		if (ts < 0) BigInteger.ZERO.subTo(r, r);
+	};
+
+
+	// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+	// justification:
+	//         xy == 1 (mod m)
+	//         xy =  1+km
+	//   xy(2-xy) = (1+km)(1-km)
+	// x[y(2-xy)] = 1-k^2m^2
+	// x[y(2-xy)] == 1 (mod m^2)
+	// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+	// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+	// JS multiply "overflows" differently from C/C++, so care is needed here.
+	BigInteger.prototype.invDigit = function () {
+		if (this.t < 1) return 0;
+		var x = this[0];
+		if ((x & 1) == 0) return 0;
+		var y = x & 3; 	// y == 1/x mod 2^2
+		y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+		y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+		y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+		// last step - calculate inverse mod DV directly;
+		// assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+		y = (y * (2 - x * y % this.DV)) % this.DV; 	// y == 1/x mod 2^dbits
+		// we really want the negative inverse, and -DV < y < DV
+		return (y > 0) ? this.DV - y : -y;
+	};
+
+
+	// (protected) true iff this is even
+	BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; };
+
+
+	// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+	BigInteger.prototype.exp = function (e, z) {
+		if (e > 0xffffffff || e < 1) return BigInteger.ONE;
+		var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
+		g.copyTo(r);
+		while (--i >= 0) {
+			z.sqrTo(r, r2);
+			if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
+			else { var t = r; r = r2; r2 = t; }
+		}
+		return z.revert(r);
+	};
+
+
+	// (public) return string representation in given radix
+	BigInteger.prototype.toString = function (b) {
+		if (this.s < 0) return "-" + this.negate().toString(b);
+		var k;
+		if (b == 16) k = 4;
+		else if (b == 8) k = 3;
+		else if (b == 2) k = 1;
+		else if (b == 32) k = 5;
+		else if (b == 4) k = 2;
+		else return this.toRadix(b);
+		var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
+		var p = this.DB - (i * this.DB) % k;
+		if (i-- > 0) {
+			if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); }
+			while (i >= 0) {
+				if (p < k) {
+					d = (this[i] & ((1 << p) - 1)) << (k - p);
+					d |= this[--i] >> (p += this.DB - k);
+				}
+				else {
+					d = (this[i] >> (p -= k)) & km;
+					if (p <= 0) { p += this.DB; --i; }
+				}
+				if (d > 0) m = true;
+				if (m) r += int2char(d);
+			}
+		}
+		return m ? r : "0";
+	};
+
+
+	// (public) -this
+	BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; };
+
+	// (public) |this|
+	BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; };
+
+	// (public) return + if this > a, - if this < a, 0 if equal
+	BigInteger.prototype.compareTo = function (a) {
+		var r = this.s - a.s;
+		if (r != 0) return r;
+		var i = this.t;
+		r = i - a.t;
+		if (r != 0) return (this.s < 0) ? -r : r;
+		while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
+		return 0;
+	}
+
+	// (public) return the number of bits in "this"
+	BigInteger.prototype.bitLength = function () {
+		if (this.t <= 0) return 0;
+		return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
+	};
+
+	// (public) this mod a
+	BigInteger.prototype.mod = function (a) {
+		var r = nbi();
+		this.abs().divRemTo(a, null, r);
+		if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
+		return r;
+	}
+
+	// (public) this^e % m, 0 <= e < 2^32
+	BigInteger.prototype.modPowInt = function (e, m) {
+		var z;
+		if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+		return this.exp(e, z);
+	};
+
+	// "constants"
+	BigInteger.ZERO = nbv(0);
+	BigInteger.ONE = nbv(1);
+
+
+
+
+
+
+
+	// Copyright (c) 2005-2009  Tom Wu
+	// All Rights Reserved.
+	// See "LICENSE" for details.
+	// Extended JavaScript BN functions, required for RSA private ops.
+	// Version 1.1: new BigInteger("0", 10) returns "proper" zero
+	// Version 1.2: square() API, isProbablePrime fix
+
+
+	// return index of lowest 1-bit in x, x < 2^31
+	function lbit(x) {
+		if (x == 0) return -1;
+		var r = 0;
+		if ((x & 0xffff) == 0) { x >>= 16; r += 16; }
+		if ((x & 0xff) == 0) { x >>= 8; r += 8; }
+		if ((x & 0xf) == 0) { x >>= 4; r += 4; }
+		if ((x & 3) == 0) { x >>= 2; r += 2; }
+		if ((x & 1) == 0) ++r;
+		return r;
+	}
+
+	// return number of 1 bits in x
+	function cbit(x) {
+		var r = 0;
+		while (x != 0) { x &= x - 1; ++r; }
+		return r;
+	}
+
+	var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+	var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
+
+
+
+	// (protected) return x s.t. r^x < DV
+	BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); };
+
+	// (protected) convert to radix string
+	BigInteger.prototype.toRadix = function (b) {
+		if (b == null) b = 10;
+		if (this.signum() == 0 || b < 2 || b > 36) return "0";
+		var cs = this.chunkSize(b);
+		var a = Math.pow(b, cs);
+		var d = nbv(a), y = nbi(), z = nbi(), r = "";
+		this.divRemTo(d, y, z);
+		while (y.signum() > 0) {
+			r = (a + z.intValue()).toString(b).substr(1) + r;
+			y.divRemTo(d, y, z);
+		}
+		return z.intValue().toString(b) + r;
+	};
+
+	// (protected) convert from radix string
+	BigInteger.prototype.fromRadix = function (s, b) {
+		this.fromInt(0);
+		if (b == null) b = 10;
+		var cs = this.chunkSize(b);
+		var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
+		for (var i = 0; i < s.length; ++i) {
+			var x = intAt(s, i);
+			if (x < 0) {
+				if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
+				continue;
+			}
+			w = b * w + x;
+			if (++j >= cs) {
+				this.dMultiply(d);
+				this.dAddOffset(w, 0);
+				j = 0;
+				w = 0;
+			}
+		}
+		if (j > 0) {
+			this.dMultiply(Math.pow(b, j));
+			this.dAddOffset(w, 0);
+		}
+		if (mi) BigInteger.ZERO.subTo(this, this);
+	};
+
+	// (protected) alternate constructor
+	BigInteger.prototype.fromNumber = function (a, b, c) {
+		if ("number" == typeof b) {
+			// new BigInteger(int,int,RNG)
+			if (a < 2) this.fromInt(1);
+			else {
+				this.fromNumber(a, c);
+				if (!this.testBit(a - 1))	// force MSB set
+					this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+				if (this.isEven()) this.dAddOffset(1, 0); // force odd
+				while (!this.isProbablePrime(b)) {
+					this.dAddOffset(2, 0);
+					if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
+				}
+			}
+		}
+		else {
+			// new BigInteger(int,RNG)
+			var x = new Array(), t = a & 7;
+			x.length = (a >> 3) + 1;
+			b.nextBytes(x);
+			if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0;
+			this.fromString(x, 256);
+		}
+	};
+
+	// (protected) r = this op a (bitwise)
+	BigInteger.prototype.bitwiseTo = function (a, op, r) {
+		var i, f, m = Math.min(a.t, this.t);
+		for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);
+		if (a.t < this.t) {
+			f = a.s & this.DM;
+			for (i = m; i < this.t; ++i) r[i] = op(this[i], f);
+			r.t = this.t;
+		}
+		else {
+			f = this.s & this.DM;
+			for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);
+			r.t = a.t;
+		}
+		r.s = op(this.s, a.s);
+		r.clamp();
+	};
+
+	// (protected) this op (1<<n)
+	BigInteger.prototype.changeBit = function (n, op) {
+		var r = BigInteger.ONE.shiftLeft(n);
+		this.bitwiseTo(r, op, r);
+		return r;
+	};
+
+	// (protected) r = this + a
+	BigInteger.prototype.addTo = function (a, r) {
+		var i = 0, c = 0, m = Math.min(a.t, this.t);
+		while (i < m) {
+			c += this[i] + a[i];
+			r[i++] = c & this.DM;
+			c >>= this.DB;
+		}
+		if (a.t < this.t) {
+			c += a.s;
+			while (i < this.t) {
+				c += this[i];
+				r[i++] = c & this.DM;
+				c >>= this.DB;
+			}
+			c += this.s;
+		}
+		else {
+			c += this.s;
+			while (i < a.t) {
+				c += a[i];
+				r[i++] = c & this.DM;
+				c >>= this.DB;
+			}
+			c += a.s;
+		}
+		r.s = (c < 0) ? -1 : 0;
+		if (c > 0) r[i++] = c;
+		else if (c < -1) r[i++] = this.DV + c;
+		r.t = i;
+		r.clamp();
+	};
+
+	// (protected) this *= n, this >= 0, 1 < n < DV
+	BigInteger.prototype.dMultiply = function (n) {
+		this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
+		++this.t;
+		this.clamp();
+	};
+
+	// (protected) this += n << w words, this >= 0
+	BigInteger.prototype.dAddOffset = function (n, w) {
+		if (n == 0) return;
+		while (this.t <= w) this[this.t++] = 0;
+		this[w] += n;
+		while (this[w] >= this.DV) {
+			this[w] -= this.DV;
+			if (++w >= this.t) this[this.t++] = 0;
+			++this[w];
+		}
+	};
+
+	// (protected) r = lower n words of "this * a", a.t <= n
+	// "this" should be the larger one if appropriate.
+	BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
+		var i = Math.min(this.t + a.t, n);
+		r.s = 0; // assumes a,this >= 0
+		r.t = i;
+		while (i > 0) r[--i] = 0;
+		var j;
+		for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
+		for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);
+		r.clamp();
+	};
+
+
+	// (protected) r = "this * a" without lower n words, n > 0
+	// "this" should be the larger one if appropriate.
+	BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
+		--n;
+		var i = r.t = this.t + a.t - n;
+		r.s = 0; // assumes a,this >= 0
+		while (--i >= 0) r[i] = 0;
+		for (i = Math.max(n - this.t, 0); i < a.t; ++i)
+			r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
+		r.clamp();
+		r.drShiftTo(1, r);
+	};
+
+	// (protected) this % n, n < 2^26
+	BigInteger.prototype.modInt = function (n) {
+		if (n <= 0) return 0;
+		var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0;
+		if (this.t > 0)
+			if (d == 0) r = this[0] % n;
+			else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
+		return r;
+	};
+
+
+	// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+	BigInteger.prototype.millerRabin = function (t) {
+		var n1 = this.subtract(BigInteger.ONE);
+		var k = n1.getLowestSetBit();
+		if (k <= 0) return false;
+		var r = n1.shiftRight(k);
+		t = (t + 1) >> 1;
+		if (t > lowprimes.length) t = lowprimes.length;
+		var a = nbi();
+		for (var i = 0; i < t; ++i) {
+			//Pick bases at random, instead of starting at 2
+			a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
+			var y = a.modPow(r, this);
+			if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+				var j = 1;
+				while (j++ < k && y.compareTo(n1) != 0) {
+					y = y.modPowInt(2, this);
+					if (y.compareTo(BigInteger.ONE) == 0) return false;
+				}
+				if (y.compareTo(n1) != 0) return false;
+			}
+		}
+		return true;
+	};
+
+
+
+	// (public)
+	BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; };
+
+	// (public) return value as integer
+	BigInteger.prototype.intValue = function () {
+		if (this.s < 0) {
+			if (this.t == 1) return this[0] - this.DV;
+			else if (this.t == 0) return -1;
+		}
+		else if (this.t == 1) return this[0];
+		else if (this.t == 0) return 0;
+		// assumes 16 < DB < 32
+		return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
+	};
+
+
+	// (public) return value as byte
+	BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; };
+
+	// (public) return value as short (assumes DB>=16)
+	BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; };
+
+	// (public) 0 if this == 0, 1 if this > 0
+	BigInteger.prototype.signum = function () {
+		if (this.s < 0) return -1;
+		else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+		else return 1;
+	};
+
+
+	// (public) convert to bigendian byte array
+	BigInteger.prototype.toByteArray = function () {
+		var i = this.t, r = new Array();
+		r[0] = this.s;
+		var p = this.DB - (i * this.DB) % 8, d, k = 0;
+		if (i-- > 0) {
+			if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p)
+				r[k++] = d | (this.s << (this.DB - p));
+			while (i >= 0) {
+				if (p < 8) {
+					d = (this[i] & ((1 << p) - 1)) << (8 - p);
+					d |= this[--i] >> (p += this.DB - 8);
+				}
+				else {
+					d = (this[i] >> (p -= 8)) & 0xff;
+					if (p <= 0) { p += this.DB; --i; }
+				}
+				if ((d & 0x80) != 0) d |= -256;
+				if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
+				if (k > 0 || d != this.s) r[k++] = d;
+			}
+		}
+		return r;
+	};
+
+	BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); };
+	BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; };
+	BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; };
+
+	// (public) this & a
+	function op_and(x, y) { return x & y; }
+	BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; };
+
+	// (public) this | a
+	function op_or(x, y) { return x | y; }
+	BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; };
+
+	// (public) this ^ a
+	function op_xor(x, y) { return x ^ y; }
+	BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; };
+
+	// (public) this & ~a
+	function op_andnot(x, y) { return x & ~y; }
+	BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; };
+
+	// (public) ~this
+	BigInteger.prototype.not = function () {
+		var r = nbi();
+		for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];
+		r.t = this.t;
+		r.s = ~this.s;
+		return r;
+	};
+
+	// (public) this << n
+	BigInteger.prototype.shiftLeft = function (n) {
+		var r = nbi();
+		if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r);
+		return r;
+	};
+
+	// (public) this >> n
+	BigInteger.prototype.shiftRight = function (n) {
+		var r = nbi();
+		if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r);
+		return r;
+	};
+
+	// (public) returns index of lowest 1-bit (or -1 if none)
+	BigInteger.prototype.getLowestSetBit = function () {
+		for (var i = 0; i < this.t; ++i)
+			if (this[i] != 0) return i * this.DB + lbit(this[i]);
+		if (this.s < 0) return this.t * this.DB;
+		return -1;
+	};
+
+	// (public) return number of set bits
+	BigInteger.prototype.bitCount = function () {
+		var r = 0, x = this.s & this.DM;
+		for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);
+		return r;
+	};
+
+	// (public) true iff nth bit is set
+	BigInteger.prototype.testBit = function (n) {
+		var j = Math.floor(n / this.DB);
+		if (j >= this.t) return (this.s != 0);
+		return ((this[j] & (1 << (n % this.DB))) != 0);
+	};
+
+	// (public) this | (1<<n)
+	BigInteger.prototype.setBit = function (n) { return this.changeBit(n, op_or); };
+	// (public) this & ~(1<<n)
+	BigInteger.prototype.clearBit = function (n) { return this.changeBit(n, op_andnot); };
+	// (public) this ^ (1<<n)
+	BigInteger.prototype.flipBit = function (n) { return this.changeBit(n, op_xor); };
+	// (public) this + a
+	BigInteger.prototype.add = function (a) { var r = nbi(); this.addTo(a, r); return r; };
+	// (public) this - a
+	BigInteger.prototype.subtract = function (a) { var r = nbi(); this.subTo(a, r); return r; };
+	// (public) this * a
+	BigInteger.prototype.multiply = function (a) { var r = nbi(); this.multiplyTo(a, r); return r; };
+	// (public) this / a
+	BigInteger.prototype.divide = function (a) { var r = nbi(); this.divRemTo(a, r, null); return r; };
+	// (public) this % a
+	BigInteger.prototype.remainder = function (a) { var r = nbi(); this.divRemTo(a, null, r); return r; };
+	// (public) [this/a,this%a]
+	BigInteger.prototype.divideAndRemainder = function (a) {
+		var q = nbi(), r = nbi();
+		this.divRemTo(a, q, r);
+		return new Array(q, r);
+	};
+
+	// (public) this^e % m (HAC 14.85)
+	BigInteger.prototype.modPow = function (e, m) {
+		var i = e.bitLength(), k, r = nbv(1), z;
+		if (i <= 0) return r;
+		else if (i < 18) k = 1;
+		else if (i < 48) k = 3;
+		else if (i < 144) k = 4;
+		else if (i < 768) k = 5;
+		else k = 6;
+		if (i < 8)
+			z = new Classic(m);
+		else if (m.isEven())
+			z = new Barrett(m);
+		else
+			z = new Montgomery(m);
+
+		// precomputation
+		var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
+		g[1] = z.convert(this);
+		if (k > 1) {
+			var g2 = nbi();
+			z.sqrTo(g[1], g2);
+			while (n <= km) {
+				g[n] = nbi();
+				z.mulTo(g2, g[n - 2], g[n]);
+				n += 2;
+			}
+		}
+
+		var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
+		i = nbits(e[j]) - 1;
+		while (j >= 0) {
+			if (i >= k1) w = (e[j] >> (i - k1)) & km;
+			else {
+				w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+				if (j > 0) w |= e[j - 1] >> (this.DB + i - k1);
+			}
+
+			n = k;
+			while ((w & 1) == 0) { w >>= 1; --n; }
+			if ((i -= n) < 0) { i += this.DB; --j; }
+			if (is1) {	// ret == 1, don't bother squaring or multiplying it
+				g[w].copyTo(r);
+				is1 = false;
+			}
+			else {
+				while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; }
+				if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; }
+				z.mulTo(r2, g[w], r);
+			}
+
+			while (j >= 0 && (e[j] & (1 << i)) == 0) {
+				z.sqrTo(r, r2); t = r; r = r2; r2 = t;
+				if (--i < 0) { i = this.DB - 1; --j; }
+			}
+		}
+		return z.revert(r);
+	};
+
+	// (public) 1/this % m (HAC 14.61)
+	BigInteger.prototype.modInverse = function (m) {
+		var ac = m.isEven();
+		if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+		var u = m.clone(), v = this.clone();
+		var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
+		while (u.signum() != 0) {
+			while (u.isEven()) {
+				u.rShiftTo(1, u);
+				if (ac) {
+					if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); }
+					a.rShiftTo(1, a);
+				}
+				else if (!b.isEven()) b.subTo(m, b);
+				b.rShiftTo(1, b);
+			}
+			while (v.isEven()) {
+				v.rShiftTo(1, v);
+				if (ac) {
+					if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); }
+					c.rShiftTo(1, c);
+				}
+				else if (!d.isEven()) d.subTo(m, d);
+				d.rShiftTo(1, d);
+			}
+			if (u.compareTo(v) >= 0) {
+				u.subTo(v, u);
+				if (ac) a.subTo(c, a);
+				b.subTo(d, b);
+			}
+			else {
+				v.subTo(u, v);
+				if (ac) c.subTo(a, c);
+				d.subTo(b, d);
+			}
+		}
+		if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+		if (d.compareTo(m) >= 0) return d.subtract(m);
+		if (d.signum() < 0) d.addTo(m, d); else return d;
+		if (d.signum() < 0) return d.add(m); else return d;
+	};
+
+
+	// (public) this^e
+	BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); };
+
+	// (public) gcd(this,a) (HAC 14.54)
+	BigInteger.prototype.gcd = function (a) {
+		var x = (this.s < 0) ? this.negate() : this.clone();
+		var y = (a.s < 0) ? a.negate() : a.clone();
+		if (x.compareTo(y) < 0) { var t = x; x = y; y = t; }
+		var i = x.getLowestSetBit(), g = y.getLowestSetBit();
+		if (g < 0) return x;
+		if (i < g) g = i;
+		if (g > 0) {
+			x.rShiftTo(g, x);
+			y.rShiftTo(g, y);
+		}
+		while (x.signum() > 0) {
+			if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
+			if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
+			if (x.compareTo(y) >= 0) {
+				x.subTo(y, x);
+				x.rShiftTo(1, x);
+			}
+			else {
+				y.subTo(x, y);
+				y.rShiftTo(1, y);
+			}
+		}
+		if (g > 0) y.lShiftTo(g, y);
+		return y;
+	};
+
+	// (public) test primality with certainty >= 1-.5^t
+	BigInteger.prototype.isProbablePrime = function (t) {
+		var i, x = this.abs();
+		if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
+			for (i = 0; i < lowprimes.length; ++i)
+				if (x[0] == lowprimes[i]) return true;
+			return false;
+		}
+		if (x.isEven()) return false;
+		i = 1;
+		while (i < lowprimes.length) {
+			var m = lowprimes[i], j = i + 1;
+			while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+			m = x.modInt(m);
+			while (i < j) if (m % lowprimes[i++] == 0) return false;
+		}
+		return x.millerRabin(t);
+	};
+
+
+	// JSBN-specific extension
+
+	// (public) this^2
+	BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; };
+
+
+	// NOTE: BigInteger interfaces not implemented in jsbn:
+	// BigInteger(int signum, byte[] magnitude)
+	// double doubleValue()
+	// float floatValue()
+	// int hashCode()
+	// long longValue()
+	// static BigInteger valueOf(long val)
+
+
+
+	// Copyright Stephan Thomas (start) --- //
+	// https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js
+	// BigInteger monkey patching
+	BigInteger.valueOf = nbv;
+
+	/**
+	* Returns a byte array representation of the big integer.
+	*
+	* This returns the absolute of the contained value in big endian
+	* form. A value of zero results in an empty array.
+	*/
+	BigInteger.prototype.toByteArrayUnsigned = function () {
+		var ba = this.abs().toByteArray();
+		if (ba.length) {
+			if (ba[0] == 0) {
+				ba = ba.slice(1);
+			}
+			return ba.map(function (v) {
+				return (v < 0) ? v + 256 : v;
+			});
+		} else {
+			// Empty array, nothing to do
+			return ba;
+		}
+	};
+
+	/**
+	* Turns a byte array into a big integer.
+	*
+	* This function will interpret a byte array as a big integer in big
+	* endian notation and ignore leading zeros.
+	*/
+	BigInteger.fromByteArrayUnsigned = function (ba) {
+		if (!ba.length) {
+			return ba.valueOf(0);
+		} else if (ba[0] & 0x80) {
+			// Prepend a zero so the BigInteger class doesn't mistake this
+			// for a negative integer.
+			return new BigInteger([0].concat(ba));
+		} else {
+			return new BigInteger(ba);
+		}
+	};
+
+	/**
+	* Converts big integer to signed byte representation.
+	*
+	* The format for this value uses a the most significant bit as a sign
+	* bit. If the most significant bit is already occupied by the
+	* absolute value, an extra byte is prepended and the sign bit is set
+	* there.
+	*
+	* Examples:
+	*
+	*      0 =>     0x00
+	*      1 =>     0x01
+	*     -1 =>     0x81
+	*    127 =>     0x7f
+	*   -127 =>     0xff
+	*    128 =>   0x0080
+	*   -128 =>   0x8080
+	*    255 =>   0x00ff
+	*   -255 =>   0x80ff
+	*  16300 =>   0x3fac
+	* -16300 =>   0xbfac
+	*  62300 => 0x00f35c
+	* -62300 => 0x80f35c
+	*/
+	BigInteger.prototype.toByteArraySigned = function () {
+		var val = this.abs().toByteArrayUnsigned();
+		var neg = this.compareTo(BigInteger.ZERO) < 0;
+
+		if (neg) {
+			if (val[0] & 0x80) {
+				val.unshift(0x80);
+			} else {
+				val[0] |= 0x80;
+			}
+		} else {
+			if (val[0] & 0x80) {
+				val.unshift(0x00);
+			}
+		}
+
+		return val;
+	};
+
+	/**
+	* Parse a signed big integer byte representation.
+	*
+	* For details on the format please see BigInteger.toByteArraySigned.
+	*/
+	BigInteger.fromByteArraySigned = function (ba) {
+		// Check for negative value
+		if (ba[0] & 0x80) {
+			// Remove sign bit
+			ba[0] &= 0x7f;
+
+			return BigInteger.fromByteArrayUnsigned(ba).negate();
+		} else {
+			return BigInteger.fromByteArrayUnsigned(ba);
+		}
+	};
+	// Copyright Stephan Thomas (end) --- //
+
+
+
+
+	// ****** REDUCTION ******* //
+
+	// Modular reduction using "classic" algorithm
+	var Classic = window.Classic = function Classic(m) { this.m = m; }
+	Classic.prototype.convert = function (x) {
+		if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+		else return x;
+	};
+	Classic.prototype.revert = function (x) { return x; };
+	Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); };
+	Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+	Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+
+
+
+
+	// Montgomery reduction
+	var Montgomery = window.Montgomery = function Montgomery(m) {
+		this.m = m;
+		this.mp = m.invDigit();
+		this.mpl = this.mp & 0x7fff;
+		this.mph = this.mp >> 15;
+		this.um = (1 << (m.DB - 15)) - 1;
+		this.mt2 = 2 * m.t;
+	}
+	// xR mod m
+	Montgomery.prototype.convert = function (x) {
+		var r = nbi();
+		x.abs().dlShiftTo(this.m.t, r);
+		r.divRemTo(this.m, null, r);
+		if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
+		return r;
+	}
+	// x/R mod m
+	Montgomery.prototype.revert = function (x) {
+		var r = nbi();
+		x.copyTo(r);
+		this.reduce(r);
+		return r;
+	};
+	// x = x/R mod m (HAC 14.32)
+	Montgomery.prototype.reduce = function (x) {
+		while (x.t <= this.mt2)	// pad x so am has enough room later
+			x[x.t++] = 0;
+		for (var i = 0; i < this.m.t; ++i) {
+			// faster way of calculating u0 = x[i]*mp mod DV
+			var j = x[i] & 0x7fff;
+			var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
+			// use am to combine the multiply-shift-add into one call
+			j = i + this.m.t;
+			x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
+			// propagate carry
+			while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+		}
+		x.clamp();
+		x.drShiftTo(this.m.t, x);
+		if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+	};
+	// r = "xy/R mod m"; x,y != r
+	Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+	// r = "x^2/R mod m"; x != r
+	Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+
+
+
+
+	// A "null" reducer
+	var NullExp = window.NullExp = function NullExp() { }
+	NullExp.prototype.convert = function (x) { return x; };
+	NullExp.prototype.revert = function (x) { return x; };
+	NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); };
+	NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); };
+
+
+
+
+
+	// Barrett modular reduction
+	var Barrett = window.Barrett = function Barrett(m) {
+		// setup Barrett
+		this.r2 = nbi();
+		this.q3 = nbi();
+		BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
+		this.mu = this.r2.divide(m);
+		this.m = m;
+	}
+	Barrett.prototype.convert = function (x) {
+		if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
+		else if (x.compareTo(this.m) < 0) return x;
+		else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
+	};
+	Barrett.prototype.revert = function (x) { return x; };
+	// x = x mod m (HAC 14.42)
+	Barrett.prototype.reduce = function (x) {
+		x.drShiftTo(this.m.t - 1, this.r2);
+		if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); }
+		this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
+		this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
+		while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);
+		x.subTo(this.r2, x);
+		while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+	};
+	// r = x*y mod m; x,y != r
+	Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+	// r = x^2 mod m; x != r
+	Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/bitcoin.js b/react/src/util/crypto/gen/bitcoin.js
new file mode 100644
index 0000000..47dfdd5
--- /dev/null
+++ b/react/src/util/crypto/gen/bitcoin.js
@@ -0,0 +1,1974 @@
+// ----- Big Integer -----//
+// (public) Constructor function of Global BigInteger object
+var BigInteger = window.BigInteger = function BigInteger(a, b, c) {
+  if (a != null)
+    if ("number" == typeof a) this.fromNumber(a, b, c);
+    else if (b == null && "string" != typeof a) this.fromString(a, 256);
+    else this.fromString(a, b);
+};
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary & 0xffffff) == 0xefcafe);
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i, x, w, j, c, n) {
+  while (--n >= 0) {
+    var v = x * this[i++] + w[j] + c;
+    c = Math.floor(v / 0x4000000);
+    w[j++] = v & 0x3ffffff;
+  }
+  return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i, x, w, j, c, n) {
+  var xl = x & 0x7fff, xh = x >> 15;
+  while (--n >= 0) {
+    var l = this[i] & 0x7fff;
+    var h = this[i++] >> 15;
+    var m = xh * l + h * xl;
+    l = xl * l + ((m & 0x7fff) << 15) + w[j] + (c & 0x3fffffff);
+    c = (l >>> 30) + (m >>> 15) + xh * h + (c >>> 30);
+    w[j++] = l & 0x3fffffff;
+  }
+  return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i, x, w, j, c, n) {
+  var xl = x & 0x3fff, xh = x >> 14;
+  while (--n >= 0) {
+    var l = this[i] & 0x3fff;
+    var h = this[i++] >> 14;
+    var m = xh * l + h * xl;
+    l = xl * l + ((m & 0x3fff) << 14) + w[j] + c;
+    c = (l >> 28) + (m >> 14) + xh * h;
+    w[j++] = l & 0xfffffff;
+  }
+  return c;
+}
+if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+  BigInteger.prototype.am = am2;
+  dbits = 30;
+}
+else if (j_lm && (navigator.appName != "Netscape")) {
+  BigInteger.prototype.am = am1;
+  dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+  BigInteger.prototype.am = am3;
+  dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1 << dbits) - 1);
+BigInteger.prototype.DV = (1 << dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2, BI_FP);
+BigInteger.prototype.F1 = BI_FP - dbits;
+BigInteger.prototype.F2 = 2 * dbits - BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr, vv;
+rr = "0".charCodeAt(0);
+for (vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for (vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s, i) {
+  var c = BI_RC[s.charCodeAt(i)];
+  return (c == null) ? -1 : c;
+}
+
+
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+
+// returns bit length of the integer x
+function nbits(x) {
+  var r = 1, t;
+  if ((t = x >>> 16) != 0) { x = t; r += 16; }
+  if ((t = x >> 8) != 0) { x = t; r += 8; }
+  if ((t = x >> 4) != 0) { x = t; r += 4; }
+  if ((t = x >> 2) != 0) { x = t; r += 2; }
+  if ((t = x >> 1) != 0) { x = t; r += 1; }
+  return r;
+}
+
+// (protected) copy this to r
+BigInteger.prototype.copyTo = function (r) {
+  for (var i = this.t - 1; i >= 0; --i) r[i] = this[i];
+  r.t = this.t;
+  r.s = this.s;
+};
+
+// (protected) set from integer value x, -DV <= x < DV
+BigInteger.prototype.fromInt = function (x) {
+  this.t = 1;
+  this.s = (x < 0) ? -1 : 0;
+  if (x > 0) this[0] = x;
+  else if (x < -1) this[0] = x + this.DV;
+  else this.t = 0;
+};
+
+// (protected) set from string and radix
+BigInteger.prototype.fromString = function (s, b) {
+  var k;
+  if (b == 16) k = 4;
+  else if (b == 8) k = 3;
+  else if (b == 256) k = 8; // byte array
+  else if (b == 2) k = 1;
+  else if (b == 32) k = 5;
+  else if (b == 4) k = 2;
+  else { this.fromRadix(s, b); return; }
+  this.t = 0;
+  this.s = 0;
+  var i = s.length, mi = false, sh = 0;
+  while (--i >= 0) {
+    var x = (k == 8) ? s[i] & 0xff : intAt(s, i);
+    if (x < 0) {
+      if (s.charAt(i) == "-") mi = true;
+      continue;
+    }
+    mi = false;
+    if (sh == 0)
+      this[this.t++] = x;
+    else if (sh + k > this.DB) {
+      this[this.t - 1] |= (x & ((1 << (this.DB - sh)) - 1)) << sh;
+      this[this.t++] = (x >> (this.DB - sh));
+    }
+    else
+      this[this.t - 1] |= x << sh;
+    sh += k;
+    if (sh >= this.DB) sh -= this.DB;
+  }
+  if (k == 8 && (s[0] & 0x80) != 0) {
+    this.s = -1;
+    if (sh > 0) this[this.t - 1] |= ((1 << (this.DB - sh)) - 1) << sh;
+  }
+  this.clamp();
+  if (mi) BigInteger.ZERO.subTo(this, this);
+};
+
+
+// (protected) clamp off excess high words
+BigInteger.prototype.clamp = function () {
+  var c = this.s & this.DM;
+  while (this.t > 0 && this[this.t - 1] == c) --this.t;
+};
+
+// (protected) r = this << n*DB
+BigInteger.prototype.dlShiftTo = function (n, r) {
+  var i;
+  for (i = this.t - 1; i >= 0; --i) r[i + n] = this[i];
+  for (i = n - 1; i >= 0; --i) r[i] = 0;
+  r.t = this.t + n;
+  r.s = this.s;
+};
+
+// (protected) r = this >> n*DB
+BigInteger.prototype.drShiftTo = function (n, r) {
+  for (var i = n; i < this.t; ++i) r[i - n] = this[i];
+  r.t = Math.max(this.t - n, 0);
+  r.s = this.s;
+};
+
+// (protected) r = this << n
+BigInteger.prototype.lShiftTo = function (n, r) {
+  var bs = n % this.DB;
+  var cbs = this.DB - bs;
+  var bm = (1 << cbs) - 1;
+  var ds = Math.floor(n / this.DB), c = (this.s << bs) & this.DM, i;
+  for (i = this.t - 1; i >= 0; --i) {
+    r[i + ds + 1] = (this[i] >> cbs) | c;
+    c = (this[i] & bm) << bs;
+  }
+  for (i = ds - 1; i >= 0; --i) r[i] = 0;
+  r[ds] = c;
+  r.t = this.t + ds + 1;
+  r.s = this.s;
+  r.clamp();
+};
+
+// (protected) r = this >> n
+BigInteger.prototype.rShiftTo = function (n, r) {
+  r.s = this.s;
+  var ds = Math.floor(n / this.DB);
+  if (ds >= this.t) { r.t = 0; return; }
+  var bs = n % this.DB;
+  var cbs = this.DB - bs;
+  var bm = (1 << bs) - 1;
+  r[0] = this[ds] >> bs;
+  for (var i = ds + 1; i < this.t; ++i) {
+    r[i - ds - 1] |= (this[i] & bm) << cbs;
+    r[i - ds] = this[i] >> bs;
+  }
+  if (bs > 0) r[this.t - ds - 1] |= (this.s & bm) << cbs;
+  r.t = this.t - ds;
+  r.clamp();
+};
+
+// (protected) r = this - a
+BigInteger.prototype.subTo = function (a, r) {
+  var i = 0, c = 0, m = Math.min(a.t, this.t);
+  while (i < m) {
+    c += this[i] - a[i];
+    r[i++] = c & this.DM;
+    c >>= this.DB;
+  }
+  if (a.t < this.t) {
+    c -= a.s;
+    while (i < this.t) {
+      c += this[i];
+      r[i++] = c & this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while (i < a.t) {
+      c -= a[i];
+      r[i++] = c & this.DM;
+      c >>= this.DB;
+    }
+    c -= a.s;
+  }
+  r.s = (c < 0) ? -1 : 0;
+  if (c < -1) r[i++] = this.DV + c;
+  else if (c > 0) r[i++] = c;
+  r.t = i;
+  r.clamp();
+};
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+BigInteger.prototype.multiplyTo = function (a, r) {
+  var x = this.abs(), y = a.abs();
+  var i = x.t;
+  r.t = i + y.t;
+  while (--i >= 0) r[i] = 0;
+  for (i = 0; i < y.t; ++i) r[i + x.t] = x.am(0, y[i], r, i, 0, x.t);
+  r.s = 0;
+  r.clamp();
+  if (this.s != a.s) BigInteger.ZERO.subTo(r, r);
+};
+
+// (protected) r = this^2, r != this (HAC 14.16)
+BigInteger.prototype.squareTo = function (r) {
+  var x = this.abs();
+  var i = r.t = 2 * x.t;
+  while (--i >= 0) r[i] = 0;
+  for (i = 0; i < x.t - 1; ++i) {
+    var c = x.am(i, x[i], r, 2 * i, 0, 1);
+    if ((r[i + x.t] += x.am(i + 1, 2 * x[i], r, 2 * i + 1, c, x.t - i - 1)) >= x.DV) {
+      r[i + x.t] -= x.DV;
+      r[i + x.t + 1] = 1;
+    }
+  }
+  if (r.t > 0) r[r.t - 1] += x.am(i, x[i], r, 2 * i, 0, 1);
+  r.s = 0;
+  r.clamp();
+};
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m.  q or r may be null.
+BigInteger.prototype.divRemTo = function (m, q, r) {
+  var pm = m.abs();
+  if (pm.t <= 0) return;
+  var pt = this.abs();
+  if (pt.t < pm.t) {
+    if (q != null) q.fromInt(0);
+    if (r != null) this.copyTo(r);
+    return;
+  }
+  if (r == null) r = nbi();
+  var y = nbi(), ts = this.s, ms = m.s;
+  var nsh = this.DB - nbits(pm[pm.t - 1]); // normalize modulus
+  if (nsh > 0) { pm.lShiftTo(nsh, y); pt.lShiftTo(nsh, r); }
+  else { pm.copyTo(y); pt.copyTo(r); }
+  var ys = y.t;
+  var y0 = y[ys - 1];
+  if (y0 == 0) return;
+  var yt = y0 * (1 << this.F1) + ((ys > 1) ? y[ys - 2] >> this.F2 : 0);
+  var d1 = this.FV / yt, d2 = (1 << this.F1) / yt, e = 1 << this.F2;
+  var i = r.t, j = i - ys, t = (q == null) ? nbi() : q;
+  y.dlShiftTo(j, t);
+  if (r.compareTo(t) >= 0) {
+    r[r.t++] = 1;
+    r.subTo(t, r);
+  }
+  BigInteger.ONE.dlShiftTo(ys, t);
+  t.subTo(y, y); // "negative" y so we can replace sub with am later
+  while (y.t < ys) y[y.t++] = 0;
+  while (--j >= 0) {
+    // Estimate quotient digit
+    var qd = (r[--i] == y0) ? this.DM : Math.floor(r[i] * d1 + (r[i - 1] + e) * d2);
+    if ((r[i] += y.am(0, qd, r, j, 0, ys)) < qd) {  // Try it out
+      y.dlShiftTo(j, t);
+      r.subTo(t, r);
+      while (r[i] < --qd) r.subTo(t, r);
+    }
+  }
+  if (q != null) {
+    r.drShiftTo(ys, q);
+    if (ts != ms) BigInteger.ZERO.subTo(q, q);
+  }
+  r.t = ys;
+  r.clamp();
+  if (nsh > 0) r.rShiftTo(nsh, r); // Denormalize remainder
+  if (ts < 0) BigInteger.ZERO.subTo(r, r);
+};
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+//         xy == 1 (mod m)
+//         xy =  1+km
+//   xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+BigInteger.prototype.invDigit = function () {
+  if (this.t < 1) return 0;
+  var x = this[0];
+  if ((x & 1) == 0) return 0;
+  var y = x & 3;  // y == 1/x mod 2^2
+  y = (y * (2 - (x & 0xf) * y)) & 0xf; // y == 1/x mod 2^4
+  y = (y * (2 - (x & 0xff) * y)) & 0xff; // y == 1/x mod 2^8
+  y = (y * (2 - (((x & 0xffff) * y) & 0xffff))) & 0xffff; // y == 1/x mod 2^16
+  // last step - calculate inverse mod DV directly;
+  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+  y = (y * (2 - x * y % this.DV)) % this.DV;  // y == 1/x mod 2^dbits
+  // we really want the negative inverse, and -DV < y < DV
+  return (y > 0) ? this.DV - y : -y;
+};
+
+// (protected) true iff this is even
+BigInteger.prototype.isEven = function () { return ((this.t > 0) ? (this[0] & 1) : this.s) == 0; };
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+BigInteger.prototype.exp = function (e, z) {
+  if (e > 0xffffffff || e < 1) return BigInteger.ONE;
+  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e) - 1;
+  g.copyTo(r);
+  while (--i >= 0) {
+    z.sqrTo(r, r2);
+    if ((e & (1 << i)) > 0) z.mulTo(r2, g, r);
+    else { var t = r; r = r2; r2 = t; }
+  }
+  return z.revert(r);
+};
+
+// (public) return string representation in given radix
+BigInteger.prototype.toString = function (b) {
+  if (this.s < 0) return "-" + this.negate().toString(b);
+  var k;
+  if (b == 16) k = 4;
+  else if (b == 8) k = 3;
+  else if (b == 2) k = 1;
+  else if (b == 32) k = 5;
+  else if (b == 4) k = 2;
+  else return this.toRadix(b);
+  var km = (1 << k) - 1, d, m = false, r = "", i = this.t;
+  var p = this.DB - (i * this.DB) % k;
+  if (i-- > 0) {
+    if (p < this.DB && (d = this[i] >> p) > 0) { m = true; r = int2char(d); }
+    while (i >= 0) {
+      if (p < k) {
+        d = (this[i] & ((1 << p) - 1)) << (k - p);
+        d |= this[--i] >> (p += this.DB - k);
+      }
+      else {
+        d = (this[i] >> (p -= k)) & km;
+        if (p <= 0) { p += this.DB; --i; }
+      }
+      if (d > 0) m = true;
+      if (m) r += int2char(d);
+    }
+  }
+  return m ? r : "0";
+};
+
+// (public) -this
+BigInteger.prototype.negate = function () { var r = nbi(); BigInteger.ZERO.subTo(this, r); return r; };
+
+// (public) |this|
+BigInteger.prototype.abs = function () { return (this.s < 0) ? this.negate() : this; };
+
+// (public) return + if this > a, - if this < a, 0 if equal
+BigInteger.prototype.compareTo = function (a) {
+  var r = this.s - a.s;
+  if (r != 0) return r;
+  var i = this.t;
+  r = i - a.t;
+  if (r != 0) return (this.s < 0) ? -r : r;
+  while (--i >= 0) if ((r = this[i] - a[i]) != 0) return r;
+  return 0;
+}
+
+// (public) return the number of bits in "this"
+BigInteger.prototype.bitLength = function () {
+  if (this.t <= 0) return 0;
+  return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ (this.s & this.DM));
+};
+
+// (public) this mod a
+BigInteger.prototype.mod = function (a) {
+  var r = nbi();
+  this.abs().divRemTo(a, null, r);
+  if (this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r, r);
+  return r;
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+BigInteger.prototype.modPowInt = function (e, m) {
+  var z;
+  if (e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+  return this.exp(e, z);
+};
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+
+// Copyright (c) 2005-2009  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+// Extended JavaScript BN functions, required for RSA private ops.
+// Version 1.1: new BigInteger("0", 10) returns "proper" zero
+// Version 1.2: square() API, isProbablePrime fix
+
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+  if (x == 0) return -1;
+  var r = 0;
+  if ((x & 0xffff) == 0) { x >>= 16; r += 16; }
+  if ((x & 0xff) == 0) { x >>= 8; r += 8; }
+  if ((x & 0xf) == 0) { x >>= 4; r += 4; }
+  if ((x & 3) == 0) { x >>= 2; r += 2; }
+  if ((x & 1) == 0) ++r;
+  return r;
+}
+
+// return number of 1 bits in x
+function cbit(x) {
+  var r = 0;
+  while (x != 0) { x &= x - 1; ++r; }
+  return r;
+}
+
+var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997];
+var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
+
+// (protected) return x s.t. r^x < DV
+BigInteger.prototype.chunkSize = function (r) { return Math.floor(Math.LN2 * this.DB / Math.log(r)); };
+
+// (protected) convert to radix string
+BigInteger.prototype.toRadix = function (b) {
+  if (b == null) b = 10;
+  if (this.signum() == 0 || b < 2 || b > 36) return "0";
+  var cs = this.chunkSize(b);
+  var a = Math.pow(b, cs);
+  var d = nbv(a), y = nbi(), z = nbi(), r = "";
+  this.divRemTo(d, y, z);
+  while (y.signum() > 0) {
+    r = (a + z.intValue()).toString(b).substr(1) + r;
+    y.divRemTo(d, y, z);
+  }
+  return z.intValue().toString(b) + r;
+};
+
+// (protected) convert from radix string
+BigInteger.prototype.fromRadix = function (s, b) {
+  this.fromInt(0);
+  if (b == null) b = 10;
+  var cs = this.chunkSize(b);
+  var d = Math.pow(b, cs), mi = false, j = 0, w = 0;
+  for (var i = 0; i < s.length; ++i) {
+    var x = intAt(s, i);
+    if (x < 0) {
+      if (s.charAt(i) == "-" && this.signum() == 0) mi = true;
+      continue;
+    }
+    w = b * w + x;
+    if (++j >= cs) {
+      this.dMultiply(d);
+      this.dAddOffset(w, 0);
+      j = 0;
+      w = 0;
+    }
+  }
+  if (j > 0) {
+    this.dMultiply(Math.pow(b, j));
+    this.dAddOffset(w, 0);
+  }
+  if (mi) BigInteger.ZERO.subTo(this, this);
+};
+
+// (protected) alternate constructor
+BigInteger.prototype.fromNumber = function (a, b, c) {
+  if ("number" == typeof b) {
+    // new BigInteger(int,int,RNG)
+    if (a < 2) this.fromInt(1);
+    else {
+      this.fromNumber(a, c);
+      if (!this.testBit(a - 1)) // force MSB set
+        this.bitwiseTo(BigInteger.ONE.shiftLeft(a - 1), op_or, this);
+      if (this.isEven()) this.dAddOffset(1, 0); // force odd
+      while (!this.isProbablePrime(b)) {
+        this.dAddOffset(2, 0);
+        if (this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a - 1), this);
+      }
+    }
+  }
+  else {
+    // new BigInteger(int,RNG)
+    var x = new Array(), t = a & 7;
+    x.length = (a >> 3) + 1;
+    b.nextBytes(x);
+    if (t > 0) x[0] &= ((1 << t) - 1); else x[0] = 0;
+    this.fromString(x, 256);
+  }
+};
+
+// (protected) r = this op a (bitwise)
+BigInteger.prototype.bitwiseTo = function (a, op, r) {
+  var i, f, m = Math.min(a.t, this.t);
+  for (i = 0; i < m; ++i) r[i] = op(this[i], a[i]);
+  if (a.t < this.t) {
+    f = a.s & this.DM;
+    for (i = m; i < this.t; ++i) r[i] = op(this[i], f);
+    r.t = this.t;
+  }
+  else {
+    f = this.s & this.DM;
+    for (i = m; i < a.t; ++i) r[i] = op(f, a[i]);
+    r.t = a.t;
+  }
+  r.s = op(this.s, a.s);
+  r.clamp();
+};
+
+// (protected) this op (1<<n)
+BigInteger.prototype.changeBit = function (n, op) {
+  var r = BigInteger.ONE.shiftLeft(n);
+  this.bitwiseTo(r, op, r);
+  return r;
+};
+
+// (protected) r = this + a
+BigInteger.prototype.addTo = function (a, r) {
+  var i = 0, c = 0, m = Math.min(a.t, this.t);
+  while (i < m) {
+    c += this[i] + a[i];
+    r[i++] = c & this.DM;
+    c >>= this.DB;
+  }
+  if (a.t < this.t) {
+    c += a.s;
+    while (i < this.t) {
+      c += this[i];
+      r[i++] = c & this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while (i < a.t) {
+      c += a[i];
+      r[i++] = c & this.DM;
+      c >>= this.DB;
+    }
+    c += a.s;
+  }
+  r.s = (c < 0) ? -1 : 0;
+  if (c > 0) r[i++] = c;
+  else if (c < -1) r[i++] = this.DV + c;
+  r.t = i;
+  r.clamp();
+};
+
+// (protected) this *= n, this >= 0, 1 < n < DV
+BigInteger.prototype.dMultiply = function (n) {
+  this[this.t] = this.am(0, n - 1, this, 0, 0, this.t);
+  ++this.t;
+  this.clamp();
+};
+
+// (protected) this += n << w words, this >= 0
+BigInteger.prototype.dAddOffset = function (n, w) {
+  if (n == 0) return;
+  while (this.t <= w) this[this.t++] = 0;
+  this[w] += n;
+  while (this[w] >= this.DV) {
+    this[w] -= this.DV;
+    if (++w >= this.t) this[this.t++] = 0;
+    ++this[w];
+  }
+};
+
+// (protected) r = lower n words of "this * a", a.t <= n
+// "this" should be the larger one if appropriate.
+BigInteger.prototype.multiplyLowerTo = function (a, n, r) {
+  var i = Math.min(this.t + a.t, n);
+  r.s = 0; // assumes a,this >= 0
+  r.t = i;
+  while (i > 0) r[--i] = 0;
+  var j;
+  for (j = r.t - this.t; i < j; ++i) r[i + this.t] = this.am(0, a[i], r, i, 0, this.t);
+  for (j = Math.min(a.t, n); i < j; ++i) this.am(0, a[i], r, i, 0, n - i);
+  r.clamp();
+};
+
+
+// (protected) r = "this * a" without lower n words, n > 0
+// "this" should be the larger one if appropriate.
+BigInteger.prototype.multiplyUpperTo = function (a, n, r) {
+  --n;
+  var i = r.t = this.t + a.t - n;
+  r.s = 0; // assumes a,this >= 0
+  while (--i >= 0) r[i] = 0;
+  for (i = Math.max(n - this.t, 0); i < a.t; ++i)
+    r[this.t + i - n] = this.am(n - i, a[i], r, 0, 0, this.t + i - n);
+  r.clamp();
+  r.drShiftTo(1, r);
+};
+
+// (protected) this % n, n < 2^26
+BigInteger.prototype.modInt = function (n) {
+  if (n <= 0) return 0;
+  var d = this.DV % n, r = (this.s < 0) ? n - 1 : 0;
+  if (this.t > 0)
+    if (d == 0) r = this[0] % n;
+    else for (var i = this.t - 1; i >= 0; --i) r = (d * r + this[i]) % n;
+  return r;
+};
+
+// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+BigInteger.prototype.millerRabin = function (t) {
+  var n1 = this.subtract(BigInteger.ONE);
+  var k = n1.getLowestSetBit();
+  if (k <= 0) return false;
+  var r = n1.shiftRight(k);
+  t = (t + 1) >> 1;
+  if (t > lowprimes.length) t = lowprimes.length;
+  var a = nbi();
+  for (var i = 0; i < t; ++i) {
+    //Pick bases at random, instead of starting at 2
+    a.fromInt(lowprimes[Math.floor(Math.random() * lowprimes.length)]);
+    var y = a.modPow(r, this);
+    if (y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+      var j = 1;
+      while (j++ < k && y.compareTo(n1) != 0) {
+        y = y.modPowInt(2, this);
+        if (y.compareTo(BigInteger.ONE) == 0) return false;
+      }
+      if (y.compareTo(n1) != 0) return false;
+    }
+  }
+  return true;
+};
+
+// (public)
+BigInteger.prototype.clone = function () { var r = nbi(); this.copyTo(r); return r; };
+
+// (public) return value as integer
+BigInteger.prototype.intValue = function () {
+  if (this.s < 0) {
+    if (this.t == 1) return this[0] - this.DV;
+    else if (this.t == 0) return -1;
+  }
+  else if (this.t == 1) return this[0];
+  else if (this.t == 0) return 0;
+  // assumes 16 < DB < 32
+  return ((this[1] & ((1 << (32 - this.DB)) - 1)) << this.DB) | this[0];
+};
+
+// (public) return value as byte
+BigInteger.prototype.byteValue = function () { return (this.t == 0) ? this.s : (this[0] << 24) >> 24; };
+
+// (public) return value as short (assumes DB>=16)
+BigInteger.prototype.shortValue = function () { return (this.t == 0) ? this.s : (this[0] << 16) >> 16; };
+
+// (public) 0 if this == 0, 1 if this > 0
+BigInteger.prototype.signum = function () {
+  if (this.s < 0) return -1;
+  else if (this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+  else return 1;
+};
+
+// (public) convert to bigendian byte array
+BigInteger.prototype.toByteArray = function () {
+  var i = this.t, r = new Array();
+  r[0] = this.s;
+  var p = this.DB - (i * this.DB) % 8, d, k = 0;
+  if (i-- > 0) {
+    if (p < this.DB && (d = this[i] >> p) != (this.s & this.DM) >> p)
+      r[k++] = d | (this.s << (this.DB - p));
+    while (i >= 0) {
+      if (p < 8) {
+        d = (this[i] & ((1 << p) - 1)) << (8 - p);
+        d |= this[--i] >> (p += this.DB - 8);
+      }
+      else {
+        d = (this[i] >> (p -= 8)) & 0xff;
+        if (p <= 0) { p += this.DB; --i; }
+      }
+      if ((d & 0x80) != 0) d |= -256;
+      if (k == 0 && (this.s & 0x80) != (d & 0x80)) ++k;
+      if (k > 0 || d != this.s) r[k++] = d;
+    }
+  }
+  return r;
+};
+
+BigInteger.prototype.equals = function (a) { return (this.compareTo(a) == 0); };
+BigInteger.prototype.min = function (a) { return (this.compareTo(a) < 0) ? this : a; };
+BigInteger.prototype.max = function (a) { return (this.compareTo(a) > 0) ? this : a; };
+
+// (public) this & a
+function op_and(x, y) { return x & y; }
+BigInteger.prototype.and = function (a) { var r = nbi(); this.bitwiseTo(a, op_and, r); return r; };
+
+// (public) this | a
+function op_or(x, y) { return x | y; }
+BigInteger.prototype.or = function (a) { var r = nbi(); this.bitwiseTo(a, op_or, r); return r; };
+
+// (public) this ^ a
+function op_xor(x, y) { return x ^ y; }
+BigInteger.prototype.xor = function (a) { var r = nbi(); this.bitwiseTo(a, op_xor, r); return r; };
+
+// (public) this & ~a
+function op_andnot(x, y) { return x & ~y; }
+BigInteger.prototype.andNot = function (a) { var r = nbi(); this.bitwiseTo(a, op_andnot, r); return r; };
+
+// (public) ~this
+BigInteger.prototype.not = function () {
+  var r = nbi();
+  for (var i = 0; i < this.t; ++i) r[i] = this.DM & ~this[i];
+  r.t = this.t;
+  r.s = ~this.s;
+  return r;
+};
+
+// (public) this << n
+BigInteger.prototype.shiftLeft = function (n) {
+  var r = nbi();
+  if (n < 0) this.rShiftTo(-n, r); else this.lShiftTo(n, r);
+  return r;
+};
+
+// (public) this >> n
+BigInteger.prototype.shiftRight = function (n) {
+  var r = nbi();
+  if (n < 0) this.lShiftTo(-n, r); else this.rShiftTo(n, r);
+  return r;
+};
+
+// (public) returns index of lowest 1-bit (or -1 if none)
+BigInteger.prototype.getLowestSetBit = function () {
+  for (var i = 0; i < this.t; ++i)
+    if (this[i] != 0) return i * this.DB + lbit(this[i]);
+  if (this.s < 0) return this.t * this.DB;
+  return -1;
+};
+
+// (public) return number of set bits
+BigInteger.prototype.bitCount = function () {
+  var r = 0, x = this.s & this.DM;
+  for (var i = 0; i < this.t; ++i) r += cbit(this[i] ^ x);
+  return r;
+};
+
+// (public) true iff nth bit is set
+BigInteger.prototype.testBit = function (n) {
+  var j = Math.floor(n / this.DB);
+  if (j >= this.t) return (this.s != 0);
+  return ((this[j] & (1 << (n % this.DB))) != 0);
+};
+
+// (public) this | (1<<n)
+BigInteger.prototype.setBit = function (n) { return this.changeBit(n, op_or); };
+// (public) this & ~(1<<n)
+BigInteger.prototype.clearBit = function (n) { return this.changeBit(n, op_andnot); };
+// (public) this ^ (1<<n)
+BigInteger.prototype.flipBit = function (n) { return this.changeBit(n, op_xor); };
+// (public) this + a
+BigInteger.prototype.add = function (a) { var r = nbi(); this.addTo(a, r); return r; };
+// (public) this - a
+BigInteger.prototype.subtract = function (a) { var r = nbi(); this.subTo(a, r); return r; };
+// (public) this * a
+BigInteger.prototype.multiply = function (a) { var r = nbi(); this.multiplyTo(a, r); return r; };
+// (public) this / a
+BigInteger.prototype.divide = function (a) { var r = nbi(); this.divRemTo(a, r, null); return r; };
+// (public) this % a
+BigInteger.prototype.remainder = function (a) { var r = nbi(); this.divRemTo(a, null, r); return r; };
+// (public) [this/a,this%a]
+BigInteger.prototype.divideAndRemainder = function (a) {
+  var q = nbi(), r = nbi();
+  this.divRemTo(a, q, r);
+  return new Array(q, r);
+};
+
+// (public) this^e % m (HAC 14.85)
+BigInteger.prototype.modPow = function (e, m) {
+  var i = e.bitLength(), k, r = nbv(1), z;
+  if (i <= 0) return r;
+  else if (i < 18) k = 1;
+  else if (i < 48) k = 3;
+  else if (i < 144) k = 4;
+  else if (i < 768) k = 5;
+  else k = 6;
+  if (i < 8)
+    z = new Classic(m);
+  else if (m.isEven())
+    z = new Barrett(m);
+  else
+    z = new Montgomery(m);
+
+  // precomputation
+  var g = new Array(), n = 3, k1 = k - 1, km = (1 << k) - 1;
+  g[1] = z.convert(this);
+  if (k > 1) {
+    var g2 = nbi();
+    z.sqrTo(g[1], g2);
+    while (n <= km) {
+      g[n] = nbi();
+      z.mulTo(g2, g[n - 2], g[n]);
+      n += 2;
+    }
+  }
+
+  var j = e.t - 1, w, is1 = true, r2 = nbi(), t;
+  i = nbits(e[j]) - 1;
+  while (j >= 0) {
+    if (i >= k1) w = (e[j] >> (i - k1)) & km;
+    else {
+      w = (e[j] & ((1 << (i + 1)) - 1)) << (k1 - i);
+      if (j > 0) w |= e[j - 1] >> (this.DB + i - k1);
+    }
+
+    n = k;
+    while ((w & 1) == 0) { w >>= 1; --n; }
+    if ((i -= n) < 0) { i += this.DB; --j; }
+    if (is1) {  // ret == 1, don't bother squaring or multiplying it
+      g[w].copyTo(r);
+      is1 = false;
+    }
+    else {
+      while (n > 1) { z.sqrTo(r, r2); z.sqrTo(r2, r); n -= 2; }
+      if (n > 0) z.sqrTo(r, r2); else { t = r; r = r2; r2 = t; }
+      z.mulTo(r2, g[w], r);
+    }
+
+    while (j >= 0 && (e[j] & (1 << i)) == 0) {
+      z.sqrTo(r, r2); t = r; r = r2; r2 = t;
+      if (--i < 0) { i = this.DB - 1; --j; }
+    }
+  }
+  return z.revert(r);
+};
+
+// (public) 1/this % m (HAC 14.61)
+BigInteger.prototype.modInverse = function (m) {
+  var ac = m.isEven();
+  if ((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+  var u = m.clone(), v = this.clone();
+  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
+  while (u.signum() != 0) {
+    while (u.isEven()) {
+      u.rShiftTo(1, u);
+      if (ac) {
+        if (!a.isEven() || !b.isEven()) { a.addTo(this, a); b.subTo(m, b); }
+        a.rShiftTo(1, a);
+      }
+      else if (!b.isEven()) b.subTo(m, b);
+      b.rShiftTo(1, b);
+    }
+    while (v.isEven()) {
+      v.rShiftTo(1, v);
+      if (ac) {
+        if (!c.isEven() || !d.isEven()) { c.addTo(this, c); d.subTo(m, d); }
+        c.rShiftTo(1, c);
+      }
+      else if (!d.isEven()) d.subTo(m, d);
+      d.rShiftTo(1, d);
+    }
+    if (u.compareTo(v) >= 0) {
+      u.subTo(v, u);
+      if (ac) a.subTo(c, a);
+      b.subTo(d, b);
+    }
+    else {
+      v.subTo(u, v);
+      if (ac) c.subTo(a, c);
+      d.subTo(b, d);
+    }
+  }
+  if (v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+  if (d.compareTo(m) >= 0) return d.subtract(m);
+  if (d.signum() < 0) d.addTo(m, d); else return d;
+  if (d.signum() < 0) return d.add(m); else return d;
+};
+
+// (public) this^e
+BigInteger.prototype.pow = function (e) { return this.exp(e, new NullExp()); };
+
+// (public) gcd(this,a) (HAC 14.54)
+BigInteger.prototype.gcd = function (a) {
+  var x = (this.s < 0) ? this.negate() : this.clone();
+  var y = (a.s < 0) ? a.negate() : a.clone();
+  if (x.compareTo(y) < 0) { var t = x; x = y; y = t; }
+  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
+  if (g < 0) return x;
+  if (i < g) g = i;
+  if (g > 0) {
+    x.rShiftTo(g, x);
+    y.rShiftTo(g, y);
+  }
+  while (x.signum() > 0) {
+    if ((i = x.getLowestSetBit()) > 0) x.rShiftTo(i, x);
+    if ((i = y.getLowestSetBit()) > 0) y.rShiftTo(i, y);
+    if (x.compareTo(y) >= 0) {
+      x.subTo(y, x);
+      x.rShiftTo(1, x);
+    }
+    else {
+      y.subTo(x, y);
+      y.rShiftTo(1, y);
+    }
+  }
+  if (g > 0) y.lShiftTo(g, y);
+  return y;
+};
+
+// (public) test primality with certainty >= 1-.5^t
+BigInteger.prototype.isProbablePrime = function (t) {
+  var i, x = this.abs();
+  if (x.t == 1 && x[0] <= lowprimes[lowprimes.length - 1]) {
+    for (i = 0; i < lowprimes.length; ++i)
+      if (x[0] == lowprimes[i]) return true;
+    return false;
+  }
+  if (x.isEven()) return false;
+  i = 1;
+  while (i < lowprimes.length) {
+    var m = lowprimes[i], j = i + 1;
+    while (j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+    m = x.modInt(m);
+    while (i < j) if (m % lowprimes[i++] == 0) return false;
+  }
+  return x.millerRabin(t);
+};
+
+// JSBN-specific extension
+
+// (public) this^2
+BigInteger.prototype.square = function () { var r = nbi(); this.squareTo(r); return r; };
+// NOTE: BigInteger interfaces not implemented in jsbn:
+// BigInteger(int signum, byte[] magnitude)
+// double doubleValue()
+// float floatValue()
+// int hashCode()
+// long longValue()
+// static BigInteger valueOf(long val)
+
+// Copyright Stephan Thomas (start) --- //
+// https://raw.github.com/bitcoinjs/bitcoinjs-lib/07f9d55ccb6abd962efb6befdd37671f85ea4ff9/src/util.js
+// BigInteger monkey patching
+BigInteger.valueOf = nbv;
+
+/**
+* Returns a byte array representation of the big integer.
+*
+* This returns the absolute of the contained value in big endian
+* form. A value of zero results in an empty array.
+*/
+BigInteger.prototype.toByteArrayUnsigned = function () {
+  var ba = this.abs().toByteArray();
+  if (ba.length) {
+    if (ba[0] == 0) {
+      ba = ba.slice(1);
+    }
+    return ba.map(function (v) {
+      return (v < 0) ? v + 256 : v;
+    });
+  } else {
+    // Empty array, nothing to do
+    return ba;
+  }
+};
+
+/**
+* Turns a byte array into a big integer.
+*
+* This function will interpret a byte array as a big integer in big
+* endian notation and ignore leading zeros.
+*/
+BigInteger.fromByteArrayUnsigned = function (ba) {
+  if (!ba.length) {
+    return ba.valueOf(0);
+  } else if (ba[0] & 0x80) {
+    // Prepend a zero so the BigInteger class doesn't mistake this
+    // for a negative integer.
+    return new BigInteger([0].concat(ba));
+  } else {
+    return new BigInteger(ba);
+  }
+};
+
+/**
+* Converts big integer to signed byte representation.
+*
+* The format for this value uses a the most significant bit as a sign
+* bit. If the most significant bit is already occupied by the
+* absolute value, an extra byte is prepended and the sign bit is set
+* there.
+*
+* Examples:
+*
+*      0 =>     0x00
+*      1 =>     0x01
+*     -1 =>     0x81
+*    127 =>     0x7f
+*   -127 =>     0xff
+*    128 =>   0x0080
+*   -128 =>   0x8080
+*    255 =>   0x00ff
+*   -255 =>   0x80ff
+*  16300 =>   0x3fac
+* -16300 =>   0xbfac
+*  62300 => 0x00f35c
+* -62300 => 0x80f35c
+*/
+BigInteger.prototype.toByteArraySigned = function () {
+  var val = this.abs().toByteArrayUnsigned();
+  var neg = this.compareTo(BigInteger.ZERO) < 0;
+
+  if (neg) {
+    if (val[0] & 0x80) {
+      val.unshift(0x80);
+    } else {
+      val[0] |= 0x80;
+    }
+  } else {
+    if (val[0] & 0x80) {
+      val.unshift(0x00);
+    }
+  }
+
+  return val;
+};
+
+/**
+* Parse a signed big integer byte representation.
+*
+* For details on the format please see BigInteger.toByteArraySigned.
+*/
+BigInteger.fromByteArraySigned = function (ba) {
+  // Check for negative value
+  if (ba[0] & 0x80) {
+    // Remove sign bit
+    ba[0] &= 0x7f;
+
+    return BigInteger.fromByteArrayUnsigned(ba).negate();
+  } else {
+    return BigInteger.fromByteArrayUnsigned(ba);
+  }
+};
+// Copyright Stephan Thomas (end) --- //
+
+// ****** REDUCTION ******* //
+
+// Modular reduction using "classic" algorithm
+var Classic = window.Classic = function Classic(m) { this.m = m; }
+Classic.prototype.convert = function (x) {
+  if (x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+  else return x;
+};
+Classic.prototype.revert = function (x) { return x; };
+Classic.prototype.reduce = function (x) { x.divRemTo(this.m, null, x); };
+Classic.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+Classic.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+// Montgomery reduction
+var Montgomery = window.Montgomery = function Montgomery(m) {
+  this.m = m;
+  this.mp = m.invDigit();
+  this.mpl = this.mp & 0x7fff;
+  this.mph = this.mp >> 15;
+  this.um = (1 << (m.DB - 15)) - 1;
+  this.mt2 = 2 * m.t;
+}
+// xR mod m
+Montgomery.prototype.convert = function (x) {
+  var r = nbi();
+  x.abs().dlShiftTo(this.m.t, r);
+  r.divRemTo(this.m, null, r);
+  if (x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r, r);
+  return r;
+}
+// x/R mod m
+Montgomery.prototype.revert = function (x) {
+  var r = nbi();
+  x.copyTo(r);
+  this.reduce(r);
+  return r;
+};
+// x = x/R mod m (HAC 14.32)
+Montgomery.prototype.reduce = function (x) {
+  while (x.t <= this.mt2) // pad x so am has enough room later
+    x[x.t++] = 0;
+  for (var i = 0; i < this.m.t; ++i) {
+    // faster way of calculating u0 = x[i]*mp mod DV
+    var j = x[i] & 0x7fff;
+    var u0 = (j * this.mpl + (((j * this.mph + (x[i] >> 15) * this.mpl) & this.um) << 15)) & x.DM;
+    // use am to combine the multiply-shift-add into one call
+    j = i + this.m.t;
+    x[j] += this.m.am(0, u0, x, i, 0, this.m.t);
+    // propagate carry
+    while (x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+  }
+  x.clamp();
+  x.drShiftTo(this.m.t, x);
+  if (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+};
+// r = "xy/R mod m"; x,y != r
+Montgomery.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+// r = "x^2/R mod m"; x != r
+Montgomery.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+// A "null" reducer
+var NullExp = window.NullExp = function NullExp() { }
+NullExp.prototype.convert = function (x) { return x; };
+NullExp.prototype.revert = function (x) { return x; };
+NullExp.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); };
+NullExp.prototype.sqrTo = function (x, r) { x.squareTo(r); };
+
+// Barrett modular reduction
+var Barrett = window.Barrett = function Barrett(m) {
+  // setup Barrett
+  this.r2 = nbi();
+  this.q3 = nbi();
+  BigInteger.ONE.dlShiftTo(2 * m.t, this.r2);
+  this.mu = this.r2.divide(m);
+  this.m = m;
+}
+Barrett.prototype.convert = function (x) {
+  if (x.s < 0 || x.t > 2 * this.m.t) return x.mod(this.m);
+  else if (x.compareTo(this.m) < 0) return x;
+  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
+};
+Barrett.prototype.revert = function (x) { return x; };
+// x = x mod m (HAC 14.42)
+Barrett.prototype.reduce = function (x) {
+  x.drShiftTo(this.m.t - 1, this.r2);
+  if (x.t > this.m.t + 1) { x.t = this.m.t + 1; x.clamp(); }
+  this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
+  this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
+  while (x.compareTo(this.r2) < 0) x.dAddOffset(1, this.m.t + 1);
+  x.subTo(this.r2, x);
+  while (x.compareTo(this.m) >= 0) x.subTo(this.m, x);
+};
+// r = x*y mod m; x,y != r
+Barrett.prototype.mulTo = function (x, y, r) { x.multiplyTo(y, r); this.reduce(r); };
+// r = x^2 mod m; x != r
+Barrett.prototype.sqrTo = function (x, r) { x.squareTo(r); this.reduce(r); };
+
+// ----- Bitcoin -----//
+export let Bitcoin = {};
+
+//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/address.js
+Bitcoin.Address = function (bytes) {
+if ("string" == typeof bytes) {
+  bytes = Bitcoin.Address.decodeString(bytes);
+}
+this.hash = bytes;
+};
+
+/**
+* Serialize this object as a standard currency address.
+*
+* Returns the address as a base58-encoded string in the standardized format.
+*/
+Bitcoin.Address.prototype.toString = function () {
+// Get a copy of the hash
+var hash = this.hash.slice(0);
+
+// Version
+hash.unshift('0x3c'); // KMD
+var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
+var bytes = hash.concat(checksum.slice(0, 4));
+return Bitcoin.Base58.encode(bytes);
+};
+
+Bitcoin.Address.prototype.getHashBase64 = function () {
+return Crypto.util.bytesToBase64(this.hash);
+};
+
+/**
+* Parse a Bitcoin address contained in a string.
+*/
+Bitcoin.Address.decodeString = function (string) {
+var bytes = Bitcoin.Base58.decode(string);
+var hash = bytes.slice(0, 21);
+var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
+
+if (checksum[0] != bytes[21] ||
+    checksum[1] != bytes[22] ||
+    checksum[2] != bytes[23] ||
+    checksum[3] != bytes[24]) {
+  throw "Checksum validation failed!";
+}
+
+return hash;
+};
+
+Bitcoin.Base58 = {
+  alphabet: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz",
+  validRegex: /^[1-9A-HJ-NP-Za-km-z]+$/,
+  base: BigInteger.valueOf(58),
+
+  /**
+  * Convert a byte array to a base58-encoded string.
+  *
+  * Written by Mike Hearn for BitcoinJ.
+  *   Copyright (c) 2011 Google Inc.
+  *
+  * Ported to JavaScript by Stefan Thomas.
+  */
+  encode: function (input) {
+    var bi = BigInteger.fromByteArrayUnsigned(input);
+    var chars = [];
+
+    while (bi.compareTo(B58.base) >= 0) {
+      var mod = bi.mod(B58.base);
+      chars.unshift(B58.alphabet[mod.intValue()]);
+      bi = bi.subtract(mod).divide(B58.base);
+    }
+    chars.unshift(B58.alphabet[bi.intValue()]);
+
+    // Convert leading zeros too.
+    for (var i = 0; i < input.length; i++) {
+      if (input[i] == 0x00) {
+        chars.unshift(B58.alphabet[0]);
+      } else break;
+    }
+
+    return chars.join('');
+  },
+
+  /**
+  * Convert a base58-encoded string to a byte array.
+  *
+  * Written by Mike Hearn for BitcoinJ.
+  *   Copyright (c) 2011 Google Inc.
+  *
+  * Ported to JavaScript by Stefan Thomas.
+  */
+  decode: function (input) {
+    var bi = BigInteger.valueOf(0);
+    var leadingZerosNum = 0;
+    for (var i = input.length - 1; i >= 0; i--) {
+      var alphaIndex = B58.alphabet.indexOf(input[i]);
+      if (alphaIndex < 0) {
+        throw "Invalid character";
+      }
+      bi = bi.add(BigInteger.valueOf(alphaIndex)
+              .multiply(B58.base.pow(input.length - 1 - i)));
+
+      // This counts leading zero bytes
+      if (input[i] == "1") leadingZerosNum++;
+      else leadingZerosNum = 0;
+    }
+    var bytes = bi.toByteArrayUnsigned();
+
+    // Add leading zeros
+    while (leadingZerosNum-- > 0) bytes.unshift(0);
+
+    return bytes;
+  }
+};
+
+const B58 = Bitcoin.Base58;
+
+Bitcoin.ECDSA = (function () {
+  var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
+  var rng = new SecureRandom();
+
+  var P_OVER_FOUR = null;
+
+  function implShamirsTrick(P, k, Q, l) {
+    var m = Math.max(k.bitLength(), l.bitLength());
+    var Z = P.add2D(Q);
+    var R = P.curve.getInfinity();
+
+    for (var i = m - 1; i >= 0; --i) {
+      R = R.twice2D();
+
+      R.z = BigInteger.ONE;
+
+      if (k.testBit(i)) {
+        if (l.testBit(i)) {
+          R = R.add2D(Z);
+        } else {
+          R = R.add2D(P);
+        }
+      } else {
+        if (l.testBit(i)) {
+          R = R.add2D(Q);
+        }
+      }
+    }
+
+    return R;
+  };
+
+  var ECDSA = {
+    getBigRandom: function (limit) {
+      return new BigInteger(limit.bitLength(), rng)
+        .mod(limit.subtract(BigInteger.ONE))
+        .add(BigInteger.ONE);
+    },
+    sign: function (hash, priv) {
+      var d = priv;
+      var n = ecparams.getN();
+      var e = BigInteger.fromByteArrayUnsigned(hash);
+
+      do {
+        var k = ECDSA.getBigRandom(n);
+        var G = ecparams.getG();
+        var Q = G.multiply(k);
+        var r = Q.getX().toBigInteger().mod(n);
+      } while (r.compareTo(BigInteger.ZERO) <= 0);
+
+      var s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n);
+
+      return ECDSA.serializeSig(r, s);
+    },
+
+    verify: function (hash, sig, pubkey) {
+      var r, s;
+      if (Bitcoin.Util.isArray(sig)) {
+        var obj = ECDSA.parseSig(sig);
+        r = obj.r;
+        s = obj.s;
+      } else if ("object" === typeof sig && sig.r && sig.s) {
+        r = sig.r;
+        s = sig.s;
+      } else {
+        throw "Invalid value for signature";
+      }
+
+      var Q;
+      if (pubkey instanceof ec.PointFp) {
+        Q = pubkey;
+      } else if (Bitcoin.Util.isArray(pubkey)) {
+        Q = EllipticCurve.PointFp.decodeFrom(ecparams.getCurve(), pubkey);
+      } else {
+        throw "Invalid format for pubkey value, must be byte array or ec.PointFp";
+      }
+      var e = BigInteger.fromByteArrayUnsigned(hash);
+
+      return ECDSA.verifyRaw(e, r, s, Q);
+    },
+
+    verifyRaw: function (e, r, s, Q) {
+      var n = ecparams.getN();
+      var G = ecparams.getG();
+
+      if (r.compareTo(BigInteger.ONE) < 0 ||
+          r.compareTo(n) >= 0)
+        return false;
+
+      if (s.compareTo(BigInteger.ONE) < 0 ||
+          s.compareTo(n) >= 0)
+        return false;
+
+      var c = s.modInverse(n);
+
+      var u1 = e.multiply(c).mod(n);
+      var u2 = r.multiply(c).mod(n);
+
+      // TODO(!!!): For some reason Shamir's trick isn't working with
+      // signed message verification!? Probably an implementation
+      // error!
+      //var point = implShamirsTrick(G, u1, Q, u2);
+      var point = G.multiply(u1).add(Q.multiply(u2));
+
+      var v = point.getX().toBigInteger().mod(n);
+
+      return v.equals(r);
+    },
+
+    /**
+    * Serialize a signature into DER format.
+    *
+    * Takes two BigIntegers representing r and s and returns a byte array.
+    */
+    serializeSig: function (r, s) {
+      var rBa = r.toByteArraySigned();
+      var sBa = s.toByteArraySigned();
+
+      var sequence = [];
+      sequence.push(0x02); // INTEGER
+      sequence.push(rBa.length);
+      sequence = sequence.concat(rBa);
+
+      sequence.push(0x02); // INTEGER
+      sequence.push(sBa.length);
+      sequence = sequence.concat(sBa);
+
+      sequence.unshift(sequence.length);
+      sequence.unshift(0x30); // SEQUENCE
+
+      return sequence;
+    },
+
+    /**
+    * Parses a byte array containing a DER-encoded signature.
+    *
+    * This function will return an object of the form:
+    *
+    * {
+    *   r: BigInteger,
+    *   s: BigInteger
+    * }
+    */
+    parseSig: function (sig) {
+      var cursor;
+      if (sig[0] != 0x30)
+        throw new Error("Signature not a valid DERSequence");
+
+      cursor = 2;
+      if (sig[cursor] != 0x02)
+        throw new Error("First element in signature must be a DERInteger"); ;
+      var rBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]);
+
+      cursor += 2 + sig[cursor + 1];
+      if (sig[cursor] != 0x02)
+        throw new Error("Second element in signature must be a DERInteger");
+      var sBa = sig.slice(cursor + 2, cursor + 2 + sig[cursor + 1]);
+
+      cursor += 2 + sig[cursor + 1];
+
+      //if (cursor != sig.length)
+      //  throw new Error("Extra bytes in signature");
+
+      var r = BigInteger.fromByteArrayUnsigned(rBa);
+      var s = BigInteger.fromByteArrayUnsigned(sBa);
+
+      return { r: r, s: s };
+    },
+
+    parseSigCompact: function (sig) {
+      if (sig.length !== 65) {
+        throw "Signature has the wrong length";
+      }
+
+      // Signature is prefixed with a type byte storing three bits of
+      // information.
+      var i = sig[0] - 27;
+      if (i < 0 || i > 7) {
+        throw "Invalid signature type";
+      }
+
+      var n = ecparams.getN();
+      var r = BigInteger.fromByteArrayUnsigned(sig.slice(1, 33)).mod(n);
+      var s = BigInteger.fromByteArrayUnsigned(sig.slice(33, 65)).mod(n);
+
+      return { r: r, s: s, i: i };
+    },
+
+    /**
+    * Recover a public key from a signature.
+    *
+    * See SEC 1: Elliptic Curve Cryptography, section 4.1.6, "Public
+    * Key Recovery Operation".
+    *
+    * http://www.secg.org/download/aid-780/sec1-v2.pdf
+    */
+    recoverPubKey: function (r, s, hash, i) {
+      // The recovery parameter i has two bits.
+      i = i & 3;
+
+      // The less significant bit specifies whether the y coordinate
+      // of the compressed point is even or not.
+      var isYEven = i & 1;
+
+      // The more significant bit specifies whether we should use the
+      // first or second candidate key.
+      var isSecondKey = i >> 1;
+
+      var n = ecparams.getN();
+      var G = ecparams.getG();
+      var curve = ecparams.getCurve();
+      var p = curve.getQ();
+      var a = curve.getA().toBigInteger();
+      var b = curve.getB().toBigInteger();
+
+      // We precalculate (p + 1) / 4 where p is if the field order
+      if (!P_OVER_FOUR) {
+        P_OVER_FOUR = p.add(BigInteger.ONE).divide(BigInteger.valueOf(4));
+      }
+
+      // 1.1 Compute x
+      var x = isSecondKey ? r.add(n) : r;
+
+      // 1.3 Convert x to point
+      var alpha = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(p);
+      var beta = alpha.modPow(P_OVER_FOUR, p);
+
+      var xorOdd = beta.isEven() ? (i % 2) : ((i + 1) % 2);
+      // If beta is even, but y isn't or vice versa, then convert it,
+      // otherwise we're done and y == beta.
+      var y = (beta.isEven() ? !isYEven : isYEven) ? beta : p.subtract(beta);
+
+      // 1.4 Check that nR is at infinity
+      var R = new EllipticCurve.PointFp(curve,
+                            curve.fromBigInteger(x),
+                            curve.fromBigInteger(y));
+      R.validate();
+
+      // 1.5 Compute e from M
+      var e = BigInteger.fromByteArrayUnsigned(hash);
+      var eNeg = BigInteger.ZERO.subtract(e).mod(n);
+
+      // 1.6 Compute Q = r^-1 (sR - eG)
+      var rInv = r.modInverse(n);
+      var Q = implShamirsTrick(R, s, G, eNeg).multiply(rInv);
+
+      Q.validate();
+      if (!ECDSA.verifyRaw(e, r, s, Q)) {
+        throw "Pubkey recovery unsuccessful";
+      }
+
+      var pubKey = new Bitcoin.ECKey();
+      pubKey.pub = Q;
+      return pubKey;
+    },
+
+    /**
+    * Calculate pubkey extraction parameter.
+    *
+    * When extracting a pubkey from a signature, we have to
+    * distinguish four different cases. Rather than putting this
+    * burden on the verifier, Bitcoin includes a 2-bit value with the
+    * signature.
+    *
+    * This function simply tries all four cases and returns the value
+    * that resulted in a successful pubkey recovery.
+    */
+    calcPubkeyRecoveryParam: function (address, r, s, hash) {
+      for (var i = 0; i < 4; i++) {
+        try {
+          var pubkey = Bitcoin.ECDSA.recoverPubKey(r, s, hash, i);
+          if (pubkey.getBitcoinAddress().toString() == address) {
+            return i;
+          }
+        } catch (e) { }
+      }
+      throw "Unable to find valid recovery factor";
+    }
+  };
+
+  return ECDSA;
+})();
+
+Bitcoin.ECKey = (function () {
+  var ECDSA = Bitcoin.ECDSA;
+  var ecparams = EllipticCurve.getSECCurveByName("secp256k1");
+  var rng = new SecureRandom();
+
+  var ECKey = function (input) {
+    if (!input) {
+      // Generate new key
+      var n = ecparams.getN();
+      this.priv = ECDSA.getBigRandom(n);
+    } else if (input instanceof BigInteger) {
+      // Input is a private key value
+      this.priv = input;
+    } else if (Bitcoin.Util.isArray(input)) {
+      // Prepend zero byte to prevent interpretation as negative integer
+      this.priv = BigInteger.fromByteArrayUnsigned(input);
+    } else if ("string" == typeof input) {
+      var bytes = null;
+      if (ECKey.isWalletImportFormat(input)) {
+        bytes = ECKey.decodeWalletImportFormat(input);
+      } else if (ECKey.isCompressedWalletImportFormat(input)) {
+        bytes = ECKey.decodeCompressedWalletImportFormat(input);
+        this.compressed = true;
+      } else if (ECKey.isMiniFormat(input)) {
+        bytes = Crypto.SHA256(input, { asBytes: true });
+      } else if (ECKey.isHexFormat(input)) {
+        bytes = Crypto.util.hexToBytes(input);
+      } else if (ECKey.isBase64Format(input)) {
+        bytes = Crypto.util.base64ToBytes(input);
+      }
+
+      if (ECKey.isBase6Format(input)) {
+        this.priv = new BigInteger(input, 6);
+      } else if (bytes == null || bytes.length != 32) {
+        this.priv = null;
+      } else {
+        // Prepend zero byte to prevent interpretation as negative integer
+        this.priv = BigInteger.fromByteArrayUnsigned(bytes);
+      }
+    }
+
+    this.compressed = (this.compressed == undefined) ? !!ECKey.compressByDefault : this.compressed;
+  };
+
+  /**
+  * Whether public keys should be returned compressed by default.
+  */
+  ECKey.compressByDefault = false;
+
+  /**
+  * Set whether the public key should be returned compressed or not.
+  */
+  ECKey.prototype.setCompressed = function (v) {
+    this.compressed = !!v;
+    if (this.pubPoint) this.pubPoint.compressed = this.compressed;
+    return this;
+  };
+
+  /*
+  * Return public key as a byte array in DER encoding
+  */
+  ECKey.prototype.getPub = function () {
+    if (this.compressed) {
+      if (this.pubComp) return this.pubComp;
+      return this.pubComp = this.getPubPoint().getEncoded(1);
+    } else {
+      if (this.pubUncomp) return this.pubUncomp;
+      return this.pubUncomp = this.getPubPoint().getEncoded(0);
+    }
+  };
+
+  /**
+  * Return public point as ECPoint object.
+  */
+  ECKey.prototype.getPubPoint = function () {
+    if (!this.pubPoint) {
+      this.pubPoint = ecparams.getG().multiply(this.priv);
+      this.pubPoint.compressed = this.compressed;
+    }
+    return this.pubPoint;
+  };
+
+  ECKey.prototype.getPubKeyHex = function () {
+    if (this.compressed) {
+      if (this.pubKeyHexComp) return this.pubKeyHexComp;
+      return this.pubKeyHexComp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase();
+    } else {
+      if (this.pubKeyHexUncomp) return this.pubKeyHexUncomp;
+      return this.pubKeyHexUncomp = Crypto.util.bytesToHex(this.getPub()).toString().toUpperCase();
+    }
+  };
+
+  /**
+  * Get the pubKeyHash for this key.
+  *
+  * This is calculated as RIPE160(SHA256([encoded pubkey])) and returned as
+  * a byte array.
+  */
+  ECKey.prototype.getPubKeyHash = function () {
+    if (this.compressed) {
+      if (this.pubKeyHashComp) return this.pubKeyHashComp;
+      return this.pubKeyHashComp = Bitcoin.Util.sha256ripe160(this.getPub());
+    } else {
+      if (this.pubKeyHashUncomp) return this.pubKeyHashUncomp;
+      return this.pubKeyHashUncomp = Bitcoin.Util.sha256ripe160(this.getPub());
+    }
+  };
+
+  ECKey.prototype.getBitcoinAddress = function () {
+    var hash = this.getPubKeyHash();
+    var addr = new Bitcoin.Address(hash);
+    return addr.toString();
+  };
+
+  /*
+  * Takes a public point as a hex string or byte array
+  */
+  ECKey.prototype.setPub = function (pub) {
+    // byte array
+    if (Bitcoin.Util.isArray(pub)) {
+      pub = Crypto.util.bytesToHex(pub).toString().toUpperCase();
+    }
+    var ecPoint = ecparams.getCurve().decodePointHex(pub);
+    this.setCompressed(ecPoint.compressed);
+    this.pubPoint = ecPoint;
+    return this;
+  };
+
+  // Sipa Private Key Wallet Import Format
+  ECKey.prototype.getBitcoinWalletImportFormat = function () {
+    var bytes = this.getBitcoinPrivateKeyByteArray();
+    bytes.unshift('0xbc'); // prepend private key prefix // KMD
+    if (this.compressed) bytes.push(0x01); // append 0x01 byte for compressed format
+    var checksum = Crypto.SHA256(Crypto.SHA256(bytes, { asBytes: true }), { asBytes: true });
+    bytes = bytes.concat(checksum.slice(0, 4));
+    var privWif = Bitcoin.Base58.encode(bytes);
+    return privWif;
+  };
+
+  // Private Key Hex Format
+  ECKey.prototype.getBitcoinHexFormat = function () {
+    return Crypto.util.bytesToHex(this.getBitcoinPrivateKeyByteArray()).toString().toUpperCase();
+  };
+
+  // Private Key Base64 Format
+  ECKey.prototype.getBitcoinBase64Format = function () {
+    return Crypto.util.bytesToBase64(this.getBitcoinPrivateKeyByteArray());
+  };
+
+  ECKey.prototype.getBitcoinPrivateKeyByteArray = function () {
+    // Get a copy of private key as a byte array
+    var bytes = this.priv.toByteArrayUnsigned();
+    // zero pad if private key is less than 32 bytes
+    while (bytes.length < 32) bytes.unshift(0x00);
+    return bytes;
+  };
+
+  ECKey.prototype.toString = function (format) {
+    format = format || "";
+    if (format.toString().toLowerCase() == "base64" || format.toString().toLowerCase() == "b64") {
+      return this.getBitcoinBase64Format();
+    }
+    // Wallet Import Format
+    else if (format.toString().toLowerCase() == "wif") {
+      return this.getBitcoinWalletImportFormat();
+    }
+    else {
+      return this.getBitcoinHexFormat();
+    }
+  };
+
+  ECKey.prototype.sign = function (hash) {
+    return ECDSA.sign(hash, this.priv);
+  };
+
+  ECKey.prototype.verify = function (hash, sig) {
+    return ECDSA.verify(hash, sig, this.getPub());
+  };
+
+  /**
+  * Parse a wallet import format private key contained in a string.
+  */
+  ECKey.decodeWalletImportFormat = function (privStr) {
+    var bytes = Bitcoin.Base58.decode(privStr);
+    var hash = bytes.slice(0, 33);
+    var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
+    if (checksum[0] != bytes[33] ||
+          checksum[1] != bytes[34] ||
+          checksum[2] != bytes[35] ||
+          checksum[3] != bytes[36]) {
+      throw "Checksum validation failed!";
+    }
+    var version = hash.shift();
+        // TODO: detect currency
+    if (version != janin.currency.privateKeyPrefix()) {
+      throw "Version " + version + " not supported!";
+    }
+    return hash;
+  };
+
+  /**
+  * Parse a compressed wallet import format private key contained in a string.
+  */
+  ECKey.decodeCompressedWalletImportFormat = function (privStr) {
+    var bytes = Bitcoin.Base58.decode(privStr);
+    var hash = bytes.slice(0, 34);
+    var checksum = Crypto.SHA256(Crypto.SHA256(hash, { asBytes: true }), { asBytes: true });
+    if (checksum[0] != bytes[34] ||
+          checksum[1] != bytes[35] ||
+          checksum[2] != bytes[36] ||
+          checksum[3] != bytes[37]) {
+      throw "Checksum validation failed!";
+    }
+    var version = hash.shift();
+        // TODO: detect currency
+    if (version != janin.currency.privateKeyPrefix()) {
+      throw "Version " + version + " not supported!";
+    }
+    hash.pop();
+    return hash;
+  };
+
+  // 64 characters [0-9A-F]
+  ECKey.isHexFormat = function (key) {
+    key = key.toString();
+    return /^[A-Fa-f0-9]{64}$/.test(key);
+  };
+
+  // 51 characters base58, always starts with a '5'
+  ECKey.isWalletImportFormat = function (key) {
+    key = key.toString();
+    return janin.currency.WIF_RegEx().test(key);
+  };
+
+  // 52 characters base58
+  ECKey.isCompressedWalletImportFormat = function (key) {
+    key = key.toString();
+    return janin.currency.CWIF_RegEx().test(key);
+  };
+
+  // 44 characters
+  ECKey.isBase64Format = function (key) {
+    key = key.toString();
+    return (/^[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789=+\/]{44}$/.test(key));
+  };
+
+  // 99 characters, 1=1, if using dice convert 6 to 0
+  ECKey.isBase6Format = function (key) {
+    key = key.toString();
+    return (/^[012345]{99}$/.test(key));
+  };
+
+  // 22, 26 or 30 characters, always starts with an 'S'
+  ECKey.isMiniFormat = function (key) {
+    key = key.toString();
+    var validChars22 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{21}$/.test(key);
+    var validChars26 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{25}$/.test(key);
+    var validChars30 = /^S[123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz]{29}$/.test(key);
+    var testBytes = Crypto.SHA256(key + "?", { asBytes: true });
+
+    return ((testBytes[0] === 0x00 || testBytes[0] === 0x01) && (validChars22 || validChars26 || validChars30));
+  };
+
+  return ECKey;
+})();
+
+//https://raw.github.com/bitcoinjs/bitcoinjs-lib/09e8c6e184d6501a0c2c59d73ca64db5c0d3eb95/src/util.js
+// Bitcoin utility functions
+Bitcoin.Util = {
+  /**
+  * Cross-browser compatibility version of Array.isArray.
+  */
+  isArray: Array.isArray || function (o) {
+    return Object.prototype.toString.call(o) === '[object Array]';
+  },
+  /**
+  * Create an array of a certain length filled with a specific value.
+  */
+  makeFilledArray: function (len, val) {
+    var array = [];
+    var i = 0;
+    while (i < len) {
+      array[i++] = val;
+    }
+    return array;
+  },
+  /**
+  * Turn an integer into a "var_int".
+  *
+  * "var_int" is a variable length integer used by Bitcoin's binary format.
+  *
+  * Returns a byte array.
+  */
+  numToVarInt: function (i) {
+    if (i < 0xfd) {
+      // unsigned char
+      return [i];
+    } else if (i <= 1 << 16) {
+      // unsigned short (LE)
+      return [0xfd, i >>> 8, i & 255];
+    } else if (i <= 1 << 32) {
+      // unsigned int (LE)
+      return [0xfe].concat(Crypto.util.wordsToBytes([i]));
+    } else {
+      // unsigned long long (LE)
+      return [0xff].concat(Crypto.util.wordsToBytes([i >>> 32, i]));
+    }
+  },
+  /**
+  * Parse a Bitcoin value byte array, returning a BigInteger.
+  */
+  valueToBigInt: function (valueBuffer) {
+    if (valueBuffer instanceof BigInteger) return valueBuffer;
+
+    // Prepend zero byte to prevent interpretation as negative integer
+    return BigInteger.fromByteArrayUnsigned(valueBuffer);
+  },
+  /**
+  * Format a Bitcoin value as a string.
+  *
+  * Takes a BigInteger or byte-array and returns that amount of Bitcoins in a
+  * nice standard formatting.
+  *
+  * Examples:
+  * 12.3555
+  * 0.1234
+  * 900.99998888
+  * 34.00
+  */
+  formatValue: function (valueBuffer) {
+    var value = this.valueToBigInt(valueBuffer).toString();
+    var integerPart = value.length > 8 ? value.substr(0, value.length - 8) : '0';
+    var decimalPart = value.length > 8 ? value.substr(value.length - 8) : value;
+    while (decimalPart.length < 8) decimalPart = "0" + decimalPart;
+    decimalPart = decimalPart.replace(/0*$/, '');
+    while (decimalPart.length < 2) decimalPart += "0";
+    return integerPart + "." + decimalPart;
+  },
+  /**
+  * Parse a floating point string as a Bitcoin value.
+  *
+  * Keep in mind that parsing user input is messy. You should always display
+  * the parsed value back to the user to make sure we understood his input
+  * correctly.
+  */
+  parseValue: function (valueString) {
+    // TODO: Detect other number formats (e.g. comma as decimal separator)
+    var valueComp = valueString.split('.');
+    var integralPart = valueComp[0];
+    var fractionalPart = valueComp[1] || "0";
+    while (fractionalPart.length < 8) fractionalPart += "0";
+    fractionalPart = fractionalPart.replace(/^0+/g, '');
+    var value = BigInteger.valueOf(parseInt(integralPart));
+    value = value.multiply(BigInteger.valueOf(100000000));
+    value = value.add(BigInteger.valueOf(parseInt(fractionalPart)));
+    return value;
+  },
+  /**
+  * Calculate RIPEMD160(SHA256(data)).
+  *
+  * Takes an arbitrary byte array as inputs and returns the hash as a byte
+  * array.
+  */
+  sha256ripe160: function (data) {
+    return Crypto.RIPEMD160(Crypto.SHA256(data, { asBytes: true }), { asBytes: true });
+  },
+  // double sha256
+  dsha256: function (data) {
+    return Crypto.SHA256(Crypto.SHA256(data, { asBytes: true }), { asBytes: true });
+  }
+};
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/crypto-scrypt.js b/react/src/util/crypto/gen/crypto-scrypt.js
new file mode 100755
index 0000000..01600f4
--- /dev/null
+++ b/react/src/util/crypto/gen/crypto-scrypt.js
@@ -0,0 +1,295 @@
+/*
+* Copyright (c) 2010-2011 Intalio Pte, All Rights Reserved
+* 
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+* 
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*/
+// https://github.com/cheongwy/node-scrypt-js
+(function () {
+
+	var MAX_VALUE = 2147483647;
+	var workerUrl = null;
+
+	//function scrypt(byte[] passwd, byte[] salt, int N, int r, int p, int dkLen)
+	/*
+	* N = Cpu cost
+	* r = Memory cost
+	* p = parallelization cost
+	* 
+	*/
+	window.Crypto_scrypt = function (passwd, salt, N, r, p, dkLen, callback) {
+		if (N == 0 || (N & (N - 1)) != 0) throw Error("N must be > 0 and a power of 2");
+
+		if (N > MAX_VALUE / 128 / r) throw Error("Parameter N is too large");
+		if (r > MAX_VALUE / 128 / p) throw Error("Parameter r is too large");
+
+		var PBKDF2_opts = { iterations: 1, hasher: Crypto.SHA256, asBytes: true };
+
+		var B = Crypto.PBKDF2(passwd, salt, p * 128 * r, PBKDF2_opts);
+
+		try {
+			var i = 0;
+			var worksDone = 0;
+			var makeWorker = function () {
+				if (!workerUrl) {
+					var code = '(' + scryptCore.toString() + ')()';
+					var blob;
+					try {
+						blob = new Blob([code], { type: "text/javascript" });
+					} catch (e) {
+						window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
+						blob = new BlobBuilder();
+						blob.append(code);
+						blob = blob.getBlob("text/javascript");
+					}
+					workerUrl = URL.createObjectURL(blob);
+				}
+				var worker = new Worker(workerUrl);
+				worker.onmessage = function (event) {
+					var Bi = event.data[0], Bslice = event.data[1];
+					worksDone++;
+
+					if (i < p) {
+						worker.postMessage([N, r, p, B, i++]);
+					}
+
+					var length = Bslice.length, destPos = Bi * 128 * r, srcPos = 0;
+					while (length--) {
+						B[destPos++] = Bslice[srcPos++];
+					}
+
+					if (worksDone == p) {
+						callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts));
+					}
+				};
+				return worker;
+			};
+			var workers = [makeWorker(), makeWorker()];
+			workers[0].postMessage([N, r, p, B, i++]);
+			if (p > 1) {
+				workers[1].postMessage([N, r, p, B, i++]);
+			}
+		} catch (e) {
+			window.setTimeout(function () {
+				scryptCore();
+				callback(Crypto.PBKDF2(passwd, B, dkLen, PBKDF2_opts));
+			}, 0);
+		}
+
+		// using this function to enclose everything needed to create a worker (but also invokable directly for synchronous use)
+		function scryptCore() {
+			var XY = [], V = [];
+
+			if (typeof B === 'undefined') {
+				onmessage = function (event) {
+					var data = event.data;
+					var N = data[0], r = data[1], p = data[2], B = data[3], i = data[4];
+
+					var Bslice = [];
+					arraycopy32(B, i * 128 * r, Bslice, 0, 128 * r);
+					smix(Bslice, 0, r, N, V, XY);
+
+					postMessage([i, Bslice]);
+				};
+			} else {
+				for (var i = 0; i < p; i++) {
+					smix(B, i * 128 * r, r, N, V, XY);
+				}
+			}
+
+			function smix(B, Bi, r, N, V, XY) {
+				var Xi = 0;
+				var Yi = 128 * r;
+				var i;
+
+				arraycopy32(B, Bi, XY, Xi, Yi);
+
+				for (i = 0; i < N; i++) {
+					arraycopy32(XY, Xi, V, i * Yi, Yi);
+					blockmix_salsa8(XY, Xi, Yi, r);
+				}
+
+				for (i = 0; i < N; i++) {
+					var j = integerify(XY, Xi, r) & (N - 1);
+					blockxor(V, j * Yi, XY, Xi, Yi);
+					blockmix_salsa8(XY, Xi, Yi, r);
+				}
+
+				arraycopy32(XY, Xi, B, Bi, Yi);
+			}
+
+			function blockmix_salsa8(BY, Bi, Yi, r) {
+				var X = [];
+				var i;
+
+				arraycopy32(BY, Bi + (2 * r - 1) * 64, X, 0, 64);
+
+				for (i = 0; i < 2 * r; i++) {
+					blockxor(BY, i * 64, X, 0, 64);
+					salsa20_8(X);
+					arraycopy32(X, 0, BY, Yi + (i * 64), 64);
+				}
+
+				for (i = 0; i < r; i++) {
+					arraycopy32(BY, Yi + (i * 2) * 64, BY, Bi + (i * 64), 64);
+				}
+
+				for (i = 0; i < r; i++) {
+					arraycopy32(BY, Yi + (i * 2 + 1) * 64, BY, Bi + (i + r) * 64, 64);
+				}
+			}
+
+			function R(a, b) {
+				return (a << b) | (a >>> (32 - b));
+			}
+
+			function salsa20_8(B) {
+				var B32 = new Array(32);
+				var x = new Array(32);
+				var i;
+
+				for (i = 0; i < 16; i++) {
+					B32[i] = (B[i * 4 + 0] & 0xff) << 0;
+					B32[i] |= (B[i * 4 + 1] & 0xff) << 8;
+					B32[i] |= (B[i * 4 + 2] & 0xff) << 16;
+					B32[i] |= (B[i * 4 + 3] & 0xff) << 24;
+				}
+
+				arraycopy(B32, 0, x, 0, 16);
+
+				for (i = 8; i > 0; i -= 2) {
+					x[4] ^= R(x[0] + x[12], 7); x[8] ^= R(x[4] + x[0], 9);
+					x[12] ^= R(x[8] + x[4], 13); x[0] ^= R(x[12] + x[8], 18);
+					x[9] ^= R(x[5] + x[1], 7); x[13] ^= R(x[9] + x[5], 9);
+					x[1] ^= R(x[13] + x[9], 13); x[5] ^= R(x[1] + x[13], 18);
+					x[14] ^= R(x[10] + x[6], 7); x[2] ^= R(x[14] + x[10], 9);
+					x[6] ^= R(x[2] + x[14], 13); x[10] ^= R(x[6] + x[2], 18);
+					x[3] ^= R(x[15] + x[11], 7); x[7] ^= R(x[3] + x[15], 9);
+					x[11] ^= R(x[7] + x[3], 13); x[15] ^= R(x[11] + x[7], 18);
+					x[1] ^= R(x[0] + x[3], 7); x[2] ^= R(x[1] + x[0], 9);
+					x[3] ^= R(x[2] + x[1], 13); x[0] ^= R(x[3] + x[2], 18);
+					x[6] ^= R(x[5] + x[4], 7); x[7] ^= R(x[6] + x[5], 9);
+					x[4] ^= R(x[7] + x[6], 13); x[5] ^= R(x[4] + x[7], 18);
+					x[11] ^= R(x[10] + x[9], 7); x[8] ^= R(x[11] + x[10], 9);
+					x[9] ^= R(x[8] + x[11], 13); x[10] ^= R(x[9] + x[8], 18);
+					x[12] ^= R(x[15] + x[14], 7); x[13] ^= R(x[12] + x[15], 9);
+					x[14] ^= R(x[13] + x[12], 13); x[15] ^= R(x[14] + x[13], 18);
+				}
+
+				for (i = 0; i < 16; ++i) B32[i] = x[i] + B32[i];
+
+				for (i = 0; i < 16; i++) {
+					var bi = i * 4;
+					B[bi + 0] = (B32[i] >> 0 & 0xff);
+					B[bi + 1] = (B32[i] >> 8 & 0xff);
+					B[bi + 2] = (B32[i] >> 16 & 0xff);
+					B[bi + 3] = (B32[i] >> 24 & 0xff);
+				}
+			}
+
+			function blockxor(S, Si, D, Di, len) {
+				var i = len >> 6;
+				while (i--) {
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+					D[Di++] ^= S[Si++]; D[Di++] ^= S[Si++];
+				}
+			}
+
+			function integerify(B, bi, r) {
+				var n;
+
+				bi += (2 * r - 1) * 64;
+
+				n = (B[bi + 0] & 0xff) << 0;
+				n |= (B[bi + 1] & 0xff) << 8;
+				n |= (B[bi + 2] & 0xff) << 16;
+				n |= (B[bi + 3] & 0xff) << 24;
+
+				return n;
+			}
+
+			function arraycopy(src, srcPos, dest, destPos, length) {
+				while (length--) {
+					dest[destPos++] = src[srcPos++];
+				}
+			}
+
+			function arraycopy32(src, srcPos, dest, destPos, length) {
+				var i = length >> 5;
+				while (i--) {
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+					dest[destPos++] = src[srcPos++]; dest[destPos++] = src[srcPos++];
+				}
+			}
+		} // scryptCore
+	}; // window.Crypto_scrypt
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.aes.js b/react/src/util/crypto/gen/cryptojs.aes.js
new file mode 100755
index 0000000..dfcba32
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.aes.js
@@ -0,0 +1,407 @@
+/*!
+* Crypto-JS v2.5.4	AES.js
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*/
+(function () {
+
+	// Shortcuts
+	var C = Crypto,
+		util = C.util,
+		charenc = C.charenc,
+		UTF8 = charenc.UTF8;
+
+	// Precomputed SBOX
+	var SBOX = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+            0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+            0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+            0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+            0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+            0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+            0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+            0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+            0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+            0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+            0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+            0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+            0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+            0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+            0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+            0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+            0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+            0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+            0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+            0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+            0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+            0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+            0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+            0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+            0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+            0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+            0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+            0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+            0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+            0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+            0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+            0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16];
+
+	// Compute inverse SBOX lookup table
+	for (var INVSBOX = [], i = 0; i < 256; i++) INVSBOX[SBOX[i]] = i;
+
+	// Compute multiplication in GF(2^8) lookup tables
+	var MULT2 = [],
+		MULT3 = [],
+		MULT9 = [],
+		MULTB = [],
+		MULTD = [],
+		MULTE = [];
+
+	function xtime(a, b) {
+		for (var result = 0, i = 0; i < 8; i++) {
+			if (b & 1) result ^= a;
+			var hiBitSet = a & 0x80;
+			a = (a << 1) & 0xFF;
+			if (hiBitSet) a ^= 0x1b;
+			b >>>= 1;
+		}
+		return result;
+	}
+
+	for (var i = 0; i < 256; i++) {
+		MULT2[i] = xtime(i, 2);
+		MULT3[i] = xtime(i, 3);
+		MULT9[i] = xtime(i, 9);
+		MULTB[i] = xtime(i, 0xB);
+		MULTD[i] = xtime(i, 0xD);
+		MULTE[i] = xtime(i, 0xE);
+	}
+
+	// Precomputed RCon lookup
+	var RCON = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
+
+	// Inner state
+	var state = [[], [], [], []],
+		keylength,
+		nrounds,
+		keyschedule;
+
+	var AES = C.AES = {
+
+		/**
+		* Public API
+		*/
+
+		encrypt: function (message, password, options) {
+
+			options = options || {};
+
+			// Determine mode
+			var mode = options.mode || new C.mode.OFB;
+
+			// Allow mode to override options
+			if (mode.fixOptions) mode.fixOptions(options);
+
+			var 
+
+			// Convert to bytes if message is a string
+		m = (
+			message.constructor == String ?
+			UTF8.stringToBytes(message) :
+			message
+		),
+
+			// Generate random IV
+		iv = options.iv || util.randomBytes(AES._blocksize * 4),
+
+			// Generate key
+		k = (
+			password.constructor == String ?
+			// Derive key from pass-phrase
+			C.PBKDF2(password, iv, 32, { asBytes: true }) :
+			// else, assume byte array representing cryptographic key
+			password
+		);
+
+			// Encrypt
+			AES._init(k);
+			mode.encrypt(AES, m, iv);
+
+			// Return ciphertext
+			m = options.iv ? m : iv.concat(m);
+			return (options && options.asBytes) ? m : util.bytesToBase64(m);
+
+		},
+
+		decrypt: function (ciphertext, password, options) {
+
+			options = options || {};
+
+			// Determine mode
+			var mode = options.mode || new C.mode.OFB;
+
+			// Allow mode to override options
+			if (mode.fixOptions) mode.fixOptions(options);
+
+			var 
+
+			// Convert to bytes if ciphertext is a string
+		c = (
+			ciphertext.constructor == String ?
+			util.base64ToBytes(ciphertext) :
+			ciphertext
+		),
+
+			// Separate IV and message
+		iv = options.iv || c.splice(0, AES._blocksize * 4),
+
+			// Generate key
+		k = (
+			password.constructor == String ?
+			// Derive key from pass-phrase
+			C.PBKDF2(password, iv, 32, { asBytes: true }) :
+			// else, assume byte array representing cryptographic key
+			password
+		);
+
+			// Decrypt
+			AES._init(k);
+			mode.decrypt(AES, c, iv);
+
+			// Return plaintext
+			return (options && options.asBytes) ? c : UTF8.bytesToString(c);
+
+		},
+
+
+		/**
+		* Package private methods and properties
+		*/
+
+		_blocksize: 4,
+
+		_encryptblock: function (m, offset) {
+
+			// Set input
+			for (var row = 0; row < AES._blocksize; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] = m[offset + col * 4 + row];
+			}
+
+			// Add round key
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] ^= keyschedule[col][row];
+			}
+
+			for (var round = 1; round < nrounds; round++) {
+
+				// Sub bytes
+				for (var row = 0; row < 4; row++) {
+					for (var col = 0; col < 4; col++)
+						state[row][col] = SBOX[state[row][col]];
+				}
+
+				// Shift rows
+				state[1].push(state[1].shift());
+				state[2].push(state[2].shift());
+				state[2].push(state[2].shift());
+				state[3].unshift(state[3].pop());
+
+				// Mix columns
+				for (var col = 0; col < 4; col++) {
+
+					var s0 = state[0][col],
+				s1 = state[1][col],
+				s2 = state[2][col],
+				s3 = state[3][col];
+
+					state[0][col] = MULT2[s0] ^ MULT3[s1] ^ s2 ^ s3;
+					state[1][col] = s0 ^ MULT2[s1] ^ MULT3[s2] ^ s3;
+					state[2][col] = s0 ^ s1 ^ MULT2[s2] ^ MULT3[s3];
+					state[3][col] = MULT3[s0] ^ s1 ^ s2 ^ MULT2[s3];
+
+				}
+
+				// Add round key
+				for (var row = 0; row < 4; row++) {
+					for (var col = 0; col < 4; col++)
+						state[row][col] ^= keyschedule[round * 4 + col][row];
+				}
+
+			}
+
+			// Sub bytes
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] = SBOX[state[row][col]];
+			}
+
+			// Shift rows
+			state[1].push(state[1].shift());
+			state[2].push(state[2].shift());
+			state[2].push(state[2].shift());
+			state[3].unshift(state[3].pop());
+
+			// Add round key
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] ^= keyschedule[nrounds * 4 + col][row];
+			}
+
+			// Set output
+			for (var row = 0; row < AES._blocksize; row++) {
+				for (var col = 0; col < 4; col++)
+					m[offset + col * 4 + row] = state[row][col];
+			}
+
+		},
+
+		_decryptblock: function (c, offset) {
+
+			// Set input
+			for (var row = 0; row < AES._blocksize; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] = c[offset + col * 4 + row];
+			}
+
+			// Add round key
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] ^= keyschedule[nrounds * 4 + col][row];
+			}
+
+			for (var round = 1; round < nrounds; round++) {
+
+				// Inv shift rows
+				state[1].unshift(state[1].pop());
+				state[2].push(state[2].shift());
+				state[2].push(state[2].shift());
+				state[3].push(state[3].shift());
+
+				// Inv sub bytes
+				for (var row = 0; row < 4; row++) {
+					for (var col = 0; col < 4; col++)
+						state[row][col] = INVSBOX[state[row][col]];
+				}
+
+				// Add round key
+				for (var row = 0; row < 4; row++) {
+					for (var col = 0; col < 4; col++)
+						state[row][col] ^= keyschedule[(nrounds - round) * 4 + col][row];
+				}
+
+				// Inv mix columns
+				for (var col = 0; col < 4; col++) {
+
+					var s0 = state[0][col],
+				s1 = state[1][col],
+				s2 = state[2][col],
+				s3 = state[3][col];
+
+					state[0][col] = MULTE[s0] ^ MULTB[s1] ^ MULTD[s2] ^ MULT9[s3];
+					state[1][col] = MULT9[s0] ^ MULTE[s1] ^ MULTB[s2] ^ MULTD[s3];
+					state[2][col] = MULTD[s0] ^ MULT9[s1] ^ MULTE[s2] ^ MULTB[s3];
+					state[3][col] = MULTB[s0] ^ MULTD[s1] ^ MULT9[s2] ^ MULTE[s3];
+
+				}
+
+			}
+
+			// Inv shift rows
+			state[1].unshift(state[1].pop());
+			state[2].push(state[2].shift());
+			state[2].push(state[2].shift());
+			state[3].push(state[3].shift());
+
+			// Inv sub bytes
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] = INVSBOX[state[row][col]];
+			}
+
+			// Add round key
+			for (var row = 0; row < 4; row++) {
+				for (var col = 0; col < 4; col++)
+					state[row][col] ^= keyschedule[col][row];
+			}
+
+			// Set output
+			for (var row = 0; row < AES._blocksize; row++) {
+				for (var col = 0; col < 4; col++)
+					c[offset + col * 4 + row] = state[row][col];
+			}
+
+		},
+
+
+		/**
+		* Private methods
+		*/
+
+		_init: function (k) {
+			keylength = k.length / 4;
+			nrounds = keylength + 6;
+			AES._keyexpansion(k);
+		},
+
+		// Generate a key schedule
+		_keyexpansion: function (k) {
+
+			keyschedule = [];
+
+			for (var row = 0; row < keylength; row++) {
+				keyschedule[row] = [
+			k[row * 4],
+			k[row * 4 + 1],
+			k[row * 4 + 2],
+			k[row * 4 + 3]
+		];
+			}
+
+			for (var row = keylength; row < AES._blocksize * (nrounds + 1); row++) {
+
+				var temp = [
+			keyschedule[row - 1][0],
+			keyschedule[row - 1][1],
+			keyschedule[row - 1][2],
+			keyschedule[row - 1][3]
+		];
+
+				if (row % keylength == 0) {
+
+					// Rot word
+					temp.push(temp.shift());
+
+					// Sub word
+					temp[0] = SBOX[temp[0]];
+					temp[1] = SBOX[temp[1]];
+					temp[2] = SBOX[temp[2]];
+					temp[3] = SBOX[temp[3]];
+
+					temp[0] ^= RCON[row / keylength];
+
+				} else if (keylength > 6 && row % keylength == 4) {
+
+					// Sub word
+					temp[0] = SBOX[temp[0]];
+					temp[1] = SBOX[temp[1]];
+					temp[2] = SBOX[temp[2]];
+					temp[3] = SBOX[temp[3]];
+
+				}
+
+				keyschedule[row] = [
+			keyschedule[row - keylength][0] ^ temp[0],
+			keyschedule[row - keylength][1] ^ temp[1],
+			keyschedule[row - keylength][2] ^ temp[2],
+			keyschedule[row - keylength][3] ^ temp[3]
+		];
+
+			}
+
+		}
+
+	};
+
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.blockmodes.js b/react/src/util/crypto/gen/cryptojs.blockmodes.js
new file mode 100755
index 0000000..e0de9e6
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.blockmodes.js
@@ -0,0 +1,410 @@
+/*!
+* Crypto-JS 2.5.4 BlockModes.js
+* contribution from Simon Greatrix
+*/
+
+(function (C) {
+
+	// Create pad namespace
+	var C_pad = C.pad = {};
+
+	// Calculate the number of padding bytes required.
+	function _requiredPadding(cipher, message) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+		var reqd = blockSizeInBytes - message.length % blockSizeInBytes;
+		return reqd;
+	}
+
+	// Remove padding when the final byte gives the number of padding bytes.
+	var _unpadLength = function (cipher, message, alg, padding) {
+		var pad = message.pop();
+		if (pad == 0) {
+			throw new Error("Invalid zero-length padding specified for " + alg
+			+ ". Wrong cipher specification or key used?");
+		}
+		var maxPad = cipher._blocksize * 4;
+		if (pad > maxPad) {
+			throw new Error("Invalid padding length of " + pad
+			+ " specified for " + alg
+			+ ". Wrong cipher specification or key used?");
+		}
+		for (var i = 1; i < pad; i++) {
+			var b = message.pop();
+			if (padding != undefined && padding != b) {
+				throw new Error("Invalid padding byte of 0x" + b.toString(16)
+				+ " specified for " + alg
+				+ ". Wrong cipher specification or key used?");
+			}
+		}
+	};
+
+	// No-operation padding, used for stream ciphers
+	C_pad.NoPadding = {
+		pad: function (cipher, message) { },
+		unpad: function (cipher, message) { }
+	};
+
+	// Zero Padding.
+	//
+	// If the message is not an exact number of blocks, the final block is
+	// completed with 0x00 bytes. There is no unpadding.
+	C_pad.ZeroPadding = {
+		pad: function (cipher, message) {
+			var blockSizeInBytes = cipher._blocksize * 4;
+			var reqd = message.length % blockSizeInBytes;
+			if (reqd != 0) {
+				for (reqd = blockSizeInBytes - reqd; reqd > 0; reqd--) {
+					message.push(0x00);
+				}
+			}
+		},
+
+		unpad: function (cipher, message) {
+			while (message[message.length - 1] == 0) {
+				message.pop();
+			}
+		}
+	};
+
+	// ISO/IEC 7816-4 padding.
+	//
+	// Pads the plain text with an 0x80 byte followed by as many 0x00
+	// bytes are required to complete the block.
+	C_pad.iso7816 = {
+		pad: function (cipher, message) {
+			var reqd = _requiredPadding(cipher, message);
+			message.push(0x80);
+			for (; reqd > 1; reqd--) {
+				message.push(0x00);
+			}
+		},
+
+		unpad: function (cipher, message) {
+			var padLength;
+			for (padLength = cipher._blocksize * 4; padLength > 0; padLength--) {
+				var b = message.pop();
+				if (b == 0x80) return;
+				if (b != 0x00) {
+					throw new Error("ISO-7816 padding byte must be 0, not 0x" + b.toString(16) + ". Wrong cipher specification or key used?");
+				}
+			}
+			throw new Error("ISO-7816 padded beyond cipher block size. Wrong cipher specification or key used?");
+		}
+	};
+
+	// ANSI X.923 padding
+	//
+	// The final block is padded with zeros except for the last byte of the
+	// last block which contains the number of padding bytes.
+	C_pad.ansix923 = {
+		pad: function (cipher, message) {
+			var reqd = _requiredPadding(cipher, message);
+			for (var i = 1; i < reqd; i++) {
+				message.push(0x00);
+			}
+			message.push(reqd);
+		},
+
+		unpad: function (cipher, message) {
+			_unpadLength(cipher, message, "ANSI X.923", 0);
+		}
+	};
+
+	// ISO 10126
+	//
+	// The final block is padded with random bytes except for the last
+	// byte of the last block which contains the number of padding bytes.
+	C_pad.iso10126 = {
+		pad: function (cipher, message) {
+			var reqd = _requiredPadding(cipher, message);
+			for (var i = 1; i < reqd; i++) {
+				message.push(Math.floor(Math.random() * 256));
+			}
+			message.push(reqd);
+		},
+
+		unpad: function (cipher, message) {
+			_unpadLength(cipher, message, "ISO 10126", undefined);
+		}
+	};
+
+	// PKCS7 padding
+	//
+	// PKCS7 is described in RFC 5652. Padding is in whole bytes. The
+	// value of each added byte is the number of bytes that are added,
+	// i.e. N bytes, each of value N are added.
+	C_pad.pkcs7 = {
+		pad: function (cipher, message) {
+			var reqd = _requiredPadding(cipher, message);
+			for (var i = 0; i < reqd; i++) {
+				message.push(reqd);
+			}
+		},
+
+		unpad: function (cipher, message) {
+			_unpadLength(cipher, message, "PKCS 7", message[message.length - 1]);
+		}
+	};
+
+	// Create mode namespace
+	var C_mode = C.mode = {};
+
+	/**
+	* Mode base "class".
+	*/
+	var Mode = C_mode.Mode = function (padding) {
+		if (padding) {
+			this._padding = padding;
+		}
+	};
+
+	Mode.prototype = {
+		encrypt: function (cipher, m, iv) {
+			this._padding.pad(cipher, m);
+			this._doEncrypt(cipher, m, iv);
+		},
+
+		decrypt: function (cipher, m, iv) {
+			this._doDecrypt(cipher, m, iv);
+			this._padding.unpad(cipher, m);
+		},
+
+		// Default padding
+		_padding: C_pad.iso7816
+	};
+
+
+	/**
+	* Electronic Code Book mode.
+	* 
+	* ECB applies the cipher directly against each block of the input.
+	* 
+	* ECB does not require an initialization vector.
+	*/
+	var ECB = C_mode.ECB = function () {
+		// Call parent constructor
+		Mode.apply(this, arguments);
+	};
+
+	// Inherit from Mode
+	var ECB_prototype = ECB.prototype = new Mode;
+
+	// Concrete steps for Mode template
+	ECB_prototype._doEncrypt = function (cipher, m, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+		// Encrypt each block
+		for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
+			cipher._encryptblock(m, offset);
+		}
+	};
+	ECB_prototype._doDecrypt = function (cipher, c, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+		// Decrypt each block
+		for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
+			cipher._decryptblock(c, offset);
+		}
+	};
+
+	// ECB never uses an IV
+	ECB_prototype.fixOptions = function (options) {
+		options.iv = [];
+	};
+
+
+	/**
+	* Cipher block chaining
+	* 
+	* The first block is XORed with the IV. Subsequent blocks are XOR with the
+	* previous cipher output.
+	*/
+	var CBC = C_mode.CBC = function () {
+		// Call parent constructor
+		Mode.apply(this, arguments);
+	};
+
+	// Inherit from Mode
+	var CBC_prototype = CBC.prototype = new Mode;
+
+	// Concrete steps for Mode template
+	CBC_prototype._doEncrypt = function (cipher, m, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+
+		// Encrypt each block
+		for (var offset = 0; offset < m.length; offset += blockSizeInBytes) {
+			if (offset == 0) {
+				// XOR first block using IV
+				for (var i = 0; i < blockSizeInBytes; i++)
+					m[i] ^= iv[i];
+			} else {
+				// XOR this block using previous crypted block
+				for (var i = 0; i < blockSizeInBytes; i++)
+					m[offset + i] ^= m[offset + i - blockSizeInBytes];
+			}
+			// Encrypt block
+			cipher._encryptblock(m, offset);
+		}
+	};
+	CBC_prototype._doDecrypt = function (cipher, c, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+
+		// At the start, the previously crypted block is the IV
+		var prevCryptedBlock = iv;
+
+		// Decrypt each block
+		for (var offset = 0; offset < c.length; offset += blockSizeInBytes) {
+			// Save this crypted block
+			var thisCryptedBlock = c.slice(offset, offset + blockSizeInBytes);
+			// Decrypt block
+			cipher._decryptblock(c, offset);
+			// XOR decrypted block using previous crypted block
+			for (var i = 0; i < blockSizeInBytes; i++) {
+				c[offset + i] ^= prevCryptedBlock[i];
+			}
+			prevCryptedBlock = thisCryptedBlock;
+		}
+	};
+
+
+	/**
+	* Cipher feed back
+	* 
+	* The cipher output is XORed with the plain text to produce the cipher output,
+	* which is then fed back into the cipher to produce a bit pattern to XOR the
+	* next block with.
+	* 
+	* This is a stream cipher mode and does not require padding.
+	*/
+	var CFB = C_mode.CFB = function () {
+		// Call parent constructor
+		Mode.apply(this, arguments);
+	};
+
+	// Inherit from Mode
+	var CFB_prototype = CFB.prototype = new Mode;
+
+	// Override padding
+	CFB_prototype._padding = C_pad.NoPadding;
+
+	// Concrete steps for Mode template
+	CFB_prototype._doEncrypt = function (cipher, m, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4,
+    keystream = iv.slice(0);
+
+		// Encrypt each byte
+		for (var i = 0; i < m.length; i++) {
+
+			var j = i % blockSizeInBytes;
+			if (j == 0) cipher._encryptblock(keystream, 0);
+
+			m[i] ^= keystream[j];
+			keystream[j] = m[i];
+		}
+	};
+	CFB_prototype._doDecrypt = function (cipher, c, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4,
+			keystream = iv.slice(0);
+
+		// Encrypt each byte
+		for (var i = 0; i < c.length; i++) {
+
+			var j = i % blockSizeInBytes;
+			if (j == 0) cipher._encryptblock(keystream, 0);
+
+			var b = c[i];
+			c[i] ^= keystream[j];
+			keystream[j] = b;
+		}
+	};
+
+
+	/**
+	* Output feed back
+	* 
+	* The cipher repeatedly encrypts its own output. The output is XORed with the
+	* plain text to produce the cipher text.
+	* 
+	* This is a stream cipher mode and does not require padding.
+	*/
+	var OFB = C_mode.OFB = function () {
+		// Call parent constructor
+		Mode.apply(this, arguments);
+	};
+
+	// Inherit from Mode
+	var OFB_prototype = OFB.prototype = new Mode;
+
+	// Override padding
+	OFB_prototype._padding = C_pad.NoPadding;
+
+	// Concrete steps for Mode template
+	OFB_prototype._doEncrypt = function (cipher, m, iv) {
+
+		var blockSizeInBytes = cipher._blocksize * 4,
+			keystream = iv.slice(0);
+
+		// Encrypt each byte
+		for (var i = 0; i < m.length; i++) {
+
+			// Generate keystream
+			if (i % blockSizeInBytes == 0)
+				cipher._encryptblock(keystream, 0);
+
+			// Encrypt byte
+			m[i] ^= keystream[i % blockSizeInBytes];
+
+		}
+	};
+	OFB_prototype._doDecrypt = OFB_prototype._doEncrypt;
+
+	/**
+	* Counter
+	* @author Gergely Risko
+	*
+	* After every block the last 4 bytes of the IV is increased by one
+	* with carry and that IV is used for the next block.
+	*
+	* This is a stream cipher mode and does not require padding.
+	*/
+	var CTR = C_mode.CTR = function () {
+		// Call parent constructor
+		Mode.apply(this, arguments);
+	};
+
+	// Inherit from Mode
+	var CTR_prototype = CTR.prototype = new Mode;
+
+	// Override padding
+	CTR_prototype._padding = C_pad.NoPadding;
+
+	CTR_prototype._doEncrypt = function (cipher, m, iv) {
+		var blockSizeInBytes = cipher._blocksize * 4;
+		var counter = iv.slice(0);
+
+		for (var i = 0; i < m.length; ) {
+			// do not lose iv
+			var keystream = counter.slice(0);
+
+			// Generate keystream for next block
+			cipher._encryptblock(keystream, 0);
+
+			// XOR keystream with block
+			for (var j = 0; i < m.length && j < blockSizeInBytes; j++, i++) {
+				m[i] ^= keystream[j];
+			}
+
+			// Increase counter
+			if (++(counter[blockSizeInBytes - 1]) == 256) {
+				counter[blockSizeInBytes - 1] = 0;
+				if (++(counter[blockSizeInBytes - 2]) == 256) {
+					counter[blockSizeInBytes - 2] = 0;
+					if (++(counter[blockSizeInBytes - 3]) == 256) {
+						counter[blockSizeInBytes - 3] = 0;
+						++(counter[blockSizeInBytes - 4]);
+					}
+				}
+			}
+		}
+	};
+	CTR_prototype._doDecrypt = CTR_prototype._doEncrypt;
+
+})(Crypto);
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.hmac.js b/react/src/util/crypto/gen/cryptojs.hmac.js
new file mode 100755
index 0000000..f33ac76
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.hmac.js
@@ -0,0 +1,43 @@
+/*!
+* Crypto-JS v2.5.4	HMAC.js
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*/
+(function () {
+
+	// Shortcuts
+	var C = Crypto,
+		util = C.util,
+		charenc = C.charenc,
+		UTF8 = charenc.UTF8,
+		Binary = charenc.Binary;
+
+	C.HMAC = function (hasher, message, key, options) {
+
+		// Convert to byte arrays
+		if (message.constructor == String) message = UTF8.stringToBytes(message);
+		if (key.constructor == String) key = UTF8.stringToBytes(key);
+		/* else, assume byte arrays already */
+
+		// Allow arbitrary length keys
+		if (key.length > hasher._blocksize * 4)
+			key = hasher(key, { asBytes: true });
+
+		// XOR keys with pad constants
+		var okey = key.slice(0),
+			ikey = key.slice(0);
+		for (var i = 0; i < hasher._blocksize * 4; i++) {
+			okey[i] ^= 0x5C;
+			ikey[i] ^= 0x36;
+		}
+
+		var hmacbytes = hasher(okey.concat(hasher(ikey.concat(message), { asBytes: true })), { asBytes: true });
+
+		return options && options.asBytes ? hmacbytes :
+		options && options.asString ? Binary.bytesToString(hmacbytes) :
+		util.bytesToHex(hmacbytes);
+
+	};
+
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.js b/react/src/util/crypto/gen/cryptojs.js
new file mode 100755
index 0000000..b8d2b15
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.js
@@ -0,0 +1,149 @@
+/*!
+* Crypto-JS v2.5.4	Crypto.js
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*/
+if (typeof Crypto == "undefined" || !Crypto.util) {
+	(function () {
+
+		var base64map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+		// Global Crypto object
+		var Crypto = window.Crypto = {};
+
+		// Crypto utilities
+		var util = Crypto.util = {
+
+			// Bit-wise rotate left
+			rotl: function (n, b) {
+				return (n << b) | (n >>> (32 - b));
+			},
+
+			// Bit-wise rotate right
+			rotr: function (n, b) {
+				return (n << (32 - b)) | (n >>> b);
+			},
+
+			// Swap big-endian to little-endian and vice versa
+			endian: function (n) {
+
+				// If number given, swap endian
+				if (n.constructor == Number) {
+					return util.rotl(n, 8) & 0x00FF00FF |
+			    util.rotl(n, 24) & 0xFF00FF00;
+				}
+
+				// Else, assume array and swap all items
+				for (var i = 0; i < n.length; i++)
+					n[i] = util.endian(n[i]);
+				return n;
+
+			},
+
+			// Generate an array of any length of random bytes
+			randomBytes: function (n) {
+				for (var bytes = []; n > 0; n--)
+					bytes.push(Math.floor(Math.random() * 256));
+				return bytes;
+			},
+
+			// Convert a byte array to big-endian 32-bit words
+			bytesToWords: function (bytes) {
+				for (var words = [], i = 0, b = 0; i < bytes.length; i++, b += 8)
+					words[b >>> 5] |= (bytes[i] & 0xFF) << (24 - b % 32);
+				return words;
+			},
+
+			// Convert big-endian 32-bit words to a byte array
+			wordsToBytes: function (words) {
+				for (var bytes = [], b = 0; b < words.length * 32; b += 8)
+					bytes.push((words[b >>> 5] >>> (24 - b % 32)) & 0xFF);
+				return bytes;
+			},
+
+			// Convert a byte array to a hex string
+			bytesToHex: function (bytes) {
+				for (var hex = [], i = 0; i < bytes.length; i++) {
+					hex.push((bytes[i] >>> 4).toString(16));
+					hex.push((bytes[i] & 0xF).toString(16));
+				}
+				return hex.join("");
+			},
+
+			// Convert a hex string to a byte array
+			hexToBytes: function (hex) {
+				for (var bytes = [], c = 0; c < hex.length; c += 2)
+					bytes.push(parseInt(hex.substr(c, 2), 16));
+				return bytes;
+			},
+
+			// Convert a byte array to a base-64 string
+			bytesToBase64: function (bytes) {
+				for (var base64 = [], i = 0; i < bytes.length; i += 3) {
+					var triplet = (bytes[i] << 16) | (bytes[i + 1] << 8) | bytes[i + 2];
+					for (var j = 0; j < 4; j++) {
+						if (i * 8 + j * 6 <= bytes.length * 8)
+							base64.push(base64map.charAt((triplet >>> 6 * (3 - j)) & 0x3F));
+						else base64.push("=");
+					}
+				}
+
+				return base64.join("");
+			},
+
+			// Convert a base-64 string to a byte array
+			base64ToBytes: function (base64) {
+				// Remove non-base-64 characters
+				base64 = base64.replace(/[^A-Z0-9+\/]/ig, "");
+
+				for (var bytes = [], i = 0, imod4 = 0; i < base64.length; imod4 = ++i % 4) {
+					if (imod4 == 0) continue;
+					bytes.push(((base64map.indexOf(base64.charAt(i - 1)) & (Math.pow(2, -2 * imod4 + 8) - 1)) << (imod4 * 2)) |
+			        (base64map.indexOf(base64.charAt(i)) >>> (6 - imod4 * 2)));
+				}
+
+				return bytes;
+			}
+
+		};
+
+		// Crypto character encodings
+		var charenc = Crypto.charenc = {};
+
+		// UTF-8 encoding
+		var UTF8 = charenc.UTF8 = {
+
+			// Convert a string to a byte array
+			stringToBytes: function (str) {
+				return Binary.stringToBytes(unescape(encodeURIComponent(str)));
+			},
+
+			// Convert a byte array to a string
+			bytesToString: function (bytes) {
+				return decodeURIComponent(escape(Binary.bytesToString(bytes)));
+			}
+
+		};
+
+		// Binary encoding
+		var Binary = charenc.Binary = {
+
+			// Convert a string to a byte array
+			stringToBytes: function (str) {
+				for (var bytes = [], i = 0; i < str.length; i++)
+					bytes.push(str.charCodeAt(i) & 0xFF);
+				return bytes;
+			},
+
+			// Convert a byte array to a string
+			bytesToString: function (bytes) {
+				for (var str = [], i = 0; i < bytes.length; i++)
+					str.push(String.fromCharCode(bytes[i]));
+				return str.join("");
+			}
+
+		};
+
+	})();
+}
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.pbkdf2.js b/react/src/util/crypto/gen/cryptojs.pbkdf2.js
new file mode 100755
index 0000000..e5be087
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.pbkdf2.js
@@ -0,0 +1,54 @@
+/*!
+* Crypto-JS v2.5.4	PBKDF2.js
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*/
+(function () {
+
+	// Shortcuts
+	var C = Crypto,
+		util = C.util,
+		charenc = C.charenc,
+		UTF8 = charenc.UTF8,
+		Binary = charenc.Binary;
+
+	C.PBKDF2 = function (password, salt, keylen, options) {
+
+		// Convert to byte arrays
+		if (password.constructor == String) password = UTF8.stringToBytes(password);
+		if (salt.constructor == String) salt = UTF8.stringToBytes(salt);
+		/* else, assume byte arrays already */
+
+		// Defaults
+		var hasher = options && options.hasher || C.SHA1,
+			iterations = options && options.iterations || 1;
+
+		// Pseudo-random function
+		function PRF(password, salt) {
+			return C.HMAC(hasher, salt, password, { asBytes: true });
+		}
+
+		// Generate key
+		var derivedKeyBytes = [],
+			blockindex = 1;
+		while (derivedKeyBytes.length < keylen) {
+			var block = PRF(password, salt.concat(util.wordsToBytes([blockindex])));
+			for (var u = block, i = 1; i < iterations; i++) {
+				u = PRF(password, u);
+				for (var j = 0; j < block.length; j++) block[j] ^= u[j];
+			}
+			derivedKeyBytes = derivedKeyBytes.concat(block);
+			blockindex++;
+		}
+
+		// Truncate excess bytes
+		derivedKeyBytes.length = keylen;
+
+		return options && options.asBytes ? derivedKeyBytes :
+		options && options.asString ? Binary.bytesToString(derivedKeyBytes) :
+		util.bytesToHex(derivedKeyBytes);
+
+	};
+
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.ripemd160.js b/react/src/util/crypto/gen/cryptojs.ripemd160.js
new file mode 100755
index 0000000..6917536
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.ripemd160.js
@@ -0,0 +1,164 @@
+/*!
+* Crypto-JS v2.0.0  RIPEMD-160
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*
+* A JavaScript implementation of the RIPEMD-160 Algorithm
+* Version 2.2 Copyright Jeremy Lin, Paul Johnston 2000 - 2009.
+* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+* Distributed under the BSD License
+* See http://pajhome.org.uk/crypt/md5 for details.
+* Also http://www.ocf.berkeley.edu/~jjlin/jsotp/
+* Ported to Crypto-JS by Stefan Thomas.
+*/
+
+(function () {
+	// Shortcuts
+	var C = Crypto,
+	util = C.util,
+	charenc = C.charenc,
+	UTF8 = charenc.UTF8,
+	Binary = charenc.Binary;
+
+	// Convert a byte array to little-endian 32-bit words
+	util.bytesToLWords = function (bytes) {
+
+		var output = Array(bytes.length >> 2);
+		for (var i = 0; i < output.length; i++)
+			output[i] = 0;
+		for (var i = 0; i < bytes.length * 8; i += 8)
+			output[i >> 5] |= (bytes[i / 8] & 0xFF) << (i % 32);
+		return output;
+	};
+
+	// Convert little-endian 32-bit words to a byte array
+	util.lWordsToBytes = function (words) {
+		var output = [];
+		for (var i = 0; i < words.length * 32; i += 8)
+			output.push((words[i >> 5] >>> (i % 32)) & 0xff);
+		return output;
+	};
+
+	// Public API
+	var RIPEMD160 = C.RIPEMD160 = function (message, options) {
+		var digestbytes = util.lWordsToBytes(RIPEMD160._rmd160(message));
+		return options && options.asBytes ? digestbytes :
+			options && options.asString ? Binary.bytesToString(digestbytes) :
+			util.bytesToHex(digestbytes);
+	};
+
+	// The core
+	RIPEMD160._rmd160 = function (message) {
+		// Convert to byte array
+		if (message.constructor == String) message = UTF8.stringToBytes(message);
+
+		var x = util.bytesToLWords(message),
+			len = message.length * 8;
+
+		/* append padding */
+		x[len >> 5] |= 0x80 << (len % 32);
+		x[(((len + 64) >>> 9) << 4) + 14] = len;
+
+		var h0 = 0x67452301;
+		var h1 = 0xefcdab89;
+		var h2 = 0x98badcfe;
+		var h3 = 0x10325476;
+		var h4 = 0xc3d2e1f0;
+
+		for (var i = 0; i < x.length; i += 16) {
+			var T;
+			var A1 = h0, B1 = h1, C1 = h2, D1 = h3, E1 = h4;
+			var A2 = h0, B2 = h1, C2 = h2, D2 = h3, E2 = h4;
+			for (var j = 0; j <= 79; ++j) {
+				T = safe_add(A1, rmd160_f(j, B1, C1, D1));
+				T = safe_add(T, x[i + rmd160_r1[j]]);
+				T = safe_add(T, rmd160_K1(j));
+				T = safe_add(bit_rol(T, rmd160_s1[j]), E1);
+				A1 = E1; E1 = D1; D1 = bit_rol(C1, 10); C1 = B1; B1 = T;
+				T = safe_add(A2, rmd160_f(79 - j, B2, C2, D2));
+				T = safe_add(T, x[i + rmd160_r2[j]]);
+				T = safe_add(T, rmd160_K2(j));
+				T = safe_add(bit_rol(T, rmd160_s2[j]), E2);
+				A2 = E2; E2 = D2; D2 = bit_rol(C2, 10); C2 = B2; B2 = T;
+			}
+			T = safe_add(h1, safe_add(C1, D2));
+			h1 = safe_add(h2, safe_add(D1, E2));
+			h2 = safe_add(h3, safe_add(E1, A2));
+			h3 = safe_add(h4, safe_add(A1, B2));
+			h4 = safe_add(h0, safe_add(B1, C2));
+			h0 = T;
+		}
+		return [h0, h1, h2, h3, h4];
+	}
+
+	function rmd160_f(j, x, y, z) {
+		return (0 <= j && j <= 15) ? (x ^ y ^ z) :
+			(16 <= j && j <= 31) ? (x & y) | (~x & z) :
+			(32 <= j && j <= 47) ? (x | ~y) ^ z :
+			(48 <= j && j <= 63) ? (x & z) | (y & ~z) :
+			(64 <= j && j <= 79) ? x ^ (y | ~z) :
+			"rmd160_f: j out of range";
+	}
+	function rmd160_K1(j) {
+		return (0 <= j && j <= 15) ? 0x00000000 :
+			(16 <= j && j <= 31) ? 0x5a827999 :
+			(32 <= j && j <= 47) ? 0x6ed9eba1 :
+			(48 <= j && j <= 63) ? 0x8f1bbcdc :
+			(64 <= j && j <= 79) ? 0xa953fd4e :
+			"rmd160_K1: j out of range";
+	}
+	function rmd160_K2(j) {
+		return (0 <= j && j <= 15) ? 0x50a28be6 :
+			(16 <= j && j <= 31) ? 0x5c4dd124 :
+			(32 <= j && j <= 47) ? 0x6d703ef3 :
+			(48 <= j && j <= 63) ? 0x7a6d76e9 :
+			(64 <= j && j <= 79) ? 0x00000000 :
+			"rmd160_K2: j out of range";
+	}
+	var rmd160_r1 = [
+		0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+		7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
+		3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
+		1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
+		4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13
+	];
+	var rmd160_r2 = [
+		5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
+		6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
+		15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
+		8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
+		12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+	];
+	var rmd160_s1 = [
+		11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
+		7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
+		11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
+		11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
+		9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6
+	];
+	var rmd160_s2 = [
+		8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
+		9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
+		9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
+		15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
+		8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+	];
+
+	/*
+	* Add integers, wrapping at 2^32. This uses 16-bit operations internally
+	* to work around bugs in some JS interpreters.
+	*/
+	function safe_add(x, y) {
+		var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+		var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+		return (msw << 16) | (lsw & 0xFFFF);
+	}
+
+	/*
+	* Bitwise rotate a 32-bit number to the left.
+	*/
+	function bit_rol(num, cnt) {
+		return (num << cnt) | (num >>> (32 - cnt));
+	}
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/cryptojs.sha256.js b/react/src/util/crypto/gen/cryptojs.sha256.js
new file mode 100755
index 0000000..8209973
--- /dev/null
+++ b/react/src/util/crypto/gen/cryptojs.sha256.js
@@ -0,0 +1,135 @@
+/*!
+* Crypto-JS v2.5.4	SHA256.js
+* http://code.google.com/p/crypto-js/
+* Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
+* http://code.google.com/p/crypto-js/wiki/License
+*/
+(function () {
+
+	// Shortcuts
+	var C = Crypto,
+		util = C.util,
+		charenc = C.charenc,
+		UTF8 = charenc.UTF8,
+		Binary = charenc.Binary;
+
+	// Constants
+	var K = [0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
+        0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
+        0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
+        0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
+        0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
+        0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
+        0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
+        0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
+        0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
+        0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
+        0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
+        0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
+        0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
+        0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
+        0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
+        0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2];
+
+	// Public API
+	var SHA256 = C.SHA256 = function (message, options) {
+		var digestbytes = util.wordsToBytes(SHA256._sha256(message));
+		return options && options.asBytes ? digestbytes :
+	    options && options.asString ? Binary.bytesToString(digestbytes) :
+	    util.bytesToHex(digestbytes);
+	};
+
+	// The core
+	SHA256._sha256 = function (message) {
+
+		// Convert to byte array
+		if (message.constructor == String) message = UTF8.stringToBytes(message);
+		/* else, assume byte array already */
+
+		var m = util.bytesToWords(message),
+		l = message.length * 8,
+		H = [0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+				0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19],
+		w = [],
+		a, b, c, d, e, f, g, h, i, j,
+		t1, t2;
+
+		// Padding
+		m[l >> 5] |= 0x80 << (24 - l % 32);
+		m[((l + 64 >> 9) << 4) + 15] = l;
+
+		for (var i = 0; i < m.length; i += 16) {
+
+			a = H[0];
+			b = H[1];
+			c = H[2];
+			d = H[3];
+			e = H[4];
+			f = H[5];
+			g = H[6];
+			h = H[7];
+
+			for (var j = 0; j < 64; j++) {
+
+				if (j < 16) w[j] = m[j + i];
+				else {
+
+					var gamma0x = w[j - 15],
+				gamma1x = w[j - 2],
+				gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
+				            ((gamma0x << 14) | (gamma0x >>> 18)) ^
+				            (gamma0x >>> 3),
+				gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
+				            ((gamma1x << 13) | (gamma1x >>> 19)) ^
+				            (gamma1x >>> 10);
+
+					w[j] = gamma0 + (w[j - 7] >>> 0) +
+				    gamma1 + (w[j - 16] >>> 0);
+
+				}
+
+				var ch = e & f ^ ~e & g,
+			maj = a & b ^ a & c ^ b & c,
+			sigma0 = ((a << 30) | (a >>> 2)) ^
+			            ((a << 19) | (a >>> 13)) ^
+			            ((a << 10) | (a >>> 22)),
+			sigma1 = ((e << 26) | (e >>> 6)) ^
+			            ((e << 21) | (e >>> 11)) ^
+			            ((e << 7) | (e >>> 25));
+
+
+				t1 = (h >>> 0) + sigma1 + ch + (K[j]) + (w[j] >>> 0);
+				t2 = sigma0 + maj;
+
+				h = g;
+				g = f;
+				f = e;
+				e = (d + t1) >>> 0;
+				d = c;
+				c = b;
+				b = a;
+				a = (t1 + t2) >>> 0;
+
+			}
+
+			H[0] += a;
+			H[1] += b;
+			H[2] += c;
+			H[3] += d;
+			H[4] += e;
+			H[5] += f;
+			H[6] += g;
+			H[7] += h;
+
+		}
+
+		return H;
+
+	};
+
+	// Package private blocksize
+	SHA256._blocksize = 16;
+
+	SHA256._digestsize = 32;
+
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/ellipticcurve.js b/react/src/util/crypto/gen/ellipticcurve.js
new file mode 100755
index 0000000..d41fee6
--- /dev/null
+++ b/react/src/util/crypto/gen/ellipticcurve.js
@@ -0,0 +1,669 @@
+//https://raw.github.com/bitcoinjs/bitcoinjs-lib/faa10f0f6a1fff0b9a99fffb9bc30cee33b17212/src/ecdsa.js
+/*!
+* Basic Javascript Elliptic Curve implementation
+* Ported loosely from BouncyCastle's Java EC code
+* Only Fp curves implemented for now
+* 
+* Copyright Tom Wu, bitaddress.org  BSD License.
+* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
+*/
+(function () {
+
+	// Constructor function of Global EllipticCurve object
+	var ec = window.EllipticCurve = function () { };
+
+
+	// ----------------
+	// ECFieldElementFp constructor
+	// q instanceof BigInteger
+	// x instanceof BigInteger
+	ec.FieldElementFp = function (q, x) {
+		this.x = x;
+		// TODO if(x.compareTo(q) >= 0) error
+		this.q = q;
+	};
+
+	ec.FieldElementFp.prototype.equals = function (other) {
+		if (other == this) return true;
+		return (this.q.equals(other.q) && this.x.equals(other.x));
+	};
+
+	ec.FieldElementFp.prototype.toBigInteger = function () {
+		return this.x;
+	};
+
+	ec.FieldElementFp.prototype.negate = function () {
+		return new ec.FieldElementFp(this.q, this.x.negate().mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.add = function (b) {
+		return new ec.FieldElementFp(this.q, this.x.add(b.toBigInteger()).mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.subtract = function (b) {
+		return new ec.FieldElementFp(this.q, this.x.subtract(b.toBigInteger()).mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.multiply = function (b) {
+		return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger()).mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.square = function () {
+		return new ec.FieldElementFp(this.q, this.x.square().mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.divide = function (b) {
+		return new ec.FieldElementFp(this.q, this.x.multiply(b.toBigInteger().modInverse(this.q)).mod(this.q));
+	};
+
+	ec.FieldElementFp.prototype.getByteLength = function () {
+		return Math.floor((this.toBigInteger().bitLength() + 7) / 8);
+	};
+
+	// D.1.4 91
+	/**
+	* return a sqrt root - the routine verifies that the calculation
+	* returns the right value - if none exists it returns null.
+	* 
+	* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+	* Ported to JavaScript by bitaddress.org
+	*/
+	ec.FieldElementFp.prototype.sqrt = function () {
+		if (!this.q.testBit(0)) throw new Error("even value of q");
+
+		// p mod 4 == 3
+		if (this.q.testBit(1)) {
+			// z = g^(u+1) + p, p = 4u + 3
+			var z = new ec.FieldElementFp(this.q, this.x.modPow(this.q.shiftRight(2).add(BigInteger.ONE), this.q));
+			return z.square().equals(this) ? z : null;
+		}
+
+		// p mod 4 == 1
+		var qMinusOne = this.q.subtract(BigInteger.ONE);
+		var legendreExponent = qMinusOne.shiftRight(1);
+		if (!(this.x.modPow(legendreExponent, this.q).equals(BigInteger.ONE))) return null;
+		var u = qMinusOne.shiftRight(2);
+		var k = u.shiftLeft(1).add(BigInteger.ONE);
+		var Q = this.x;
+		var fourQ = Q.shiftLeft(2).mod(this.q);
+		var U, V;
+
+		do {
+			var rand = new SecureRandom();
+			var P;
+			do {
+				P = new BigInteger(this.q.bitLength(), rand);
+			}
+			while (P.compareTo(this.q) >= 0 || !(P.multiply(P).subtract(fourQ).modPow(legendreExponent, this.q).equals(qMinusOne)));
+
+			var result = ec.FieldElementFp.fastLucasSequence(this.q, P, Q, k);
+
+			U = result[0];
+			V = result[1];
+			if (V.multiply(V).mod(this.q).equals(fourQ)) {
+				// Integer division by 2, mod q
+				if (V.testBit(0)) {
+					V = V.add(this.q);
+				}
+				V = V.shiftRight(1);
+				return new ec.FieldElementFp(this.q, V);
+			}
+		}
+		while (U.equals(BigInteger.ONE) || U.equals(qMinusOne));
+
+		return null;
+	};
+
+	/*
+	* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+	* Ported to JavaScript by bitaddress.org
+	*/
+	ec.FieldElementFp.fastLucasSequence = function (p, P, Q, k) {
+		// TODO Research and apply "common-multiplicand multiplication here"
+
+		var n = k.bitLength();
+		var s = k.getLowestSetBit();
+		var Uh = BigInteger.ONE;
+		var Vl = BigInteger.TWO;
+		var Vh = P;
+		var Ql = BigInteger.ONE;
+		var Qh = BigInteger.ONE;
+
+		for (var j = n - 1; j >= s + 1; --j) {
+			Ql = Ql.multiply(Qh).mod(p);
+			if (k.testBit(j)) {
+				Qh = Ql.multiply(Q).mod(p);
+				Uh = Uh.multiply(Vh).mod(p);
+				Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
+				Vh = Vh.multiply(Vh).subtract(Qh.shiftLeft(1)).mod(p);
+			}
+			else {
+				Qh = Ql;
+				Uh = Uh.multiply(Vl).subtract(Ql).mod(p);
+				Vh = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
+				Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p);
+			}
+		}
+
+		Ql = Ql.multiply(Qh).mod(p);
+		Qh = Ql.multiply(Q).mod(p);
+		Uh = Uh.multiply(Vl).subtract(Ql).mod(p);
+		Vl = Vh.multiply(Vl).subtract(P.multiply(Ql)).mod(p);
+		Ql = Ql.multiply(Qh).mod(p);
+
+		for (var j = 1; j <= s; ++j) {
+			Uh = Uh.multiply(Vl).mod(p);
+			Vl = Vl.multiply(Vl).subtract(Ql.shiftLeft(1)).mod(p);
+			Ql = Ql.multiply(Ql).mod(p);
+		}
+
+		return [Uh, Vl];
+	};
+
+	// ----------------
+	// ECPointFp constructor
+	ec.PointFp = function (curve, x, y, z, compressed) {
+		this.curve = curve;
+		this.x = x;
+		this.y = y;
+		// Projective coordinates: either zinv == null or z * zinv == 1
+		// z and zinv are just BigIntegers, not fieldElements
+		if (z == null) {
+			this.z = BigInteger.ONE;
+		}
+		else {
+			this.z = z;
+		}
+		this.zinv = null;
+		// compression flag
+		this.compressed = !!compressed;
+	};
+
+	ec.PointFp.prototype.getX = function () {
+		if (this.zinv == null) {
+			this.zinv = this.z.modInverse(this.curve.q);
+		}
+		var r = this.x.toBigInteger().multiply(this.zinv);
+		this.curve.reduce(r);
+		return this.curve.fromBigInteger(r);
+	};
+
+	ec.PointFp.prototype.getY = function () {
+		if (this.zinv == null) {
+			this.zinv = this.z.modInverse(this.curve.q);
+		}
+		var r = this.y.toBigInteger().multiply(this.zinv);
+		this.curve.reduce(r);
+		return this.curve.fromBigInteger(r);
+	};
+
+	ec.PointFp.prototype.equals = function (other) {
+		if (other == this) return true;
+		if (this.isInfinity()) return other.isInfinity();
+		if (other.isInfinity()) return this.isInfinity();
+		var u, v;
+		// u = Y2 * Z1 - Y1 * Z2
+		u = other.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(other.z)).mod(this.curve.q);
+		if (!u.equals(BigInteger.ZERO)) return false;
+		// v = X2 * Z1 - X1 * Z2
+		v = other.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(other.z)).mod(this.curve.q);
+		return v.equals(BigInteger.ZERO);
+	};
+
+	ec.PointFp.prototype.isInfinity = function () {
+		if ((this.x == null) && (this.y == null)) return true;
+		return this.z.equals(BigInteger.ZERO) && !this.y.toBigInteger().equals(BigInteger.ZERO);
+	};
+
+	ec.PointFp.prototype.negate = function () {
+		return new ec.PointFp(this.curve, this.x, this.y.negate(), this.z);
+	};
+
+	ec.PointFp.prototype.add = function (b) {
+		if (this.isInfinity()) return b;
+		if (b.isInfinity()) return this;
+
+		// u = Y2 * Z1 - Y1 * Z2
+		var u = b.y.toBigInteger().multiply(this.z).subtract(this.y.toBigInteger().multiply(b.z)).mod(this.curve.q);
+		// v = X2 * Z1 - X1 * Z2
+		var v = b.x.toBigInteger().multiply(this.z).subtract(this.x.toBigInteger().multiply(b.z)).mod(this.curve.q);
+
+
+		if (BigInteger.ZERO.equals(v)) {
+			if (BigInteger.ZERO.equals(u)) {
+				return this.twice(); // this == b, so double
+			}
+			return this.curve.getInfinity(); // this = -b, so infinity
+		}
+
+		var THREE = new BigInteger("3");
+		var x1 = this.x.toBigInteger();
+		var y1 = this.y.toBigInteger();
+		var x2 = b.x.toBigInteger();
+		var y2 = b.y.toBigInteger();
+
+		var v2 = v.square();
+		var v3 = v2.multiply(v);
+		var x1v2 = x1.multiply(v2);
+		var zu2 = u.square().multiply(this.z);
+
+		// x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
+		var x3 = zu2.subtract(x1v2.shiftLeft(1)).multiply(b.z).subtract(v3).multiply(v).mod(this.curve.q);
+		// y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
+		var y3 = x1v2.multiply(THREE).multiply(u).subtract(y1.multiply(v3)).subtract(zu2.multiply(u)).multiply(b.z).add(u.multiply(v3)).mod(this.curve.q);
+		// z3 = v^3 * z1 * z2
+		var z3 = v3.multiply(this.z).multiply(b.z).mod(this.curve.q);
+
+		return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
+	};
+
+	ec.PointFp.prototype.twice = function () {
+		if (this.isInfinity()) return this;
+		if (this.y.toBigInteger().signum() == 0) return this.curve.getInfinity();
+
+		// TODO: optimized handling of constants
+		var THREE = new BigInteger("3");
+		var x1 = this.x.toBigInteger();
+		var y1 = this.y.toBigInteger();
+
+		var y1z1 = y1.multiply(this.z);
+		var y1sqz1 = y1z1.multiply(y1).mod(this.curve.q);
+		var a = this.curve.a.toBigInteger();
+
+		// w = 3 * x1^2 + a * z1^2
+		var w = x1.square().multiply(THREE);
+		if (!BigInteger.ZERO.equals(a)) {
+			w = w.add(this.z.square().multiply(a));
+		}
+		w = w.mod(this.curve.q);
+		//this.curve.reduce(w);
+		// x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
+		var x3 = w.square().subtract(x1.shiftLeft(3).multiply(y1sqz1)).shiftLeft(1).multiply(y1z1).mod(this.curve.q);
+		// y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
+		var y3 = w.multiply(THREE).multiply(x1).subtract(y1sqz1.shiftLeft(1)).shiftLeft(2).multiply(y1sqz1).subtract(w.square().multiply(w)).mod(this.curve.q);
+		// z3 = 8 * (y1 * z1)^3
+		var z3 = y1z1.square().multiply(y1z1).shiftLeft(3).mod(this.curve.q);
+
+		return new ec.PointFp(this.curve, this.curve.fromBigInteger(x3), this.curve.fromBigInteger(y3), z3);
+	};
+
+	// Simple NAF (Non-Adjacent Form) multiplication algorithm
+	// TODO: modularize the multiplication algorithm
+	ec.PointFp.prototype.multiply = function (k) {
+		if (this.isInfinity()) return this;
+		if (k.signum() == 0) return this.curve.getInfinity();
+
+		var e = k;
+		var h = e.multiply(new BigInteger("3"));
+
+		var neg = this.negate();
+		var R = this;
+
+		var i;
+		for (i = h.bitLength() - 2; i > 0; --i) {
+			R = R.twice();
+
+			var hBit = h.testBit(i);
+			var eBit = e.testBit(i);
+
+			if (hBit != eBit) {
+				R = R.add(hBit ? this : neg);
+			}
+		}
+
+		return R;
+	};
+
+	// Compute this*j + x*k (simultaneous multiplication)
+	ec.PointFp.prototype.multiplyTwo = function (j, x, k) {
+		var i;
+		if (j.bitLength() > k.bitLength())
+			i = j.bitLength() - 1;
+		else
+			i = k.bitLength() - 1;
+
+		var R = this.curve.getInfinity();
+		var both = this.add(x);
+		while (i >= 0) {
+			R = R.twice();
+			if (j.testBit(i)) {
+				if (k.testBit(i)) {
+					R = R.add(both);
+				}
+				else {
+					R = R.add(this);
+				}
+			}
+			else {
+				if (k.testBit(i)) {
+					R = R.add(x);
+				}
+			}
+			--i;
+		}
+
+		return R;
+	};
+
+	// patched by bitaddress.org and Casascius for use with Bitcoin.ECKey
+	// patched by coretechs to support compressed public keys
+	ec.PointFp.prototype.getEncoded = function (compressed) {
+		var x = this.getX().toBigInteger();
+		var y = this.getY().toBigInteger();
+		var len = 32; // integerToBytes will zero pad if integer is less than 32 bytes. 32 bytes length is required by the Bitcoin protocol.
+		var enc = ec.integerToBytes(x, len);
+
+		// when compressed prepend byte depending if y point is even or odd 
+		if (compressed) {
+			if (y.isEven()) {
+				enc.unshift(0x02);
+			}
+			else {
+				enc.unshift(0x03);
+			}
+		}
+		else {
+			enc.unshift(0x04);
+			enc = enc.concat(ec.integerToBytes(y, len)); // uncompressed public key appends the bytes of the y point
+		}
+		return enc;
+	};
+
+	ec.PointFp.decodeFrom = function (curve, enc) {
+		var type = enc[0];
+		var dataLen = enc.length - 1;
+
+		// Extract x and y as byte arrays
+		var xBa = enc.slice(1, 1 + dataLen / 2);
+		var yBa = enc.slice(1 + dataLen / 2, 1 + dataLen);
+
+		// Prepend zero byte to prevent interpretation as negative integer
+		xBa.unshift(0);
+		yBa.unshift(0);
+
+		// Convert to BigIntegers
+		var x = new BigInteger(xBa);
+		var y = new BigInteger(yBa);
+
+		// Return point
+		return new ec.PointFp(curve, curve.fromBigInteger(x), curve.fromBigInteger(y));
+	};
+
+	ec.PointFp.prototype.add2D = function (b) {
+		if (this.isInfinity()) return b;
+		if (b.isInfinity()) return this;
+
+		if (this.x.equals(b.x)) {
+			if (this.y.equals(b.y)) {
+				// this = b, i.e. this must be doubled
+				return this.twice();
+			}
+			// this = -b, i.e. the result is the point at infinity
+			return this.curve.getInfinity();
+		}
+
+		var x_x = b.x.subtract(this.x);
+		var y_y = b.y.subtract(this.y);
+		var gamma = y_y.divide(x_x);
+
+		var x3 = gamma.square().subtract(this.x).subtract(b.x);
+		var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
+
+		return new ec.PointFp(this.curve, x3, y3);
+	};
+
+	ec.PointFp.prototype.twice2D = function () {
+		if (this.isInfinity()) return this;
+		if (this.y.toBigInteger().signum() == 0) {
+			// if y1 == 0, then (x1, y1) == (x1, -y1)
+			// and hence this = -this and thus 2(x1, y1) == infinity
+			return this.curve.getInfinity();
+		}
+
+		var TWO = this.curve.fromBigInteger(BigInteger.valueOf(2));
+		var THREE = this.curve.fromBigInteger(BigInteger.valueOf(3));
+		var gamma = this.x.square().multiply(THREE).add(this.curve.a).divide(this.y.multiply(TWO));
+
+		var x3 = gamma.square().subtract(this.x.multiply(TWO));
+		var y3 = gamma.multiply(this.x.subtract(x3)).subtract(this.y);
+
+		return new ec.PointFp(this.curve, x3, y3);
+	};
+
+	ec.PointFp.prototype.multiply2D = function (k) {
+		if (this.isInfinity()) return this;
+		if (k.signum() == 0) return this.curve.getInfinity();
+
+		var e = k;
+		var h = e.multiply(new BigInteger("3"));
+
+		var neg = this.negate();
+		var R = this;
+
+		var i;
+		for (i = h.bitLength() - 2; i > 0; --i) {
+			R = R.twice();
+
+			var hBit = h.testBit(i);
+			var eBit = e.testBit(i);
+
+			if (hBit != eBit) {
+				R = R.add2D(hBit ? this : neg);
+			}
+		}
+
+		return R;
+	};
+
+	ec.PointFp.prototype.isOnCurve = function () {
+		var x = this.getX().toBigInteger();
+		var y = this.getY().toBigInteger();
+		var a = this.curve.getA().toBigInteger();
+		var b = this.curve.getB().toBigInteger();
+		var n = this.curve.getQ();
+		var lhs = y.multiply(y).mod(n);
+		var rhs = x.multiply(x).multiply(x).add(a.multiply(x)).add(b).mod(n);
+		return lhs.equals(rhs);
+	};
+
+	ec.PointFp.prototype.toString = function () {
+		return '(' + this.getX().toBigInteger().toString() + ',' + this.getY().toBigInteger().toString() + ')';
+	};
+
+	/**
+	* Validate an elliptic curve point.
+	*
+	* See SEC 1, section 3.2.2.1: Elliptic Curve Public Key Validation Primitive
+	*/
+	ec.PointFp.prototype.validate = function () {
+		var n = this.curve.getQ();
+
+		// Check Q != O
+		if (this.isInfinity()) {
+			throw new Error("Point is at infinity.");
+		}
+
+		// Check coordinate bounds
+		var x = this.getX().toBigInteger();
+		var y = this.getY().toBigInteger();
+		if (x.compareTo(BigInteger.ONE) < 0 || x.compareTo(n.subtract(BigInteger.ONE)) > 0) {
+			throw new Error('x coordinate out of bounds');
+		}
+		if (y.compareTo(BigInteger.ONE) < 0 || y.compareTo(n.subtract(BigInteger.ONE)) > 0) {
+			throw new Error('y coordinate out of bounds');
+		}
+
+		// Check y^2 = x^3 + ax + b (mod n)
+		if (!this.isOnCurve()) {
+			throw new Error("Point is not on the curve.");
+		}
+
+		// Check nQ = 0 (Q is a scalar multiple of G)
+		if (this.multiply(n).isInfinity()) {
+			// TODO: This check doesn't work - fix.
+			throw new Error("Point is not a scalar multiple of G.");
+		}
+
+		return true;
+	};
+
+
+
+
+	// ----------------
+	// ECCurveFp constructor
+	ec.CurveFp = function (q, a, b) {
+		this.q = q;
+		this.a = this.fromBigInteger(a);
+		this.b = this.fromBigInteger(b);
+		this.infinity = new ec.PointFp(this, null, null);
+		this.reducer = new Barrett(this.q);
+	}
+
+	ec.CurveFp.prototype.getQ = function () {
+		return this.q;
+	};
+
+	ec.CurveFp.prototype.getA = function () {
+		return this.a;
+	};
+
+	ec.CurveFp.prototype.getB = function () {
+		return this.b;
+	};
+
+	ec.CurveFp.prototype.equals = function (other) {
+		if (other == this) return true;
+		return (this.q.equals(other.q) && this.a.equals(other.a) && this.b.equals(other.b));
+	};
+
+	ec.CurveFp.prototype.getInfinity = function () {
+		return this.infinity;
+	};
+
+	ec.CurveFp.prototype.fromBigInteger = function (x) {
+		return new ec.FieldElementFp(this.q, x);
+	};
+
+	ec.CurveFp.prototype.reduce = function (x) {
+		this.reducer.reduce(x);
+	};
+
+	// for now, work with hex strings because they're easier in JS
+	// compressed support added by bitaddress.org
+	ec.CurveFp.prototype.decodePointHex = function (s) {
+		var firstByte = parseInt(s.substr(0, 2), 16);
+		switch (firstByte) { // first byte
+			case 0:
+				return this.infinity;
+			case 2: // compressed
+			case 3: // compressed
+				var yTilde = firstByte & 1;
+				var xHex = s.substr(2, s.length - 2);
+				var X1 = new BigInteger(xHex, 16);
+				return this.decompressPoint(yTilde, X1);
+			case 4: // uncompressed
+			case 6: // hybrid
+			case 7: // hybrid
+				var len = (s.length - 2) / 2;
+				var xHex = s.substr(2, len);
+				var yHex = s.substr(len + 2, len);
+
+				return new ec.PointFp(this,
+					this.fromBigInteger(new BigInteger(xHex, 16)),
+					this.fromBigInteger(new BigInteger(yHex, 16)));
+
+			default: // unsupported
+				return null;
+		}
+	};
+
+	ec.CurveFp.prototype.encodePointHex = function (p) {
+		if (p.isInfinity()) return "00";
+		var xHex = p.getX().toBigInteger().toString(16);
+		var yHex = p.getY().toBigInteger().toString(16);
+		var oLen = this.getQ().toString(16).length;
+		if ((oLen % 2) != 0) oLen++;
+		while (xHex.length < oLen) {
+			xHex = "0" + xHex;
+		}
+		while (yHex.length < oLen) {
+			yHex = "0" + yHex;
+		}
+		return "04" + xHex + yHex;
+	};
+
+	/*
+	* Copyright (c) 2000 - 2011 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
+	* Ported to JavaScript by bitaddress.org
+	*
+	* Number yTilde
+	* BigInteger X1
+	*/
+	ec.CurveFp.prototype.decompressPoint = function (yTilde, X1) {
+		var x = this.fromBigInteger(X1);
+		var alpha = x.multiply(x.square().add(this.getA())).add(this.getB());
+		var beta = alpha.sqrt();
+		// if we can't find a sqrt we haven't got a point on the curve - run!
+		if (beta == null) throw new Error("Invalid point compression");
+		var betaValue = beta.toBigInteger();
+		var bit0 = betaValue.testBit(0) ? 1 : 0;
+		if (bit0 != yTilde) {
+			// Use the other root
+			beta = this.fromBigInteger(this.getQ().subtract(betaValue));
+		}
+		return new ec.PointFp(this, x, beta, null, true);
+	};
+
+
+	ec.fromHex = function (s) { return new BigInteger(s, 16); };
+
+	ec.integerToBytes = function (i, len) {
+		var bytes = i.toByteArrayUnsigned();
+		if (len < bytes.length) {
+			bytes = bytes.slice(bytes.length - len);
+		} else while (len > bytes.length) {
+			bytes.unshift(0);
+		}
+		return bytes;
+	};
+
+
+	// Named EC curves
+	// ----------------
+	// X9ECParameters constructor
+	ec.X9Parameters = function (curve, g, n, h) {
+		this.curve = curve;
+		this.g = g;
+		this.n = n;
+		this.h = h;
+	}
+	ec.X9Parameters.prototype.getCurve = function () { return this.curve; };
+	ec.X9Parameters.prototype.getG = function () { return this.g; };
+	ec.X9Parameters.prototype.getN = function () { return this.n; };
+	ec.X9Parameters.prototype.getH = function () { return this.h; };
+
+	// secp256k1 is the Curve used by Bitcoin
+	ec.secNamedCurves = {
+		// used by Bitcoin
+		"secp256k1": function () {
+			// p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1
+			var p = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F");
+			var a = BigInteger.ZERO;
+			var b = ec.fromHex("7");
+			var n = ec.fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141");
+			var h = BigInteger.ONE;
+			var curve = new ec.CurveFp(p, a, b);
+			var G = curve.decodePointHex("04"
+					+ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798"
+					+ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8");
+			return new ec.X9Parameters(curve, G, n, h);
+		}
+	};
+
+	// secp256k1 called by Bitcoin's ECKEY
+	ec.getSECCurveByName = function (name) {
+		if (ec.secNamedCurves[name] == undefined) return null;
+		return ec.secNamedCurves[name]();
+	}
+})();
\ No newline at end of file
diff --git a/react/src/util/crypto/gen/securerandom.js b/react/src/util/crypto/gen/securerandom.js
new file mode 100755
index 0000000..51b8349
--- /dev/null
+++ b/react/src/util/crypto/gen/securerandom.js
@@ -0,0 +1,187 @@
+/*!
+* Random number generator with ArcFour PRNG
+*
+* NOTE: For best results, put code like
+* <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'>
+* in your main HTML document.
+*
+* Copyright Tom Wu, bitaddress.org  BSD License.
+* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
+*/
+(function () {
+
+	// Constructor function of Global SecureRandom object
+	var sr = window.SecureRandom = function () { };
+
+	// Properties
+	sr.state;
+	sr.pool;
+	sr.pptr;
+
+	// Pool size must be a multiple of 4 and greater than 32.
+	// An array of bytes the size of the pool will be passed to init()
+	sr.poolSize = 256;
+
+	// --- object methods ---
+
+	// public method
+	// ba: byte array
+	sr.prototype.nextBytes = function (ba) {
+		var i;
+		if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
+			try {
+				var rvBytes = new Uint8Array(ba.length);
+				window.crypto.getRandomValues(rvBytes);
+				for (i = 0; i < ba.length; ++i)
+					ba[i] = sr.getByte() ^ rvBytes[i];
+				return;
+			} catch (e) {
+				alert(e);
+			}
+		}
+		for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte();
+	};
+
+
+	// --- static methods ---
+
+	// Mix in the current time (w/milliseconds) into the pool
+	// NOTE: this method should be called from body click/keypress event handlers to increase entropy
+	sr.seedTime = function () {
+		sr.seedInt(new Date().getTime());
+	}
+
+	sr.getByte = function () {
+		/*if(!ninja.seeder.isDone()) {
+			alert("Premature initialisation of the random generator. Something is really wrong, do not generate wallets.");
+			return NaN;
+		}*/
+
+		if (sr.state == null) {
+			sr.seedTime();
+			sr.state = sr.ArcFour(); // Plug in your RNG constructor here
+			sr.state.init(sr.pool);
+			sr.pptr = 0;
+		}
+		// TODO: allow reseeding after first request
+		return sr.state.next();
+	}
+
+	// Mix in a 32-bit integer into the pool
+	sr.seedInt = function (x) {
+		sr.seedInt8(x);
+		sr.seedInt8((x >> 8));
+		sr.seedInt8((x >> 16));
+		sr.seedInt8((x >> 24));
+	}
+
+	// Mix in a 16-bit integer into the pool
+	sr.seedInt16 = function (x) {
+		sr.seedInt8(x);
+		sr.seedInt8((x >> 8));
+	}
+
+	// Mix in a 8-bit integer into the pool
+	sr.seedInt8 = function (x) {
+		sr.pool[sr.pptr++] ^= x & 255;
+		if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
+	}
+
+	// Arcfour is a PRNG
+	sr.ArcFour = function () {
+		function Arcfour() {
+			this.i = 0;
+			this.j = 0;
+			this.S = new Array();
+		}
+
+		// Initialize arcfour context from key, an array of ints, each from [0..255]
+		function ARC4init(key) {
+			var i, j, t;
+			for (i = 0; i < 256; ++i)
+				this.S[i] = i;
+			j = 0;
+			for (i = 0; i < 256; ++i) {
+				j = (j + this.S[i] + key[i % key.length]) & 255;
+				t = this.S[i];
+				this.S[i] = this.S[j];
+				this.S[j] = t;
+			}
+			this.i = 0;
+			this.j = 0;
+		}
+
+		function ARC4next() {
+			var t;
+			this.i = (this.i + 1) & 255;
+			this.j = (this.j + this.S[this.i]) & 255;
+			t = this.S[this.i];
+			this.S[this.i] = this.S[this.j];
+			this.S[this.j] = t;
+			return this.S[(t + this.S[this.i]) & 255];
+		}
+
+		Arcfour.prototype.init = ARC4init;
+		Arcfour.prototype.next = ARC4next;
+
+		return new Arcfour();
+	};
+
+
+	// Initialize the pool with junk if needed.
+	if (sr.pool == null) {
+		sr.pool = new Array();
+		sr.pptr = 0;
+		var t;
+		if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
+			try {
+				// Use webcrypto if available
+				var ua = new Uint8Array(sr.poolSize);
+				window.crypto.getRandomValues(ua);
+				for (t = 0; t < sr.poolSize; ++t)
+					sr.pool[sr.pptr++] = ua[t];
+			} catch (e) { alert(e); }
+		}
+		while (sr.pptr < sr.poolSize) {  // extract some randomness from Math.random()
+			t = Math.floor(65536 * Math.random());
+			sr.pool[sr.pptr++] = t >>> 8;
+			sr.pool[sr.pptr++] = t & 255;
+		}
+		sr.pptr = Math.floor(sr.poolSize * Math.random());
+		sr.seedTime();
+		// entropy
+		var entropyStr = "";
+		// screen size and color depth: ~4.8 to ~5.4 bits
+		entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth);
+		entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth);
+		// time zone offset: ~4 bits
+		var dateObj = new Date();
+		var timeZoneOffset = dateObj.getTimezoneOffset();
+		entropyStr += timeZoneOffset;
+		// user agent: ~8.3 to ~11.6 bits
+		entropyStr += navigator.userAgent;
+		// browser plugin details: ~16.2 to ~21.8 bits
+		var pluginsStr = "";
+		for (var i = 0; i < navigator.plugins.length; i++) {
+			pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", ";
+		}
+		var mimeTypesStr = "";
+		for (var i = 0; i < navigator.mimeTypes.length; i++) {
+			mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", ";
+		}
+		entropyStr += pluginsStr + mimeTypesStr;
+		// cookies and storage: 1 bit
+		entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage);
+		// language: ~7 bit
+		entropyStr += navigator.language;
+		// history: ~2 bit
+		entropyStr += window.history.length;
+		// location
+		entropyStr += window.location;
+
+		var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true });
+		for (var i = 0 ; i < entropyBytes.length ; i++) {
+			sr.seedInt8(entropyBytes[i]);
+		}
+	}
+})();
\ No newline at end of file