Example #1
0
def reloadBroadcastSendersForWhichImWatching():
    """
    Reinitialize runtime data for the broadcasts I'm subscribed to
    from the config file
    """
    broadcastSendersForWhichImWatching.clear()
    MyECSubscriptionCryptorObjects.clear()
    queryreturn = sqlQuery('SELECT address FROM subscriptions where enabled=1')
    logger.debug('reloading subscriptions...')
    for row in queryreturn:
        address, = row
        # status
        addressVersionNumber, streamNumber, hashobj = decodeAddress(
            address)[1:]
        if addressVersionNumber == 2:
            broadcastSendersForWhichImWatching[hashobj] = 0
        # Now, for all addresses, even version 2 addresses,
        # we should create Cryptor objects in a dictionary which we will
        # use to attempt to decrypt encrypted broadcast messages.

        if addressVersionNumber <= 3:
            privEncryptionKey = hashlib.sha512(
                encodeVarint(addressVersionNumber) +
                encodeVarint(streamNumber) + hashobj).digest()[:32]
            MyECSubscriptionCryptorObjects[hashobj] = \
                highlevelcrypto.makeCryptor(hexlify(privEncryptionKey))
        else:
            doubleHashOfAddressData = hashlib.sha512(
                hashlib.sha512(
                    encodeVarint(addressVersionNumber) +
                    encodeVarint(streamNumber) + hashobj).digest()).digest()
            tag = doubleHashOfAddressData[32:]
            privEncryptionKey = doubleHashOfAddressData[:32]
            MyECSubscriptionCryptorObjects[tag] = \
                highlevelcrypto.makeCryptor(hexlify(privEncryptionKey))
Example #2
0
def reloadBroadcastSendersForWhichImWatching():
    broadcastSendersForWhichImWatching.clear()
    MyECSubscriptionCryptorObjects.clear()
    queryreturn = sqlQuery('SELECT address FROM subscriptions where enabled=1')
    logger.debug('reloading subscriptions...')
    for row in queryreturn:
        address, = row
        status, addressVersionNumber, streamNumber, hash = decodeAddress(
            address)
        if addressVersionNumber == 2:
            broadcastSendersForWhichImWatching[hash] = 0
        #Now, for all addresses, even version 2 addresses, we should create Cryptor objects in a dictionary which we will use to attempt to decrypt encrypted broadcast messages.

        if addressVersionNumber <= 3:
            privEncryptionKey = hashlib.sha512(
                encodeVarint(addressVersionNumber) +
                encodeVarint(streamNumber) + hash).digest()[:32]
            MyECSubscriptionCryptorObjects[hash] = highlevelcrypto.makeCryptor(
                privEncryptionKey.encode('hex'))
        else:
            doubleHashOfAddressData = hashlib.sha512(
                hashlib.sha512(
                    encodeVarint(addressVersionNumber) +
                    encodeVarint(streamNumber) + hash).digest()).digest()
            tag = doubleHashOfAddressData[32:]
            privEncryptionKey = doubleHashOfAddressData[:32]
            MyECSubscriptionCryptorObjects[tag] = highlevelcrypto.makeCryptor(
                privEncryptionKey.encode('hex'))
Example #3
0
def reloadBroadcastSendersForWhichImWatching():
    broadcastSendersForWhichImWatching.clear()
    MyECSubscriptionCryptorObjects.clear()
    queryreturn = sqlQuery('SELECT address FROM subscriptions where enabled=1')
    logger.debug('reloading subscriptions...')
    for row in queryreturn:
        address, = row
        status, addressVersionNumber, streamNumber, hash = decodeAddress(address)
        if addressVersionNumber == 2:
            broadcastSendersForWhichImWatching[hash] = 0

        # Now, for all addresses, even version 2 addresses,
        # we should create Cryptor objects in a dictionary
        # which we will use to attempt to decrypt encrypted broadcast messages.

        if addressVersionNumber <= 3:
            privEncryptionKey = hashlib.sha512(encodeVarint(addressVersionNumber) +
                                               encodeVarint(streamNumber) + hash).digest()[:32]
            MyECSubscriptionCryptorObjects[hash] = highlevelcrypto.makeCryptor(hexlify(privEncryptionKey))
        else:
            doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
                addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()
            tag = doubleHashOfAddressData[32:]
            privEncryptionKey = doubleHashOfAddressData[:32]
            MyECSubscriptionCryptorObjects[tag] = highlevelcrypto.makeCryptor(hexlify(privEncryptionKey))
Example #4
0
def reloadMyAddressHashes():
    logger.debug('reloading keys from keys.dat file')
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    #myPrivateKeys.clear()

    keyfileSecure = checkSensitiveFilePermissions(appdata + 'keys.dat')
    configSections = config.sections()
    hasEnabledKeys = False
    for addressInKeysFile in configSections:
        if addressInKeysFile <> 'bitmessagesettings':
            isEnabled = config.getboolean(addressInKeysFile, 'enabled')
            if isEnabled:
                hasEnabledKeys = True
                status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
                    # Returns a simple 32 bytes of information encoded in 64 Hex characters,
                    # or null if there was an error.
                    privEncryptionKey = decodeWalletImportFormat(
                            config.get(addressInKeysFile, 'privencryptionkey')).encode('hex')

                    if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile

                else:
                    logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n')

    if not keyfileSecure:
        fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
Example #5
0
def reloadMyAddressHashes():
    logger.debug('reloading keys from keys.dat file')
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    myAddressesByTag.clear()
    #myPrivateKeys.clear()

    keyfileSecure = checkSensitiveFilePermissions(appdata + 'keys.dat')
    configSections = config.sections()
    hasEnabledKeys = False
    for addressInKeysFile in configSections:
        if addressInKeysFile <> 'bitmessagesettings':
            isEnabled = config.getboolean(addressInKeysFile, 'enabled')
            if isEnabled:
                hasEnabledKeys = True
                status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
                    # Returns a simple 32 bytes of information encoded in 64 Hex characters,
                    # or null if there was an error.
                    privEncryptionKey = decodeWalletImportFormat(
                            config.get(addressInKeysFile, 'privencryptionkey')).encode('hex')

                    if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile
                        tag = hashlib.sha512(hashlib.sha512(encodeVarint(
                            addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()[32:]
                        myAddressesByTag[tag] = addressInKeysFile

                else:
                    logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n')

    if not keyfileSecure:
        fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
Example #6
0
def reloadMyAddressHashes():
    logger.debug("reloading keys from keys.dat file")
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    # myPrivateKeys.clear()

    keyfileSecure = checkSensitiveFilePermissions(appdata + "keys.dat")
    configSections = config.sections()
    hasEnabledKeys = False
    for addressInKeysFile in configSections:
        if addressInKeysFile <> "bitmessagesettings":
            isEnabled = config.getboolean(addressInKeysFile, "enabled")
            if isEnabled:
                hasEnabledKeys = True
                status, addressVersionNumber, streamNumber, hash = decodeAddress(addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
                    # Returns a simple 32 bytes of information encoded in 64 Hex characters,
                    # or null if there was an error.
                    privEncryptionKey = decodeWalletImportFormat(
                        config.get(addressInKeysFile, "privencryptionkey")
                    ).encode("hex")

                    if len(privEncryptionKey) == 64:  # It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile

                else:
                    logger.error(
                        "Error in reloadMyAddressHashes: Can't handle address versions other than 2, 3, or 4.\n"
                    )

    if not keyfileSecure:
        fixSensitiveFilePermissions(appdata + "keys.dat", hasEnabledKeys)
Example #7
0
def reloadMyAddressHashes():
    logger.debug('reloading keys from keys.dat file')
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    myAddressesByTag.clear()
    #myPrivateKeys.clear()

    keyfileSecure = checkSensitiveFilePermissions(state.appdata + 'keys.dat')
    hasEnabledKeys = False
    for addressInKeysFile in BMConfigParser().addresses():
        isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
        if isEnabled:
            hasEnabledKeys = True
            status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
            if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
                # Returns a simple 32 bytes of information encoded in 64 Hex characters,
                # or null if there was an error.
                privEncryptionKey = hexlify(decodeWalletImportFormat(
                        BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))

                if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters
                    myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
                    myAddressesByHash[hash] = addressInKeysFile
                    tag = hashlib.sha512(hashlib.sha512(encodeVarint(
                        addressVersionNumber) + encodeVarint(streamNumber) + hash).digest()).digest()[32:]
                    myAddressesByTag[tag] = addressInKeysFile

            else:
                logger.error('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2, 3, or 4.\n')

    if not keyfileSecure:
        fixSensitiveFilePermissions(state.appdata + 'keys.dat', hasEnabledKeys)
Example #8
0
def reloadMyAddressHashes():
    printLock.acquire()
    print 'reloading keys from keys.dat file'
    printLock.release()
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    #myPrivateKeys.clear()
    configSections = config.sections()
    for addressInKeysFile in configSections:
        if addressInKeysFile <> 'bitmessagesettings':
            isEnabled = config.getboolean(addressInKeysFile, 'enabled')
            if isEnabled:
                status, addressVersionNumber, streamNumber, hash = decodeAddress(
                    addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3:
                    privEncryptionKey = decodeWalletImportFormat(
                        config.get(addressInKeysFile, 'privencryptionkey')
                    ).encode(
                        'hex'
                    )  #returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error
                    if len(
                            privEncryptionKey
                    ) == 64:  #It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(
                            privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile
                else:
                    sys.stderr.write(
                        'Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n'
                    )
Example #9
0
def reloadBroadcastSendersForWhichImWatching():
    logger.debug('reloading subscriptions...')
    broadcastSendersForWhichImWatching.clear()
    MyECSubscriptionCryptorObjects.clear()
    sqlLock.acquire()
    sqlSubmitQueue.put('SELECT address FROM subscriptions where enabled=1')
    sqlSubmitQueue.put('')
    queryreturn = sqlReturnQueue.get()
    sqlLock.release()
    for row in queryreturn:
        address, = row
        status,addressVersionNumber,streamNumber,hash = decodeAddress(address)
        if addressVersionNumber == 2:
            broadcastSendersForWhichImWatching[hash] = 0
        #Now, for all addresses, even version 2 addresses, we should create Cryptor objects in a dictionary which we will use to attempt to decrypt encrypted broadcast messages.
        privEncryptionKey = hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+hash).digest()[:32]
        MyECSubscriptionCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))
Example #10
0
def reloadMyAddressHashes():
    logger.debug('reloading keys from keys.dat file')
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    #myPrivateKeys.clear()
    configSections = config.sections()
    for addressInKeysFile in configSections:
        if addressInKeysFile <> 'bitmessagesettings':
            isEnabled = config.getboolean(addressInKeysFile, 'enabled')
            if isEnabled:
                status,addressVersionNumber,streamNumber,hash = decodeAddress(addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3:
                    privEncryptionKey = decodeWalletImportFormat(config.get(addressInKeysFile, 'privencryptionkey')).encode('hex') #returns a simple 32 bytes of information encoded in 64 Hex characters, or null if there was an error
                    if len(privEncryptionKey) == 64:#It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile
                else:
                    sys.stderr.write('Error in reloadMyAddressHashes: Can\'t handle address versions other than 2 or 3.\n')
    def missing_public_key(self, address ):
        PUBKEY_REQUEST_WAIT_SECONDS = 60 * 60 * 24
        last_request_time = self.settings_get_pubkey_last_request_time( address )
        if last_request_time is not None and last_request_time > time.time() - PUBKEY_REQUEST_WAIT_SECONDS:
            # We requested this pubkey recently, so let's not do it again right now
            
            # However, we need to put the tag in neededPubkeys in case the user just restarted the client
            _, addressVersionNumber, streamNumber, ripe = decodeAddress(address)
            if addressVersionNumber <= 3:
                shared.neededPubkeys[ripe] = 0
            elif addressVersionNumber >= 4:
                tag = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).digest()).digest()[32:] # Note that this is the second half of the sha512 hash.
                if tag not in shared.neededPubkeys:
                    privEncryptionKey = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).digest()).digest()[:32] # Note that this is the first half of the sha512 hash.
                    import highlevelcrypto
                    shared.neededPubkeys[tag] = (address, highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))) # We'll need this for when we receive a pubkey reply: it will be encrypted and we'll need to decrypt it.

            return 
        
        self.settings_set_pubkey_last_request_time( address, time.time() )
        shared.workerQueue.put( ( "requestPubkey", address ) )
Example #12
0
def reloadMyAddressHashes():
    myECCryptorObjects.clear()
    myAddressesByHash.clear()
    myAddressesByTag.clear()
    #myPrivateKeys.clear()

    keyfileSecure = checkSensitiveFilePermissions(appdata + 'keys.dat')
    configSections = config.sections()
    hasEnabledKeys = False
    for addressInKeysFile in configSections:
        if addressInKeysFile <> 'bitmessagesettings':
            isEnabled = config.getboolean(addressInKeysFile, 'enabled')
            if isEnabled:
                hasEnabledKeys = True
                status, addressVersionNumber, streamNumber, hash = decodeAddress(
                    addressInKeysFile)
                if addressVersionNumber == 2 or addressVersionNumber == 3 or addressVersionNumber == 4:
                    # Returns a simple 32 bytes of information encoded in 64 Hex characters,
                    # or null if there was an error.
                    privEncryptionKey = decodeWalletImportFormat(
                        config.get(addressInKeysFile,
                                   'privencryptionkey')).encode('hex')

                    if len(
                            privEncryptionKey
                    ) == 64:  #It is 32 bytes encoded as 64 hex characters
                        myECCryptorObjects[hash] = highlevelcrypto.makeCryptor(
                            privEncryptionKey)
                        myAddressesByHash[hash] = addressInKeysFile
                        tag = hashlib.sha512(
                            hashlib.sha512(
                                encodeVarint(addressVersionNumber) +
                                encodeVarint(streamNumber) +
                                hash).digest()).digest()[32:]
                        myAddressesByTag[tag] = addressInKeysFile

    if not keyfileSecure:
        fixSensitiveFilePermissions(appdata + 'keys.dat', hasEnabledKeys)
Example #13
0
    def missing_public_key(self, address):
        PUBKEY_REQUEST_WAIT_SECONDS = 60 * 60 * 24
        last_request_time = self.settings_get_pubkey_last_request_time(address)
        if last_request_time is not None and last_request_time > time.time(
        ) - PUBKEY_REQUEST_WAIT_SECONDS:
            # We requested this pubkey recently, so let's not do it again right now

            # However, we need to put the tag in neededPubkeys in case the user just restarted the client
            _, addressVersionNumber, streamNumber, ripe = decodeAddress(
                address)
            if addressVersionNumber <= 3:
                shared.neededPubkeys[ripe] = 0
            elif addressVersionNumber >= 4:
                tag = hashlib.sha512(
                    hashlib.sha512(
                        encodeVarint(addressVersionNumber) +
                        encodeVarint(streamNumber) + ripe).digest()
                ).digest(
                )[32:]  # Note that this is the second half of the sha512 hash.
                if tag not in shared.neededPubkeys:
                    privEncryptionKey = hashlib.sha512(
                        hashlib.sha512(
                            encodeVarint(addressVersionNumber) +
                            encodeVarint(streamNumber) + ripe).digest()
                    ).digest(
                    )[:
                      32]  # Note that this is the first half of the sha512 hash.
                    import highlevelcrypto
                    shared.neededPubkeys[tag] = (
                        address,
                        highlevelcrypto.makeCryptor(
                            privEncryptionKey.encode('hex'))
                    )  # We'll need this for when we receive a pubkey reply: it will be encrypted and we'll need to decrypt it.

            return

        self.settings_set_pubkey_last_request_time(address, time.time())
        shared.workerQueue.put(("requestPubkey", address))
Example #14
0
    def run(self):
        while state.shutdown == 0:
            queueValue = queues.addressGeneratorQueue.get()
            nonceTrialsPerByte = 0
            payloadLengthExtraBytes = 0
            live = True
            if queueValue[0] == 'createChan':
                command, addressVersionNumber, streamNumber, label, \
                    deterministicPassphrase, live = queueValue
                eighteenByteRipe = False
                numberOfAddressesToMake = 1
                numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif queueValue[0] == 'joinChan':
                command, chanAddress, label, deterministicPassphrase, \
                    live = queueValue
                eighteenByteRipe = False
                addressVersionNumber = decodeAddress(chanAddress)[1]
                streamNumber = decodeAddress(chanAddress)[2]
                numberOfAddressesToMake = 1
                numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif len(queueValue) == 7:
                command, addressVersionNumber, streamNumber, label, \
                    numberOfAddressesToMake, deterministicPassphrase, \
                    eighteenByteRipe = queueValue
                try:
                    numberOfNullBytesDemandedOnFrontOfRipeHash = \
                        BMConfigParser().getint(
                            'bitmessagesettings',
                            'numberofnullbytesonaddress'
                        )
                except:
                    if eighteenByteRipe:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 2
                    else:
                        # the default
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif len(queueValue) == 9:
                command, addressVersionNumber, streamNumber, label, \
                    numberOfAddressesToMake, deterministicPassphrase, \
                    eighteenByteRipe, nonceTrialsPerByte, \
                    payloadLengthExtraBytes = queueValue
                try:
                    numberOfNullBytesDemandedOnFrontOfRipeHash = \
                        BMConfigParser().getint(
                            'bitmessagesettings',
                            'numberofnullbytesonaddress'
                        )
                except:
                    if eighteenByteRipe:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 2
                    else:
                        # the default
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif queueValue[0] == 'stopThread':
                break
            else:
                logger.error(
                    'Programming error: A structure with the wrong number'
                    ' of values was passed into the addressGeneratorQueue.'
                    ' Here is the queueValue: %r\n', queueValue)
            if addressVersionNumber < 3 or addressVersionNumber > 4:
                logger.error(
                    'Program error: For some reason the address generator'
                    ' queue has been given a request to create at least'
                    ' one version %s address which it cannot do.\n',
                    addressVersionNumber)
            if nonceTrialsPerByte == 0:
                nonceTrialsPerByte = BMConfigParser().getint(
                    'bitmessagesettings', 'defaultnoncetrialsperbyte')
            if nonceTrialsPerByte < \
                    defaults.networkDefaultProofOfWorkNonceTrialsPerByte:
                nonceTrialsPerByte = \
                    defaults.networkDefaultProofOfWorkNonceTrialsPerByte
            if payloadLengthExtraBytes == 0:
                payloadLengthExtraBytes = BMConfigParser().getint(
                    'bitmessagesettings', 'defaultpayloadlengthextrabytes')
            if payloadLengthExtraBytes < \
                    defaults.networkDefaultPayloadLengthExtraBytes:
                payloadLengthExtraBytes = \
                    defaults.networkDefaultPayloadLengthExtraBytes
            if command == 'createRandomAddress':
                queues.UISignalQueue.put(
                    ('updateStatusBar',
                     tr._translate("MainWindow",
                                   "Generating one new address")))
                # 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.
                startTime = time.time()
                numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                potentialPrivSigningKey = OpenSSL.rand(32)
                potentialPubSigningKey = highlevelcrypto.pointMult(
                    potentialPrivSigningKey)
                while True:
                    numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                    potentialPrivEncryptionKey = OpenSSL.rand(32)
                    potentialPubEncryptionKey = highlevelcrypto.pointMult(
                        potentialPrivEncryptionKey)
                    sha = hashlib.new('sha512')
                    sha.update(potentialPubSigningKey +
                               potentialPubEncryptionKey)
                    ripe = RIPEMD160Hash(sha.digest()).digest()
                    if (ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash] ==
                            '\x00' *
                            numberOfNullBytesDemandedOnFrontOfRipeHash):
                        break
                logger.info('Generated address with ripe digest: %s',
                            hexlify(ripe))
                try:
                    logger.info(
                        'Address generator calculated %s addresses at %s'
                        ' addresses per second before finding one with'
                        ' the correct ripe-prefix.',
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix,
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix
                        / (time.time() - startTime))
                except ZeroDivisionError:
                    # The user must have a pretty fast computer.
                    # time.time() - startTime equaled zero.
                    pass
                address = encodeAddress(addressVersionNumber, streamNumber,
                                        ripe)

                # 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)

                privEncryptionKey = '\x80' + potentialPrivEncryptionKey
                checksum = hashlib.sha256(
                    hashlib.sha256(privEncryptionKey).digest()).digest()[0:4]
                privEncryptionKeyWIF = arithmetic.changebase(
                    privEncryptionKey + checksum, 256, 58)

                BMConfigParser().add_section(address)
                BMConfigParser().set(address, 'label', label)
                BMConfigParser().set(address, 'enabled', 'true')
                BMConfigParser().set(address, 'decoy', 'false')
                BMConfigParser().set(address, 'noncetrialsperbyte',
                                     str(nonceTrialsPerByte))
                BMConfigParser().set(address, 'payloadlengthextrabytes',
                                     str(payloadLengthExtraBytes))
                BMConfigParser().set(address, 'privsigningkey',
                                     privSigningKeyWIF)
                BMConfigParser().set(address, 'privencryptionkey',
                                     privEncryptionKeyWIF)
                BMConfigParser().save()

                # The API and the join and create Chan functionality
                # both need information back from the address generator.
                queues.apiAddressGeneratorReturnQueue.put(address)

                queues.UISignalQueue.put(
                    ('updateStatusBar',
                     tr._translate(
                         "MainWindow",
                         "Done generating address. Doing work necessary"
                         " to broadcast it...")))
                queues.UISignalQueue.put(
                    ('writeNewAddressToTable', (label, address, streamNumber)))
                shared.reloadMyAddressHashes()
                if addressVersionNumber == 3:
                    queues.workerQueue.put(('sendOutOrStoreMyV3Pubkey', ripe))
                elif addressVersionNumber == 4:
                    queues.workerQueue.put(
                        ('sendOutOrStoreMyV4Pubkey', address))

            elif command == 'createDeterministicAddresses' \
                    or command == 'getDeterministicAddress' \
                    or command == 'createChan' or command == 'joinChan':
                if len(deterministicPassphrase) == 0:
                    logger.warning(
                        'You are creating deterministic'
                        ' address(es) using a blank passphrase.'
                        ' Bitmessage will do it but it is rather stupid.')
                if command == 'createDeterministicAddresses':
                    queues.UISignalQueue.put(
                        ('updateStatusBar',
                         tr._translate("MainWindow",
                                       "Generating %1 new addresses.").arg(
                                           str(numberOfAddressesToMake))))
                signingKeyNonce = 0
                encryptionKeyNonce = 1
                # We fill out this list no matter what although we only
                # need it if we end up passing the info to the API.
                listOfNewAddressesToSendOutThroughTheAPI = []

                for _ in range(numberOfAddressesToMake):
                    # This next section is a little bit strange. We're
                    # going to generate keys over and over until we find
                    # one that has a RIPEMD hash 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.
                    startTime = time.time()
                    numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                    while True:
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                        potentialPrivSigningKey = hashlib.sha512(
                            deterministicPassphrase +
                            encodeVarint(signingKeyNonce)).digest()[:32]
                        potentialPrivEncryptionKey = hashlib.sha512(
                            deterministicPassphrase +
                            encodeVarint(encryptionKeyNonce)).digest()[:32]
                        potentialPubSigningKey = highlevelcrypto.pointMult(
                            potentialPrivSigningKey)
                        potentialPubEncryptionKey = highlevelcrypto.pointMult(
                            potentialPrivEncryptionKey)
                        signingKeyNonce += 2
                        encryptionKeyNonce += 2
                        sha = hashlib.new('sha512')
                        sha.update(potentialPubSigningKey +
                                   potentialPubEncryptionKey)
                        ripe = RIPEMD160Hash(sha.digest()).digest()
                        if (ripe[:numberOfNullBytesDemandedOnFrontOfRipeHash]
                                == '\x00' *
                                numberOfNullBytesDemandedOnFrontOfRipeHash):
                            break

                    logger.info('Generated address with ripe digest: %s',
                                hexlify(ripe))
                    try:
                        logger.info(
                            'Address generator calculated %s addresses'
                            ' at %s addresses per second before finding'
                            ' one with the correct ripe-prefix.',
                            numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix,
                            numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix
                            / (time.time() - startTime))
                    except ZeroDivisionError:
                        # The user must have a pretty fast computer.
                        # time.time() - startTime equaled zero.
                        pass
                    address = encodeAddress(addressVersionNumber, streamNumber,
                                            ripe)

                    saveAddressToDisk = True
                    # If we are joining an existing chan, let us check
                    # to make sure it matches the provided Bitmessage address
                    if command == 'joinChan':
                        if address != chanAddress:
                            listOfNewAddressesToSendOutThroughTheAPI.append(
                                'chan name does not match address')
                            saveAddressToDisk = False
                    if command == 'getDeterministicAddress':
                        saveAddressToDisk = False

                    if saveAddressToDisk and live:
                        # 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)

                        privEncryptionKey = '\x80' + \
                            potentialPrivEncryptionKey
                        checksum = hashlib.sha256(
                            hashlib.sha256(
                                privEncryptionKey).digest()).digest()[0:4]
                        privEncryptionKeyWIF = arithmetic.changebase(
                            privEncryptionKey + checksum, 256, 58)

                        try:
                            BMConfigParser().add_section(address)
                            addressAlreadyExists = False
                        except:
                            addressAlreadyExists = True

                        if addressAlreadyExists:
                            logger.info(
                                '%s already exists. Not adding it again.',
                                address)
                            queues.UISignalQueue.put(
                                ('updateStatusBar',
                                 tr._translate(
                                     "MainWindow",
                                     "%1 is already in 'Your Identities'."
                                     " Not adding it again.").arg(address)))
                        else:
                            logger.debug('label: %s', label)
                            BMConfigParser().set(address, 'label', label)
                            BMConfigParser().set(address, 'enabled', 'true')
                            BMConfigParser().set(address, 'decoy', 'false')
                            if command == 'joinChan' \
                                    or command == 'createChan':
                                BMConfigParser().set(address, 'chan', 'true')
                            BMConfigParser().set(address, 'noncetrialsperbyte',
                                                 str(nonceTrialsPerByte))
                            BMConfigParser().set(address,
                                                 'payloadlengthextrabytes',
                                                 str(payloadLengthExtraBytes))
                            BMConfigParser().set(address, 'privSigningKey',
                                                 privSigningKeyWIF)
                            BMConfigParser().set(address, 'privEncryptionKey',
                                                 privEncryptionKeyWIF)
                            BMConfigParser().save()

                            queues.UISignalQueue.put(
                                ('writeNewAddressToTable',
                                 (label, address, str(streamNumber))))
                            listOfNewAddressesToSendOutThroughTheAPI.append(
                                address)
                            shared.myECCryptorObjects[ripe] = \
                                highlevelcrypto.makeCryptor(
                                hexlify(potentialPrivEncryptionKey))
                            shared.myAddressesByHash[ripe] = address
                            tag = hashlib.sha512(
                                hashlib.sha512(
                                    encodeVarint(addressVersionNumber) +
                                    encodeVarint(streamNumber) +
                                    ripe).digest()).digest()[32:]
                            shared.myAddressesByTag[tag] = address
                            if addressVersionNumber == 3:
                                # If this is a chan address,
                                # the worker thread won't send out
                                # the pubkey over the network.
                                queues.workerQueue.put(
                                    ('sendOutOrStoreMyV3Pubkey', ripe))
                            elif addressVersionNumber == 4:
                                queues.workerQueue.put(
                                    ('sendOutOrStoreMyV4Pubkey', address))
                            queues.UISignalQueue.put(
                                ('updateStatusBar',
                                 tr._translate("MainWindow",
                                               "Done generating address")))
                    elif saveAddressToDisk and not live \
                            and not BMConfigParser().has_section(address):
                        listOfNewAddressesToSendOutThroughTheAPI.append(
                            address)

                # Done generating addresses.
                if command == 'createDeterministicAddresses' \
                        or command == 'joinChan' or command == 'createChan':
                    queues.apiAddressGeneratorReturnQueue.put(
                        listOfNewAddressesToSendOutThroughTheAPI)
                elif command == 'getDeterministicAddress':
                    queues.apiAddressGeneratorReturnQueue.put(address)
            else:
                raise Exception(
                    "Error in the addressGenerator thread. Thread was" +
                    " given a command it could not understand: " + command)
            queues.addressGeneratorQueue.task_done()
    def run(self):
        while shared.shutdown == 0:
            queueValue = shared.addressGeneratorQueue.get()
            nonceTrialsPerByte = 0
            payloadLengthExtraBytes = 0
            if queueValue[0] == 'createChan':
                command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
                eighteenByteRipe = False
                numberOfAddressesToMake = 1
                numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif queueValue[0] == 'joinChan':
                command, chanAddress, label, deterministicPassphrase = queueValue
                eighteenByteRipe = False
                addressVersionNumber = decodeAddress(chanAddress)[1]
                streamNumber = decodeAddress(chanAddress)[2]
                numberOfAddressesToMake = 1
                numberOfNullBytesDemandedOnFrontOfRipeHash = 1
            elif len(queueValue) == 7:
                command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue
                try:
                    numberOfNullBytesDemandedOnFrontOfRipeHash = shared.config.getint(
                        'bitmessagesettings', 'numberofnullbytesonaddress')
                except:
                    if eighteenByteRipe:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 2
                    else:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 1  # The default
            elif len(queueValue) == 9:
                command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue
                try:
                    numberOfNullBytesDemandedOnFrontOfRipeHash = shared.config.getint(
                        'bitmessagesettings', 'numberofnullbytesonaddress')
                except:
                    if eighteenByteRipe:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 2
                    else:
                        numberOfNullBytesDemandedOnFrontOfRipeHash = 1  # The default
            elif queueValue[0] == 'stopThread':
                break
            else:
                sys.stderr.write('Programming error: A structure with the wrong ' +
                                 'number of values was passed into the addressGeneratorQueue. ' +
                                 'Here is the queueValue: %s\n' % repr(queueValue))
            if addressVersionNumber < 3 or addressVersionNumber > 4:
                sys.stderr.write(
                    'Program error: For some reason the address generator queue has ' +
                    'been given a request to create at least one version %s address ' +
                    'which it cannot do.\n' % addressVersionNumber)
            if nonceTrialsPerByte == 0:
                nonceTrialsPerByte = shared.config.getint(
                    'bitmessagesettings', 'defaultnoncetrialsperbyte')
            if nonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte:
                nonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
            if payloadLengthExtraBytes == 0:
                payloadLengthExtraBytes = shared.config.getint(
                    'bitmessagesettings', 'defaultpayloadlengthextrabytes')
            if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
                payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
            if command == 'createRandomAddress':
                shared.UISignalQueue.put(('updateStatusBar',
                                          tr._translate("MainWindow",
                                                        "Generating one new address")))
                # 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.
                startTime = time.time()
                numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                potentialPrivSigningKey = OpenSSL.rand(32)
                potentialPubSigningKey = highlevelcrypto.pointMult(potentialPrivSigningKey)
                while True:
                    numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                    potentialPrivEncryptionKey = OpenSSL.rand(32)
                    potentialPubEncryptionKey = highlevelcrypto.pointMult(
                        potentialPrivEncryptionKey)
                    ripe = hashlib.new('ripemd160')
                    sha = hashlib.new('sha512')
                    sha.update(
                        potentialPubSigningKey + potentialPubEncryptionKey)
                    ripe.update(sha.digest())
                    if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
                        break
                logger.info('Generated address with ripe digest: %s' % hexlify(ripe.digest()))
                try:
                    logger.info('Address generator calculated %s addresses at %s addresses per second before finding one with the correct ripe-prefix.' % (numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime)))
                except ZeroDivisionError:
                    # The user must have a pretty fast computer. time.time() - startTime equaled zero.
                    pass
                address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())

                # 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)

                privEncryptionKey = '\x80' + potentialPrivEncryptionKey
                checksum = hashlib.sha256(hashlib.sha256(
                    privEncryptionKey).digest()).digest()[0:4]
                privEncryptionKeyWIF = arithmetic.changebase(
                    privEncryptionKey + checksum, 256, 58)

                shared.config.add_section(address)
                shared.config.set(address, 'label', label)
                shared.config.set(address, 'enabled', 'true')
                shared.config.set(address, 'decoy', 'false')
                shared.config.set(address, 'noncetrialsperbyte', str(
                    nonceTrialsPerByte))
                shared.config.set(address, 'payloadlengthextrabytes', str(
                    payloadLengthExtraBytes))
                shared.config.set(
                    address, 'privSigningKey', privSigningKeyWIF)
                shared.config.set(
                    address, 'privEncryptionKey', privEncryptionKeyWIF)
                shared.writeKeysFile()

                # The API and the join and create Chan functionality
                # both need information back from the address generator.
                shared.apiAddressGeneratorReturnQueue.put(address)

                shared.UISignalQueue.put(('updateStatusBar',
                                          tr._translate("MainWindow",
                                                        "Done generating address. Doing work necessary to broadcast it...")))
                shared.UISignalQueue.put(('writeNewAddressToTable',
                                         (label, address, streamNumber)))
                shared.reloadMyAddressHashes()
                if addressVersionNumber == 3:
                    shared.workerQueue.put((
                        'sendOutOrStoreMyV3Pubkey', ripe.digest()))
                elif addressVersionNumber == 4:
                    shared.workerQueue.put((
                        'sendOutOrStoreMyV4Pubkey', address))

            elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan':
                if len(deterministicPassphrase) == 0:
                    sys.stderr.write('[WARN]: You are creating deterministic address(es) ' +
                                     'using a blank passphrase. Bitmessage will do it ' +
                                     'but it is rather stupid.')
                if command == 'createDeterministicAddresses':
                    shared.UISignalQueue.put(('updateStatusBar',
                                             tr._translate("MainWindow",
                                                           "Generating %1 new addresses.").arg(str(numberOfAddressesToMake))))
                signingKeyNonce = 0
                encryptionKeyNonce = 1

                # We fill out this list no matter what although we only need it if we end up passing the info to the API.
                listOfNewAddressesToSendOutThroughTheAPI = []

                for i in range(numberOfAddressesToMake):
                    # This next section is a little bit strange. We're going to generate keys over and over until we
                    # find one that has a RIPEMD hash 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.
                    startTime = time.time()
                    numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                    while True:
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                        potentialPrivSigningKey = hashlib.sha512(
                            deterministicPassphrase + encodeVarint(signingKeyNonce)).digest()[:32]
                        potentialPrivEncryptionKey = hashlib.sha512(
                            deterministicPassphrase + encodeVarint(encryptionKeyNonce)).digest()[:32]
                        potentialPubSigningKey = highlevelcrypto.pointMult(
                            potentialPrivSigningKey)
                        potentialPubEncryptionKey = highlevelcrypto.pointMult(
                            potentialPrivEncryptionKey)
                        signingKeyNonce += 2
                        encryptionKeyNonce += 2
                        ripe = hashlib.new('ripemd160')
                        sha = hashlib.new('sha512')
                        sha.update(
                            potentialPubSigningKey + potentialPubEncryptionKey)
                        ripe.update(sha.digest())
                        if ripe.digest()[:numberOfNullBytesDemandedOnFrontOfRipeHash] == '\x00' * numberOfNullBytesDemandedOnFrontOfRipeHash:
                            break

                    logger.info('Generated address with ripe digest: %s' % hexlify(ripe.digest()))
                    try:
                        logger.info('Address generator calculated %s addresses at %s addresses per second before finding one with the correct ripe-prefix.' % (numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime)))
                    except ZeroDivisionError:
                        # The user must have a pretty fast computer. time.time() - startTime equaled zero.
                        pass
                    address = encodeAddress(addressVersionNumber, streamNumber, ripe.digest())

                    saveAddressToDisk = True
                    # If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address
                    if command == 'joinChan':
                        if address != chanAddress:
                            shared.apiAddressGeneratorReturnQueue.put('chan name does not match address')
                            saveAddressToDisk = False
                    if command == 'getDeterministicAddress':
                        saveAddressToDisk = False

                    if saveAddressToDisk:
                        # 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)

                        privEncryptionKey = '\x80' + \
                            potentialPrivEncryptionKey
                        checksum = hashlib.sha256(hashlib.sha256(
                            privEncryptionKey).digest()).digest()[0:4]
                        privEncryptionKeyWIF = arithmetic.changebase(
                            privEncryptionKey + checksum, 256, 58)

                        try:
                            shared.config.add_section(address)
                            addressAlreadyExists = False
                        except:
                            addressAlreadyExists = True

                        if addressAlreadyExists:
                            logger.info('%s already exists. Not adding it again.' % address)
                            shared.UISignalQueue.put(('updateStatusBar',
                                                      tr._translate("MainWindow",
                                                                    "%1 is already in 'Your Identities'. Not adding it again.").arg(address)))
                        else:
                            logger.debug('label: %s' % label)
                            shared.config.set(address, 'label', label)
                            shared.config.set(address, 'enabled', 'true')
                            shared.config.set(address, 'decoy', 'false')
                            if command == 'joinChan' or command == 'createChan':
                                shared.config.set(address, 'chan', 'true')
                            shared.config.set(address, 'noncetrialsperbyte', str(nonceTrialsPerByte))
                            shared.config.set(address, 'payloadlengthextrabytes', str(payloadLengthExtraBytes))
                            shared.config.set(address, 'privSigningKey', privSigningKeyWIF)
                            shared.config.set(address, 'privEncryptionKey', privEncryptionKeyWIF)
                            shared.writeKeysFile()

                            shared.UISignalQueue.put(('writeNewAddressToTable',
                                                     (label, address, str(streamNumber))))
                            listOfNewAddressesToSendOutThroughTheAPI.append(address)
                            shared.myECCryptorObjects[ripe.digest()] = highlevelcrypto.makeCryptor(
                                hexlify(potentialPrivEncryptionKey))
                            shared.myAddressesByHash[ripe.digest()] = address
                            tag = hashlib.sha512(hashlib.sha512(encodeVarint(
                                addressVersionNumber) + encodeVarint(streamNumber) + ripe.digest()).digest()).digest()[32:]
                            shared.myAddressesByTag[tag] = address
                            if addressVersionNumber == 3:
                                # If this is a chan address,
                                # the worker thread won't send out the pubkey over the network.
                                shared.workerQueue.put(('sendOutOrStoreMyV3Pubkey', ripe.digest())) 
                            elif addressVersionNumber == 4:
                                shared.workerQueue.put(('sendOutOrStoreMyV4Pubkey', address))
                            shared.UISignalQueue.put(('updateStatusBar',
                                                     tr._translate("MainWindow",
                                                                   "Done generating address")))


                # Done generating addresses.
                if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
                    shared.apiAddressGeneratorReturnQueue.put(
                        listOfNewAddressesToSendOutThroughTheAPI)
                elif command == 'getDeterministicAddress':
                    shared.apiAddressGeneratorReturnQueue.put(address)
            else:
                raise Exception("Error in the addressGenerator thread. " +
                                "Thread was given a command it could not understand: " +
                                command)
            shared.addressGeneratorQueue.task_done()
Example #16
0
def decryptAndCheckPubkeyPayload(payload, address):
    status, addressVersion, streamNumber, ripe = decodeAddress(address)
    doubleHashOfAddressData = hashlib.sha512(
        hashlib.sha512(
            encodeVarint(addressVersion) + encodeVarint(streamNumber) +
            ripe).digest()).digest()
    readPosition = 8  # bypass the nonce
    readPosition += 8  # bypass the time
    embeddedVersionNumber, varintLength = decodeVarint(
        payload[readPosition:readPosition + 10])
    if embeddedVersionNumber != addressVersion:
        logger.info(
            'Pubkey decryption was UNsuccessful due to address version mismatch. This shouldn\'t have happened.'
        )
        return 'failed'
    readPosition += varintLength
    embeddedStreamNumber, varintLength = decodeVarint(
        payload[readPosition:readPosition + 10])
    if embeddedStreamNumber != streamNumber:
        logger.info(
            'Pubkey decryption was UNsuccessful due to stream number mismatch. This shouldn\'t have happened.'
        )
        return 'failed'
    readPosition += varintLength
    signedData = payload[
        8:
        readPosition]  # Some of the signed data is not encrypted so let's keep it for now.
    toTag = payload[readPosition:readPosition + 32]
    readPosition += 32  #for the tag
    encryptedData = payload[readPosition:]
    # Let us try to decrypt the pubkey
    privEncryptionKey = doubleHashOfAddressData[:32]
    cryptorObject = highlevelcrypto.makeCryptor(
        privEncryptionKey.encode('hex'))
    try:
        decryptedData = cryptorObject.decrypt(encryptedData)
    except:
        # Someone must have encrypted some data with a different key
        # but tagged it with a tag for which we are watching.
        logger.info(
            'Pubkey decryption was UNsuccessful. This shouldn\'t have happened.'
        )
        return 'failed'
    logger.debug('Pubkey decryption successful')
    readPosition = 4  # bypass the behavior bitfield
    publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
    # Is it possible for a public key to be invalid such that trying to
    # encrypt or check a sig with it will cause an error? If it is, we should
    # probably test these keys here.
    readPosition += 64
    publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition +
                                                 64]
    readPosition += 64
    specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += specifiedNonceTrialsPerByteLength
    specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += specifiedPayloadLengthExtraBytesLength
    signedData += decryptedData[:readPosition]
    signatureLength, signatureLengthLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += signatureLengthLength
    signature = decryptedData[readPosition:readPosition + signatureLength]
    try:
        if not highlevelcrypto.verify(signedData, signature,
                                      publicSigningKey.encode('hex')):
            logger.info(
                'ECDSA verify failed (within decryptAndCheckPubkeyPayload).')
            return 'failed'
        logger.debug(
            'ECDSA verify passed (within decryptAndCheckPubkeyPayload)')
    except Exception as err:
        logger.debug(
            'ECDSA verify failed (within decryptAndCheckPubkeyPayload) %s' %
            err)
        return 'failed'

    sha = hashlib.new('sha512')
    sha.update(publicSigningKey + publicEncryptionKey)
    ripeHasher = hashlib.new('ripemd160')
    ripeHasher.update(sha.digest())
    embeddedRipe = ripeHasher.digest()

    if embeddedRipe != ripe:
        # Although this pubkey object had the tag were were looking for and was
        # encrypted with the correct encryption key, it doesn't contain the
        # correct keys. Someone is either being malicious or using buggy software.
        logger.info(
            'Pubkey decryption was UNsuccessful due to RIPE mismatch. This shouldn\'t have happened.'
        )
        return 'failed'

    t = (ripe, addressVersion, signedData, int(time.time()), 'yes')
    sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
    return 'successful'
Example #17
0
    def requestPubKey(self, toAddress):
        toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress(
            toAddress)
        if toStatus != 'success':
            return
        
        queryReturn = sqlQuery(
            '''SELECT retrynumber FROM sent WHERE toaddress=? AND (status='doingpubkeypow' OR status='awaitingpubkey') LIMIT 1''', 
            toAddress)
        if len(queryReturn) == 0:
            return
        retryNumber = queryReturn[0][0]

        if addressVersionNumber <= 3:
            shared.neededPubkeys[toAddress] = 0
        elif addressVersionNumber >= 4:
            # If the user just clicked 'send' then the tag (and other information) will already
            # be in the neededPubkeys dictionary. But if we are recovering from a restart
            # of the client then we have to put it in now. 
            privEncryptionKey = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).digest()).digest()[:32] # Note that this is the first half of the sha512 hash.
            tag = hashlib.sha512(hashlib.sha512(encodeVarint(addressVersionNumber)+encodeVarint(streamNumber)+ripe).digest()).digest()[32:] # Note that this is the second half of the sha512 hash.
            if tag not in shared.neededPubkeys:
                shared.neededPubkeys[tag] = (toAddress, highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))) # We'll need this for when we receive a pubkey reply: it will be encrypted and we'll need to decrypt it.
        
        if retryNumber == 0:
            TTL = 2.5*24*60*60 # 2.5 days. This was chosen fairly arbitrarily. 
        else:
            TTL = 28*24*60*60
        TTL = TTL + random.randrange(-300, 300) # add some randomness to the TTL
        embeddedTime = int(time.time() + TTL)
        payload = pack('>Q', embeddedTime)
        payload += '\x00\x00\x00\x00' # object type: getpubkey
        payload += encodeVarint(addressVersionNumber)
        payload += encodeVarint(streamNumber)
        if addressVersionNumber <= 3:
            payload += ripe
        else:
            payload += tag

        statusbar = 'Doing the computations necessary to request the recipient\'s public key.'
        
        target = 2 ** 64 / (shared.networkDefaultProofOfWorkNonceTrialsPerByte*(len(payload) + 8 + shared.networkDefaultPayloadLengthExtraBytes + ((TTL*(len(payload)+8+shared.networkDefaultPayloadLengthExtraBytes))/(2 ** 16))))
        initialHash = hashlib.sha512(payload).digest()
        trialValue, nonce = proofofwork.run(target, initialHash)
        payload = pack('>Q', nonce) + payload
        inventoryHash = calculateInventoryHash(payload)
        objectType = 1
        shared.inventory[inventoryHash] = (
            objectType, streamNumber, payload, embeddedTime, '')
        shared.inventorySets[streamNumber].add(inventoryHash)
        shared.broadcastToSendDataQueues((
            streamNumber, 'advertiseobject', inventoryHash))
        
        if retryNumber == 0:
            sleeptill = int(time.time()) + TTL
        else:
            sleeptill = int(time.time()) + 28*24*60*60 * 2**retryNumber
        sqlExecute(
            '''UPDATE sent SET lastactiontime=?, status='awaitingpubkey', retrynumber=?, sleeptill=? WHERE toaddress=? AND (status='doingpubkeypow' OR status='awaitingpubkey') ''',
            int(time.time()),
            retryNumber+1,
            sleeptill,
            toAddress)
Example #18
0
def decryptAndCheckPubkeyPayload(payload, address):
    status, addressVersion, streamNumber, ripe = decodeAddress(address)
    doubleHashOfAddressData = hashlib.sha512(hashlib.sha512(encodeVarint(
        addressVersion) + encodeVarint(streamNumber) + ripe).digest()).digest()
    # this function expects that the nonce is Not included in payload.
    readPosition = 8  # for the time
    embeddedVersionNumber, varintLength = decodeVarint(
        payload[readPosition:readPosition + 10])
    if embeddedVersionNumber != addressVersion:
        with shared.printLock:
            print 'Pubkey decryption was UNsuccessful due to address version mismatch. This shouldn\'t have happened.'
        return 'failed'
    readPosition += varintLength
    embeddedStreamNumber, varintLength = decodeVarint(
        payload[readPosition:readPosition + 10])
    if embeddedStreamNumber != streamNumber:
        with shared.printLock:
            print 'Pubkey decryption was UNsuccessful due to stream number mismatch. This shouldn\'t have happened.'
        return 'failed'
    readPosition += varintLength
    signedData = payload[:readPosition] # Some of the signed data is not encrypted so let's keep it for now.
    toTag = payload[readPosition:readPosition+32]
    readPosition += 32 #for the tag
    encryptedData = payload[readPosition:]
    # Let us try to decrypt the pubkey
    privEncryptionKey = doubleHashOfAddressData[:32]
    cryptorObject = highlevelcrypto.makeCryptor(privEncryptionKey.encode('hex'))
    try:
        decryptedData = cryptorObject.decrypt(encryptedData)
    except:
        # Someone must have encrypted some data with a different key
        # but tagged it with a tag for which we are watching.
        with shared.printLock:
            print 'Pubkey decryption was UNsuccessful. This shouldn\'t have happened.'
        return 'failed'
    print 'Pubkey decryption successful'
    readPosition = 4 # bypass the behavior bitfield
    publicSigningKey = '\x04' + decryptedData[readPosition:readPosition + 64]
    # Is it possible for a public key to be invalid such that trying to
    # encrypt or sign with it will cause an error? If it is, we should
    # probably test these keys here.
    readPosition += 64
    publicEncryptionKey = '\x04' + decryptedData[readPosition:readPosition + 64]
    readPosition += 64
    specifiedNonceTrialsPerByte, specifiedNonceTrialsPerByteLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += specifiedNonceTrialsPerByteLength
    specifiedPayloadLengthExtraBytes, specifiedPayloadLengthExtraBytesLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += specifiedPayloadLengthExtraBytesLength
    signedData += decryptedData[:readPosition]
    signatureLength, signatureLengthLength = decodeVarint(
        decryptedData[readPosition:readPosition + 10])
    readPosition += signatureLengthLength
    signature = decryptedData[readPosition:readPosition + signatureLength]
    try:
        if not highlevelcrypto.verify(signedData, signature, publicSigningKey.encode('hex')):
            print 'ECDSA verify failed (within decryptAndCheckPubkeyPayload).'
            return 'failed'
        print 'ECDSA verify passed (within decryptAndCheckPubkeyPayload)'
    except Exception as err:
        print 'ECDSA verify failed (within decryptAndCheckPubkeyPayload)', err
        return 'failed'

    sha = hashlib.new('sha512')
    sha.update(publicSigningKey + publicEncryptionKey)
    ripeHasher = hashlib.new('ripemd160')
    ripeHasher.update(sha.digest())
    embeddedRipe = ripeHasher.digest()

    if embeddedRipe != ripe:
        # Although this pubkey object had the tag were were looking for and was
        # encrypted with the correct encryption key, it doesn't contain the
        # correct keys. Someone is either being malicious or using buggy software.
        with shared.printLock:
            print 'Pubkey decryption was UNsuccessful due to RIPE mismatch. This shouldn\'t have happened.'
        return 'failed'
    
    t = (ripe, addressVersion, signedData, int(time.time()), 'yes')
    sqlExecute('''INSERT INTO pubkeys VALUES (?,?,?,?,?)''', *t)
    return 'successful'
Example #19
0
    def requestPubKey(self, toAddress):
        toStatus, addressVersionNumber, streamNumber, ripe = decodeAddress(
            toAddress)
        if toStatus != 'success':
            return

        queryReturn = sqlQuery(
            '''SELECT retrynumber FROM sent WHERE toaddress=? AND (status='doingpubkeypow' OR status='awaitingpubkey') LIMIT 1''',
            toAddress)
        if len(queryReturn) == 0:
            return
        retryNumber = queryReturn[0][0]

        if addressVersionNumber <= 3:
            shared.neededPubkeys[toAddress] = 0
        elif addressVersionNumber >= 4:
            # If the user just clicked 'send' then the tag (and other information) will already
            # be in the neededPubkeys dictionary. But if we are recovering from a restart
            # of the client then we have to put it in now.
            privEncryptionKey = hashlib.sha512(
                hashlib.sha512(
                    encodeVarint(addressVersionNumber) +
                    encodeVarint(streamNumber) + ripe).digest()
            ).digest(
            )[:32]  # Note that this is the first half of the sha512 hash.
            tag = hashlib.sha512(
                hashlib.sha512(
                    encodeVarint(addressVersionNumber) +
                    encodeVarint(streamNumber) + ripe).digest()
            ).digest()[
                32:]  # Note that this is the second half of the sha512 hash.
            if tag not in shared.neededPubkeys:
                shared.neededPubkeys[tag] = (
                    toAddress,
                    highlevelcrypto.makeCryptor(
                        privEncryptionKey.encode('hex'))
                )  # We'll need this for when we receive a pubkey reply: it will be encrypted and we'll need to decrypt it.

        if retryNumber == 0:
            TTL = 2.5 * 24 * 60 * 60  # 2.5 days. This was chosen fairly arbitrarily.
        else:
            TTL = 28 * 24 * 60 * 60
        TTL = TTL + random.randrange(-300,
                                     300)  # add some randomness to the TTL
        embeddedTime = int(time.time() + TTL)
        payload = pack('>Q', embeddedTime)
        payload += '\x00\x00\x00\x00'  # object type: getpubkey
        payload += encodeVarint(addressVersionNumber)
        payload += encodeVarint(streamNumber)
        if addressVersionNumber <= 3:
            payload += ripe
        else:
            payload += tag

        statusbar = 'Doing the computations necessary to request the recipient\'s public key.'

        target = 2**64 / (
            shared.networkDefaultProofOfWorkNonceTrialsPerByte *
            (len(payload) + 8 + shared.networkDefaultPayloadLengthExtraBytes +
             ((TTL * (len(payload) + 8 +
                      shared.networkDefaultPayloadLengthExtraBytes)) /
              (2**16))))
        initialHash = hashlib.sha512(payload).digest()
        trialValue, nonce = proofofwork.run(target, initialHash)
        payload = pack('>Q', nonce) + payload
        inventoryHash = calculateInventoryHash(payload)
        objectType = 1
        shared.inventory[inventoryHash] = (objectType, streamNumber, payload,
                                           embeddedTime, '')
        shared.inventorySets[streamNumber].add(inventoryHash)
        shared.broadcastToSendDataQueues(
            (streamNumber, 'advertiseobject', inventoryHash))

        if retryNumber == 0:
            sleeptill = int(time.time()) + TTL
        else:
            sleeptill = int(time.time()) + 28 * 24 * 60 * 60 * 2**retryNumber
        sqlExecute(
            '''UPDATE sent SET lastactiontime=?, status='awaitingpubkey', retrynumber=?, sleeptill=? WHERE toaddress=? AND (status='doingpubkeypow' OR status='awaitingpubkey') ''',
            int(time.time()), retryNumber + 1, sleeptill, toAddress)
Example #20
0
    def run(self):
        while True:
            queueValue = shared.addressGeneratorQueue.get()
            nonceTrialsPerByte = 0
            payloadLengthExtraBytes = 0
            if queueValue[0] == 'createChan':
                command, addressVersionNumber, streamNumber, label, deterministicPassphrase = queueValue
                eighteenByteRipe = False
                numberOfAddressesToMake = 1
            elif queueValue[0] == 'joinChan':
                command, chanAddress, label, deterministicPassphrase = queueValue
                eighteenByteRipe = False
                addressVersionNumber = decodeAddress(chanAddress)[1]
                streamNumber = decodeAddress(chanAddress)[2]
                numberOfAddressesToMake = 1
            elif len(queueValue) == 7:
                command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe = queueValue
            elif len(queueValue) == 9:
                command, addressVersionNumber, streamNumber, label, numberOfAddressesToMake, deterministicPassphrase, eighteenByteRipe, nonceTrialsPerByte, payloadLengthExtraBytes = queueValue
            else:
                sys.stderr.write(
                    'Programming error: A structure with the wrong number of values was passed into the addressGeneratorQueue. Here is the queueValue: %s\n' % repr(queueValue))
            if addressVersionNumber < 3 or addressVersionNumber > 3:
                sys.stderr.write(
                    'Program error: For some reason the address generator queue has been given a request to create at least one version %s address which it cannot do.\n' % addressVersionNumber)
            if nonceTrialsPerByte == 0:
                nonceTrialsPerByte = shared.config.getint(
                    'bitmessagesettings', 'defaultnoncetrialsperbyte')
            if nonceTrialsPerByte < shared.networkDefaultProofOfWorkNonceTrialsPerByte:
                nonceTrialsPerByte = shared.networkDefaultProofOfWorkNonceTrialsPerByte
            if payloadLengthExtraBytes == 0:
                payloadLengthExtraBytes = shared.config.getint(
                    'bitmessagesettings', 'defaultpayloadlengthextrabytes')
            if payloadLengthExtraBytes < shared.networkDefaultPayloadLengthExtraBytes:
                payloadLengthExtraBytes = shared.networkDefaultPayloadLengthExtraBytes
            if addressVersionNumber == 3:  # currently the only one supported.
                if command == 'createRandomAddress':
                    shared.UISignalQueue.put((
                        'updateStatusBar', tr.translateText("MainWindow", "Generating one new address")))
                    # 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.
                    startTime = time.time()
                    numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                    potentialPrivSigningKey = OpenSSL.rand(32)
                    potentialPubSigningKey = pointMult(potentialPrivSigningKey)
                    while True:
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                        potentialPrivEncryptionKey = OpenSSL.rand(32)
                        potentialPubEncryptionKey = pointMult(
                            potentialPrivEncryptionKey)
                        # print 'potentialPubSigningKey', potentialPubSigningKey.encode('hex')
                        # print 'potentialPubEncryptionKey',
                        # potentialPubEncryptionKey.encode('hex')
                        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 eighteenByteRipe:
                            if ripe.digest()[:2] == '\x00\x00':
                                break
                        else:
                            if ripe.digest()[:1] == '\x00':
                                break
                    print 'Generated address with ripe digest:', ripe.digest().encode('hex')
                    print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'addresses per second before finding one with the correct ripe-prefix.'
                    address = encodeAddress(3, streamNumber, ripe.digest())

                    # 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

                    shared.config.add_section(address)
                    shared.config.set(address, 'label', label)
                    shared.config.set(address, 'enabled', 'true')
                    shared.config.set(address, 'decoy', 'false')
                    shared.config.set(address, 'noncetrialsperbyte', str(
                        nonceTrialsPerByte))
                    shared.config.set(address, 'payloadlengthextrabytes', str(
                        payloadLengthExtraBytes))
                    shared.config.set(
                        address, 'privSigningKey', privSigningKeyWIF)
                    shared.config.set(
                        address, 'privEncryptionKey', privEncryptionKeyWIF)
                    with open(shared.appdata + 'keys.dat', 'wb') as configfile:
                        shared.config.write(configfile)

                    # The API and the join and create Chan functionality
                    # both need information back from the address generator.
                    shared.apiAddressGeneratorReturnQueue.put(address)

                    shared.UISignalQueue.put((
                        'updateStatusBar', tr.translateText("MainWindow", "Done generating address. Doing work necessary to broadcast it...")))
                    shared.UISignalQueue.put(('writeNewAddressToTable', (
                        label, address, streamNumber)))
                    shared.reloadMyAddressHashes()
                    shared.workerQueue.put((
                        'sendOutOrStoreMyV3Pubkey', ripe.digest()))

                elif command == 'createDeterministicAddresses' or command == 'getDeterministicAddress' or command == 'createChan' or command == 'joinChan':
                    if len(deterministicPassphrase) == 0:
                        sys.stderr.write(
                            'WARNING: You are creating deterministic address(es) using a blank passphrase. Bitmessage will do it but it is rather stupid.')
                    if command == 'createDeterministicAddresses':
                        statusbar = 'Generating ' + str(
                            numberOfAddressesToMake) + ' new addresses.'
                        shared.UISignalQueue.put((
                            'updateStatusBar', statusbar))
                    signingKeyNonce = 0
                    encryptionKeyNonce = 1
                    listOfNewAddressesToSendOutThroughTheAPI = [
                    ]  # We fill out this list no matter what although we only need it if we end up passing the info to the API.

                    for i in range(numberOfAddressesToMake):
                        # This next section is a little bit strange. We're going to generate keys over and over until we
                        # find one that has a RIPEMD hash 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.
                        startTime = time.time()
                        numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix = 0
                        while True:
                            numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix += 1
                            potentialPrivSigningKey = hashlib.sha512(
                                deterministicPassphrase + encodeVarint(signingKeyNonce)).digest()[:32]
                            potentialPrivEncryptionKey = hashlib.sha512(
                                deterministicPassphrase + encodeVarint(encryptionKeyNonce)).digest()[:32]
                            potentialPubSigningKey = pointMult(
                                potentialPrivSigningKey)
                            potentialPubEncryptionKey = pointMult(
                                potentialPrivEncryptionKey)
                            # print 'potentialPubSigningKey', potentialPubSigningKey.encode('hex')
                            # print 'potentialPubEncryptionKey',
                            # potentialPubEncryptionKey.encode('hex')
                            signingKeyNonce += 2
                            encryptionKeyNonce += 2
                            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 eighteenByteRipe:
                                if ripe.digest()[:2] == '\x00\x00':
                                    break
                            else:
                                if ripe.digest()[:1] == '\x00':
                                    break

                        print 'ripe.digest', ripe.digest().encode('hex')
                        print 'Address generator calculated', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix, 'addresses at', numberOfAddressesWeHadToMakeBeforeWeFoundOneWithTheCorrectRipePrefix / (time.time() - startTime), 'keys per second.'
                        address = encodeAddress(3, streamNumber, ripe.digest())

                        saveAddressToDisk = True
                        # If we are joining an existing chan, let us check to make sure it matches the provided Bitmessage address
                        if command == 'joinChan':
                            if address != chanAddress:
                                shared.apiAddressGeneratorReturnQueue.put('chan name does not match address')
                                saveAddressToDisk = False
                        if command == 'getDeterministicAddress':
                            saveAddressToDisk = False

                        if saveAddressToDisk:
                            # 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)

                            privEncryptionKey = '\x80' + \
                                potentialPrivEncryptionKey
                            checksum = hashlib.sha256(hashlib.sha256(
                                privEncryptionKey).digest()).digest()[0:4]
                            privEncryptionKeyWIF = arithmetic.changebase(
                                privEncryptionKey + checksum, 256, 58)

                            addressAlreadyExists = False
                            try:
                                shared.config.add_section(address)
                            except:
                                print address, 'already exists. Not adding it again.'
                                addressAlreadyExists = True
                            if not addressAlreadyExists:
                                print 'label:', label
                                shared.config.set(address, 'label', label)
                                shared.config.set(address, 'enabled', 'true')
                                shared.config.set(address, 'decoy', 'false')
                                if command == 'joinChan' or command == 'createChan':
                                    shared.config.set(address, 'chan', 'true')
                                shared.config.set(address, 'noncetrialsperbyte', str(
                                    nonceTrialsPerByte))
                                shared.config.set(address, 'payloadlengthextrabytes', str(
                                    payloadLengthExtraBytes))
                                shared.config.set(
                                    address, 'privSigningKey', privSigningKeyWIF)
                                shared.config.set(
                                    address, 'privEncryptionKey', privEncryptionKeyWIF)
                                with open(shared.appdata + 'keys.dat', 'wb') as configfile:
                                    shared.config.write(configfile)

                                shared.UISignalQueue.put(('writeNewAddressToTable', (
                                    label, address, str(streamNumber))))
                                listOfNewAddressesToSendOutThroughTheAPI.append(
                                    address)
                                shared.myECCryptorObjects[ripe.digest()] = highlevelcrypto.makeCryptor(
                                    potentialPrivEncryptionKey.encode('hex'))
                                shared.myAddressesByHash[
                                    ripe.digest()] = address
                                shared.workerQueue.put((
                                    'sendOutOrStoreMyV3Pubkey', ripe.digest())) # If this is a chan address,
                                        # the worker thread won't send out the pubkey over the network.


                    # Done generating addresses.
                    if command == 'createDeterministicAddresses' or command == 'joinChan' or command == 'createChan':
                        shared.apiAddressGeneratorReturnQueue.put(
                            listOfNewAddressesToSendOutThroughTheAPI)
                        shared.UISignalQueue.put((
                            'updateStatusBar', tr.translateText("MainWindow", "Done generating address")))
                        # shared.reloadMyAddressHashes()
                    elif command == 'getDeterministicAddress':
                        shared.apiAddressGeneratorReturnQueue.put(address)
                    #todo: return things to the API if createChan or joinChan assuming saveAddressToDisk
                else:
                    raise Exception(
                        "Error in the addressGenerator thread. Thread was given a command it could not understand: " + command)