Browse Source

added jumblr native

all-modes
pbca26 8 years ago
parent
commit
37e5ea2b6b
  1. 1
      react/src/actions/actionCreators.js
  2. 14
      react/src/actions/actions/copyAddress.js
  3. 164
      react/src/actions/actions/jumblr.js
  4. 12
      react/src/actions/actions/nativeNewAddress.js
  5. 7
      react/src/components/dashboard/coinTile/coinTileItem.js
  6. 387
      react/src/components/dashboard/jumblr/jumblr.js
  7. 544
      react/src/components/dashboard/jumblr/jumblr.render.js
  8. 2
      react/src/components/dashboard/navbar/navbar.render.js
  9. 10
      react/src/components/dashboard/receiveCoin/receiveCoin.js
  10. 86
      react/src/components/dashboard/receiveCoin/receiveCoin.render.js
  11. 2
      react/src/components/dashboard/walletsData/walletsData.js
  12. 11
      react/src/components/dashboard/walletsNativeSend/walletsNativeSend.js
  13. 46
      react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js
  14. 2
      react/src/components/dashboard/walletsNav/walletsNav.render.js
  15. 100
      react/src/components/overrides.scss
  16. 4
      react/src/translate/en.js
  17. 57
      react/src/util/crypto/gen/array.map.js
  18. 1271
      react/src/util/crypto/gen/biginteger.js
  19. 1974
      react/src/util/crypto/gen/bitcoin.js
  20. 295
      react/src/util/crypto/gen/crypto-scrypt.js
  21. 407
      react/src/util/crypto/gen/cryptojs.aes.js
  22. 410
      react/src/util/crypto/gen/cryptojs.blockmodes.js
  23. 43
      react/src/util/crypto/gen/cryptojs.hmac.js
  24. 149
      react/src/util/crypto/gen/cryptojs.js
  25. 54
      react/src/util/crypto/gen/cryptojs.pbkdf2.js
  26. 164
      react/src/util/crypto/gen/cryptojs.ripemd160.js
  27. 135
      react/src/util/crypto/gen/cryptojs.sha256.js
  28. 669
      react/src/util/crypto/gen/ellipticcurve.js
  29. 187
      react/src/util/crypto/gen/securerandom.js

1
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 {

14
react/src/actions/actions/copyAddress.js

@ -15,3 +15,17 @@ 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'
)
);
}
}

164
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);
})
});
}

12
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(

7
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));
}

387
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('<br>');

544
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(
<tr key={ `jumblr-secret-address-${i}` }>
<td>{ _jumblrAddressList[i].address }</td>
<td>{ _jumblrAddressList[i].wif }</td>
</tr>
);
}
return _items;
} else {
return null;
}
};
/* passphrase toggle
<div className={ 'toggle-box padding-top-20 padding-bottom-' + (this.state.jumblrDepositAddressPBased ? '10' : '30') }>
<span className="pointer">
<label className="switch">
<input
type="checkbox"
checked={ this.state.jumblrDepositAddressPBased } />
<div
className="slider"
onClick={ () => this.toggleAddressGenMod() }></div>
</label>
<div
className="toggle-label"
onClick={ () => this.toggleAddressGenMod() }>
Passphrase based address
</div>
</span>
</div>
*/
export const JumblrRender = function() {
return (
<div className="page margin-left-0">
<div className="page margin-left-0 jumblr">
<WalletsHeader activeSection="jumblr" />
<div className="page-content margin-top-30">
<div className="row">
@ -32,87 +75,135 @@ const JumblrRender = function() {
<span>×</span>
</button>
<span className="jumblr-header">
<i className="icon fa-paw"></i> { translate('JUMBLR.NEED_NATIVE') }
<i className="icon fa-paw"></i> About Jumblr
</span>
<br />
{ translate('JUMBLR.TO_USE_JUMBLR') }
<br />
{ translate('JUMBLR.IF_YOU_ALREADY_RUNNING') }
<p>
Jumblr functions all locally which means no middle man is required to jumble your funds. You take control over the whole process.
</p>
<p>
<strong>Tip:</strong> to achive maximum anonimity setup Jumblr node on a dedicated piece of hardware (laptop or VPS), use a separate IP address for main Jumblr node.
</p>
</div>
</div>
<div className="col-xlg-12 col-md-12">
<p>{ translate('JUMBLR.THIS_SCREEN_DOESNT_REFRESH') }</p>
<div className="col-xlg-12 col-md-12 padding-top-20 padding-bottom-30">
<div
className="form-group col-lg-2 col-md-2 col-sm-2 col-xs-2"
style={{ padding: 0 }}>
<input
type="radio"
className="to-labelauty labelauty"
name={ `mode-public` }
id={ `mode-public` }
checked={ this.state.jumblrMode === 'public' ? true : false } />
<label
htmlFor={ `mode-public` }
style={{ margin: 0 }}
onClick={ () => this.switchJumblrMode('public') }>
<span
className="labelauty-unchecked-image"
style={{ display: this.state.jumblrMode === 'public' ? 'none' : 'inline-block' }}></span>
<span
className="labelauty-unchecked"
style={{ display: this.state.jumblrMode === 'public' ? 'none' : 'inline-block' }}>
Public node
</span>
<span
className="labelauty-checked-image"
style={{ display: this.state.jumblrMode === 'public' ? 'inline-block' : 'none' }}></span>
<span
className="labelauty-checked"
style={{ display: this.state.jumblrMode === 'public' ? 'inline-block' : 'none' }}>
Public node
</span>
</label>
</div>
<div className="col-xs-12">
<div className="panel-group">
<div className="panel">
<div
className="panel-heading"
onClick={ () => this.openTab(0) }>
<a className={ this.state.activeTab === 0 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.FEW_SECURITY_NOTES') }</a>
</div>
<div className={ this.state.activeTab === 0 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
<div className="panel-body">
<ul>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }</li>
</ul>
</div>
className="form-group col-lg-2 col-md-2 col-sm-2 col-xs-2"
style={{ padding: 0 }}>
<input
type="radio"
className="to-labelauty labelauty"
name={ `mode-private` }
id={ `mode-private` }
checked={ this.state.jumblrMode === 'private' ? true : false } />
<label
htmlFor={ `mode-private` }
style={{ margin: 0 }}
onClick={ () => this.switchJumblrMode('private') }>
<span
className="labelauty-unchecked-image"
style={{ display: this.state.jumblrMode === 'private' ? 'none' : 'inline-block' }}></span>
<span
className="labelauty-unchecked"
style={{ display: this.state.jumblrMode === 'private' ? 'none' : 'inline-block' }}>
Private node
</span>
<span
className="labelauty-checked-image"
style={{ display: this.state.jumblrMode === 'private' ? 'inline-block' : 'none' }}></span>
<span
className="labelauty-checked"
style={{ display: this.state.jumblrMode === 'private' ? 'inline-block' : 'none' }}>
Private node
</span>
</label>
</div>
</div>
<div className="panel">
<div
className="panel-heading"
onClick={ () => this.openTab(1) }>
<a className={ this.state.activeTab === 1 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.ACCESS_JUMBLR_FUNDS') }</a>
<div className="col-xlg-12 col-md-12">
{ this.state.jumblrMode === 'public' &&
<div className="jumblr-mode-selector nav-tabs-horizontal nav-tabs-inverse">
<div className="img-responsive">
<span className="coin">{ this.props.ActiveCoin.coin }</span>
<img
className="image"
src={ `assets/images/cryptologo/${this.props.ActiveCoin.coin.toLowerCase()}.png` }
alt={ this.props.ActiveCoin.coin }/>
</div>
<div className={ this.state.activeTab === 1 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
<div className="panel-body">
<p>{ translate('JUMBLR.ADDRESS_ACCESSIBLE_EASILY') }</p>
<ul>
<code>duck dog cat donkey</code>
</ul>
<ol>
<li>{ translate('JUMBLR.TO_ACCESS') }</li>
<li>{ translate('JUMBLR.CLOSE_IAPP') }</li>
<li>{ translate('JUMBLR.START_IAPP') }</li>
<li>{ translate('JUMBLR.START_KMD') }</li>
<li>{ translate('JUMBLR.ACCESS_JUMBLR_FUNDS') }
<ul>
<li>{ translate('JUMBLR.SMALL_LETTERS') }</li>
<li>{ translate('JUMBLR.WHITE_SPACE') }</li>
</ul>
<ul className="nav nav-tabs">
<li
className={ this.state.activeTab === 0 ? 'active' : '' }
onClick={ () => this.openTab(0) }>
<a>
{ translate('JUMBLR.USING_JUMBLR') }
</a>
</li>
<li>
{ translate('JUMBLR.PER_EXAMPLE') }
<br />
<code>jumblr duck dog cat donkey</code>
<li
className={ this.state.activeTab === 1 ? 'active' : '' }
onClick={ () => this.openTab(1) }>
<a>
Deposit address
</a>
</li>
<li>{ translate('JUMBLR.LOGIN_WITH_JUMBLR') }</li>
</ol>
<h4>{ translate('JUMBLR.AGAIN_DONT_SHARE') }</h4>
</div>
</div>
</div>
<div className="panel">
<div
className="panel-heading"
<li
className={ this.state.activeTab === 2 ? 'active' : '' }
onClick={ () => this.openTab(2) }>
<a className={ this.state.activeTab === 2 ? 'panel-title' : 'panel-title collapsed' }>{ translate('JUMBLR.USING_JUMBLR') }</a>
</div>
<div className={ this.state.activeTab === 2 ? 'panel-collapse collapse in' : 'panel-collapse collapse' }>
<div className="panel-body">
<a>
Secret address
</a>
</li>
<li
className={ this.state.activeTab === 3 ? 'active' : '' }
onClick={ () => this.openTab(3) }>
<a>
Deposit funds
</a>
</li>
</ul>
<div className="tab-content padding-20">
<div className={ 'tab-pane' + (this.state.activeTab === 0 ? ' active' : '') }>
<button
type="button"
className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
onClick={ () => this.openTab(1) }>Next</button>
<h5>How to use Jumblr</h5>
<ul>
<li>{ translate('JUMBLR.RUN_KMD') }</li>
<li>{ translate('JUMBLR.LOGIN_KMD') }</li>
<li>{ translate('JUMBLR.GO_TO') }</li>
<li>{ translate('JUMBLR.FIND_DEPOSIT_ADDR') }</li>
<li>{ translate('JUMBLR.YOU_SEND_FUNDS') }</li>
<li>Create deposit address</li>
<li>Create secret address</li>
<li>Send funds to deposit address</li>
<li>{ translate('JUMBLR.KEEP_WALLET_OPEN') }</li>
<li>{ translate('JUMBLR.IMPORTANT_FUNDS') }</li>
<li>{ translate('JUMBLR.LARGE_LOT') }</li>
@ -122,105 +213,276 @@ const JumblrRender = function() {
<p>{ translate('JUMBLR.TO_CLEAR_THEM') }</p>
<p>{ translate('JUMBLR.WHEN_IT_TOTALS') }</p>
</div>
<div className={ 'tab-pane' + (this.state.activeTab === 1 ? ' active' : '') }>
<button
type="button"
className="btn btn-success waves-effect waves-light btn-next"
onClick={ () => this.openTab(2) }>Next</button>
<h5>{ translate('JUMBLR.FEW_SECURITY_NOTES') }</h5>
<div className="col-xs-12 nofloat">
<ul className="padding-bottom-20">
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC1') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC2') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC3') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC4') }</li>
<li>{ translate('JUMBLR.FEW_SECURITY_NOTES_DESC5') }</li>
</ul>
</div>
{ this.state.jumblrDepositAddressPBased &&
<div className="padding-bottom-30">
<div className="padding-bottom-20">
<p>
<strong>Please write down your Jumblr passphrase and keept it safe.</strong>
</p>
<p>This is your main recovery passphrase.</p>
<p>All Jumblr addresses can be regenrated based on it.</p>
<p>
<strong>Tip:</strong> do not use smart editors to store your passphrase as they tend to add extra characters.<br />This may result in passphrase mismatch with the original passphrase.
</p>
</div>
<label>Passphrase</label>
<input
type="text"
className="form-control"
name="loginPassphrase"
onChange={ this.returnPassphrase }
value={ this.state.randomSeed } />
<button
className="btn btn-default btn-xs clipboard-edexaddr copy-string-btn"
title={ translate('INDEX.COPY_TO_CLIPBOARD') }
onClick={ () => this.copyPassphrase() }>
<i className="icon wb-copy"></i> { translate('INDEX.COPY') }
</button>
</div>
</div>
<div className="col-xlg-12 col-md-12">
<h4 className="font-size-14 text-uppercase">{ translate('JUMBLR.JADDR') }</h4>
<div className="panel">
<div className="table-responsive">
<table className="table table-striped">
<tbody>
<tr>
<td width="20%">{ translate('JUMBLR.BTC_DEPOSIT') }</td>
<td>
<span></span>
</td>
</tr>
<tr>
<td>BTC Jumblr</td>
<td>
}
<button
type="button"
className="btn btn-animate btn-animate-side btn-default btn-sm waves-effect waves-light">
<span>
<i className="icon fa-eye"></i> { translate('JUMBLR.SHOW_HIDE') }
</span>
className="btn btn-info waves-effect waves-light"
onClick={ this.generateJumblrDepositAddress }>Create Jumblr deposit address</button>
{ this.state.jumblrDepositAddress && this.state.jumblrDepositAddress.address &&
<div className="padding-top-40">
<strong>Your Jumblr deposit address:</strong>
<p>
{ this.state.jumblrDepositAddress.address }
<button
className="btn btn-default btn-xs clipboard-edexaddr margin-left-10"
title={ translate('INDEX.COPY_TO_CLIPBOARD') }
onClick={ () => this._copyCoinAddress(this.state.jumblrDepositAddress.address) }>
<i className="icon wb-copy"></i> { translate('INDEX.COPY') }
</button>
<span className="label label-lg label-outline label-success hide"></span>
<span className="label label-lg label-outline label-default">{ translate('JUMBLR.HIDDEN') }</span>
</td>
</tr>
<tr>
<td>{ translate('JUMBLR.KMD_DEPOSIT') }</td>
<td></td>
</tr>
<tr>
<td>KMD Jumblr</td>
<td>
</p>
<p>
{ this.state.jumblrDepositAddress.wif }
<button
className="btn btn-default btn-xs clipboard-edexaddr margin-left-10"
title={ translate('INDEX.COPY_TO_CLIPBOARD') }
onClick={ () => this._copyCoinAddress(this.state.jumblrDepositAddress.wif) }>
<i className="icon wb-copy"></i> { translate('INDEX.COPY') }
</button>
</p>
</div>
}
</div>
<div className={ 'tab-pane' + (this.state.activeTab === 2 ? ' active' : '') }>
<button
type="button"
className="btn btn-animate btn-animate-side btn-default btn-sm waves-effect waves-light">
<span>
<i className="icon fa-eye"></i> { translate('JUMBLR.SHOW_HIDE') }
</span>
className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
onClick={ () => this.openTab(3) }>Next</button>
<p>Jumblr secret addresses are used for the final z -> t transactions.</p>
<p>In order to allow larger accounts to obtain privacy, up to 777 secret addresses are supported.</p>
<p>Whenever a z -> t stage is activated, a random secret address from the list of the then active secret addresses is selected.</p>
<p>To add a new set of secret addresses enter address count below. The passphrase below is exactly the same you saw on the previous step.</p>
<p>Your Jumblr secret address recovery passphrase will have the following pattern <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer XXX</code>. Where XXX any number from 001 to 777.</p>
{ this.state.jumblrDepositAddressPBased &&
<div className="padding-bottom-20 padding-top-20">
<label>Passphrase</label>
<input
type="text"
className="form-control"
name="jumblrPassphrase"
onChange={ this.returnPassphrase }
value={ this.state.randomSeed } />
<button
className="btn btn-default btn-xs clipboard-edexaddr copy-string-btn"
title={ translate('INDEX.COPY_TO_CLIPBOARD') }
onClick={ () => this.copyPassphrase() }>
<i className="icon wb-copy"></i> { translate('INDEX.COPY') }
</button>
<span className="label label-lg label-outline label-success hide"></span>
<span className="label label-lg label-outline label-default">
{ translate('JUMBLR.HIDDEN') }
</div>
}
<div className="col-xs-2 nofloat padding-top-30">Number of secret addresses</div>
<div className="col-xs-2 nofloat padding-left-10">
<input
type="text"
pattern="[0-9]*"
className="form-control"
name="secretAddressCount"
min="1"
max="777"
onChange={ this.onChange }
value={ this.state.secretAddressCount } />
</div>
<div className="col-xs-2 nofloat">
<button
type="button"
className="btn btn-info waves-effect waves-light"
onClick={ this.generateJumblrSecretAddress }>Create Jumblr secret address(es)</button>
</div>
<div className="toggle-box padding-top-20">
<span className="pointer">
<label className="switch">
<input
type="checkbox"
checked={ this.state.jumblrSecretAddressShow } />
<div
className="slider"
onClick={ () => this.toggle('jumblrSecretAddressShow') }></div>
</label>
<div
className="toggle-label"
onClick={ () => this.toggle('jumblrSecretAddressShow') }>
Show address list
</div>
</span>
</div>
<div className="col-xlg-12 col-md-12 padding-top-20 nofloat">
{ this.state.jumblrSecretAddressShow && this.checkJumblrSecretAddressListLength('gen') &&
<table className="table table-hover dataTable table-striped">
<thead>
<tr>
<td>
<strong>Address</strong>
</td>
<td>
<strong>Wif</strong>
</td>
</tr>
</thead>
<tbody>
{ this._JumblrRenderSecretAddressList('gen') }
</tbody>
</table>
}
</div>
</div>
<div className={ 'tab-pane' + (this.state.activeTab === 3 ? ' active' : '') }>
<p>Use the form below to send funds to your jumblr deposit address.</p>
<p className="padding-bottom-20">You can also send funds to deposit address from an external service or another wallet.</p>
<WalletsNativeSend
{...this.props}
renderFormOnly="true"
nativeActiveSection="send" />
</div>
</div>
</div>
}
{ this.state.jumblrMode === 'private' &&
<div className="jumblr-mode-selector nav-tabs-horizontal nav-tabs-inverse">
<ul className="nav nav-tabs">
<li
className={ this.state.activeTab === 0 ? 'active' : '' }
onClick={ () => this.openTab(0) }>
<a>
Import secret address
</a>
</li>
<li
className={ this.state.activeTab === 1 ? 'active' : '' }
onClick={ () => this.openTab(1) }>
<a>
Check funds
</a>
</li>
</ul>
<div className="tab-content padding-20">
<div className={ 'tab-pane' + (this.state.activeTab === 0 ? ' active' : '') }>
<button
type="button"
className="btn btn-success waves-effect waves-light margin-top-20 btn-next"
onClick={ () => this.openTab(1) }>Next</button>
<div className="col-xlg-12 col-md-12 nofloat">
<p>Enter your Jumblr passphrase you got previously during Public node configuration to import secret address.</p>
<p>Passphrase example: <code>jumblr muffin smart educate tomato boss foil open dirt opinion pizza goddess skate action card garden cotton life write life note shine myself gloom summer</code>.</p>
<p>The form below will "regenerate" Jumblr secret address based on passphrase provided.</p>
<p>After this final step expect to see funds processed and credited to your address after 2 days period.</p>
<div className="col-xlg-12 col-md-12">
<h4 className="font-size-14 text-uppercase">
{ translate('JUMBLR.JSTATUS') }
</h4>
<div className="panel">
<div className="table-responsive">
<table className="table table-striped">
<tbody>
{ this.state.jumblrDepositAddressPBased &&
<div className="padding-bottom-20 padding-top-20">
<label>Passphrase</label>
<input
type="text"
className="form-control"
name="jumblrPassphraseImport"
onChange={ (event) => this.passphraseOnChange(event) }
value={ this.state.jumblrPassphraseImport } />
</div>
}
<div className="col-xs-2 nofloat padding-top-30">Number of secret addresses</div>
<div className="col-xs-2 nofloat padding-left-10">
<input
type="text"
pattern="[0-9]*"
className="form-control"
name="secretAddressCountImport"
min="1"
max="777"
onChange={ this.onChange }
value={ this.state.secretAddressCountImport } />
</div>
<div className="col-xs-2 nofloat">
<button
type="button"
className="btn btn-info waves-effect waves-light"
onClick={ this.importJumblrSecretAddress }>Import Jumblr secret address(es)</button>
</div>
<div className="toggle-box padding-top-20">
<span className="pointer">
<label className="switch">
<input
type="checkbox"
checked={ this.state.jumblrSecretAddressShowImport } />
<div
className="slider"
onClick={ () => this.toggle('jumblrSecretAddressShowImport') }></div>
</label>
<div
className="toggle-label"
onClick={ () => this.toggle('jumblrSecretAddressShowImport') }>
Show address list
</div>
</span>
</div>
<div className="col-xlg-12 col-md-12 padding-top-20 nofloat">
{ this.state.jumblrSecretAddressShowImport && this.checkJumblrSecretAddressListLength('import') &&
<table className="table table-hover dataTable table-striped">
<thead>
<tr>
<td width="20%">{ translate('JUMBLR.RESULT') }</td>
<td>
<span className="label label-success"></span>
<strong>Address</strong>
</td>
<td>
<strong>Wif</strong>
</td>
</tr>
<tr>
<td>{ translate('JUMBLR.DEPOSITED') }</td>
<td></td>
</tr>
<tr>
<td>{ translate('JUMBLR.PUB_TO_PRIV') }</td>
<td></td>
</tr>
<tr>
<td>{ translate('JUMBLR.PRIV_TO_PRIV') }</td>
<td></td>
</tr>
<tr>
<td>{ translate('JUMBLR.PRIV_TO_PUB') }</td>
<td></td>
</tr>
<tr>
<td>{ translate('JUMBLR.FINISHED') }</td>
<td></td>
</tr>
<tr>
<td>{ translate('JUMBLR.PENDING') }</td>
<td></td>
</tr>
</thead>
<tbody>
{ this._JumblrRenderSecretAddressList('import') }
</tbody>
</table>
}
</div>
</div>
</div>
<div className={ 'tab-pane' + (this.state.activeTab === 1 ? ' active' : '') }>
<ReceiveCoin
{...this.props.ActiveCoin}
nativeActiveSection="receive"
renderTableOnly="true" />
</div>
</div>
</div>
}
</div>
</div>
</div>

2
react/src/components/dashboard/navbar/navbar.render.js

@ -57,11 +57,13 @@ const NavbarRender = function() {
<i className="site-menu-icon"></i> BarterDEX
</a>
</li>
{ this.props.ActiveCoin && this.props.ActiveCoin.mode === 'native' &&
<li className={ this.isSectionActive('jumblr') ? 'active nav-top-menu' : 'nav-top-menu' }>
<a onClick={ () => this.dashboardChangeSection('jumblr') }>
<i className="site-menu-icon"></i> Jumblr
</a>
</li>
}
<li className={ this.state.nativeOnly ? 'hide' : (this.isSectionActive('atomic') ? 'active nav-top-menu' : 'nav-top-menu') }>
<a onClick={ () => this.dashboardChangeSection('atomic') }>
<i className="site-menu-icon"></i> Atomic Explorer

10
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() {

86
react/src/components/dashboard/receiveCoin/receiveCoin.render.js

@ -61,43 +61,9 @@ export const AddressItemRender = function(address, type) {
);
};
export const ReceiveCoinRender = function() {
export const _ReceiveCoinTableRender = function() {
return (
<div>
<div className="col-xs-12 margin-top-20">
<div className="panel nav-tabs-horizontal">
<div>
<div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
<div className="panel">
<header className="panel-heading">
{this.isNativeMode() &&
<div className="panel-actions">
<div
className={ 'dropdown' + (this.state.openDropMenu ? ' open' : '') }
onClick={ this.openDropMenu }>
<a className="dropdown-toggle white btn btn-warning">
<i className="icon md-arrows margin-right-10"></i> { translate('INDEX.GET_NEW_ADDRESS') }
<span className="caret"></span>
</a>
<ul
className="dropdown-menu dropdown-menu-right">
<li>
<a onClick={ () => this.getNewAddress('public') }>
<i className="icon fa-eye"></i> { translate('INDEX.TRANSPARENT_ADDRESS') }
</a>
</li>
<li>
<a onClick={ () => this.getNewAddress('private') }>
<i className="icon fa-eye-slash"></i> { translate('INDEX.PRIVATE_Z_ADDRESS') }
</a>
</li>
</ul>
</div>
</div>
}
<h4 className="panel-title">{ translate('INDEX.RECEIVING_ADDRESS') }</h4>
</header>
<div className="panel-body">
<span>
{ this.checkTotalBalance() === 0 &&
<div className="text-left padding-top-10 padding-bottom-10">
<div
@ -153,6 +119,53 @@ export const ReceiveCoinRender = function() {
}
</tfoot>
</table>
</span>
);
};
export const ReceiveCoinRender = function() {
if (this.props.renderTableOnly) {
return (
<div>{ this.ReceiveCoinTableRender() }</div>
);
} else {
return (
<div>
<div className="col-xs-12 margin-top-20">
<div className="panel nav-tabs-horizontal">
<div>
<div className="col-xlg-12 col-lg-12 col-sm-12 col-xs-12">
<div className="panel">
<header className="panel-heading">
{ this.isNativeMode() &&
<div className="panel-actions">
<div
className={ 'dropdown' + (this.state.openDropMenu ? ' open' : '') }
onClick={ this.openDropMenu }>
<a className="dropdown-toggle white btn btn-warning">
<i className="icon md-arrows margin-right-10"></i> { translate('INDEX.GET_NEW_ADDRESS') }
<span className="caret"></span>
</a>
<ul
className="dropdown-menu dropdown-menu-right">
<li>
<a onClick={ () => this.getNewAddress('public') }>
<i className="icon fa-eye"></i> { translate('INDEX.TRANSPARENT_ADDRESS') }
</a>
</li>
<li>
<a onClick={ () => this.getNewAddress('private') }>
<i className="icon fa-eye-slash"></i> { translate('INDEX.PRIVATE_Z_ADDRESS') }
</a>
</li>
</ul>
</div>
</div>
}
<h4 className="panel-title">{ translate('INDEX.RECEIVING_ADDRESS') }</h4>
</header>
<div className="panel-body">
{ this.ReceiveCoinTableRender() }
</div>
</div>
</div>
@ -161,5 +174,6 @@ export const ReceiveCoinRender = function() {
</div>
</div>
);
}
};

2
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 (
<tr className="hover--none">
<td colSpan="7">{ translate('INDEX.LOADING_HISTORY') }...</td>
</tr>
);
}
} else if (this.state.itemsList === 'no data') {
return (
<tr className="hover--none">

11
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);
}

46
react/src/components/dashboard/walletsNativeSend/walletsNativeSend.render.js

@ -65,24 +65,8 @@ export const OASendUIRender = function() {
);
};
export const WalletsNativeSendRender = function() {
export const _WalletsNativeSendFormRender = function() {
return (
<div id="kmd_wallet_send">
<div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12">
<div
className="panel"
id="projects">
<div className="panel-heading">
<h3 className="panel-title">
{ translate('INDEX.SEND') } { this.props.ActiveCoin.coin }
</h3>
</div>
<div className="qr-modal-send-block">
<QRModal
mode="scan"
setRecieverFromScan={ this.setRecieverFromScan } />
</div>
<div className="panel-body container-fluid">
<form
className="extcoin-send-form"
method="post"
@ -162,6 +146,33 @@ export const WalletsNativeSendRender = function() {
</div>
</div>
</form>
);
}
export const WalletsNativeSendRender = function() {
if (this.props.renderFormOnly) {
return (
<div>{ this.WalletsNativeSendFormRender() }</div>
);
} else {
return (
<div id="kmd_wallet_send">
<div className="col-xlg-12 col-md-12 col-sm-12 col-xs-12">
<div
className="panel"
id="projects">
<div className="panel-heading">
<h3 className="panel-title">
{ translate('INDEX.SEND') } { this.props.ActiveCoin.coin }
</h3>
</div>
<div className="qr-modal-send-block">
<QRModal
mode="scan"
setRecieverFromScan={ this.setRecieverFromScan } />
</div>
<div className="panel-body container-fluid">
{ this.WalletsNativeSendFormRender() }
</div>
</div>
</div>
@ -212,4 +223,5 @@ export const WalletsNativeSendRender = function() {
}
</div>
);
}
};

2
react/src/components/dashboard/walletsNav/walletsNav.render.js

@ -26,7 +26,7 @@ export const WalletsNavWithWalletRender = function() {
<div
className={ 'page-header page-header-bordered header-easydex padding-bottom-' + (this.state.nativeOnly ? '40 page-header--native' : '20') }
id="header-dashboard"
style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30' : '0') }}>
style={{ marginBottom: this.props.ActiveCoin.mode === 'basilisk' ? '30px' : (this.state.nativeOnly ? '30px' : '0') }}>
<ol className={ this.state.nativeOnly ? 'hide' : 'breadcrumb' }>
<strong>{ translate('INDEX.MY') } { this.props && this.props.ActiveCoin ? this.props.ActiveCoin.coin : '-' } { translate('INDEX.ADDRESS') }: </strong>
{ this.props && this.props.Dashboard && this.props.Dashboard.activeHandle ? this.props.Dashboard.activeHandle[this.props.ActiveCoin.coin] : '-' }

100
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;
}
@ -739,3 +740,100 @@ 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;
}
}
}

4
react/src/translate/en.js

@ -279,7 +279,7 @@ 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.',
@ -287,7 +287,7 @@ export const _lang = {
'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.',
'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.',

57
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;
};
}

1271
react/src/util/crypto/gen/biginteger.js

File diff suppressed because it is too large

1974
react/src/util/crypto/gen/bitcoin.js

File diff suppressed because it is too large

295
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
})();

407
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]
];
}
}
};
})();

410
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);

43
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);
};
})();

149
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("");
}
};
})();
}

54
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);
};
})();

164
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));
}
})();

135
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;
})();

669
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]();
}
})();

187
react/src/util/crypto/gen/securerandom.js

@ -0,0 +1,187 @@
/*!
* Random number generator with ArcFour PRNG
*
* NOTE: For best results, put code like
* <body onclick='SecureRandom.seedTime();' onkeypress='SecureRandom.seedTime();'>
* in your main HTML document.
*
* Copyright Tom Wu, bitaddress.org BSD License.
* http://www-cs-students.stanford.edu/~tjw/jsbn/LICENSE
*/
(function () {
// Constructor function of Global SecureRandom object
var sr = window.SecureRandom = function () { };
// Properties
sr.state;
sr.pool;
sr.pptr;
// Pool size must be a multiple of 4 and greater than 32.
// An array of bytes the size of the pool will be passed to init()
sr.poolSize = 256;
// --- object methods ---
// public method
// ba: byte array
sr.prototype.nextBytes = function (ba) {
var i;
if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
try {
var rvBytes = new Uint8Array(ba.length);
window.crypto.getRandomValues(rvBytes);
for (i = 0; i < ba.length; ++i)
ba[i] = sr.getByte() ^ rvBytes[i];
return;
} catch (e) {
alert(e);
}
}
for (i = 0; i < ba.length; ++i) ba[i] = sr.getByte();
};
// --- static methods ---
// Mix in the current time (w/milliseconds) into the pool
// NOTE: this method should be called from body click/keypress event handlers to increase entropy
sr.seedTime = function () {
sr.seedInt(new Date().getTime());
}
sr.getByte = function () {
/*if(!ninja.seeder.isDone()) {
alert("Premature initialisation of the random generator. Something is really wrong, do not generate wallets.");
return NaN;
}*/
if (sr.state == null) {
sr.seedTime();
sr.state = sr.ArcFour(); // Plug in your RNG constructor here
sr.state.init(sr.pool);
sr.pptr = 0;
}
// TODO: allow reseeding after first request
return sr.state.next();
}
// Mix in a 32-bit integer into the pool
sr.seedInt = function (x) {
sr.seedInt8(x);
sr.seedInt8((x >> 8));
sr.seedInt8((x >> 16));
sr.seedInt8((x >> 24));
}
// Mix in a 16-bit integer into the pool
sr.seedInt16 = function (x) {
sr.seedInt8(x);
sr.seedInt8((x >> 8));
}
// Mix in a 8-bit integer into the pool
sr.seedInt8 = function (x) {
sr.pool[sr.pptr++] ^= x & 255;
if (sr.pptr >= sr.poolSize) sr.pptr -= sr.poolSize;
}
// Arcfour is a PRNG
sr.ArcFour = function () {
function Arcfour() {
this.i = 0;
this.j = 0;
this.S = new Array();
}
// Initialize arcfour context from key, an array of ints, each from [0..255]
function ARC4init(key) {
var i, j, t;
for (i = 0; i < 256; ++i)
this.S[i] = i;
j = 0;
for (i = 0; i < 256; ++i) {
j = (j + this.S[i] + key[i % key.length]) & 255;
t = this.S[i];
this.S[i] = this.S[j];
this.S[j] = t;
}
this.i = 0;
this.j = 0;
}
function ARC4next() {
var t;
this.i = (this.i + 1) & 255;
this.j = (this.j + this.S[this.i]) & 255;
t = this.S[this.i];
this.S[this.i] = this.S[this.j];
this.S[this.j] = t;
return this.S[(t + this.S[this.i]) & 255];
}
Arcfour.prototype.init = ARC4init;
Arcfour.prototype.next = ARC4next;
return new Arcfour();
};
// Initialize the pool with junk if needed.
if (sr.pool == null) {
sr.pool = new Array();
sr.pptr = 0;
var t;
if (window.crypto && window.crypto.getRandomValues && window.Uint8Array) {
try {
// Use webcrypto if available
var ua = new Uint8Array(sr.poolSize);
window.crypto.getRandomValues(ua);
for (t = 0; t < sr.poolSize; ++t)
sr.pool[sr.pptr++] = ua[t];
} catch (e) { alert(e); }
}
while (sr.pptr < sr.poolSize) { // extract some randomness from Math.random()
t = Math.floor(65536 * Math.random());
sr.pool[sr.pptr++] = t >>> 8;
sr.pool[sr.pptr++] = t & 255;
}
sr.pptr = Math.floor(sr.poolSize * Math.random());
sr.seedTime();
// entropy
var entropyStr = "";
// screen size and color depth: ~4.8 to ~5.4 bits
entropyStr += (window.screen.height * window.screen.width * window.screen.colorDepth);
entropyStr += (window.screen.availHeight * window.screen.availWidth * window.screen.pixelDepth);
// time zone offset: ~4 bits
var dateObj = new Date();
var timeZoneOffset = dateObj.getTimezoneOffset();
entropyStr += timeZoneOffset;
// user agent: ~8.3 to ~11.6 bits
entropyStr += navigator.userAgent;
// browser plugin details: ~16.2 to ~21.8 bits
var pluginsStr = "";
for (var i = 0; i < navigator.plugins.length; i++) {
pluginsStr += navigator.plugins[i].name + " " + navigator.plugins[i].filename + " " + navigator.plugins[i].description + " " + navigator.plugins[i].version + ", ";
}
var mimeTypesStr = "";
for (var i = 0; i < navigator.mimeTypes.length; i++) {
mimeTypesStr += navigator.mimeTypes[i].description + " " + navigator.mimeTypes[i].type + " " + navigator.mimeTypes[i].suffixes + ", ";
}
entropyStr += pluginsStr + mimeTypesStr;
// cookies and storage: 1 bit
entropyStr += navigator.cookieEnabled + typeof (sessionStorage) + typeof (localStorage);
// language: ~7 bit
entropyStr += navigator.language;
// history: ~2 bit
entropyStr += window.history.length;
// location
entropyStr += window.location;
var entropyBytes = Crypto.SHA256(entropyStr, { asBytes: true });
for (var i = 0 ; i < entropyBytes.length ; i++) {
sr.seedInt8(entropyBytes[i]);
}
}
})();
Loading…
Cancel
Save