From c017b0a7bb5d6e8524c77c3f08ab756bd50ee1a6 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Thu, 6 Jul 2017 10:02:20 -0700 Subject: [PATCH 01/16] unlock jumblr menu tab --- react/src/components/dashboard/navbar/navbar.render.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js index 1bba47d..625b468 100644 --- a/react/src/components/dashboard/navbar/navbar.render.js +++ b/react/src/components/dashboard/navbar/navbar.render.js @@ -55,7 +55,7 @@ const NavbarRender = function() { EasyDEX -
  • +
  • this.dashboardChangeSection('jumblr') }> Jumblr From 6ea6603d4ce8a1f2f8a6df4a635a5b20a81ccbef Mon Sep 17 00:00:00 2001 From: petitPapillon Date: Thu, 27 Jul 2017 23:11:06 +0200 Subject: [PATCH 02/16] Rename walletsNativeInfo to walletsInfo rename nativeActiveSection to activeSection --- .../dashboard/receiveCoin/receiveCoin.js | 4 ++-- .../dashboard/walletsBalance/walletsBalance.js | 2 +- .../walletsInfo.js} | 4 ++-- .../walletsInfo.render.js} | 4 ++-- .../walletsNative/walletsNative.render.js | 4 ++-- .../walletsNativeSend/walletsNativeSend.js | 2 +- .../components/dashboard/walletsNav/walletsNav.js | 6 +++--- .../dashboard/walletsTxInfo/walletsTxInfo.js | 2 +- react/src/reducers/activeCoin.js | 14 +++++++------- 9 files changed, 21 insertions(+), 21 deletions(-) rename react/src/components/dashboard/{walletsNativeInfo/walletsNativeInfo.js => walletsInfo/walletsInfo.js} (72%) rename react/src/components/dashboard/{walletsNativeInfo/walletsNativeInfo.render.js => walletsInfo/walletsInfo.render.js} (98%) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 9193512..d084cdd 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -146,10 +146,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/walletsBalance/walletsBalance.js b/react/src/components/dashboard/walletsBalance/walletsBalance.js index 1dab912..bb30acc 100755 --- a/react/src/components/dashboard/walletsBalance/walletsBalance.js +++ b/react/src/components/dashboard/walletsBalance/walletsBalance.js @@ -103,7 +103,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/walletsNativeInfo/walletsNativeInfo.js b/react/src/components/dashboard/walletsInfo/walletsInfo.js similarity index 72% rename from react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js rename to react/src/components/dashboard/walletsInfo/walletsInfo.js index 6e025e1..11e7280 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js +++ b/react/src/components/dashboard/walletsInfo/walletsInfo.js @@ -1,5 +1,5 @@ import React from 'react'; -import WalletsNativeInfoRender from './walletsNativeInfo.render'; +import WalletsNativeInfoRender from './walletsInfo.render'; class WalletsNativeInfo extends React.Component { constructor(props) { @@ -10,7 +10,7 @@ class WalletsNativeInfo extends React.Component { if (this.props && this.props.Dashboard && this.props.Dashboard.progress && - this.props.ActiveCoin.nativeActiveSection === 'settings') { + this.props.ActiveCoin.activeSection === 'settings') { return WalletsNativeInfoRender.call(this); } diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js similarity index 98% rename from react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js rename to react/src/components/dashboard/walletsInfo/walletsInfo.render.js index 07bd784..b128057 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js +++ b/react/src/components/dashboard/walletsInfo/walletsInfo.render.js @@ -1,7 +1,7 @@ import React from 'react'; import { translate } from '../../../translate/translate'; -const WalletsNativeInfoRender = function() { +const WalletsInfoRender = function() { return (
    @@ -146,4 +146,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.render.js b/react/src/components/dashboard/walletsNative/walletsNative.render.js index 72ecaaf..e71ca60 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'; @@ -32,7 +32,7 @@ const WalletsNativeRender = function() { - +
    diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js index 3bc67df..21e2f46 100644 --- a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js +++ b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js @@ -279,7 +279,7 @@ class WalletsNativeSend extends React.Component { render() { if (this.props && this.props.ActiveCoin && - this.props.ActiveCoin.nativeActiveSection === 'send') { + this.props.ActiveCoin.activeSection === 'send') { return WalletsNativeSendRender.call(this); } diff --git a/react/src/components/dashboard/walletsNav/walletsNav.js b/react/src/components/dashboard/walletsNav/walletsNav.js index 0835bfd..02221d6 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.js @@ -35,7 +35,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 { @@ -47,7 +47,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 { @@ -59,7 +59,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/walletsTxInfo/walletsTxInfo.js b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js index 3055c67..e988b6f 100644 --- a/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js +++ b/react/src/components/dashboard/walletsTxInfo/walletsTxInfo.js @@ -39,7 +39,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/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, { From 356bf2c21fbd02c30b4074adf11e9a5858c6ec52 Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Fri, 4 Aug 2017 00:59:27 +0300 Subject: [PATCH 03/16] Adding missing argument --- react/src/components/dashboard/receiveCoin/receiveCoin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 34303a6..9f1c1dd 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.js @@ -179,7 +179,7 @@ class ReceiveCoin extends React.Component { } if (this.state.hideZeroAddresses) { - if (!this.hasNoAmount) { + if (!this.hasNoAmount(address)) { items.push( AddressItemRender.call(this, address, type) ); From 0891d8708ecaf0b66c589c127cf904795ee4256e Mon Sep 17 00:00:00 2001 From: Miika Turunen Date: Fri, 4 Aug 2017 01:05:03 +0300 Subject: [PATCH 04/16] Show toggle button if balance is not 0 --- .../src/components/dashboard/receiveCoin/receiveCoin.render.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index de187d2..2ad384d 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -102,7 +102,7 @@ export const ReceiveCoinRender = function() {

    { translate('INDEX.RECEIVING_ADDRESS') }

    - { this.checkTotalBalance() === 0 && + { this.checkTotalBalance() !== 0 &&
    Date: Fri, 4 Aug 2017 23:07:58 +0300 Subject: [PATCH 05/16] Toggle button label text to the right --- .../dashboard/receiveCoin/receiveCoin.render.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 2ad384d..a95a02d 100644 --- a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js +++ b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js @@ -104,11 +104,6 @@ export const ReceiveCoinRender = function() {
    { this.checkTotalBalance() !== 0 &&
    -
    - { translate('INDEX.TOGGLE_ZERO_ADDRESSES') } -
    +
    + { translate('INDEX.TOGGLE_ZERO_ADDRESSES') } +
    } From 9310060920f6e7276c56a2c512071db92188279a Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 5 Aug 2017 19:07:03 +0300 Subject: [PATCH 06/16] nativeNewAddress action creator err fix --- react/src/actions/actions/nativeNewAddress.js | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/react/src/actions/actions/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js index 4bd4088..8340170 100644 --- a/react/src/actions/actions/nativeNewAddress.js +++ b/react/src/actions/actions/nativeNewAddress.js @@ -11,20 +11,10 @@ import { } 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 +105,33 @@ export function getNewKMDAddresses(coin, pubpriv) { })); } dispatch( + triggerToaster( + json.result ? json.result : json, + translate('KMD_NATIVE.NEW_ADDR_GENERATED'), + 'info', + false + ) + ); + dispatch(getKMDAddressesNative(coin, mode)); + /*dispatch( handleGetNewKMDAddresses( pubpriv, coin, dispatch, json ) - ); + );*/ }) .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 From e8ca9d849aa3e791ab0a4f8a8f059ee2f73cd548 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 7 Aug 2017 15:49:40 +0300 Subject: [PATCH 07/16] importprivkey edge case progress --- react/src/actions/actions/nativeSyncInfo.js | 76 ++++++++++++--------- 1 file changed, 44 insertions(+), 32 deletions(-) diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index 8260128..196ef53 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -11,7 +11,7 @@ import { } from './log'; import Config from '../../config'; -export function getSyncInfoNativeKMD(skipDebug) { +export function getSyncInfoNativeKMD(skipDebug, json) { const coin = 'KMD'; return dispatch => { @@ -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,51 @@ 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 + ) + ); + dispatch(getDebugLog('komodo', 50)); + dispatch(toggleCoindDownModal(true)); + } else { + json = JSON.parse(json); + } - if (json.error && - json.error.message.indexOf('Activating best') === -1) { - dispatch(getDebugLog('komodo', 1)); - } + if (json.error && + json.error.message.indexOf('Activating best') === -1) { + dispatch(getDebugLog('komodo', 1)); + } - if (Config.debug) { - dispatch(logGuiHttp({ - 'timestamp': _timestamp, - 'status': 'success', - 'response': json, - })); + 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 From 24153c159c6d9c9b629b0166bc1d2e16437bcb52 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 11 Aug 2017 15:12:00 +0300 Subject: [PATCH 08/16] fixed outdated ac supply params --- react/src/components/addcoin/payload.js | 31 ++++++++++++++++--------- 1 file changed, 20 insertions(+), 11 deletions(-) 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}) } }; From 31a5aa2e42793b5568a7f9d02741f9030146bcb1 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 11 Aug 2017 15:12:51 +0300 Subject: [PATCH 09/16] added coqui chain --- react/src/assets/images/cryptologo/coqui.png | Bin 0 -> 5725 bytes react/src/components/addcoin/addcoinOptionsAC.js | 1 + 2 files changed, 1 insertion(+) create mode 100644 react/src/assets/images/cryptologo/coqui.png diff --git a/react/src/assets/images/cryptologo/coqui.png b/react/src/assets/images/cryptologo/coqui.png new file mode 100644 index 0000000000000000000000000000000000000000..59f61a8bd62dd537a792fc5f9962a2d6331f131e GIT binary patch literal 5725 zcmV-j7NY5iP)Oz@Z0f2-7z;ux~O9+4z06=<WDR*FRcSTFz- zW=q650N5=6FiBTtNC2?60Km==3$g$R3;-}uh=nNt1bYBr$Ri_o0EC$U6h`t_Jn<{8 z5a%iY0C<_QJh>z}MS)ugEpZ1|S1ukX&Pf+56gFW3VVXcL!g-k)GJ!M?;PcD?0HBc- z5#WRK{dmp}uFlRjj{U%*%WZ25jX z{P*?XzTzZ-GF^d31o+^>%=Ap99M6&ogks$0k4OBs3;+Bb(;~!4V!2o<6ys46agIcq zjPo+3B8fthDa9qy|77CdEc*jK-!%ZRYCZvbku9iQV*~a}ClFY4z~c7+0P?$U!PF=S z1Au6Q;m>#f??3%Vpd|o+W=WE9003S@Bra6Svp>fO002awfhw>;8}z{#EWidF!3EsG z3;bXU&9EIRU@z1_9W=mEXoiz;4lcq~xDGvV5BgyU zp1~-*fe8db$Osc*A=-!mVv1NJjtCc-h4>-CNCXm#Bp}I%6j35eku^v$Qi@a{RY)E3 zJ#qp$hg?Rwkvqr$GJ^buyhkyVfwECO)C{#lxu`c9ghrwZ&}4KmnvWKso6vH!8a<3Q zq36)6Xb;+tK10Vaz~~qUGsJ8#F2=(`u{bOVlVi)VBCHIn#u~6ztOL7=^<&SmcLWlF zMZgI*1b0FpVIDz9SWH+>*hr`#93(Um+6gxa1B6k+CnA%mOSC4s5&6UzVlpv@SV$}* z))J2sFA#f(L&P^E5{W}HC%KRUNwK6<(h|}}(r!{C=`5+6G)NjFlgZj-YqAG9lq?`C z$c5yc>d>VnA`E_*3F2Qp##d8RZb=H01_mm@+|Cqnc9PsG(F5HIG_C zt)aG3uTh7n6Et<2In9F>NlT@zqLtGcXcuVrX|L#Xx)I%#9!{6gSJKPrN9dR61N3(c z4Tcqi$B1Vr8Jidf7-t!G7_XR2rWwr)$3XQ?}=hpK0&Z&W{| zep&sA23f;Q!%st`QJ}G3cbou<7-yIK2z4nfCCCtN2-XOGSWo##{8Q{ATurxr~;I`ytDs%xbip}RzP zziy}Qn4Z2~fSycmr`~zJ=lUFdFa1>gZThG6M+{g7vkW8#+YHVaJjFF}Z#*3@$J_By zLtVo_L#1JrVVB{Ak-5=4qt!-@Mh}c>#$4kh<88)m#-k<%CLtzEP3leVno>={htGUuD;o7bD)w_sX$S}eAxwzy?UvgBH(S?;#HZiQMoS*2K2 zT3xe7t(~nU*1N5{rxB;QPLocnp4Ml>u<^FZwyC!nu;thW+pe~4wtZn|Vi#w(#jeBd zlf9FDx_yoPJqHbk*$%56S{;6Kv~mM9!g3B(KJ}#RZ#@)!hR|78Dq|Iq-afF%KE1Brn_fm;Im z_u$xr8UFki1L{Ox>G0o)(&RAZ;=|I=wN2l97;cLaHH6leTB-XXa*h%dBOEvi`+x zi?=Txl?TadvyiL>SuF~-LZ;|cS}4~l2eM~nS7yJ>iOM;atDY;(?aZ^v+mJV$@1Ote z62cPUlD4IWOIIx&SmwQ~YB{nzae3Pc;}r!fhE@iwJh+OsDs9zItL;~pu715HdQEGA zUct(O!LkCy1<%NCg+}G`0PgpNm-?d@-hMgNe6^V+j6x$b<6@S<$+<4_1hi}Ti zncS4LsjI}fWY1>OX6feMEuLErma3QLmkw?X+1j)X-&VBk_4Y;EFPF_I+q;9dL%E~B zJh;4Nr^(LEJ3myURP{Rblsw%57T)g973R8o)DE9*xN#~;4_o$q%o z4K@u`jhx2fBXC4{U8Qn{*%*B$Ge=nny$HAYq{=vy|sI0 z_vss+H_qMky?OB#|JK!>IX&II^LlUh#rO5!7TtbwC;iULyV-Xq?ybB}ykGP{?LpZ? z-G|jbTmIbG@7#ZCz;~eY(cDM(28Dyq{*m>M4?_iynUBkc4TkHUI6gT!;y-fz>HMcd z&t%Ugo)`Y2{>!cx7B7DI)$7;J(U{Spm-3gBzioV_{p!H$8L!*M!p0uH$#^p{Ui4P` z?ZJ24cOCDe-w#jZd?0@)|7iKK^;6KN`;!@ylm7$*nDhK&GcDTy000JJOGiWi{{a60 z|De66lK=n!32;bRa{vGi!~g&e!~vBn4jTXf00(qQO+^Rc2nP%`0boZOy8r+Sk4Z#9 zRCwC$oO!Grbrr`ybML$rUR#hNwJNQpQc49{mLMXs6QKgdVl>EF5^w<}LMjzZAcz|V zW33TrL0Uyw6f4ANfk4!8_B1^6&1xS-&(PX*RSj`hIxb*|&rz$@Z=d9%QB6V81II0Wz_=f=i<2j~Odl4_Wk zRPQTWIa=oqkhET!!_P#02KwA2UTW2-060=S0*nVf0jv_gPUIP-1K20V^Jpyab>Mrz zzhn3OH1K|)U*`sZ^MPN;cBavq*upx1dkd~*2jFzs?6%m3w*faxqSxx@n}MNb0Qe%X z5}1@@cmn~oFK~?1Jv=`YlS&5|1a`^+@DFlKpV99RN@|?~Htb5^^V%#TpHY6_r;Xo3 zKsKz}X-?$F2@E9BfIvAua?S%*0KJiORp3?Nft>rj4xA0_FT+0zc)p+m7!p7IDZCqj z=u6A`%245IN_MhYG2cEpw!+aS{26#Oa(*qa4wxo}9|OK1(_kWMwSz*9f!GGTCcuYk z5QM)1p9Mx`0A3Lfi-B94Wdp;9_oql`Rg3n3=YYFqPvUf|Jn(p37p0E@XGzNX9Nl z(}17J#`+PDczO*EBaOxZHvm%;z<(Av6Zmhl!^0e_az5rae z1)_Ia?Yr>e!ySN+p7A9IV8+>JJB>;p3SQlq0G|Su#2D)WCeNBXx7Qd0#zenos*a)8@8+%_U7p84k2Yez1Zi>P(GOEd z5_;9?%66tHgBT}s;^#>DWeRB;PSsb4?zj9Rg!-;DZ?p8&Wnw#M4tCT&hZ){|Q{E7IXp(n0FQo;)|RrNeXk@$&#R~z}u_A{J8pDsW|Ueecxd# z6;R!j3i3O4e&dD>*SxuI-5K3u#(19R4VfSaOc0nAH{BFXyLy060*4B;9Tc9l3$%?T z@!hUt889FC7w~35X)TqU1jd#sSM_7pIZmZ=|8}EC&%<$E-`v}4e9zliA4! zwu|*2)dRB@SdUbN)fXqnquxRBMwBb{o`!8o9W9Ta73w^K?b-ZELg1AJAj(CT0N>JL zYAID!bW~N8eOW2s^V*n4v3-eO7@)a3eudwI4N>K;P zuz}&ZDz?8cS8>~53Xow%It;v@5lH`#6t9&Ez7_l44a#Lr%01U&yJ%^2xPs+P+s#5C{YSg$=nW)9H9jGKf4ZwcjtJn#Juu^jxaIqHK4CmFUxboCmk>3`yUQWW# z;45se?hX7<3kz~oH4J|`B4JiXM04^oppRgy?yI+j1lCHcu|3)}+xm9_cp7%XAt+F1 z+=T5Au2OcgUYXD|;6ynbFXvv5%f4NZz z+7qRE?E)$~jO0oh2I{zfC{^E9^<_hi-+x0P%P$oInFP>xFRGo50vN`D6J@JT0>(tb zoFHZ@DiMZ*Ix~RRBz4OhaDq?CR-TcPW$m;z0GzC{)ojIO;cSYZk^0qJY%p>XPXb@Y z_NAe*4&ehz78;p?tqZ_$3PBFRPOJtAnMT>vF8g&3w#QpmDCMO9xT#qZI19L3p#e0x zVH2U}fs0B6FRLI@QTpkZ3E(JfbNc*x^2LM-Of6Fl9(IWH@sc-XEa}r}&lcsc2!Nxp z^MW%eHn|$DmbCHqY~U-(l`G1z$781y`g!L-W=K8271)W0vS~_+`u1U`$x4wxSNZ1= z6dy+t0KYt8soDr)gMpf?ZNb?lv2G|vgB2XwXg4JbnTPGi6qcMcP|qolYPCycuP8C3@tOo)xUMU-L1_)Cnp&lml$-3ReAdhP z?vvP2ijhDD+Y324Loh0``wamIw%3r?J#(?mr@;{dU?=bmsi~78rH9HsHU!|50;Mja z@WdYh;8n4`or4QpyN9lG8v$@^fn2a6RUZlO3~wh>(^lZxKw(Tn0CpAtFi;t5Bmj7U z0%xxvfKw@0Y)-pqus{swW4mi@!yLSDB)BhS{b3WzjijI}8cpS17Jzv#8_vL%zwaBS z;5kYLlE#UB?8}T->fG_zX8wAGI$k3HKCOr5iSZ_7AIH>KXxLid&6HD!OWhE50DVCO z+|~6wBn_Zd1=FwqJL7U4>FYDjwlX*Af`nbWXM?C?#Z=v02#fa>Dy;mKx_Cui7$ zEs!o&p1ZMZJCXIbS=f4Z1hW{s~j9oOqo!D8x5lc?NYmB1vnb_v}?y@g~ zbpl#si1J+nV3ax}je82n@d)o zY{j>Vh9iLS#gCDy?};7vI85g@lUzPOTHg3w=|t+Ge%ZFwz+bTc&BG`8^;QJz$`*j> z6`fw}i#r<NBET (BET) + From 6d6c95a71a7c95a61e81c99092037d31ce0752b9 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Fri, 11 Aug 2017 15:13:34 +0300 Subject: [PATCH 10/16] minor wallet header refactoring --- .../images/cryptologo/{AUD.png => aud.png} | Bin .../images/cryptologo/{BET.png => bet.png} | Bin .../images/cryptologo/{BGN.png => bgn.png} | Bin .../images/cryptologo/{BOTS.png => bots.png} | Bin .../images/cryptologo/{BRL.png => brl.png} | Bin .../images/cryptologo/{CAD.png => cad.png} | Bin .../images/cryptologo/{CEAL.png => ceal.png} | Bin .../images/cryptologo/{CHF.png => chf.png} | Bin .../images/cryptologo/{CNY.png => cny.png} | Bin .../cryptologo/{CRYPTO.png => crypto.png} | Bin .../images/cryptologo/{CZK.png => czk.png} | Bin .../images/cryptologo/{DKK.png => dkk.png} | Bin .../images/cryptologo/{EUR.png => eur.png} | Bin .../images/cryptologo/{GAME.png => game.png} | Bin .../images/cryptologo/{GBP.png => gbp.png} | Bin .../images/cryptologo/{HKD.png => hkd.png} | Bin .../images/cryptologo/{HODL.png => hodl.png} | Bin .../images/cryptologo/{HRK.png => hrk.png} | Bin .../images/cryptologo/{HUF.png => huf.png} | Bin .../images/cryptologo/{IDR.png => idr.png} | Bin .../images/cryptologo/{ILS.png => ils.png} | Bin .../images/cryptologo/{INR.png => inr.png} | Bin .../images/cryptologo/{JPY.png => jpy.png} | Bin .../cryptologo/{JUMBLR.png => jumblr.png} | Bin .../images/cryptologo/{komodo.png => kmd.png} | Bin .../images/cryptologo/{KRW.png => krw.png} | Bin .../images/cryptologo/{KV.png => kv.png} | Bin .../images/cryptologo/{MESH.png => mesh.png} | Bin .../images/cryptologo/{MGW.png => mgw.png} | Bin .../images/cryptologo/{MVP.png => mvp.png} | Bin .../images/cryptologo/{MXN.png => mxn.png} | Bin .../images/cryptologo/{MYR.png => myr.png} | Bin .../images/cryptologo/{NOK.png => nok.png} | Bin .../images/cryptologo/{NZD.png => nzd.png} | Bin .../cryptologo/{PANGEA.png => pangea.png} | Bin .../images/cryptologo/{PHP.png => php.png} | Bin .../images/cryptologo/{PLN.png => pln.png} | Bin .../images/cryptologo/{REVS.png => revs.png} | Bin .../images/cryptologo/{RON.png => ron.png} | Bin .../images/cryptologo/{RUB.png => rub.png} | Bin .../images/cryptologo/{SEK.png => sek.png} | Bin .../images/cryptologo/{SGD.png => sgd.png} | Bin .../cryptologo/{SHARK.png => shark.png} | Bin .../cryptologo/{SUPERNET.png => supernet.png} | Bin .../images/cryptologo/{THB.png => thb.png} | Bin .../images/cryptologo/{TRY.png => try.png} | Bin .../images/cryptologo/{WLC.png => wlc.png} | Bin .../images/cryptologo/{ZAR.png => zar.png} | Bin .../dashboard/coinTile/coinTileItem.render.js | 2 +- .../dashboard/walletsNative/walletsNative.js | 25 ++++- .../walletsNative/walletsNative.render.js | 10 +- .../dashboard/walletsNav/walletsNav.render.js | 4 +- react/src/components/overrides.scss | 54 +++++++++++ react/src/util/coinHelper.js | 91 ++++++++++++++++-- 54 files changed, 167 insertions(+), 19 deletions(-) rename react/src/assets/images/cryptologo/{AUD.png => aud.png} (100%) rename react/src/assets/images/cryptologo/{BET.png => bet.png} (100%) rename react/src/assets/images/cryptologo/{BGN.png => bgn.png} (100%) rename react/src/assets/images/cryptologo/{BOTS.png => bots.png} (100%) rename react/src/assets/images/cryptologo/{BRL.png => brl.png} (100%) rename react/src/assets/images/cryptologo/{CAD.png => cad.png} (100%) rename react/src/assets/images/cryptologo/{CEAL.png => ceal.png} (100%) rename react/src/assets/images/cryptologo/{CHF.png => chf.png} (100%) rename react/src/assets/images/cryptologo/{CNY.png => cny.png} (100%) rename react/src/assets/images/cryptologo/{CRYPTO.png => crypto.png} (100%) rename react/src/assets/images/cryptologo/{CZK.png => czk.png} (100%) rename react/src/assets/images/cryptologo/{DKK.png => dkk.png} (100%) rename react/src/assets/images/cryptologo/{EUR.png => eur.png} (100%) rename react/src/assets/images/cryptologo/{GAME.png => game.png} (100%) rename react/src/assets/images/cryptologo/{GBP.png => gbp.png} (100%) rename react/src/assets/images/cryptologo/{HKD.png => hkd.png} (100%) rename react/src/assets/images/cryptologo/{HODL.png => hodl.png} (100%) rename react/src/assets/images/cryptologo/{HRK.png => hrk.png} (100%) rename react/src/assets/images/cryptologo/{HUF.png => huf.png} (100%) rename react/src/assets/images/cryptologo/{IDR.png => idr.png} (100%) rename react/src/assets/images/cryptologo/{ILS.png => ils.png} (100%) rename react/src/assets/images/cryptologo/{INR.png => inr.png} (100%) rename react/src/assets/images/cryptologo/{JPY.png => jpy.png} (100%) rename react/src/assets/images/cryptologo/{JUMBLR.png => jumblr.png} (100%) rename react/src/assets/images/cryptologo/{komodo.png => kmd.png} (100%) rename react/src/assets/images/cryptologo/{KRW.png => krw.png} (100%) rename react/src/assets/images/cryptologo/{KV.png => kv.png} (100%) rename react/src/assets/images/cryptologo/{MESH.png => mesh.png} (100%) rename react/src/assets/images/cryptologo/{MGW.png => mgw.png} (100%) rename react/src/assets/images/cryptologo/{MVP.png => mvp.png} (100%) rename react/src/assets/images/cryptologo/{MXN.png => mxn.png} (100%) rename react/src/assets/images/cryptologo/{MYR.png => myr.png} (100%) rename react/src/assets/images/cryptologo/{NOK.png => nok.png} (100%) rename react/src/assets/images/cryptologo/{NZD.png => nzd.png} (100%) rename react/src/assets/images/cryptologo/{PANGEA.png => pangea.png} (100%) rename react/src/assets/images/cryptologo/{PHP.png => php.png} (100%) rename react/src/assets/images/cryptologo/{PLN.png => pln.png} (100%) rename react/src/assets/images/cryptologo/{REVS.png => revs.png} (100%) rename react/src/assets/images/cryptologo/{RON.png => ron.png} (100%) rename react/src/assets/images/cryptologo/{RUB.png => rub.png} (100%) rename react/src/assets/images/cryptologo/{SEK.png => sek.png} (100%) rename react/src/assets/images/cryptologo/{SGD.png => sgd.png} (100%) rename react/src/assets/images/cryptologo/{SHARK.png => shark.png} (100%) rename react/src/assets/images/cryptologo/{SUPERNET.png => supernet.png} (100%) rename react/src/assets/images/cryptologo/{THB.png => thb.png} (100%) rename react/src/assets/images/cryptologo/{TRY.png => try.png} (100%) rename react/src/assets/images/cryptologo/{WLC.png => wlc.png} (100%) rename react/src/assets/images/cryptologo/{ZAR.png => zar.png} (100%) 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/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/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() { { { item.modecode } 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..f50e95b 100644 --- a/react/src/components/dashboard/walletsNative/walletsNative.render.js +++ b/react/src/components/dashboard/walletsNative/walletsNative.render.js @@ -13,12 +13,14 @@ const WalletsNativeRender = function() {
    -
      + style={ this.getCoinStyle('transparent') }> +
      1. - + { this.getCoinStyle('title') && + + } { this.props.ActiveCoin.coin } diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index 67d43a7..7c79dad 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 (
        + style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30' : '0') }}>
          { translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' } diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index a3cb152..94eff32 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -684,4 +684,58 @@ 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; } \ No newline at end of file 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': From 37e5ea2b6be9f4dc19dd70ca885342e7c60a0e58 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 12 Aug 2017 19:24:49 +0300 Subject: [PATCH 11/16] added jumblr native --- react/src/actions/actionCreators.js | 1 + react/src/actions/actions/copyAddress.js | 14 + react/src/actions/actions/jumblr.js | 164 ++ react/src/actions/actions/nativeNewAddress.js | 12 - .../dashboard/coinTile/coinTileItem.js | 7 +- .../src/components/dashboard/jumblr/jumblr.js | 387 +++- .../dashboard/jumblr/jumblr.render.js | 594 +++-- .../dashboard/navbar/navbar.render.js | 12 +- .../dashboard/receiveCoin/receiveCoin.js | 10 +- .../receiveCoin/receiveCoin.render.js | 196 +- .../dashboard/walletsData/walletsData.js | 12 +- .../walletsNativeSend/walletsNativeSend.js | 11 +- .../walletsNativeSend.render.js | 284 +-- .../dashboard/walletsNav/walletsNav.render.js | 2 +- react/src/components/overrides.scss | 100 +- react/src/translate/en.js | 6 +- react/src/util/crypto/gen/array.map.js | 57 + react/src/util/crypto/gen/biginteger.js | 1271 +++++++++++ react/src/util/crypto/gen/bitcoin.js | 1974 +++++++++++++++++ react/src/util/crypto/gen/crypto-scrypt.js | 295 +++ react/src/util/crypto/gen/cryptojs.aes.js | 407 ++++ .../util/crypto/gen/cryptojs.blockmodes.js | 410 ++++ react/src/util/crypto/gen/cryptojs.hmac.js | 43 + react/src/util/crypto/gen/cryptojs.js | 149 ++ react/src/util/crypto/gen/cryptojs.pbkdf2.js | 54 + .../src/util/crypto/gen/cryptojs.ripemd160.js | 164 ++ react/src/util/crypto/gen/cryptojs.sha256.js | 135 ++ react/src/util/crypto/gen/ellipticcurve.js | 669 ++++++ react/src/util/crypto/gen/securerandom.js | 187 ++ 29 files changed, 7199 insertions(+), 428 deletions(-) create mode 100644 react/src/actions/actions/jumblr.js create mode 100755 react/src/util/crypto/gen/array.map.js create mode 100755 react/src/util/crypto/gen/biginteger.js create mode 100644 react/src/util/crypto/gen/bitcoin.js create mode 100755 react/src/util/crypto/gen/crypto-scrypt.js create mode 100755 react/src/util/crypto/gen/cryptojs.aes.js create mode 100755 react/src/util/crypto/gen/cryptojs.blockmodes.js create mode 100755 react/src/util/crypto/gen/cryptojs.hmac.js create mode 100755 react/src/util/crypto/gen/cryptojs.js create mode 100755 react/src/util/crypto/gen/cryptojs.pbkdf2.js create mode 100755 react/src/util/crypto/gen/cryptojs.ripemd160.js create mode 100755 react/src/util/crypto/gen/cryptojs.sha256.js create mode 100755 react/src/util/crypto/gen/ellipticcurve.js create mode 100755 react/src/util/crypto/gen/securerandom.js diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index 69d451c..68e99e4 100644 --- a/react/src/actions/actionCreators.js +++ b/react/src/actions/actionCreators.js @@ -68,6 +68,7 @@ export * from './actions/basiliskTxHistory'; export * from './actions/iguanaHelpers'; export * from './actions/cli'; export * from './actions/update'; +export * from './actions/jumblr'; export function changeActiveAddress(address) { return { 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/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/nativeNewAddress.js b/react/src/actions/actions/nativeNewAddress.js index 8340170..e3f9821 100644 --- a/react/src/actions/actions/nativeNewAddress.js +++ b/react/src/actions/actions/nativeNewAddress.js @@ -10,10 +10,6 @@ import { guiLogState } from './log'; -function handleGetNewKMDAddresses(pubpriv, coin, dispatch, json) { - -} - export function getNewKMDAddresses(coin, pubpriv, mode) { let payload; let ajaxFunctionInput = pubpriv === 'public' ? 'getnewaddress' : 'z_getnewaddress'; @@ -113,14 +109,6 @@ export function getNewKMDAddresses(coin, pubpriv, mode) { ) ); dispatch(getKMDAddressesNative(coin, mode)); - /*dispatch( - handleGetNewKMDAddresses( - pubpriv, - coin, - dispatch, - json - ) - );*/ }) .catch(function(ex) { dispatch( 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/jumblr/jumblr.js b/react/src/components/dashboard/jumblr/jumblr.js index 4ae03a0..d75b948 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.code, + '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.code, + '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.code, + '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.code, + '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('
          '); diff --git a/react/src/components/dashboard/jumblr/jumblr.render.js b/react/src/components/dashboard/jumblr/jumblr.render.js index 846400d..fab7b1c 100644 --- a/react/src/components/dashboard/jumblr/jumblr.render.js +++ b/react/src/components/dashboard/jumblr/jumblr.render.js @@ -2,10 +2,53 @@ 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 = []; + + console.warn('_jumblrAddressList', type); + if (_jumblrAddressList && + _jumblrAddressList.length) { + for (let i = 0; i < _jumblrAddressList.length; i++) { + _items.push( +
    + + + + ); + } + return _items; + } else { + return null; + } +}; + +/* passphrase toggle +
    + + +
    this.toggleAddressGenMod() }> + Passphrase based address +
    +
    +
    +*/ + +export const JumblrRender = function() { return ( -
    +
    @@ -32,87 +75,135 @@ const JumblrRender = function() { × - { translate('JUMBLR.NEED_NATIVE') } + About Jumblr
    - { translate('JUMBLR.TO_USE_JUMBLR') } -
    - { translate('JUMBLR.IF_YOU_ALREADY_RUNNING') } +

    + Jumblr functions all locally which means no middle man is required to jumble your funds. You take control over the whole process. +

    +

    + Tip: 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. +

    -
    -

    { translate('JUMBLR.THIS_SCREEN_DOESNT_REFRESH') }

    +
    +
    + + +
    + +
    + + +
    -
    -
    -
    - -
    -
    -
      -
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }
    • -
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }
    • -
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }
    • -
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }
    • -
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }
    • -
    -
    -
    -
    -
    - -
    -
    -

    { translate('JUMBLR.ADDRESS_ACCESSIBLE_EASILY') }

    -
      - duck dog cat donkey -
    -
      -
    1. { translate('JUMBLR.TO_ACCESS') }
    2. -
    3. { translate('JUMBLR.CLOSE_IAPP') }
    4. -
    5. { translate('JUMBLR.START_IAPP') }
    6. -
    7. { translate('JUMBLR.START_KMD') }
    8. -
    9. { translate('JUMBLR.ACCESS_JUMBLR_FUNDS') } -
        -
      • { translate('JUMBLR.SMALL_LETTERS') }
      • -
      • { translate('JUMBLR.WHITE_SPACE') }
      • -
      -
    10. -
    11. - { translate('JUMBLR.PER_EXAMPLE') } -
      - jumblr duck dog cat donkey -
    12. -
    13. { translate('JUMBLR.LOGIN_WITH_JUMBLR') }
    14. -
    -

    { translate('JUMBLR.AGAIN_DONT_SHARE') }

    -
    -
    -
    -
    -
    this.openTab(2) }> - { translate('JUMBLR.USING_JUMBLR') } +
    + { this.state.jumblrMode === 'public' && +
    +
    + { this.props.ActiveCoin.coin } + {
    -
    -
    + +
    +
    + +
    How to use Jumblr
      -
    • { translate('JUMBLR.RUN_KMD') }
    • -
    • { translate('JUMBLR.LOGIN_KMD') }
    • -
    • { translate('JUMBLR.GO_TO') }
    • -
    • { translate('JUMBLR.FIND_DEPOSIT_ADDR') }
    • -
    • { translate('JUMBLR.YOU_SEND_FUNDS') }
    • +
    • Create deposit address
    • +
    • Create secret address
    • +
    • Send funds to deposit address
    • { translate('JUMBLR.KEEP_WALLET_OPEN') }
    • { translate('JUMBLR.IMPORTANT_FUNDS') }
    • { translate('JUMBLR.LARGE_LOT') }
    • @@ -122,105 +213,276 @@ const JumblrRender = function() {

      { translate('JUMBLR.TO_CLEAR_THEM') }

      { translate('JUMBLR.WHEN_IT_TOTALS') }

    -
    -
    -
    -
    - -
    -

    { translate('JUMBLR.JADDR') }

    -
    -
    -
    { _jumblrAddressList[i].address }{ _jumblrAddressList[i].wif }
    - - - - - - - - - - - - - - - - - - -
    { translate('JUMBLR.BTC_DEPOSIT') } - -
    BTC Jumblr +
    + +
    { translate('JUMBLR.FEW_SECURITY_NOTES') }
    +
    +
      +
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }
    • +
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }
    • +
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }
    • +
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }
    • +
    • { translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }
    • +
    +
    + { this.state.jumblrDepositAddressPBased && +
    +
    +

    + Please write down your Jumblr passphrase and keept it safe. +

    +

    This is your main recovery passphrase.

    +

    All Jumblr addresses can be regenrated based on it.

    +

    + Tip: do not use smart editors to store your passphrase as they tend to add extra characters.
    This may result in passphrase mismatch with the original passphrase. +

    +
    + + - - { translate('JUMBLR.HIDDEN') } -
    { translate('JUMBLR.KMD_DEPOSIT') }
    KMD Jumblr + + } + + { this.state.jumblrDepositAddress && this.state.jumblrDepositAddress.address && +
    + Your Jumblr deposit address: +

    + { this.state.jumblrDepositAddress.address } + +

    +

    + { this.state.jumblrDepositAddress.wif } + +

    +
    + } + +
    + +

    Jumblr secret addresses are used for the final z -> t transactions.

    +

    In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported.

    +

    Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected.

    +

    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.

    +

    Your Jumblr secret address recovery passphrase will have the following pattern 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. Where XXX any number from 001 to 777.

    + + { this.state.jumblrDepositAddressPBased && +
    + + - - - { translate('JUMBLR.HIDDEN') } - -
    +
    + } +
    Number of secret addresses
    +
    + +
    +
    + +
    +
    + + +
    this.toggle('jumblrSecretAddressShow') }> + Show address list +
    +
    +
    +
    + { this.state.jumblrSecretAddressShow && this.checkJumblrSecretAddressListLength('gen') && + + + + + + + + + { this._JumblrRenderSecretAddressList('gen') } + +
    + Address + + Wif +
    + } +
    +
    +
    +

    Use the form below to send funds to your jumblr deposit address.

    +

    You can also send funds to deposit address from an external service or another wallet.

    + +
    +
    - - + } + { this.state.jumblrMode === 'private' && +
    + +
    +
    + +
    +

    Enter your Jumblr passphrase you got previously during Public node configuration to import secret address.

    +

    Passphrase example: 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.

    +

    The form below will "regenerate" Jumblr secret address based on passphrase provided.

    +

    After this final step expect to see funds processed and credited to your address after 2 days period.

    -
    -

    - { translate('JUMBLR.JSTATUS') } -

    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    { translate('JUMBLR.RESULT') } - -
    { translate('JUMBLR.DEPOSITED') }
    { translate('JUMBLR.PUB_TO_PRIV') }
    { translate('JUMBLR.PRIV_TO_PRIV') }
    { translate('JUMBLR.PRIV_TO_PUB') }
    { translate('JUMBLR.FINISHED') }
    { translate('JUMBLR.PENDING') }
    + { this.state.jumblrDepositAddressPBased && +
    + + this.passphraseOnChange(event) } + value={ this.state.jumblrPassphraseImport } /> +
    + } +
    Number of secret addresses
    +
    + +
    +
    + +
    +
    + + +
    this.toggle('jumblrSecretAddressShowImport') }> + Show address list +
    +
    +
    +
    + { this.state.jumblrSecretAddressShowImport && this.checkJumblrSecretAddressListLength('import') && + + + + + + + + + { this._JumblrRenderSecretAddressList('import') } + +
    + Address + + Wif +
    + } +
    +
    +
    +
    + +
    +
    -
    + }
    diff --git a/react/src/components/dashboard/navbar/navbar.render.js b/react/src/components/dashboard/navbar/navbar.render.js index 03a1f3e..48816d0 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() { BarterDEX
  • -
  • - this.dashboardChangeSection('jumblr') }> - Jumblr - -
  • + { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && +
  • + this.dashboardChangeSection('jumblr') }> + Jumblr + +
  • + }
  • this.dashboardChangeSection('atomic') }> Atomic Explorer diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.js b/react/src/components/dashboard/receiveCoin/receiveCoin.js index 1c13748..475e047 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() { diff --git a/react/src/components/dashboard/receiveCoin/receiveCoin.render.js b/react/src/components/dashboard/receiveCoin/receiveCoin.render.js index 788988c..32a3324 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 ( -
    -
    -
    -
    -
    -
    -
    - {this.isNativeMode() && - - } -

    { translate('INDEX.RECEIVING_ADDRESS') }

    -
    -
    - { this.checkTotalBalance() === 0 && -
    -
    - { translate('INDEX.TOGGLE_ZERO_ADDRESSES') } -
    -
    - ); + ); + } }; diff --git a/react/src/components/dashboard/walletsData/walletsData.js b/react/src/components/dashboard/walletsData/walletsData.js index 867c214..ffedc92 100644 --- a/react/src/components/dashboard/walletsData/walletsData.js +++ b/react/src/components/dashboard/walletsData/walletsData.js @@ -428,13 +428,11 @@ 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()) { - return ( - - { translate('INDEX.LOADING_HISTORY') }... - - ); - } + return ( + + { translate('INDEX.LOADING_HISTORY') }... + + ); } else if (this.state.itemsList === 'no data') { return ( diff --git a/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js b/react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js index d9a601e..3444ff8 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.nativeActiveSection === 'send' || this.props.nativeActiveSection === '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 ( -
    -
    -
    -
    -

    - { translate('INDEX.SEND') } { this.props.ActiveCoin.coin } -

    -
    -
    - -
    -
    -
    - { this.state.renderAddressDropdown && -
    -
    - - { this.renderAddressList() } -
    -
    - } - { this.renderOASendUI() } -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - - { translate('INDEX.TOTAL') }:  - { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  - { this.props.ActiveCoin.coin } - -
    -
    - -
    -
    -
    +
    + { this.state.renderAddressDropdown && +
    +
    + + { this.renderAddressList() }
    + } + { this.renderOASendUI() } +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + { translate('INDEX.TOTAL') }:  + { this.state.amount } - { this.state.fee }/kb = { Number(this.state.amount) - Number(this.state.fee) }  + { this.props.ActiveCoin.coin } + +
    +
    + +
    +
    + ); +} - { this.renderOPIDListCheck() && -
    -
    -
    -
    -
    -
    -
    -

    - { translate('INDEX.OPERATIONS_STATUSES') } -

    -
    -
    - - - - - - - - - - - { this.renderOPIDList() } - - - - - - - - - -
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    +export const WalletsNativeSendRender = function() { + if (this.props.renderFormOnly) { + return ( +
    { this.WalletsNativeSendFormRender() }
    + ); + } else { + return ( +
    +
    +
    +
    +

    + { translate('INDEX.SEND') } { this.props.ActiveCoin.coin } +

    +
    +
    + +
    +
    + { this.WalletsNativeSendFormRender() } +
    +
    +
    + + { this.renderOPIDListCheck() && +
    +
    +
    +
    +
    +
    +
    +

    + { translate('INDEX.OPERATIONS_STATUSES') } +

    +
    +
    + + + + + + + + + + + { this.renderOPIDList() } + + + + + + + + + +
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    { translate('INDEX.STATUS') }ID{ translate('INDEX.TIME') }{ translate('INDEX.RESULT') }
    +
    -
    - } -
    - ); + } +
    + ); + } }; \ No newline at end of file diff --git a/react/src/components/dashboard/walletsNav/walletsNav.render.js b/react/src/components/dashboard/walletsNav/walletsNav.render.js index 7c79dad..b17f82d 100644 --- a/react/src/components/dashboard/walletsNav/walletsNav.render.js +++ b/react/src/components/dashboard/walletsNav/walletsNav.render.js @@ -26,7 +26,7 @@ export const WalletsNavWithWalletRender = function() {
    + style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30px' : '0') }}>
      { translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: { this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' } diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index 94eff32..c675967 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; } @@ -738,4 +739,101 @@ select{ .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; + } + } } \ No newline at end of file diff --git a/react/src/translate/en.js b/react/src/translate/en.js index df4a558..95af166 100644 --- a/react/src/translate/en.js +++ b/react/src/translate/en.js @@ -279,15 +279,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/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<>= 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< 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<>= 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< 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 +* +* 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 From 9c602dab7cd44be9a9f59be6165d6d735744102d Mon Sep 17 00:00:00 2001 From: pbca26 Date: Sat, 12 Aug 2017 20:32:41 +0300 Subject: [PATCH 12/16] zcash params check --- react/change.log | 3 +++ .../components/dashboard/jumblr/jumblr.render.js | 1 - react/src/components/main/main.js | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/react/change.log b/react/change.log index 65eee02..239bf47 100644 --- a/react/change.log +++ b/react/change.log @@ -16,6 +16,9 @@ UI: - qr code generator / scan - basilisk send form reset fix - added native wallet info button +- added coqui assetchain +- jumblr +- zcashparams folder check v0.2.0.21a-beta -------------- diff --git a/react/src/components/dashboard/jumblr/jumblr.render.js b/react/src/components/dashboard/jumblr/jumblr.render.js index fab7b1c..0e8b25e 100644 --- a/react/src/components/dashboard/jumblr/jumblr.render.js +++ b/react/src/components/dashboard/jumblr/jumblr.render.js @@ -9,7 +9,6 @@ export const JumblrRenderSecretAddressList = function(type) { const _jumblrAddressList = type === 'gen' ? this.state.jumblrSecretAddress : this.state.jumblrSecretAddressImport; let _items = []; - console.warn('_jumblrAddressList', type); if (_jumblrAddressList && _jumblrAddressList.length) { for (let i = 0; i < _jumblrAddressList.length; i++) { 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()); From 7b138a94891d444ae63edfd9bd32d9914a0e9c5b Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 14 Aug 2017 17:29:56 +0300 Subject: [PATCH 13/16] claim interest modal --- react/src/actions/actionCreators.js | 9 ++ react/src/actions/actions/interest.js | 86 +++++++++++ react/src/actions/actions/log.js | 1 - react/src/actions/actions/nativeSend.js | 43 +++++- react/src/actions/actions/nativeSyncInfo.js | 2 +- react/src/actions/storeType.js | 3 +- .../claimInterestModal/claimInterestModal.js | 118 +++++++++++++++ .../claimInterestModal.render.js | 140 ++++++++++++++++++ .../src/components/dashboard/navbar/navbar.js | 6 + .../dashboard/navbar/navbar.render.js | 2 +- .../walletsNativeInfo/walletsNativeInfo.js | 7 + .../walletsNativeInfo.render.js | 10 ++ react/src/components/overrides.scss | 44 ++++++ react/src/reducers/dashboard.js | 13 +- 14 files changed, 476 insertions(+), 8 deletions(-) create mode 100644 react/src/actions/actions/interest.js create mode 100755 react/src/components/dashboard/claimInterestModal/claimInterestModal.js create mode 100644 react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js diff --git a/react/src/actions/actionCreators.js b/react/src/actions/actionCreators.js index 68e99e4..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'; @@ -69,6 +70,7 @@ 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 { @@ -367,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/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/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/nativeSend.js b/react/src/actions/actions/nativeSend.js index 0f788c8..e6cbfbc 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,45 @@ export function getKMDOPID(opid, coin) { }) }) } +} + +export function sendFromPromise(coin, address, amount) { + return new Promise((resolve, reject) => { + const payload = { + mode: null, + chain: coin, + cmd: 'sendfrom', + params: [ + address, + amount + ] + }; + + 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( + 'sendFrom', + '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/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index 196ef53..b75b161 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -13,7 +13,7 @@ import Config from '../../config'; export function getSyncInfoNativeKMD(skipDebug, json) { const coin = 'KMD'; - + // https://www.kmd.host/ return dispatch => { const _timestamp = Date.now(); if (Config.debug) { 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/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js new file mode 100755 index 0000000..95b70bb --- /dev/null +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js @@ -0,0 +1,118 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import Store from '../../../store'; +import { + toggleClaimInterestModal, + getListUnspent, + getRawTransaction, + copyString, + sendFromPromise +} 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('KMD') + .then((json) => { + if (json && + json.length) { + for (let i = 0; i < json.length; i++) { + getRawTransaction('KMD', 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) { + console.warn('claim interest', `${address} ${amount}`); + /*sendFromPromise(address, amount) + .then((json) => { + console.warn(json); + });*/ + } + + 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..8872fc2 --- /dev/null +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js @@ -0,0 +1,140 @@ +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( + + + + + { _transactionsList[i].address } + 10 ? 'green bold' : '' }>{ _transactionsList[i].amount } + { _transactionsList[i].interest } + + { _transactionsList[i].locktime && + + } + { !_transactionsList[i].locktime && + + } + + + + + + ); + } + } + + return ( + +
      + Requirements to accure interest: locktime field is set and amount is greater than 10 KMD +
      +
      + +
      + Show zero interest +
      +
      +
      + + + + + + + + + + + + + { _items } + + + + + + + + + + + +
      AddressAmountInterestLocktime
      AddressAmountInterestLocktime
      +
      +
      + ); +}; + + //{ this.renderAddressList('public') } + //{ this.isNativeMode() && this.renderAddressList('private') } + + +export const ClaimInterestModalRender = function() { + return ( + +
      +
      +
      +
      + +

      Claim interest

      +
      +
      + +
      +
      + { this.state.isLoading && + Loading interest data... + } + { !this.state.isLoading && this.checkTransactionsListLength() && +
      { this.claimInterestTableRender() }
      + } + { !this.state.isLoading && !this.checkTransactionsListLength() && +
      No data
      + } +
      +
      +
      +
      +
      +
      +
      +
      + ); +}; \ No newline at end of file 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 48816d0..4449f5f 100644 --- a/react/src/components/dashboard/navbar/navbar.render.js +++ b/react/src/components/dashboard/navbar/navbar.render.js @@ -57,7 +57,7 @@ const NavbarRender = function() { BarterDEX - { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && + { this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' && (this._checkAC() || this.props.ActiveCoin.coin === 'KMD') &&
    1. this.dashboardChangeSection('jumblr') }> Jumblr diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js index 6e025e1..4630f4e 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js +++ b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.js @@ -1,9 +1,16 @@ import React from 'react'; +import { toggleClaimInterestModal } from '../../../actions/actionCreators'; +import Store from '../../../store'; import WalletsNativeInfoRender from './walletsNativeInfo.render'; class WalletsNativeInfo extends React.Component { constructor(props) { super(props); + this.openClaimInterestModal = this.openClaimInterestModal.bind(this); + } + + openClaimInterestModal() { + Store.dispatch(toggleClaimInterestModal(true)); } render() { diff --git a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js index 07bd784..19acf59 100644 --- a/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js +++ b/react/src/components/dashboard/walletsNativeInfo/walletsNativeInfo.render.js @@ -1,5 +1,6 @@ import React from 'react'; import { translate } from '../../../translate/translate'; +import ClaimInterestModal from '../claimInterestModal/claimInterestModal'; const WalletsNativeInfoRender = function() { return ( @@ -40,6 +41,15 @@ const WalletsNativeInfoRender = function() {
    + { this.props.ActiveCoin.coin === 'KMD' && +
    + + +
    + }
    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index c675967..ed599ec 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -836,4 +836,48 @@ select{ 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; + } + + .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; + } + } } \ No newline at end of file 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; } From 8aa3164b23f36f1221e8fb86d0439d6250586135 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Mon, 14 Aug 2017 23:34:13 +0300 Subject: [PATCH 14/16] send whole balance to yourself --- react/src/actions/actions/nativeSend.js | 13 +++++--- .../claimInterestModal/claimInterestModal.js | 32 +++++++++++++++---- .../claimInterestModal.render.js | 22 ++++--------- .../src/components/dashboard/jumblr/jumblr.js | 8 ++--- react/src/components/overrides.scss | 5 +++ 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/react/src/actions/actions/nativeSend.js b/react/src/actions/actions/nativeSend.js index e6cbfbc..fc3e3e2 100644 --- a/react/src/actions/actions/nativeSend.js +++ b/react/src/actions/actions/nativeSend.js @@ -286,15 +286,18 @@ export function getKMDOPID(opid, coin) { } } -export function sendFromPromise(coin, address, amount) { +export function sendToAddressPromise(coin, address, amount) { return new Promise((resolve, reject) => { const payload = { mode: null, chain: coin, - cmd: 'sendfrom', + cmd: 'sendtoaddress', params: [ address, - amount + amount, + 'KMD interest claim request', + 'KMD interest claim request', + true ] }; @@ -314,7 +317,7 @@ export function sendFromPromise(coin, address, amount) { console.log(error); dispatch( triggerToaster( - 'sendFrom', + 'sendToAddress', 'Error', 'error' ) @@ -322,7 +325,7 @@ export function sendFromPromise(coin, address, amount) { }) .then(response => response.json()) .then(json => { - resolve(json.result ? json.result : json); + resolve(json); }) }); } \ No newline at end of file diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js index 95b70bb..94e05f5 100755 --- a/react/src/components/dashboard/claimInterestModal/claimInterestModal.js +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.js @@ -6,7 +6,8 @@ import { getListUnspent, getRawTransaction, copyString, - sendFromPromise + sendToAddressPromise, + triggerToaster } from '../../../actions/actionCreators'; import { translate } from '../../../translate/translate'; import { @@ -36,12 +37,12 @@ class ClaimInterestModal extends React.Component { loadListUnspent() { let _transactionsList = []; - getListUnspent('KMD') + getListUnspent(this.props.ActiveCoin.coin) .then((json) => { if (json && json.length) { for (let i = 0; i < json.length; i++) { - getRawTransaction('KMD', json[i].txid) + getRawTransaction(this.props.ActiveCoin.coin, json[i].txid) .then((_json) => { _transactionsList.push({ address: json[i].address, @@ -64,11 +65,28 @@ class ClaimInterestModal extends React.Component { } claimInterest(address, amount) { - console.warn('claim interest', `${address} ${amount}`); - /*sendFromPromise(address, amount) + sendToAddressPromise(this.props.ActiveCoin.coin, this.state.transactionsList[0].address, this.props.ActiveCoin.balance.transparent) .then((json) => { - console.warn(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() { diff --git a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js index 8872fc2..8754965 100644 --- a/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js +++ b/react/src/components/dashboard/claimInterestModal/claimInterestModal.render.js @@ -30,14 +30,6 @@ export const _ClaimInterestTableRender = function() { } - - - ); } @@ -46,7 +38,7 @@ export const _ClaimInterestTableRender = function() { return (
    - Requirements to accure interest: locktime field is set and amount is greater than 10 KMD + Requirements to accrue interest: locktime field is set and amount is greater than 10 KMD
    +
    @@ -72,7 +70,6 @@ export const _ClaimInterestTableRender = function() { - @@ -85,7 +82,6 @@ export const _ClaimInterestTableRender = function() { -
    Amount Interest Locktime
    Amount Interest Locktime
    @@ -94,10 +90,6 @@ export const _ClaimInterestTableRender = function() { ); }; - //{ this.renderAddressList('public') } - //{ this.isNativeMode() && this.renderAddressList('private') } - - export const ClaimInterestModalRender = function() { return ( diff --git a/react/src/components/dashboard/jumblr/jumblr.js b/react/src/components/dashboard/jumblr/jumblr.js index d75b948..a69dbd1 100755 --- a/react/src/components/dashboard/jumblr/jumblr.js +++ b/react/src/components/dashboard/jumblr/jumblr.js @@ -169,7 +169,7 @@ class Jumblr extends React.Component { json.error.code) { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -299,7 +299,7 @@ class Jumblr extends React.Component { } else { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -348,7 +348,7 @@ class Jumblr extends React.Component { json.error.code) { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) @@ -372,7 +372,7 @@ class Jumblr extends React.Component { } else { Store.dispatch( triggerToaster( - json.error.code, + json.error.message, 'Error', 'error' ) diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index ed599ec..b074e1f 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -851,6 +851,11 @@ select{ padding: 8px 30px 8px 0; } + .claim-btn { + position: absolute; + right: 29px; + top: 66px; + } .table-scroll { height: 366px; overflow-y: auto; From 346fb0a229721c880ffd7b182c117d8dfda6e06f Mon Sep 17 00:00:00 2001 From: pbca26 Date: Tue, 15 Aug 2017 20:21:19 +0300 Subject: [PATCH 15/16] asset chain crash handler --- react/src/actions/actions/nativeSyncInfo.js | 13 +++++++++++-- react/src/actions/actions/settings.js | 6 +++++- .../coindDownModal/coindDownModal.render.js | 2 +- react/src/components/overrides.scss | 9 ++++++++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/react/src/actions/actions/nativeSyncInfo.js b/react/src/actions/actions/nativeSyncInfo.js index b75b161..009c190 100644 --- a/react/src/actions/actions/nativeSyncInfo.js +++ b/react/src/actions/actions/nativeSyncInfo.js @@ -182,7 +182,12 @@ export function getSyncInfoNative(coin, skipDebug) { true ) ); - dispatch(getDebugLog('komodo', 50)); + + if (coin === 'KMD') { + dispatch(getDebugLog('komodo', 50)); + } else { + dispatch(getDebugLog('komodo', 50, coin)); + } dispatch(toggleCoindDownModal(true)); } else { json = JSON.parse(json); @@ -190,7 +195,11 @@ export function getSyncInfoNative(coin, skipDebug) { if (json.error && json.error.message.indexOf('Activating best') === -1) { - dispatch(getDebugLog('komodo', 1)); + if (coin === 'KMD') { + dispatch(getDebugLog('komodo', 1)); + } else { + dispatch(getDebugLog('komodo', 1, coin)); + } } if (Config.debug) { 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/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 }> × -

    Komodod is down!

    +

    { this.props.ActiveCoin.coin === 'KMD' ? 'Komodod' : `Komodod / ${this.props.ActiveCoin.coin}` } is down!

    diff --git a/react/src/components/overrides.scss b/react/src/components/overrides.scss index b074e1f..6d1ea2f 100644 --- a/react/src/components/overrides.scss +++ b/react/src/components/overrides.scss @@ -629,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%; } } } From a23618cc5a83dea9ba23c58d7b6272c0b542a3b9 Mon Sep 17 00:00:00 2001 From: pbca26 Date: Wed, 16 Aug 2017 11:14:47 +0300 Subject: [PATCH 16/16] updated change.log --- react/change.log | 1 + 1 file changed, 1 insertion(+) diff --git a/react/change.log b/react/change.log index 239bf47..5ee34f5 100644 --- a/react/change.log +++ b/react/change.log @@ -19,6 +19,7 @@ UI: - added coqui assetchain - jumblr - zcashparams folder check +- claim interest modal v0.2.0.21a-beta --------------