def isUxArraySorted(uxa): n = len(uxa) prev = uxa current = prev current += 1 hash_1 = skycoin.cipher_SHA256() hash_2 = skycoin.cipher_SHA256() prevHash = None currentHash = None result = int() for i in n: if (prevHash == None): result = skycoin.SKY_coin_UxOut_Hash(prev, hash_1) assert result == skycoin.SKY_OK prevHash = hash_1 if currentHash == None: currentHash = hash_2 result = skycoin.SKY_coin_UxOut_Hash(current, currentHash) assert result == skycoin.SKY_OK if prevHash.__eq__(currentHash) > 0: return 0 if i % 2 != 0: prevHash = hash_2 currentHash = hash_1 else: prevHash = hash_1 currentHash = hash_2 prev += 1 current += 1 return 1
def test_TestTransactionHash(): handle, _ = utils.makeTransaction() h = skycoin.cipher_SHA256() h2 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_Hash(handle, h) == skycoin.SKY_OK assert h != h2 assert skycoin.SKY_coin_Transaction_HashInner( handle, h2) == skycoin.SKY_OK assert h != h2
def manualUxArrayIsSorted(uxa): sha_1 = skycoin.cipher_SHA256() sha_2 = skycoin.cipher_SHA256() isSorte = True for i in range(len(uxa) - 1): assert skycoin.SKY_coin_UxOut_Hash(uxa[i], sha_1) == skycoin.SKY_OK assert skycoin.SKY_coin_UxOut_Hash(uxa[i + 1], sha_2) == skycoin.SKY_OK if sha_1 > sha_2: isSorte = False return isSorte
def test_TestSumSHA256(): _, b = skycoin.SKY_cipher_RandByte(256) h1 = skycoin.cipher_SHA256() skycoin.SKY_cipher_SumSHA256(b, h1) assert h1 != skycoin.cipher_SHA256() _, c = skycoin.SKY_cipher_RandByte(256) h2 = skycoin.cipher_SHA256() skycoin.SKY_cipher_SumSHA256(c, h2) assert h2 != skycoin.cipher_SHA256() assert h2 == freshSumSHA256(c)
def test_TestSHA256Hex(): h = skycoin.cipher_SHA256() _, b = skycoin.SKY_cipher_RandByte(32) skycoin.SKY_cipher_SHA256_Set(h, b) _, s = skycoin.SKY_cipher_SHA256_Hex(h) h2 = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SHA256FromHex(s, h2) assert err == skycoin.SKY_OK assert h == h2 _, s2 = skycoin.SKY_cipher_SHA256_Hex(h2) assert s2 == s
def test_TestAddSHA256(): _, b = skycoin.SKY_cipher_RandByte(128) h = skycoin.cipher_SHA256() skycoin.SKY_cipher_SumSHA256(b, h) _, c = skycoin.SKY_cipher_RandByte(64) i = skycoin.cipher_SHA256() skycoin.SKY_cipher_SumSHA256(c, i) add = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_AddSHA256(h, i, add) assert err == skycoin.SKY_OK assert add != skycoin.cipher_SHA256() assert add != h assert add != i
def test_TestBlockHashHeader(): uxHash = utils.RandSHA256() err, block = makeNewBlock(uxHash) assert err == skycoin.SKY_OK err, pBlock = skycoin.SKY_coin_GetBlockObject(block) assert err == skycoin.SKY_OK hash1 = skycoin.cipher_SHA256() hash2 = skycoin.cipher_SHA256() err = skycoin.SKY_coin_Block_HashHeader(block, hash1) assert err == skycoin.SKY_OK err = skycoin.SKY_coin_BlockHeader_Hash(pBlock.Head, hash2) assert err == skycoin.SKY_OK assert hash1.toStr() == hash2.toStr() hash2 = skycoin.cipher_SHA256() assert hash1 != hash2
def sign_hash(hashHex, seckeyHex): seckey = skycoin.cipher_Sig() error = skycoin.SKY_cipher_SecKeyFromHex(seckeyHex.encode(), seckey) if error != 0: return make_response( jsonify(build_error('Invalid Input Format', error_codes.badFormat)), 400) sha256 = skycoin.cipher_SHA256() error = skycoin.SKY_cipher_SHA256FromHex(hashHex.encode(), sha256) if error != 0: return make_response( jsonify(build_error('Invalid Input Format', error_codes.badFormat)), 400) signedHash = skycoin.cipher__Sig() error = skycoin.SKY_cipher_SignHash(hash, seckey, signedHash) if error != 0: return make_response( jsonify(build_error('Unknown Server Error', error_codes.unknown)), 500) error, signedHashHex = SKY_cipher_Sig_Hex(signedHash) if error != 0: return make_response( jsonify(build_error('Unknown Server Error', error_codes.unknown)), 500) retvalue = {"signedTransaction": signedHashHex} return jsonify(retvalue)
def test_TestCreateUnspent(): err, pubkey, seckey, address = utils.makeKeysAndAddress() assert err == skycoin.SKY_OK hash1 = skycoin.cipher_SHA256() handle = utils.makeEmptyTransaction() err = skycoin.SKY_coin_Transaction_PushOutput(handle, address, 11000000, 255) assert err == skycoin.SKY_OK bh = skycoin.coin__BlockHeader() bh.Time = 0 bh.BkSeq = 1 t = [] tc1 = testcase() t.append(tc1) tc2 = testcase() tc2.index = 10 tc2.failure = skycoin.SKY_ERROR t.append(tc2) ux = skycoin.coin__UxOut() tests_count = len(t) for i in range(tests_count): err = skycoin.SKY_coin_CreateUnspent(bh, handle, t[i].index, ux) if t[i].failure == skycoin.SKY_ERROR: pass assert bh.Time == ux.Head.Time assert bh.BkSeq == ux.Head.BkSeq
def RandSHA256(): err, sha = skycoin.SKY_cipher_RandByte(128) assert err == skycoin.SKY_OK sh = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SumSHA256(sha, sh) assert err == skycoin.SKY_OK return sh
def test_TestUxOutHash(): uxb, _ = utils.makeUxBodyWithSecret() uxo, _ = utils.makeUxOutWithSecret() uxo.Body = uxb hash_body = skycoin.cipher_SHA256() hash_out = skycoin.cipher_SHA256() assert skycoin.SKY_coin_UxBody_Hash(uxb, hash_body) == skycoin.SKY_OK assert skycoin.SKY_coin_UxOut_Hash(uxo, hash_out) == skycoin.SKY_OK assert hash_body == hash_out # Head should not affect hash uxh = skycoin.coin__UxHead() uxh.Time = 0 uxh.BkSeq = 1 uxo.Head = uxh assert skycoin.SKY_coin_UxOut_Hash(uxo, hash_out) == skycoin.SKY_OK assert hash_body == hash_out
def test_TestBlockHashBody(): uxHash = utils.RandSHA256() err, block = makeNewBlock(uxHash) assert err == skycoin.SKY_OK err, pBlock = skycoin.SKY_coin_GetBlockObject(block) assert err == skycoin.SKY_OK hash1 = skycoin.cipher_SHA256() hash2 = skycoin.cipher_SHA256() err = skycoin.SKY_coin_Block_HashBody(block, hash1) assert err == skycoin.SKY_OK err, blockBody = skycoin.SKY_coin_GetBlockBody(block) assert err == skycoin.SKY_OK err = skycoin.SKY_coin_BlockBody_Hash(blockBody, hash2) assert err == skycoin.SKY_OK assert hash1 == hash2
def test_TestXorSHA256(): _, b = skycoin.SKY_cipher_RandByte(128) _, c = skycoin.SKY_cipher_RandByte(128) h = skycoin.cipher_SHA256() i = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SumSHA256(b, h) assert err == skycoin.SKY_OK err = skycoin.SKY_cipher_SumSHA256(c, i) assert err == skycoin.SKY_OK temp = skycoin.cipher_SHA256() temp2 = skycoin.cipher_SHA256() assert skycoin.SKY_cipher_SHA256_Xor(h, i, temp) == skycoin.SKY_OK assert skycoin.SKY_cipher_SHA256_Xor(i, h, temp2) == skycoin.SKY_OK assert temp != h assert temp != i assert temp != skycoin.cipher_SHA256() assert temp == temp2
def test_TestSHA256Null(): x = skycoin.cipher_SHA256() _, isNull = skycoin.SKY_cipher_SHA256_Null(x) assert isNull _, b = skycoin.SKY_cipher_RandByte(128) skycoin.SKY_cipher_SumSHA256(b, x) _, isNull = skycoin.SKY_cipher_SHA256_Null(x) assert not isNull
def test_TestTransactionHashInner(): handle, tx = utils.makeTransaction() h = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_HashInner(handle, h) == skycoin.SKY_OK assert h != skycoin.cipher_SHA256() # If tx.In is changed, hash should change handle2, tx2 = utils.copyTransaction(handle) ux = utils.makeUxOut() h = skycoin.cipher_SHA256() h1 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_UxOut_Hash(ux, h) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_SetInputAt( handle2, 0, h) == skycoin.SKY_OK assert tx != tx2 assert skycoin.SKY_coin_UxOut_Hash(ux, h1) == skycoin.SKY_OK assert h == h1 assert skycoin.SKY_coin_Transaction_HashInner(handle, h) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_HashInner( handle2, h1) == skycoin.SKY_OK assert h != h1 # If tx.Out is changed, hash should change handle2, tx2 = utils.copyTransaction(handle) a = utils.makeAddress() a2 = skycoin.cipher__Address() pOut = skycoin.coin__TransactionOutput() assert skycoin.SKY_coin_Transaction_GetOutputAt( handle2, 0, pOut) == skycoin.SKY_OK pOut.Address = a assert skycoin.SKY_coin_Transaction_SetOutputAt( handle2, 0, pOut) == skycoin.SKY_OK assert tx != tx2 assert skycoin.SKY_coin_Transaction_GetOutputAt( handle2, 0, pOut) == skycoin.SKY_OK assert pOut.Address == a sha1 = skycoin.cipher_SHA256() sha2 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_HashInner( handle, sha1) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_HashInner( handle2, sha2) == skycoin.SKY_OK assert sha1 != sha2 # If tx.Head is changed, hash should not change handle2, tx2 = utils.copyTransaction(handle) sig = skycoin.cipher_Sig() assert skycoin.SKY_coin_Transaction_PushSignature( handle, sig) == skycoin.SKY_OK sha1 = skycoin.cipher_SHA256() sha2 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_HashInner( handle, sha1) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_HashInner( handle2, sha2) == skycoin.SKY_OK assert sha1 == sha2
def test_TestTransactionPushInput(): handle = utils.makeEmptyTransaction() ux = utils.makeUxOut() sha = skycoin.cipher_SHA256() assert skycoin.SKY_coin_UxOut_Hash(ux, sha) == skycoin.SKY_OK r = skycoin.SKY_coin_Transaction_PushInput(handle, sha) assert r == 0 _, count = skycoin.SKY_coin_Transaction_GetInputsCount(handle) assert count == 1 sha1 = skycoin.cipher_SHA256() skycoin.SKY_coin_Transaction_GetInputAt(handle, 0, sha1) assert sha == sha1 skycoin.SKY_coin_Transaction_ResetInputs(handle, 0) for _ in range(utils.MaxUint16): skycoin.SKY_coin_Transaction_PushInput( handle, skycoin.cipher_SHA256()) ux = utils.makeUxOut() assert skycoin.SKY_coin_UxOut_Hash(ux, sha) == skycoin.SKY_OK
def InputTestDataFromJSON(InputTestDataJSON): hashes = [] for h in InputTestDataJSON.Hashes: h2 = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SHA256FromHex(h.encode(), h2) #ok python2 hashes.append(h2) if err != skycoin.SKY_OK: return skycoin.SKY_ERROR, None return skycoin.SKY_OK, hashes
def test_TestMerkle(): hashlist = [] h = skycoin.cipher_SHA256() for _ in range(5): hashlist.append(h) for i in range(5): err, data = skycoin.SKY_cipher_RandByte(128) assert err == skycoin.SKY_OK err = skycoin.SKY_cipher_SumSHA256(data, hashlist[i]) assert err == skycoin.SKY_OK
def test_TestSHA256FromHex(): # Invalid hex hash h = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SHA256FromHex(b"cawcad", h) assert err == skycoin.SKY_ERROR # Truncated hex hash _, b = skycoin.SKY_cipher_RandByte(128) h = skycoin.cipher_SHA256() skycoin.SKY_cipher_SumSHA256(b, h) h_bytes = h.toStr() h1 = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SHA256FromHex(h_bytes[:int(len(h_bytes) / 2)], h1) assert err == skycoin.SKY_ERROR # Valid hex hash h2 = skycoin.cipher_SHA256() err, b = skycoin.SKY_cipher_SHA256_Hex(h) err = skycoin.SKY_cipher_SHA256FromHex(b, h2) assert h == h2 assert err == skycoin.SKY_OK
def test_TestSecKeyHashTest(): public_key = skycoin.cipher_PubKey() secret_key = skycoin.cipher_SecKey() secret_key_2 = skycoin.cipher_SecKey() skycoin.SKY_cipher_GenerateKeyPair(public_key, secret_key) sha_sum_1 = skycoin.cipher_SHA256() _, data = skycoin.SKY_cipher_RandByte(256) skycoin.SKY_cipher_SumSHA256(data, sha_sum_1) value = skycoin.skycoin.SKY_cipher_CheckSecKeyHash(secret_key, sha_sum_1) assert value == skycoin.SKY_OK value = skycoin.skycoin.SKY_cipher_CheckSecKeyHash(secret_key_2, sha_sum_1) assert value == skycoin.SKY_ErrInvalidSecKyVerification
def test_TestTransactionSignInputs(): handle = utils.makeEmptyTransaction() # Panics if txns already signed sig = skycoin.cipher_Sig() assert skycoin.SKY_coin_Transaction_PushSignature(handle, sig) == skycoin.SKY_OK secKeys = [] secKeys.append(skycoin.cipher_SecKey()) # Panics if not enough keys handle = utils.makeEmptyTransaction() ux, s = utils.makeUxOutWithSecret() h = skycoin.cipher_SHA256() assert skycoin.SKY_coin_UxOut_Hash(ux, h) == skycoin.SKY_OK err, _ = skycoin.SKY_coin_Transaction_PushInput(handle, h) assert err == skycoin.SKY_OK ux2, s2 = utils.makeUxOutWithSecret() assert skycoin.SKY_coin_UxOut_Hash(ux2, h) == skycoin.SKY_OK err, _ = skycoin.SKY_coin_Transaction_PushInput(handle, h) assert err == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_PushOutput( handle, utils.makeAddress(), 40, 80) == skycoin.SKY_OK err, count = skycoin.SKY_coin_Transaction_GetSignaturesCount(handle) assert err == skycoin.SKY_OK assert count == 0 # Valid signing assert skycoin.SKY_coin_Transaction_HashInner(handle, h) == skycoin.SKY_OK secKeys = [] secKeys.append(s) secKeys.append(s2) assert skycoin.SKY_coin_Transaction_SignInputs( handle, secKeys) == skycoin.SKY_OK err, count = skycoin.SKY_coin_Transaction_GetSignaturesCount(handle) assert err == skycoin.SKY_OK assert count == 2 h2 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_HashInner( handle, h2) == skycoin.SKY_OK assert h == h2 p = skycoin.cipher_PubKey() assert skycoin.SKY_cipher_PubKeyFromSecKey(s, p) == skycoin.SKY_OK a = skycoin.cipher__Address() a2 = skycoin.cipher__Address() assert skycoin.SKY_cipher_AddressFromPubKey(p, a) == skycoin.SKY_OK assert skycoin.SKY_cipher_PubKeyFromSecKey(s2, p) == skycoin.SKY_OK assert skycoin.SKY_cipher_AddressFromPubKey(p, a2) == skycoin.SKY_OK sha1 = skycoin.cipher_SHA256() sha2 = skycoin.cipher_SHA256() txin0 = skycoin.cipher_SHA256() txin1 = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_GetInputAt( handle, 0, txin0) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_GetInputAt( handle, 1, txin1) == skycoin.SKY_OK assert skycoin.SKY_cipher_AddSHA256(h, txin0, sha1) == skycoin.SKY_OK assert skycoin.SKY_cipher_AddSHA256(h, txin1, sha2) == skycoin.SKY_OK txsig0 = skycoin.cipher_Sig() txsig1 = skycoin.cipher_Sig() assert skycoin.SKY_coin_Transaction_GetSignatureAt( handle, 0, txsig0) == skycoin.SKY_OK assert skycoin.SKY_coin_Transaction_GetSignatureAt( handle, 1, txsig1) == skycoin.SKY_OK
def test_TestTransactionsHashes(): handle = utils.makeTransactions(4) err, hashes = skycoin.SKY_coin_Transactions_Hashes(handle) assert err == skycoin.SKY_OK len_hashes = len(hashes) assert len_hashes == 4 for i in range(len_hashes): err, tx = skycoin.SKY_coin_Transactions_GetAt(handle, i) assert err == skycoin.SKY_OK h = skycoin.cipher_SHA256() assert skycoin.SKY_coin_Transaction_Hash(tx, h) == skycoin.SKY_OK assert h == hashes[i] i += 1
def test_TestSignHash(): public_key = skycoin.cipher_PubKey() secret_key = skycoin.cipher_SecKey() addres = skycoin.cipher__Address() sha_sum = skycoin.cipher_SHA256() sig_1 = skycoin.cipher_Sig() sig_2 = skycoin.cipher_Sig() skycoin.SKY_cipher_GenerateKeyPair(public_key, secret_key) skycoin.SKY_cipher_AddressFromPubKey(public_key, addres) _, data = skycoin.SKY_cipher_RandByte(256) skycoin.SKY_cipher_SumSHA256(data, sha_sum) skycoin.SKY_cipher_SignHash(sha_sum, secret_key, sig_1) assert sig_1 != sig_2
def test_TestUxArrayHashArray(): uxa = utils.makeUxArray(4) sha = skycoin.cipher_SHA256() err, hashs = skycoin.SKY_coin_UxArray_Hashes(uxa) assert err == skycoin.SKY_OK assert len(hashs) == len(uxa) skycoin.SKY_coin_UxOut_Hash(uxa[0], sha) print(sha) print(uxa[0]) assert hashs[0] == sha for i in range(len(hashs)): assert skycoin.SKY_coin_UxOut_Hash(uxa[i], sha) == 0 assert sha == hashs[i]
def test_TestSHA256Set(): h = skycoin.cipher_SHA256() _, b = skycoin.SKY_cipher_RandByte(33) assert skycoin.SKY_cipher_SHA256_Set(h, b) == skycoin.SKY_ErrInvalidLengthSHA256 _, b = skycoin.SKY_cipher_RandByte(100) assert skycoin.SKY_cipher_SHA256_Set(h, b) == skycoin.SKY_ErrInvalidLengthSHA256 _, b = skycoin.SKY_cipher_RandByte(31) assert skycoin.SKY_cipher_SHA256_Set(h, b) == skycoin.SKY_ErrInvalidLengthSHA256 _, b = skycoin.SKY_cipher_RandByte(0) assert skycoin.SKY_cipher_SHA256_Set(h, b) == skycoin.SKY_ErrInvalidLengthSHA256 _, b = skycoin.SKY_cipher_RandByte(32) assert skycoin.SKY_cipher_SHA256_Set(h, b) == skycoin.SKY_OK _, b = skycoin.SKY_cipher_RandByte(32) skycoin.SKY_cipher_SHA256_Set(h, b) assert h.toStr()[:] == b
def test_TestCreateUnspents(): err, pubkey, seckey, address = utils.makeKeysAndAddress() assert err == skycoin.SKY_OK hash1 = skycoin.cipher_SHA256() txn = utils.makeEmptyTransaction() err = skycoin.SKY_coin_Transaction_PushOutput(txn, address, int(11e6), int(255)) assert err == skycoin.SKY_OK bh = skycoin.coin__BlockHeader() bh.Time = 0 bh.BkSeq = 1 err, uxouts = skycoin.SKY_coin_CreateUnspents(bh, txn) assert err == skycoin.SKY_OK assert err == skycoin.SKY_OK assert len(uxouts) == 1
def makeUxBodyWithSecret(): p = skycoin.cipher_PubKey() s = skycoin.cipher_SecKey() assert skycoin.SKY_cipher_GenerateKeyPair(p, s) == skycoin.SKY_OK uxb = skycoin.coin__UxBody() err, b = skycoin.SKY_cipher_RandByte(128) assert err == skycoin.SKY_OK h = skycoin.cipher_SHA256() assert skycoin.SKY_cipher_SumSHA256(b, h) == skycoin.SKY_OK assert h.assignTo(uxb.SrcTransaction) == None a = skycoin.cipher__Address() assert skycoin.SKY_cipher_AddressFromPubKey(p, a) == skycoin.SKY_OK uxb.Address = a uxb.Coins = int(1e6) uxb.Hours = int(100) return uxb, s
def test_TestPubKeyFromSig(): public_key = skycoin.cipher_PubKey() secret_key = skycoin.cipher_SecKey() skycoin.SKY_cipher_GenerateKeyPair(public_key, secret_key) sha_sum = skycoin.cipher_SHA256() _, data = skycoin.SKY_cipher_RandByte(256) skycoin.SKY_cipher_SumSHA256(data, sha_sum) sig_1 = skycoin.cipher_Sig() skycoin.SKY_cipher_SignHash(sha_sum, secret_key, sig_1) public_key_2 = skycoin.cipher_PubKey() assert skycoin.SKY_cipher_PubKeyFromSig(sig_1, sha_sum, public_key_2) == skycoin.SKY_OK assert public_key == public_key_2 sig_2 = skycoin.cipher_Sig() assert skycoin.SKY_cipher_PubKeyFromSig( sig_2, sha_sum, public_key_2) == skycoin.SKY_ErrInvalidSigPubKeyRecovery
def makeNewBlock(uxHash): bodyhash = skycoin.cipher_SHA256() transactions = makeTestTransactions() err, block = skycoin.SKY_coin_NewEmptyBlock(transactions) assert err == skycoin.SKY_OK err, pBlock = skycoin.SKY_coin_GetBlockObject(block) assert err == skycoin.SKY_OK pBlock.Head.Version = 0x02 pBlock.Head.Time = 100 pBlock.Head.BkSeq = 0 pBlock.Head.Fee = 10 err, body = skycoin.SKY_coin_GetBlockBody(block) assert err == skycoin.SKY_OK err = skycoin.SKY_coin_BlockBody_Hash(body, bodyhash) assert err == skycoin.SKY_OK return skycoin.SKY_coin_NewBlock(block, int(100 + 200), uxHash, transactions, utils.feeCalc)
def test_TestSHA256KnownValue(): vals = [] values = struct_test() values.inputs = b"skycoin" values.outputs = b"5a42c0643bdb465d90bf673b99c14f5fa02db71513249d904573d2b8b63d353d" vals.append(values) values.inputs = b"hello world" values.outputs = b"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9" vals.append(values) values.inputs = b"hello world asd awd awd awdapodawpokawpod " values.outputs = b"99d71f95cafe05ea2dddebc35b6083bd5af0e44850c9dc5139b4476c99950be4" for v in vals: b = v.inputs h = skycoin.cipher_SHA256() err = skycoin.SKY_cipher_SumSHA256(b, h) assert err == skycoin.SKY_OK _, h = skycoin.SKY_cipher_SHA256_Hex(h) assert h == v.outputs