/*
*
* Copyright 2014 http://Bither.net
*
* 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 net.bither.xrandom;
import net.bither.Bither;
import net.bither.bitherj.core.Address;
import net.bither.bitherj.crypto.ECKey;
import net.bither.bitherj.crypto.SecureCharSequence;
import net.bither.bitherj.utils.PrivateKeyUtil;
import net.bither.utils.KeyUtil;
import net.bither.utils.PeerUtil;
import net.bither.viewsystem.froms.PasswordPanel;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
public class PrivateKeyUEntropyDialog extends UEntropyDialog<java.util.List<String>> {
public PrivateKeyUEntropyDialog(int targetCount, PasswordPanel.PasswordGetter passwordGetter) {
super(targetCount, passwordGetter);
}
@Override
Thread getGeneratingThreadWithXRandom(UEntropyCollector collector) {
return new GenerateThread(collector);
}
@Override
void didSuccess(List<String> addressStr) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
quit();
Bither.refreshFrame();
}
});
}
private class GenerateThread extends Thread {
private double saveProgress = 0.1;
private double startProgress = 0.01;
private double progressKeyRate = 0.5;
private double progressEntryptRate = 0.5;
private long startGeneratingTime;
private Runnable cancelRunnable;
private UEntropyCollector entropyCollector;
public GenerateThread(UEntropyCollector entropyCollector) {
this.entropyCollector = entropyCollector;
}
@Override
public synchronized void start() {
super.start();
}
public void cancel(Runnable cancelRunnable) {
this.cancelRunnable = cancelRunnable;
}
private void finishGenerate() {
passwordGetter.wipe();
PeerUtil.startPeer();
entropyCollector.stop();
}
@Override
public void run() {
startGeneratingTime = System.currentTimeMillis();
onProgress(startProgress);
SecureCharSequence password = passwordGetter.getPassword();
boolean success = false;
final ArrayList<String> addressStrs = new ArrayList<String>();
double progress = startProgress;
double itemProgress = (1.0 - startProgress - saveProgress) / (double) targetCount;
try {
entropyCollector.start();
PeerUtil.stopPeer();
java.util.List<Address> addressList = new ArrayList<Address>();
for (int i = 0;
i < targetCount;
i++) {
if (cancelRunnable != null) {
finishGenerate();
SwingUtilities.invokeLater(cancelRunnable);
return;
}
XRandom xRandom = new XRandom(entropyCollector);
ECKey ecKey = ECKey.generateECKey(xRandom);
ecKey.setFromXRandom(true);
progress += itemProgress * progressKeyRate;
onProgress(progress);
if (cancelRunnable != null) {
finishGenerate();
SwingUtilities.invokeLater(cancelRunnable);
return;
}
// start encrypt
ecKey = PrivateKeyUtil.encrypt(ecKey, password);
Address address = new Address(ecKey.toAddress(), ecKey.getPubKey(),
PrivateKeyUtil.getEncryptedString(ecKey), ecKey.isFromXRandom());
ecKey.clearPrivateKey();
addressList.add(address);
addressStrs.add(address.getAddress());
progress += itemProgress * progressEntryptRate;
onProgress(progress);
}
entropyCollector.stop();
passwordGetter.wipe();
if (cancelRunnable != null) {
finishGenerate();
SwingUtilities.invokeLater(cancelRunnable);
return;
}
KeyUtil.addAddressListByDesc(addressList);
success = true;
} catch (Exception e) {
e.printStackTrace();
}
finishGenerate();
if (success) {
while (System.currentTimeMillis() - startGeneratingTime < MinGeneratingTime) {
}
onProgress(1);
didSuccess(addressStrs);
} else {
onFailed();
}
}
private void onFailed() {
quit();
}
}
}