Mobile message & behavior bitfield support #808

Open
kyucrane wants to merge 3 commits from kyucrane/mobileRecv into master
11 changed files with 137 additions and 35 deletions

View File

@ -220,24 +220,34 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
elif len(params) == 1:
label, = params
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 2:
label, eighteenByteRipe = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 3:
label, eighteenByteRipe, totalDifficulty = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 4:
label, eighteenByteRipe, totalDifficulty, smallMessageDifficulty = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = int(
shared.networkDefaultPayloadLengthExtraBytes * smallMessageDifficulty)
elif len(params) == 5:
label, eighteenByteRipe, totalDifficulty, smallMessageDifficulty, behaviorBits = params
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = int(
@ -252,7 +262,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
shared.apiAddressGeneratorReturnQueue.queue.clear()
streamNumberForAddress = 1
shared.addressGeneratorQueue.put((
'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes))
'createRandomAddress', 4, streamNumberForAddress, label, 1, "", eighteenByteRipe, behaviorBits, nonceTrialsPerByte, payloadLengthExtraBytes))
return shared.apiAddressGeneratorReturnQueue.get()
def HandleCreateDeterministicAddresses(self, params):
@ -264,6 +274,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
addressVersionNumber = 0
streamNumber = 0
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
@ -273,6 +284,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
addressVersionNumber = 0
streamNumber = 0
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
@ -281,6 +293,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
passphrase, numberOfAddresses, addressVersionNumber = params
streamNumber = 0
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
@ -288,24 +301,34 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
elif len(params) == 4:
passphrase, numberOfAddresses, addressVersionNumber, streamNumber = params
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 5:
passphrase, numberOfAddresses, addressVersionNumber, streamNumber, eighteenByteRipe = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = shared.config.get(
'bitmessagesettings', 'defaultnoncetrialsperbyte')
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 6:
passphrase, numberOfAddresses, addressVersionNumber, streamNumber, eighteenByteRipe, totalDifficulty = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = shared.config.get(
'bitmessagesettings', 'defaultpayloadlengthextrabytes')
elif len(params) == 7:
passphrase, numberOfAddresses, addressVersionNumber, streamNumber, eighteenByteRipe, totalDifficulty, smallMessageDifficulty = params
behaviorBits = shared.BEHAVIOR_SENDACK,
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = int(
shared.networkDefaultPayloadLengthExtraBytes * smallMessageDifficulty)
elif len(params) == 8:
passphrase, numberOfAddresses, addressVersionNumber, streamNumber, eighteenByteRipe, totalDifficulty, smallMessageDifficulty, behaviorBits = params
nonceTrialsPerByte = int(
shared.networkDefaultProofOfWorkNonceTrialsPerByte * totalDifficulty)
payloadLengthExtraBytes = int(
@ -333,7 +356,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
logger.debug('Requesting that the addressGenerator create %s addresses.', numberOfAddresses)
shared.addressGeneratorQueue.put(
('createDeterministicAddresses', addressVersionNumber, streamNumber,
'unused API address', numberOfAddresses, passphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes))
'unused API address', numberOfAddresses, passphrase, eighteenByteRipe, behaviorBits, nonceTrialsPerByte, payloadLengthExtraBytes))
data = '{"addresses":['
queueReturn = shared.apiAddressGeneratorReturnQueue.get()
for item in queueReturn:
@ -349,6 +372,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
passphrase, addressVersionNumber, streamNumber = params
numberOfAddresses = 1
eighteenByteRipe = False
behaviorBits = shared.BEHAVIOR_SENDACK,
if len(passphrase) == 0:
raise APIError(1, 'The specified passphrase is blank.')
passphrase = self._decode(passphrase, "base64")
@ -360,7 +384,7 @@ class MySimpleXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
logger.debug('Requesting that the addressGenerator create %s addresses.', numberOfAddresses)
shared.addressGeneratorQueue.put(
('getDeterministicAddress', addressVersionNumber,
streamNumber, 'unused API address', numberOfAddresses, passphrase, eighteenByteRipe))
streamNumber, 'unused API address', numberOfAddresses, passphrase, eighteenByteRipe, behaviorBits))
return shared.apiAddressGeneratorReturnQueue.get()
def HandleCreateChan(self, params):

View File

@ -427,11 +427,15 @@ def handlech(c, stdscr):
if r == d.DIALOG_OK:
stream = decodeAddress(addrs[int(t)][1])[2]
shorten = False
behaviorBits = shared.BEHAVIOR_SENDACK,
r, t = d.checklist("Miscellaneous options",
choices=[("1", "Spend time shortening the address", shorten)])
if r == d.DIALOG_OK and "1" in t:
shorten = True
shared.addressGeneratorQueue.put(("createRandomAddress", 4, stream, label, 1, "", shorten))
choices=[("1", "Spend time shortening the address", shorten), ("2", "Create a mobile address")])
if r == d.DIALOG_OK:
if "1" in t:
shorten = True
if "2" in t:
behaviorBits += shared.BEHAVIOR_NEEDRIPE,
shared.addressGeneratorQueue.put(("createRandomAddress", 4, stream, label, 1, "", shorten, behaviorBits))
elif t == "2":
d.set_background_title("Make deterministic addresses")
r, t = d.passwordform("Enter passphrase",
@ -447,15 +451,19 @@ def handlech(c, stdscr):
number = t
stream = 1
shorten = False
behaviorBits = shared.BEHAVIOR_SENDACK,
r, t = d.checklist("Miscellaneous options",
choices=[("1", "Spend time shortening the address", shorten)])
if r == d.DIALOG_OK and "1" in t:
shorten = True
choices=[("1", "Spend time shortening the address", shorten), ("2", "Create a mobile address")])
if r == d.DIALOG_OK:
if "1" in t:
shorten = True
if "2" in t:
behaviorBits += shared.BEHAVIOR_NEEDRIPE,
d.scrollbox(unicode("In addition to your passphrase, be sure to remember the following numbers:\n"
"\n * Address version number: "+str(4)+"\n"
" * Stream number: "+str(stream)),
exit_label="Continue")
shared.addressGeneratorQueue.put(('createDeterministicAddresses', 4, stream, "unused deterministic address", number, str(passphrase), shorten))
shared.addressGeneratorQueue.put(('createDeterministicAddresses', 4, stream, "unused deterministic address", number, str(passphrase), shorten, behaviorBits))
else:
d.scrollbox(unicode("Passphrases do not match"), exit_label="Continue")
elif t == "2": # Send a message

View File

@ -1405,8 +1405,11 @@ class MyForm(QtGui.QMainWindow):
QMessageBox.about(self, _translate("MainWindow", "Bad address version number"), _translate(
"MainWindow", "Your address version number must be either 3 or 4."))
return
behaviorBits = shared.BEHAVIOR_SENDACK,
if self.dialog.ui.checkBoxMobile.isChecked():
behaviorBits += shared.BEHAVIOR_NEEDRIPE,
shared.addressGeneratorQueue.put(('createDeterministicAddresses', addressVersionNumber, streamNumberForAddress, "regenerated deterministic address", self.regenerateAddressesDialogInstance.ui.spinBoxNumberOfAddressesToMake.value(
), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked()))
), self.regenerateAddressesDialogInstance.ui.lineEditPassphrase.text().toUtf8(), self.regenerateAddressesDialogInstance.ui.checkBoxEighteenByteRipe.isChecked(), behaviorBits))
self.ui.tabWidget.setCurrentIndex(3)
def click_actionJoinChan(self):
@ -2635,8 +2638,11 @@ more work your computer must do to send the message. A Time-To-Live of four or f
# address.'
streamNumberForAddress = decodeAddress(
self.dialog.ui.comboBoxExisting.currentText())[2]
behaviorBits = shared.BEHAVIOR_SENDACK,
if self.dialog.ui.checkBoxMobile.isChecked():
behaviorBits += shared.BEHAVIOR_NEEDRIPE,
shared.addressGeneratorQueue.put(('createRandomAddress', 4, streamNumberForAddress, str(
self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
self.dialog.ui.newaddresslabel.text().toUtf8()), 1, "", self.dialog.ui.checkBoxEighteenByteRipe.isChecked(), behaviorBits))
else:
if self.dialog.ui.lineEditPassphrase.text() != self.dialog.ui.lineEditPassphraseAgain.text():
QMessageBox.about(self, _translate("MainWindow", "Passphrase mismatch"), _translate(
@ -2646,8 +2652,11 @@ more work your computer must do to send the message. A Time-To-Live of four or f
"MainWindow", "Choose a passphrase"), _translate("MainWindow", "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.
behaviorBits = shared.BEHAVIOR_SENDACK,
if self.dialog.ui.checkBoxMobile.isChecked():
behaviorBits += shared.BEHAVIOR_NEEDRIPE,
shared.addressGeneratorQueue.put(('createDeterministicAddresses', 4, streamNumberForAddress, "unused deterministic address", self.dialog.ui.spinBoxNumberOfAddressesToMake.value(
), self.dialog.ui.lineEditPassphrase.text().toUtf8(), self.dialog.ui.checkBoxEighteenByteRipe.isChecked()))
), self.dialog.ui.lineEditPassphrase.text().toUtf8(), self.dialog.ui.checkBoxEighteenByteRipe.isChecked(), behaviorBits))
else:
print 'new address dialog box rejected'

View File

@ -64,6 +64,9 @@ class Ui_NewAddressDialog(object):
self.checkBoxEighteenByteRipe = QtGui.QCheckBox(NewAddressDialog)
self.checkBoxEighteenByteRipe.setObjectName(_fromUtf8("checkBoxEighteenByteRipe"))
self.formLayout.setWidget(9, QtGui.QFormLayout.SpanningRole, self.checkBoxEighteenByteRipe)
self.checkBoxMobile = QtGui.QCheckBox(NewAddressDialog)
self.checkBoxMobile.setObjectName(_fromUtf8("checkBoxMobile"))
self.formLayout.setWidget(10, QtGui.QFormLayout.SpanningRole, self.checkBoxMobile)
self.groupBoxDeterministic = QtGui.QGroupBox(NewAddressDialog)
self.groupBoxDeterministic.setObjectName(_fromUtf8("groupBoxDeterministic"))
self.gridLayout = QtGui.QGridLayout(self.groupBoxDeterministic)
@ -149,7 +152,7 @@ class Ui_NewAddressDialog(object):
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.formLayout.setWidget(11, QtGui.QFormLayout.SpanningRole, self.buttonBox)
self.retranslateUi(NewAddressDialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), NewAddressDialog.accept)
@ -167,7 +170,8 @@ class Ui_NewAddressDialog(object):
NewAddressDialog.setTabOrder(self.lineEditPassphrase, self.lineEditPassphraseAgain)
NewAddressDialog.setTabOrder(self.lineEditPassphraseAgain, self.spinBoxNumberOfAddressesToMake)
NewAddressDialog.setTabOrder(self.spinBoxNumberOfAddressesToMake, self.checkBoxEighteenByteRipe)
NewAddressDialog.setTabOrder(self.checkBoxEighteenByteRipe, self.buttonBox)
NewAddressDialog.setTabOrder(self.checkBoxEighteenByteRipe, self.checkBoxMobile)
NewAddressDialog.setTabOrder(self.checkBoxMobile, self.buttonBox)
def retranslateUi(self, NewAddressDialog):
NewAddressDialog.setWindowTitle(_translate("NewAddressDialog", "Create new Address", None))
@ -177,6 +181,7 @@ class Ui_NewAddressDialog(object):
self.radioButtonRandomAddress.setText(_translate("NewAddressDialog", "Use a random number generator to make an address", None))
self.radioButtonDeterministicAddress.setText(_translate("NewAddressDialog", "Use a passphrase to make addresses", None))
self.checkBoxEighteenByteRipe.setText(_translate("NewAddressDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None))
self.checkBoxMobile.setText(_translate("NewAddressDialog", "Require messages sent to you include your address unencrypted (saves resources, for mobile)", None))
self.groupBoxDeterministic.setTitle(_translate("NewAddressDialog", "Make deterministic addresses", None))
self.label_9.setText(_translate("NewAddressDialog", "Address version number: 4", None))
self.label_8.setText(_translate("NewAddressDialog", "In addition to your passphrase, you must remember these numbers:", None))

View File

@ -90,6 +90,13 @@ The 'Random Number' option is selected by default but deterministic addresses ha
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QCheckBox" name="checkBoxMobile">
<property name="text">
<string>Require messages sent to you include your address(es) unencrypted (saves resources, for mobile)</string>
</propert>
</widget>
</item>
<item row="8" column="0">
<widget class="QGroupBox" name="groupBoxDeterministic">
<property name="title">
@ -284,7 +291,7 @@ The 'Random Number' option is selected by default but deterministic addresses ha
<zorder>horizontalSpacer_3</zorder>
</widget>
</item>
<item row="10" column="0" colspan="2">
<item row="11" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">

View File

@ -94,11 +94,14 @@ class Ui_regenerateAddressesDialog(object):
self.gridLayout.addItem(spacerItem2, 5, 2, 1, 3)
self.checkBoxEighteenByteRipe = QtGui.QCheckBox(self.groupBox)
self.checkBoxEighteenByteRipe.setObjectName(_fromUtf8("checkBoxEighteenByteRipe"))
self.gridLayout.addWidget(self.checkBoxEighteenByteRipe, 6, 0, 1, 5)
self.gridLayout.addWidget(self.checkBoxEighteenByteRipe, 7, 0, 1, 5)
self.checkBoxMobile = QtGui.QCheckBox(self.groupBox)
self.checkBoxMobile.setObjectName(_fromUtf8("checkBoxMobile"))
self.gridLayout.addWidget(self.checkBoxMobile, 6, 0, 1, 5)
self.label_4 = QtGui.QLabel(self.groupBox)
self.label_4.setWordWrap(True)
self.label_4.setObjectName(_fromUtf8("label_4"))
self.gridLayout.addWidget(self.label_4, 7, 0, 1, 5)
self.gridLayout.addWidget(self.label_4, 8, 0, 1, 5)
self.label = QtGui.QLabel(self.groupBox)
self.label.setWordWrap(True)
self.label.setObjectName(_fromUtf8("label"))
@ -119,6 +122,7 @@ class Ui_regenerateAddressesDialog(object):
self.label_3.setText(_translate("regenerateAddressesDialog", "Stream number:", None))
self.lineEditStreamNumber.setText(_translate("regenerateAddressesDialog", "1", None))
self.checkBoxEighteenByteRipe.setText(_translate("regenerateAddressesDialog", "Spend several minutes of extra computing time to make the address(es) 1 or 2 characters shorter", None))
self.checkBoxMobile.setText(_translate("regenerateAddressesDialog", "Require messages sent to you include your address(es) unencrypted (saves resources, for mobile)", None))
self.label_4.setText(_translate("regenerateAddressesDialog", "You must check (or not check) this box just like you did (or didn\'t) when you made your addresses the first time.", None))
self.label.setText(_translate("regenerateAddressesDialog", "If you have previously made deterministic addresses but lost them due to an accident (like hard drive failure), you can regenerate them here. If you used the random number generator to make your addresses then this form will be of no use to you.", None))

View File

@ -168,13 +168,20 @@
</spacer>
</item>
<item row="6" column="0" colspan="5">
<widget class="QCheckBox" name="checkBoxMobile">
<property name="text">
<string>Require messages sent to you include your address(es) unencrypted (saves resources, for mobile)</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="5">
<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="7" column="0" colspan="5">
<item row="8" column="0" colspan="5">
<widget class="QLabel" name="label_4">
<property name="text">
<string>You must check (or not check) this box just like you did (or didn't) when you made your addresses the first time.</string>

View File

@ -25,17 +25,19 @@ class addressGenerator(threading.Thread):
if queueValue[0] == 'createChan':
command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
eighteenByteRipe = False
behaviorBits = ()
numberOfAddressesToMake = 1
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
elif queueValue[0] == 'joinChan':
command, chanAddress, label, deterministicPassphrase = queueValue
eighteenByteRipe = False
behaviorBits = ()
addressVersionNumber = decodeAddress(chanAddress)[1]
streamNumber = decodeAddress(chanAddress)[2]
numberOfAddressesToMake = 1
numberOfNullBytesDemandedOnFrontOfRipeHash = 1
elif len(queueValue) == 7:
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue
elif len(queueValue) == 8:
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, behaviorBits = queueValue
try:
numberOfNullBytesDemandedOnFrontOfRipeHash = shared.config.getint(
'bitmessagesettings', 'numberofnullbytesonaddress')
@ -44,8 +46,8 @@ class addressGenerator(threading.Thread):
numberOfNullBytesDemandedOnFrontOfRipeHash = 2
else:
numberOfNullBytesDemandedOnFrontOfRipeHash = 1 # the default
elif len(queueValue) == 9:
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue
elif len(queueValue) == 10:
command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, behaviorBits, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue
try:
numberOfNullBytesDemandedOnFrontOfRipeHash = shared.config.getint(
'bitmessagesettings', 'numberofnullbytesonaddress')
@ -119,6 +121,7 @@ class addressGenerator(threading.Thread):
shared.config.set(address, 'label', label)
shared.config.set(address, 'enabled', 'true')
shared.config.set(address, 'decoy', 'false')
shared.setConfigFromBehaviorBitfield(address, shared.createBitfield(*behaviorBits))
shared.config.set(address, 'noncetrialsperbyte', str(
nonceTrialsPerByte))
shared.config.set(address, 'payloadlengthextrabytes', str(
@ -236,6 +239,7 @@ class addressGenerator(threading.Thread):
shared.config.set(address, 'label', label)
shared.config.set(address, 'enabled', 'true')
shared.config.set(address, 'decoy', 'false')
shared.setConfigFromBehaviorBitfield(address, shared.createBitfield(*behaviorBits))
if command == 'joinChan' or command == 'createChan':
shared.config.set(address, 'chan', 'true')
shared.config.set(address, 'noncetrialsperbyte', str(

View File

@ -342,7 +342,12 @@ class objectProcessor(threading.Thread):
for key, cryptorObject in shared.myECCryptorObjects.items():
try:
decryptedData = cryptorObject.decrypt(data[readPosition:])
mobileRipe = key.lstrip('\x00')
if data[readPosition:readPosition+len(mobileRipe)] == mobileRipe:
decryptedData = cryptorObject.decrypt(data[readPosition+len(mobileRipe):])
logger.info('Received a mobile message containing our unencrypted address.')
else:
decryptedData = cryptorObject.decrypt(data[readPosition:])
toRipe = key # This is the RIPE hash of my pubkeys. We need this below to compare to the destination_ripe included in the encrypted data.
initialDecryptionSuccessful = True
logger.info('EC decryption successful using key associated with ripe hash: %s.' % key.encode('hex'))
@ -575,7 +580,10 @@ class objectProcessor(threading.Thread):
shared.workerQueue.put(('sendbroadcast', ''))
if self.ackDataHasAVaildHeader(ackData):
shared.checkAndShareObjectWithPeers(ackData[24:])
if shared.config.getboolean(toAddress, 'notsendack'):
logger.info('Ack data was provided even though we do not send it. Ignoring.')
else:
shared.checkAndShareObjectWithPeers(ackData[24:])
# Display timing data
timeRequiredToAttemptToDecryptMessage = time.time(

View File

@ -106,7 +106,7 @@ class singleWorker(threading.Thread):
payload += '\x00\x00\x00\x01' # object type: pubkey
payload += encodeVarint(addressVersionNumber) # Address version number
payload += encodeVarint(streamNumber)
payload += '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
payload += shared.createBehaviorBitfieldFromConfig(myAddress) # bitfield of features supported by me (see the wiki).
try:
privSigningKeyBase58 = shared.config.get(
@ -191,7 +191,7 @@ class singleWorker(threading.Thread):
payload += '\x00\x00\x00\x01' # object type: pubkey
payload += encodeVarint(addressVersionNumber) # Address version number
payload += encodeVarint(streamNumber)
payload += '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
payload += shared.createBehaviorBitfieldFromConfig(myAddress) # bitfield of features supported by me (see the wiki).
try:
privSigningKeyBase58 = shared.config.get(
@ -277,7 +277,7 @@ class singleWorker(threading.Thread):
payload += encodeVarint(addressVersionNumber) # Address version number
payload += encodeVarint(streamNumber)
dataToEncrypt = '\x00\x00\x00\x01' # bitfield of features supported by me (see the wiki).
dataToEncrypt = shared.createBehaviorBitfieldFromConfig(myAddress) # bitfield of features supported by me (see the wiki).
try:
privSigningKeyBase58 = shared.config.get(
@ -410,7 +410,7 @@ class singleWorker(threading.Thread):
dataToEncrypt = encodeVarint(addressVersionNumber)
dataToEncrypt += encodeVarint(streamNumber)
dataToEncrypt += '\x00\x00\x00\x01' # behavior bitfield
dataToEncrypt += shared.createBehaviorBitfieldFromConfig(fromaddress) # behavior bitfield
dataToEncrypt += pubSigningKey[1:]
dataToEncrypt += pubEncryptionKey[1:]
if addressVersionNumber >= 3:
@ -641,7 +641,7 @@ class singleWorker(threading.Thread):
# Mobile users may ask us to include their address's RIPE hash on a message
# unencrypted. Before we actually do it the sending human must check a box
# in the settings menu to allow it.
if shared.isBitSetWithinBitfield(behaviorBitfield,30): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
if shared.isBitSetWithinBitfield(behaviorBitfield,shared.BEHAVIOR_NEEDRIPE): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
if not shared.safeConfigGetBoolean('bitmessagesettings','willinglysendtomobile'): # if we are Not willing to include the receiver's RIPE hash on the message..
logger.info('The receiver is a mobile user but the sender (you) has not selected that you are willing to send to mobiles. Aborting send.')
shared.UISignalQueue.put(('updateSentItemStatusByAckdata',(ackdata,tr.translateText("MainWindow",'Problem: Destination is a mobile device who requests that the destination be included in the message but this is disallowed in your settings. %1').arg(l10n.formatTimestamp()))))
@ -687,7 +687,7 @@ class singleWorker(threading.Thread):
else: # if we are sending a message to ourselves or a chan..
with shared.printLock:
print 'Sending a message. First 150 characters of message:', repr(message[:150])
behaviorBitfield = '\x00\x00\x00\x01'
behaviorBitfield = shared.createBehaviorBitfieldFromConfig(toaddress)
try:
privEncryptionKeyBase58 = shared.config.get(
@ -710,7 +710,7 @@ class singleWorker(threading.Thread):
# Now we can start to assemble our message.
payload = encodeVarint(fromAddressVersionNumber)
payload += encodeVarint(fromStreamNumber)
payload += '\x00\x00\x00\x01' # Bitfield of features and behaviors that can be expected from me. (See https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features )
payload += shared.createBehaviorBitfieldFromConfig(fromaddress) # Bitfield of features and behaviors that can be expected from me. (See https://bitmessage.org/wiki/Protocol_specification#Pubkey_bitfield_features )
# We need to convert our private keys to public keys in order
# to include them.
@ -764,7 +764,7 @@ class singleWorker(threading.Thread):
with shared.printLock:
print 'Not bothering to include ackdata because we are sending to ourselves or a chan.'
fullAckPayload = ''
elif not shared.isBitSetWithinBitfield(behaviorBitfield,31):
elif not shared.isBitSetWithinBitfield(behaviorBitfield,shared.BEHAVIOR_SENDACK):
with shared.printLock:
print 'Not bothering to include ackdata because the receiver said that they won\'t relay it anyway.'
fullAckPayload = ''
@ -789,7 +789,10 @@ class singleWorker(threading.Thread):
encryptedPayload = pack('>Q', embeddedTime)
encryptedPayload += '\x00\x00\x00\x02' # object type: msg
encryptedPayload += encodeVarint(1) # msg version
encryptedPayload += encodeVarint(toStreamNumber) + encrypted
encryptedPayload += encodeVarint(toStreamNumber)
if shared.isBitSetWithinBitfield(behaviorBitfield,shared.BEHAVIOR_NEEDRIPE): # if receiver is a mobile device who expects that their address RIPE is included unencrypted on the front of the message..
encryptedPayload += toRipe.lstrip('\x00')
encryptedPayload += encrypted
target = 2 ** 64 / (requiredAverageProofOfWorkNonceTrialsPerByte*(len(encryptedPayload) + 8 + requiredPayloadLengthExtraBytes + ((TTL*(len(encryptedPayload)+8+requiredPayloadLengthExtraBytes))/(2 ** 16))))
with shared.printLock:
print '(For msg message) Doing proof of work. Total required difficulty:', float(requiredAverageProofOfWorkNonceTrialsPerByte) / shared.networkDefaultProofOfWorkNonceTrialsPerByte, 'Required small message difficulty:', float(requiredPayloadLengthExtraBytes) / shared.networkDefaultPayloadLengthExtraBytes

View File

@ -116,6 +116,10 @@ frozen = getattr(sys,'frozen', None)
# security.
trustedPeer = None
# Behavior bitfield constants
BEHAVIOR_SENDACK = 31
BEHAVIOR_NEEDRIPE = 30
#Compiled struct for packing/unpacking headers
#New code should use CreatePacket instead of Header.pack
Header = Struct('!L12sL4s')
@ -473,6 +477,25 @@ def isBitSetWithinBitfield(fourByteString, n):
x, = unpack('>L', fourByteString)
return x & 2**n != 0
def createBitfield(*fields):
x = 0
for n in fields:
n = 31 - n
x |= 2**n
return pack('>L', x)
def createBehaviorBitfieldFromConfig(myAddress):
fields = ()
if not config.getboolean(myAddress, 'notsendack'):
fields += BEHAVIOR_SENDACK,
if config.getboolean(myAddress, 'needripe'):
fields += BEHAVIOR_NEEDRIPE,
return createBitfield(*fields)
def setConfigFromBehaviorBitfield(address, bitfield):
config.set(address, 'notsendack', str(not isBitSetWithinBitfield(bitfield, BEHAVIOR_SENDACK)))
config.set(address, 'needripe', str(isBitSetWithinBitfield(bitfield, BEHAVIOR_NEEDRIPE)))
def decryptAndCheckPubkeyPayload(data, address):
"""