Agreebase uses SHA-256 hashes to make record and content identity independently checkable. The correct input depends on the record type.
Ordinary agreement, declaration, or witnessed record body hash
Normalize the body in this order:
- Unicode NFC normalization.
- Replace CRLF and CR with LF.
- Strip leading and trailing whitespace.
- Encode as UTF-8.
- Compute SHA-256 as lowercase hexadecimal.
Pseudocode:
text = unicode_nfc(raw_body)
text = replace(text, "\\r\\n", "\\n")
text = replace(text, "\\r", "\\n")
text = strip(text)
body_hash = sha256_hex(utf8(text))
The database commonly stores the digest without a prefix. Evidence metadata and blockchain records use sha256:<64 lowercase hex characters>.
Notarization content hash
For a file notarization, hash the exact file bytes. Do not hash its filename, rendered PDF appearance, or metadata.
For a text notarization, apply the same NFC/LF/trim/UTF-8 process before hashing. The server checks that the submitted digest matches the normalized text.
For a hash notarization, the caller supplies an existing SHA-256 digest. The server does not infer or reconstruct the source content.
Notarizations do not use the agreement fuzzy fingerprint.
Evidence metadata hash
At seal time, Agreebase builds an agreebase.evidence_metadata.v1 package. It contains stable record facts, the body/content hash, completed current-version participants, redacted and scoped contact evidence, and signature-method evidence. A notarization package also includes its notarization payload and content hash.
To compute metadata_hash:
- Copy the metadata object.
- Remove
metadata_hashif present. - Serialize JSON with keys sorted at every level, compact
,and:separators, and UTF-8 output. - Compute SHA-256.
- Compare
sha256:<digest>with the package and blockchain value.
The metadata hash is separate from the signed PDF/document hash.
Fuzzy fingerprints
An exact body hash only matches text that's identical down to the last character. That's the right check most of the time, but it means a single retyped word, a copy-paste that dropped a line break, or a PDF-to-text export that mangled some whitespace will fail to match even though the substance is clearly the same document. The fuzzy fingerprint exists for that situation: a secondary, near-complete-text match that can succeed where the exact hash can't.
It works by treating the normalized body as a set of overlapping short character sequences, encoding them alongside a large number of decoy values so the stored fingerprint reveals nothing about the text itself, and requiring a high proportion of a candidate's sequences to line up with the stored ones before it counts as a match. That threshold is intentionally strict; it tolerates small, incidental differences, not a different document that happens to share some wording.
Some ordinary agreement, declaration, and witnessed-record bodies carry a fuzzy fingerprint; notarizations do not use one at all, since a notarization's whole purpose is proving identity of exact content. A fuzzy fingerprint match is always reported as a fuzzy match, never as an exact one; treat it as "this is very likely the same text," not as cryptographic proof that it is.
Blockchain record format
Ordinary hash-only records contain the AGR reference, body hash, metadata hash, and completion time. Full-text records contain the selected body text instead of the body-hash line.
Notarization records contain the AGR reference, content hash, content type, hash algorithm, selected advisory metadata, metadata hash, and completion time. A text notarization can include normalized text only when public text publication was enabled.
Independent verification
A verifier can use the public verifier, a retained PDF/email, the evidence metadata package, and the transaction hash. For hash-only ordinary records, the verifier needs candidate text. For file notarizations, the verifier needs the original file bytes or its independently computed digest.
See Comparing document hashes for a user-oriented procedure.