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.
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.
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
-
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. -
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. -
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. -
The stamp file (
*.ots
) is upgraded usingots 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.
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.
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.
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.
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 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]"
I would consider adding support for other lightweight markup languages:
Maybe other structured document formats:
- HTML
- ENEX (Evernote)
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.
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.