some address generation work completed
This commit is contained in:
parent
f18eb5c91b
commit
f0666e6544
29
addresses.py
29
addresses.py
|
@ -95,6 +95,12 @@ def calculateInventoryHash(data):
|
|||
return sha2.digest()[0:32]
|
||||
|
||||
def encodeAddress(version,stream,ripe):
|
||||
if version >= 2:
|
||||
if ripe[:2] == '\x00\x00':
|
||||
ripe = ripe[2:]
|
||||
elif ripe[:1] == '\x00':
|
||||
ripe = ripe[1:]
|
||||
print 'within encodeAddress, length of ripe is:', len(ripe)
|
||||
a = encodeVarint(version) + encodeVarint(stream) + ripe
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(a)
|
||||
|
@ -162,15 +168,30 @@ def decodeAddress(address):
|
|||
#print 'addressVersionNumber', addressVersionNumber
|
||||
#print 'bytesUsedByVersionNumber', bytesUsedByVersionNumber
|
||||
|
||||
if addressVersionNumber != 1:
|
||||
print 'cannot decode version address version numbers this high'
|
||||
if addressVersionNumber > 2:
|
||||
print 'cannot decode address version numbers this high'
|
||||
status = 'versiontoohigh'
|
||||
return status,0,0,0
|
||||
elif addressVersionNumber == 0:
|
||||
print 'cannot decode address version numbers of zero.'
|
||||
status = 'versiontoohigh'
|
||||
return status,0,0,0
|
||||
|
||||
streamNumber, bytesUsedByStreamNumber = decodeVarint(data[bytesUsedByVersionNumber:10+bytesUsedByVersionNumber])
|
||||
streamNumber, bytesUsedByStreamNumber = decodeVarint(data[bytesUsedByVersionNumber:])
|
||||
#print streamNumber
|
||||
status = 'success'
|
||||
return status,addressVersionNumber,streamNumber,data[-24:-4]
|
||||
if addressVersionNumber == 1:
|
||||
return status,addressVersionNumber,streamNumber,data[-24:-4]
|
||||
elif addressVersionNumber == 2:
|
||||
if len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]) == 19:
|
||||
print 'within decode address, lenth I think is 19'
|
||||
return status,addressVersionNumber,streamNumber,'\x00'+data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]
|
||||
elif len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]) == 20:
|
||||
print 'within decode address, lenth I think is 20'
|
||||
return status,addressVersionNumber,streamNumber,data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]
|
||||
elif len(data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]) == 18:
|
||||
print 'within decode address, lenth I think is 18'
|
||||
return status,addressVersionNumber,streamNumber,'\x00\x00'+data[bytesUsedByVersionNumber+bytesUsedByStreamNumber:-4]
|
||||
|
||||
def addBMIfNotPresent(address):
|
||||
if address[:3] != 'BM-':
|
||||
|
|
|
@ -48,6 +48,11 @@ from time import strftime, localtime
|
|||
import os
|
||||
import string
|
||||
import socks
|
||||
import pyelliptic
|
||||
from pyelliptic import highlevelcrypto
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
import ctypes
|
||||
from pyelliptic import arithmetic
|
||||
|
||||
#For each stream to which we connect, one outgoingSynSender thread will exist and will create 8 connections with peers.
|
||||
class outgoingSynSender(QThread):
|
||||
|
@ -64,7 +69,7 @@ class outgoingSynSender(QThread):
|
|||
time.sleep(1)
|
||||
resetTime = int(time.time()) #used below to clear out the alreadyAttemptedConnectionsList periodically so that we will retry connecting to hosts to which we have already tried to connect.
|
||||
while True:
|
||||
#time.sleep(999999)#I'm using this to prevent connections for testing.
|
||||
time.sleep(999999)#I'm using this to prevent connections for testing.
|
||||
if len(self.selfInitiatedConnectionList) < 8: #maximum number of outgoing connections = 8
|
||||
random.seed()
|
||||
HOST, = random.sample(knownNodes[self.streamNumber], 1)
|
||||
|
@ -2084,43 +2089,151 @@ class addressGenerator(QThread):
|
|||
def __init__(self, parent = None):
|
||||
QThread.__init__(self, parent)
|
||||
|
||||
def setup(self,streamNumber,label):
|
||||
def setup(self,addressVersionNumber,streamNumber,label="(no label)",numberOfAddressesToMake=1,deterministicPassphrase="",eighteenByteRipe=False):
|
||||
self.addressVersionNumber = addressVersionNumber
|
||||
self.streamNumber = streamNumber
|
||||
self.label = label
|
||||
self.numberOfAddressesToMake = numberOfAddressesToMake
|
||||
self.deterministicPassphrase = deterministicPassphrase
|
||||
self.eighteenByteRipe = eighteenByteRipe
|
||||
|
||||
def run(self):
|
||||
statusbar = 'Generating new ' + str(config.getint('bitmessagesettings', 'bitstrength')) + ' bit RSA key. This takes a minute on average. If you want to generate multiple addresses now, you can; they will queue.'
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),statusbar)
|
||||
(pubkey, privkey) = rsa.newkeys(config.getint('bitmessagesettings', 'bitstrength'))
|
||||
print privkey['n']
|
||||
print privkey['e']
|
||||
print privkey['d']
|
||||
print privkey['p']
|
||||
print privkey['q']
|
||||
if self.addressVersionNumber == 2:
|
||||
|
||||
sha = hashlib.new('sha512')
|
||||
#sha.update(str(pubkey.n)+str(pubkey.e))
|
||||
sha.update(convertIntToString(pubkey.n)+convertIntToString(pubkey.e))
|
||||
ripe = hashlib.new('ripemd160')
|
||||
ripe.update(sha.digest())
|
||||
address = encodeAddress(1,self.streamNumber,ripe.digest())
|
||||
if self.deterministicPassphrase == "":
|
||||
statusbar = 'Generating one new address'
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),statusbar)
|
||||
#This next section is a little bit strange. We're going to generate keys over and over until we
|
||||
#find one that starts with either \x00 or \x00\x00. Then when we pack them into a Bitmessage address,
|
||||
#we won't store the \x00 or \x00\x00 bytes thus making the address shorter.
|
||||
while True:
|
||||
potentialPrivSigningKey = OpenSSL.rand(32)
|
||||
potentialPrivEncryptionKey = OpenSSL.rand(32)
|
||||
potentialPubSigningKey = self.pointMult(potentialPrivSigningKey)
|
||||
potentialPubEncryptionKey = self.pointMult(potentialPrivEncryptionKey)
|
||||
#print 'potentialPubSigningKey', potentialPubSigningKey.encode('hex')
|
||||
#print 'potentialPubEncryptionKey', potentialPubEncryptionKey.encode('hex')
|
||||
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Finished generating address. Writing to keys.dat')
|
||||
config.add_section(address)
|
||||
config.set(address,'label',self.label)
|
||||
config.set(address,'enabled','true')
|
||||
config.set(address,'decoy','false')
|
||||
config.set(address,'n',str(privkey['n']))
|
||||
config.set(address,'e',str(privkey['e']))
|
||||
config.set(address,'d',str(privkey['d']))
|
||||
config.set(address,'p',str(privkey['p']))
|
||||
config.set(address,'q',str(privkey['q']))
|
||||
with open(appdata + 'keys.dat', 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
ripe = hashlib.new('ripemd160')
|
||||
sha = hashlib.new('sha512')
|
||||
sha.update(potentialPubSigningKey+potentialPubEncryptionKey)
|
||||
ripe.update(sha.digest())
|
||||
#print 'potential ripe.digest', ripe.digest().encode('hex')
|
||||
if self.eighteenByteRipe:
|
||||
if ripe.digest()[:2] == '\x00\x00':
|
||||
break
|
||||
else:
|
||||
if ripe.digest()[:1] == '\x00':
|
||||
break
|
||||
print 'ripe.digest', ripe.digest().encode('hex')
|
||||
if ripe.digest()[:2] == '\x00\x00':
|
||||
address = encodeAddress(2,self.streamNumber,ripe.digest()[2:])
|
||||
print 'address has 18 byte ripe:', address
|
||||
elif ripe.digest()[:1] == '\x00':
|
||||
address = encodeAddress(2,self.streamNumber,ripe.digest()[1:])
|
||||
print 'address has 19 byte ripe:', address
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Finished generating address. Writing to keys.dat')
|
||||
status,addressVersionNumber,streamNumber,hash = decodeAddress(address)
|
||||
print status,addressVersionNumber,streamNumber,hash.encode('hex')
|
||||
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Done generating address')
|
||||
self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(self.streamNumber))
|
||||
#An excellent way for us to store our keys is in Wallet Import Format. Let us convert now.
|
||||
#https://en.bitcoin.it/wiki/Wallet_import_format
|
||||
privSigningKey = '\x80'+potentialPrivSigningKey
|
||||
checksum = hashlib.sha256(hashlib.sha256(privSigningKey).digest()).digest()[0:4]
|
||||
privSigningKeyWIF = arithmetic.changebase(privSigningKey + checksum,256,58)
|
||||
print 'privSigningKeyWIF',privSigningKeyWIF
|
||||
|
||||
privEncryptionKey = '\x80'+potentialPrivEncryptionKey
|
||||
checksum = hashlib.sha256(hashlib.sha256(privEncryptionKey).digest()).digest()[0:4]
|
||||
privEncryptionKeyWIF = arithmetic.changebase(privEncryptionKey + checksum,256,58)
|
||||
print 'privEncryptionKeyWIF',privEncryptionKeyWIF
|
||||
|
||||
config.add_section(address)
|
||||
print 'self.label', self.label
|
||||
config.set(address,'label',self.label)
|
||||
config.set(address,'enabled','true')
|
||||
config.set(address,'decoy','false')
|
||||
config.set(address,'privSigningKey',privSigningKeyWIF)
|
||||
config.set(address,'privEncryptionKey',privEncryptionKeyWIF)
|
||||
with open(appdata + 'keys.dat', 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Done generating address')
|
||||
self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(self.streamNumber))
|
||||
|
||||
|
||||
else: #There is something in the deterministicPassphrase variable thus we are going to do this deterministically.
|
||||
statusbar = 'Generating '+numberOfAddressesToMake + ' new addresses.'
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),statusbar)
|
||||
|
||||
elif self.addressVersionNumber == 1:
|
||||
statusbar = 'Generating new ' + str(config.getint('bitmessagesettings', 'bitstrength')) + ' bit RSA key. This takes a minute on average. If you want to generate multiple addresses now, you can; they will queue.'
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),statusbar)
|
||||
(pubkey, privkey) = rsa.newkeys(config.getint('bitmessagesettings', 'bitstrength'))
|
||||
print privkey['n']
|
||||
print privkey['e']
|
||||
print privkey['d']
|
||||
print privkey['p']
|
||||
print privkey['q']
|
||||
|
||||
sha = hashlib.new('sha512')
|
||||
#sha.update(str(pubkey.n)+str(pubkey.e))
|
||||
sha.update(convertIntToString(pubkey.n)+convertIntToString(pubkey.e))
|
||||
ripe = hashlib.new('ripemd160')
|
||||
ripe.update(sha.digest())
|
||||
address = encodeAddress(1,self.streamNumber,ripe.digest())
|
||||
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Finished generating address. Writing to keys.dat')
|
||||
config.add_section(address)
|
||||
config.set(address,'label',self.label)
|
||||
config.set(address,'enabled','true')
|
||||
config.set(address,'decoy','false')
|
||||
config.set(address,'n',str(privkey['n']))
|
||||
config.set(address,'e',str(privkey['e']))
|
||||
config.set(address,'d',str(privkey['d']))
|
||||
config.set(address,'p',str(privkey['p']))
|
||||
config.set(address,'q',str(privkey['q']))
|
||||
with open(appdata + 'keys.dat', 'wb') as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
self.emit(SIGNAL("updateStatusBar(PyQt_PyObject)"),'Done generating address')
|
||||
self.emit(SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"),self.label,address,str(self.streamNumber))
|
||||
|
||||
def pointMult(self,secret):
|
||||
#passphrase += 'a'
|
||||
#secret = hashlib.sha256(passphrase.encode('utf8')).digest()
|
||||
#if secret starts with too many FF's, continue
|
||||
ctx = OpenSSL.BN_CTX_new()
|
||||
#secret = OpenSSL.rand(32)
|
||||
k = OpenSSL.EC_KEY_new_by_curve_name(OpenSSL.get_curve('secp256k1'))
|
||||
priv_key = OpenSSL.BN_bin2bn(secret, 32, 0)
|
||||
group = OpenSSL.EC_KEY_get0_group(k)
|
||||
pub_key = OpenSSL.EC_POINT_new(group)
|
||||
|
||||
OpenSSL.EC_POINT_mul(group, pub_key, priv_key, None, None, ctx)
|
||||
OpenSSL.EC_KEY_set_private_key(k, priv_key)
|
||||
OpenSSL.EC_KEY_set_public_key(k, pub_key)
|
||||
#print 'priv_key',priv_key
|
||||
#print 'pub_key',pub_key
|
||||
|
||||
size = OpenSSL.i2o_ECPublicKey(k, 0)
|
||||
mb = ctypes.create_string_buffer(size)
|
||||
OpenSSL.i2o_ECPublicKey(k, ctypes.byref(ctypes.pointer(mb)))
|
||||
#print 'mb.raw', mb.raw.encode('hex'), 'length:', len(mb.raw)
|
||||
#print 'mb.raw', mb.raw, 'length:', len(mb.raw)
|
||||
|
||||
|
||||
|
||||
|
||||
#ripe = hashlib.new('ripemd160')
|
||||
#sha = hashlib.new('sha512')
|
||||
#sha.update(mb.raw)
|
||||
#ripe.update(sha.digest())
|
||||
OpenSSL.EC_POINT_free(pub_key)
|
||||
OpenSSL.BN_CTX_free(ctx)
|
||||
OpenSSL.BN_free(priv_key)
|
||||
OpenSSL.EC_KEY_free(k)
|
||||
return mb.raw
|
||||
|
||||
class iconGlossaryDialog(QtGui.QDialog):
|
||||
def __init__(self,parent):
|
||||
|
@ -2231,8 +2344,8 @@ class NewSubscriptionDialog(QtGui.QDialog):
|
|||
class NewAddressDialog(QtGui.QDialog):
|
||||
def __init__(self, parent):
|
||||
QtGui.QWidget.__init__(self, parent)
|
||||
self.ui = Ui_NewAddressDialog() #Jonathan changed this line
|
||||
self.ui.setupUi(self) #Jonathan left this line alone
|
||||
self.ui = Ui_NewAddressDialog()
|
||||
self.ui.setupUi(self)
|
||||
self.parent = parent
|
||||
row = 1
|
||||
while self.parent.ui.tableWidgetYourIdentities.item(row-1,1):
|
||||
|
@ -2240,8 +2353,8 @@ class NewAddressDialog(QtGui.QDialog):
|
|||
#print self.parent.ui.tableWidgetYourIdentities.item(row-1,1).text()
|
||||
self.ui.comboBoxExisting.addItem(self.parent.ui.tableWidgetYourIdentities.item(row-1,1).text())
|
||||
row += 1
|
||||
#QtGui.QWidget.resize(self,QtGui.QWidget.sizeHint(self))
|
||||
|
||||
self.ui.groupBoxDeterministic.setHidden(True)
|
||||
QtGui.QWidget.resize(self,QtGui.QWidget.sizeHint(self))
|
||||
|
||||
|
||||
class MyForm(QtGui.QMainWindow):
|
||||
|
@ -2541,7 +2654,7 @@ class MyForm(QtGui.QMainWindow):
|
|||
queryreturn = sqlReturnQueue.get()
|
||||
for row in queryreturn:
|
||||
ackdata, = row
|
||||
print 'Watching for ackdata', repr(ackdata)
|
||||
print 'Watching for ackdata', ackdata.encode('hex')
|
||||
ackdataForWhichImWatching[ackdata] = 0
|
||||
|
||||
QtCore.QObject.connect(self.ui.tableWidgetYourIdentities, QtCore.SIGNAL("itemChanged(QTableWidgetItem *)"), self.tableWidgetYourIdentitiesItemChanged)
|
||||
|
@ -3225,31 +3338,36 @@ class MyForm(QtGui.QMainWindow):
|
|||
|
||||
|
||||
def click_NewAddressDialog(self):
|
||||
print 'click_buttondialog'
|
||||
self.dialog = NewAddressDialog(self)
|
||||
|
||||
# For Modal dialogs
|
||||
if self.dialog.exec_():
|
||||
self.dialog.ui.buttonBox.enabled = False
|
||||
if self.dialog.ui.radioButtonMostAvailable.isChecked():
|
||||
#self.generateAndStoreAnAddress(1)
|
||||
streamNumberForAddress = 1
|
||||
|
||||
#self.dialog.ui.buttonBox.enabled = False
|
||||
if self.dialog.ui.radioButtonRandomAddress.isChecked():
|
||||
if self.dialog.ui.radioButtonMostAvailable.isChecked():
|
||||
streamNumberForAddress = 1
|
||||
else:
|
||||
#User selected 'Use the same stream as an existing address.'
|
||||
streamNumberForAddress = addressStream(self.dialog.ui.comboBoxExisting.currentText())
|
||||
|
||||
self.addressGenerator = addressGenerator()
|
||||
self.addressGenerator.setup(2,streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()),1,"",self.dialog.ui.checkBoxEighteenByteRipe.isChecked())
|
||||
QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
||||
QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||
self.addressGenerator.start()
|
||||
else:
|
||||
#User selected 'Use the same stream as an existing address.'
|
||||
streamNumberForAddress = addressStream(self.dialog.ui.comboBoxExisting.currentText())
|
||||
|
||||
self.addressGenerator = addressGenerator()
|
||||
self.addressGenerator.setup(streamNumberForAddress,str(self.dialog.ui.newaddresslabel.text().toUtf8()))
|
||||
|
||||
QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
||||
QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||
|
||||
|
||||
self.addressGenerator.start()
|
||||
if self.dialog.ui.lineEditPassphrase.text() != self.dialog.ui.lineEditPassphraseAgain.text():
|
||||
QMessageBox.about(self, "Passphrase mismatch", "The passphrase you entered twice doesn\'t match. Try again.")
|
||||
elif self.dialog.ui.lineEditPassphrase.text() == "":
|
||||
QMessageBox.about(self, "Choose a passphrase", "You really do need a passphrase.")
|
||||
else:
|
||||
streamNumberForAddress = 1 #this will eventually have to be replaced by logic to determine the most available stream number.
|
||||
self.addressGenerator = addressGenerator()
|
||||
self.addressGenerator.setup(2,streamNumberForAddress,"unused address",self.dialog.ui.spinBoxNumberOfAddressesToMake.value(),self.dialog.ui.lineEditPassphrase.text().toUtf8(),self.dialog.ui.checkBoxEighteenByteRipe.isChecked())
|
||||
QtCore.QObject.connect(self.addressGenerator, SIGNAL("writeNewAddressToTable(PyQt_PyObject,PyQt_PyObject,PyQt_PyObject)"), self.writeNewAddressToTable)
|
||||
QtCore.QObject.connect(self.addressGenerator, QtCore.SIGNAL("updateStatusBar(PyQt_PyObject)"), self.updateStatusBar)
|
||||
self.addressGenerator.start()
|
||||
else:
|
||||
print 'rejected'
|
||||
print 'new address dialog box rejected'
|
||||
|
||||
def closeEvent(self, event):
|
||||
broadcastToSendDataQueues((0, 'shutdown', 'all'))
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
# Form implementation generated from reading ui file 'newaddressdialog.ui'
|
||||
#
|
||||
# Created: Wed Dec 19 15:55:07 2012
|
||||
# Created: Tue Jan 15 15:21:33 2013
|
||||
# by: PyQt4 UI code generator 4.9.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
@ -17,57 +17,154 @@ except AttributeError:
|
|||
class Ui_NewAddressDialog(object):
|
||||
def setupUi(self, NewAddressDialog):
|
||||
NewAddressDialog.setObjectName(_fromUtf8("NewAddressDialog"))
|
||||
NewAddressDialog.resize(383, 258)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(NewAddressDialog)
|
||||
self.buttonBox.setGeometry(QtCore.QRect(160, 220, 201, 32))
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
|
||||
NewAddressDialog.resize(723, 704)
|
||||
self.formLayout = QtGui.QFormLayout(NewAddressDialog)
|
||||
self.formLayout.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
|
||||
self.formLayout.setObjectName(_fromUtf8("formLayout"))
|
||||
self.label = QtGui.QLabel(NewAddressDialog)
|
||||
self.label.setGeometry(QtCore.QRect(10, 0, 361, 41))
|
||||
self.label.setAlignment(QtCore.Qt.AlignBottom|QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft)
|
||||
self.label.setWordWrap(True)
|
||||
self.label.setObjectName(_fromUtf8("label"))
|
||||
self.label_2 = QtGui.QLabel(NewAddressDialog)
|
||||
self.label_2.setGeometry(QtCore.QRect(20, 50, 301, 20))
|
||||
self.formLayout.setWidget(0, QtGui.QFormLayout.SpanningRole, self.label)
|
||||
self.label_5 = QtGui.QLabel(NewAddressDialog)
|
||||
self.label_5.setWordWrap(True)
|
||||
self.label_5.setObjectName(_fromUtf8("label_5"))
|
||||
self.formLayout.setWidget(2, QtGui.QFormLayout.SpanningRole, self.label_5)
|
||||
self.line = QtGui.QFrame(NewAddressDialog)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.line.sizePolicy().hasHeightForWidth())
|
||||
self.line.setSizePolicy(sizePolicy)
|
||||
self.line.setMinimumSize(QtCore.QSize(100, 2))
|
||||
self.line.setFrameShape(QtGui.QFrame.HLine)
|
||||
self.line.setFrameShadow(QtGui.QFrame.Sunken)
|
||||
self.line.setObjectName(_fromUtf8("line"))
|
||||
self.formLayout.setWidget(4, QtGui.QFormLayout.SpanningRole, self.line)
|
||||
self.radioButtonRandomAddress = QtGui.QRadioButton(NewAddressDialog)
|
||||
self.radioButtonRandomAddress.setChecked(True)
|
||||
self.radioButtonRandomAddress.setObjectName(_fromUtf8("radioButtonRandomAddress"))
|
||||
self.formLayout.setWidget(5, QtGui.QFormLayout.SpanningRole, self.radioButtonRandomAddress)
|
||||
self.radioButtonDeterministicAddress = QtGui.QRadioButton(NewAddressDialog)
|
||||
self.radioButtonDeterministicAddress.setObjectName(_fromUtf8("radioButtonDeterministicAddress"))
|
||||
self.formLayout.setWidget(6, QtGui.QFormLayout.LabelRole, self.radioButtonDeterministicAddress)
|
||||
self.checkBoxEighteenByteRipe = QtGui.QCheckBox(NewAddressDialog)
|
||||
self.checkBoxEighteenByteRipe.setObjectName(_fromUtf8("checkBoxEighteenByteRipe"))
|
||||
self.formLayout.setWidget(9, QtGui.QFormLayout.SpanningRole, self.checkBoxEighteenByteRipe)
|
||||
self.groupBoxDeterministic = QtGui.QGroupBox(NewAddressDialog)
|
||||
self.groupBoxDeterministic.setObjectName(_fromUtf8("groupBoxDeterministic"))
|
||||
self.gridLayout = QtGui.QGridLayout(self.groupBoxDeterministic)
|
||||
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
|
||||
self.label_6 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_6.setObjectName(_fromUtf8("label_6"))
|
||||
self.gridLayout.addWidget(self.label_6, 0, 0, 1, 4)
|
||||
self.lineEditPassphrase = QtGui.QLineEdit(self.groupBoxDeterministic)
|
||||
self.lineEditPassphrase.setInputMethodHints(QtCore.Qt.ImhHiddenText|QtCore.Qt.ImhNoAutoUppercase|QtCore.Qt.ImhNoPredictiveText)
|
||||
self.lineEditPassphrase.setEchoMode(QtGui.QLineEdit.Password)
|
||||
self.lineEditPassphrase.setObjectName(_fromUtf8("lineEditPassphrase"))
|
||||
self.gridLayout.addWidget(self.lineEditPassphrase, 1, 0, 1, 7)
|
||||
self.label_7 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_7.setObjectName(_fromUtf8("label_7"))
|
||||
self.gridLayout.addWidget(self.label_7, 2, 0, 1, 4)
|
||||
self.lineEditPassphraseAgain = QtGui.QLineEdit(self.groupBoxDeterministic)
|
||||
self.lineEditPassphraseAgain.setEchoMode(QtGui.QLineEdit.Password)
|
||||
self.lineEditPassphraseAgain.setObjectName(_fromUtf8("lineEditPassphraseAgain"))
|
||||
self.gridLayout.addWidget(self.lineEditPassphraseAgain, 3, 0, 1, 7)
|
||||
self.label_8 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_8.setObjectName(_fromUtf8("label_8"))
|
||||
self.gridLayout.addWidget(self.label_8, 4, 0, 1, 7)
|
||||
self.label_9 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_9.setObjectName(_fromUtf8("label_9"))
|
||||
self.gridLayout.addWidget(self.label_9, 5, 0, 1, 1)
|
||||
spacerItem = QtGui.QSpacerItem(73, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.gridLayout.addItem(spacerItem, 5, 1, 1, 1)
|
||||
self.label_10 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_10.setObjectName(_fromUtf8("label_10"))
|
||||
self.gridLayout.addWidget(self.label_10, 5, 3, 1, 1)
|
||||
spacerItem1 = QtGui.QSpacerItem(42, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.gridLayout.addItem(spacerItem1, 5, 4, 1, 2)
|
||||
self.label_11 = QtGui.QLabel(self.groupBoxDeterministic)
|
||||
self.label_11.setObjectName(_fromUtf8("label_11"))
|
||||
self.gridLayout.addWidget(self.label_11, 6, 0, 1, 5)
|
||||
self.spinBoxNumberOfAddressesToMake = QtGui.QSpinBox(self.groupBoxDeterministic)
|
||||
self.spinBoxNumberOfAddressesToMake.setMinimum(1)
|
||||
self.spinBoxNumberOfAddressesToMake.setProperty("value", 8)
|
||||
self.spinBoxNumberOfAddressesToMake.setObjectName(_fromUtf8("spinBoxNumberOfAddressesToMake"))
|
||||
self.gridLayout.addWidget(self.spinBoxNumberOfAddressesToMake, 6, 5, 1, 2)
|
||||
self.formLayout.setWidget(8, QtGui.QFormLayout.LabelRole, self.groupBoxDeterministic)
|
||||
self.groupBox = QtGui.QGroupBox(NewAddressDialog)
|
||||
self.groupBox.setObjectName(_fromUtf8("groupBox"))
|
||||
self.gridLayout_2 = QtGui.QGridLayout(self.groupBox)
|
||||
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
|
||||
self.label_2 = QtGui.QLabel(self.groupBox)
|
||||
self.label_2.setObjectName(_fromUtf8("label_2"))
|
||||
self.newaddresslabel = QtGui.QLineEdit(NewAddressDialog)
|
||||
self.newaddresslabel.setGeometry(QtCore.QRect(20, 70, 351, 20))
|
||||
self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 2)
|
||||
self.newaddresslabel = QtGui.QLineEdit(self.groupBox)
|
||||
self.newaddresslabel.setObjectName(_fromUtf8("newaddresslabel"))
|
||||
self.radioButtonMostAvailable = QtGui.QRadioButton(NewAddressDialog)
|
||||
self.radioButtonMostAvailable.setGeometry(QtCore.QRect(20, 110, 401, 16))
|
||||
self.radioButtonMostAvailable.setChecked(True)
|
||||
self.gridLayout_2.addWidget(self.newaddresslabel, 1, 0, 1, 2)
|
||||
self.radioButtonMostAvailable = QtGui.QRadioButton(self.groupBox)
|
||||
self.radioButtonMostAvailable.setChecked(False)
|
||||
self.radioButtonMostAvailable.setObjectName(_fromUtf8("radioButtonMostAvailable"))
|
||||
self.radioButtonExisting = QtGui.QRadioButton(NewAddressDialog)
|
||||
self.radioButtonExisting.setGeometry(QtCore.QRect(20, 150, 351, 18))
|
||||
self.radioButtonExisting.setChecked(False)
|
||||
self.radioButtonExisting.setObjectName(_fromUtf8("radioButtonExisting"))
|
||||
self.label_3 = QtGui.QLabel(NewAddressDialog)
|
||||
self.label_3.setGeometry(QtCore.QRect(35, 127, 351, 20))
|
||||
self.gridLayout_2.addWidget(self.radioButtonMostAvailable, 2, 0, 1, 2)
|
||||
self.label_3 = QtGui.QLabel(self.groupBox)
|
||||
self.label_3.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.label_3.setObjectName(_fromUtf8("label_3"))
|
||||
self.label_4 = QtGui.QLabel(NewAddressDialog)
|
||||
self.label_4.setGeometry(QtCore.QRect(37, 167, 351, 21))
|
||||
self.gridLayout_2.addWidget(self.label_3, 3, 1, 1, 1)
|
||||
self.radioButtonExisting = QtGui.QRadioButton(self.groupBox)
|
||||
self.radioButtonExisting.setChecked(False)
|
||||
self.radioButtonExisting.setObjectName(_fromUtf8("radioButtonExisting"))
|
||||
self.gridLayout_2.addWidget(self.radioButtonExisting, 4, 0, 1, 2)
|
||||
self.label_4 = QtGui.QLabel(self.groupBox)
|
||||
self.label_4.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.label_4.setObjectName(_fromUtf8("label_4"))
|
||||
self.comboBoxExisting = QtGui.QComboBox(NewAddressDialog)
|
||||
self.gridLayout_2.addWidget(self.label_4, 5, 1, 1, 1)
|
||||
spacerItem2 = QtGui.QSpacerItem(13, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
|
||||
self.gridLayout_2.addItem(spacerItem2, 6, 0, 1, 1)
|
||||
self.comboBoxExisting = QtGui.QComboBox(self.groupBox)
|
||||
self.comboBoxExisting.setEnabled(False)
|
||||
self.comboBoxExisting.setGeometry(QtCore.QRect(40, 190, 331, 22))
|
||||
self.comboBoxExisting.setEditable(True)
|
||||
self.comboBoxExisting.setObjectName(_fromUtf8("comboBoxExisting"))
|
||||
self.gridLayout_2.addWidget(self.comboBoxExisting, 6, 1, 1, 1)
|
||||
self.formLayout.setWidget(7, QtGui.QFormLayout.LabelRole, self.groupBox)
|
||||
self.buttonBox = QtGui.QDialogButtonBox(NewAddressDialog)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.buttonBox.sizePolicy().hasHeightForWidth())
|
||||
self.buttonBox.setSizePolicy(sizePolicy)
|
||||
self.buttonBox.setMinimumSize(QtCore.QSize(160, 0))
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
|
||||
self.formLayout.setWidget(10, QtGui.QFormLayout.SpanningRole, self.buttonBox)
|
||||
|
||||
self.retranslateUi(NewAddressDialog)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), NewAddressDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), NewAddressDialog.reject)
|
||||
QtCore.QObject.connect(self.radioButtonExisting, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.comboBoxExisting.setEnabled)
|
||||
QtCore.QObject.connect(self.radioButtonDeterministicAddress, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBoxDeterministic.setShown)
|
||||
QtCore.QObject.connect(self.radioButtonRandomAddress, QtCore.SIGNAL(_fromUtf8("toggled(bool)")), self.groupBox.setShown)
|
||||
QtCore.QMetaObject.connectSlotsByName(NewAddressDialog)
|
||||
|
||||
def retranslateUi(self, NewAddressDialog):
|
||||
NewAddressDialog.setWindowTitle(QtGui.QApplication.translate("NewAddressDialog", "Create new Address", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate("NewAddressDialog", "Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged.", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate("NewAddressDialog", "Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged. You may generate addresses by using either random numbers or by using a passphrase. If you use a passphrase, the address is called a \"deterministic\" address.\n"
|
||||
"The \'Random Number\' option is selected by default but deterministic addresses have several pros and cons:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_5.setText(QtGui.QApplication.translate("NewAddressDialog", "<html><head/><body><p><span style=\" font-weight:600;\">Pros:<br/></span>You can recreate your addresses on any computer from memory. <br/>You need-not worry about backing up your keys.dat file as long as you can remember your passphrase. <br/><span style=\" font-weight:600;\">Cons:<br/></span>You must remember (or write down) your passphrase if you expect to be able to recreate your keys if they are lost. <br/>You must remember the address version number and the stream number along with your passphrase. <br/>If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you.</p></body></html>", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.radioButtonRandomAddress.setText(QtGui.QApplication.translate("NewAddressDialog", "Use a random number generator to make an address", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.radioButtonDeterministicAddress.setText(QtGui.QApplication.translate("NewAddressDialog", "Use a passpharase to make addresses", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkBoxEighteenByteRipe.setText(QtGui.QApplication.translate("NewAddressDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.groupBoxDeterministic.setTitle(QtGui.QApplication.translate("NewAddressDialog", "Make deterministic addresses", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_6.setText(QtGui.QApplication.translate("NewAddressDialog", "Passphrase", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_7.setText(QtGui.QApplication.translate("NewAddressDialog", "Retype passphrase", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_8.setText(QtGui.QApplication.translate("NewAddressDialog", "In addition to your passphrase, you must remember these numbers:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_9.setText(QtGui.QApplication.translate("NewAddressDialog", "Address version number: 2", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_10.setText(QtGui.QApplication.translate("NewAddressDialog", "Stream number: 1", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_11.setText(QtGui.QApplication.translate("NewAddressDialog", "Number of addresses to make based on your passphrase:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.groupBox.setTitle(QtGui.QApplication.translate("NewAddressDialog", "Randomly generate address", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_2.setText(QtGui.QApplication.translate("NewAddressDialog", "Label (not shown to anyone except you)", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.radioButtonMostAvailable.setText(QtGui.QApplication.translate("NewAddressDialog", "Use the most available stream", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.radioButtonExisting.setText(QtGui.QApplication.translate("NewAddressDialog", "Use the same stream as an existing address", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_3.setText(QtGui.QApplication.translate("NewAddressDialog", " (best if this is the first of many addresses you will create)", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.radioButtonExisting.setText(QtGui.QApplication.translate("NewAddressDialog", "Use the same stream as an existing address", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_4.setText(QtGui.QApplication.translate("NewAddressDialog", "(saves you some bandwidth and processing power)", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
|
|
|
@ -6,151 +6,301 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>383</width>
|
||||
<height>258</height>
|
||||
<width>723</width>
|
||||
<height>704</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Create new Address</string>
|
||||
</property>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>220</y>
|
||||
<width>201</width>
|
||||
<height>32</height>
|
||||
</rect>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>0</y>
|
||||
<width>361</width>
|
||||
<height>41</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged.</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>50</y>
|
||||
<width>301</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Label (not shown to anyone except you)</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="newaddresslabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>70</y>
|
||||
<width>351</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButtonMostAvailable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>110</y>
|
||||
<width>401</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use the most available stream</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="radioButtonExisting">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>150</y>
|
||||
<width>351</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use the same stream as an existing address</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>35</x>
|
||||
<y>127</y>
|
||||
<width>351</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string> (best if this is the first of many addresses you will create)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>37</x>
|
||||
<y>167</y>
|
||||
<width>351</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>(saves you some bandwidth and processing power)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="comboBoxExisting">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>190</y>
|
||||
<width>331</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Here you may generate as many addresses as you like. Indeed, creating and abandoning addresses is encouraged. You may generate addresses by using either random numbers or by using a passphrase. If you use a passphrase, the address is called a "deterministic" address.
|
||||
The 'Random Number' option is selected by default but deterministic addresses have several pros and cons:</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><span style=" font-weight:600;">Pros:<br/></span>You can recreate your addresses on any computer from memory. <br/>You need-not worry about backing up your keys.dat file as long as you can remember your passphrase. <br/><span style=" font-weight:600;">Cons:<br/></span>You must remember (or write down) your passphrase if you expect to be able to recreate your keys if they are lost. <br/>You must remember the address version number and the stream number along with your passphrase. <br/>If you choose a weak passphrase and someone on the Internet can brute-force it, they can read your messages and send messages as you.</p></body></html></string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="Line" name="line">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>100</width>
|
||||
<height>2</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButtonRandomAddress">
|
||||
<property name="text">
|
||||
<string>Use a random number generator to make an address</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QRadioButton" name="radioButtonDeterministicAddress">
|
||||
<property name="text">
|
||||
<string>Use a passpharase to make addresses</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0" colspan="2">
|
||||
<widget class="QCheckBox" name="checkBoxEighteenByteRipe">
|
||||
<property name="text">
|
||||
<string>Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QGroupBox" name="groupBoxDeterministic">
|
||||
<property name="title">
|
||||
<string>Make deterministic addresses</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Passphrase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="7">
|
||||
<widget class="QLineEdit" name="lineEditPassphrase">
|
||||
<property name="inputMethodHints">
|
||||
<set>Qt::ImhHiddenText|Qt::ImhNoAutoUppercase|Qt::ImhNoPredictiveText</set>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Retype passphrase</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="7">
|
||||
<widget class="QLineEdit" name="lineEditPassphraseAgain">
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="7">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>In addition to your passphrase, you must remember these numbers:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Address version number: 2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>73</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QLabel" name="label_10">
|
||||
<property name="text">
|
||||
<string>Stream number: 1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="4" colspan="2">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>42</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="0" colspan="5">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Number of addresses to make based on your passphrase:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="5" colspan="2">
|
||||
<widget class="QSpinBox" name="spinBoxNumberOfAddressesToMake">
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>8</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Randomly generate address</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Label (not shown to anyone except you)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="2">
|
||||
<widget class="QLineEdit" name="newaddresslabel"/>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButtonMostAvailable">
|
||||
<property name="text">
|
||||
<string>Use the most available stream</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string> (best if this is the first of many addresses you will create)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0" colspan="2">
|
||||
<widget class="QRadioButton" name="radioButtonExisting">
|
||||
<property name="text">
|
||||
<string>Use the same stream as an existing address</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>(saves you some bandwidth and processing power)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>13</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="comboBoxExisting">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<zorder>comboBoxExisting</zorder>
|
||||
<zorder>label_3</zorder>
|
||||
<zorder>radioButtonExisting</zorder>
|
||||
<zorder>newaddresslabel</zorder>
|
||||
<zorder>label_4</zorder>
|
||||
<zorder>radioButtonMostAvailable</zorder>
|
||||
<zorder>label_2</zorder>
|
||||
<zorder>horizontalSpacer_3</zorder>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>160</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
|
@ -161,8 +311,8 @@
|
|||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>360</x>
|
||||
<y>234</y>
|
||||
<x>580</x>
|
||||
<y>644</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
|
@ -177,8 +327,8 @@
|
|||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>360</x>
|
||||
<y>240</y>
|
||||
<x>580</x>
|
||||
<y>650</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
|
@ -193,12 +343,44 @@
|
|||
<slot>setEnabled(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>30</x>
|
||||
<y>158</y>
|
||||
<x>60</x>
|
||||
<y>349</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>99</x>
|
||||
<y>199</y>
|
||||
<x>148</x>
|
||||
<y>394</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>radioButtonDeterministicAddress</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBoxDeterministic</receiver>
|
||||
<slot>setShown(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>92</x>
|
||||
<y>213</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>277</x>
|
||||
<y>601</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>radioButtonRandomAddress</sender>
|
||||
<signal>toggled(bool)</signal>
|
||||
<receiver>groupBox</receiver>
|
||||
<slot>setShown(bool)</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>72</x>
|
||||
<y>189</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>68</x>
|
||||
<y>268</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
|
|
17
pyelliptic/__init__.py
Normal file
17
pyelliptic/__init__.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (C) 2010
|
||||
# Author: Yann GUIBET
|
||||
# Contact: <yannguibet@gmail.com>
|
||||
|
||||
__version__ = '1.3'
|
||||
|
||||
__all__ = [
|
||||
'OpenSSL',
|
||||
'ecc',
|
||||
'cipher',
|
||||
'hash',
|
||||
]
|
||||
|
||||
from .openssl import OpenSSL
|
||||
from .ecc import ECC
|
||||
from .cipher import Cipher
|
||||
from .hash import hmac_sha256, hmac_sha512, pbkdf2
|
103
pyelliptic/arithmetic.py
Normal file
103
pyelliptic/arithmetic.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
import hashlib, re
|
||||
|
||||
P = 2**256-2**32-2**9-2**8-2**7-2**6-2**4-1
|
||||
A = 0
|
||||
Gx = 55066263022277343669578718895168534326250603453777594175500187360389116729240
|
||||
Gy = 32670510020758816978083085130507043184471273380659243275938904335757337482424
|
||||
G = (Gx,Gy)
|
||||
|
||||
def inv(a,n):
|
||||
lm, hm = 1,0
|
||||
low, high = a%n,n
|
||||
while low > 1:
|
||||
r = high/low
|
||||
nm, new = hm-lm*r, high-low*r
|
||||
lm, low, hm, high = nm, new, lm, low
|
||||
return lm % n
|
||||
|
||||
def get_code_string(base):
|
||||
if base == 2: return '01'
|
||||
elif base == 10: return '0123456789'
|
||||
elif base == 16: return "0123456789abcdef"
|
||||
elif base == 58: return "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
|
||||
elif base == 256: return ''.join([chr(x) for x in range(256)])
|
||||
else: raise ValueError("Invalid base!")
|
||||
|
||||
def encode(val,base,minlen=0):
|
||||
code_string = get_code_string(base)
|
||||
result = ""
|
||||
while val > 0:
|
||||
result = code_string[val % base] + result
|
||||
val /= base
|
||||
if len(result) < minlen:
|
||||
result = code_string[0]*(minlen-len(result))+result
|
||||
return result
|
||||
|
||||
def decode(string,base):
|
||||
code_string = get_code_string(base)
|
||||
result = 0
|
||||
if base == 16: string = string.lower()
|
||||
while len(string) > 0:
|
||||
result *= base
|
||||
result += code_string.find(string[0])
|
||||
string = string[1:]
|
||||
return result
|
||||
|
||||
def changebase(string,frm,to,minlen=0):
|
||||
return encode(decode(string,frm),to,minlen)
|
||||
|
||||
def base10_add(a,b):
|
||||
if a == None: return b[0],b[1]
|
||||
if b == None: return a[0],a[1]
|
||||
if a[0] == b[0]:
|
||||
if a[1] == b[1]: return base10_double(a[0],a[1])
|
||||
else: return None
|
||||
m = ((b[1]-a[1]) * inv(b[0]-a[0],P)) % P
|
||||
x = (m*m-a[0]-b[0]) % P
|
||||
y = (m*(a[0]-x)-a[1]) % P
|
||||
return (x,y)
|
||||
|
||||
def base10_double(a):
|
||||
if a == None: return None
|
||||
m = ((3*a[0]*a[0]+A)*inv(2*a[1],P)) % P
|
||||
x = (m*m-2*a[0]) % P
|
||||
y = (m*(a[0]-x)-a[1]) % P
|
||||
return (x,y)
|
||||
|
||||
def base10_multiply(a,n):
|
||||
if n == 0: return G
|
||||
if n == 1: return a
|
||||
if (n%2) == 0: return base10_double(base10_multiply(a,n/2))
|
||||
if (n%2) == 1: return base10_add(base10_double(base10_multiply(a,n/2)),a)
|
||||
|
||||
def hex_to_point(h): return (decode(h[2:34],16),decode(h[34:],16))
|
||||
|
||||
def point_to_hex(p): return '04'+encode(p[0],16,32)+encode(p[1],16,32)
|
||||
|
||||
def multiply(privkey,pubkey):
|
||||
return point_to_hex(base10_multiply(hex_to_point(pubkey),decode(privkey,16)))
|
||||
|
||||
def privtopub(privkey):
|
||||
return point_to_hex(base10_multiply(G,decode(privkey,16)))
|
||||
|
||||
def add(p1,p2):
|
||||
if (len(p1)==32):
|
||||
return encode(decode(p1,16) + decode(p2,16) % P,16,32)
|
||||
else:
|
||||
return point_to_hex(base10_add(hex_to_point(p1),hex_to_point(p2)))
|
||||
|
||||
def hash160(string):
|
||||
intermed = hashlib.sha256(string).digest()
|
||||
return hashlib.new('ripemd160').update(intermed).digest()
|
||||
|
||||
def dbl_sha256(string):
|
||||
return hashlib.sha256(hashlib.sha256(string).digest()).digest()
|
||||
|
||||
def bin_to_b58check(inp):
|
||||
inp_fmtd = '\x00' + inp
|
||||
leadingzbytes = len(re.match('^\x00*',inp_fmtd).group(0))
|
||||
checksum = dbl_sha256(inp_fmtd)[:4]
|
||||
return '1' * leadingzbytes + changebase(inp_fmtd+checksum,256,58)
|
||||
|
||||
def pubkey_to_address(pubkey):
|
||||
return bin_to_b58check(hash_160(changebase(pubkey,16,256)))
|
81
pyelliptic/cipher.py
Normal file
81
pyelliptic/cipher.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
||||
# See LICENSE for details.
|
||||
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
|
||||
|
||||
class Cipher:
|
||||
"""
|
||||
Symmetric encryption
|
||||
|
||||
import pyelliptic
|
||||
iv = pyelliptic.Cipher.gen_IV('aes-256-cfb')
|
||||
ctx = pyelliptic.Cipher("secretkey", iv, 1, ciphername='aes-256-cfb')
|
||||
ciphertext = ctx.update('test1')
|
||||
ciphertext += ctx.update('test2')
|
||||
ciphertext += ctx.final()
|
||||
|
||||
ctx2 = pyelliptic.Cipher("secretkey", iv, 0, ciphername='aes-256-cfb')
|
||||
print ctx2.ciphering(ciphertext)
|
||||
"""
|
||||
def __init__(self, key, iv, do, ciphername='aes-256-cbc'):
|
||||
"""
|
||||
do == 1 => Encrypt; do == 0 => Decrypt
|
||||
"""
|
||||
self.cipher = OpenSSL.get_cipher(ciphername)
|
||||
self.ctx = OpenSSL.EVP_CIPHER_CTX_new()
|
||||
if do == 1 or do == 0:
|
||||
k = OpenSSL.malloc(key, len(key))
|
||||
IV = OpenSSL.malloc(iv, len(iv))
|
||||
OpenSSL.EVP_CipherInit_ex(
|
||||
self.ctx, self.cipher.get_pointer(), 0, k, IV, do)
|
||||
else:
|
||||
raise Exception("RTFM ...")
|
||||
|
||||
@staticmethod
|
||||
def get_all_cipher():
|
||||
"""
|
||||
static method, returns all ciphers available
|
||||
"""
|
||||
return OpenSSL.cipher_algo.keys()
|
||||
|
||||
@staticmethod
|
||||
def get_blocksize(ciphername):
|
||||
cipher = OpenSSL.get_cipher(ciphername)
|
||||
return cipher.get_blocksize()
|
||||
|
||||
@staticmethod
|
||||
def gen_IV(ciphername):
|
||||
cipher = OpenSSL.get_cipher(ciphername)
|
||||
return OpenSSL.rand(cipher.get_blocksize())
|
||||
|
||||
def update(self, input):
|
||||
i = OpenSSL.c_int(0)
|
||||
buffer = OpenSSL.malloc(b"", len(input) + self.cipher.get_blocksize())
|
||||
inp = OpenSSL.malloc(input, len(input))
|
||||
if OpenSSL.EVP_CipherUpdate(self.ctx, OpenSSL.byref(buffer),
|
||||
OpenSSL.byref(i), inp, len(input)) == 0:
|
||||
raise Exception("[OpenSSL] EVP_CipherUpdate FAIL ...")
|
||||
return buffer.raw[0:i.value]
|
||||
|
||||
def final(self):
|
||||
i = OpenSSL.c_int(0)
|
||||
buffer = OpenSSL.malloc(b"", self.cipher.get_blocksize())
|
||||
if (OpenSSL.EVP_CipherFinal_ex(self.ctx, OpenSSL.byref(buffer),
|
||||
OpenSSL.byref(i))) == 0:
|
||||
raise Exception("[OpenSSL] EVP_CipherFinal_ex FAIL ...")
|
||||
return buffer.raw[0:i.value]
|
||||
|
||||
def ciphering(self, input):
|
||||
"""
|
||||
Do update and final in one method
|
||||
"""
|
||||
buff = self.update(input)
|
||||
return buff + self.final()
|
||||
|
||||
def __del__(self):
|
||||
OpenSSL.EVP_CIPHER_CTX_cleanup(self.ctx)
|
||||
OpenSSL.EVP_CIPHER_CTX_free(self.ctx)
|
460
pyelliptic/ecc.py
Normal file
460
pyelliptic/ecc.py
Normal file
|
@ -0,0 +1,460 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Copyright (C) 2011 Yann GUIBET <yannguibet@gmail.com>
|
||||
# See LICENSE for details.
|
||||
|
||||
from hashlib import sha512
|
||||
from pyelliptic.openssl import OpenSSL
|
||||
from pyelliptic.cipher import Cipher
|
||||
from pyelliptic.hash import hmac_sha256
|
||||
from struct import pack, unpack
|
||||
|
||||
|
||||
class ECC:
|
||||
"""
|
||||
Asymmetric encryption with Elliptic Curve Cryptography (ECC)
|
||||
ECDH, ECDSA and ECIES
|
||||
|
||||
import pyelliptic
|
||||
|
||||
alice = pyelliptic.ECC() # default curve: sect283r1
|
||||
bob = pyelliptic.ECC(curve='sect571r1')
|
||||
|
||||
ciphertext = alice.encrypt("Hello Bob", bob.get_pubkey())
|
||||
print bob.decrypt(ciphertext)
|
||||
|
||||
signature = bob.sign("Hello Alice")
|
||||
# alice's job :
|
||||
print pyelliptic.ECC(
|
||||
pubkey=bob.get_pubkey()).verify(signature, "Hello Alice")
|
||||
|
||||
# ERROR !!!
|
||||
try:
|
||||
key = alice.get_ecdh_key(bob.get_pubkey())
|
||||
except: print("For ECDH key agreement,\
|
||||
the keys must be defined on the same curve !")
|
||||
|
||||
alice = pyelliptic.ECC(curve='sect571r1')
|
||||
print alice.get_ecdh_key(bob.get_pubkey()).encode('hex')
|
||||
print bob.get_ecdh_key(alice.get_pubkey()).encode('hex')
|
||||
|
||||
"""
|
||||
def __init__(self, pubkey=None, privkey=None, pubkey_x=None,
|
||||
pubkey_y=None, raw_privkey=None, curve='sect283r1'):
|
||||
"""
|
||||
For a normal and High level use, specifie pubkey,
|
||||
privkey (if you need) and the curve
|
||||
"""
|
||||
if type(curve) == str:
|
||||
self.curve = OpenSSL.get_curve(curve)
|
||||
else:
|
||||
self.curve = curve
|
||||
|
||||
if pubkey_x is not None and pubkey_y is not None:
|
||||
self._set_keys(pubkey_x, pubkey_y, raw_privkey)
|
||||
elif pubkey is not None:
|
||||
curve, pubkey_x, pubkey_y, i = ECC._decode_pubkey(pubkey)
|
||||
if privkey is not None:
|
||||
curve2, raw_privkey, i = ECC._decode_privkey(privkey)
|
||||
if curve != curve2:
|
||||
raise Exception("Bad ECC keys ...")
|
||||
self.curve = curve
|
||||
self._set_keys(pubkey_x, pubkey_y, raw_privkey)
|
||||
else:
|
||||
self.privkey, self.pubkey_x, self.pubkey_y = self._generate()
|
||||
|
||||
def _set_keys(self, pubkey_x, pubkey_y, privkey):
|
||||
if self.raw_check_key(privkey, pubkey_x, pubkey_y) < 0:
|
||||
self.pubkey_x = None
|
||||
self.pubkey_y = None
|
||||
self.privkey = None
|
||||
raise Exception("Bad ECC keys ...")
|
||||
else:
|
||||
self.pubkey_x = pubkey_x
|
||||
self.pubkey_y = pubkey_y
|
||||
self.privkey = privkey
|
||||
|
||||
@staticmethod
|
||||
def get_curves():
|
||||
"""
|
||||
static method, returns the list of all the curves available
|
||||
"""
|
||||
return OpenSSL.curves.keys()
|
||||
|
||||
def get_curve(self):
|
||||
return OpenSSL.get_curve_by_id(self.curve)
|
||||
|
||||
def get_curve_id(self):
|
||||
return self.curve
|
||||
|
||||
def get_pubkey(self):
|
||||
"""
|
||||
High level function which returns :
|
||||
curve(2) + len_of_pubkeyX(2) + pubkeyX + len_of_pubkeyY + pubkeyY
|
||||
"""
|
||||
return b''.join((pack('!H', self.curve),
|
||||
pack('!H', len(self.pubkey_x)),
|
||||
self.pubkey_x,
|
||||
pack('!H', len(self.pubkey_y)),
|
||||
self.pubkey_y
|
||||
))
|
||||
|
||||
def get_privkey(self):
|
||||
"""
|
||||
High level function which returns
|
||||
curve(2) + len_of_privkey(2) + privkey
|
||||
"""
|
||||
return b''.join((pack('!H', self.curve),
|
||||
pack('!H', len(self.privkey)),
|
||||
self.privkey
|
||||
))
|
||||
|
||||
@staticmethod
|
||||
def _decode_pubkey(pubkey):
|
||||
i = 0
|
||||
curve = unpack('!H', pubkey[i:i + 2])[0]
|
||||
i += 2
|
||||
tmplen = unpack('!H', pubkey[i:i + 2])[0]
|
||||
i += 2
|
||||
pubkey_x = pubkey[i:i + tmplen]
|
||||
i += tmplen
|
||||
tmplen = unpack('!H', pubkey[i:i + 2])[0]
|
||||
i += 2
|
||||
pubkey_y = pubkey[i:i + tmplen]
|
||||
i += tmplen
|
||||
return curve, pubkey_x, pubkey_y, i
|
||||
|
||||
@staticmethod
|
||||
def _decode_privkey(privkey):
|
||||
i = 0
|
||||
curve = unpack('!H', privkey[i:i + 2])[0]
|
||||
|