Book a demo
Under the hood

Check the invoice without seeing it.

Countersign is a registry of invoice fingerprints, pledges and customer confirmations. It is built so that no single party's word is enough, the registry never receives an invoice, and every answer is a receipt anyone can check. Here is how, and how far along each piece is.

Doneworks today Buildingin the MVP Plannedbefore the first paid pilot
01

Each state is signed by whoever knows it.

No step relies on the lender's word, an AI review, or our database alone.

StateSigned byWhat it proves
RegisteredSupplier, at issueThis invoice existed in this form at this time.
CountersignedCustomer (the account debtor)The customer owes it, unchanged, and to this pay-to account.
PledgedLenderWho funded it first, without telling other lenders who.
ReleasedLender, or the payment itselfIt's paid or repurchased, so it can't be funded again.

The registry adds its own signature to every state change through Optima Prime, so the record of who said what, and when, can't be quietly edited later.

02

Blinded fingerprints.

Building

Invoice fields are low-entropy. A plain hash of a supplier tax ID, an invoice number and an amount can be guessed by brute force in minutes. A shared secret key doesn't fix that either, because every member would need the key and any of them could run the guesses.

Countersign uses an oblivious pseudorandom function (OPRF) over the ristretto255 group. Your side blinds the fields before they leave; the registry applies its secret key to a value it can't read; your side removes the blind. The result is a fingerprint only computable with the registry's help, one rate-limited query at a time.

# on the lender's or supplier's side
fields = normalise(supplier_tax_id, customer_tax_id, invoice_no,
                   issue_date, amount_cents, currency, due_date)
P      = hash_to_group(fields)          # ristretto255 point
r      = random_scalar()
B      = r * P                          # blinded; reveals nothing

# at the registry (never sees fields or P)
Z      = k * B                          # k = registry key

# back on your side
F      = hash(fields, (1/r) * Z)        # = hash(fields, k * P)
fingerprint = "cs1:" + F

Normalising matters as much as the cryptography: the same invoice must give the same fingerprint whether it came from a PDF, a CSV row or an accounting system. Tax IDs, invoice numbers, dates and amounts each get one canonical form before hashing.

Planned The registry key k is split between independent key holders, so no single party, including us, can compute fingerprints alone.

03

Exact and partial matches.

Building

One fingerprint can only say "same" or "different". To catch a $180 invoice resubmitted as $9,000, each invoice gets several fingerprints over different groups of fields:

FingerprintFieldsCatches
fullAll core fieldsAn exact duplicate
identitySupplier, customer, invoice numberThe same invoice with a changed amount or date
economicsSupplier, customer, amount, issue dateThe same invoice under a new number

A check returns one of: never seen (no record, which is not a pass), registered and unchanged, registered but fields differ, already pledged to another lender, or countersigned by the customer.

04

The customer countersignature.

Building

Signing at issue stops later changes and double sales. It can't stop a supplier from inventing an invoice. Only the customer knows whether it owes the money, so the customer's confirmation is the core of the product.

  1. Countersign finds and verifies the customer's payables contact itself. The supplier never supplies it.
  2. The customer gets a link. No account, no app.
  3. They confirm with a passkey (WebAuthn: Face ID, Touch ID, Windows Hello or a security key). The passkey signs a challenge built from the invoice fingerprint, the amount and a hash of the pay-to account.
  4. That signature is attached to the invoice's record and to the lender's receipt.

Because the pay-to account is part of what the customer signs, a later request to send the money somewhere else needs a new countersignature from the customer. Large payables teams can register a hardware security key instead; Optima Prime already verifies those as standard OpenSSH signatures.

05

An append-only pledge log.

Planned

"Who pledged first" is only worth something if the registry can't reorder or hide entries. Every pledge and release is appended to a Merkle tree, in the style of Certificate Transparency (RFC 6962). The tree's head is signed and time-stamped by an independent RFC 3161 time-stamp authority.

Any member can ask for an inclusion proof (my pledge is in the log) and a consistency proof (today's log extends yesterday's without rewriting it). Entries hold fingerprints and blinded member IDs, so the log can be audited without exposing anyone's book.

06

Receipts anyone can check.

Done in Optima Prime

Countersign signs through Optima Prime, our signing server. Its /v1/attest endpoint signs a statement that a given key attested a given SHA-256 at a given time, without ever seeing the data behind the hash. That is exactly the shape of an invoice fingerprint.

Every receipt carries two signatures over canonical JSON: Ed25519 and the post-quantum ML-DSA-87, so the evidence stays checkable for the years a dispute can run. The public keys are published, and a receipt can be verified offline with open tools.

{
  "statement":  "check",
  "fingerprint":"cs1:7f3a91c0e24b0d8f55a1c9e73b02aa64",
  "result":     "fields_differ",
  "member":     "m_9c2e",                 // blinded
  "time":       "2026-10-10T16:42:09Z",
  "signatures": { "ed25519": "…", "ml_dsa_87": "…" }
}

Field names above are illustrative. The receipt format is being finalised.

07

What we store, and what we never get.

StoredNever received
Fingerprints (blinded, see 02)The invoice document
Pledge and release statesCustomer and supplier names
Member IDsAmounts and terms in the clear
Signed receipts and countersignaturesYour client list

A hit tells a lender that a match exists. It never says which lender holds it. Identities are released only with the holder's consent or under legal process, under a written member rulebook.

08

Stack.

No blockchain. No token.

PieceBuilt withStatus
Signing and verificationOptima Prime, on our own hardwareDone
Registry API and matchingPHP 8.1 and MySQL on our own Ubuntu serversBuilding
Blinded fingerprintslibsodium ristretto255Building
Customer countersignatureWebAuthn passkeysBuilding
IntakeREST API and CSV upload; QuickBooks Online firstBuilding
Pledge logMerkle tree with RFC 3161 time stampsPlanned
Signing keys in a hardware moduleHSM-held Optima Prime keysPlanned

Countersign is closed source. The receipts aren't: their format and the public keys are published, so checking one never depends on trusting our code.

09

What it can't do.

Countersign informs. It doesn't enforce. A lender that funds without waiting for the customer's confirmation is back to taking the supplier's word.

  • If someone inside the customer's payables team is in on the fraud, their countersignature is a lie too. Confirmation history across lenders and matching against actual payments help, but nothing fully stops collusion.
  • Detecting a double sale needs the other lender to be a member. An empty network only protects your own book.
  • A receipt is evidence. It does not perfect a lien or set legal priority between lenders.

Want to go deeper?