main_pywallet.py 51 KB

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