gentest.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  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 hex2wif,privnum2addr
  29. start_mscolor()
  30. rounds = 100
  31. opts_data = {
  32. 'desc': "Test address generation using various methods",
  33. 'usage':'[options] a:b [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. {pnm} can generate addresses from secret keys using one of three methods,
  42. as specified by the user:
  43. 1) with the native Python ecdsa library (very slow)
  44. 2) with the 'keyconv' utility from the 'vanitygen' package (old default)
  45. 3) using bitcoincore.org's secp256k1 library (default from v0.8.6)
  46. This test suite compares the output of these different methods against each
  47. other over set of randomly generated secret keys ({snum} by default).
  48. EXAMPLE:
  49. gentest.py 2:3 1000
  50. (compare output of 'keyconv' with secp256k1 library, 1000 rounds)
  51. """.format(pnm=g.proj_name,snum=rounds)
  52. }
  53. cmd_args = opts.init(opts_data,add_opts=['exact_output'])
  54. if not 1 <= len(cmd_args) <= 2: opts.usage()
  55. if len(cmd_args) == 2:
  56. try:
  57. rounds = int(cmd_args[1])
  58. assert rounds > 0
  59. except:
  60. die(1,"'rounds' must be a positive integer")
  61. try:
  62. a,b = cmd_args[0].split(':')
  63. a,b = int(a),int(b)
  64. for i in a,b: assert 1 <= i <= len(g.key_generators)
  65. assert a != b
  66. except:
  67. die(1,"%s: incorrect 'a:b' specifier" % cmd_args[0])
  68. if opt.system: sys.path.pop(0)
  69. m = "Comparing address generators '{}' and '{}'"
  70. msg(green(m.format(g.key_generators[a-1],g.key_generators[b-1])))
  71. from mmgen.addr import get_privhex2addr_f
  72. gen_a = get_privhex2addr_f(selector=a)
  73. gen_b = get_privhex2addr_f(selector=b)
  74. compressed = False
  75. for i in range(1,rounds+1):
  76. msg_r('\rRound %s/%s ' % (i,rounds))
  77. sec = hexlify(os.urandom(32))
  78. wif = hex2wif(sec,compressed=compressed)
  79. a_addr = gen_a(sec,compressed)
  80. b_addr = gen_b(sec,compressed)
  81. vmsg('\nkey: %s\naddr: %s\n' % (wif,a_addr))
  82. if a_addr != b_addr:
  83. msg_r(red('\nERROR: Addresses do not match!'))
  84. die(3,"""
  85. sec key: {}
  86. WIF key: {}
  87. {pnm}: {}
  88. keyconv: {}
  89. """.format(sec,wif,a_addr,b_addr,pnm=g.proj_name).rstrip())
  90. if a != 2 and b != 2:
  91. compressed = not compressed
  92. msg(green(('\n','')[bool(opt.verbose)] + 'OK'))