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