Galatine Contact us

galatine / txint-format

TXINT

TXINT export format

TXINT exports an investigation as JSON, CSV, Excel, Markdown and PDF. The JSON file carries the whole journal of the investigation, so the person who receives it checks it from the file alone, without the product or its database.

What an export holds

The Markdown and PDF reports are built from the same content, so a section cannot appear in one and be missing from the other. The report is written in the language chosen in the interface.

  1. What the investigation is, and a note that the analysis is heuristic.
  2. In the PDF, the picture of the graph as it stood on the analyst's screen.
  3. The risk reading with every reason, the rule and its limits.
  4. The largest movements of funds.
  5. What is missing from the graph.
  6. What the data sources answered.
  7. Where the trail crosses between chains.
  8. The analyst's notes and the addresses they name.
  9. The findings, and the analyst's decision on each.
  10. The journal of the investigation and its head.

Every piece of text is marked as TXINT's own words, as data from outside or as an identifier, and is escaped according to that mark. Rebuilding the same report gives a PDF identical byte for byte.

The journal of the investigation

Every step that changes what the investigation says is written to the journal as it happens: creation, collection, expanding a node, running the detectors, the analyst's decision, a note, an export. The entry names who took the step and when, and carries SHA-256 digests of what it produced.

Every entry also carries the digest of the one before it. An edited or removed entry breaks the chain at a place the check can name.

What is hashed

  • The graph: for every node its identifier, chain, address and labels (source, name, category), and for every transfer its identifier, chain, transaction, ends, asset, amount as text, time, block, type and status. The records are sorted by identifier. What a person typed into the graph is left out: notes are recorded as entries of their own.
  • The findings: identifier, detector and its version, severity, confidence as text to three decimal places, the identifiers of nodes, links and transactions, and the thresholds. The text of the explanation is left out of the digest: it exists in two languages and says the same thing in both.
  • The file: the bytes of the export exactly as it was sent.

The digest of the graph after a build is computed from the graph read back from the database. That way every later check compares what is stored.

The canonical text

A digest is computed from JSON with keys in alphabetical order, no whitespace between elements, in UTF-8, with Cyrillic and other characters as they are. The scheme of the journal entries is called txint-custody-v1.

A journal entry is stored as the exact text its digest was computed from. Rebuilt from database columns, it could disagree with its digest over the way one number is written.

Checking an export

The person who receives a JSON file checks three things, and everything needed for that is in the file itself.

  1. The journal is intact: every entry's digest matches, each links to the one before, and the numbering has no gaps.
  2. The head of the chain recorded in the file is the last entry of the journal.
  3. The graph and the findings in the file give the digests the journal last recorded.

The standard library of any language is enough for these checks: SHA-256 and canonical JSON by the rules above.

Matching TXINT's journal

The entry for an export is written to TXINT's journal after the file, because a file cannot contain its own digest. Its file digest equals the SHA-256 of the file received, and its link to the previous entry equals the head of the chain inside the file.

The head of the chain in every export is kept outside TXINT, by the recipient. It shows whether the journal in TXINT's database was rewritten as a whole after the export.