mirror of https://github.com/m2049r/xmrwallet.git
convert ledger seed dialog (#549)
This commit is contained in:
parent
d5a967f690
commit
da1d4ea1bf
|
@ -115,6 +115,10 @@ dependencies {
|
||||||
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
implementation 'org.slf4j:slf4j-nop:1.7.25'
|
||||||
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
|
||||||
|
|
||||||
|
// https://mvnrepository.com/artifact/com.github.aelstad/keccakj
|
||||||
|
implementation 'com.github.aelstad:keccakj:1.1.0'
|
||||||
|
|
||||||
|
|
||||||
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
testImplementation "junit:junit:$rootProject.ext.junitVersion"
|
||||||
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
|
||||||
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
testImplementation "com.squareup.okhttp3:mockwebserver:$rootProject.ext.okHttpVersion"
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
package com.m2049r.xmrwallet;
|
package com.m2049r.xmrwallet;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
|
@ -33,6 +34,7 @@ import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
@ -45,6 +47,7 @@ import com.m2049r.xmrwallet.util.FingerprintHelper;
|
||||||
import com.m2049r.xmrwallet.util.Helper;
|
import com.m2049r.xmrwallet.util.Helper;
|
||||||
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
import com.m2049r.xmrwallet.util.KeyStoreHelper;
|
||||||
import com.m2049r.xmrwallet.util.RestoreHeight;
|
import com.m2049r.xmrwallet.util.RestoreHeight;
|
||||||
|
import com.m2049r.xmrwallet.util.ledger.Monero;
|
||||||
import com.m2049r.xmrwallet.widget.Toolbar;
|
import com.m2049r.xmrwallet.widget.Toolbar;
|
||||||
import com.nulabinc.zxcvbn.Strength;
|
import com.nulabinc.zxcvbn.Strength;
|
||||||
import com.nulabinc.zxcvbn.Zxcvbn;
|
import com.nulabinc.zxcvbn.Zxcvbn;
|
||||||
|
@ -240,9 +243,7 @@ public class GenerateFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
etWalletAddress.setVisibility(View.VISIBLE);
|
etWalletAddress.setVisibility(View.VISIBLE);
|
||||||
etWalletAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener()
|
etWalletAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
|
||||||
{
|
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|
||||||
|| (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
|| (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||||
|
@ -274,9 +275,7 @@ public class GenerateFragment extends Fragment {
|
||||||
}
|
}
|
||||||
if (type.equals(TYPE_KEY)) {
|
if (type.equals(TYPE_KEY)) {
|
||||||
etWalletSpendKey.setVisibility(View.VISIBLE);
|
etWalletSpendKey.setVisibility(View.VISIBLE);
|
||||||
etWalletSpendKey.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener()
|
etWalletSpendKey.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
|
|
||||||
{
|
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|
||||||
|| (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
|| (actionId == EditorInfo.IME_ACTION_NEXT)) {
|
||||||
|
@ -303,9 +302,7 @@ public class GenerateFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
bGenerate.setOnClickListener(new View.OnClickListener()
|
bGenerate.setOnClickListener(new View.OnClickListener() {
|
||||||
|
|
||||||
{
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Helper.hideKeyboard(getActivity());
|
Helper.hideKeyboard(getActivity());
|
||||||
|
@ -616,4 +613,80 @@ public class GenerateFragment extends Fragment {
|
||||||
}
|
}
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AlertDialog ledgerDialog = null;
|
||||||
|
|
||||||
|
public void convertLedgerSeed() {
|
||||||
|
if (ledgerDialog != null) return;
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
View promptsView = getLayoutInflater().inflate(R.layout.prompt_ledger_seed, null);
|
||||||
|
android.app.AlertDialog.Builder alertDialogBuilder = new android.app.AlertDialog.Builder(activity);
|
||||||
|
alertDialogBuilder.setView(promptsView);
|
||||||
|
|
||||||
|
final TextInputLayout etSeed = promptsView.findViewById(R.id.etSeed);
|
||||||
|
final TextInputLayout etPassphrase = promptsView.findViewById(R.id.etPassphrase);
|
||||||
|
|
||||||
|
etSeed.getEditText().addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (etSeed.getError() != null) {
|
||||||
|
etSeed.setError(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start,
|
||||||
|
int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start,
|
||||||
|
int before, int count) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
alertDialogBuilder
|
||||||
|
.setCancelable(false)
|
||||||
|
.setPositiveButton(getString(R.string.label_ok), null)
|
||||||
|
.setNegativeButton(getString(R.string.label_cancel),
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
Helper.hideKeyboardAlways(activity);
|
||||||
|
etWalletMnemonic.getEditText().getText().clear();
|
||||||
|
dialog.cancel();
|
||||||
|
ledgerDialog = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ledgerDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
ledgerDialog.setOnShowListener(new DialogInterface.OnShowListener() {
|
||||||
|
@Override
|
||||||
|
public void onShow(DialogInterface dialog) {
|
||||||
|
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
|
button.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
String ledgerSeed = etSeed.getEditText().getText().toString();
|
||||||
|
String ledgerPassphrase = etPassphrase.getEditText().getText().toString();
|
||||||
|
String moneroSeed = Monero.convert(ledgerSeed, ledgerPassphrase);
|
||||||
|
if (moneroSeed != null) {
|
||||||
|
etWalletMnemonic.getEditText().setText(moneroSeed);
|
||||||
|
ledgerDialog.dismiss();
|
||||||
|
ledgerDialog = null;
|
||||||
|
} else {
|
||||||
|
etSeed.setError(getString(R.string.bad_ledger_seed));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||||
|
ledgerDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ledgerDialog.show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
|
@ -620,6 +621,11 @@ public class GenerateReviewFragment extends Fragment {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||||
|
openDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
return openDialog;
|
return openDialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1229,6 +1229,12 @@ public class LoginActivity extends BaseActivity
|
||||||
case R.id.action_language:
|
case R.id.action_language:
|
||||||
onChangeLocale();
|
onChangeLocale();
|
||||||
return true;
|
return true;
|
||||||
|
case R.id.action_ledger_seed:
|
||||||
|
Fragment f = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
|
||||||
|
if (f instanceof GenerateFragment) {
|
||||||
|
((GenerateFragment) f).convertLedgerSeed();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
@ -505,6 +506,10 @@ public class NodeFragment extends Fragment
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||||
|
editDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
etNodePass.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
etNodePass.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
|
||||||
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
|
||||||
|
|
|
@ -62,9 +62,6 @@ public class ProgressDialog extends AlertDialog {
|
||||||
pbBar = view.findViewById(R.id.pbBar);
|
pbBar = view.findViewById(R.id.pbBar);
|
||||||
tvProgress = view.findViewById(R.id.tvProgress);
|
tvProgress = view.findViewById(R.id.tvProgress);
|
||||||
setView(view);
|
setView(view);
|
||||||
//setTitle("blabla");
|
|
||||||
//super.setMessage("bubbu");
|
|
||||||
// view.invalidate();
|
|
||||||
setIndeterminate(indeterminate);
|
setIndeterminate(indeterminate);
|
||||||
if (maxValue > 0) {
|
if (maxValue > 0) {
|
||||||
setMax(maxValue);
|
setMax(maxValue);
|
||||||
|
|
|
@ -27,11 +27,13 @@ import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.data.TxDataBtc;
|
import com.m2049r.xmrwallet.data.TxDataBtc;
|
||||||
|
@ -435,6 +437,11 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||||
|
passwordDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
passwordDialog.show();
|
passwordDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,10 +27,12 @@ import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.m2049r.xmrwallet.BuildConfig;
|
||||||
import com.m2049r.xmrwallet.R;
|
import com.m2049r.xmrwallet.R;
|
||||||
import com.m2049r.xmrwallet.data.TxData;
|
import com.m2049r.xmrwallet.data.TxData;
|
||||||
import com.m2049r.xmrwallet.model.PendingTransaction;
|
import com.m2049r.xmrwallet.model.PendingTransaction;
|
||||||
|
@ -322,6 +324,11 @@ public class SendConfirmWizardFragment extends SendWizardFragment implements Sen
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// set FLAG_SECURE to prevent screenshots in Release Mode
|
||||||
|
if (!(BuildConfig.DEBUG && BuildConfig.FLAVOR_type.equals("alpha"))) {
|
||||||
|
passwordDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
|
||||||
|
}
|
||||||
|
|
||||||
passwordDialog.show();
|
passwordDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Based on
|
||||||
|
* https://stackoverflow.com/a/19943894
|
||||||
|
*
|
||||||
|
* Curve parameters from
|
||||||
|
* https://en.bitcoin.it/wiki/Secp256k1
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 m2049r
|
||||||
|
* Copyright (c) 2013 ChiaraHsieh
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.util.ledger;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.security.spec.ECPoint;
|
||||||
|
|
||||||
|
public class ECsecp256k1 {
|
||||||
|
static private final BigInteger TWO = new BigInteger("2");
|
||||||
|
static public final BigInteger p = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
|
||||||
|
static public final BigInteger a = new BigInteger("0000000000000000000000000000000000000000000000000000000000000000", 16);
|
||||||
|
static public final BigInteger b = new BigInteger("0000000000000000000000000000000000000000000000000000000000000007", 16);
|
||||||
|
static public final BigInteger n = new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
|
||||||
|
static public final ECPoint G = new ECPoint(
|
||||||
|
new BigInteger("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16),
|
||||||
|
new BigInteger("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 16));
|
||||||
|
|
||||||
|
public static ECPoint scalmult(BigInteger kin, ECPoint P) {
|
||||||
|
ECPoint R = ECPoint.POINT_INFINITY, S = P;
|
||||||
|
BigInteger k = kin.mod(n); // not necessary b/c that's how curves work
|
||||||
|
int length = k.bitLength();
|
||||||
|
byte[] binarray = new byte[length];
|
||||||
|
for (int i = 0; i <= length - 1; i++) {
|
||||||
|
binarray[i] = k.mod(TWO).byteValue();
|
||||||
|
k = k.divide(TWO);
|
||||||
|
}
|
||||||
|
for (int i = length - 1; i >= 0; i--) {
|
||||||
|
// i should start at length-1 not -2 because the MSB of binary may not be 1
|
||||||
|
R = doublePoint(R);
|
||||||
|
if (binarray[i] == 1)
|
||||||
|
R = addPoint(R, S);
|
||||||
|
}
|
||||||
|
return R;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ECPoint addPoint(ECPoint r, ECPoint s) {
|
||||||
|
if (r.equals(s))
|
||||||
|
return doublePoint(r);
|
||||||
|
else if (r.equals(ECPoint.POINT_INFINITY))
|
||||||
|
return s;
|
||||||
|
else if (s.equals(ECPoint.POINT_INFINITY))
|
||||||
|
return r;
|
||||||
|
BigInteger slope = (r.getAffineY().subtract(s.getAffineY())).multiply(r.getAffineX().subtract(s.getAffineX()).modInverse(p)).mod(p);
|
||||||
|
BigInteger Xout = (slope.modPow(TWO, p).subtract(r.getAffineX())).subtract(s.getAffineX()).mod(p);
|
||||||
|
BigInteger Yout = s.getAffineY().negate().mod(p);
|
||||||
|
Yout = Yout.add(slope.multiply(s.getAffineX().subtract(Xout))).mod(p);
|
||||||
|
return new ECPoint(Xout, Yout);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ECPoint doublePoint(ECPoint r) {
|
||||||
|
if (r.equals(ECPoint.POINT_INFINITY))
|
||||||
|
return r;
|
||||||
|
BigInteger slope = (r.getAffineX().pow(2)).multiply(new BigInteger("3"));
|
||||||
|
slope = slope.add(a);
|
||||||
|
slope = slope.multiply((r.getAffineY().multiply(TWO)).modInverse(p));
|
||||||
|
BigInteger Xout = slope.pow(2).subtract(r.getAffineX().multiply(TWO)).mod(p);
|
||||||
|
BigInteger Yout = (r.getAffineY().negate()).add(slope.multiply(r.getAffineX().subtract(Xout))).mod(p);
|
||||||
|
return new ECPoint(Xout, Yout);
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,170 @@
|
||||||
|
package com.theromus.sha;
|
||||||
|
|
||||||
|
import static com.theromus.utils.HexUtils.leftRotate64;
|
||||||
|
import static com.theromus.utils.HexUtils.convertToUint;
|
||||||
|
import static com.theromus.utils.HexUtils.convertFromLittleEndianTo64;
|
||||||
|
import static com.theromus.utils.HexUtils.convertFrom64ToLittleEndian;
|
||||||
|
import static java.lang.Math.min;
|
||||||
|
import static java.lang.System.arraycopy;
|
||||||
|
import static java.util.Arrays.fill;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keccak implementation.
|
||||||
|
*
|
||||||
|
* @author romus
|
||||||
|
*/
|
||||||
|
public class Keccak {
|
||||||
|
|
||||||
|
private static BigInteger BIT_64 = new BigInteger("18446744073709551615");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do hash.
|
||||||
|
*
|
||||||
|
* @param message input data
|
||||||
|
* @param parameter keccak param
|
||||||
|
* @return byte-array result
|
||||||
|
*/
|
||||||
|
public byte[] getHash(final byte[] message, final Parameters parameter) {
|
||||||
|
int[] uState = new int[200];
|
||||||
|
int[] uMessage = convertToUint(message);
|
||||||
|
|
||||||
|
|
||||||
|
int rateInBytes = parameter.getRate() / 8;
|
||||||
|
int blockSize = 0;
|
||||||
|
int inputOffset = 0;
|
||||||
|
|
||||||
|
// Absorbing phase
|
||||||
|
while (inputOffset < uMessage.length) {
|
||||||
|
blockSize = min(uMessage.length - inputOffset, rateInBytes);
|
||||||
|
for (int i = 0; i < blockSize; i++) {
|
||||||
|
uState[i] = uState[i] ^ uMessage[i + inputOffset];
|
||||||
|
}
|
||||||
|
|
||||||
|
inputOffset = inputOffset + blockSize;
|
||||||
|
if (blockSize == rateInBytes) {
|
||||||
|
doKeccakf(uState);
|
||||||
|
blockSize = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Padding phase
|
||||||
|
uState[blockSize] = uState[blockSize] ^ parameter.getD();
|
||||||
|
if ((parameter.getD() & 0x80) != 0 && blockSize == (rateInBytes - 1)) {
|
||||||
|
doKeccakf(uState);
|
||||||
|
}
|
||||||
|
|
||||||
|
uState[rateInBytes - 1] = uState[rateInBytes - 1] ^ 0x80;
|
||||||
|
doKeccakf(uState);
|
||||||
|
|
||||||
|
// Squeezing phase
|
||||||
|
ByteArrayOutputStream byteResults = new ByteArrayOutputStream();
|
||||||
|
int tOutputLen = parameter.getOutputLen() / 8;
|
||||||
|
while (tOutputLen > 0) {
|
||||||
|
blockSize = min(tOutputLen, rateInBytes);
|
||||||
|
for (int i = 0; i < blockSize; i++) {
|
||||||
|
byteResults.write((byte) uState[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
tOutputLen -= blockSize;
|
||||||
|
if (tOutputLen > 0) {
|
||||||
|
doKeccakf(uState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteResults.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doKeccakf(final int[] uState) {
|
||||||
|
BigInteger[][] lState = new BigInteger[5][5];
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
for (int j = 0; j < 5; j++) {
|
||||||
|
int[] data = new int[8];
|
||||||
|
arraycopy(uState, 8 * (i + 5 * j), data, 0, data.length);
|
||||||
|
lState[i][j] = convertFromLittleEndianTo64(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roundB(lState);
|
||||||
|
|
||||||
|
fill(uState, 0);
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
for (int j = 0; j < 5; j++) {
|
||||||
|
int[] data = convertFrom64ToLittleEndian(lState[i][j]);
|
||||||
|
arraycopy(data, 0, uState, 8 * (i + 5 * j), data.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permutation on the given state.
|
||||||
|
*
|
||||||
|
* @param state state
|
||||||
|
*/
|
||||||
|
private void roundB(final BigInteger[][] state) {
|
||||||
|
int LFSRstate = 1;
|
||||||
|
for (int round = 0; round < 24; round++) {
|
||||||
|
BigInteger[] C = new BigInteger[5];
|
||||||
|
BigInteger[] D = new BigInteger[5];
|
||||||
|
|
||||||
|
// θ step
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
C[i] = state[i][0].xor(state[i][1]).xor(state[i][2]).xor(state[i][3]).xor(state[i][4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
D[i] = C[(i + 4) % 5].xor(leftRotate64(C[(i + 1) % 5], 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
for (int j = 0; j < 5; j++) {
|
||||||
|
state[i][j] = state[i][j].xor(D[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ρ and π steps
|
||||||
|
int x = 1, y = 0;
|
||||||
|
BigInteger current = state[x][y];
|
||||||
|
for (int i = 0; i < 24; i++) {
|
||||||
|
int tX = x;
|
||||||
|
x = y;
|
||||||
|
y = (2 * tX + 3 * y) % 5;
|
||||||
|
|
||||||
|
BigInteger shiftValue = current;
|
||||||
|
current = state[x][y];
|
||||||
|
|
||||||
|
state[x][y] = leftRotate64(shiftValue, (i + 1) * (i + 2) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
//χ step
|
||||||
|
for (int j = 0; j < 5; j++) {
|
||||||
|
BigInteger[] t = new BigInteger[5];
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
t[i] = state[i][j];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
// ~t[(i + 1) % 5]
|
||||||
|
BigInteger invertVal = t[(i + 1) % 5].xor(BIT_64);
|
||||||
|
// t[i] ^ ((~t[(i + 1) % 5]) & t[(i + 2) % 5])
|
||||||
|
state[i][j] = t[i].xor(invertVal.and(t[(i + 2) % 5]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ι step
|
||||||
|
for (int i = 0; i < 7; i++) {
|
||||||
|
LFSRstate = ((LFSRstate << 1) ^ ((LFSRstate >> 7) * 0x71)) % 256;
|
||||||
|
// pow(2, i) - 1
|
||||||
|
int bitPosition = (1 << i) - 1;
|
||||||
|
if ((LFSRstate & 2) != 0) {
|
||||||
|
state[0][0] = state[0][0].xor(new BigInteger("1").shiftLeft(bitPosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package com.theromus.sha;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The parameters defining the standard FIPS 202.
|
||||||
|
*
|
||||||
|
* @author romus
|
||||||
|
*/
|
||||||
|
public enum Parameters {
|
||||||
|
KECCAK_224 (1152, 0x01, 224),
|
||||||
|
KECCAK_256 (1088, 0x01, 256),
|
||||||
|
KECCAK_384 (832, 0x01, 384),
|
||||||
|
KECCAK_512 (576, 0x01, 512),
|
||||||
|
|
||||||
|
SHA3_224 (1152, 0x06, 224),
|
||||||
|
SHA3_256 (1088, 0x06, 256),
|
||||||
|
SHA3_384 (832, 0x06, 384),
|
||||||
|
SHA3_512 (576, 0x06, 512),
|
||||||
|
|
||||||
|
SHAKE128 (1344, 0x1F, 256),
|
||||||
|
SHAKE256 (1088, 0x1F, 512);
|
||||||
|
|
||||||
|
private final int rate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delimited suffix.
|
||||||
|
*/
|
||||||
|
public final int d;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output length (bits).
|
||||||
|
*/
|
||||||
|
public final int outputLen;
|
||||||
|
|
||||||
|
Parameters(int rate, int d, int outputLen) {
|
||||||
|
this.rate = rate;
|
||||||
|
this.d = d;
|
||||||
|
this.outputLen = outputLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getRate() {
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getD() {
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOutputLen() {
|
||||||
|
return outputLen;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
package com.theromus.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hex-utils.
|
||||||
|
*
|
||||||
|
* @author romus
|
||||||
|
*/
|
||||||
|
public class HexUtils {
|
||||||
|
|
||||||
|
private static final byte[] ENCODE_BYTE_TABLE = {
|
||||||
|
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
|
||||||
|
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert byte array to unsigned array.
|
||||||
|
*
|
||||||
|
* @param data byte array
|
||||||
|
* @return unsigned array
|
||||||
|
*/
|
||||||
|
public static int[] convertToUint(final byte[] data) {
|
||||||
|
int[] converted = new int[data.length];
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
converted[i] = data[i] & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return converted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert LE to 64-bit value (unsigned long).
|
||||||
|
*
|
||||||
|
* @param data data
|
||||||
|
* @return 64-bit value (unsigned long)
|
||||||
|
*/
|
||||||
|
public static BigInteger convertFromLittleEndianTo64(final int[] data) {
|
||||||
|
BigInteger uLong = new BigInteger("0");
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
uLong = uLong.add(new BigInteger(Integer.toString(data[i])).shiftLeft(8 * i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return uLong;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert 64-bit (unsigned long) value to LE.
|
||||||
|
*
|
||||||
|
* @param uLong 64-bit value (unsigned long)
|
||||||
|
* @return LE
|
||||||
|
*/
|
||||||
|
public static int[] convertFrom64ToLittleEndian(final BigInteger uLong) {
|
||||||
|
int[] data = new int[8];
|
||||||
|
BigInteger mod256 = new BigInteger("256");
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
data[i] = uLong.shiftRight((8 * i)).mod(mod256).intValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitwise rotate left.
|
||||||
|
*
|
||||||
|
* @param value unsigned long value
|
||||||
|
* @param rotate rotate left
|
||||||
|
* @return result
|
||||||
|
*/
|
||||||
|
public static BigInteger leftRotate64(final BigInteger value, final int rotate) {
|
||||||
|
BigInteger lp = value.shiftRight(64 - (rotate % 64));
|
||||||
|
BigInteger rp = value.shiftLeft(rotate % 64);
|
||||||
|
|
||||||
|
return lp.add(rp).mod(new BigInteger("18446744073709551616"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert bytes to string.
|
||||||
|
*
|
||||||
|
* @param data bytes array
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static String convertBytesToString(final byte[] data) {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
for (int i = 0; i < data.length; i++) {
|
||||||
|
int uVal = data[i] & 0xFF;
|
||||||
|
|
||||||
|
buffer.write(ENCODE_BYTE_TABLE[(uVal >>> 4)]);
|
||||||
|
buffer.write(ENCODE_BYTE_TABLE[uVal & 0xF]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new String(buffer.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="8dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/MoneroLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:labelFor="@+id/etSeed"
|
||||||
|
android:text="@string/menu_ledger_seed"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
style="@style/MoneroLabel"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
android:textColor="@color/colorAccent"
|
||||||
|
android:labelFor="@+id/etSeed"
|
||||||
|
android:text="@string/prompt_ledger_seed_warn" />
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/etSeed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:errorEnabled="true">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
style="@style/MoneroEdit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt_ledger_seed"
|
||||||
|
android:imeOptions="normal"
|
||||||
|
android:inputType="textMultiLine|textVisiblePassword" />
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputLayout
|
||||||
|
android:id="@+id/etPassphrase"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:errorEnabled="true">
|
||||||
|
|
||||||
|
<android.support.design.widget.TextInputEditText
|
||||||
|
style="@style/MoneroEdit"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/prompt_ledger_phrase"
|
||||||
|
android:imeOptions="normal"
|
||||||
|
android:inputType="textVisiblePassword" />
|
||||||
|
|
||||||
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvOpenPrompt"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:drawablePadding="10dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</LinearLayout>
|
|
@ -7,6 +7,13 @@
|
||||||
android:icon="@drawable/ic_help_white_24dp"
|
android:icon="@drawable/ic_help_white_24dp"
|
||||||
android:orderInCategory="100"
|
android:orderInCategory="100"
|
||||||
android:title="@string/menu_help"
|
android:title="@string/menu_help"
|
||||||
app:showAsAction="always" />
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_ledger_seed"
|
||||||
|
android:icon="@drawable/ic_ledger_restore"
|
||||||
|
android:orderInCategory="200"
|
||||||
|
android:title="@string/menu_ledger_seed"
|
||||||
|
app:showAsAction="never" />
|
||||||
|
|
||||||
</menu>
|
</menu>
|
|
@ -376,4 +376,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -375,4 +375,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -375,4 +375,10 @@
|
||||||
<string name="xmrto_error_012">Tro da mendoj</string>
|
<string name="xmrto_error_012">Tro da mendoj</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">ĈIO!</string>
|
<string name="street_sweep_amount">ĈIO!</string>
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -365,4 +365,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -373,4 +373,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -379,4 +379,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -377,4 +377,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -378,4 +378,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -421,4 +421,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -375,4 +375,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -375,4 +375,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -367,4 +367,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -379,4 +379,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -375,4 +375,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -379,4 +379,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -377,4 +377,9 @@
|
||||||
|
|
||||||
<string name="street_sweep_amount">VŠETKO!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">VŠETKO!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -360,4 +360,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -379,4 +379,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -373,4 +373,10 @@
|
||||||
<string name="xmrto_error_012">Too many requests</string>
|
<string name="xmrto_error_012">Too many requests</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
<string name="street_sweep_amount">EVERYTHING!</string> <!-- as in: "everything in the account" = "all the money" -->
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -374,4 +374,10 @@
|
||||||
<string name="xmrto_error_012">請求過於頻繁</string>
|
<string name="xmrto_error_012">請求過於頻繁</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">全部!</string>
|
<string name="street_sweep_amount">全部!</string>
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (optional)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -424,4 +424,10 @@
|
||||||
<string name="xmrto_error" translatable="false">XMR.TO Service Error</string>
|
<string name="xmrto_error" translatable="false">XMR.TO Service Error</string>
|
||||||
|
|
||||||
<string name="street_sweep_amount">EVERYTHING!</string>
|
<string name="street_sweep_amount">EVERYTHING!</string>
|
||||||
|
|
||||||
|
<string name="menu_ledger_seed">Convert Ledger Seed</string>
|
||||||
|
<string name="prompt_ledger_seed">Ledger Seed Words</string>
|
||||||
|
<string name="prompt_ledger_phrase">Ledger Passphrase (advanced)</string>
|
||||||
|
<string name="bad_ledger_seed">Invalid Ledger Seed!</string>
|
||||||
|
<string name="prompt_ledger_seed_warn">Entering you Ledger Seed here is a major security risk!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019 m2049r
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.m2049r.xmrwallet.util.ledger;
|
||||||
|
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
public class MoneroTest {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public ExpectedException thrown = ExpectedException.none();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aRealTest() {
|
||||||
|
String ledgerMnemonic = "weird cloth shiver soda music slight system slender daughter magic design story gospel bulk teach between spice kangaroo inside satoshi convince load morning income";
|
||||||
|
String ledgerPassphrase = "";
|
||||||
|
String monero_mnemonic = "maverick aimless laptop eating vibrate sensible bugs dreams " +
|
||||||
|
"journal sincerely renting obtains boss mullet rustled cuddled " +
|
||||||
|
"goblet nightly jailed hamburger getting benches haggled hesitate laptop";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bRealTest() {
|
||||||
|
String ledgerMnemonic = "weird cloth shiver soda music slight system slender daughter magic design story gospel bulk teach between spice kangaroo inside satoshi convince load morning income";
|
||||||
|
String ledgerPassphrase = "secret";
|
||||||
|
String monero_mnemonic = "surfer hemlock afraid huddle mostly yanks revamp pairing " +
|
||||||
|
"northern yodel obliged vials azure huddle mowing melting " +
|
||||||
|
"ruthless subtly civilian midst playful vats nabbing nowhere mowing";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aTest() {
|
||||||
|
String ledgerMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
String ledgerPassphrase = "";
|
||||||
|
String monero_mnemonic = "tavern judge beyond bifocals deepest mural onward dummy " +
|
||||||
|
"eagle diode gained vacation rally cause firm idled " +
|
||||||
|
"jerseys moat vigilant upload bobsled jobs cunning doing jobs";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bTest() {
|
||||||
|
String ledgerMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
String ledgerPassphrase = "xyz";
|
||||||
|
String monero_mnemonic = "gambit observant swiftly metro hoax pheasants agile oozed " +
|
||||||
|
"fibula nuns picked stellar nibs cause gained phase " +
|
||||||
|
"lettuce tomorrow pierce awakened pistons pheasants sorry tedious gambit";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whitespaceTest() {
|
||||||
|
String ledgerMnemonic = " abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
String ledgerPassphrase = "xyz";
|
||||||
|
String monero_mnemonic = "gambit observant swiftly metro hoax pheasants agile oozed " +
|
||||||
|
"fibula nuns picked stellar nibs cause gained phase " +
|
||||||
|
"lettuce tomorrow pierce awakened pistons pheasants sorry tedious gambit";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void caseTest() {
|
||||||
|
String ledgerMnemonic = "Abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
String ledgerPassphrase = "xyz";
|
||||||
|
String monero_mnemonic = "gambit observant swiftly metro hoax pheasants agile oozed " +
|
||||||
|
"fibula nuns picked stellar nibs cause gained phase " +
|
||||||
|
"lettuce tomorrow pierce awakened pistons pheasants sorry tedious gambit";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertTrue(monero_mnemonic.equals(test_monero));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void nullTest() {
|
||||||
|
String ledgerMnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||||
|
String ledgerPassphrase = "xyz";
|
||||||
|
String test_monero = Monero.convert(ledgerMnemonic, ledgerPassphrase);
|
||||||
|
assertNull(test_monero);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,9 @@ allprojects {
|
||||||
maven {
|
maven {
|
||||||
url "https://maven.google.com"
|
url "https://maven.google.com"
|
||||||
}
|
}
|
||||||
|
maven {
|
||||||
|
url "https://repository.mulesoft.org/nexus/content/repositories/public/"
|
||||||
|
}
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue