Ejemplo n.º 1
0
def secure_mnemonic(entropy=0, num_bits=128):
    '''Generates a mnemonic phrase using the number of bits'''
    # if we have more than 128 bits, just mask everything but the last 128 bits
    if len(bin(entropy)) > num_bits + 2:
        entropy &= (1 << num_bits) - 1
    # xor some random bits with the entropy that was passed in
    preseed = randbits(num_bits) ^ entropy
    # convert the number to big-endian
    s = int_to_big_endian(preseed, 16)
    # 1 extra bit for checksum is needed per 32 bits
    checksum_bits_needed = num_bits // 32
    # the checksum is the sha256's first n bits. At most this is 8
    checksum = sha256(s)[0] >> (8 - checksum_bits_needed)
    # we concatenate the checksum to the preseed
    total = (preseed << checksum_bits_needed) | checksum
    # now we get the mnemonic passphrase
    mnemonic = []
    # now group into groups of 11 bits
    for _ in range((num_bits + checksum_bits_needed) // 11):
        # grab the last 11 bits
        current = total & ((1 << 11) - 1)
        # insert the correct word at the front
        mnemonic.insert(0, WORD_LIST[current])
        # shift by 11 bits so we can move to the next set
        total >>= 11
    # return the mnemonic phrase by putting spaces between
    return ' '.join(mnemonic)
Ejemplo n.º 2
0
 def from_mnemonic(cls, mnemonic, password=b'', path=b'm', testnet=False):
     binary_seed = bytearray()
     words = mnemonic.split()
     if len(words) not in (12, 15, 18, 21, 24):
         raise ValueError('you need 12, 15, 18, 21, or 24 words')
     number = 0
     for word in words:
         index = WORD_LOOKUP[word]
         number = (number << 11) + index
     # checksum is the last n bits where n = (# of words / 3)
     checksum_bits_length = len(words) // 3
     checksum = number & ((1 << checksum_bits_length) - 1)
     bits_to_ignore = (8 - checksum_bits_length) % 8
     data_num = number >> checksum_bits_length
     data = data_num.to_bytes(checksum_bits_length * 4, 'big')
     computed_checksum = sha256(data)[0] >> bits_to_ignore
     if checksum != computed_checksum:
         raise ValueError('words fail checksum: {}'.format(words))
     normalized_words = []
     for word in words:
         normalized_words.append(WORD_LIST[WORD_LOOKUP[word]])
     normalized_mnemonic = ' '.join(normalized_words)
     seed = PBKDF2(
         normalized_mnemonic,
         b'mnemonic' + password,
         iterations=PBKDF2_ROUNDS,
         macmodule=hmac,
         digestmodule=sha512,
     ).read(64)
     return cls.from_seed(seed, path, testnet=testnet)
Ejemplo n.º 3
0
def secure_mnemonic(entropy=0, num_bits=128):
    # if we have more than 128 bits, just mask everything but the last 128 bits
    if len(bin(entropy)) > num_bits + 2:
        entropy &= (1 << num_bits) - 1
    preseed = randbits(num_bits) ^ entropy
    s = preseed.to_bytes(16, 'big')
    bits_needed = num_bits // 32
    checksum = sha256(s)[0] >> (8 - bits_needed)
    total = (preseed << bits_needed) + checksum
    mnemonic = []
    # now group into groups of 11 bits
    for _ in range((num_bits + bits_needed) // 11):
        # last 11 bits
        current = total & ((1 << 11) - 1)
        mnemonic.insert(0, WORD_LIST[current])
        total >>= 11
    return ' '.join(mnemonic)
Ejemplo n.º 4
0
 def from_mnemonic(cls, mnemonic, password=b'', path='m', testnet=False):
     '''Returns a HDPrivateKey object from the mnemonic.'''
     # split the mnemonic into words with .split()
     words = mnemonic.split()
     # check that there are 12, 15, 18, 21 or 24 words
     # if not, raise a ValueError
     if len(words) not in (12, 15, 18, 21, 24):
         raise ValueError('you need 12, 15, 18, 21, or 24 words')
     # calculate the number
     number = 0
     # each word is 11 bits
     for word in words:
         # get the number that the word represents using WORD_LOOKUP
         index = WORD_LOOKUP[word]
         # left-shift the number by 11 bits and bitwise-or the index
         number = (number << 11) | index
     # checksum is the last n bits where n = (# of words / 3)
     checksum_bits_length = len(words) // 3
     # grab the checksum bits
     checksum = number & ((1 << checksum_bits_length) - 1)
     # get the actual number by right-shifting by the checksum bits length
     data_num = number >> checksum_bits_length
     # convert the number to big-endian
     data = int_to_big_endian(data_num, checksum_bits_length * 4)
     # the one byte we get is from sha256 of the data, shifted by
     #  8 - the number of bits we need for the checksum
     computed_checksum = sha256(data)[0] >> (8 - checksum_bits_length)
     # check that the checksum is correct or raise ValueError
     if checksum != computed_checksum:
         raise ValueError('words fail checksum: {}'.format(words))
     # normalize in case we got a mnemonic that's just the first 4 letters
     normalized_words = []
     for word in words:
         normalized_words.append(WORD_LIST[WORD_LOOKUP[word]])
     normalized_mnemonic = ' '.join(normalized_words)
     # salt is b'mnemonic' + password
     salt = b'mnemonic' + password
     # the seed is the hmac_sha512_kdf with normalized mnemonic and salt
     seed = hmac_sha512_kdf(normalized_mnemonic, salt)
     # return the HDPrivateKey at the path specified
     return cls.from_seed(seed, testnet=testnet).traverse(path)
Ejemplo n.º 5
0
def from_mnemonic(cls, mnemonic, password=b'', path='m', testnet=False):
    words = mnemonic.split()
    if len(words) not in (12, 15, 18, 21, 24):
        raise ValueError('you need 12, 15, 18, 21, or 24 words')
    number = 0
    for word in words:
        index = WORD_LOOKUP[word]
        number = (number << 11) | index
    checksum_bits_length = len(words) // 3
    checksum = number & ((1 << checksum_bits_length) - 1)
    data_num = number >> checksum_bits_length
    data = int_to_big_endian(data_num, checksum_bits_length * 4)
    computed_checksum = sha256(data)[0] >> (8 - checksum_bits_length)
    if checksum != computed_checksum:
        raise ValueError('words fail checksum: {}'.format(words))
    normalized_words = []
    for word in words:
        normalized_words.append(WORD_LIST[WORD_LOOKUP[word]])
    normalized_mnemonic = ' '.join(normalized_words)
    salt = b'mnemonic' + password
    seed = hmac_sha512_kdf(normalized_mnemonic, salt)
    return cls.from_seed(seed, testnet=testnet).traverse(path)
Ejemplo n.º 6
0
 def evaluate(self, z, witness):
     # create a copy as we may need to add to this list if we have a
     # RedeemScript
     cmds = self.cmds[:]
     stack = []
     altstack = []
     while len(cmds) > 0:
         cmd = cmds.pop(0)
         if type(cmd) == int:
             # do what the opcode says
             operation = OP_CODE_FUNCTIONS[cmd]
             if cmd in (99, 100):
                 # op_if/op_notif require the cmds array
                 if not operation(stack, cmds):
                     LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                     return False
             elif cmd in (107, 108):
                 # op_toaltstack/op_fromaltstack require the altstack
                 if not operation(stack, altstack):
                     LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                     return False
             elif cmd in (172, 173, 174, 175):
                 # these are signing operations, they need a sig_hash
                 # to check against
                 if not operation(stack, z):
                     LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                     return False
             else:
                 if not operation(stack):
                     LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                     return False
         else:
             # add the cmd to the stack
             stack.append(cmd)
             # p2sh rule. if the next three cmds are:
             # OP_HASH160 <20 byte hash> OP_EQUAL this is the RedeemScript
             # OP_HASH160 == 0xa9 and OP_EQUAL == 0x87
             if len(cmds) == 3 and cmds[0] == 0xa9 \
                 and type(cmds[1]) == bytes and len(cmds[1]) == 20 \
                 and cmds[2] == 0x87:
                 redeem_script = encode_varint(len(cmd)) + cmd
                 # we execute the next three opcodes
                 cmds.pop()
                 h160 = cmds.pop()
                 cmds.pop()
                 if not op_hash160(stack):
                     return False
                 stack.append(h160)
                 if not op_equal(stack):
                     return False
                 # final result should be a 1
                 if not op_verify(stack):
                     LOGGER.info('bad p2sh h160')
                     return False
                 # hashes match! now add the RedeemScript
                 redeem_script = encode_varint(len(cmd)) + cmd
                 stream = BytesIO(redeem_script)
                 cmds.extend(Script.parse(stream).cmds)
             # witness program version 0 rule. if stack cmds are:
             # 0 <20 byte hash> this is p2wpkh
             # tag::source3[]
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20:  # <1>
                 h160 = stack.pop()
                 stack.pop()
                 cmds.extend(witness)
                 cmds.extend(p2pkh_script(h160).cmds)
             # end::source3[]
             # witness program version 0 rule. if stack cmds are:
             # 0 <32 byte hash> this is p2wsh
             # tag::source6[]
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 32:
                 s256 = stack.pop()  # <1>
                 stack.pop()  # <2>
                 cmds.extend(witness[:-1])  # <3>
                 witness_script = witness[-1]  # <4>
                 if s256 != sha256(witness_script):  # <5>
                     print('bad sha256 {} vs {}'.format
                         (s256.hex(), sha256(witness_script).hex()))
                     return False
                 stream = BytesIO(encode_varint(len(witness_script)) 
                     + witness_script)
                 witness_script_cmds = Script.parse(stream).cmds  # <6>
                 cmds.extend(witness_script_cmds)
             # end::source6[]
     if len(stack) == 0:
         return False
     if stack.pop() == b'':
         return False
     return True
Ejemplo n.º 7
0
 def evaluate(self, z, witness):
     # create a copy as we may need to add to this list if we have a
     # RedeemScript
     instructions = self.instructions[:]
     stack = []
     altstack = []
     while len(instructions) > 0:
         instruction = instructions.pop(0)
         if type(instruction) == int:
             # do what the opcode says
             operation = OP_CODE_FUNCTIONS[instruction]
             if instruction in (99, 100):
                 # op_if/op_notif require the instructions array
                 if not operation(stack, instructions):
                     LOGGER.info('bad op: {}'.format(
                         OP_CODE_NAMES[instruction]))
                     return False
             elif instruction in (107, 108):
                 # op_toaltstack/op_fromaltstack require the altstack
                 if not operation(stack, altstack):
                     LOGGER.info('bad op: {}'.format(
                         OP_CODE_NAMES[instruction]))
                     return False
             elif instruction in (172, 173, 174, 175):
                 # these are signing operations, they need a sig_hash
                 # to check against
                 if not operation(stack, z):
                     LOGGER.info('bad op: {}'.format(
                         OP_CODE_NAMES[instruction]))
                     return False
             else:
                 if not operation(stack):
                     LOGGER.info('bad op: {}'.format(
                         OP_CODE_NAMES[instruction]))
                     return False
         else:
             # add the instruction to the stack
             stack.append(instruction)
             # p2sh rule. if the next three instructions are:
             # OP_HASH160 <20 byte hash> OP_EQUAL this is the RedeemScript
             # OP_HASH160 == 0xa9 and OP_EQUAL == 0x87
             if len(instructions) == 3 and instructions[0] == 0xa9 \
                 and type(instructions[1]) == bytes and len(instructions[1]) == 20 \
                 and instructions[2] == 0x87:
                 redeem_script = encode_varint(
                     len(instruction)) + instruction
                 # we execute the next three opcodes
                 instructions.pop()
                 h160 = instructions.pop()
                 instructions.pop()
                 if not op_hash160(stack):
                     return False
                 stack.append(h160)
                 if not op_equal(stack):
                     return False
                 # final result should be a 1
                 if not op_verify(stack):
                     LOGGER.info('bad p2sh h160')
                     return False
                 # hashes match! now add the RedeemScript
                 redeem_script = encode_varint(
                     len(instruction)) + instruction
                 stream = BytesIO(redeem_script)
                 instructions.extend(Script.parse(stream).instructions)
             # witness program version 0 rule. if stack instructions are:
             # 0 <20 byte hash> this is p2wpkh
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20:
                 h160 = stack.pop()
                 stack.pop()
                 instructions.extend(witness)
                 instructions.extend(p2pkh_script(h160).instructions)
             # witness program version 0 rule. if stack instructions are:
             # 0 <32 byte hash> this is p2wsh
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 32:
                 h256 = stack.pop()
                 stack.pop()
                 instructions.extend(witness[:-1])
                 witness_script = witness[-1]
                 if h256 != sha256(witness_script):
                     LOGGER.info('bad sha256 {} vs {}'.format(
                         h256.hex(),
                         sha256(witness_script).hex()))
                     return False
                 # hashes match! now add the Witness Script
                 stream = BytesIO(
                     encode_varint(len(witness_script)) + witness_script)
                 witness_script_instructions = Script.parse(
                     stream).instructions
                 instructions.extend(witness_script_instructions)
     if len(stack) == 0:
         return False
     if stack.pop() == b'':
         return False
     return True
Ejemplo n.º 8
0
 def sha256(self):
     '''Return the sha256 of the serialized script (without length)'''
     return sha256(self.raw_serialize())
Ejemplo n.º 9
0
 def cipher(self, other_point: S256Point) -> CPCipher:
     '''Returns a cipher and the prefix needed by the owner of
     the private key to decrypt this message'''
     shared_secret = sha256((self.secret * other_point).sec())
     return CPCipher(shared_secret)
Ejemplo n.º 10
0
from sys import argv
from os.path import isfile, realpath, dirname
from helper import sha256
from flask import Flask
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_sqlalchemy import SQLAlchemy

# Local
from config import Config

path = dirname(realpath(__file__))
secret = "%s/app.secret" % path
if not isfile(secret):
    with open(secret, "w") as f:
        f.write(sha256())

app = Flask(__name__, static_url_path="/assets")

with open(secret, "r") as f:
    app.secret_key = f.read()

app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)

manager = None
if len(argv) > 1:
    manager = Manager(app)
    manager.add_command("db", MigrateCommand)
Ejemplo n.º 11
0
    def evaluate(self, z, witness):
        # create a copy as we may need to add to this list if we have a
        # RedeemScript
        cmds = self.cmds[:]
        stack = []
        altstack = []
        while len(cmds) > 0:
            cmd = cmds.pop(0)
            if type(cmd) == int:
                # do what the opcode says
                # retrieving the function in op.py corresponding to the opcode
                operation = OP_CODE_FUNCTIONS[cmd]
                if cmd in (99, 100):
                    # op_if/op_notif require the cmds array
                    if not operation(stack, cmds):
                        LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                        return False
                elif cmd in (107, 108):
                    # op_toaltstack/op_fromaltstack require the altstack
                    if not operation(stack, altstack):
                        LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                        return False
                elif cmd in (172, 173, 174, 175):
                    # these are signing operations, they need a sig_hash
                    # to check against
                    if not operation(stack, z):
                        LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                        return False
                else:
                    if not operation(stack):
                        LOGGER.info('bad op: {}'.format(OP_CODE_NAMES[cmd]))
                        return False
            else:
                # add the cmd to the stack
                stack.append(cmd)
                # Determine whether this is a p2sh:
                # To do so, you need to look at the next three items in the command set.
                # Are there only three items remaining in the command set and are theY:
                # 0xa9 --op_hash160, 20 bytes--for the script hash and 0x87--op_equal?
                if len(cmds) == 3 and cmds[0] == 0xa9 and type(cmds[1]) == bytes and len(cmds[1]) == 20 and cmds[2] == 0x87:  # <1>
                    cmds.pop()  # <2>
                    h160 = cmds.pop()
                    cmds.pop()
                    if not op.op_hash160(stack):  # <3>
                        return False
                    stack.append(h160)
                    if not op.op_equal(stack):
                        return False
                    if not op.op_verify(stack):  # <4>
                        LOGGER.info('bad p2sh h160')
                        return False
                    redeem_script = encode_varint(len(cmd)) + cmd  # <5>
                    stream = BytesIO(redeem_script)
                    cmds.extend(Script.parse(stream).cmds)  # <6>
                # Determine whether this is a p2wpkh. 
                # To do so, you need to look at the stack (remember focus on the stack now, not the command set).
                # Are there only two items on the stack?  is the first b'' and the second 20 bytes?
                # The 20 bytes will be the hash of the witness field.
                # If so, then use the witness field and the hash on the stack to build a p2pkh command set.
                if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20:
                    h160 = stack.pop()
                    stack.pop()
                    # witness should be two items, the signature and the public key (in bytes not BASE58)
                    cmds.extend(witness)
                    # the build out the command set with the p2pkh commands
                    cmds.extend(p2pkh_script(h160).cmds)
                    # now we have the p2pkh command set and the script evaluation proceeds...
                # Determine whether this is a p2wsh:
                # Does stack have just two items, b'' and a 32 byte hash-which hash is the witness script hash.
                # If so, check that the hash of the witness script equals the witness script hash 
                # that is already on the stack.  If so, build a command set starting with the witness filed items 
                # and then parse the witness script.  Append the parsed witness script items to the command set.
                # The p2wsh is often used for the segwit form of the m of n multisig.
                if len(stack) == 2 and stack[0] == b'' and type(stack[1]) == bytes and len(stack[1])==32:
                    s256 = stack.pop()
                    stack.pop()
                    witness_script = witness[-1]
                    if s256 != sha256(witness_script):
                        print('bad sha256 {} vs {}'.format(s256.hex(), sha256(witness_script).hex()))
                        return False
                    # If the wintess script checks out then add the witness fields to the command set--leaving the 
                    # witness script item to be parsed still
                    cmds.extend(witness[:-1])
                    # Parse the witness script--prepare it as a raw script and make into a stream first.
                    witness_script = encode_varint(len(witness_script)) + witness_script
                    witness_stream = BytesIO(witness_script)
                    witness_script_cmds = Script.parse(witness_stream).cmds
                    # Add the witness script items to the command set--these should be the script_pub_key
                    # items from a regular p2sh script_pub_key--which would be the m of n multisig.
                    cmds.extend(witness_script_cmds)

        if len(stack) == 0:
            return False
        if stack.pop() == b'':
            return False
        return True
Ejemplo n.º 12
0
def SHA256(*args):
    return sha256(b''.join(args))
Ejemplo n.º 13
0
def routing():
  global total_bytes_routed_main

  print("----Route Mode----")

  prev_hop = get_peer(peers, 'mst8broiaX4PFMFNbjfrBnMSnrVF42Jgd7')
  prev_hop_channel = get_channel(prev_hop, channels)
  sym_key_prev_hop = prev_hop.sym_key

  wallet_balance = get_total_channel_balance(channels)
  local_balance_DC = get_channel_balance(channels[0])
  local_balance_DA = get_channel_balance(channels[1])

  totalBalance.set(wallet_balance)
  channel_A_local.set(local_balance_DA)
  channel_C_local.set(local_balance_DC)

  while True:

      # receive header
      received_header = json.loads((prev_hop.receive()).decode())
      commitment_tx_prev_hop = Tx.parse(BytesIO(bytes.fromhex(received_header['commitment_tx'])))
      H = check_htlc_and_get_secret_hash(node, commitment_tx_prev_hop, prev_hop_channel)
      num_packets = received_header['num_packets']
      packet_size = received_header['packet_size']
      num_bytes = num_packets*packet_size
      #num_kilobytes = int(num_packets*packet_size/1000)

      prev_hop.send(b'header ACK')

      #receive packets
      packet_payloads = []
      for i in range(num_packets):
        packet_payloads.append(prev_hop.receive())
        prev_hop.send(b'packet ACK')
        
      cost_paid = int(route_cost(received_header['route'], num_bytes))
      
      #adapt header for next hop
      header = received_header
      header['route'] = received_header['route'][1:]
      cost_to_pay = int(route_cost(header['route'], num_bytes))

      next_hop = get_peer(peers, header['route'][0][0])
      next_hop_channel = get_channel(next_hop, channels)

      commitment_tx_next_hop = new_commitment_tx(node, next_hop_channel, cost_to_pay, H)
      header['commitment_tx'] = str(commitment_tx_next_hop.serialize().hex())

      #send header
      next_hop.send(str.encode(json.dumps(header)))

      if(next_hop.receive()==b'header ACK'):

        for i in range(num_packets):
          next_hop.send(packet_payloads[i])
          next_hop.receive()

      reply = json.loads(next_hop.receive().decode())
      commitment_tx_next_hop = Tx.parse(BytesIO(bytes.fromhex(reply['commitment_tx'])))
      revealed_secret = reply['secret']

      if(not (H == None) and (sha256(str.encode(str(revealed_secret))) == H)):
          print("I can sign the htlc output with the secret")

          next_hop_channel.pay(cost_to_pay)

          #sign the commitment tx
          commitment_tx_prev_hop.tx_ins[0].script_sig = get_script_sig(commitment_tx_prev_hop, node.private_key)

          reply = {"commitment_tx": str(commitment_tx_prev_hop.serialize().hex()), "secret": revealed_secret}

          prev_hop.send(str.encode(json.dumps(reply)))

          prev_hop_channel.paid(cost_paid)
          
          for c in channels:
            print(c)

          total_bytes_routed_main += num_bytes
          total_bytes_routed.set(total_bytes_routed_main)

          wallet_balance = get_total_channel_balance(channels)
          local_balance_DC = get_channel_balance(channels[0])
          local_balance_DA = get_channel_balance(channels[1])

          totalBalance.set(wallet_balance)
          channel_A_local.set(local_balance_DA)
          channel_C_local.set(local_balance_DC)

          print("Total Balance: "+str(wallet_balance))

      else:
          print("Cannot unlock HTLC")
Ejemplo n.º 14
0
 def evaluate(self, z, witness, version=None, locktime=None, sequence=None):
     # get a copy of the commands array.
     cmds = self.cmds.copy()
     stack = []
     altstack = []
     # execute until commands array is empty.
     while len(cmds) > 0:
         cmd = cmds.pop(0)
         print("cmd", cmd)
         # if command is an opcode.
         if type(cmd) == int:
             # get the function that executes the opcode from the OP_CODE_FUNCTIONS array.
             operation = OP_CODE_FUNCTIONS[cmd]
             # 99 and 100 are OP_IF and OP_NOTIF. They require manipulations of the cmds array based on
             # the top element of the stack.
             if cmd in (99, 100):
                 # if executing the opcode returns False (fails)
                 if not operation(stack, cmds):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
             # 107 and 108 are OP_TOALTSTACK and OP_FROMALTSTACK respectively. They move stack elements
             # to an alternate stack (altstack)
             elif cmd in (107, 108):
                 # if executing the opcode returns False (fails)
                 if not operation(stack, altstack):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
             # 172, 173, 174 and 175 are OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY
             # all require the signature hash z for validation.
             elif cmd in (172, 173, 174, 175):
                 # if executing the opcode returns False (fails)
                 if not operation(stack, z):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
             # 177 is OP_CHECKLOCKTIMEVERIFY. Requires locktime and sequence.
             elif cmd == 177:
                 # if executing the opcode returns False (fails)
                 if not operation(stack, locktime, sequence):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
             # 177 is OP_CHECKSEQUENCEVERIFY. Requires sequence and version.
             elif cmd == 178:
                 # if executing the opcode returns False (fails)
                 if not operation(stack, version, sequence):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
             else:
                 # if executing the opcode returns False (fails)
                 if not operation(stack):
                     LOGGER.info(f"bad op: {OP_CODE_NAMES[cmd]}")
                     return False
         # if cmd is not an opcode, it's an element. We push it to the stack.
         else:
             stack.append(cmd)
             # We check if the commands follow the p2wsh special rule.
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 32:
                 # The top element is the sha256 hash of the WitnessScript.
                 s256 = stack.pop()
                 # The second element is the witness version.
                 stack.pop()
                 # Everything but the WitnessScript is added to the command set.
                 cmds.extend(witness[:-1])
                 witness_script = witness[-1]
                 s256_calculated = sha256(witness_script)
                 if s256 != s256_calculated:
                     print(
                         f"Bad sha256 {s256.hex()} vs. {s256_calculated.hex()}"
                     )
                     return False
                 stream = BytesIO(
                     encode_varint(len(witness_script)) + witness_script)
                 witness_script_cmds = Script.parse(stream).cmds
                 cmds.extend(witness_script_cmds)
             # We check if the commands follow the p2wpkh special rule - page 235.
             if len(stack) == 2 and stack[0] == b'' and len(stack[1]) == 20:
                 h160 = stack.pop()
                 stack.pop()
                 cmds.extend(witness)
                 cmds.extend(p2pkh_script(h160).cmds)
             # we check if next commands form the pattern that executes the special p2sh rule - page 152 and 156.
             # if that is the case, the last cmd appended would be the RedeemScript, which is an element.
             # That's why we check for the next 3 commands only.
             # Specifically, we check that they are: OP_HASH160 (0xa9), a hash element and OP_EQUAL(0x87).
             if len(cmds) == 3 and cmds[0] == 0xa9 and type(
                     cmds[1]) == bytes and len(
                         cmds[1]) == 20 and cmds[2] == 0x87:
                 # we run the sequence manually.
                 cmds.pop()
                 # the only value we need to save is the hash, the other two we know are OP_HASH160 and OP_EQUAL.
                 h160 = cmds.pop()
                 cmds.pop()
                 # first we perform the op_hash160 on the current stack, which hashes the top element of the stack.
                 if not op_hash160(stack):
                     return False
                 # then we push the hash160 we got in the commands to the stack.
                 stack.append(h160)
                 # next we perform an op_equal, which compares the 2 top most elements of the stack.
                 if not op_equal(stack):
                     return False
                 # next we need to check if the element left on the stack is a 1, which is what op_verify does.
                 if not op_verify(stack):
                     LOGGER.info('bad p2sh h160')
                     return False
                 # if we got to this point, we know cmd is the RedeemScrtipt.
                 # to be able to parse it, we need to prepend its length.
                 redeem_script = encode_varint(len(cmd)) + cmd
                 # we convert the script into a stream of bytes.
                 stream = BytesIO(redeem_script)
                 # we get the parsed script
                 parsed_script = Script.parse(stream)
                 # we extend the commands set with the commands from the parsed RedeemScript.
                 cmds.extend(parsed_script.cmds)
     # if stack is empty after running all the commands, we fail the script returning False.
     if len(stack) == 0:
         return False
     # if the stack's top element is an empty byte, which is how the stack stores a 0, we fail the script.
     if stack.pop() == b'':
         return False
     # any other result means the script is valid.
     return True
Ejemplo n.º 15
0
def send_packets():
    global packet_size_main
    global num_packets_main
    global total_bytes_sent_main
    global go

    # destination (C's address (or rather, the Gateways BTC address))
    destination = 'n1weDdde5xXLfPeutESLaG8swr5jLCqz72'
    sym_key_dest = get_peer(peers, destination).sym_key

    wallet_balance = get_total_channel_balance(channels)
    local_balance_AB = get_channel_balance(channels[0])
    local_balance_AD = get_channel_balance(channels[1])
    totalBalance.set(wallet_balance)
    channel_B_local.set(local_balance_AB)
    channel_D_local.set(local_balance_AD)

    while True:

        #packet_size_freeze = packet_size_main*1000 #convert from kB to B

        #num_kilobytes = int(num_bytes/1000)

        if (packet_size_main > 0 and num_packets_main > 0 and go == True):
            packet_size_freeze = packet_size_main
            num_packets_freeze = num_packets_main
            num_bytes = packet_size_freeze * num_packets_freeze

            # find routes
            routes = [[[
                'mfwnjj1Jbd1uwXbj5Q4FUjmkEcGqQQsYDn',
                prices['mfwnjj1Jbd1uwXbj5Q4FUjmkEcGqQQsYDn']
            ],
                       [
                           'n1weDdde5xXLfPeutESLaG8swr5jLCqz72',
                           prices['n1weDdde5xXLfPeutESLaG8swr5jLCqz72']
                       ]],
                      [[
                          'mmqrZXdvAi8mcjvXGJX2eJdA37kWXmCWjW',
                          prices['mmqrZXdvAi8mcjvXGJX2eJdA37kWXmCWjW']
                      ],
                       [
                           'n1weDdde5xXLfPeutESLaG8swr5jLCqz72',
                           prices['n1weDdde5xXLfPeutESLaG8swr5jLCqz72']
                       ]]]

            #body: secret and actual message -> encrypt for destination

            packet_payloads = []

            if (num_packets_freeze == 1):
                X = randint(1000000000000000000000000000000000000000,
                            2000000000000000000000000000000000000000)
                shares = [X]
            else:
                X, shares = shamir.make_random_shares(num_packets_freeze,
                                                      num_packets_freeze)

            H = sha256(str.encode(str(X)))

            for i in range(num_packets_freeze):
                message = secrets.token_urlsafe(packet_size_freeze)
                secret_share = str(shares[i])
                body = {"secret_share": secret_share, "message": message}
                encrypted_body = encrypt(str.encode(json.dumps(body)),
                                         sym_key_dest.sec())
                packet_payloads.append(encrypted_body)

            success = False

            while success == False:

                # Find cost of each route and choose cheapest
                cheap_route_index = find_cheapest_route(routes)
                cheapest_route = routes[cheap_route_index]

                # get next hop from route and hence get relevent channel
                next_hop = get_peer(peers, routes[cheap_route_index][0][0])
                next_hop_channel = get_channel(next_hop, channels)

                cost = route_cost(cheapest_route, num_bytes)
                commitment_tx = new_commitment_tx(node, next_hop_channel, cost,
                                                  H)
                #print(commitment_tx.serialize().hex())
                header = {
                    "source": node.address,
                    "route": cheapest_route,
                    "num_packets": num_packets_freeze,
                    "packet_size": packet_size_freeze,
                    "commitment_tx": str(commitment_tx.serialize().hex())
                }

                # send header
                next_hop.send(str.encode(json.dumps(header)))

                if (next_hop.receive() == b'header ACK'):

                    for i in range(num_packets_freeze):
                        print(sys.getsizeof(packet_payloads[i]))
                        next_hop.send(packet_payloads[i])
                        next_hop.receive()

                reply = json.loads(next_hop.receive().decode())
                commitment_tx = Tx.parse(
                    BytesIO(bytes.fromhex(reply['commitment_tx'])))
                revealed_secret = reply['secret']

                if (revealed_secret == X):
                    print(
                        "Successful delivery of message proven. Thus update channel state"
                    )
                    success = True

                    next_hop_channel.pay(commitment_tx.tx_outs[2].amount)

                    print(get_channel(next_hop, channels))

                    total_bytes_sent_main += num_bytes
                    total_bytes_sent.set(total_bytes_sent_main)

                    wallet_balance = get_total_channel_balance(channels)
                    local_balance_AB = get_channel_balance(channels[0])
                    local_balance_AD = get_channel_balance(channels[1])

                    totalBalance.set(wallet_balance)
                    channel_B_local.set(local_balance_AB)
                    channel_D_local.set(local_balance_AD)

                    print("Total Balance: " + str(wallet_balance))
                    go = False

                else:
                    print(
                        "Malicious node detected, choose next cheapest route")
                    routes.pop(cheap_route_index)
                    go = False
Ejemplo n.º 16
0
 def cipher(cls, salt, iv, password):
     key = password + salt
     for _ in range(KEY_ITERATIONS):
         key = sha256(key)
     return AES.new(key, AES.MODE_CBC, iv)
Ejemplo n.º 17
0
def sock_checker(node_address):
    global total_bytes_received_main

    prev_hop = get_peer(peers, node_address)
    current_channel = get_channel(prev_hop, channels)
    sym_key_prev_hop = prev_hop.sym_key

    while True:

        received_header = json.loads((prev_hop.receive()).decode())
        source = get_peer(peers, received_header['source'])
        commitment_tx = Tx.parse(
            BytesIO(bytes.fromhex(received_header['commitment_tx'])))
        H = check_htlc_and_get_secret_hash(node, commitment_tx,
                                           current_channel)
        num_packets = received_header['num_packets']
        packet_size = received_header['packet_size']
        num_bytes = num_packets * packet_size
        #num_kilobytes = int(num_packets*packet_size/1000)

        prev_hop.send(b'header ACK')

        #receive body
        sym_key_source = source.sym_key

        packet_payloads = []

        for i in range(num_packets):
            packet_payloads.append(prev_hop.receive())
            prev_hop.send(b'packet ACK')

        #decode packets
        decoded_packets = []
        for i in range(len(packet_payloads)):
            decoded_packets.append(
                json.loads(
                    decrypt(packet_payloads[i],
                            sym_key_source.sec()).decode()))

        #get the shares
        if (num_packets == 1):
            revealed_secret = int(decoded_packets[0]['secret_share'])
        else:
            shares = []
            for i in range(len(decoded_packets)):
                shamir_share = decoded_packets[i]['secret_share']
                x, y = map(int, shamir_share.strip('()').split(','))
                shares.append((x, y))

            revealed_secret = shamir.recover_secret(shares)

        #check that you can suceesfully unlock the htlc output
        if (not (H == None)
                and (sha256(str.encode(str(revealed_secret))) == H)):
            print("I can sign the htlc output with the secret")

            #sign the commitment tx
            commitment_tx.tx_ins[0].script_sig = get_script_sig(
                commitment_tx, node.private_key)

            reply = {
                "commitment_tx": str(commitment_tx.serialize().hex()),
                "secret": revealed_secret
            }

            prev_hop.send(str.encode(json.dumps(reply)))

            current_channel.paid(commitment_tx.tx_outs[2].amount)
            print(current_channel)

            total_bytes_received_main += num_bytes
            total_bytes_received.set(total_bytes_received_main)

            wallet_balance = get_total_channel_balance(channels)
            local_balance_CB = get_channel_balance(channels[0])
            local_balance_CD = get_channel_balance(channels[1])

            totalBalance.set(wallet_balance)
            channel_B_local.set(local_balance_CB)
            channel_D_local.set(local_balance_CD)

            print("Total Balance: " + str(get_total_channel_balance(channels)))

        else:
            print("Cannot unlock HTLC")
Ejemplo n.º 18
0
 def sha256(self):
     '''Returns the sha256 of the raw serialization for witness program'''
     return sha256(self.raw_serialize())