py3port: Zcash and Monero-related changes
This commit is contained in:
parent
66c01a9ed8
commit
53189f4469
12 changed files with 118 additions and 36 deletions
|
|
@ -99,11 +99,11 @@ class AddrGeneratorZcashZ(AddrGenerator):
|
|||
vk_width = 97
|
||||
|
||||
def zhash256(self,s,t):
|
||||
s = list(map(ord,s+'\0'*32))
|
||||
s = bytearray(s + bytes(32))
|
||||
s[0] |= 0xc0
|
||||
s[32] = t
|
||||
from mmgen.sha256 import Sha256
|
||||
return Sha256(list(map(chr,s)),preprocess=False).digest()
|
||||
return Sha256(s,preprocess=False).digest()
|
||||
|
||||
def to_addr(self,pubhex): # pubhex is really privhex
|
||||
key = unhexlify(pubhex)
|
||||
|
|
@ -120,12 +120,12 @@ class AddrGeneratorZcashZ(AddrGenerator):
|
|||
def to_viewkey(self,pubhex): # pubhex is really privhex
|
||||
key = unhexlify(pubhex)
|
||||
assert len(key) == 32,'{}: incorrect privkey length'.format(len(key))
|
||||
vk = list(map(ord,self.zhash256(key,0)+self.zhash256(key,1)))
|
||||
vk = bytearray(self.zhash256(key,0)+self.zhash256(key,1))
|
||||
vk[32] &= 0xf8
|
||||
vk[63] &= 0x7f
|
||||
vk[63] |= 0x40
|
||||
from mmgen.protocol import _b58chk_encode
|
||||
ret = _b58chk_encode(g.proto.addr_ver_num['viewkey'][0] + hexlify(''.join(map(chr,vk))))
|
||||
ret = _b58chk_encode(g.proto.addr_ver_num['viewkey'][0] + hexlify(vk))
|
||||
assert len(ret) == self.vk_width,'Invalid Zcash view key length'
|
||||
return ZcashViewKey(ret)
|
||||
|
||||
|
|
@ -142,13 +142,11 @@ class AddrGeneratorMonero(AddrGenerator):
|
|||
|
||||
def to_addr(self,sk_hex): # sk_hex instead of pubhex
|
||||
|
||||
# ed25519ll, a low-level ctypes wrapper for Ed25519 digital signatures by
|
||||
# Daniel Holth <dholth@fastmail.fm> - http://bitbucket.org/dholth/ed25519ll/
|
||||
try:
|
||||
assert not opt.use_internal_ed25519_mod
|
||||
from ed25519ll.djbec import scalarmult,edwards,encodepoint,B
|
||||
except:
|
||||
from mmgen.ed25519 import scalarmult,edwards,encodepoint,B
|
||||
if opt.use_old_ed25519:
|
||||
from mmgen.ed25519 import edwards,encodepoint,B,scalarmult
|
||||
else:
|
||||
from mmgen.ed25519ll_djbec import scalarmult
|
||||
from mmgen.ed25519 import edwards,encodepoint,B
|
||||
|
||||
# Source and license for scalarmultbase function:
|
||||
# https://github.com/bigreddmachine/MoneroPy/blob/master/moneropy/crypto/ed25519.py
|
||||
|
|
|
|||
|
|
@ -2,15 +2,10 @@
|
|||
# Source: https://ed25519.cr.yp.to/python/ed25519.py
|
||||
# Date accessed: 2 Nov. 2016
|
||||
|
||||
import hashlib
|
||||
|
||||
b = 256
|
||||
q = 2**255 - 19
|
||||
l = 2**252 + 27742317777372353535851937790883648493
|
||||
|
||||
def H(m):
|
||||
return hashlib.sha512(m).digest()
|
||||
|
||||
def expmod(b, e, m):
|
||||
if e == 0: return 1
|
||||
t = expmod(b, e//2, m)**2 % m
|
||||
|
|
@ -54,4 +49,4 @@ def encodepoint(P):
|
|||
x = P[0]
|
||||
y = P[1]
|
||||
bits = [(y >> i) & 1 for i in range(b-1)] + [x & 1]
|
||||
return b''.join([chr(sum([bits[i * 8 + j] << j for j in range(8)])) for i in range(b//8)])
|
||||
return bytes([sum([bits[i * 8 + j] << j for j in range(8)]) for i in range(b//8)])
|
||||
|
|
|
|||
85
mmgen/ed25519ll_djbec.py
Normal file
85
mmgen/ed25519ll_djbec.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
# Ported to Python 3 (added floor division) from ed25519ll package:
|
||||
# https://pypi.org/project/ed25519ll/
|
||||
# This module is adapted from that package's pure-Python fallback
|
||||
# implementation. All functions and vars not required by MMGen have
|
||||
# been removed.
|
||||
#
|
||||
# ed25519ll, a low-level ctypes wrapper for Ed25519 digital signatures by
|
||||
# Daniel Holth <dholth@fastmail.fm> - http://bitbucket.org/dholth/ed25519ll/
|
||||
# This wrapper also contains a reasonably performant pure-Python fallback.
|
||||
# Unlike the reference implementation, the Python implementation does not
|
||||
# contain protection against timing attacks.
|
||||
#
|
||||
# Ed25519 digital signatures
|
||||
# Based on http://ed25519.cr.yp.to/python/ed25519.py
|
||||
# See also http://ed25519.cr.yp.to/software.html
|
||||
# Adapted by Ron Garret
|
||||
# Sped up considerably using coordinate transforms found on:
|
||||
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
# Specifically add-2008-hwcd-4 and dbl-2008-hwcd
|
||||
|
||||
q = 2**255 - 19
|
||||
|
||||
def expmod(b,e,m):
|
||||
if e == 0: return 1
|
||||
t = expmod(b,e//2,m)**2 % m
|
||||
if e & 1: t = (t*b) % m
|
||||
return t
|
||||
|
||||
# Can probably get some extra speedup here by replacing this with
|
||||
# an extended-euclidean, but performance seems OK without that
|
||||
def inv(x):
|
||||
return expmod(x,q-2,q)
|
||||
|
||||
# Faster (!) version based on:
|
||||
# http://www.hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html
|
||||
|
||||
def xpt_add(pt1, pt2):
|
||||
(X1, Y1, Z1, T1) = pt1
|
||||
(X2, Y2, Z2, T2) = pt2
|
||||
A = ((Y1-X1)*(Y2+X2)) % q
|
||||
B = ((Y1+X1)*(Y2-X2)) % q
|
||||
C = (Z1*2*T2) % q
|
||||
D = (T1*2*Z2) % q
|
||||
E = (D+C) % q
|
||||
F = (B-A) % q
|
||||
G = (B+A) % q
|
||||
H = (D-C) % q
|
||||
X3 = (E*F) % q
|
||||
Y3 = (G*H) % q
|
||||
Z3 = (F*G) % q
|
||||
T3 = (E*H) % q
|
||||
return (X3, Y3, Z3, T3)
|
||||
|
||||
def xpt_double (pt):
|
||||
(X1, Y1, Z1, _) = pt
|
||||
A = (X1*X1)
|
||||
B = (Y1*Y1)
|
||||
C = (2*Z1*Z1)
|
||||
D = (-A) % q
|
||||
J = (X1+Y1) % q
|
||||
E = (J*J-A-B) % q
|
||||
G = (D+B) % q
|
||||
F = (G-C) % q
|
||||
H = (D-B) % q
|
||||
X3 = (E*F) % q
|
||||
Y3 = (G*H) % q
|
||||
Z3 = (F*G) % q
|
||||
T3 = (E*H) % q
|
||||
return (X3, Y3, Z3, T3)
|
||||
|
||||
def pt_xform (pt):
|
||||
(x, y) = pt
|
||||
return (x, y, 1, (x*y)%q)
|
||||
|
||||
def pt_unxform (pt):
|
||||
(x, y, z, _) = pt
|
||||
return ((x*inv(z))%q, (y*inv(z))%q)
|
||||
|
||||
def xpt_mult (pt, n):
|
||||
if n==0: return pt_xform((0,1))
|
||||
_ = xpt_double(xpt_mult(pt, n>>1))
|
||||
return xpt_add(_, pt) if n&1 else _
|
||||
|
||||
def scalarmult(pt, e):
|
||||
return pt_unxform(xpt_mult(pt_xform(pt), e))
|
||||
|
|
@ -53,8 +53,8 @@ opts_data = lambda: {
|
|||
-c, --print-checksum Print address list checksum and exit
|
||||
-d, --outdir= d Output files to directory 'd' instead of working dir
|
||||
-e, --echo-passphrase Echo passphrase or mnemonic to screen upon entry
|
||||
-E, --use-internal-ed25519-mod Use (slow) internal ed25519 module for Monero
|
||||
address generation, even if ed25519ll is installed
|
||||
-E, --use-old-ed25519 Use original (and slow) ed25519 module for Monero
|
||||
address generation instead of ed25519ll_djbec
|
||||
-i, --in-fmt= f Input is from wallet format 'f' (see FMT CODES below)
|
||||
-H, --hidden-incog-input-params=f,o Read hidden incognito data from file
|
||||
'f' at offset 'o' (comma-separated)
|
||||
|
|
@ -123,8 +123,8 @@ addr_type = MAT(opt.type or g.proto.dfl_mmtype,errmsg=errmsg)
|
|||
|
||||
if len(cmd_args) < 1: opts.usage()
|
||||
|
||||
if opt.use_internal_ed25519_mod:
|
||||
msg('Using (slow) internal ed25519 module by user request')
|
||||
if opt.use_old_ed25519:
|
||||
msg('Using old (slow) ed25519 module by user request')
|
||||
|
||||
idxs = AddrIdxList(fmt_str=cmd_args.pop())
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ Type '{pn} help <command> for help on a particular command
|
|||
)
|
||||
}
|
||||
|
||||
cmd_args = opts.init(opts_data,add_opts=['hidden_incog_input_params','in_fmt','use_internal_ed25519_mod'])
|
||||
cmd_args = opts.init(opts_data,add_opts=['hidden_incog_input_params','in_fmt','use_old_ed25519'])
|
||||
|
||||
if len(cmd_args) < 1: opts.usage()
|
||||
|
||||
|
|
|
|||
|
|
@ -397,6 +397,7 @@ class BTCAmt(Decimal,Hilite,InitErrors):
|
|||
class BCHAmt(BTCAmt): pass
|
||||
class B2XAmt(BTCAmt): pass
|
||||
class LTCAmt(BTCAmt): max_amt = 84000000
|
||||
class XMRAmt(BTCAmt): min_coin_unit = Decimal('0.000000000001')
|
||||
|
||||
from mmgen.altcoins.eth.obj import ETHAmt,ETHNonce
|
||||
|
||||
|
|
|
|||
|
|
@ -402,10 +402,7 @@ class MoneroProtocol(DummyWIF,BitcoinProtocolAddrgen):
|
|||
|
||||
@classmethod
|
||||
def preprocess_key(cls,hexpriv,pubkey_type): # reduce key
|
||||
try:
|
||||
from ed25519ll.djbec import l
|
||||
except:
|
||||
from mmgen.ed25519 import l
|
||||
from mmgen.ed25519 import l
|
||||
n = int(hexlify(unhexlify(hexpriv)[::-1]),16) % l
|
||||
return hexlify(unhexlify('{:064x}'.format(n))[::-1])
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ class Sha256(object):
|
|||
n,nPrime = 2,0
|
||||
while nPrime < 64:
|
||||
if isPrime(n):
|
||||
k[nPrime] = getFractionalBits(math.pow(n, 1.0 / 3))
|
||||
k[nPrime] = getFractionalBits(math.pow(n, 1 / 3))
|
||||
nPrime += 1
|
||||
n += 1
|
||||
|
||||
|
|
@ -73,21 +73,21 @@ class Sha256(object):
|
|||
return hexlify(self.digest())
|
||||
|
||||
def bytesToWords(self):
|
||||
assert type(self.M) in (str,list)
|
||||
assert type(self.M) in (bytes,bytearray,list)
|
||||
words = [0] * (len(self.M) // 4 + len(self.M) % 4)
|
||||
b = 0
|
||||
for i in range(len(self.M)):
|
||||
words[b >> 5] |= ord(self.M[i]) << (24 - b % 32)
|
||||
words[b >> 5] |= self.M[i] << (24 - b % 32)
|
||||
b += 8
|
||||
self.M = words
|
||||
|
||||
def wordsToBytes(self):
|
||||
assert type(self.M) == list and len(self.M) == 8
|
||||
self.M = ''.join([chr((self.M[b >> 5] >> (24 - b % 32)) & 0xff) for b in range(0,len(self.M)*32,8)])
|
||||
self.M = bytes([(self.M[b >> 5] >> (24 - b % 32) & 0xff) for b in range(0,len(self.M)*32,8)])
|
||||
|
||||
def preprocessBlock(self):
|
||||
def lshift(a,b): return (a << b) & 0xffffffff
|
||||
assert type(self.M) == str
|
||||
assert type(self.M) in (bytes,bytearray)
|
||||
l = len(self.M) * 8
|
||||
self.bytesToWords()
|
||||
last_idx = lshift((l + 64 >> 9),4) + 15
|
||||
|
|
|
|||
|
|
@ -624,14 +624,15 @@ def monero_wallet_ops(infile,op,blockheight=None,addrs=None):
|
|||
gmsg('\n{} wallet{} {}ed'.format(dl,suf(dl),m[op][0].lower()))
|
||||
if op == 'sync':
|
||||
col1_w = max(list(map(len,bals))) + 1
|
||||
fs = '{:%s} {:18} {:18}' % col1_w
|
||||
msg('\n'+fs.format('Wallet',' Balance',' Unlocked Balance'))
|
||||
fs = '{:%s} {} {}' % col1_w
|
||||
msg('\n'+fs.format('Wallet','Balance ','Unlocked Balance '))
|
||||
tbals = [Decimal('0'),Decimal('0')]
|
||||
from mmgen.obj import XMRAmt
|
||||
for bal in bals:
|
||||
for i in (0,1): tbals[i] += bals[bal][i]
|
||||
msg(fs.format(bal+':',*bals[bal]))
|
||||
msg(fs.format(bal+':',*[XMRAmt(b).fmt(fs='5.12',color=True) for b in bals[bal]]))
|
||||
msg(fs.format('-'*col1_w,'-'*18,'-'*18))
|
||||
msg(fs.format('TOTAL:',*tbals))
|
||||
msg(fs.format('TOTAL:',*[XMRAmt(b).fmt(fs='5.12',color=True) for b in tbals]))
|
||||
|
||||
os.environ['LANG'] = 'C'
|
||||
import pexpect
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ t_monero=(
|
|||
"mmgen-walletgen -q -r0 -p1 -Llabel --outdir $TMPDIR -o words"
|
||||
"$mmgen_keygen -q --accept-defaults --outdir $TMPDIR --coin=xmr $TMPDIR/*.mmwords $monero_addrs"
|
||||
'cs1=$(mmgen-tool -q --accept-defaults --coin=xmr keyaddrfile_chksum $TMPDIR/*-XMR*.akeys)'
|
||||
"$mmgen_keygen -q --use-internal-ed25519-mod --accept-defaults --outdir $TMPDIR --coin=xmr $TMPDIR/*.mmwords $monero_addrs"
|
||||
"$mmgen_keygen -q --use-old-ed25519 --accept-defaults --outdir $TMPDIR --coin=xmr $TMPDIR/*.mmwords $monero_addrs"
|
||||
'cs2=$(mmgen-tool -q --accept-defaults --coin=xmr keyaddrfile_chksum $TMPDIR/*-XMR*.akeys)'
|
||||
'[ "$cs1" == "$cs2" ] || false'
|
||||
"$mmgen_tool -q --accept-defaults --outdir $TMPDIR keyaddrlist2monerowallets $TMPDIR/*-XMR*.akeys addrs=23"
|
||||
|
|
|
|||
1
setup.py
1
setup.py
|
|
@ -115,6 +115,7 @@ setup(
|
|||
'mmgen.common',
|
||||
'mmgen.crypto',
|
||||
'mmgen.ed25519',
|
||||
'mmgen.ed25519ll_djbec',
|
||||
'mmgen.exception',
|
||||
'mmgen.filename',
|
||||
'mmgen.globalvars',
|
||||
|
|
|
|||
|
|
@ -1069,6 +1069,8 @@ cmd_group['ref_alt'] = (
|
|||
('ref_addrfile_gen_zec', 'generate address file (ZEC-T)'),
|
||||
('ref_addrfile_gen_zec_z','generate address file (ZEC-Z)'),
|
||||
('ref_addrfile_gen_xmr', 'generate address file (XMR)'),
|
||||
# we test the old ed25519 library in test-release.sh, so skip this
|
||||
# ('ref_addrfile_gen_xmr_old','generate address file (XMR - old (slow) ed25519 library)'),
|
||||
|
||||
('ref_keyaddrfile_gen_eth', 'generate key-address file (ETH)'),
|
||||
('ref_keyaddrfile_gen_etc', 'generate key-address file (ETC)'),
|
||||
|
|
@ -2609,6 +2611,8 @@ class MMGenTestSuite(object):
|
|||
def ref_addrfile_gen_xmr(self,name):
|
||||
self.ref_altcoin_addrgen(name,coin='XMR',mmtype='monero')
|
||||
|
||||
def ref_addrfile_gen_xmr_old(self,name):
|
||||
self.ref_altcoin_addrgen(name,coin='XMR',mmtype='monero',add_args=['--use-old-ed25519'])
|
||||
|
||||
def ref_keyaddrfile_gen_eth(self,name):
|
||||
self.ref_altcoin_addrgen(name,coin='ETH',mmtype='ethereum',gen_what='key')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue