pywallet.py 52 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755
  1. #!/usr/bin/env python
  2. # Changes by Philemon:
  3. # password entry at prompt
  4. # dump keys, addresses or keys for specified addresses (output in flat list)
  5. # PyWallet 1.2.1 (Public Domain)
  6. # http://github.com/joric/pywallet
  7. # Most of the actual PyWallet code placed in the public domain.
  8. # PyWallet includes portions of free software, listed below.
  9. # BitcoinTools (wallet.dat handling code, MIT License)
  10. # https://github.com/gavinandresen/bitcointools
  11. # Copyright (c) 2010 Gavin Andresen
  12. # python-ecdsa (EC_KEY implementation, MIT License)
  13. # http://github.com/warner/python-ecdsa
  14. # "python-ecdsa" Copyright (c) 2010 Brian Warner
  15. # Portions written in 2005 by Peter Pearson and placed in the public domain.
  16. # SlowAES (aes.py code, Apache 2 License)
  17. # http://code.google.com/p/slowaes/
  18. # Copyright (c) 2008, Josh Davis (http://www.josh-davis.org),
  19. # Alex Martelli (http://www.aleax.it)
  20. # Ported from C code written by Laurent Haan (http://www.progressive-coding.com)
  21. from mmgen.utils import msg
  22. from bsddb.db import *
  23. import os, sys, time
  24. import json
  25. import logging
  26. import struct
  27. import StringIO
  28. import traceback
  29. import socket
  30. import types
  31. import string
  32. import exceptions
  33. import hashlib
  34. import random
  35. import math
  36. max_version = 60000
  37. addrtype = 0
  38. json_db = {}
  39. private_keys = []
  40. password = None
  41. # def determine_db_dir():
  42. # import os
  43. # import os.path
  44. # import platform
  45. # if platform.system() == "Darwin":
  46. # return os.path.expanduser("~/Library/Application Support/Bitcoin/")
  47. # elif platform.system() == "Windows":
  48. # return os.path.join(os.environ['APPDATA'], "Bitcoin")
  49. # return os.path.expanduser("~/.bitcoin")
  50. # from the SlowAES project, http://code.google.com/p/slowaes (aes.py)
  51. def append_PKCS7_padding(s):
  52. """return s padded to a multiple of 16-bytes by PKCS7 padding"""
  53. numpads = 16 - (len(s)%16)
  54. return s + numpads*chr(numpads)
  55. def strip_PKCS7_padding(s):
  56. """return s stripped of PKCS7 padding"""
  57. if len(s)%16 or not s:
  58. raise ValueError("String of len %d can't be PCKS7-padded" % len(s))
  59. numpads = ord(s[-1])
  60. if numpads > 16:
  61. raise ValueError("String ending with %r can't be PCKS7-padded" % s[-1])
  62. return s[:-numpads]
  63. class AES(object):
  64. # valid key sizes
  65. keySize = dict(SIZE_128=16, SIZE_192=24, SIZE_256=32)
  66. # Rijndael S-box
  67. sbox = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67,
  68. 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59,
  69. 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7,
  70. 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1,
  71. 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05,
  72. 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83,
  73. 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29,
  74. 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
  75. 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa,
  76. 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c,
  77. 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc,
  78. 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
  79. 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19,
  80. 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee,
  81. 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49,
  82. 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
  83. 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4,
  84. 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6,
  85. 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70,
  86. 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9,
  87. 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e,
  88. 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1,
  89. 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0,
  90. 0x54, 0xbb, 0x16]
  91. # Rijndael Inverted S-box
  92. rsbox = [0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3,
  93. 0x9e, 0x81, 0xf3, 0xd7, 0xfb , 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f,
  94. 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb , 0x54,
  95. 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
  96. 0x42, 0xfa, 0xc3, 0x4e , 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24,
  97. 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 , 0x72, 0xf8,
  98. 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d,
  99. 0x65, 0xb6, 0x92 , 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
  100. 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 , 0x90, 0xd8, 0xab,
  101. 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3,
  102. 0x45, 0x06 , 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1,
  103. 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b , 0x3a, 0x91, 0x11, 0x41,
  104. 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6,
  105. 0x73 , 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9,
  106. 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e , 0x47, 0xf1, 0x1a, 0x71, 0x1d,
  107. 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b ,
  108. 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0,
  109. 0xfe, 0x78, 0xcd, 0x5a, 0xf4 , 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07,
  110. 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f , 0x60,
  111. 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f,
  112. 0x93, 0xc9, 0x9c, 0xef , 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5,
  113. 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 , 0x17, 0x2b,
  114. 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55,
  115. 0x21, 0x0c, 0x7d]
  116. def getSBoxValue(self,num):
  117. """Retrieves a given S-Box Value"""
  118. return self.sbox[num]
  119. def getSBoxInvert(self,num):
  120. """Retrieves a given Inverted S-Box Value"""
  121. return self.rsbox[num]
  122. def rotate(self, word):
  123. """ Rijndael's key schedule rotate operation.
  124. Rotate a word eight bits to the left: eg, rotate(1d2c3a4f) == 2c3a4f1d
  125. Word is an char list of size 4 (32 bits overall).
  126. """
  127. return word[1:] + word[:1]
  128. # Rijndael Rcon
  129. Rcon = [0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36,
  130. 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97,
  131. 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72,
  132. 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66,
  133. 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04,
  134. 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
  135. 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3,
  136. 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61,
  137. 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
  138. 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40,
  139. 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc,
  140. 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
  141. 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a,
  142. 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d,
  143. 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
  144. 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
  145. 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4,
  146. 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
  147. 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08,
  148. 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
  149. 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
  150. 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2,
  151. 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74,
  152. 0xe8, 0xcb ]
  153. def getRconValue(self, num):
  154. """Retrieves a given Rcon Value"""
  155. return self.Rcon[num]
  156. def core(self, word, iteration):
  157. """Key schedule core."""
  158. # rotate the 32-bit word 8 bits to the left
  159. word = self.rotate(word)
  160. # apply S-Box substitution on all 4 parts of the 32-bit word
  161. for i in range(4):
  162. word[i] = self.getSBoxValue(word[i])
  163. # XOR the output of the rcon operation with i to the first part
  164. # (leftmost) only
  165. word[0] = word[0] ^ self.getRconValue(iteration)
  166. return word
  167. def expandKey(self, key, size, expandedKeySize):
  168. """Rijndael's key expansion.
  169. Expands an 128,192,256 key into an 176,208,240 bytes key
  170. expandedKey is a char list of large enough size,
  171. key is the non-expanded key.
  172. """
  173. # current expanded keySize, in bytes
  174. currentSize = 0
  175. rconIteration = 1
  176. expandedKey = [0] * expandedKeySize
  177. # set the 16, 24, 32 bytes of the expanded key to the input key
  178. for j in range(size):
  179. expandedKey[j] = key[j]
  180. currentSize += size
  181. while currentSize < expandedKeySize:
  182. # assign the previous 4 bytes to the temporary value t
  183. t = expandedKey[currentSize-4:currentSize]
  184. # every 16,24,32 bytes we apply the core schedule to t
  185. # and increment rconIteration afterwards
  186. if currentSize % size == 0:
  187. t = self.core(t, rconIteration)
  188. rconIteration += 1
  189. # For 256-bit keys, we add an extra sbox to the calculation
  190. if size == self.keySize["SIZE_256"] and ((currentSize % size) == 16):
  191. for l in range(4): t[l] = self.getSBoxValue(t[l])
  192. # We XOR t with the four-byte block 16,24,32 bytes before the new
  193. # expanded key. This becomes the next four bytes in the expanded
  194. # key.
  195. for m in range(4):
  196. expandedKey[currentSize] = expandedKey[currentSize - size] ^ \
  197. t[m]
  198. currentSize += 1
  199. return expandedKey
  200. def addRoundKey(self, state, roundKey):
  201. """Adds (XORs) the round key to the state."""
  202. for i in range(16):
  203. state[i] ^= roundKey[i]
  204. return state
  205. def createRoundKey(self, expandedKey, roundKeyPointer):
  206. """Create a round key.
  207. Creates a round key from the given expanded key and the
  208. position within the expanded key.
  209. """
  210. roundKey = [0] * 16
  211. for i in range(4):
  212. for j in range(4):
  213. roundKey[j*4+i] = expandedKey[roundKeyPointer + i*4 + j]
  214. return roundKey
  215. def galois_multiplication(self, a, b):
  216. """Galois multiplication of 8 bit characters a and b."""
  217. p = 0
  218. for counter in range(8):
  219. if b & 1: p ^= a
  220. hi_bit_set = a & 0x80
  221. a <<= 1
  222. # keep a 8 bit
  223. a &= 0xFF
  224. if hi_bit_set:
  225. a ^= 0x1b
  226. b >>= 1
  227. return p
  228. #
  229. # substitute all the values from the state with the value in the SBox
  230. # using the state value as index for the SBox
  231. #
  232. def subBytes(self, state, isInv):
  233. if isInv: getter = self.getSBoxInvert
  234. else: getter = self.getSBoxValue
  235. for i in range(16): state[i] = getter(state[i])
  236. return state
  237. # iterate over the 4 rows and call shiftRow() with that row
  238. def shiftRows(self, state, isInv):
  239. for i in range(4):
  240. state = self.shiftRow(state, i*4, i, isInv)
  241. return state
  242. # each iteration shifts the row to the left by 1
  243. def shiftRow(self, state, statePointer, nbr, isInv):
  244. for i in range(nbr):
  245. if isInv:
  246. state[statePointer:statePointer+4] = \
  247. state[statePointer+3:statePointer+4] + \
  248. state[statePointer:statePointer+3]
  249. else:
  250. state[statePointer:statePointer+4] = \
  251. state[statePointer+1:statePointer+4] + \
  252. state[statePointer:statePointer+1]
  253. return state
  254. # galois multiplication of the 4x4 matrix
  255. def mixColumns(self, state, isInv):
  256. # iterate over the 4 columns
  257. for i in range(4):
  258. # construct one column by slicing over the 4 rows
  259. column = state[i:i+16:4]
  260. # apply the mixColumn on one column
  261. column = self.mixColumn(column, isInv)
  262. # put the values back into the state
  263. state[i:i+16:4] = column
  264. return state
  265. # galois multiplication of 1 column of the 4x4 matrix
  266. def mixColumn(self, column, isInv):
  267. if isInv: mult = [14, 9, 13, 11]
  268. else: mult = [2, 1, 1, 3]
  269. cpy = list(column)
  270. g = self.galois_multiplication
  271. column[0] = g(cpy[0], mult[0]) ^ g(cpy[3], mult[1]) ^ \
  272. g(cpy[2], mult[2]) ^ g(cpy[1], mult[3])
  273. column[1] = g(cpy[1], mult[0]) ^ g(cpy[0], mult[1]) ^ \
  274. g(cpy[3], mult[2]) ^ g(cpy[2], mult[3])
  275. column[2] = g(cpy[2], mult[0]) ^ g(cpy[1], mult[1]) ^ \
  276. g(cpy[0], mult[2]) ^ g(cpy[3], mult[3])
  277. column[3] = g(cpy[3], mult[0]) ^ g(cpy[2], mult[1]) ^ \
  278. g(cpy[1], mult[2]) ^ g(cpy[0], mult[3])
  279. return column
  280. # applies the 4 operations of the forward round in sequence
  281. def aes_round(self, state, roundKey):
  282. state = self.subBytes(state, False)
  283. state = self.shiftRows(state, False)
  284. state = self.mixColumns(state, False)
  285. state = self.addRoundKey(state, roundKey)
  286. return state
  287. # applies the 4 operations of the inverse round in sequence
  288. def aes_invRound(self, state, roundKey):
  289. state = self.shiftRows(state, True)
  290. state = self.subBytes(state, True)
  291. state = self.addRoundKey(state, roundKey)
  292. state = self.mixColumns(state, True)
  293. return state
  294. # Perform the initial operations, the standard round, and the final
  295. # operations of the forward aes, creating a round key for each round
  296. def aes_main(self, state, expandedKey, nbrRounds):
  297. state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
  298. i = 1
  299. while i < nbrRounds:
  300. state = self.aes_round(state, self.createRoundKey(expandedKey, 16*i))
  301. i += 1
  302. state = self.subBytes(state, False)
  303. state = self.shiftRows(state, False)
  304. state = self.addRoundKey(state, self.createRoundKey(expandedKey, 16*nbrRounds))
  305. return state
  306. # Perform the initial operations, the standard round, and the final
  307. # operations of the inverse aes, creating a round key for each round
  308. def aes_invMain(self, state, expandedKey, nbrRounds):
  309. state = self.addRoundKey(state, self.createRoundKey(expandedKey, 16*nbrRounds))
  310. i = nbrRounds - 1
  311. while i > 0:
  312. state = self.aes_invRound(state, self.createRoundKey(expandedKey, 16*i))
  313. i -= 1
  314. state = self.shiftRows(state, True)
  315. state = self.subBytes(state, True)
  316. state = self.addRoundKey(state, self.createRoundKey(expandedKey, 0))
  317. return state
  318. # encrypts a 128 bit input block against the given key of size specified
  319. def encrypt(self, iput, key, size):
  320. output = [0] * 16
  321. # the number of rounds
  322. nbrRounds = 0
  323. # the 128 bit block to encode
  324. block = [0] * 16
  325. # set the number of rounds
  326. if size == self.keySize["SIZE_128"]: nbrRounds = 10
  327. elif size == self.keySize["SIZE_192"]: nbrRounds = 12
  328. elif size == self.keySize["SIZE_256"]: nbrRounds = 14
  329. else: return None
  330. # the expanded keySize
  331. expandedKeySize = 16*(nbrRounds+1)
  332. # Set the block values, for the block:
  333. # a0,0 a0,1 a0,2 a0,3
  334. # a1,0 a1,1 a1,2 a1,3
  335. # a2,0 a2,1 a2,2 a2,3
  336. # a3,0 a3,1 a3,2 a3,3
  337. # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
  338. #
  339. # iterate over the columns
  340. for i in range(4):
  341. # iterate over the rows
  342. for j in range(4):
  343. block[(i+(j*4))] = iput[(i*4)+j]
  344. # expand the key into an 176, 208, 240 bytes key
  345. # the expanded key
  346. expandedKey = self.expandKey(key, size, expandedKeySize)
  347. # encrypt the block using the expandedKey
  348. block = self.aes_main(block, expandedKey, nbrRounds)
  349. # unmap the block again into the output
  350. for k in range(4):
  351. # iterate over the rows
  352. for l in range(4):
  353. output[(k*4)+l] = block[(k+(l*4))]
  354. return output
  355. # decrypts a 128 bit input block against the given key of size specified
  356. def decrypt(self, iput, key, size):
  357. output = [0] * 16
  358. # the number of rounds
  359. nbrRounds = 0
  360. # the 128 bit block to decode
  361. block = [0] * 16
  362. # set the number of rounds
  363. if size == self.keySize["SIZE_128"]: nbrRounds = 10
  364. elif size == self.keySize["SIZE_192"]: nbrRounds = 12
  365. elif size == self.keySize["SIZE_256"]: nbrRounds = 14
  366. else: return None
  367. # the expanded keySize
  368. expandedKeySize = 16*(nbrRounds+1)
  369. # Set the block values, for the block:
  370. # a0,0 a0,1 a0,2 a0,3
  371. # a1,0 a1,1 a1,2 a1,3
  372. # a2,0 a2,1 a2,2 a2,3
  373. # a3,0 a3,1 a3,2 a3,3
  374. # the mapping order is a0,0 a1,0 a2,0 a3,0 a0,1 a1,1 ... a2,3 a3,3
  375. # iterate over the columns
  376. for i in range(4):
  377. # iterate over the rows
  378. for j in range(4):
  379. block[(i+(j*4))] = iput[(i*4)+j]
  380. # expand the key into an 176, 208, 240 bytes key
  381. expandedKey = self.expandKey(key, size, expandedKeySize)
  382. # decrypt the block using the expandedKey
  383. block = self.aes_invMain(block, expandedKey, nbrRounds)
  384. # unmap the block again into the output
  385. for k in range(4):
  386. # iterate over the rows
  387. for l in range(4):
  388. output[(k*4)+l] = block[(k+(l*4))]
  389. return output
  390. class AESModeOfOperation(object):
  391. aes = AES()
  392. # structure of supported modes of operation
  393. modeOfOperation = dict(OFB=0, CFB=1, CBC=2)
  394. # converts a 16 character string into a number array
  395. def convertString(self, string, start, end, mode):
  396. if end - start > 16: end = start + 16
  397. if mode == self.modeOfOperation["CBC"]: ar = [0] * 16
  398. else: ar = []
  399. i = start
  400. j = 0
  401. while len(ar) < end - start:
  402. ar.append(0)
  403. while i < end:
  404. ar[j] = ord(string[i])
  405. j += 1
  406. i += 1
  407. return ar
  408. # Mode of Operation Encryption
  409. # stringIn - Input String
  410. # mode - mode of type modeOfOperation
  411. # hexKey - a hex key of the bit length size
  412. # size - the bit length of the key
  413. # hexIV - the 128 bit hex Initilization Vector
  414. def encrypt(self, stringIn, mode, key, size, IV):
  415. if len(key) % size:
  416. return None
  417. if len(IV) % 16:
  418. return None
  419. # the AES input/output
  420. plaintext = []
  421. iput = [0] * 16
  422. output = []
  423. ciphertext = [0] * 16
  424. # the output cipher string
  425. cipherOut = []
  426. # char firstRound
  427. firstRound = True
  428. if stringIn != None:
  429. for j in range(int(math.ceil(float(len(stringIn))/16))):
  430. start = j*16
  431. end = j*16+16
  432. if end > len(stringIn):
  433. end = len(stringIn)
  434. plaintext = self.convertString(stringIn, start, end, mode)
  435. # print 'PT@%s:%s' % (j, plaintext)
  436. if mode == self.modeOfOperation["CFB"]:
  437. if firstRound:
  438. output = self.aes.encrypt(IV, key, size)
  439. firstRound = False
  440. else:
  441. output = self.aes.encrypt(iput, key, size)
  442. for i in range(16):
  443. if len(plaintext)-1 < i:
  444. ciphertext[i] = 0 ^ output[i]
  445. elif len(output)-1 < i:
  446. ciphertext[i] = plaintext[i] ^ 0
  447. elif len(plaintext)-1 < i and len(output) < i:
  448. ciphertext[i] = 0 ^ 0
  449. else:
  450. ciphertext[i] = plaintext[i] ^ output[i]
  451. for k in range(end-start):
  452. cipherOut.append(ciphertext[k])
  453. iput = ciphertext
  454. elif mode == self.modeOfOperation["OFB"]:
  455. if firstRound:
  456. output = self.aes.encrypt(IV, key, size)
  457. firstRound = False
  458. else:
  459. output = self.aes.encrypt(iput, key, size)
  460. for i in range(16):
  461. if len(plaintext)-1 < i:
  462. ciphertext[i] = 0 ^ output[i]
  463. elif len(output)-1 < i:
  464. ciphertext[i] = plaintext[i] ^ 0
  465. elif len(plaintext)-1 < i and len(output) < i:
  466. ciphertext[i] = 0 ^ 0
  467. else:
  468. ciphertext[i] = plaintext[i] ^ output[i]
  469. for k in range(end-start):
  470. cipherOut.append(ciphertext[k])
  471. iput = output
  472. elif mode == self.modeOfOperation["CBC"]:
  473. for i in range(16):
  474. if firstRound:
  475. iput[i] = plaintext[i] ^ IV[i]
  476. else:
  477. iput[i] = plaintext[i] ^ ciphertext[i]
  478. # print 'IP@%s:%s' % (j, iput)
  479. firstRound = False
  480. ciphertext = self.aes.encrypt(iput, key, size)
  481. # always 16 bytes because of the padding for CBC
  482. for k in range(16):
  483. cipherOut.append(ciphertext[k])
  484. return mode, len(stringIn), cipherOut
  485. # Mode of Operation Decryption
  486. # cipherIn - Encrypted String
  487. # originalsize - The unencrypted string length - required for CBC
  488. # mode - mode of type modeOfOperation
  489. # key - a number array of the bit length size
  490. # size - the bit length of the key
  491. # IV - the 128 bit number array Initilization Vector
  492. def decrypt(self, cipherIn, originalsize, mode, key, size, IV):
  493. # cipherIn = unescCtrlChars(cipherIn)
  494. if len(key) % size:
  495. return None
  496. if len(IV) % 16:
  497. return None
  498. # the AES input/output
  499. ciphertext = []
  500. iput = []
  501. output = []
  502. plaintext = [0] * 16
  503. # the output plain text string
  504. stringOut = ''
  505. # char firstRound
  506. firstRound = True
  507. if cipherIn != None:
  508. for j in range(int(math.ceil(float(len(cipherIn))/16))):
  509. start = j*16
  510. end = j*16+16
  511. if j*16+16 > len(cipherIn):
  512. end = len(cipherIn)
  513. ciphertext = cipherIn[start:end]
  514. if mode == self.modeOfOperation["CFB"]:
  515. if firstRound:
  516. output = self.aes.encrypt(IV, key, size)
  517. firstRound = False
  518. else:
  519. output = self.aes.encrypt(iput, key, size)
  520. for i in range(16):
  521. if len(output)-1 < i:
  522. plaintext[i] = 0 ^ ciphertext[i]
  523. elif len(ciphertext)-1 < i:
  524. plaintext[i] = output[i] ^ 0
  525. elif len(output)-1 < i and len(ciphertext) < i:
  526. plaintext[i] = 0 ^ 0
  527. else:
  528. plaintext[i] = output[i] ^ ciphertext[i]
  529. for k in range(end-start):
  530. stringOut += chr(plaintext[k])
  531. iput = ciphertext
  532. elif mode == self.modeOfOperation["OFB"]:
  533. if firstRound:
  534. output = self.aes.encrypt(IV, key, size)
  535. firstRound = False
  536. else:
  537. output = self.aes.encrypt(iput, key, size)
  538. for i in range(16):
  539. if len(output)-1 < i:
  540. plaintext[i] = 0 ^ ciphertext[i]
  541. elif len(ciphertext)-1 < i:
  542. plaintext[i] = output[i] ^ 0
  543. elif len(output)-1 < i and len(ciphertext) < i:
  544. plaintext[i] = 0 ^ 0
  545. else:
  546. plaintext[i] = output[i] ^ ciphertext[i]
  547. for k in range(end-start):
  548. stringOut += chr(plaintext[k])
  549. iput = output
  550. elif mode == self.modeOfOperation["CBC"]:
  551. output = self.aes.decrypt(ciphertext, key, size)
  552. for i in range(16):
  553. if firstRound:
  554. plaintext[i] = IV[i] ^ output[i]
  555. else:
  556. plaintext[i] = iput[i] ^ output[i]
  557. firstRound = False
  558. if originalsize is not None and originalsize < end:
  559. for k in range(originalsize-start):
  560. stringOut += chr(plaintext[k])
  561. else:
  562. for k in range(end-start):
  563. stringOut += chr(plaintext[k])
  564. iput = ciphertext
  565. return stringOut
  566. # end of aes.py code
  567. # pywallet crypter implementation
  568. crypter = None
  569. try:
  570. from Crypto.Cipher import AES
  571. crypter = 'pycrypto'
  572. except:
  573. pass
  574. class Crypter_pycrypto( object ):
  575. def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  576. if nDerivationMethod != 0:
  577. return 0
  578. data = vKeyData + vSalt
  579. for i in xrange(nDerivIterations):
  580. data = hashlib.sha512(data).digest()
  581. self.SetKey(data[0:32])
  582. self.SetIV(data[32:32+16])
  583. return len(data)
  584. def SetKey(self, key):
  585. self.chKey = key
  586. def SetIV(self, iv):
  587. self.chIV = iv[0:16]
  588. def Encrypt(self, data):
  589. return AES.new(self.chKey,AES.MODE_CBC,self.chIV).encrypt(data)[0:32]
  590. def Decrypt(self, data):
  591. return AES.new(self.chKey,AES.MODE_CBC,self.chIV).decrypt(data)[0:32]
  592. try:
  593. if not crypter:
  594. import ctypes
  595. import ctypes.util
  596. ssl = ctypes.cdll.LoadLibrary (ctypes.util.find_library ('ssl') or 'libeay32')
  597. crypter = 'ssl'
  598. except:
  599. pass
  600. class Crypter_ssl(object):
  601. def __init__(self):
  602. self.chKey = ctypes.create_string_buffer (32)
  603. self.chIV = ctypes.create_string_buffer (16)
  604. def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  605. if nDerivationMethod != 0:
  606. return 0
  607. strKeyData = ctypes.create_string_buffer (vKeyData)
  608. chSalt = ctypes.create_string_buffer (vSalt)
  609. return ssl.EVP_BytesToKey(ssl.EVP_aes_256_cbc(), ssl.EVP_sha512(), chSalt, strKeyData,
  610. len(vKeyData), nDerivIterations, ctypes.byref(self.chKey), ctypes.byref(self.chIV))
  611. def SetKey(self, key):
  612. self.chKey = ctypes.create_string_buffer(key)
  613. def SetIV(self, iv):
  614. self.chIV = ctypes.create_string_buffer(iv)
  615. def Encrypt(self, data):
  616. buf = ctypes.create_string_buffer(len(data) + 16)
  617. written = ctypes.c_int(0)
  618. final = ctypes.c_int(0)
  619. ctx = ssl.EVP_CIPHER_CTX_new()
  620. ssl.EVP_CIPHER_CTX_init(ctx)
  621. ssl.EVP_EncryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV)
  622. ssl.EVP_EncryptUpdate(ctx, buf, ctypes.byref(written), data, len(data))
  623. output = buf.raw[:written.value]
  624. ssl.EVP_EncryptFinal_ex(ctx, buf, ctypes.byref(final))
  625. output += buf.raw[:final.value]
  626. return output
  627. def Decrypt(self, data):
  628. buf = ctypes.create_string_buffer(len(data) + 16)
  629. written = ctypes.c_int(0)
  630. final = ctypes.c_int(0)
  631. ctx = ssl.EVP_CIPHER_CTX_new()
  632. ssl.EVP_CIPHER_CTX_init(ctx)
  633. ssl.EVP_DecryptInit_ex(ctx, ssl.EVP_aes_256_cbc(), None, self.chKey, self.chIV)
  634. ssl.EVP_DecryptUpdate(ctx, buf, ctypes.byref(written), data, len(data))
  635. output = buf.raw[:written.value]
  636. ssl.EVP_DecryptFinal_ex(ctx, buf, ctypes.byref(final))
  637. output += buf.raw[:final.value]
  638. return output
  639. class Crypter_pure(object):
  640. def __init__(self):
  641. self.m = AESModeOfOperation()
  642. self.cbc = self.m.modeOfOperation["CBC"]
  643. self.sz = self.m.aes.keySize["SIZE_256"]
  644. def SetKeyFromPassphrase(self, vKeyData, vSalt, nDerivIterations, nDerivationMethod):
  645. if nDerivationMethod != 0:
  646. return 0
  647. data = vKeyData + vSalt
  648. for i in xrange(nDerivIterations):
  649. data = hashlib.sha512(data).digest()
  650. self.SetKey(data[0:32])
  651. self.SetIV(data[32:32+16])
  652. return len(data)
  653. def SetKey(self, key):
  654. self.chKey = [ord(i) for i in key]
  655. def SetIV(self, iv):
  656. self.chIV = [ord(i) for i in iv]
  657. def Encrypt(self, data):
  658. mode, size, cypher = self.m.encrypt(data, self.cbc, self.chKey, self.sz, self.chIV)
  659. return ''.join(map(chr, cypher))
  660. def Decrypt(self, data):
  661. chData = [ord(i) for i in data]
  662. return self.m.decrypt(chData, self.sz, self.cbc, self.chKey, self.sz, self.chIV)
  663. # secp256k1
  664. _p = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FL
  665. _r = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141L
  666. _b = 0x0000000000000000000000000000000000000000000000000000000000000007L
  667. _a = 0x0000000000000000000000000000000000000000000000000000000000000000L
  668. _Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798L
  669. _Gy = 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8L
  670. # python-ecdsa code (EC_KEY implementation)
  671. class CurveFp( object ):
  672. def __init__( self, p, a, b ):
  673. self.__p = p
  674. self.__a = a
  675. self.__b = b
  676. def p( self ):
  677. return self.__p
  678. def a( self ):
  679. return self.__a
  680. def b( self ):
  681. return self.__b
  682. def contains_point( self, x, y ):
  683. return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
  684. class Point( object ):
  685. def __init__( self, curve, x, y, order = None ):
  686. self.__curve = curve
  687. self.__x = x
  688. self.__y = y
  689. self.__order = order
  690. if self.__curve: assert self.__curve.contains_point( x, y )
  691. if order: assert self * order == INFINITY
  692. def __add__( self, other ):
  693. if other == INFINITY: return self
  694. if self == INFINITY: return other
  695. assert self.__curve == other.__curve
  696. if self.__x == other.__x:
  697. if ( self.__y + other.__y ) % self.__curve.p() == 0:
  698. return INFINITY
  699. else:
  700. return self.double()
  701. p = self.__curve.p()
  702. l = ( ( other.__y - self.__y ) * \
  703. inverse_mod( other.__x - self.__x, p ) ) % p
  704. x3 = ( l * l - self.__x - other.__x ) % p
  705. y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  706. return Point( self.__curve, x3, y3 )
  707. def __mul__( self, other ):
  708. def leftmost_bit( x ):
  709. assert x > 0
  710. result = 1L
  711. while result <= x: result = 2 * result
  712. return result / 2
  713. e = other
  714. if self.__order: e = e % self.__order
  715. if e == 0: return INFINITY
  716. if self == INFINITY: return INFINITY
  717. assert e > 0
  718. e3 = 3 * e
  719. negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
  720. i = leftmost_bit( e3 ) / 2
  721. result = self
  722. while i > 1:
  723. result = result.double()
  724. if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
  725. if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
  726. i = i / 2
  727. return result
  728. def __rmul__( self, other ):
  729. return self * other
  730. def __str__( self ):
  731. if self == INFINITY: return "infinity"
  732. return "(%d,%d)" % ( self.__x, self.__y )
  733. def double( self ):
  734. if self == INFINITY:
  735. return INFINITY
  736. p = self.__curve.p()
  737. a = self.__curve.a()
  738. l = ( ( 3 * self.__x * self.__x + a ) * \
  739. inverse_mod( 2 * self.__y, p ) ) % p
  740. x3 = ( l * l - 2 * self.__x ) % p
  741. y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
  742. return Point( self.__curve, x3, y3 )
  743. def x( self ):
  744. return self.__x
  745. def y( self ):
  746. return self.__y
  747. def curve( self ):
  748. return self.__curve
  749. def order( self ):
  750. return self.__order
  751. INFINITY = Point( None, None, None )
  752. def inverse_mod( a, m ):
  753. if a < 0 or m <= a: a = a % m
  754. c, d = a, m
  755. uc, vc, ud, vd = 1, 0, 0, 1
  756. while c != 0:
  757. q, c, d = divmod( d, c ) + ( c, )
  758. uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
  759. assert d == 1
  760. if ud > 0: return ud
  761. else: return ud + m
  762. class Signature( object ):
  763. def __init__( self, r, s ):
  764. self.r = r
  765. self.s = s
  766. class Public_key( object ):
  767. def __init__( self, generator, point ):
  768. self.curve = generator.curve()
  769. self.generator = generator
  770. self.point = point
  771. n = generator.order()
  772. if not n:
  773. raise RuntimeError, "Generator point must have order."
  774. if not n * point == INFINITY:
  775. raise RuntimeError, "Generator point order is bad."
  776. if point.x() < 0 or n <= point.x() or point.y() < 0 or n <= point.y():
  777. raise RuntimeError, "Generator point has x or y out of range."
  778. def verifies( self, hash, signature ):
  779. G = self.generator
  780. n = G.order()
  781. r = signature.r
  782. s = signature.s
  783. if r < 1 or r > n-1: return False
  784. if s < 1 or s > n-1: return False
  785. c = inverse_mod( s, n )
  786. u1 = ( hash * c ) % n
  787. u2 = ( r * c ) % n
  788. xy = u1 * G + u2 * self.point
  789. v = xy.x() % n
  790. return v == r
  791. class Private_key( object ):
  792. def __init__( self, public_key, secret_multiplier ):
  793. self.public_key = public_key
  794. self.secret_multiplier = secret_multiplier
  795. def der( self ):
  796. hex_der_key = '06052b8104000a30740201010420' + \
  797. '%064x' % self.secret_multiplier + \
  798. 'a00706052b8104000aa14403420004' + \
  799. '%064x' % self.public_key.point.x() + \
  800. '%064x' % self.public_key.point.y()
  801. return hex_der_key.decode('hex')
  802. def sign( self, hash, random_k ):
  803. G = self.public_key.generator
  804. n = G.order()
  805. k = random_k % n
  806. p1 = k * G
  807. r = p1.x()
  808. if r == 0: raise RuntimeError, "amazingly unlucky random number r"
  809. s = ( inverse_mod( k, n ) * \
  810. ( hash + ( self.secret_multiplier * r ) % n ) ) % n
  811. if s == 0: raise RuntimeError, "amazingly unlucky random number s"
  812. return Signature( r, s )
  813. class EC_KEY(object):
  814. def __init__( self, secret ):
  815. curve = CurveFp( _p, _a, _b )
  816. generator = Point( curve, _Gx, _Gy, _r )
  817. self.pubkey = Public_key( generator, generator * secret )
  818. self.privkey = Private_key( self.pubkey, secret )
  819. self.secret = secret
  820. # end of python-ecdsa code
  821. # pywallet openssl private key implementation
  822. def i2d_ECPrivateKey(pkey, compressed=False):
  823. if compressed:
  824. key = '3081d30201010420' + \
  825. '%064x' % pkey.secret + \
  826. 'a081a53081a2020101302c06072a8648ce3d0101022100' + \
  827. '%064x' % _p + \
  828. '3006040100040107042102' + \
  829. '%064x' % _Gx + \
  830. '022100' + \
  831. '%064x' % _r + \
  832. '020101a124032200'
  833. else:
  834. key = '308201130201010420' + \
  835. '%064x' % pkey.secret + \
  836. 'a081a53081a2020101302c06072a8648ce3d0101022100' + \
  837. '%064x' % _p + \
  838. '3006040100040107044104' + \
  839. '%064x' % _Gx + \
  840. '%064x' % _Gy + \
  841. '022100' + \
  842. '%064x' % _r + \
  843. '020101a144034200'
  844. return key.decode('hex') + i2o_ECPublicKey(pkey, compressed)
  845. def i2o_ECPublicKey(pkey, compressed=False):
  846. # public keys are 65 bytes long (520 bits)
  847. # 0x04 + 32-byte X-coordinate + 32-byte Y-coordinate
  848. # 0x00 = point at infinity, 0x02 and 0x03 = compressed, 0x04 = uncompressed
  849. # compressed keys: <sign> <x> where <sign> is 0x02 if y is even and 0x03 if y is odd
  850. if compressed:
  851. if pkey.pubkey.point.y() & 1:
  852. key = '03' + '%064x' % pkey.pubkey.point.x()
  853. else:
  854. key = '02' + '%064x' % pkey.pubkey.point.x()
  855. else:
  856. key = '04' + \
  857. '%064x' % pkey.pubkey.point.x() + \
  858. '%064x' % pkey.pubkey.point.y()
  859. return key.decode('hex')
  860. # bitcointools hashes and base58 implementation
  861. def hash_160(public_key):
  862. md = hashlib.new('ripemd160')
  863. md.update(hashlib.sha256(public_key).digest())
  864. return md.digest()
  865. def public_key_to_bc_address(public_key):
  866. h160 = hash_160(public_key)
  867. return hash_160_to_bc_address(h160)
  868. def hash_160_to_bc_address(h160):
  869. vh160 = chr(addrtype) + h160
  870. h = Hash(vh160)
  871. addr = vh160 + h[0:4]
  872. return b58encode(addr)
  873. def bc_address_to_hash_160(addr):
  874. bytes = b58decode(addr, 25)
  875. return bytes[1:21]
  876. __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
  877. __b58base = len(__b58chars)
  878. def b58encode(v):
  879. """ encode v, which is a string of bytes, to base58.
  880. """
  881. long_value = 0L
  882. for (i, c) in enumerate(v[::-1]):
  883. long_value += (256**i) * ord(c)
  884. result = ''
  885. while long_value >= __b58base:
  886. div, mod = divmod(long_value, __b58base)
  887. result = __b58chars[mod] + result
  888. long_value = div
  889. result = __b58chars[long_value] + result
  890. # Bitcoin does a little leading-zero-compression:
  891. # leading 0-bytes in the input become leading-1s
  892. nPad = 0
  893. for c in v:
  894. if c == '\0': nPad += 1
  895. else: break
  896. return (__b58chars[0]*nPad) + result
  897. def b58decode(v, length):
  898. """ decode v into a string of len bytes
  899. """
  900. long_value = 0L
  901. for (i, c) in enumerate(v[::-1]):
  902. long_value += __b58chars.find(c) * (__b58base**i)
  903. result = ''
  904. while long_value >= 256:
  905. div, mod = divmod(long_value, 256)
  906. result = chr(mod) + result
  907. long_value = div
  908. result = chr(long_value) + result
  909. nPad = 0
  910. for c in v:
  911. if c == __b58chars[0]: nPad += 1
  912. else: break
  913. result = chr(0)*nPad + result
  914. if length is not None and len(result) != length:
  915. return None
  916. return result
  917. # end of bitcointools base58 implementation
  918. # address handling code
  919. def Hash(data):
  920. return hashlib.sha256(hashlib.sha256(data).digest()).digest()
  921. def EncodeBase58Check(secret):
  922. hash = Hash(secret)
  923. return b58encode(secret + hash[0:4])
  924. def DecodeBase58Check(sec):
  925. vchRet = b58decode(sec, None)
  926. secret = vchRet[0:-4]
  927. csum = vchRet[-4:]
  928. hash = Hash(secret)
  929. cs32 = hash[0:4]
  930. if cs32 != csum:
  931. return None
  932. else:
  933. return secret
  934. def PrivKeyToSecret(privkey):
  935. if len(privkey) == 279:
  936. return privkey[9:9+32]
  937. else:
  938. return privkey[8:8+32]
  939. def SecretToASecret(secret, compressed=False):
  940. vchIn = chr((addrtype+128)&255) + secret
  941. if compressed: vchIn += '\01'
  942. return EncodeBase58Check(vchIn)
  943. def ASecretToSecret(sec):
  944. vch = DecodeBase58Check(sec)
  945. if vch and vch[0] == chr((addrtype+128)&255):
  946. return vch[1:]
  947. else:
  948. return False
  949. def regenerate_key(sec):
  950. b = ASecretToSecret(sec)
  951. if not b:
  952. return False
  953. b = b[0:32]
  954. secret = int('0x' + b.encode('hex'), 16)
  955. return EC_KEY(secret)
  956. def GetPubKey(pkey, compressed=False):
  957. return i2o_ECPublicKey(pkey, compressed)
  958. def GetPrivKey(pkey, compressed=False):
  959. return i2d_ECPrivateKey(pkey, compressed)
  960. def GetSecret(pkey):
  961. return ('%064x' % pkey.secret).decode('hex')
  962. def is_compressed(sec):
  963. b = ASecretToSecret(sec)
  964. return len(b) == 33
  965. # bitcointools wallet.dat handling code
  966. def create_env(db_dir):
  967. db_env = DBEnv(0)
  968. r = db_env.open(db_dir, (DB_CREATE|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_THREAD|DB_RECOVER))
  969. return db_env
  970. def parse_CAddress(vds):
  971. d = {'ip':'0.0.0.0','port':0,'nTime': 0}
  972. try:
  973. d['nVersion'] = vds.read_int32()
  974. d['nTime'] = vds.read_uint32()
  975. d['nServices'] = vds.read_uint64()
  976. d['pchReserved'] = vds.read_bytes(12)
  977. d['ip'] = socket.inet_ntoa(vds.read_bytes(4))
  978. d['port'] = vds.read_uint16()
  979. except:
  980. pass
  981. return d
  982. def deserialize_CAddress(d):
  983. return d['ip']+":"+str(d['port'])
  984. def parse_BlockLocator(vds):
  985. d = { 'hashes' : [] }
  986. nHashes = vds.read_compact_size()
  987. for i in xrange(nHashes):
  988. d['hashes'].append(vds.read_bytes(32))
  989. return d
  990. def deserialize_BlockLocator(d):
  991. result = "Block Locator top: "+d['hashes'][0][::-1].encode('hex_codec')
  992. return result
  993. def parse_setting(setting, vds):
  994. if setting[0] == "f": # flag (boolean) settings
  995. return str(vds.read_boolean())
  996. elif setting[0:4] == "addr": # CAddress
  997. d = parse_CAddress(vds)
  998. return deserialize_CAddress(d)
  999. elif setting == "nTransactionFee":
  1000. return vds.read_int64()
  1001. elif setting == "nLimitProcessors":
  1002. return vds.read_int32()
  1003. return 'unknown setting'
  1004. class SerializationError(Exception):
  1005. """ Thrown when there's a problem deserializing or serializing """
  1006. class BCDataStream(object):
  1007. def __init__(self):
  1008. self.input = None
  1009. self.read_cursor = 0
  1010. def clear(self):
  1011. self.input = None
  1012. self.read_cursor = 0
  1013. def write(self, bytes): # Initialize with string of bytes
  1014. if self.input is None:
  1015. self.input = bytes
  1016. else:
  1017. self.input += bytes
  1018. def map_file(self, file, start): # Initialize with bytes from file
  1019. self.input = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
  1020. self.read_cursor = start
  1021. def seek_file(self, position):
  1022. self.read_cursor = position
  1023. def close_file(self):
  1024. self.input.close()
  1025. def read_string(self):
  1026. # Strings are encoded depending on length:
  1027. # 0 to 252 : 1-byte-length followed by bytes (if any)
  1028. # 253 to 65,535 : byte'253' 2-byte-length followed by bytes
  1029. # 65,536 to 4,294,967,295 : byte '254' 4-byte-length followed by bytes
  1030. # ... and the Bitcoin client is coded to understand:
  1031. # greater than 4,294,967,295 : byte '255' 8-byte-length followed by bytes of string
  1032. # ... but I don't think it actually handles any strings that big.
  1033. if self.input is None:
  1034. raise SerializationError("call write(bytes) before trying to deserialize")
  1035. try:
  1036. length = self.read_compact_size()
  1037. except IndexError:
  1038. raise SerializationError("attempt to read past end of buffer")
  1039. return self.read_bytes(length)
  1040. def write_string(self, string):
  1041. # Length-encoded as with read-string
  1042. self.write_compact_size(len(string))
  1043. self.write(string)
  1044. def read_bytes(self, length):
  1045. try:
  1046. result = self.input[self.read_cursor:self.read_cursor+length]
  1047. self.read_cursor += length
  1048. return result
  1049. except IndexError:
  1050. raise SerializationError("attempt to read past end of buffer")
  1051. return ''
  1052. def read_boolean(self): return self.read_bytes(1)[0] != chr(0)
  1053. def read_int16(self): return self._read_num('<h')
  1054. def read_uint16(self): return self._read_num('<H')
  1055. def read_int32(self): return self._read_num('<i')
  1056. def read_uint32(self): return self._read_num('<I')
  1057. def read_int64(self): return self._read_num('<q')
  1058. def read_uint64(self): return self._read_num('<Q')
  1059. def write_boolean(self, val): return self.write(chr(1) if val else chr(0))
  1060. def write_int16(self, val): return self._write_num('<h', val)
  1061. def write_uint16(self, val): return self._write_num('<H', val)
  1062. def write_int32(self, val): return self._write_num('<i', val)
  1063. def write_uint32(self, val): return self._write_num('<I', val)
  1064. def write_int64(self, val): return self._write_num('<q', val)
  1065. def write_uint64(self, val): return self._write_num('<Q', val)
  1066. def read_compact_size(self):
  1067. size = ord(self.input[self.read_cursor])
  1068. self.read_cursor += 1
  1069. if size == 253:
  1070. size = self._read_num('<H')
  1071. elif size == 254:
  1072. size = self._read_num('<I')
  1073. elif size == 255:
  1074. size = self._read_num('<Q')
  1075. return size
  1076. def write_compact_size(self, size):
  1077. if size < 0:
  1078. raise SerializationError("attempt to write size < 0")
  1079. elif size < 253:
  1080. self.write(chr(size))
  1081. elif size < 2**16:
  1082. self.write('\xfd')
  1083. self._write_num('<H', size)
  1084. elif size < 2**32:
  1085. self.write('\xfe')
  1086. self._write_num('<I', size)
  1087. elif size < 2**64:
  1088. self.write('\xff')
  1089. self._write_num('<Q', size)
  1090. def _read_num(self, format):
  1091. (i,) = struct.unpack_from(format, self.input, self.read_cursor)
  1092. self.read_cursor += struct.calcsize(format)
  1093. return i
  1094. def _write_num(self, format, num):
  1095. s = struct.pack(format, num)
  1096. self.write(s)
  1097. def open_wallet(db_env, db_file="wallet.dat", writable=False):
  1098. db = DB(db_env)
  1099. flags = DB_THREAD | (DB_CREATE if writable else DB_RDONLY)
  1100. try:
  1101. r = db.open(db_file, "main", DB_BTREE, flags)
  1102. except DBError:
  1103. r = True
  1104. if r is not None:
  1105. logging.error("Couldn't open " + db_file + "/main. Try quitting Bitcoin and running this again.")
  1106. sys.exit(1)
  1107. return db
  1108. def parse_wallet(db, item_callback):
  1109. kds = BCDataStream()
  1110. vds = BCDataStream()
  1111. for (key, value) in db.items():
  1112. d = { }
  1113. kds.clear(); kds.write(key)
  1114. vds.clear(); vds.write(value)
  1115. type = kds.read_string()
  1116. d["__key__"] = key
  1117. d["__value__"] = value
  1118. d["__type__"] = type
  1119. try:
  1120. if type == "tx":
  1121. d["tx_id"] = kds.read_bytes(32)
  1122. elif type == "name":
  1123. d['hash'] = kds.read_string()
  1124. d['name'] = vds.read_string()
  1125. elif type == "version":
  1126. d['version'] = vds.read_uint32()
  1127. elif type == "minversion":
  1128. d['minversion'] = vds.read_uint32()
  1129. elif type == "setting":
  1130. d['setting'] = kds.read_string()
  1131. d['value'] = parse_setting(d['setting'], vds)
  1132. elif type == "key":
  1133. d['public_key'] = kds.read_bytes(kds.read_compact_size())
  1134. d['private_key'] = vds.read_bytes(vds.read_compact_size())
  1135. elif type == "wkey":
  1136. d['public_key'] = kds.read_bytes(kds.read_compact_size())
  1137. d['private_key'] = vds.read_bytes(vds.read_compact_size())
  1138. d['created'] = vds.read_int64()
  1139. d['expires'] = vds.read_int64()
  1140. d['comment'] = vds.read_string()
  1141. elif type == "ckey":
  1142. d['public_key'] = kds.read_bytes(kds.read_compact_size())
  1143. d['crypted_key'] = vds.read_bytes(vds.read_compact_size())
  1144. elif type == "mkey":
  1145. d['nID'] = kds.read_int32()
  1146. d['crypted_key'] = vds.read_bytes(vds.read_compact_size())
  1147. d['salt'] = vds.read_bytes(vds.read_compact_size())
  1148. d['nDerivationMethod'] = vds.read_int32()
  1149. d['nDeriveIterations'] = vds.read_int32()
  1150. d['vchOtherDerivationParameters'] = vds.read_bytes(vds.read_compact_size())
  1151. elif type == "defaultkey":
  1152. d['key'] = vds.read_bytes(vds.read_compact_size())
  1153. elif type == "pool":
  1154. d['n'] = kds.read_int64()
  1155. d['nVersion'] = vds.read_int32()
  1156. d['nTime'] = vds.read_int64()
  1157. d['public_key'] = vds.read_bytes(vds.read_compact_size())
  1158. elif type == "acc":
  1159. d['account'] = kds.read_string()
  1160. d['nVersion'] = vds.read_int32()
  1161. d['public_key'] = vds.read_bytes(vds.read_compact_size())
  1162. elif type == "acentry":
  1163. d['account'] = kds.read_string()
  1164. d['n'] = kds.read_uint64()
  1165. d['nVersion'] = vds.read_int32()
  1166. d['nCreditDebit'] = vds.read_int64()
  1167. d['nTime'] = vds.read_int64()
  1168. d['otherAccount'] = vds.read_string()
  1169. d['comment'] = vds.read_string()
  1170. elif type == "bestblock":
  1171. d['nVersion'] = vds.read_int32()
  1172. d.update(parse_BlockLocator(vds))
  1173. item_callback(type, d)
  1174. except Exception, e:
  1175. traceback.print_exc()
  1176. print("ERROR parsing wallet.dat, type %s" % type)
  1177. print("key data in hex: %s"%key.encode('hex_codec'))
  1178. print("value data in hex: %s"%value.encode('hex_codec'))
  1179. sys.exit(1)
  1180. def update_wallet(db, type, data):
  1181. """Write a single item to the wallet.
  1182. db must be open with writable=True.
  1183. type and data are the type code and data dictionary as parse_wallet would
  1184. give to item_callback.
  1185. data's __key__, __value__ and __type__ are ignored; only the primary data
  1186. fields are used.
  1187. """
  1188. d = data
  1189. kds = BCDataStream()
  1190. vds = BCDataStream()
  1191. # Write the type code to the key
  1192. kds.write_string(type)
  1193. vds.write("") # Ensure there is something
  1194. try:
  1195. if type == "tx":
  1196. raise NotImplementedError("Writing items of type 'tx'")
  1197. kds.write(d['tx_id'])
  1198. elif type == "name":
  1199. kds.write_string(d['hash'])
  1200. vds.write_string(d['name'])
  1201. elif type == "version":
  1202. vds.write_uint32(d['version'])
  1203. elif type == "minversion":
  1204. vds.write_uint32(d['minversion'])
  1205. elif type == "setting":
  1206. raise NotImplementedError("Writing items of type 'setting'")
  1207. kds.write_string(d['setting'])
  1208. #d['value'] = parse_setting(d['setting'], vds)
  1209. elif type == "key":
  1210. kds.write_string(d['public_key'])
  1211. vds.write_string(d['private_key'])
  1212. elif type == "wkey":
  1213. kds.write_string(d['public_key'])
  1214. vds.write_string(d['private_key'])
  1215. vds.write_int64(d['created'])
  1216. vds.write_int64(d['expires'])
  1217. vds.write_string(d['comment'])
  1218. elif type == "ckey":
  1219. kds.write_string(d['public_key'])
  1220. vds.write_string(d['crypted_key'])
  1221. elif type == "defaultkey":
  1222. vds.write_string(d['key'])
  1223. elif type == "pool":
  1224. kds.write_int64(d['n'])
  1225. vds.write_int32(d['nVersion'])
  1226. vds.write_int64(d['nTime'])
  1227. vds.write_string(d['public_key'])
  1228. elif type == "acc":
  1229. kds.write_string(d['account'])
  1230. vds.write_int32(d['nVersion'])
  1231. vds.write_string(d['public_key'])
  1232. elif type == "acentry":
  1233. kds.write_string(d['account'])
  1234. kds.write_uint64(d['n'])
  1235. vds.write_int32(d['nVersion'])
  1236. vds.write_int64(d['nCreditDebit'])
  1237. vds.write_int64(d['nTime'])
  1238. vds.write_string(d['otherAccount'])
  1239. vds.write_string(d['comment'])
  1240. elif type == "bestblock":
  1241. vds.write_int32(d['nVersion'])
  1242. vds.write_compact_size(len(d['hashes']))
  1243. for h in d['hashes']:
  1244. vds.write(h)
  1245. else:
  1246. print "Unknown key type: "+type
  1247. # Write the key/value pair to the database
  1248. db.put(kds.input, vds.input)
  1249. except Exception, e:
  1250. print("ERROR writing to wallet.dat, type %s"%type)
  1251. print("data dictionary: %r"%data)
  1252. traceback.print_exc()
  1253. # def rewrite_wallet(db_env, destFileName, pre_put_callback=None):
  1254. # db = open_wallet(db_env)
  1255. #
  1256. # db_out = DB(db_env)
  1257. # try:
  1258. # r = db_out.open(destFileName, "main", DB_BTREE, DB_CREATE)
  1259. # except DBError:
  1260. # r = True
  1261. #
  1262. # if r is not None:
  1263. # logging.error("Couldn't open %s."%destFileName)
  1264. # sys.exit(1)
  1265. #
  1266. # def item_callback(type, d):
  1267. # if (pre_put_callback is None or pre_put_callback(type, d)):
  1268. # db_out.put(d["__key__"], d["__value__"])
  1269. #
  1270. # parse_wallet(db, item_callback)
  1271. # db_out.close()
  1272. # db.close()
  1273. #
  1274. # end of bitcointools wallet.dat handling code
  1275. # wallet.dat reader / writer
  1276. def read_wallet(json_db, db_env, db_file, print_wallet, print_wallet_transactions, transaction_filter):
  1277. global password
  1278. db = open_wallet(db_env, db_file)
  1279. json_db['keys'] = []
  1280. json_db['pool'] = []
  1281. json_db['names'] = {}
  1282. def item_callback(type, d):
  1283. if type == "name":
  1284. json_db['names'][d['hash']] = d['name']
  1285. elif type == "version":
  1286. json_db['version'] = d['version']
  1287. elif type == "minversion":
  1288. json_db['minversion'] = d['minversion']
  1289. elif type == "setting":
  1290. if not json_db.has_key('settings'): json_db['settings'] = {}
  1291. json_db["settings"][d['setting']] = d['value']
  1292. elif type == "defaultkey":
  1293. json_db['defaultkey'] = public_key_to_bc_address(d['key'])
  1294. elif type == "key":
  1295. addr = public_key_to_bc_address(d['public_key'])
  1296. compressed = d['public_key'][0] != '\04'
  1297. sec = SecretToASecret(PrivKeyToSecret(d['private_key']), compressed)
  1298. private_keys.append(sec)
  1299. json_db['keys'].append({'addr' : addr, 'sec' : sec})
  1300. # json_db['keys'].append({'addr' : addr, 'sec' : sec,
  1301. # 'secret':PrivKeyToSecret(d['private_key']).encode('hex'),
  1302. # 'pubkey':d['public_key'].encode('hex'),
  1303. # 'privkey':d['private_key'].encode('hex')})
  1304. elif type == "wkey":
  1305. if not json_db.has_key('wkey'): json_db['wkey'] = []
  1306. json_db['wkey']['created'] = d['created']
  1307. elif type == "ckey":
  1308. addr = public_key_to_bc_address(d['public_key'])
  1309. ckey = d['crypted_key']
  1310. pubkey = d['public_key']
  1311. json_db['keys'].append( {'addr' : addr, 'ckey': ckey.encode('hex'), 'pubkey': pubkey.encode('hex') })
  1312. elif type == "mkey":
  1313. mkey = {}
  1314. mkey['nID'] = d['nID']
  1315. mkey['crypted_key'] = d['crypted_key'].encode('hex')
  1316. mkey['salt'] = d['salt'].encode('hex')
  1317. mkey['nDeriveIterations'] = d['nDeriveIterations']
  1318. mkey['nDerivationMethod'] = d['nDerivationMethod']
  1319. mkey['vchOtherDerivationParameters'] = d['vchOtherDerivationParameters'].encode('hex')
  1320. json_db['mkey'] = mkey
  1321. if password:
  1322. global crypter
  1323. if crypter == 'pycrypto':
  1324. crypter = Crypter_pycrypto()
  1325. elif crypter == 'ssl':
  1326. crypter = Crypter_ssl()
  1327. else:
  1328. crypter = Crypter_pure()
  1329. logging.warning("pycrypto or libssl not found, decryption may be slow")
  1330. res = crypter.SetKeyFromPassphrase(password, d['salt'], d['nDeriveIterations'], d['nDerivationMethod'])
  1331. if res == 0:
  1332. logging.error("Unsupported derivation method")
  1333. sys.exit(1)
  1334. masterkey = crypter.Decrypt(d['crypted_key'])
  1335. crypter.SetKey(masterkey)
  1336. elif type == "pool":
  1337. json_db['pool'].append( {'n': d['n'], 'addr': public_key_to_bc_address(d['public_key']), 'nTime' : d['nTime'] } )
  1338. elif type == "acc":
  1339. json_db['acc'] = d['account']
  1340. msg("Account %s (current key: %s)"%(d['account'], public_key_to_bc_address(d['public_key'])))
  1341. elif type == "acentry":
  1342. json_db['acentry'] = (d['account'], d['nCreditDebit'], d['otherAccount'], time.ctime(d['nTime']), d['n'], d['comment'])
  1343. elif type == "bestblock":
  1344. json_db['bestblock'] = d['hashes'][0][::-1].encode('hex_codec')
  1345. else:
  1346. json_db[type] = 'unsupported'
  1347. parse_wallet(db, item_callback)
  1348. db.close()
  1349. for k in json_db['keys']:
  1350. addr = k['addr']
  1351. if addr in json_db['names'].keys():
  1352. k["label"] = json_db['names'][addr]
  1353. else:
  1354. k["reserve"] = 1
  1355. crypted = 'mkey' in json_db.keys()
  1356. if (crypted and not password) and \
  1357. (options.dump or options.keysforaddrs or options.privkeys):
  1358. print("Encrypted wallet. Specify '--password' to decrypt")
  1359. sys.exit(1)
  1360. if crypted and password:
  1361. check = True
  1362. for k in json_db['keys']:
  1363. ckey = k['ckey'].decode('hex')
  1364. public_key = k['pubkey'].decode('hex')
  1365. crypter.SetIV(Hash(public_key))
  1366. secret = crypter.Decrypt(ckey)
  1367. compressed = public_key[0] != '\04'
  1368. if check:
  1369. check = False
  1370. pkey = EC_KEY(int('0x' + secret.encode('hex'), 16))
  1371. if public_key != GetPubKey(pkey, compressed):
  1372. logging.error("wrong password")
  1373. sys.exit(1)
  1374. sec = SecretToASecret(secret, compressed)
  1375. k['sec'] = sec
  1376. k['secret'] = secret.encode('hex')
  1377. del(k['ckey'])
  1378. del(k['secret'])
  1379. del(k['pubkey'])
  1380. private_keys.append(sec)
  1381. del(json_db['pool'])
  1382. del(json_db['names'])
  1383. def importprivkey(db, sec):
  1384. pkey = regenerate_key(sec)
  1385. if not pkey:
  1386. return False
  1387. compressed = is_compressed(sec)
  1388. secret = GetSecret(pkey)
  1389. private_key = GetPrivKey(pkey, compressed)
  1390. public_key = GetPubKey(pkey, compressed)
  1391. addr = public_key_to_bc_address(public_key)
  1392. print "Address: %s" % addr
  1393. print "Privkey: %s" % SecretToASecret(secret, compressed)
  1394. global crypter, password, json_db
  1395. crypted = 'mkey' in json_db.keys()
  1396. if crypted:
  1397. if password:
  1398. crypter.SetIV(Hash(public_key))
  1399. crypted_key = crypter.Encrypt(secret)
  1400. update_wallet(db, 'ckey', { 'public_key' : public_key, 'crypted_key' : crypted_key })
  1401. update_wallet(db, 'name', { 'hash' : addr, 'name' : '' })
  1402. return True
  1403. else:
  1404. logging.error("password not specified")
  1405. sys.exit(1)
  1406. else:
  1407. update_wallet(db, 'key', { 'public_key' : public_key, 'private_key' : private_key })
  1408. update_wallet(db, 'name', { 'hash' : addr, 'name' : '' })
  1409. return True
  1410. return False
  1411. def parse_wallet_file_arg(path):
  1412. import os
  1413. try:
  1414. os.stat(path)
  1415. except:
  1416. print "File '%s' does not exist" % path
  1417. sys.exit(1)
  1418. s = path.rfind("/")
  1419. if path[0] == '/':
  1420. if s == 0:
  1421. return "/", path
  1422. else:
  1423. return path[0:s], path[s+1:]
  1424. else:
  1425. curdir = os.path.abspath(".")
  1426. if s == -1:
  1427. return curdir,path
  1428. else:
  1429. return curdir + "/" + path[0:s], path[s+1:]
  1430. from optparse import OptionParser
  1431. def main():
  1432. global max_version, addrtype
  1433. parser = OptionParser(usage="%prog [options] walletfile", version="%prog 1.2")
  1434. parser.add_option("--dumpwallet", dest="dump", action="store_true",
  1435. help="dump wallet in json format")
  1436. parser.add_option("--privkeys", dest="privkeys", action="store_true",
  1437. help="dump all private keys in wallet (flat list)")
  1438. parser.add_option("--addrs", dest="addrs", action="store_true",
  1439. help="dump all addresses in wallet (flat list)")
  1440. parser.add_option("--keysforaddrs", dest="keysforaddrs",
  1441. help="dump all private keys corresponding to addresses in file KEYSFORADDRS (flat list)")
  1442. parser.add_option("--importprivkey", dest="key",
  1443. help="import private key from vanitygen")
  1444. parser.add_option("--testnet", dest="testnet", action="store_true",
  1445. help="use testnet subdirectory and address type")
  1446. parser.add_option("--password", dest="password", action="store_true",
  1447. help="prompt for password for the encrypted wallet")
  1448. global options
  1449. (options, args) = parser.parse_args()
  1450. if options.dump is None and options.key is None \
  1451. and options.keysforaddrs is None \
  1452. and options.addrs is None and options.privkeys is None:
  1453. print "A mandatory option is missing\n"
  1454. parser.print_help()
  1455. sys.exit(1)
  1456. db_dir,db_file = parse_wallet_file_arg(args[0])
  1457. # print "[%s] [%s]" % (db_dir,db_file)
  1458. # sys.exit()
  1459. if options.testnet: addrtype = 111
  1460. db_env = create_env(db_dir)
  1461. global password
  1462. if options.password:
  1463. from mmgen.utils import my_getpass
  1464. password = my_getpass("Enter password: ")
  1465. read_wallet(json_db, db_env, db_file, True, True, "")
  1466. if json_db.get('minversion') > max_version:
  1467. print "Version mismatch (must be <= %d)" % max_version
  1468. exit(1)
  1469. if options.dump:
  1470. print json.dumps(json_db, sort_keys=True, indent=4)
  1471. elif options.privkeys:
  1472. for i in json_db['keys']:
  1473. print i['sec']
  1474. elif options.addrs:
  1475. for i in json_db['keys']:
  1476. print i['addr']
  1477. elif options.keysforaddrs:
  1478. from mmgen.utils import get_lines_from_file
  1479. addrs = get_lines_from_file(options.keysforaddrs,"addresses")
  1480. for i in json_db['keys']:
  1481. if i['addr'] in addrs:
  1482. print i['sec']
  1483. elif options.key:
  1484. if options.key in private_keys:
  1485. print "Already exists"
  1486. else:
  1487. db = open_wallet(db_env, db_file, writable=True)
  1488. if importprivkey(db, options.key):
  1489. print "Imported successfully"
  1490. else:
  1491. print "Bad private key"
  1492. db.close()
  1493. if __name__ == '__main__':
  1494. main()