Skip to content

Blockchain-backed timestamp proof for structured document sections

License

Notifications You must be signed in to change notification settings

wonkyweirdy/stramp

Repository files navigation

PyPI Python package build status

stramp

Timestamp a structured text document such that the content of any section or subsection can later be proved to have existed at (approximately) the time the document was stamped.

STRuctured text stAMP → STRAMP

This tool uses decentralized trusted timestamping technology that is backed by the Bitcoin blockchain. The protocol used is OpenTimestamps. Servers supporting this protocol are public and free to use.

The advantage of Stramp over using another OpenTimestamps client directly is that you can prove one or more chosen sections of your document selectively without revealing the content of the entire document. This is useful if you collect notes for a project in a large file where some sections may have information you don't want to reveal and other sections have text for which you might want timestamp proof at some later time.

It is intended for this command to be run periodically in the background with a service such as cron. I'd recommend setting it up to run once or twice a day.

Applications

This tool has the same applications as digital trusted timestamping in general, but the convenience and zero cost make it much more practical. Set it up to run in the background on your note files, and with practically no further effort you'll get the benefit in case you ever need it:

  • Patent documentation - This can't be directly used to win a patent since everyone has switched to first-to-file. However, it may still be useful for defensive publication to prevent someone else from patenting an idea you came up with.

  • Trade secrets - Prove that you had the idea of doing something a certain way.

  • Simple bragging rights - Write your idea or prediction in your notes so you can later prove you had it at a specific date.

Installation

Stramp requires Python 3.6 or newer. In addition to the Python library dependencies (automatically installed, assuming you use pip), you will also need the ots command from opentimestamps-client:

pip install opentimestamps-client

If Stramp is available from PyPI, you can install it with:

pip install stramp

Other options are to install it from the GitHub repository directly:

pip install -U "git+https://github.com/wonkyweirdy/stramp#egg=stramp"

or to install from a cloned git repository:

git clone https://github.com/wonkyweirdy/stramp.git
pip install ./stramp

How it works

  1. Each document files is copied to create an archive copy. The archive copy is stored in the directory ~/.stramp/data named based on the hash of the file.

  2. The text of each document, individual sections, and recursive subsections, is hashed using a secure hash algorithm to produce hexadecimal hash strings. These hash strings are collected into a JSON file along with the associated file paths and some other metadata. The JSON file goes in the ~/.stramp/new directory.

  3. The generated JSON hash file is then timestamped using the ots stamp command. Once stamped, the JSON hash file and its associated *.ots file are moved into the ~/.stramp/stamped directory. At this point, the stamp data will have been submitted to the public calendar servers. It will take time for the timestamp to be processed on the servers.

  4. The stamp file (*.ots) is upgraded using ots upgrade. Once upgraded, the JSON hash file and its associated *.ots file are moved into the ~/.stramp/complete directory. The upgraded stamp will contain all the information needed to trace the timestamp back to the specific transaction and block in the Bitcoin blockchain. Note that for a hash file stamped on the current run, the upgrade will happen on a subsequent run. It can take a few hours before the path is confirmed into a Bitcoin block. There is a built-in age limit that will prevent new (less than eight hours old) stamps from being upgraded; this is to help ensure that all the servers had enough time to process the stamp completely.

The new and stamped directories are used as queues. If the ots stamp or ots upgade command fails for a hash file on one run, it will be retried on a later run.

Configuration

The configuration file is expected to be at ~/.stramp/config.json.

Example content:

{
    "ots_command_path": "/usr/local/bin/ots",
    "documents": [
        {
          "path": "/home/joe/Documents/personal-notes.org",
          "format": "org"
        },
        {
          "path": "/home/joe/Documents/project1/project1.md",
          "format": "commonmark"
        }
    ]
}

The ots_command_path specification is optional. It defaults to just "ots", expecting that command to be found in the command search path.

Usage

Stramp will normally be called as:

stramp -x

The -x option implies -p, so the result of the above command would be to hash all the documents in the configured list and then do any processing (see the How it works section above).

Command help is available with stramp --help:

Usage: stramp [OPTIONS] [FILES]...

Options:
  -x, --hash       Hash the files listed in the configuration
  -p, --process    Stamp or upgrade any hash files that need processing
  -c, --hash-only  Just write generated hash file JSON to standard output
  -v, --verbose    Print more information
  -V, --version    Print the application version
  --help           Show this message and exit.

Stamp verification

Stramp does not implement anything to help with verification. The easiest way to check a stamp is to drop it onto the opentimestamps.org web page. If you want to check it locally, it is more involved since you need to run (or have access to) a server running Bitcoin Core.

Document formats

Org-mode

Org-mode format as UTF-8 is supported since this is what I use for my notes. The Org-mode support may not even be complete since have only implemented it to support the Org features I use.

Markdown

Markdown is supported. The specific variant of Markdown supported is CommonMark. Other variants may work as long as the headings can still be correctly interpreted using the rules of CommonMark.

Markdown support depends on Marko. Either install Marko separately or specify commonmark extra when installing with pip:

pip install "stramp[commonmark]"

Future formats

I would consider adding support for other lightweight markup languages:

Maybe other structured document formats:

  • HTML
  • ENEX (Evernote)

Security

I am aware that the content of a section could be deduced from only a hash in a hash file if that text is short or predictable. For example, this would be a problematic in an Org-mode text file:

* Passwords:
** letmein
** YouCantGuessThis

I'm ignoring this for now in the interest of keeping things simple.

Legal

My opinion is that this tool should in principal allow creating indisputable proof that the text of a section of a document existed at a specific point of time. The proof will continue to be indisputable for as long as the cryptography involved can be trusted. However, we don't know for sure there isn't someone in a secret lab somewhere able to trivially forge an SHA-2 hash.

I can't promise this tool is appropriate for any certain use case. Users need to evaluate this for themselves. Quoth the LICENSE file:

The software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.

Similar and related projects