protocol.py: check that private key is within allowable range
- if pk == 0 or pk == secp256k1_ge: FAIL - if pk > secp256k1_ge: pk = pk % secp256k1_ge
This commit is contained in:
parent
610d0dd243
commit
0d77a78a4c
2 changed files with 24 additions and 7 deletions
10
mmgen/obj.py
10
mmgen/obj.py
|
|
@ -657,12 +657,14 @@ class PrivKey(str,Hilite,InitErrors,MMGenObject):
|
|||
try:
|
||||
assert s and type(compressed) == bool and pubkey_type,'Incorrect args for PrivKey()'
|
||||
assert len(s) == cls.width / 2,'Key length must be {}'.format(cls.width/2)
|
||||
me = str.__new__(cls,g.proto.preprocess_key(s.encode('hex'),pubkey_type))
|
||||
me.orig_hex = s.encode('hex') # save the non-preprocessed key
|
||||
if pubkey_type == 'password': # skip WIF creation and pre-processing for passwds
|
||||
me = str.__new__(cls,s.encode('hex'))
|
||||
else:
|
||||
me = str.__new__(cls,g.proto.preprocess_key(s.encode('hex'),pubkey_type))
|
||||
me.wif = WifKey(g.proto.hex2wif(me,pubkey_type,compressed),on_fail='raise')
|
||||
me.compressed = compressed
|
||||
me.pubkey_type = pubkey_type
|
||||
if pubkey_type != 'password': # skip WIF creation for passwds
|
||||
me.wif = WifKey(g.proto.hex2wif(me,pubkey_type,compressed),on_fail='raise')
|
||||
me.orig_hex = s.encode('hex') # save the non-preprocessed key
|
||||
return me
|
||||
except Exception as e:
|
||||
fs = "Key={!r}\nCompressed={}\nValue pair cannot be converted to PrivKey\n({})"
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ protocol.py: Coin protocol functions, classes and methods
|
|||
|
||||
import sys,os,hashlib
|
||||
from binascii import unhexlify
|
||||
from mmgen.util import msg,pmsg,Msg,pdie
|
||||
from mmgen.util import msg,pmsg,ymsg,Msg,pdie,ydie
|
||||
from mmgen.obj import MMGenObject,BTCAmt,LTCAmt,BCHAmt,B2XAmt,ETHAmt
|
||||
from mmgen.globalvars import g
|
||||
import mmgen.bech32 as bech32
|
||||
|
|
@ -93,6 +93,7 @@ class BitcoinProtocol(MMGenObject):
|
|||
witness_vernum = int(witness_vernum_hex,16)
|
||||
bech32_hrp = 'bc'
|
||||
sign_mode = 'daemon'
|
||||
secp256k1_ge = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
|
||||
|
||||
@classmethod
|
||||
def is_testnet(cls):
|
||||
|
|
@ -110,7 +111,19 @@ class BitcoinProtocol(MMGenObject):
|
|||
def cap(cls,s): return s in cls.caps
|
||||
|
||||
@classmethod
|
||||
def preprocess_key(cls,hexpriv,pubkey_type): return hexpriv
|
||||
def preprocess_key(cls,hexpriv,pubkey_type):
|
||||
# Key must be non-zero and less than group order of secp256k1 curve
|
||||
if 0 < int(hexpriv,16) < cls.secp256k1_ge:
|
||||
return hexpriv
|
||||
else: # chance of this is less than 1 in 2^127
|
||||
pk = int(hexpriv,16)
|
||||
if pk == 0: # chance of this is 1 in 2^256
|
||||
ydie(3,'Private key is zero!')
|
||||
elif pk == cls.secp256k1_ge: # ditto
|
||||
ydie(3,'Private key == secp256k1_ge!')
|
||||
else:
|
||||
ymsg('Warning: private key is greater than secp256k1 group order!:\n {}'.format(hexpriv))
|
||||
return '{:064x}'.format(pk % cls.secp256k1_ge)
|
||||
|
||||
@classmethod
|
||||
def hex2wif(cls,hexpriv,pubkey_type,compressed):
|
||||
|
|
@ -131,6 +144,8 @@ class BitcoinProtocol(MMGenObject):
|
|||
else:
|
||||
assert len(key) == 64,'invalid key length'
|
||||
compressed = False
|
||||
assert 0 < int(key[:64],16) < cls.secp256k1_ge,(
|
||||
"'{}': invalid WIF (produces key outside allowable range)".format(wif))
|
||||
return { 'hex':key[:64], 'pubkey_type':pubkey_type, 'compressed':compressed }
|
||||
|
||||
@classmethod
|
||||
|
|
@ -292,7 +307,7 @@ class DummyWIF(object):
|
|||
def wif2hex(cls,wif):
|
||||
return { 'hex':str(wif), 'pubkey_type':cls.pubkey_type, 'compressed':False }
|
||||
|
||||
class EthereumProtocol(DummyWIF,BitcoinProtocolAddrgen):
|
||||
class EthereumProtocol(DummyWIF,BitcoinProtocol):
|
||||
|
||||
addr_width = 40
|
||||
mmtypes = ('E',)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue