def test_verifyMultiSigSignature(self): "Test the verifyMultiSigSignature function" tx = dummy_interfaces.Tracer() def getSignatureBodyHash(*args, **kwargs): tx.trace.append(("getSignatureBodyHash", args, kwargs)) return "bodyHash" tx.getSignatureBodyHash = getSignatureBodyHash key = crypto.Key() key.makeNewKey() signature = bitcoinutils.signMultiSigTransaction( tx, 3, ["toPubKey1", "toPubKey2"], key) self.assertTrue( bitcoinutils.verifyMultiSigSignature(tx, 3, ["toPubKey1", "toPubKey2"], key, signature)) key2 = crypto.Key() key2.makeNewKey() self.assertFalse( bitcoinutils.verifyMultiSigSignature(tx, 3, ["toPubKey1", "toPubKey2"], key2, signature)) self.assertFalse( bitcoinutils.verifyMultiSigSignature(tx, 3, ["toPubKey1", "toPubKey2"], key, signature[:-1] + "\x02"))
def test_newKey(self): "Test behavior of a new private key object" key = crypto.Key() key.makeNewKey(compressed=False) self.__testPrivateKey(key, 65, 32) key = crypto.Key() key.makeNewKey(compressed=True) self.__testPrivateKey(key, 33, 33)
def test_signMultiSigTransaction(self): "Test the signMultiSigTransaction function" tx = dummy_interfaces.Tracer() def getSignatureBodyHash(*args, **kwargs): tx.trace.append(("getSignatureBodyHash", args, kwargs)) return "bodyHash" tx.getSignatureBodyHash = getSignatureBodyHash key = crypto.Key() key.makeNewKey() signature = bitcoinutils.signMultiSigTransaction( tx, 3, ["toPubKey1", "toPubKey2"], key) self.assertEqual(len(tx.trace), 1) self.assertEqual(tx.trace[0][0], "getSignatureBodyHash") self.assertEqual(tx.trace[0][1][0], 3) script = tx.trace[0][1][1] self.assertEqual(tx.trace[0][1][2], 1) self.assertEqual( script.elements, [OP.TWO, "toPubKey1", "toPubKey2", OP.TWO, OP.CHECKMULTISIG]) self.assertEqual(signature[-1], "\x01") signature = signature[:-1] self.assertTrue(key.verify("bodyHash", signature))
def test_emptyKey(self): "Test behavior of an empty key object" key = crypto.Key() self.assertRaises(Exception, key.getPublicKey) self.assertRaises(Exception, key.getPrivateKey) self.assertRaises(Exception, key.sign, "foo") self.assertRaises(Exception, key.verify, "foo", "bar")
def test_sendToMultiSigPubKey(self): "Test the sendToMultiSigPubKey function" with DummyTransaction(): tx = bitcoinutils.sendToMultiSigPubKey(self.bitcoind, 40, "toPK1", "toPK2", "changeHash", 3) self.assertEqual(len(tx.trace), 2) #Constructor, with tx_in and tx_out: self.assertEqual(tx.trace[0][0], "__init__") self.assertEqual(tx.trace[0][1], tuple()) self.assertEqual(len(tx.trace[0][2]), 2) self.assertEqual(len(tx.trace[0][2]["tx_in"]), 1) self.assertEqual(len(tx.trace[0][2]["tx_out"]), 2) tx_in = tx.trace[0][2]["tx_in"][0] self.assertEqual(tx_in.trace, [('__init__', ('foobar_tx', 1), {})]) tx_out = tx.trace[0][2]["tx_out"][0] self.assertEqual(len(tx_out.trace), 1) self.assertEqual(tx_out.trace[0][0], "__init__") self.assertEqual(len(tx_out.trace[0][1]), 2) self.assertEqual(tx_out.trace[0][1][0], 40) script = tx_out.trace[0][1][1] self.assertEqual( script.elements, [OP.TWO, "toPK1", "toPK2", OP.TWO, OP.CHECKMULTISIG]) tx_out = tx.trace[0][2]["tx_out"][1] self.assertEqual(len(tx_out.trace), 1) self.assertEqual(tx_out.trace[0][0], "__init__") self.assertEqual(len(tx_out.trace[0][1]), 2) self.assertEqual(tx_out.trace[0][1][0], 7) script = tx_out.trace[0][1][1] self.assertEqual(script.elements, (OP.DUP, OP.HASH160, "changeHash", OP.EQUALVERIFY, OP.CHECKSIG)) #Transaction signing: self.assertEqual(tx.trace[1][0], "signInput") self.assertEqual(len(tx.trace[1][1]), 4) self.assertEqual(tx.trace[1][1][0], 0) scriptPubKey = tx.trace[1][1][1] self.assertEqual(scriptPubKey.serialize(), "foobar_pub") key = crypto.Key() key.setPrivateKey("foobar") self.assertEqual(tx.trace[1][1][2], [None, key.getPublicKey()]) self.assertEqual(len(tx.trace[1][1][3]), 1) self.assertEqual(tx.trace[1][1][3][0].getPrivateKey(), key.getPrivateKey())
def test_crossSigning(self): "Test whether one key's signature is accepted with another public key" for compressed in (False, True): priv1 = crypto.Key() priv1.makeNewKey(compressed=compressed) priv2 = crypto.Key() priv2.makeNewKey(compressed=compressed) self.assertNotEqual(priv1.getPrivateKey(), priv2.getPrivateKey()) self.assertNotEqual(priv1.getPublicKey(), priv2.getPublicKey()) message = "foo" sig1 = priv1.sign(message) sig2 = priv2.sign(message) pub1 = crypto.Key() pub1.setPublicKey(priv1.getPublicKey()) pub2 = crypto.Key() pub2.setPublicKey(priv2.getPublicKey()) self.assertTrue(pub1.verify(message, sig1)) self.assertFalse(pub1.verify(message, sig2))
def test_publicKey(self): "Test behavior of a public key object" for compressed in (False, True): publicKey, privateKey, fooSignature = self.__getKeyPair( compressed=compressed) key = crypto.Key() key.setPublicKey(publicKey) self.assertEqual(type(key.getPublicKey()), str) self.assertEqual(key.getPublicKey(), publicKey) self.assertRaises(Exception, key.getPrivateKey) self.assertTrue(key.verify("foo", fooSignature)) self.assertFalse(key.verify("bar", fooSignature))
def test_privateKey(self): "Test behavior of an imported private key object" publicKey, privateKey, fooSignature = self.__getKeyPair( compressed=False) key = crypto.Key() key.setPrivateKey(privateKey) self.__testPrivateKey(key, 65, 32) self.assertEqual(key.getPublicKey(), publicKey) self.assertEqual(key.getPrivateKey(), privateKey) self.assertTrue(key.verify("foo", fooSignature)) self.assertFalse(key.verify("bar", fooSignature)) publicKey, privateKey, fooSignature = self.__getKeyPair( compressed=True) key = crypto.Key() key.setPrivateKey(privateKey) self.__testPrivateKey(key, 33, 33) self.assertEqual(key.getPublicKey(), publicKey) self.assertEqual(key.getPrivateKey(), privateKey) self.assertTrue(key.verify("foo", fooSignature)) self.assertFalse(key.verify("bar", fooSignature))
def __testPrivateKey(self, key, lenPubKey, lenPrivKey): publicKey = key.getPublicKey() self.assertEqual(type(publicKey), str) self.assertEqual(len(publicKey), lenPubKey) privateKey = key.getPrivateKey() self.assertEqual(type(privateKey), str) self.assertEqual(len(privateKey), lenPrivKey) message = "foo" signature = key.sign(message) self.assertEqual(type(signature), str) self.assertLess(len(signature), 74) self.assertTrue(key.verify(message, signature)) self.assertFalse(key.verify("bar", signature)) key2 = crypto.Key() key2.setPublicKey(publicKey) self.assertTrue(key2.verify(message, signature)) self.assertFalse(key2.verify("bar", signature))
def test(): k = crypto.Key() k.makeNewKey(compressed=True) k.getPrivateKey()
def test_failures(self): "Test what happens in case of libssl failures" #Note: this is an incredibly white-box test. #Its main purpose is to get full code coverage, to make sure all #lines of the code "work" as intended. with DummyLibSSL() as libssl: libssl.returnValues = {'EC_KEY_new_by_curve_name': [1]} key = crypto.Key() libssl.returnValues = {'EC_KEY_generate_key': [0]} self.assertRaises(Exception, key.makeNewKey) libssl.returnValues = {'o2i_ECPublicKey': [0]} self.assertRaises(Exception, key.setPublicKey, '') libssl.returnValues = \ { 'EC_KEY_generate_key': [1], 'EC_KEY_set_conv_form': [None] } key.makeNewKey() libssl.returnValues = {'i2o_ECPublicKey': [0]} self.assertRaises(Exception, key.getPublicKey) libssl.returnValues = {'i2o_ECPublicKey': [32, 33]} self.assertRaises(Exception, key.getPublicKey) libssl.returnValues = {'BN_init': [None], 'BN_bin2bn': [0]} self.assertRaises(Exception, key.setPrivateKey, '') libssl.returnValues = \ { 'EC_KEY_new_by_curve_name': [0], 'BN_init': [None], 'BN_bin2bn': [1] } key = crypto.Key() self.assertRaises(Exception, key.setPrivateKey, '') libssl.returnValues = {'EC_KEY_new_by_curve_name': [1]} key = crypto.Key() libssl.returnValues = \ { 'BN_init': [None], 'BN_bin2bn': [1], 'EC_KEY_get0_group': [None], 'BN_CTX_new': [0] } self.assertRaises(Exception, key.setPrivateKey, '') libssl.returnValues = \ { 'BN_init': [None], 'BN_bin2bn': [1], 'EC_KEY_get0_group': [None], 'BN_CTX_new': [1], 'EC_POINT_new': [0] } self.assertRaises(Exception, key.setPrivateKey, '') libssl.returnValues = \ { 'BN_init': [None], 'BN_bin2bn': [1], 'EC_KEY_get0_group': [None], 'BN_CTX_new': [1], 'EC_POINT_new': [1], 'EC_POINT_mul': [0] } self.assertRaises(Exception, key.setPrivateKey, '') libssl.returnValues = \ { 'EC_KEY_generate_key': [1], 'EC_KEY_set_conv_form': [None] } key.makeNewKey() libssl.returnValues = {'EC_KEY_get0_private_key': [0]} self.assertRaises(Exception, key.getPrivateKey) libssl.returnValues = \ { 'EC_KEY_get0_private_key': [1], 'BN_num_bits': [32*8], 'BN_bn2bin': [33] } self.assertRaises(Exception, key.getPrivateKey) libssl.returnValues = \ { 'ECDSA_size': [71], 'ECDSA_sign': [0] } self.assertRaises(Exception, key.sign, '') libssl.returnValues = {'ECDSA_verify': [-1]} self.assertRaises(Exception, key.verify, '', '')