def testVerifyEncryptionKey(self): testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) theIV = SecureBinaryData(hex_to_binary(INIT_VECTOR)) testAddr.enableKeyEncryption(theIV) self.assertFalse(testAddr.verifyEncryptionKey(FAKE_KDF_OUTPUT1)) testAddr.lock(FAKE_KDF_OUTPUT1) self.assertTrue(testAddr.verifyEncryptionKey(FAKE_KDF_OUTPUT1)) self.assertFalse(testAddr.verifyEncryptionKey(FAKE_KDF_OUTPUT2))
def checkSig(self,binSig, binPubKey, txOutScript, txInTx, txInIndex, lastOpCodeSep=None): """ Generic method for checking Bitcoin tx signatures. This needs to be used for both OP_CHECKSIG and OP_CHECKMULTISIG. Step 1 is to pop signature and public key off the stack, which must be done outside this method and passed in through the argument list. The remaining steps do not require access to the stack. """ # 2. Subscript is from latest OP_CODESEPARATOR until end... if DNE, use whole script subscript = txOutScript if lastOpCodeSep: subscript = subscript[lastOpCodeSep:] # 3. Signature is deleted from subscript # I'm not sure why this line is necessary - maybe for non-standard scripts? lengthInBinary = int_to_binary(len(binSig)) subscript = subscript.replace( lengthInBinary + binSig, "") # 4. Hashtype is popped and stored hashtype = binary_to_int(binSig[-1]) justSig = binSig[:-1] if not hashtype == 1: LOGERROR('Non-unity hashtypes not implemented yet! (hashtype = %d)', hashtype) assert(False) # 5. Make a copy of the transaction -- we will be hashing a modified version txCopy = PyTx().unserialize( txInTx.serialize() ) # 6. Remove all OP_CODESEPARATORs subscript.replace( int_to_binary(OP_CODESEPARATOR), '') # 7. All the TxIn scripts in the copy are blanked (set to empty string) for txin in txCopy.inputs: txin.binScript = '' # 8. Script for the current input in the copy is set to subscript txCopy.inputs[txInIndex].binScript = subscript # 9. Prepare the signature and public key senderAddr = PyBtcAddress().createFromPublicKey(binPubKey) binHashCode = int_to_binary(hashtype, widthBytes=4) toHash = txCopy.serialize() + binHashCode # Hashes are computed as part of CppBlockUtils::CryptoECDSA methods ##hashToVerify = hash256(toHash) ##hashToVerify = binary_switchEndian(hashToVerify) # 10. Apply ECDSA signature verification if senderAddr.verifyDERSignature(toHash, justSig): return True else: return False
def testCopy(self): testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) testCopy = testAddr.copy() self.assertEqual(testAddr.binPrivKey32_Plain, testCopy.binPrivKey32_Plain) self.assertEqual(testAddr.binPrivKey32_Encr, testCopy.binPrivKey32_Encr) self.assertEqual(testAddr.binPublicKey65, testCopy.binPublicKey65) self.assertEqual(testAddr.binInitVect16, testCopy.binInitVect16) self.assertEqual(testAddr.isLocked, testCopy.isLocked) self.assertEqual(testAddr.useEncryption, testCopy.useEncryption) self.assertEqual(testAddr.isInitialized, testCopy.isInitialized) self.assertEqual(testAddr.keyChanged, testCopy.keyChanged) self.assertEqual(testAddr.walletByteLoc, testCopy.walletByteLoc) self.assertEqual(testAddr.chaincode, testCopy.chaincode) self.assertEqual(testAddr.chainIndex, testCopy.chainIndex)
def testCreateTx(self): addrA = PyBtcAddress().createFromPrivateKey(hex_to_int('aa' * 32)) addrB = PyBtcAddress().createFromPrivateKey(hex_to_int('bb' * 32)) # This TxIn will be completely ignored, so it can contain garbage txinA = PyTxIn() txinA.outpoint = PyOutPoint().unserialize(hex_to_binary('00' * 36)) txinA.binScript = hex_to_binary('99' * 4) txinA.intSeq = hex_to_int('ff' * 4) # test binary unpacker in unserialize testTxIn = PyTxIn().unserialize(txinA.serialize()) self.assertEqual(txinA.getScript(), testTxIn.getScript()) self.assertEqual(txinA.intSeq, testTxIn.intSeq) self.assertEqual(txinA.outpoint.txHash, testTxIn.outpoint.txHash) txoutA = PyTxOut() txoutA.value = 50 * ONE_BTC txoutA.binScript = '\x76\xa9\x14' + addrA.getAddr160() + '\x88\xac' # Test pprint print '\nTest pretty print PyTxIn, expect PrevTXHash all 0s' testTxIn.pprint() # test binary unpacker in unserialize testTxOut = PyTxOut().unserialize(txoutA.serialize()) self.assertEqual(txoutA.getScript(), testTxOut.getScript()) self.assertEqual(txoutA.value, testTxOut.getValue()) # Test pprint print '\nTest pretty print PyTxOut' testTxOut.pprint() tx1 = PyTx() tx1.version = 1 tx1.numInputs = 1 tx1.inputs = [txinA] tx1.numOutputs = 1 tx1.outputs = [txoutA] tx1.locktime = 0 tx1hash = tx1.getHash() recipientList = tx1.makeRecipientsList() self.assertEqual(len(recipientList), 1) self.assertEqual(recipientList[0][0], 0) self.assertEqual(recipientList[0][1], 50 * ONE_BTC) self.assertEqual(tx1.getHashHex(), binary_to_hex(tx1hash)) # Creating transaction to send coins from A to B tx2 = PyCreateAndSignTx_old([[addrA, tx1, 0]], [[addrB, 50 * ONE_BTC]]) psp = PyScriptProcessor() psp.setTxObjects(tx1, tx2, 0) self.assertTrue(psp.verifyTransactionValid())
def testCreateTx(self): addrA = PyBtcAddress().createFromPrivateKey(hex_to_int('aa' * 32)) addrB = PyBtcAddress().createFromPrivateKey(hex_to_int('bb' * 32)) # This TxIn will be completely ignored, so it can contain garbage txinA = PyTxIn() txinA.outpoint = PyOutPoint().unserialize(hex_to_binary('00'*36)) txinA.binScript = hex_to_binary('99'*4) txinA.intSeq = hex_to_int('ff'*4) # test binary unpacker in unserialize testTxIn = PyTxIn().unserialize(txinA.serialize()) self.assertEqual(txinA.getScript(), testTxIn.getScript()) self.assertEqual(txinA.intSeq, testTxIn.intSeq) self.assertEqual(txinA.outpoint.txHash, testTxIn.outpoint.txHash) txoutA = PyTxOut() txoutA.value = 50 * ONE_BTC txoutA.binScript = '\x76\xa9\x14' + addrA.getAddr160() + '\x88\xac' # Test pprint print '\nTest pretty print PyTxIn, expect PrevTXHash all 0s' testTxIn.pprint() # test binary unpacker in unserialize testTxOut = PyTxOut().unserialize(txoutA.serialize()) self.assertEqual(txoutA.getScript(), testTxOut.getScript()) self.assertEqual(txoutA.value, testTxOut.getValue()) # Test pprint print '\nTest pretty print PyTxOut' testTxOut.pprint() tx1 = PyTx() tx1.version = 1 tx1.numInputs = 1 tx1.inputs = [txinA] tx1.numOutputs = 1 tx1.outputs = [txoutA] tx1.locktime = 0 tx1hash = tx1.getHash() recipientList = tx1.makeRecipientsList() self.assertEqual(len(recipientList), 1) self.assertEqual(recipientList[0][0], 0) self.assertEqual(recipientList[0][1], 50 * ONE_BTC) self.assertEqual(tx1.getHashHex(), binary_to_hex(tx1hash)) # Creating transaction to send coins from A to B tx2 = PyCreateAndSignTx_old( [[ addrA, tx1, 0 ]], [[addrB, 50*ONE_BTC]]) psp = PyScriptProcessor() psp.setTxObjects(tx1, tx2, 0) self.assertTrue(psp.verifyTransactionValid())
def verifyMultiSigAddrExtraction(self, scr, expectedBtcAddrList): addrList = getMultisigScriptInfo(scr)[2] btcAddrList = [] for a in addrList: btcAddrList.append( PyBtcAddress().createFromPublicKeyHash160(a).getAddrStr()) self.assertEqual(btcAddrList, expectedBtcAddrList)
def testSimpleAddress(self): # Execute the tests with Satoshi's public key from the Bitcoin specification page satoshiPubKeyHex = '04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284' addrPiece1Hex = '65a4358f4691660849d9f235eb05f11fabbd69fa' addrPiece1Bin = hex_to_binary(addrPiece1Hex) satoshiAddrStr = hash160_to_addrStr(addrPiece1Bin) saddr = PyBtcAddress().createFromPublicKey( hex_to_binary(satoshiPubKeyHex) ) print '\tAddr calc from pubkey: ', saddr.calculateAddrStr() self.assertTrue(checkAddrStrValid(satoshiAddrStr)) testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) msg = int_to_binary(39029348428) theHash = hash256(msg) derSig = testAddr.generateDERSignature(theHash) # Testing ECDSA signing & verification -- arbitrary binary strings: self.assertTrue(testAddr.verifyDERSignature( theHash, derSig))
def buildCorruptWallet(self, walletPath): from armoryengine.PyBtcWallet import PyBtcWallet crpWlt = PyBtcWallet() crpWlt.createNewWallet(walletPath, securePassphrase='testing', doRegisterWithBDM=False) #not registering with the BDM, have to fill the wallet address pool manually crpWlt.fillAddressPool(100) #grab the last computed address lastaddr = crpWlt.addrMap[crpWlt.lastComputedChainAddr160] #corrupt the pubkey PubKey = hex_to_binary('0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455') lastaddr.binPublicKey65 = SecureBinaryData(PubKey) crpWlt.addrMap[crpWlt.lastComputedChainAddr160] = lastaddr crpWlt.fillAddressPool(200) #insert a gap and inconsistent encryption newAddr = PyBtcAddress() newAddr.chaincode = lastaddr.chaincode newAddr.chainIndex = 250 PrivKey = hex_to_binary('e3b0c44298fc1c149afbf4c8996fb92427ae41e5978fe51ca495991b7852b855') newAddr.binPrivKey32_Plain = SecureBinaryData(PrivKey) newAddr.binPublicKey65 = CryptoECDSA().ComputePublicKey(newAddr.binPrivKey32_Plain) newAddr.addrStr20 = newAddr.binPublicKey65.getHash160() newAddr.isInitialized = True crpWlt.addrMap[newAddr.addrStr20] = newAddr crpWlt.lastComputedChainAddr160 = newAddr.addrStr20 crpWlt.fillAddressPool(250) #TODO: corrupt a private key #break an address entry at binary level return crpWlt.uniqueIDB58
def buildCorruptWallet(self, walletPath): crpWlt = PyBtcWallet() crpWlt.createNewWallet(walletPath, securePassphrase='testing', doRegisterWithBDM=False) #not registering with the BDM, have to fill the wallet address pool manually crpWlt.fillAddressPool(100) #grab the last computed address lastaddr = crpWlt.addrMap[crpWlt.lastComputedChainAddr160] #corrupt the pubkey PubKey = hex_to_binary( '0478d430274f8c5ec1321338151e9f27f4c676a008bdf8638d07c0b6be9ab35c71a1518063243acd4dfe96b66e3f2ec8013c8e072cd09b3834a19f81f659cc3455' ) lastaddr.binPublicKey65 = SecureBinaryData(PubKey) crpWlt.addrMap[crpWlt.lastComputedChainAddr160] = lastaddr crpWlt.fillAddressPool(200) #insert a gap and inconsistent encryption newAddr = PyBtcAddress() newAddr.chaincode = lastaddr.chaincode newAddr.chainIndex = 250 PrivKey = hex_to_binary( 'e3b0c44298fc1c149afbf4c8996fb92427ae41e5978fe51ca495991b7852b855') newAddr.binPrivKey32_Plain = SecureBinaryData(PrivKey) newAddr.binPublicKey65 = CryptoECDSA().ComputePublicKey( \ newAddr.binPrivKey32_Plain) newAddr.addrStr20 = newAddr.binPublicKey65.getHash160() newAddr.isInitialized = True crpWlt.addrMap[newAddr.addrStr20] = newAddr crpWlt.lastComputedChainAddr160 = newAddr.addrStr20 crpWlt.fillAddressPool(250) lastAddr = crpWlt.addrMap[crpWlt.lastComputedChainAddr160] PrivKey = hex_to_binary( 'e3b0c44298fc1c149afbf4c8996fb92427ae41e5978fe51ca495991b00000000') lastAddr.binPrivKey32_Plain = SecureBinaryData(PrivKey) lastAddr.binPublicKey65 = CryptoECDSA().ComputePublicKey( \ lastAddr.binPrivKey32_Plain) lastAddr.keyChanged = True crpWlt.kdfKey = crpWlt.kdf.DeriveKey(SecureBinaryData('testing')) lastAddr.lock(secureKdfOutput=crpWlt.kdfKey) lastAddr.useEncryption = True crpWlt.fillAddressPool(350) #TODO: corrupt a private key #break an address entry at binary level return crpWlt.uniqueIDB58
def testSimpleAddress(self): # Execute the tests with Satoshi's public key from the Bitcoin specification page satoshiPubKeyHex = '04fc9702847840aaf195de8442ebecedf5b095cdbb9bc716bda9110971b28a49e0ead8564ff0db22209e0374782c093bb899692d524e9d6a6956e7c5ecbcd68284' addrPiece1Hex = '65a4358f4691660849d9f235eb05f11fabbd69fa' addrPiece1Bin = hex_to_binary(addrPiece1Hex) satoshiAddrStr = hash160_to_addrStr(addrPiece1Bin) saddr = PyBtcAddress().createFromPublicKey( hex_to_binary(satoshiPubKeyHex)) print '\tAddr calc from pubkey: ', saddr.calculateAddrStr() self.assertTrue(checkAddrStrValid(satoshiAddrStr)) testAddr = PyBtcAddress().createFromPlainKeyData( PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) msg = int_to_binary(39029348428) theHash = hash256(msg) derSig = testAddr.generateDERSignature(theHash) # Testing ECDSA signing & verification -- arbitrary binary strings: self.assertTrue(testAddr.verifyDERSignature(theHash, derSig))
def testEncryptedAddress(self): # test serialization and unserialization of an empty PyBtcAddrss # Should serialize to a string that starts with 20 bytes of zeros # Unserialize should throw an UnserializeError caused by checksum mismatch emptyBtcAddr = PyBtcAddress() emptyBtcAddrSerialized = emptyBtcAddr.serialize() self.assertEqual(emptyBtcAddrSerialized[:20], hex_to_binary('00'*20)) self.assertRaises(UnserializeError, PyBtcAddress().unserialize, emptyBtcAddrSerialized) # Test non-crashing testAddr1 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20) testAddr2 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, chksum=PRIVATE_CHECKSUM) testAddr3 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) testAddr4 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY, skipCheck=True) testAddr5 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, skipPubCompute=True) testString = testAddr1.toString() self.assertTrue(len(testString) > 0) testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) serializedAddr1 = testAddr.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr1) serializedRetest1 = retestAddr.serialize() self.assertEqual(serializedAddr1, serializedRetest1) theIV = SecureBinaryData(hex_to_binary(INIT_VECTOR)) testAddr.enableKeyEncryption(theIV) testAddr.lock(FAKE_KDF_OUTPUT1) self.assertTrue(testAddr.useEncryption) self.assertTrue(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) serializedAddr2 = testAddr.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr2) serializedRetest2 = retestAddr.serialize() self.assertEqual(serializedAddr2, serializedRetest2) testAddr.unlock(FAKE_KDF_OUTPUT1) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) testAddr.changeEncryptionKey(None, FAKE_KDF_OUTPUT1) self.assertTrue(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) # Save off this data for a later test addr20_1 = testAddr.getAddr160() encryptedKey1 = testAddr.binPrivKey32_Encr encryptionIV1 = testAddr.binInitVect16 plainPubKey1 = testAddr.binPublicKey65 # OP(Key1 --> Unencrypted) testAddr.changeEncryptionKey(FAKE_KDF_OUTPUT1, None) self.assertFalse(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), '') # OP(Unencrypted --> Key2) if not testAddr.isKeyEncryptionEnabled(): testAddr.enableKeyEncryption(theIV) testAddr.changeEncryptionKey(None, FAKE_KDF_OUTPUT2) self.assertTrue(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR2) # Save off this data for a later test addr20_2 = testAddr.getAddr160() encryptedKey2 = testAddr.binPrivKey32_Encr encryptionIV2 = testAddr.binInitVect16 plainPubKey2 = testAddr.binPublicKey65 # OP(Key2 --> Key1) testAddr.changeEncryptionKey(FAKE_KDF_OUTPUT2, FAKE_KDF_OUTPUT1) self.assertTrue(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) # OP(Key1 --> Lock --> Key2) testAddr.lock(FAKE_KDF_OUTPUT1) testAddr.changeEncryptionKey(FAKE_KDF_OUTPUT1, FAKE_KDF_OUTPUT2) self.assertTrue(testAddr.useEncryption) self.assertTrue(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR2) # OP(Key2 --> Lock --> Unencrypted) testAddr.changeEncryptionKey(FAKE_KDF_OUTPUT2, None) self.assertFalse(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), '') # Encryption Key Tests: self.assertEqual(testAddr.serializePlainPrivateKey(), PRIVATE_KEY.toBinStr()) # Test loading pre-encrypted key data testAddr = PyBtcAddress().createFromEncryptedKeyData(addr20_1, encryptedKey1, encryptionIV1) self.assertTrue(testAddr.useEncryption) self.assertTrue(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) # OP(EncrAddr --> Unlock1) testAddr.unlock(FAKE_KDF_OUTPUT1) self.assertTrue(testAddr.useEncryption) self.assertFalse(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) # OP(Unlock1 --> Lock1) testAddr.lock() self.assertTrue(testAddr.useEncryption) self.assertTrue(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR1) # OP(Lock1 --> Lock2) testAddr.changeEncryptionKey(FAKE_KDF_OUTPUT1, FAKE_KDF_OUTPUT2) self.assertTrue(testAddr.useEncryption) self.assertTrue(testAddr.isLocked) self.assertEqual(testAddr.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(testAddr.binPrivKey32_Encr.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR2) # Test serializing locked wallet from pre-encrypted data' serializedAddr = testAddr.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) ############################################################################# # Now testing chained-key (deterministic) address generation # Test chained priv key generation # Starting with plain key data chaincode = SecureBinaryData(hex_to_binary('ee'*32)) addr0 = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20) addr0.markAsRootAddr(chaincode) pub0 = addr0.binPublicKey65 # Test serializing address-chain-root serializedAddr = addr0.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) self.assertEqual(retestAddr.binPrivKey32_Plain.toHexStr(), PRIVATE_KEY.toHexStr()) # Generate chained PRIVATE key address # OP(addr[0] --> addr[1]) addr1 = addr0.extendAddressChain() self.assertEqual(addr1.binPrivKey32_Plain.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR3) # OP(addr[0] --> addr[1]) [again]' addr1a = addr0.extendAddressChain() self.assertEqual(addr1a.binPrivKey32_Plain.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR3) # OP(addr[1] --> addr[2]) addr2 = addr1.extendAddressChain() pub2 = addr2.binPublicKey65.copy() priv2 = addr2.binPrivKey32_Plain.copy() self.assertEqual(priv2.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR4) # Addr1.PRIVATE_KEY == Addr1a.PRIVATE_KEY:', self.assertEqual(addr1.binPublicKey65, addr1a.binPublicKey65) # Test serializing priv-key-chained', serializedAddr = addr2.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) ############################################################################# # Generate chained PUBLIC key address # addr[0] addr0 = PyBtcAddress().createFromPublicKeyData(pub0) addr0.markAsRootAddr(chaincode) self.assertEqual(addr0.chainIndex, -1) self.assertEqual(addr0.chaincode, chaincode) # Test serializing pub-key-only-root', serializedAddr = addr0.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) # OP(addr[0] --> addr[1])' addr1 = addr0.extendAddressChain() self.assertEqual(addr1.binPrivKey32_Plain.toHexStr(), '') # OP(addr[1] --> addr[2])' addr2 = addr1.extendAddressChain() pub2a = addr2.binPublicKey65.copy() self.assertEqual(addr2.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(pub2a.toHexStr(), TEST_PUB_KEY1) # Addr2.PublicKey == Addr2a.PublicKey:' # Test serializing pub-key-from-chain' serializedAddr = addr2.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) ############################################################################# # Generate chained keys from locked addresses addr0 = PyBtcAddress().createFromPlainKeyData( PRIVATE_KEY, \ willBeEncr=True, IV16=theIV) addr0.markAsRootAddr(chaincode) # OP(addr[0] plain) # Test serializing unlocked addr-chain-root serializedAddr = addr0.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) self.assertFalse(retestAddr.useEncryption) # OP(addr[0] locked) addr0.lock(FAKE_KDF_OUTPUT1) self.assertEqual(addr0.binPrivKey32_Plain.toHexStr(), '') # OP(addr[0] w/Key --> addr[1]) addr1 = addr0.extendAddressChain(FAKE_KDF_OUTPUT1, newIV=theIV) self.assertEqual(addr1.binPrivKey32_Plain.toHexStr(), '') # OP(addr[1] w/Key --> addr[2]) addr2 = addr1.extendAddressChain(FAKE_KDF_OUTPUT1, newIV=theIV) addr2.unlock(FAKE_KDF_OUTPUT1) priv2a = addr2.binPrivKey32_Plain.copy() addr2.lock() self.assertEqual(addr2.binPrivKey32_Plain.toHexStr(), '') # Addr2.priv == Addr2a.priv: self.assertEqual(priv2, priv2a) # Test serializing chained address from locked root serializedAddr = addr2.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) ############################################################################# # Generate chained keys from locked addresses, no unlocking addr0 = PyBtcAddress().createFromPlainKeyData( PRIVATE_KEY, \ willBeEncr=True, IV16=theIV) addr0.markAsRootAddr(chaincode) # OP(addr[0] locked) addr0.lock(FAKE_KDF_OUTPUT1) self.assertEqual(addr0.binPrivKey32_Plain.toHexStr(), '') # OP(addr[0] locked --> addr[1] locked)' addr1 = addr0.extendAddressChain(newIV=theIV) self.assertEqual(addr1.binPrivKey32_Plain.toHexStr(), '') # OP(addr[1] locked --> addr[2] locked) addr2 = addr1.extendAddressChain(newIV=theIV) pub2b = addr2.binPublicKey65.copy() self.assertEqual(addr2.binPrivKey32_Plain.toHexStr(), '') self.assertEqual(pub2b.toHexStr(), TEST_PUB_KEY1) # Addr2.Pub == Addr2b.pub: # Test serializing priv-key-bearing address marked for unlock serializedAddr = addr2.serialize() retestAddr = PyBtcAddress().unserialize(serializedAddr) serializedRetest = retestAddr.serialize() self.assertEqual(serializedAddr, serializedRetest) addr2.unlock(FAKE_KDF_OUTPUT1) priv2b = addr2.binPrivKey32_Plain.copy() # OP(addr[2] locked --> unlocked) self.assertEqual(priv2b.toHexStr(), TEST_ADDR1_PRIV_KEY_ENCR4) addr2.lock() # OP(addr[2] unlocked --> locked)' # Addr2.priv == Addr2b.priv: self.assertEqual(priv2, priv2b)
def testTouch(self): self.verifyBlockHeight() testAddr = PyBtcAddress().createFromPlainKeyData(PRIVATE_KEY, ADDRESS_20, publicKey65=PUBLIC_KEY) theIV = SecureBinaryData(hex_to_binary(INIT_VECTOR)) testAddr.enableKeyEncryption(theIV) rightNow = RightNow() testAddr.touch(rightNow) self.assertEqual(testAddr.timeRange[0], long(rightNow)) self.assertEqual(testAddr.timeRange[1], long(rightNow)) testAddr.touch(0) self.assertEqual(testAddr.timeRange[0], long(0)) self.assertEqual(testAddr.timeRange[1], long(rightNow)) testAddr.touch(blkNum=TEST_BLOCK_NUM) self.assertEqual(testAddr.blkRange[0], TEST_BLOCK_NUM) self.assertEqual(testAddr.blkRange[1], TOP_TIAB_BLOCK) testAddr.touch(blkNum=0) self.assertEqual(testAddr.blkRange[0], 0) self.assertEqual(testAddr.blkRange[1], TOP_TIAB_BLOCK) # Cover the case where the blkRange[0] starts at 0 testAddr.touch(blkNum=TEST_BLOCK_NUM) self.assertEqual(testAddr.blkRange[0], TEST_BLOCK_NUM) self.assertEqual(testAddr.blkRange[1], TOP_TIAB_BLOCK)