Пример #1
0
 def test_keysigs(self):
     m = hashlib.sha256()
     m.update(b"Nobody respects")
     m.update(b" the spammish repetition")
     skx, pkx = genkeys(n, p, g)
     hm = int(m.hexdigest(), 16)
     sig = sign(skx, hm, p, g)
     self.assertTrue(verify(pkx, sig, hm, p, g))
     self.assertFalse(verify(pkx, sig, hm + 1, p, g))
Пример #2
0
    def sign_pre_images(self, PreImages, sk):
        signatures = []

        for image in PreImages:
            sigHash = dbl256(image.decode("hex"))
            signature = keys.sign(sk, sigHash)
            sig_type = signature.encode("hex") + "01"
            signatures.append(sig_type)

        return signatures
Пример #3
0
 def test_keysigs(self):
     msg = [
         b"4194909766994028808293623689273419362309706882612353484933795166041013714163",
         b"81514427175971543293164191618001506196838267623329851389681647701779330840600",
         b"17252908227080267616614312042183132638406086197574336239937230109815325852588"
     ]
     for i in range(len(msg)):
         m = hashlib.sha256()
         m.update(msg[i])
         skx, pkx = genkeys()
         hm = int(m.hexdigest(), 16)
         sig = sign(skx, hm)
         self.assertTrue(verify(pkx, sig, hm))
         self.assertFalse(verify(pkx, sig, hm + 1))
Пример #4
0
    def sign_legacy_tx(self):
        transaction = self.raw["nVersion"]

        # inputs
        transaction += self.rtxin["count"]

        for i in range(self.incount):
            transaction += self.rtxin["hash"][i]
            transaction += self.rtxin["index"][i]
            transaction += "{" + str(i) + "}"  # format
            transaction += self.rtxin["sequence"][i]

        # outputs
        transaction += self.serialize_outputs()

        # locktime and hashtype
        transaction += self.raw["nLocktime"]
        transaction += self.hashtype

        # signing
        is_compr = keys.is_compr_addr(self.my_addr, self.my_pk, self.testnet)

        if is_compr:
            sk, my_publ = keys.get_compressed_publ(self.my_pk)
        else:
            sk, my_publ = keys.get_uncompressed_publ(self.my_pk)

        my_program = self.get_program(self.my_addr, is_compr).encode("hex")
        scriptSig = self.varstr("76a914" + my_program + "88ac")

        my_publ_vs = self.varstr(my_publ, is_hex=False)

        scriptSigs = []

        for i in range(self.incount):
            sign_this = self.format_scripts(transaction, i, scriptSig)
            sigHash = dbl256(sign_this.decode("hex"))
            sig_type = keys.sign(sk, sigHash).encode("hex") + "01"
            ss = self.varstr(sig_type) + my_publ_vs
            scriptSigs.append(ss)
        """ [:-8] to remove the sighashtype """
        signed_tx = self.replace_scriptsigs(transaction, scriptSigs)[:-8]

        return signed_tx
Пример #5
0
    def test_5(self):
        possibleTxs = []
        print("Test 5: test isValidTx() with some invalid transactions")
        nPeople = 10
        people = [] #new list of KeyPair
        for i in range(nPeople):
           sk,pk = genkeys(n,p,g)
           people.append((sk,pk))

# Create a pool and an index into key pairs
        utxoPool = UTXOPool()
        utxoToKeyPair = {}
        keyPairAtIndex = {}
        nUTXOTx=10
        maxUTXOTxOutput = 5
        maxInput = 3
        maxValue = 100

        for i in range(nUTXOTx):
           num = random.randint(1,maxUTXOTxOutput)
           tx = Transaction()
           # add num randonm outputs to tx
           for j in range(num):
              # pick a random public address
              rIndex = random.randint(0,len(people)-1)
              #print("Index",rIndex); print(people[rIndex])
              addr = people[rIndex][1]  #(sk,pk)
              value = random.random() * maxValue
              tx.addOutput(value, addr);
              keyPairAtIndex[j] = people[rIndex]
           tx.finalize()
         # add all num tx outputs to utxo pool
           for j in range(num):
              ut = UTXO(tx.getHash(), j)
              utxoPool.addUTXO(ut, tx.getOutput(j))
              utxoToKeyPair[ut] = keyPairAtIndex[j]

        print("Len of utxoSet", len(utxoPool.getAllUTXO()))
        maxValidInput = min(maxInput, len(utxoPool.getAllUTXO()))

        nTxPerTest= 11
        maxValidInput = 2
        maxOutput = 3
        passes = True
        txHandler = TxHandler(utxoPool)

        for i in range(nTxPerTest):
           tx = Transaction()
           uncorrupted = True
           utxoAtIndex = {}
           nInput = random.randint(1,maxValidInput+ 1)
           inputValue = 0.0

           # We're using this as our sample space to pull UTXOs from for
           # a Transaction's input. This is helpful because it ensures that
           # we never introduce a duplicate UTXO for an input of a valid Transaction.
           utxoSet = set(utxoPool.getAllUTXO())

           for j in range(nInput):
              utxo = random.sample(utxoSet, 1)[0]
              tx.addInput(utxo.getTxHash(), utxo.getIndex())
              utxoSet.remove(utxo) # See comment in test_1.py
              inputValue += utxoPool.getTxOutput(utxo).value
              utxoAtIndex[j] = utxo
           nOutput = random.randint(1,maxOutput)
           outputValue = 0.0
           for j in range(nOutput):
               value = random.random()*(maxValue)
               if (outputValue + value > inputValue):
                  break
               rIndex = random.randint(0,len(people)-1)
               addr = people[rIndex][1]
               tx.addOutput(value, addr)
               outputValue += value

           pCorrupt = 0.5
           for j in range(nInput):
                 m=hashlib.sha256()
                 m.update(str.encode(tx.getRawDataToSign(j)))
                 hm = int(m.hexdigest(),16)
                 if (random.random() < pCorrupt):
                     hm += 1
                     uncorrupted = False
                 keyPair = utxoToKeyPair[utxoAtIndex[j]]
                 tx.addSignature(sign(keyPair[0], hm,p,g), j)

           tx.finalize()

           possibleTxs.append(tx)

           if (txHandler.isValidTx(tx) != uncorrupted):
             passes = False
        self.assertTrue(passes)

        valid_txs = txHandler.handleTxs(possibleTxs)
        is_valid = False

        for tx in valid_txs:
           if txHandler.isValidTx(tx):
               is_valid = True
           else:
               break

        self.assertTrue(is_valid)
Пример #6
0
    def test_2(self):
        print("Test 2: test isValidTx() with some invalid transactions")
        nPeople = 10
        people = []  #new list of KeyPair
        for i in range(nPeople):
            sk, pk = genkeys(n, p, g)
            people.append((sk, pk))


# Create a pool and an index into key pairs
        utxoPool = UTXOPool()
        utxoToKeyPair = {}
        keyPairAtIndex = {}
        nUTXOTx = 10
        maxUTXOTxOutput = 5
        maxInput = 3
        maxValue = 100

        for i in range(nUTXOTx):
            num = random.randint(1, maxUTXOTxOutput)
            tx = Transaction()
            # add num randonm outputs to tx
            for j in range(num):
                # pick a random public address
                rIndex = random.randint(0, len(people) - 1)
                #print("Index",rIndex); print(people[rIndex])
                addr = people[rIndex][1]  #(sk,pk)
                value = random.random() * maxValue
                tx.addOutput(value, addr)
                keyPairAtIndex[j] = people[rIndex]
            tx.finalize()
            # add all num tx outputs to utxo pool
            for j in range(num):
                ut = UTXO(tx.getHash(), j)
                utxoPool.addUTXO(ut, tx.getOutput(j))
                utxoToKeyPair[ut] = keyPairAtIndex[j]

        utxoSet = utxoPool.getAllUTXO()
        print("Len of utxoSet", len(utxoSet))
        maxValidInput = min(maxInput, len(utxoSet))

        nTxPerTest = 1000
        maxValidInput = 2
        maxOutput = 3
        passes = True

        for i in range(nTxPerTest):
            pks = []
            usedInputs = set()
            tx = Transaction()

            uncorrupted = True
            utxoAtIndex = {}
            nInput = random.randint(1, maxValidInput + 1)
            inputValue = 0.0
            for j in range(nInput):
                utxo = random.sample(utxoSet, 1)[0]
                while ((utxo.getTxHash(), utxo.getIndex()) in usedInputs):
                    utxo = random.sample(utxoSet, 1)[0]
                usedInputs.add((utxo.getTxHash(), utxo.getIndex()))
                tx.addInput(utxo.getTxHash(), utxo.getIndex())
                inputValue += utxoPool.getTxOutput(utxo).value
                utxoAtIndex[j] = utxo
            nOutput = random.randint(1, maxOutput)
            outputValue = 0.0
            for j in range(nOutput):
                value = random.random() * (maxValue)
                if (outputValue + value > inputValue):
                    break
                rIndex = random.randint(0, len(people) - 1)
                addr = people[rIndex][1]
                tx.addOutput(value, addr)
                outputValue += value

            pCorrupt = 0.5
            for j in range(nInput):
                m = hashlib.sha256()
                m.update(str.encode(tx.getRawDataToSign(j)))
                hm = int(m.hexdigest(), 16)
                if (random.random() < pCorrupt):
                    hm += 1
                    uncorrupted = False
                keyPair = utxoToKeyPair[utxoAtIndex[j]]
                tx.addSignature(sign(keyPair[0], hm), j)
                pks.append(utxoToKeyPair[utxoAtIndex[j]][1])
            tx.finalize()
            if (txHandler.isValidTx(tx, utxoPool, pks) != uncorrupted):
                passes = False
        self.assertTrue(passes)
Пример #7
0
    def test_3(self):
        print(
            "Test 3: test isValidTx() with transactions containing signatures using incorrect private keys"
        )
        nPeople = 10
        people = []  #new List RSAKeyPair
        for i in range(nPeople):
            sk, pk = genkeys(n, p, g)
            people.append((sk, pk))


# Create a pool and an index into key pairs
        utxoPool = UTXOPool()
        utxoToKeyPair = {}
        keyPairAtIndex = {}
        nUTXOTx = 10
        maxUTXOTxOutput = 5
        maxInput = 3
        maxValue = 100

        for i in range(nUTXOTx):
            num = random.randint(1, maxUTXOTxOutput)
            tx = Transaction()
            # add num randonm outputs to tx
            for j in range(num):
                # pick a random public address
                rIndex = random.randint(0, len(people) - 1)
                #print("Index",rIndex); print(people[rIndex])
                addr = people[rIndex][1]  #(sk,pk)
                value = random.random() * maxValue
                tx.addOutput(value, addr)
                keyPairAtIndex[j] = people[rIndex]
            tx.finalize()
            # add all num tx outputs to utxo pool
            for j in range(num):
                ut = UTXO(tx.getHash(), j)
                utxoPool.addUTXO(ut, tx.getOutput(j))
                utxoToKeyPair[ut] = keyPairAtIndex[j]

        print("Len of utxoSet", len(utxoPool.getAllUTXO()))
        maxValidInput = min(maxInput, len(utxoPool.getAllUTXO()))

        nTxPerTest = 11
        maxValidInput = 2
        maxOutput = 3
        passes = True
        txHandler = TxHandler(utxoPool)

        for i in range(nTxPerTest):
            tx = Transaction()
            uncorrupted = True
            utxoAtIndex = {}
            nInput = random.randint(1, maxValidInput + 1)
            inputValue = 0.0

            # We're using this as our sample space to pull UTXOs from for
            # a Transaction's input. This is helpful because it ensures that
            # we never introduce a duplicate UTXO for an input of a valid Transaction.
            utxoSet = set(utxoPool.getAllUTXO())

            for j in range(nInput):
                utxo = random.sample(utxoSet, 1)[0]
                tx.addInput(utxo.getTxHash(), utxo.getIndex())
                utxoSet.remove(utxo)  # See comment in test_1.py
                inputValue += utxoPool.getTxOutput(utxo).value
                utxoAtIndex[j] = utxo
            nOutput = random.randint(1, maxOutput)
            outputValue = 0.0
            for j in range(nOutput):
                value = random.random() * (maxValue)
                if (outputValue + value > inputValue):
                    break
                rIndex = random.randint(0, len(people) - 1)
                addr = people[rIndex][1]
                tx.addOutput(value, addr)
                outputValue += value

            pCorrupt = 0.5

            for j in range(nInput):
                m = hashlib.sha256()
                m.update(str.encode(tx.getRawDataToSign(j)))
                hm = int(m.hexdigest(), 16)

                keyPair = utxoToKeyPair[utxoAtIndex[j]]
                if (random.random() < pCorrupt):
                    # Attempt to corrupt the signature.
                    potential_key_pair = people[random.randint(0, nPeople - 1)]
                    if potential_key_pair[0] is not keyPair[0]:
                        # Only consider _different_ randomly chosen keys
                        # as "corrupted".
                        keyPair = potential_key_pair
                        uncorrupted = False

                tx.addSignature(sign(keyPair[0], hm, p, g), j)

            tx.finalize()
            if (txHandler.isValidTx(tx) != uncorrupted):
                print("Corrupted keys:", not uncorrupted)
                print("isValidTx got:", txHandler.isValidTx(tx))
                passes = False
        self.assertTrue(passes)
Пример #8
0
    def test_4(self):
        possibleTxs = []
        print("Test 4: test isValidTx() with valid transactions")
        nPeople = 10
        people = []  #new List DigSigKeyPair
        # Create |nPeople| pairs of {secret, public} keys.
        for i in range(nPeople):
            sk, pk = genkeys(n, p, g)
            people.append((sk, pk))

        # Create a pool and an index into key pairs
        utxoPool = UTXOPool()
        utxoToKeyPair = {}  # {UTXO: (sk, pk)}

        # |keyPairAtIndex| maps {idx: (sk, pk)}, so we
        # can know a person's keys for a given
        # Transaction.Output in a Transaction.
        keyPairAtIndex = {}
        nUTXOTx = 10
        maxUTXOTxOutput = 5
        maxInput = 3
        maxValue = 100

        # For num Transaction()s:
        for i in range(nUTXOTx):
            num = random.randint(1, maxUTXOTxOutput)
            tx = Transaction()
            # Add num random outputs to tx.
            for j in range(num):
                # Pick a random public address and transaction value.
                rIndex = random.randint(0, len(people) - 1)
                #print("Index",rIndex); print(people[rIndex])
                addr = people[rIndex][1]  #(sk,pk)
                value = random.random() * maxValue
                tx.addOutput(value, addr)
                keyPairAtIndex[j] = people[rIndex]
            tx.finalize()

            # Add all of the Transaction's outputs to UTXOPool.
            for j in range(num):
                ut = UTXO(tx.getHash(), j)
                utxoPool.addUTXO(ut, tx.getOutput(j))
                utxoToKeyPair[ut] = keyPairAtIndex[j]

        # At this point we have a UTXOPool with all of the generated UTXOs
        # in the form of:
        #   {UTXO(TransactionHash, TransactionIndex): Transaction.Output},
        # as well as a map {UTXO: (sk, pk)}, so we can book-keep the
        # identities of the UTXO "authors" for testing.

        print("Len of utxoSet", len(utxoPool.getAllUTXO()))
        maxValidInput = min(maxInput, len(utxoPool.getAllUTXO()))

        nTxPerTest = 11
        maxValidInput = 2
        maxOutput = 3
        passes = True
        txHandler = TxHandler(utxoPool)

        for i in range(nTxPerTest):
            tx = Transaction()  # Create a new Transaction.
            utxoAtIndex = {}
            nInput = random.randint(1, maxValidInput + 1)
            inputValue = 0.0

            # We're using this as our sample space to pull UTXOs from for
            # a Transaction's input. This is helpful because it ensures that
            # we never introduce a duplicate UTXO for an input of a valid Transaction.
            utxoSet = set(utxoPool.getAllUTXO())

            # Add a bunch of inputs to |tx|.
            for j in range(nInput):
                # Choose a random UTXO to fund the input.
                # There is a non-zero chance that this could actually
                # pick duplicate UTXOs for a Transaction's input, thus
                # breaking the test.
                utxo = random.sample(utxoSet, 1)[0]
                tx.addInput(utxo.getTxHash(), utxo.getIndex())
                utxoSet.remove(
                    utxo)  # Ensure we do not pick this UTXO as another input.
                inputValue += utxoPool.getTxOutput(utxo).value
                utxoAtIndex[j] = utxo

            nOutput = random.randint(1, maxOutput)
            outputValue = 0.0

            # Add a bunch of outputs to |tx|, as long as the sum of
            # all of the outputs <= the sum of the inputs.
            for j in range(nOutput):
                value = random.random() * (maxValue)
                if (outputValue + value >
                        inputValue):  # Keep the transaction valid.
                    break

                # Pick a random person to send the $ to.
                rIndex = random.randint(0, len(people) - 1)
                addr = people[rIndex][1]  # Random person's public key address.
                tx.addOutput(value, addr)
                outputValue += value

            # Sign each input of the transaction.
            for j in range(nInput):
                m = hashlib.sha256()
                m.update(str.encode(tx.getRawDataToSign(j)))
                hm = int(m.hexdigest(), 16)
                signature = sign(utxoToKeyPair[utxoAtIndex[j]][0], hm, p, g)
                tx.addSignature(signature, j)

            # Compute overall transaction hash.
            tx.finalize()

            possibleTxs.append(tx)

            if (not txHandler.isValidTx(tx)):
                passes = False
        self.assertTrue(passes)

        valid_txs = txHandler.handleTxs(possibleTxs)
        is_valid = False

        for tx in valid_txs:
            if txHandler.isValidTx(tx):
                is_valid = True
            else:
                break

        self.assertTrue(is_valid)
Пример #9
0
    def test_3(self):
        print("Test 3: test isValidTx() with transactions containing signatures using incorrect private keys")
        nPeople = 10
        people = [] #new List RSAKeyPair
        for i in range(nPeople):
           sk,pk = genkeys(n,p,g)
           people.append((sk,pk))
        
# Create a pool and an index into key pairs
        utxoPool = UTXOPool()     
        utxoToKeyPair = {}
        keyPairAtIndex = {}
        nUTXOTx=10
        maxUTXOTxOutput = 5
        maxInput = 3
        maxValue = 100

        for i in range(nUTXOTx):
           num = random.randint(1,maxUTXOTxOutput)
           tx = Transaction()
           # add num randonm outputs to tx
           for j in range(num):
              # pick a random public address
              rIndex = random.randint(0,len(people)-1)
              #print("Index",rIndex); print(people[rIndex])
              addr = people[rIndex][1]  #(sk,pk)
              value = random.random() * maxValue
              tx.addOutput(value, addr);
              keyPairAtIndex[j] = people[rIndex]
           tx.finalize()
         # add all num tx outputs to utxo pool
           for j in range(num):
              ut = UTXO(tx.getHash(), j)
              utxoPool.addUTXO(ut, tx.getOutput(j))
              utxoToKeyPair[ut] = keyPairAtIndex[j]

        utxoSet = utxoPool.getAllUTXO()
        print("Len of utxoSet", len(utxoSet))
        maxValidInput = min(maxInput, len(utxoSet))

        nTxPerTest= 11
        maxValidInput = 2
        maxOutput = 3
        passes = True

        for i in range(nTxPerTest):         
           tx = Transaction()
           uncorrupted = True
           utxoAtIndex = {}
           nInput = random.randint(1,maxValidInput+ 1)
           inputValue = 0.0
           for j in range(nInput):
              utxo = random.sample(utxoSet,1)[0]
              tx.addInput(utxo.getTxHash(), utxo.getIndex())
              inputValue += utxoPool.getTxOutput(utxo).value
              utxoAtIndex[j] = utxo
           nOutput = random.randint(1,maxOutput)
           outputValue = 0.0
           for j in range(nOutput):
               value = random.random()*(maxValue)
               if (outputValue + value > inputValue):
                  break
               rIndex = random.randint(0,len(people)-1)
               addr = people[rIndex][1]
               tx.addOutput(value, addr)
               outputValue += value
           pCorrupt = 0.1
           for j in range(nInput):
              keyPair = utxoToKeyPair[utxoAtIndex][j]
              if (random.random() < pCorrupt):
                  index = people.indexOf(keyPair);
                  keyPair = people[(index + 1) % nPeople]
                 uncorrupted = False
         
           for j in range(nInput):
             tx.addSignature(sign(utxoToKeyPair[utxoAtIndex[j]][0], tx.getRawDataToSign(j),p,g), j)
         
           tx.finalize()
           if (txHandler.isValidTx(tx) != uncorrupted):
             passes = False
        self.assertTrue(passes)