mirror of
https://github.com/OneKeyHQ/bip39.git
synced 2026-04-29 13:36:01 +00:00
Entropy can be supplied by user
This commit is contained in:
+50
-6
@@ -65,12 +65,14 @@
|
||||
<div class="col-md-12">
|
||||
<h2>Mnemonic</h2>
|
||||
<form class="form-horizontal" role="form">
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-10">
|
||||
<p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
|
||||
<p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-10">
|
||||
<p>You can enter an existing BIP39 mnemonic, or generate a new random one. Typing your own twelve words will probably not work how you expect, since the words require a particular structure (the last word is a checksum)</p>
|
||||
<p>For more info see the <a href="https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki" target="_blank">BIP39 spec</a></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group generate-container">
|
||||
<label class="col-sm-2 control-label"></label>
|
||||
<div class="col-sm-10">
|
||||
<div class="form-inline">
|
||||
@@ -92,7 +94,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="entropy-container hidden">
|
||||
<label for="entropy" class="col-sm-2 control-label">Entropy</label>
|
||||
<div class="col-sm-10">
|
||||
<input id="entropy" class="entropy form-control" placeholder="Accepts binary, base 6, 6-sided dice, base 10, hexadecimal">
|
||||
<span class="help-block">
|
||||
<div class="text-danger">
|
||||
This is an advanced feature.
|
||||
Your mnemonic may be insecure if this feature is used incorrectly.
|
||||
<a href="#entropy-notes">Read more</a>
|
||||
</div>
|
||||
<div class="text-danger entropy-error"></div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-2"></div>
|
||||
<div class="col-sm-10 checkbox">
|
||||
<label>
|
||||
<input type="checkbox" class="use-entropy">
|
||||
Supply my own source of entropy
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-2 control-label"></label>
|
||||
<div class="col-sm-10 languages">
|
||||
<a href="#english">English</a>
|
||||
@@ -353,6 +378,24 @@
|
||||
but be careful - it can be easy to make mistakes if you
|
||||
don't know what you're doing
|
||||
</p>
|
||||
<h3 id="entropy-notes">Entropy</h3>
|
||||
<p>
|
||||
Entropy values must be sourced from a
|
||||
<a href="https://en.wikipedia.org/wiki/Random_number_generation" target="_blank">strong source of randomness</a>.
|
||||
This means flipping a fair coin, rolling a fair dice, noise measurements etc. Do <strong>NOT</strong> use
|
||||
phrases from books, lyrics from songs, your birthday or steet address, keyboard mashing, or anything you <i>think</i>
|
||||
is random, because chances are <em>overwhelming</em> that it isn't random enough for the needs of this tool.
|
||||
</p>
|
||||
<p>
|
||||
The random mnemonic generator on this page uses a
|
||||
<a href="https://developer.mozilla.org/en-US/docs/Web/API/RandomSource/getRandomValues" target="_blank">cryptographically secure random number generator</a>,
|
||||
and can generally be trusted more than your own intuition about randomness.
|
||||
If cryptographic randomness isn't available in your browser, this page will show a warning and <i>will not generate
|
||||
random mnemonics</i>.
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://bitcointalk.org/index.php?topic=311000.msg3345309#msg3345309" target="_blank">You are not a good source of entropy.</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -465,6 +508,7 @@
|
||||
<script src="js/wordlist_french.js"></script>
|
||||
<script src="js/wordlist_italian.js"></script>
|
||||
<script src="js/jsbip39.js"></script>
|
||||
<script src="js/entropy.js"></script>
|
||||
<script src="js/index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+1774
File diff suppressed because it is too large
Load Diff
+105
-1
@@ -14,14 +14,20 @@
|
||||
var showPubKey = true;
|
||||
var showPrivKey = true;
|
||||
|
||||
var entropyChangeTimeoutEvent = null;
|
||||
var phraseChangeTimeoutEvent = null;
|
||||
var rootKeyChangedTimeoutEvent = null;
|
||||
|
||||
var DOM = {};
|
||||
DOM.network = $(".network");
|
||||
DOM.phraseNetwork = $("#network-phrase");
|
||||
DOM.useEntropy = $(".use-entropy");
|
||||
DOM.entropyContainer = $(".entropy-container");
|
||||
DOM.entropy = $(".entropy");
|
||||
DOM.entropyError = $(".entropy-error");
|
||||
DOM.phrase = $(".phrase");
|
||||
DOM.passphrase = $(".passphrase");
|
||||
DOM.generateContainer = $(".generate-container");
|
||||
DOM.generate = $(".generate");
|
||||
DOM.seed = $(".seed");
|
||||
DOM.rootKey = $(".root-key");
|
||||
@@ -53,6 +59,8 @@
|
||||
function init() {
|
||||
// Events
|
||||
DOM.network.on("change", networkChanged);
|
||||
DOM.useEntropy.on("change", setEntropyVisibility);
|
||||
DOM.entropy.on("input", delayedEntropyChanged);
|
||||
DOM.phrase.on("input", delayedPhraseChanged);
|
||||
DOM.passphrase.on("input", delayedPhraseChanged);
|
||||
DOM.generate.on("click", generateClicked);
|
||||
@@ -89,6 +97,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
function setEntropyVisibility() {
|
||||
if (isUsingOwnEntropy()) {
|
||||
DOM.entropyContainer.removeClass("hidden");
|
||||
DOM.generateContainer.addClass("hidden");
|
||||
DOM.phrase.prop("readonly", true);
|
||||
DOM.entropy.focus();
|
||||
entropyChanged();
|
||||
}
|
||||
else {
|
||||
DOM.entropyContainer.addClass("hidden");
|
||||
DOM.generateContainer.removeClass("hidden");
|
||||
DOM.phrase.prop("readonly", false);
|
||||
}
|
||||
}
|
||||
|
||||
function delayedPhraseChanged() {
|
||||
hideValidationError();
|
||||
showPending();
|
||||
@@ -116,6 +139,20 @@
|
||||
hidePending();
|
||||
}
|
||||
|
||||
function delayedEntropyChanged() {
|
||||
hideValidationError();
|
||||
showPending();
|
||||
if (entropyChangeTimeoutEvent != null) {
|
||||
clearTimeout(entropyChangeTimeoutEvent);
|
||||
}
|
||||
entropyChangeTimeoutEvent = setTimeout(entropyChanged, 400);
|
||||
}
|
||||
|
||||
function entropyChanged() {
|
||||
setMnemonicFromEntropy();
|
||||
phraseChanged();
|
||||
}
|
||||
|
||||
function delayedRootKeyChanged() {
|
||||
// Warn if there is an existing mnemonic or passphrase.
|
||||
if (DOM.phrase.val().length > 0 || DOM.passphrase.val().length > 0) {
|
||||
@@ -168,6 +205,9 @@
|
||||
}
|
||||
|
||||
function generateClicked() {
|
||||
if (isUsingOwnEntropy()) {
|
||||
return;
|
||||
}
|
||||
clearDisplay();
|
||||
showPending();
|
||||
setTimeout(function() {
|
||||
@@ -599,7 +639,12 @@
|
||||
}
|
||||
|
||||
function getLanguageFromUrl() {
|
||||
return window.location.hash.substring(1);
|
||||
for (var language in WORDLISTS) {
|
||||
if (window.location.hash.indexOf(language) > -1) {
|
||||
return language;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
function setMnemonicLanguage() {
|
||||
@@ -650,6 +695,65 @@
|
||||
return phrase;
|
||||
}
|
||||
|
||||
function isUsingOwnEntropy() {
|
||||
return DOM.useEntropy.prop("checked");
|
||||
}
|
||||
|
||||
function setMnemonicFromEntropy() {
|
||||
hideEntropyError();
|
||||
// Work out minimum base for entropy
|
||||
var entropyStr = DOM.entropy.val();
|
||||
var entropy = Entropy.fromString(entropyStr);
|
||||
if (entropy.hexStr.length == 0) {
|
||||
return;
|
||||
}
|
||||
// Show entropy details
|
||||
var extraBits = 32 - (entropy.binaryStr.length % 32);
|
||||
var extraChars = Math.ceil(extraBits * Math.log(2) / Math.log(entropy.base.asInt));
|
||||
var strength = "an extremely weak";
|
||||
if (entropy.hexStr.length >= 8) {
|
||||
strength = "a very weak";
|
||||
}
|
||||
if (entropy.hexStr.length >= 12) {
|
||||
strength = "a weak";
|
||||
}
|
||||
if (entropy.hexStr.length >= 24) {
|
||||
strength = "a strong";
|
||||
}
|
||||
if (entropy.hexStr.length >= 32) {
|
||||
strength = "a very strong";
|
||||
}
|
||||
if (entropy.hexStr.length >= 40) {
|
||||
strength = "an extremely strong";
|
||||
}
|
||||
if (entropy.hexStr.length >=48) {
|
||||
strength = "an even stronger"
|
||||
}
|
||||
var msg = "Have " + entropy.binaryStr.length + " bits of entropy, " + extraChars + " more " + entropy.base.str + " chars required to generate " + strength + " mnemonic: " + entropy.cleanStr;
|
||||
showEntropyError(msg);
|
||||
// Discard trailing entropy
|
||||
var hexStr = entropy.hexStr.substring(0, Math.floor(entropy.hexStr.length / 8) * 8);
|
||||
// Convert entropy string to numeric array
|
||||
var entropyArr = [];
|
||||
for (var i=0; i<hexStr.length / 2; i++) {
|
||||
var entropyByte = parseInt(hexStr[i*2].concat(hexStr[i*2+1]), 16);
|
||||
entropyArr.push(entropyByte)
|
||||
}
|
||||
// Convert entropy array to mnemonic
|
||||
var phrase = mnemonic.toMnemonic(entropyArr);
|
||||
// Set the mnemonic in the UI
|
||||
DOM.phrase.val(phrase);
|
||||
}
|
||||
|
||||
function hideEntropyError() {
|
||||
DOM.entropyError.addClass("hidden");
|
||||
}
|
||||
|
||||
function showEntropyError(msg) {
|
||||
DOM.entropyError.text(msg);
|
||||
DOM.entropyError.removeClass("hidden");
|
||||
}
|
||||
|
||||
var networks = [
|
||||
{
|
||||
name: "Bitcoin",
|
||||
|
||||
Reference in New Issue
Block a user