Advertisement
joric

Importing private keys into wallet.dat (pywallet.py 1.1)

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