1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
\
\
\ \ \
import argparse import binascii import json import scrypt import sys from passlib.utils import pbkdf2 from pycoin import ecdsa, encoding from pycoin.ecdsa import secp256k1
class WarpWallet(object):
def \_\_init\_\_(self, pbkdf2\_count, derived\_key\_len, scrypt\_power, scrypt_p, scrypt_r): self.dklen = derived\_key\_len self.pbkdf2\_count = pbkdf2\_count self.scrypt\_power = scrypt\_power self.scrypt\_r = scrypt\_r self.scrypt\_p = scrypt\_p
def warp(self, passphrase, salt=""): """ Return dictionary of WarpWallet public and private keys corresponding to the given passphrase and salt. """ s1 = binascii.hexlify(self._scrypt(passphrase, salt)) out = self._pbkdf2(passphrase, salt) s2 = binascii.hexlify(out) base = binascii.unhexlify(s1) s3 = binascii.hexlify(self._sxor(base,out)) secret_exponent = int(s3, 16) public\_pair = ecdsa.public\_pair\_for\_secret\_exponent(secp256k1.generator\_secp256k1, secret_exponent) public\_key = encoding.public\_pair\_to\_bitcoin\_address(public\_pair, compressed=False) out = public_key return out
def _scrypt(self, passphrase, salt=""): scrypt_key = passphrase + "x01" scrypt_salt = salt + "x01" out = scrypt.hash(scrypt\_key, scrypt\_salt, N=2**self.scrypt_power, r=self.scrypt\_r, p=self.scrypt\_p, buflen=self.dklen) return out
def _pbkdf2(self, passphrase, salt=""): hexlified_key = binascii.hexlify(passphrase) + "02" pbkdf2\_key = binascii.unhexlify(hexlified\_key) hexlified_salt = binascii.hexlify(salt) + "02" pbkdf2\_salt = binascii.unhexlify(hexlified\_salt) out = pbkdf2.pbkdf2(secret=pbkdf2\_key, salt=pbkdf2\_salt, keylen=self.dklen, rounds=self.pbkdf2\_count, prf='hmac\_sha256') return out
def _sxor (self, s1, s2): return ''.join(chr(ord(a) ^ ord(b)) for a,b in zip(s1,s2))
def parse_args(): parser = argparse.ArgumentParser() parser.add\_argument("-c", "--pbkdf2\_count", help="iteration count", type=int, default=2**16) parser.add_argument("-d", "--dklen", help="derived key length", type=int, default=32) parser.add\_argument("-n", "--scrypt\_power", help="2^n passed as the 'N' param to scrypt", type=int, default=18) parser.add\_argument("-p", "--scrypt\_p", help="'p' param to scrypt", type=int, default=1) parser.add\_argument("-r", "--scrypt\_r", help="'r' param to scrypt", type=int, default=8) parser.add_argument("-P", "--passphrase" , help="passphrase", type=str) parser.add_argument("-S", "--salt" , help="salt", type=str) args = parser.parse_args()
if not args.passphrase: print "Must provide passphrase (-P)" sys.exit(1) if not args.salt: print "Must provide salt (-S)" sys.exit(1)
return args
if \_\_name\_\_ == "\_\_main\_\_": f = open("c300dict.txt", 'r') for line in f: strpass = line.strip() salt = '[email protected]' wallet = WarpWallet(2**16, 32, 18,1, 8) str = wallet.warp(strpass, salt) if str == '1Atk95NnaQDiegEkqjJvg6c2KkJbSr2BEL': print 'get!', strpass break print line
|