Skip to content
This repository was archived by the owner on Jan 24, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "warpwallet",
"version": "1.0.8",
"version": "1.0.9",
"description": "Open Source JavaScript Client-Side Bitcoin Wallet Generator Using scrypt",
"dependencies": {
"brew": "*",
Expand All @@ -13,7 +13,8 @@
"iced-utils": ">=0.1.1",
"icsify": "*",
"keybase-bitcoin": ">=0.0.0",
"triplesec": "keybase/triplesec#header_v3"
"triplesec": "keybase/triplesec#header_v3",
"bitcore-mnemonic": ">=1.1.1"
},
"repository": {
"type": "git",
Expand Down
8 changes: 7 additions & 1 deletion src/coffee/site.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ class Warper
$('#passphrase').on 'keyup', => @any_change()
$('#public-address').on 'click', -> $(@).select()
$('#private-key').on 'click', -> $(@).select()
$('#bip39-seed').on 'click', -> $(@).select()
$('#bip39-mnemonic').on 'click', -> $(@).select()
$('.what-salt').on 'click', => $('.salt-explanation').toggle()

any_change: ->
$('.progress-form').hide()
$('#private-key').val ''
$('#public-address').val ''
$('#bip39-seed').val ''
$('#bip39-mnemonic').val ''
$('#btn-submit').attr('disabled', false).show().html 'Generate'
pp = $('#passphrase').val()
salt = $('#salt').val()
Expand Down Expand Up @@ -92,7 +96,7 @@ class Warper

click_reset: ->
$('#btn-submit').attr('disabled', false).show().html 'Please enter a passphrase'
$('#passphrase, #public-address, #private-key').val ''
$('#passphrase, #public-address, #private-key', '#bip39-seed', '#bip39-mnemonic').val ''
if not window.SALT_DEFAULT?
$('#salt').val ''
$('#checkbox-salt-confirm').attr 'checked', false
Expand Down Expand Up @@ -135,6 +139,8 @@ class Warper
$('#btn-reset').attr('disabled', false).html 'Clear & reset'
$('#public-address').val res.public
$('#private-key').val res.private
$('#bip39-seed').val res.seeds[2].toString('hex')
$('#bip39-mnemonic').val res.mnemonic
@write_qrs res.public, res.private
console.log

Expand Down
4 changes: 2 additions & 2 deletions src/css/site.css
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ h1 .second-half {
.salt-summary {
text-decoration: underline
}
#public-address, #private-key {
#public-address, #private-key, #bip39-seed, #bip39-mnemonic {
cursor:pointer;
background-color: #fff
}
Expand Down Expand Up @@ -175,4 +175,4 @@ hr {
border-top: 1px solid #777;
margin: 1em 0;
padding: 0;
}
}
2 changes: 2 additions & 0 deletions src/iced/top.iced
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

{scrypt,pbkdf2,HMAC_SHA256,WordArray,util} = require 'triplesec'
generate = require('keybase-bitcoin').generate
mnemonic = require('bitcore-mnemonic')
params = require('../json/params.json')

#=====================================
Expand Down Expand Up @@ -47,6 +48,7 @@ exports.run = run = ({passphrase, salt, progress_hook}, cb) ->

out = generate seed_final
out.seeds = seeds
out.mnemonic = mnemonic.fromSeed(seed_final.slice(0,16), mnemonic.Words.ENGLISH).toString()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any particular reason to only use 16 elements from the seed? I believe that mnemonic.fromSeed does not require any particular number of items, so we might as well use the whole seed.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

16 bytes of entropy will generate a 12 word phrase (this is the most common used phrase size) 32 bytes would generate a 24 word phrase, and so on. Every 4 bytes adds 3 words.

Copy link

@casey casey Feb 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, gotcha.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case I think the mnemonic length should be a user defined parameter. And perhaps it should default to 24. Since it doesn't need to be remembered or stored, it might as well be more secure.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maximum security of ECDSA is n/2 of key size.

256 bit keys of bitcoin are only 128 bits strong, which is why 12 words is considered default on most wallets. 24 words exists if you need more words for some sort of special security measure.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First of all, obfuscating this person's name does nobody any favors. Second of all, you show in your chat that you walk in to the conversation with a preconceived notion that I am wrong, and merely went to find someone you thought has clout (by looking at a wallet that uses default 24 words and poking around until someone vindicated your position) and strangely, obfuscate the name.

Also, I never said "a 24 word mnemonic doesn't provide additional security." like you did. I recognize that in special circumstances, having a 24 word or 300 word phrase could be useful, but as with the 300 word phrase example it is easy to understand that phrase lengths increasing starts to add detriments to the user experience.

To cover the points given though:

  1. Symmetric encryption is not relevant here, a brute force against 2^128 phrases and 2^256 phrases would find bitcoins at random OR targeted specifically at the same probability due to the pigeon hole principle.
  2. This is the only valid concern, but for instance, Trezor manages this vector by having the Trezor randomly display "type the word 'baseball'" etc. during recovery process in order to throw off key loggers, and inserting random fake words into the out of order recovery process. tl;dr these concerns are easily dealt with.
  3. Worrying about the chaincode is a moot point, if there was any known weakness in SHA2 (512 bit is also SHA2) that would show that knowing the later 32 bytes along with having a smaller possibility set would make the leftmost 32 bytes brute forceable in less than 2^256 or the original source of entropy (2^128 in our case) then that would be a very very bad weakness, and someone being able to brute force your phrase a tiny bit faster would be the least of your worries. (it could mean the beginning of a large avalanche of weaknesses found in SHA2 and bitcoin is going to be in for a wild ride)
  4. The Quantum computer comment at the end was also completely wrong, as the 128 bit seed is not directly used for calculating the public key... it is encoded into a phrase which requires a hash for the checksum as well as an iterative hash over the phrase to create a 64 byte hash which then is run through an HMAC which creates the private key and chain code which is then hashed again a few more times to derive the different paths to get to the actual key with a balance, which is THEN run through ECDSA multiplication... grover's algorithm must have gotten very versatile to do all of that. /s

And to top it all off:

99% of warp wallets don't have 128 bits of entropy to begin with (as the whole selling point is "ooooh look how long it takes, you can have a simple one word password with your email address and we'll magically turn that into 5 million bits of entropy using iterative hashing") so arguing over 12 or 24 words is security theatre to be honest.

The likelihood that a user is using their dogs name with their publicly known email as their warp wallet is far more likely than someone snagging their phone and running a forensic analysis on their finger prints in order to lift 12 words but they just so happen to not be able to do it for 24 words.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't mean to come off wrong. Please assume good intent. All I care about is that warpwallet be as secure as possible.

I asked in a public channel and this was the first answer I got. I asked the question in the way I did because I know that ledger uses 24 word mnemonics, and so I was concerned that this PR only uses 12.

I obfuscated the name simply because I didn't ask this person's permission to quote them, and figured that it would be polite not to use their name.

I'm not sure if the last point is correct. WarpWallets don't have 128 bits of entropy, however, that is before key stretching. Since key stretching provides additional security, it seems like we should treat entropy before key stretching and after key stretching as separate.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also:

  1. In that case, wouldn't it be better to force an attacker to brute force attack 2^256 phrases?

  2. Grover's algorithm can be used to find inputs to a black box function using O(sqrt(N)) evaluations of the function, where N is the size of the function's domain. (Copied from wikipedia.) In this case, the black box function would be that whose input is the 128 bit seed and whose output is a public key. I could be wrong, but I don't believe it matters what the function is.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The added extra entropy by the stretching is insignificant.

Thinking in bits is hard, but to make things simple to understand, let's imagine the user had a super strong password. 80 bits (which would be a 25 character password completely random from a 70 character set)

In order for key stretching to provide equivalent 48 bits of the remaining neede effective entropy, it would need to make the calculations be 2.81 x 10^14 times more expensive in calculation time.

If the original calculation took one microsecond, your stretching would need to take 8 years to make 48 bits of effective entropy.

tl;dr Key stretching is NOT meant to replace entropy. And entropy is a LOT harder to gather than people think.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a persuasive argument. Let me see if I can follow it:

If a password is 80 random bits, then in the worst case it will take 2^80 guesses to guess it. If each guess takes a microsecond, then that's 3.8e10 years.

If a password is 128 random bits, then in the worst case it will take 2^128 guesses to guess it. At one microsecond a guess, that's 1.1e25 years.

So, in order for key stretching to make guessing our 80 bit password take as long as our 128 bit password, we need to make the 2^80 guesses take as long as the 2^128 guesses.

Through the magic of exponentiation, 1.1e25 years - 3.8e10 years ~= 1.1e25 years, so we need to make 2^80 * key-stretching function evaluation time = 1.1e25 years.

This means that each evaluation needs to take 9 years. (I rounded liberally, and 9 === 8 for the purposes of this discussion.)

So you're definitely right, key stretching cannot make up for entropy.

cb out

#=====================================
Expand Down
Loading