PricingDemo
Log InGet API Key
H33-128H33-CKKSH33-256H33-FHE-IQH33-TFHEFHE OverviewH33-CompileZK LookupsBiometricsH33-3-KeyH33-MPCZK-TrustlessZK-PhishZK-VerifyPQC ArchitecturePQ VideoStorage EncryptionAI DetectionEncrypted Search
Security 10 min read

Why a Biometric Attestation Can Never Masquerade as a Bitcoin UTXO

Domain separation in the H33 substrate ensures that two substrates with identical payloads but different computation types produce completely different signing messages. 12 types tested, 66 cross-comparisons, zero collisions.

Eric Beans CEO, H33.ai

This is the third post in our series on the H33 substrate test suite. The first post covered the 74-byte primitive itself. The second covered canonical round-trip fidelity. This post is about a property that sounds mundane until you think about what happens without it: domain separation.

Domain separation is the guarantee that a substrate attesting one kind of computation can never be mistaken for a substrate attesting a different kind of computation. A BiometricAuth attestation (type 0x01) can never masquerade as a BitcoinUtxo attestation (type 0x06). A MedVaultPhi attestation (type 0x0A) can never masquerade as a KycVerification attestation (type 0x07). A LoanApplication attestation (type 0x11) can never masquerade as an AiInference attestation (type 0x0D). Not because of access control. Not because of database constraints. Because the cryptography makes it impossible.

The mechanism is straightforward. The consequences are not.

How the computation type byte enters the signing message

The H33-74 is 58 bytes. The second byte, at offset 1, is the computation type identifier. When a substrate is signed, the signing message is not the raw payload data. The signing message is the SHA3-256 hash of the entire 58-byte canonical encoding, which includes the computation type byte. The three-family signature bundle (ML-DSA-65, FALCON-512, SLH-DSA-SHA2-128f) is produced over this signing message. The compact receipt commits to the resulting signature bundle via another SHA3-256 hash.

This means the computation type byte is not metadata that rides alongside the signature. It is mixed into the hash that the signature covers. Change the computation type byte, and the SHA3-256 digest changes. Change the SHA3-256 digest, and the signing message changes. Change the signing message, and every signature in the three-family bundle becomes invalid. The type byte is load-bearing cryptographic structure, not an annotation.

We tested this explicitly. We constructed 12 substrates with identical payload data, identical 32-byte content hashes, identical 8-byte timestamps, identical 16-byte nonces, and identical version bytes. The only difference between any two substrates was the computation type byte at offset 1. We then computed the signing message (SHA3-256 of the canonical encoding) for each of the 12 substrates and compared every pair. That is 66 cross-comparisons: 12 choose 2. Every single pair produced a different signing message. Zero collisions. Zero near-collisions. Zero shared prefixes beyond what you would expect from a random oracle.

This is, of course, exactly what SHA3-256 guarantees. A single bit flip in the pre-image produces an avalanche in the digest. But guarantees from hash function theory and guarantees from running code are different things, and the test suite exists to verify that the running code matches the theory. It does.

The attack that domain separation prevents

Imagine a world without domain separation. The substrate's signing message is computed from the payload data but not from the computation type byte. The type byte exists only as a label, not as an input to the hash. In this world, here is what an attacker can do.

A hospital runs H33 substrate to attest biometric authentication events. Every time a nurse authenticates to a medication dispensing station, the system produces a BiometricAuth substrate (type 0x01) containing a SHA3-256 hash of the biometric match score, a timestamp, and a nonce. The substrate is signed with the hospital's three-family key set. The signature is valid. The attestation is legitimate.

Now the attacker takes that substrate, strips the 0x01 type byte, replaces it with 0x06 (BitcoinUtxo), and presents it to a different system that accepts Bitcoin UTXO attestations. In the world without domain separation, the signing message is the same because it was computed from the payload data alone. The signatures still verify. The receiving system sees a valid substrate with type 0x06, interprets the 32-byte content hash as a Bitcoin transaction hash, and processes it accordingly. The attacker has just taken a biometric authentication event and made it look like a Bitcoin transaction attestation, with cryptographically valid signatures.

This is a type confusion attack. It is the cryptographic equivalent of casting a float* to an int* in C and then dereferencing it: the bytes are the same, but the interpretation is wrong, and the consequences range from silent data corruption to total system compromise. Type confusion attacks are among the most dangerous classes of vulnerability in any system that handles typed data, because they subvert the type system that every downstream consumer relies on for correctness.

Domain separation eliminates this attack by construction. When the computation type byte is mixed into the signing message, changing the type byte invalidates the signatures. The attacker cannot produce valid signatures for the new type byte because producing valid signatures requires the signer's private keys. The attack is not merely difficult. It is cryptographically infeasible under the same assumptions that make the three-family signature bundle unforgeable.

The IANA analogy

Domain separation in the substrate is the same design principle that TCP port numbers, HTTP Content-Type headers, and IANA media types implement at the protocol layer. Port 80 is HTTP. Port 443 is HTTPS. Port 22 is SSH. A packet addressed to port 80 cannot be claimed to have been addressed to port 443, because the port number is part of the TCP header that routers and firewalls inspect. A file with Content-Type application/json cannot be claimed to be application/pdf, because the Content-Type header is part of the HTTP response that browsers and APIs interpret.

These registries share three properties. First, the namespace is public. Anyone can look up what port 443 means. Second, the namespace is append-only. Once port 443 is assigned to HTTPS, it stays HTTPS forever. IANA does not reassign port numbers. Third, the type identifier is part of the protocol's processing path, not a decorative label. A firewall that blocks port 22 doesn't care what the packet's payload looks like; it blocks the packet because the port number says SSH.

The substrate's computation type registry has all three properties. The registry is public: the list of all 28 assigned computation types is published in the substrate specification. The registry is append-only: once 0x06 is assigned to BitcoinUtxo, it will be BitcoinUtxo for the entire lifetime of the substrate protocol, regardless of what new types are added in the future. And the type identifier is part of the cryptographic processing path: it is mixed into the signing message hash, which means it is enforced by the mathematics of the signature scheme, not by a database constraint or an access control rule.

The analogy to IANA port numbers is more than illustrative. It is architectural. The substrate's computation type registry is, in effect, an IANA-style registry for cryptographic attestation domains. The same administrative discipline that makes TCP port numbers stable and trustworthy makes computation type bytes stable and trustworthy. The difference is that TCP port numbers are enforced by network stacks that can be reconfigured, while computation type bytes are enforced by SHA3-256 hashes that cannot be reconfigured. Domain separation in the substrate is IANA-grade administrative machinery backed by cryptographic-grade enforcement.

Practical use: Healthcare cross-application confusion

Consider a hospital network that uses substrate for two different purposes. First, MedVault attestations (type 0x0A, MedVaultPhi) that record when a physician accesses a patient's protected health information under HIPAA. Second, identity verification attestations (type 0x07, KycVerification) that record when a patient's identity is verified at intake.

Both attestation types are produced by the same hospital's signing infrastructure, using the same three-family key set. Both contain 32-byte content hashes. Both contain timestamps and nonces. A MedVaultPhi substrate might attest: "Dr. Smith accessed Patient 12345's medication history at 14:32:07 UTC." A KycVerification substrate might attest: "Patient 12345's identity was verified against a government-issued ID at 09:15:22 UTC."

Without domain separation, these two substrates are cryptographically interchangeable. An attacker with access to the MedVaultPhi attestation stream could take an attestation proving that a doctor accessed a record and present it as an attestation proving that a patient's identity was verified. The signatures would check out. An auditor examining the KycVerification log would see a valid substrate with what appears to be a verified identity event. The patient's identity was never actually verified at the claimed time; the attestation was lifted from a different context entirely.

In a healthcare setting, this kind of confusion has real consequences. A fraudulent identity verification attestation could be used to obtain prescriptions under someone else's name, to access medical services under a stolen identity, or to satisfy regulatory audit requirements without the underlying verification having actually occurred. HIPAA's access logging requirements exist precisely because the provenance of who accessed what record and when matters. If attestation types are interchangeable, the audit trail is meaningless.

Domain separation makes this substitution impossible. The MedVaultPhi substrate has 0x0A at offset 1. The KycVerification substrate has 0x07 at offset 1. The signing messages are different SHA3-256 digests. The signatures are different. Presenting one as the other fails verification immediately. The cryptography does not care whether the attacker has access to the attestation stream, whether they have inside knowledge of the hospital's systems, or whether they can manipulate database records. The type byte is inside the hash. The hash is inside the signature. The signature cannot be transferred.

Practical use: Multi-product companies

H33 runs substrate across more than nine products today. Biometric authentication (type 0x01). Fraud scoring (type 0x02). FedNow payment attestation (type 0x03). Solana transaction attestation (type 0x04). HATS governance proofs (type 0x05). Bitcoin UTXO attestation (type 0x06). KYC verification (type 0x07). Document archival signing (type 0x09). Medical PHI operations (type 0x0A). HTTP API response attestation (type 0x0C). AI model inference provenance (type 0x0D). And several more.

All of these products share the same signing infrastructure. They use the same three-family key sets. They produce substrates with the same 58-byte canonical layout. They store compact receipts with the same 42-byte format. A naive implementation without domain separation would create a massive cross-product attack surface: any substrate from any product could be replayed into any other product's verification pipeline. A fraud score attestation could be presented as an AI inference attestation. A document signing attestation could be presented as a FedNow payment attestation. The attack surface would be the Cartesian product of all products times all products, minus the diagonal.

Domain separation collapses this attack surface to zero. Each product's attestations are cryptographically isolated by the computation type byte. A substrate from the biometrics product cannot verify as a substrate from the document signing product, even though both were signed by the same key set, because the signing messages are different. This is not a policy enforcement or a configuration setting. It is a mathematical consequence of including the type byte in the hash pre-image. No amount of misconfiguration, no accidental routing of substrates between products, no insider with database access can cause one product's attestation to verify as another product's attestation. The isolation is cryptographic, not procedural.

For a company running substrate across many products, this property eliminates an entire class of integration bugs. When product A's verification pipeline receives a substrate, it checks the computation type byte, and if the byte does not match product A's expected type, verification fails before the signatures are even checked. But even if someone removed that check through a coding error, the signatures themselves would still fail, because the signing message that product A's verifier recomputes from the canonical encoding with product A's type byte would not match the signing message that was actually signed with product B's type byte. Defense in depth: the type check catches it first, and the signature check catches it even if the type check is missing.

Practical use: Regulatory compliance

Financial regulators increasingly require that different categories of attestation be kept separate. The reasoning is sound: a system that conflates financial transaction records with non-financial operational records creates opportunities for fraud, makes audits harder, and violates the principle of least privilege at the data layer.

Consider a lending platform that uses substrate for two purposes. First, LoanApplication attestations (type 0x11) that record the cryptographic commitment to a borrower's application data at the time of submission. Second, ApiResponse attestations (type 0x0C) that record the cryptographic commitment to API responses served to internal dashboards. Both are legitimate uses of substrate. Both produce valid, signed attestations. But a regulator examining the lending platform's audit trail needs to know, with certainty, that a LoanApplication attestation is actually a LoanApplication attestation and not an ApiResponse attestation that was relabeled.

Without domain separation, this certainty does not exist at the cryptographic level. It exists only at the database level, which means it is only as trustworthy as the database's access controls, the application's labeling logic, and the operator's discipline. Any of these can fail. Database migrations can mislabel records. Application bugs can write the wrong type. Operators with admin access can edit records. If the type label is not part of the cryptographic commitment, the regulator's certainty rests on operational controls, not on mathematics.

With domain separation, the certainty is cryptographic. A LoanApplication substrate has 0x11 at offset 1. An ApiResponse substrate has 0x0C at offset 1. The signing messages are different. The signatures are different. No database migration, application bug, or administrative action can cause one to verify as the other. When a regulator asks "how do you ensure that financial attestations are not conflated with non-financial attestations?", the answer is not "we have database constraints and access controls." The answer is "the computation type byte is mixed into the SHA3-256 hash that the three-family signature bundle covers, and changing the type byte invalidates the signatures. The separation is enforced by the same mathematics that makes the signatures unforgeable."

This is a qualitatively different kind of compliance guarantee. Operational controls can be audited, but they can also be circumvented. Cryptographic controls can be audited and they cannot be circumvented, because circumventing them requires breaking the underlying cryptographic assumptions. For financial regulators who have spent the last two decades watching operational controls fail in increasingly creative ways, a compliance guarantee that rests on SHA3-256 collision resistance and three-family signature unforgeability is a meaningful upgrade.

The test results

Our test suite for domain separation is exhaustive within the current type registry. We tested 12 computation types: BiometricAuth (0x01), FraudScore (0x02), FedNowPayment (0x03), SolanaTransaction (0x04), HatsGovernance (0x05), BitcoinUtxo (0x06), KycVerification (0x07), MpcComputation (0x08), DocumentArchive (0x09), MedVaultPhi (0x0A), SecretManagement (0x0B), and ApiResponse (0x0C). For each pair of types, we constructed two substrates with identical payloads (same content hash, same timestamp, same nonce, same version byte) and verified that the signing messages are different. That is 66 pairwise comparisons. All 66 produced different signing messages.

We also verified the positive case: for each of the 12 types, a substrate signed under that type verifies correctly when the verifier expects that type. And the negative case: for each of the 66 pairs, a substrate signed under type A fails verification when the verifier expects type B. The failure is not a timeout or an error code. It is a signature verification failure, which is the strongest possible rejection: the mathematics says no.

The test does not merely check that the signing messages are "different" in the sense of not being byte-equal. It checks that they are cryptographically independent in the sense that knowing one signing message gives no information about any other signing message derived from the same payload with a different type byte. This is a consequence of SHA3-256's design as a sponge construction with full-width absorption, but we verify it empirically because empirical verification is cheap and the alternative is trusting theory alone.

Why this matters for the post-quantum transition

The post-quantum transition is not going to be a single event. It is going to be a gradual process in which more and more systems adopt post-quantum cryptographic primitives for more and more purposes. During this transition, the number of distinct attestation types will grow. Biometric attestations, financial attestations, healthcare attestations, AI provenance attestations, document signing attestations, IoT device attestations, supply chain attestations, and categories we have not yet imagined will all need post-quantum cryptographic binding.

Without domain separation, the growth of attestation types creates a growing attack surface. Each new type adds new cross-type confusion opportunities. The number of potential confusion attacks grows quadratically with the number of types: N types means N(N-1)/2 possible confusions. At 28 types (the current registry size), that is 378 potential confusion vectors. At 100 types, it is 4,950. At 256 types (the maximum for a single byte), it is 32,640.

With domain separation, the growth of attestation types creates zero additional attack surface. Each new type is cryptographically isolated from every existing type by the same mechanism that isolates the first two types from each other. The computation type byte is mixed into the hash. The hash is covered by the signature. The signature cannot be transferred. Adding the 29th type to the registry does not weaken the isolation between any of the existing 28 types. The security argument is the same whether the registry has 2 types or 256 types.

This is the kind of property that matters most when you are building infrastructure that will be used for decades. The substrate is a primitive, and primitives outlive the applications that first use them. TCP port numbers were defined in 1981. They are still the same port numbers. The substrate's computation type registry is designed with the same time horizon in mind, and domain separation is the property that makes that time horizon achievable without the attack surface growing alongside the registry.

The next post in this series covers Test 4: timestamp and nonce uniqueness, and why no two substrates should ever share the same signing message even when attesting the same computation type with the same payload. Domain separation ensures different types produce different signing messages. Timestamp and nonce uniqueness ensures that even within the same type, each attestation is a distinct cryptographic event.

Build with the H33 Substrate

The substrate crate is available for integration. Every H33 API call now returns a substrate attestation.

Get API Key Read the Docs