QSign is a post quantum document signature SDK for the Quantova network. It signs any document with the Module Lattice Digital Signature Algorithm, parameter set 65, as standardised in FIPS 204, and it can bind each signature to a Qstamp time proof so that any third party can establish that the signature existed no later than a stated moment.
A QSign signature does not depend on elliptic curve or RSA cryptography at any point. The signature, the key fingerprint, the time proof and the chain that carries it are all built on primitives that no known quantum algorithm breaks.
QSign is a software library and command line tool that gives any organisation post quantum digital signatures for its documents. A signature made with QSign proves three things to anyone who checks it. It proves which key signed, because only the holder of that key can produce it. It proves what was signed, because any change to a single byte of the document breaks the signature. And when the signature is anchored, it proves when it was signed, because the Quantova network records independent evidence of the moment the signature existed.
QSign is designed to sit beside the systems an organisation already runs. It does not replace a document management system, an electronic signature platform or a records archive. It adds a signature layer that remains secure after the arrival of large scale quantum computers, and an evidence layer that a court, a regulator or an auditor can check without relying on the signer, on the platform that stored the document or on Quantova Inc.
QSign is standalone. It runs on the servers of the organisation, holds its keys locally and uses the Quantova network only as a neutral public ledger for time proofs.
Nearly every digital signature in use today relies on RSA or elliptic curve cryptography. A sufficiently capable quantum computer will be able to forge those signatures, and from that point a forged contract and a genuine one cannot be told apart. Records that must be kept for five, ten or more years are signed today but must still be provable after that point.
Governments have set dates for the transition. The NSA CNSA 2.0 suite requires post quantum software and firmware signing by 2030. NIST proposes to retire classical signatures after 2030 and to disallow them after 2035. The European Union, the United Kingdom, Singapore, Japan and South Korea have published comparable roadmaps for the financial sector and public bodies.
QSign supports that transition for documents now, with a standardised algorithm, and adds independent proof of signing time so that every signature made before any future compromise can still be shown to be genuine.
- Banks and lenders signing loan agreements, credit decisions, mandates and board resolutions.
- Payment firms and insurers signing policies, claims decisions, settlement instructions and customer correspondence.
- Asset managers and broker dealers signing trade confirmations, client agreements and regulatory reports.
- Government bodies and agencies signing permits, procurement awards, certificates and official decisions.
- Law firms, notaries and auditors sealing executed copies, evidence bundles and audit reports.
- Software and AI companies signing releases, model cards and outputs that their clients must later rely on.
Integration follows the same sequence in every organisation, whatever its size.
-
Decide who signs. Each signing role, such as a treasury officer, a credit committee, a compliance function or an automated system, receives its own key. Keys are never shared between people or systems.
-
Create and protect the keys. Each key is created with the keygen command or the generateKey function and stored where the organisation stores its most sensitive secrets, such as a secrets manager, an encrypted vault or a hardware protected store. The key file is a 32 byte seed and must be readable only by the signing service or person.
-
Publish the keys. For every key the organisation signs and anchors a key publish statement, and gives the resulting key description to its counterparties, auditors and regulators. Anyone who verifies a signature then checks it against that published key.
-
Sign at the point of decision. The signing call is added to the workflow at the moment a document becomes final, for example when a loan is approved, a policy is issued or a filing is submitted. The application passes the document and the signing key to QSign and stores the returned envelope beside the document. The document itself never leaves the systems of the organisation.
-
Anchor on a schedule. A single service with a funded Quantova account anchors new envelopes in batches, for example every few minutes or once an hour. One transaction can anchor many signatures at negligible cost, and each envelope receives its own receipt.
-
Keep the envelope with the record. The envelope with its receipt is stored for the full retention period alongside the document, in the same archive and under the same retention rules.
-
Verify when evidence is needed. When a court, a regulator, an auditor or a counterparty asks for proof, the organisation hands over the document and its envelope. The recipient verifies them with the verify command, the library or the independent procedure below, without any access to the systems of the organisation.
-
Revoke keys when people leave or devices are retired. A key revoke statement is signed and anchored at once. Signatures anchored before the revocation remain valid, and any later use of the key is shown to be invalid.
- Document management and archives. A hook in the archive signs each document when it is marked final and stores the envelope as an attachment.
- Loan origination, policy administration and case management. The approval step calls QSign with the approver key and records the key identifier in the decision log.
- Electronic signature platforms. A completed agreement from an existing platform is sealed with an organisation key, adding a post quantum signature and an independent time proof to the classical one.
- Regulatory reporting. Each report file is signed before submission and the envelope is retained as evidence of what was filed and when.
- Software and AI release pipelines. The build step signs each artefact and its manifest so that clients can verify exactly what was delivered.
- Service integration. Any language that can call a Node service can use QSign through a small internal signing service that holds the keys and exposes sign and verify to other systems on the internal network.
The document never leaves the systems of its holder. QSign signs the SHA3 digest of the document, and the signature envelope holds that digest, never the document itself.
When a signature is anchored, only a 32 byte Qstamp commitment reaches the chain. That commitment is derived from a salted fingerprint of the signature and cannot be reversed into the signature, the document digest, the signer label or the note. The signature envelope and its receipt stay with the parties who hold them and are disclosed only when they choose, for example to a court, a regulator or an auditor.
-
Key. A signing key is a 32 byte seed held only by its owner. The ML-DSA-65 key pair is derived from the seed by the key generation procedure of FIPS 204. The public key is 1952 bytes.
-
Key identifier. The key identifier is the SHA3 hash with a 256 bit output of the ASCII label quantova/qsign/key/1, the byte 0x00 and the public key. It is written as 64 lowercase hexadecimal characters.
-
Subject. The subject of a document signature is the SHA3 digest with a 256 bit output of the document bytes, as specified in FIPS 202.
-
Statement. The signed message is a canonical binary statement. It begins with the ASCII bytes QSIG and the version byte 1, followed by seven fields in a fixed order. Each field is an unsigned 16 bit big endian length followed by its bytes. The fields are the statement type, the digest algorithm name sha3-256, the 32 byte subject digest, the 32 byte key identifier, the signing time as an ISO 8601 UTC string with milliseconds, the signer label in UTF-8 and the note in UTF-8. The length prefixes make every statement uniquely decodable, so no two distinct statements share an encoding.
-
Signature. The statement is signed with ML-DSA-65 in its hedged form, using 32 bytes of fresh randomness from the platform secure random source, under the FIPS 204 context string quantova/qsign/1. The context separates QSign signatures from every other use of the algorithm, including Quantova network transactions and contract orders, so a QSign signature can never be replayed as either. The signature is 3309 bytes and is checked against the public key before it is returned.
-
Envelope. The result is a JSON envelope in the format qsign/1. It holds the statement type, the algorithm name, the key identifier and public key, the subject digest, the signing time, the signer label, the note, the signature and, once anchored, a Qstamp receipt. Every field is validated strictly and any unknown field is refused.
-
Anchor. To anchor a signature, QSign computes the SHA3 hash of the ASCII label quantova/qsign/anchor/1, the byte 0x00, the encoded statement and the signature. That value is stamped as a Qstamp record of kind document, or of kind public record for key statements. Because the anchor value covers the signature itself, a receipt for one signature can never be attached to another.
A key holder can sign a key publish statement, which records that the key is in use, and a key revoke statement, which withdraws it. Both are QSign envelopes whose subject is the key identifier and both are anchored in the same way as document signatures.
A revocation takes effect from its anchor time. A document signature anchored before the revocation remains valid. A document signature anchored at or after the revocation, or within the same block, is invalid. When the chain of both anchors is the same, the order is decided by block height. A revocation that is not validly signed by the key it names is ignored, so no third party can withdraw a key or invalidate a genuine signature.
When verification succeeds, the following statements hold.
- The envelope is well formed and every field satisfies the format.
- The key identifier is the fingerprint of the public key in the envelope.
- The signature is a valid ML-DSA-65 signature by that public key over the exact statement.
- The document was supplied and its SHA3 digest equals the signed subject. Without the document a document signature is never valid, and the result is unverified.
- The signature was made by the expected key, which the verifier must always supply, so a signature by any other key never verifies.
- The envelope is anchored, unless the verifier explicitly allows an unanchored signature, and the anchor is a valid Qstamp receipt on the named chain that Qstamp reports as proven, it covers this exact signature, and the claimed signing time is no later than five minutes after the anchor time and no more than 24 hours before it, a window the verifier may change, or the signing time is reported as not proven.
- None of the revocations supplied was anchored before this signature. The verifier must always supply the revocations it holds, an empty list when it holds none, and without a list the result is indeterminate.
- The identity of the person or organisation behind a key. A key identifier must be matched to its holder by the verifier, for example through a published key statement or an agreement between the parties. The signer name and the note are text chosen by the holder of the key. They are self asserted, not a verified identity, and the verifier says so. A verifier can bind the signer name to the identity of the key by giving the key publish statement it received for that key through a trusted channel with the keyPublication option, or --key-publication, and verification then requires the signer name to match the name published with the key.
- The signing time when the envelope is not anchored. Without an anchor the time is only the claim of the signer.
- That a key has not been revoked by a revocation the verifier does not hold.
- Legal status as a qualified electronic signature in any jurisdiction, which requires a qualified trust service provider.
This release anchors on the live Quantova network Q-test-net-01. The signing module is compiled from the Quantova Q-Crypto library, which follows FIPS 204 and FIPS 202 and has been tested against the NIST vectors and cross checked against an independent implementation. It has not been validated under FIPS 140-3. An anchor counts as proven only when Qstamp reports it proven, by a finality certificate checked against a pinned validator roster or by official endpoints of the network run by two different operators. An anchor confirmed only by custom endpoints, or by a single endpoint under trustSingleEndpoint, is reported as unproven and treated as not anchored, so the result is never valid. Verification names the endpoints it consulted and says whether they are the official endpoints of the network.
Secret material is handled with care. The seed is accepted only as a byte array that the caller can wipe. Inside the signing module every copy of the seed, the randomness and the expanded private key is overwritten with zeros after each call, and the working memory used during signing is cleared.
QSign protects the signing keys, the signature envelopes, the key publish and key revoke statements, and the receipts of anchors. Documents never leave their holder.
It trusts the key that the verifier names as the expected signer, the key publications and revocations the verifier receives through a channel it trusts, the network values pinned in the Qstamp release it depends on, and the storage that holds the keys. It does not trust the gateway or any endpoint, or any party that holds or presents an envelope.
A forged or altered envelope fails its signature or the digest of the document, and verification always requires the expected key, so a signature by any other key never verifies. Signatures use the context string quantova/qsign/1, so a QSign signature can never be replayed as a network transaction, a contract order or a signature of another SDK. The anchor value covers the signature itself, so a receipt cannot be moved to another envelope, and every anchor is checked against the genesis and contract pinned in the Qstamp release. A hostile gateway cannot make an unproven anchor count. A signing time later than its anchor, allowing five minutes, makes the result invalid, and one more than 24 hours before its anchor is not proven. The holder of an exposed key anchors a key revoke statement, and signatures anchored at or after it are invalid. A revocation not signed by the key it names is ignored, so no third party can withdraw a key. Unknown fields and repeated JSON keys are refused, and the command line reads at most 64 KiB of envelope.
QSign keeps no ledger and signs no series, so presenting an envelope again proves the same signature and creates nothing new. Left to the integrator are the protection of keys, matching a key to its holder, supplying the revocations it holds, at most 64 for one verification, and the legal status of a signature. A key that is already lost cannot sign its own revocation, so verifiers should obtain revocations through the same trusted channel as the key.
npm install @quantovainc/qsign
QSign requires Node 20 or later.
Create a key. The key file holds the 32 byte seed as 64 hexadecimal characters and is written readable only by its owner.
qsign keygen alice.key
qsign key alice.key > alice.pub.json
Sign a document. The envelope is written beside the document with the suffix .qsig.json unless another path is given.
qsign sign contract.pdf --key alice.key --signer-file signer.txt --note-file note.txt
The signer name and the note are read from files, or from standard input when the file is given as -, so they never appear in the shell history or the process list.
Anchor one or more envelopes through a funded Quantova account.
qsign anchor contract.pdf.qsig.json --network testnet --seed-file account.key --index 0
qsign complete contract.pdf.qsig.json --pending contract.pdf.qsig.json.pending.json
If an anchor is interrupted after its transaction may have been sent, the pending stamp is kept beside the first envelope and complete finishes it without paying again.
Verify an envelope against the document and the expected signer.
qsign verify contract.pdf.qsig.json --network testnet --file contract.pdf --public-key alice.pub.json --no-revocations
Publish or revoke a key.
qsign statement publish --key alice.key --out alice.publish.json
printf "Device retired" | qsign statement revoke --key alice.key --note-file - --out alice.revoke.json
qsign verify contract.pdf.qsig.json --network testnet --file contract.pdf --public-key alice.pub.json --revocation alice.revoke.json
The command exits with status 0 when the result is valid, 1 when it is invalid or the envelope cannot be read, 2 when it cannot be decided or rests on an unproven anchor, for example because no endpoint could be reached or a revocation has no proven time, 3 when it is unverified because the document was not given, and 64 for usage errors. An unreachable endpoint never produces a valid result. Key files that are readable by other users, are symbolic links or are not regular files are refused. Output files are written privately and moved into place, and an existing file is replaced only with the force option.
const qsign = require('@quantovainc/qsign');
const key = qsign.generateKey();
const envelope = await qsign.sign({ key, file: 'contract.pdf', signer: 'Alice Holdings' });
const publicKey = qsign.describeKey(key).publicKey;
key.fill(0);
const [anchored] = await qsign.anchor([envelope], { seed, index: 0 });
const result = await qsign.verify(anchored, { network: 'testnet', file: 'contract.pdf', publicKey, revocations: [] });The result reports a status of valid, invalid, indeterminate, unverified when the document was not given, or unproven when an anchor rests only on endpoints that are not pinned operators. It lists every check with its outcome and reason, and states whether the document was checked, whether the signer matched the expected key, whether the signer name matched a key publication and whether revocations were considered. A key statement is never accepted as a document signature.
An auditor can verify an envelope without this SDK by following these steps.
- Decode the public key and signature from base64 and confirm their lengths are 1952 and 3309 bytes.
- Compute the SHA3 hash of the label quantova/qsign/key/1, the byte 0x00 and the public key, and compare it with the key identifier.
- Encode the statement as described above and verify the signature over it with ML-DSA-65 under the context string quantova/qsign/1, following FIPS 204.
- Compute the SHA3 digest of the document and compare it with the subject digest.
- Compute the anchor value from the label quantova/qsign/anchor/1, the byte 0x00, the encoded statement and the signature, and verify the attached receipt for that value by the procedure published with Qstamp.
- Confirm the signing time is no later than five minutes after the block time of the anchor.
The live Quantova network is named Q-test-net-01. Its genesis hash and the official Qstamp contract that records anchors are pinned in the Qstamp release this SDK depends on. The public endpoint is https://q-test-net-01.quantova.org. By default verification consults the official endpoints of the network. Every verification names the network its envelopes were anchored on with the network option, or --network on the command line, testnet for the public network or custom for a chain reached only through endpoints the verifier chose, and an anchor recorded on any other network fails. Endpoints chosen by the verifier are given with the rpc or clients option, or with --rpc once for each on the command line, and verification consults them only with trustCustomEndpoints, or --trust-custom-endpoints. An endpoint on a loopback address is refused unless allowLoopback, or --allow-loopback, is set, and an endpoint on a private network address unless it is named in endpointAllowList, or with --allow-endpoint. The option expectedSender, or --expect-sender, names the Quantova accounts entitled to anchor records, and an anchor signed by any other account is invalid. Anchoring accepts chain data only when at least two endpoints run by different operators agree, and the option trustSingleEndpoint, or --trust-single-endpoint, relies on one endpoint for anchoring and for the time of the chain.
QSign is created and owned by Quantova Inc. It is licensed under the Apache License 2.0 or the MIT licence, at your option. The full texts are in the files LICENSE-APACHE and LICENSE-MIT, and the notice is in NOTICE.