gentest.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env python
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2016 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. test/gentest.py: Bitcoin key/address generation tests for the MMGen suite
  20. """
  21. import sys,os
  22. pn = os.path.dirname(sys.argv[0])
  23. os.chdir(os.path.join(pn,os.pardir))
  24. sys.path.__setitem__(0,os.path.abspath(os.curdir))
  25. from binascii import hexlify
  26. # Import these _after_ local path's been added to sys.path
  27. from mmgen.common import *
  28. from mmgen.bitcoin import hextowif,privnum2addr
  29. start_mscolor()
  30. rounds = 100
  31. opts_data = {
  32. 'desc': "Test addresses generated by {} against output of 'keyconv'".format(g.proj_name),
  33. 'usage':'[options] [rounds]',
  34. 'options': """
  35. -h, --help Print this help message
  36. -s, --system Test scripts and modules installed on system rather than
  37. those in the repo root
  38. -v, --verbose Produce more verbose output
  39. """,
  40. 'notes': """
  41. 'keyconv' is the address generation utility from the well-known vanitygen
  42. package. If it's installed on your system, {pnm} will use it by default to
  43. generate Bitcoin addresses. Otherwise, it falls back on its own internal
  44. routines, which use the Python ecdsa library.
  45. rounds is {} by default.
  46. """.format(rounds,pnm=g.proj_name)
  47. }
  48. cmd_args = opts.init(opts_data,add_opts=['exact_output'])
  49. if len(cmd_args) == 1:
  50. try:
  51. rounds = int(cmd_args[0])
  52. assert rounds > 0
  53. except:
  54. die(1,"'rounds' must be a positive integer")
  55. elif len(cmd_args) > 1:
  56. opts.usage(opts_data)
  57. if opt.system: sys.path.pop(0)
  58. from mmgen.addr import test_for_keyconv
  59. if not test_for_keyconv(silent=True):
  60. die(1,"To run this test, you must install 'keyconv' from the vanitygen package.")
  61. m = "Comparing {}'s internally generated addresses against output of 'keyconv'"
  62. msg(green(m.format(g.proj_name)))
  63. from subprocess import check_output
  64. for i in range(1,rounds+1):
  65. msg_r('\rRound %s/%s ' % (i,rounds))
  66. sec = hexlify(os.urandom(32))
  67. wif = hextowif(sec)
  68. a = privnum2addr(int(sec,16))
  69. vmsg('\nkey: %s\naddr: %s\n' % (wif,a))
  70. b = check_output(['keyconv', wif]).split()[1]
  71. if a != b:
  72. msg_r(red('\nERROR: Addresses do not match!'))
  73. die(3,"""
  74. sec key: {}
  75. WIF key: {}
  76. {pnm}: {}
  77. keyconv: {}
  78. """.format(sec,wif,a,b,pnm=g.proj_name).rstrip())
  79. msg(green(('\n','')[bool(opt.verbose)] + 'OK'))