edgecase
Author: StJohn Piano
Published: 2019-02-07
Datafeed Article 83
This article has been digitally signed by Edgecase Datafeed.
This article has been digitally signed by its author.
4392 words - 1667 lines - 42 pages





GOAL



Verify the first checkpoint article published on Edgecase Datafeed.




CONTENTS



- Goal
- Contents
- Brief Summary
- Summary
- Notes
- Project Log




BRIEF SUMMARY



I verified the digital signature and the timestamp of the first checkpoint in Edgecase Datafeed.

The digital signature was made by the Edgecase Datafeed public key.

A SHA256 hash can be used as a Bitcoin private key. A Bitcoin address was derived from the SHA256 hash of the signed checkpoint article. The oldest transaction that contains this address exists in a particular block.

The presence of this address shows that the signed checkpoint article existed at the blockheight and timestamp of this particular block.

The Bitcoin blockchain data for this block:
- block height: 473266
- date confirmed: 2017-06-28

So:
- Edgecase Datafeed began on 2017-06-28 (block height 473266).
- The Edgecase Datafeed public key has existed since at least 2017-06-28 (because a valid signature made by this key is known to exist at this date).






SUMMARY



Working on a VPS, I verified the digital signature and the timestamp of the first checkpoint in Edgecase Datafeed.

I used these tools on the VPS:
- GPG 1.4.10
- cURL
- Vim
- Bash
- sha256sum
- Python 2.6.6

I also used a local machine for various tasks e.g. web browsing.

The digital signature was made by the Edgecase Datafeed public key.

The timestamp was the confirmation datetime of a block in the Bitcoin blockchain. This block contained a transaction that made a payment to a particular Bitcoin address. This Bitcoin address was derived from the SHA256 hash of the signed checkpoint article.

The transaction shows [0] that this article existed at the blockheight and timestamp of this particular block.

Details of the checkpoint block and transaction:
- block hash:
0000000000000000013bd1a5f07afc8791542f0e24044e218b606f71804eca33
- block height: 473266
- txid:
b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670

Link to the first checkpoint article:
checkpoint 0

The first checkpoint article contains a hyperlink in the Navigation Menu that leads to the original article. In a browser, I copied the hyperlink address.

I then used cURL on the VPS to download the checkpoint file from this address to the VPS.

I verified the checkpoint article's digital signature, which was made by the Edgecase Datafeed public key. For details, see the "Verifying the digital signature of the checkpoint article" part of the Notes section.

I confirmed the validity of the timestamp of this checkpoint article, using the Bitcoin blockchain as the source of truth. For details, see the "Verifying the timestamp of the checkpoint article" part of the Notes section.

The article contained this date:
2017-06-28
and this approximate block height:
473264

The actual blockchain data was:
- block height: 473266
- date confirmed: 2017-06-28

The dates are the same. The address is timestamped 2 blocks later than the approximate block height.

So:
- Edgecase Datafeed began on 2017-06-28 (block height 473266).
- The Edgecase Datafeed public key has existed since at least 2017-06-28 (because a valid signature made by this key is known to exist at this date).


Notes section:

The Notes section contains the following parts:

- Terms and acryonyms
- Services used during this project
- Equipment used during this project
- Checkpoint system in Edgecase Datafeed
- Verifying the digital signature of the checkpoint article
- Verifying the timestamp of the checkpoint article








NOTES





Parts:


- Terms and acryonyms
- Services used during this project
- Equipment used during this project
- Checkpoint system in Edgecase Datafeed
- Verifying the digital signature of the checkpoint article
- Verifying the timestamp of the checkpoint article




Terms and acronyms


- GPG or GnuPG = GNU Privacy Guard
- GNU = GNU's not Unix
- VPS = Virtual Private Server
- DigitalOcean = A cloud infrastructure provider
- Droplet = DigitalOcean's term for a VPS
- tx = transaction
- txid = transaction id




Services used during this project


I used the search field at
live.blockcypher.com
to search for the address
17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae

On the resulting address page:
live.blockcypher.com/btc/address/17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae
two transactions are listed. The bottom one was the oldest. Click the hyperlinked txid of the bottom one.

On the resulting transaction page:
live.blockcypher.com/btc/tx/b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670
I clicked Advanced Details / API Call, which produced a raw text dump of the transaction:
api.blockcypher.com/v1/btc/main/txs/b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670?limit=50&includeHex=true




Equipment used during this project


From several previous projects, I have a VPS (a DigitalOcean droplet) on which GPG 1.4.10 is installed and which I can access via openSSH from a Windows laptop.


Local system:
- Name = SP_THINKPAD_1. SP stands for StJohn Piano.
- Hardware = Lenovo Thinkpad X200 (Laptop). Two internal hard drives, each of 75 GB capacity.
- Processor = Intel(R) Core(TM)2 Duo CPU, P8600 @ 2.40GHz
- Memory (RAM) = 4.00 GB
- Operating System = Windows 7 Professional (Service Pack 1), 64-bit

I installed Cygwin on SP_THINKPAD_1 during a previous project:
Installing Cygwin on Windows 7

I installed OpenSSH on Cygwin on SP_THINKPAD_1 during another previous project:
Installing OpenSSH on Cygwin and using it to access a VPS


Remote system (a VPS):
- Provider: DigitalOcean
- Distribution = CentOS 6.9 x64
- Memory = 1 GB
- vCPUS = 1 vCPU
- SSD Disk = 25 GB
- Transfer = 1 TB
- Price = $5/mo, $0.007/hr
- Datacentre region = London
- hostname = spt1
- SSH Key = SP_THINKPAD_1
- IP address = 178.62.36.113
- domain = edgecase-test.net

I installed GPG 1.4.10 on the VPS in a previous project:
Compiling GPG 1.4.10 from source




Checkpoint system in Edgecase Datafeed


Currently, the Edgecase Datafeed checkpoint process involves:

- Creating a new checkpoint article, which contains various details of each new article (including its SHA256 hash) published since the last checkpoint.
- Digitally signing the new checkpoint article using GPG 1.4.21 and the Edgecase Datafeed public key.
- Finding the SHA256 hash of the new signed checkpoint article.
- Using the resulting SHA256 hash as a Bitcoin private key and deriving the corresponding Bitcoin public address.
- Transferring some bitcoin to this new address. The transaction that executes this transfer will be embedded in a particular block on the Bitcoin blockchain.

The Bitcoin block will have a particular blockheight and timestamp. The presence of this transaction in this block shows that the signed checkpoint article existed at this blockheight and timestamp. It also shows that the set of new non-checkpoint articles, whose details were included in the new checkpoint article, existed at some time between this checkpoint and the previous checkpoint.




Verifying the digital signature of the checkpoint article


The first checkpoint article is named checkpoint_0.txt.

The signature is a GPG detached signature that has been appended (with some formatting) to the end of the checkpoint article file.

Using a text editor (e.g. Vim), open the checkpoint article file, and perform the following steps:

- Find the line number of the line
<datafeed_article>
. It should be 2.
- Find the line number of the line
</datafeed_article>
. For the first checkpoint article, it is 25.
- Find the line number of the line
<datafeed_signature>
. For the first checkpoint article, it is 26.
- Find the line number of the line
</datafeed_signature>
. For the first checkpoint article, it is 40.
- Copy the lines starting from
<datafeed_article>
and ending at
</datafeed_article>
to a new file named "datafeed_article.txt". For the first checkpoint article, these are lines 2-25 inclusive.
- Copy the lines starting from
<datafeed_signature>
and ending at
</datafeed_signature>
to a new file named "datafeed_article.sig". For the first checkpoint article, these are lines 26-40 inclusive.

Note: Line numbers are 1-indexed.

Remove the last newline byte from datafeed_article.txt. The article data ends with a final greater-than-sign (>), which closes the final element in the data tree.

The
truncate
tool can be used to do this:
truncate -s -1 datafeed_article.txt


Open datafeed_article.sig and perform the following steps:
- Replace the first line
<datafeed_signature>
with
-----BEGIN PGP SIGNATURE-----
. Add an additional blank line after it.
- Replace the last line
</datafeed_signature>
with
-----END PGP SIGNATURE-----
.

Download the public key of Edgecase Datafeed.

Link to the Edgecase Datafeed page:
edgecase.net/pages/edgecase_datafeed

This page contains a hyperlink that leads to the public key file.

In a browser, I copied the hyperlink address.

I then used cURL on the VPS to download the public key file from this address to the VPS.

Next: Set up a temporary GPG keyring, import the Edgecase Datafeed public key into this keyring, and run the verify-signature command.

Make a directory "keyring_tmp" that will contain the temporary GPG keyring.

[root@spt1 work]# mkdir keyring_tmp


Set the directory permissions for "keyring_tmp" to the permissions that GPG expects. A setting of 700 allows the user (you) to read/write/execute anything in the directory, but prevents any other user account on your system (e.g. another program) from doing so.

[root@spt1 work]# chmod 700 keyring_tmp


Create a temporary GPG keyring in the keyring_tmp directory and import the Edgecase Datafeed public key into it.

[root@spt1 work]# gpg --no-default-keyring --keyring pubring.gpg --homedir keyring_tmp --import edgecase_datafeed_public_key.txt

gpg: keyring `keyring_tmp/secring.gpg' created gpg: keyring `keyring_tmp/pubring.gpg' created gpg: keyring_tmp/trustdb.gpg: trustdb created gpg: key 60881870: public key "edgecase_datafeed" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)


Check the validity of the digital signature of the checkpoint article.

[root@spt1 work]# gpg --no-default-keyring --keyring pubring.gpg --homedir keyring_tmp --verify datafeed_article.sig datafeed_article.txt

gpg: Signature made Wed 28 Jun 2017 06:26:55 PM UTC using RSA key ID 60881870 gpg: Good signature from "edgecase_datafeed" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 112D 22BA 9DE1 60ED 6A20 E07D 22F5 3B36 6088 1870


This line:
gpg: Good signature from "edgecase_datafeed"

means that GPG has verified that the signature was made by the Edgecase Datafeed private key.




Verifying the timestamp of the checkpoint article


Find the SHA256 hash digest of the signed checkpoint article file.

[root@spt1 work]# sha256sum checkpoint_0.txt

1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa checkpoint_0.txt


SHA256 hash:
1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa


Use this SHA256 hash as a Bitcoin private key and derive the corresponding Bitcoin address.

I followed this recipe:
Recipe for generating a Bitcoin address

Bitcoin address:
17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae


Look up this address in a blockchain information service, and find out if and when some bitcoin was transferred to it.

I used:
live.blockcypher.com

The oldest transaction shown for this address had this txid:
b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670


The information service reported that for this transaction:
- block height: 473266
- confirmed: 2017-06-28 17:28:22 UTC










PROJECT LOG




From several previous projects, I have a VPS (a DigitalOcean droplet) on which GPG 1.4.10 is installed and which I can access via openSSH from a Windows laptop.


Local system:
- Name = SP_THINKPAD_1. SP stands for StJohn Piano.
- Hardware = Lenovo Thinkpad X200 (Laptop). Two internal hard drives, each of 75 GB capacity.
- Processor = Intel(R) Core(TM)2 Duo CPU, P8600 @ 2.40GHz
- Memory (RAM) = 4.00 GB
- Operating System = Windows 7 Professional (Service Pack 1), 64-bit

I installed Cygwin on SP_THINKPAD_1 during a previous project:
Installing Cygwin on Windows 7

I installed OpenSSH on Cygwin on SP_THINKPAD_1 during another previous project:
Installing OpenSSH on Cygwin and using it to access a VPS

Remote system (a VPS):
- Provider: DigitalOcean
- Distribution = CentOS 6.9 x64
- Memory = 1 GB
- vCPUS = 1 vCPU
- SSD Disk = 25 GB
- Transfer = 1 TB
- Price = $5/mo, $0.007/hr
- Datacentre region = London
- hostname = spt1
- SSH Key = SP_THINKPAD_1
- IP address = 178.62.36.113
- domain = edgecase-test.net

I installed GPG 1.4.10 on the VPS in a previous project:
Compiling GPG 1.4.10 from source




Currently, the Edgecase Datafeed checkpoint process involves:
- creating a new checkpoint article that contains the SHA256 hash of each new article published since the last checkpoint.
- digitally signing the new checkpoint article using GPG 1.4.21. This proves that the checkpoint was written and published by Edgecase Datafeed.
- hashing the new signed checkpoint article using SHA256.
- using the resulting hash digest as a Bitcoin private key and deriving the corresponding Bitcoin public address.
- transferring some bitcoin to this new address. This means that the new signed checkpoint article has now been timestamped on the Bitcoin blockchain. It also means that the set of new articles has been timestamped between two checkpoint articles - this checkpoint and the previous one.


During this project, I will verify the first checkpoint article - checkpoint 0. In this context, "verify" means to confirm the validity of the Edgecase digital signature and of the Bitcoin blockchain timestamp.




On my local machine:


Create new project directory:
verifying_a_checkpoint_article

Create new work directory named "work" in the project directory.


Open a Cygwin64 Terminal and use
ssh
to log into the CentOS VPS.

Admin@Admin-PC ~

$ ssh root@edgecase-test.net
Last login: Fri Oct 5 13:33:12 2018 from [IP address string]

[root@spt1 ~]# cd /home/work


[root@spt1 work]# ls -1


[root@spt1 work]# curl --version

curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.27.1 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz



cURL is available.


On my local machine, open Chrome. Browse to:
checkpoint 0

Right-click "Download this article" and choose "Copy link address". The link address is the http link to the checkpoint file.

Link address:
edgecase.net/articles/2017-06-28_edgecase_datafeed_article_0_checkpoint_0/2017-06-28_edgecase_datafeed_article_0_checkpoint_0.txt


I'll use cURL on the VPS to download the checkpoint file to the VPS.



[root@spt1 work]# curl http://edgecase.net/articles/2017-06-28_edgecase_datafeed_article_0_checkpoint_0/2017-06-28_edgecase_datafeed_article_0_checkpoint_0.txt > checkpoint_0.txt

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 105 1894 105 1894 0 0 25861 0 --:--:-- --:--:-- --:--:-- 1849k


[root@spt1 work]# ls -1

checkpoint_0.txt

[root@spt1 work]# file checkpoint_0.txt

checkpoint_0.txt: ASCII English text

[root@spt1 work]# ls -l checkpoint_0.txt

-rw-r--r-- 1 root root 1894 Oct 6 15:57 checkpoint_0.txt

[root@spt1 work]# ls -lh checkpoint_0.txt

-rw-r--r-- 1 root root 1.9K Oct 6 15:57 checkpoint_0.txt



Good.

Its size is 1.9 KB.





Next: Verify the digital signature of the checkpoint.

The signature is a GPG detached signature that has been appended (with some formatting) to the end of the checkpoint article file.


So, I need to extract the signature, producing two files: the signature file and the unsigned checkpoint file.


I'm going to use a text editor to do the extraction manually.

From previous work, I know that the Vim editor is available on this VPS. For a basic guide to Vim, see the Basic Vim Commands section of the project Testing a list of Vim commands.



Use the
cat
command to view the contents of checkpoint_0.txt. Copy the contents into this article (the Cygwin terminal provides scroll-back functionality).



checkpoint_0.txt
<signed_datafeed_article> <datafeed_article> <datafeed_name>edgecase_datafeed</datafeed_name> <datafeed_article_id>0</datafeed_article_id> <date>2017-06-28 <note>This is the date at the time of creation of this datafeed article. A block containing a transaction confirming this datafeed article may appear on this date or at a later date.</note> </date> <previous_checkpoint>None</previous_checkpoint> <checkpoint_article> <checkpoint_id>0</checkpoint_id> <title>checkpoint_0</title> <date>2017-06-28 <note>This is the date at the time of creation of this checkpoint article. A block containing a transaction confirming this checkpoint may appear on this date or at a later date.</note> </date> <block> <blockchain_name>bitcoin</blockchain_name> <block_height>473264 <note>This is the approximate block height at the time of creation of this checkpoint article. A transaction confirming this checkpoint will appear in a later block.</note> </block_height> </block> <content> This is the first checkpoint in the edgecase datafeed. </content> </checkpoint_article> </datafeed_article> <datafeed_signature> iQIcBAABCgAGBQJZU/TvAAoJECL1OzZgiBhwL8YP/iKeSW4pdfD65am4Vnm26KjX sEdogn6LsqTl06IANIFspuQFA26yUb1RoRB0wKpGLCVrz1K2cOrLCQ/PQNVzOje0 dZtkAosg/kNUnkBNTjdlQKIu8zFwn2iQk6oUJacdrxpMjNHOLYPrLmDpOYm3NSfJ erfwOlVPmc8zKtImnYQ9T0LLX/Y2q/YDalj4NQEInvI1Aw+O/Mr9l0+cbyKAxpTq mAwllQgtswuYtyGX7M5cpfG2MyfUYhny0P9+dYGkdlR8eecjqtNDMyTbMZ0iSQfw DEUH6uPSvny8nluilMX0TKoXELHZw1gp7UjZV9AP1rq7b9R6E61B1i2xt9iD84c/ 4Vr+gbzwUn0DFIFxo09rTI7+3SUCJSWWswy6+BAx2P5Ga8qqYAkky+j7qO6eDu4W KfpNmjNR8S6T+duRB8rBcZIWYZnPpiiyh+DJlczRARUK0iT2wOIoUp81OLn9yiC0 adVC2v27zEwQMI7YJh6RSi7t2mEHz5ZpK3gAkRhlquHX+4ESI3rM/PlusKUquP71 DYPc1GWku/i80veu7t+577vlihFvoh02gTFLVsIGOOjxXn7KLZLanhjCxeqf0HXK AOC9lGAcAS/e0GztecXlwg0WnXhweyrk4Bx+8q+KO7QucHwYzBPt7GfY16gf0kzw nvKkCYvCLNolb4hCQkY2 =xbHy </datafeed_signature> </signed_datafeed_article>





Open checkpoint_0.txt in
vim
and perform the following steps:
- Find the line number of the line
<datafeed_article>
. It should be 2.
- Find the line number of the line
</datafeed_article>
. In this case, it is 25.
- Find the line number of the line
<datafeed_signature>
. In this case, it is 26.
- Find the line number of the line
</datafeed_signature>
. In this case, it is 40.
- Copy the lines starting from
<datafeed_article>
and ending at
</datafeed_article>
to a new file named "datafeed_article.txt". In this case, these are lines 2-25 inclusive.
- Copy the lines starting from
<datafeed_signature>
and ending at
</datafeed_signature>
to a new file named "datafeed_article.sig". In this case, these are lines 26-40 inclusive.
- Exit Vim.



Open file in Vim:

[root@spt1 work]# vim checkpoint_0.txt




Done.



[root@spt1 work]# ls -1

checkpoint_0.txt
datafeed_article.sig
datafeed_article.txt





datafeed_article.txt
<datafeed_article> <datafeed_name>edgecase_datafeed</datafeed_name> <datafeed_article_id>0</datafeed_article_id> <date>2017-06-28 <note>This is the date at the time of creation of this datafeed article. A block containing a transaction confirming this datafeed article may appear on this date or at a later date.</note> </date> <previous_checkpoint>None</previous_checkpoint> <checkpoint_article> <checkpoint_id>0</checkpoint_id> <title>checkpoint_0</title> <date>2017-06-28 <note>This is the date at the time of creation of this checkpoint article. A block containing a transaction confirming this checkpoint may appear on this date or at a later date.</note> </date> <block> <blockchain_name>bitcoin</blockchain_name> <block_height>473264 <note>This is the approximate block height at the time of creation of this checkpoint article. A transaction confirming this checkpoint will appear in a later block.</note> </block_height> </block> <content> This is the first checkpoint in the edgecase datafeed. </content> </checkpoint_article> </datafeed_article>





datafeed_article.sig
<datafeed_signature> iQIcBAABCgAGBQJZU/TvAAoJECL1OzZgiBhwL8YP/iKeSW4pdfD65am4Vnm26KjX sEdogn6LsqTl06IANIFspuQFA26yUb1RoRB0wKpGLCVrz1K2cOrLCQ/PQNVzOje0 dZtkAosg/kNUnkBNTjdlQKIu8zFwn2iQk6oUJacdrxpMjNHOLYPrLmDpOYm3NSfJ erfwOlVPmc8zKtImnYQ9T0LLX/Y2q/YDalj4NQEInvI1Aw+O/Mr9l0+cbyKAxpTq mAwllQgtswuYtyGX7M5cpfG2MyfUYhny0P9+dYGkdlR8eecjqtNDMyTbMZ0iSQfw DEUH6uPSvny8nluilMX0TKoXELHZw1gp7UjZV9AP1rq7b9R6E61B1i2xt9iD84c/ 4Vr+gbzwUn0DFIFxo09rTI7+3SUCJSWWswy6+BAx2P5Ga8qqYAkky+j7qO6eDu4W KfpNmjNR8S6T+duRB8rBcZIWYZnPpiiyh+DJlczRARUK0iT2wOIoUp81OLn9yiC0 adVC2v27zEwQMI7YJh6RSi7t2mEHz5ZpK3gAkRhlquHX+4ESI3rM/PlusKUquP71 DYPc1GWku/i80veu7t+577vlihFvoh02gTFLVsIGOOjxXn7KLZLanhjCxeqf0HXK AOC9lGAcAS/e0GztecXlwg0WnXhweyrk4Bx+8q+KO7QucHwYzBPt7GfY16gf0kzw nvKkCYvCLNolb4hCQkY2 =xbHy </datafeed_signature>





Remove the last newline byte from datafeed_article.txt.

[root@spt1 work]# truncate -s -1 datafeed_article.txt







Open datafeed_article.sig in
vim
and perform the following steps:
- Replace the first line
<datafeed_signature>
with
-----BEGIN PGP SIGNATURE-----
. Add an additional blank line after it.
- Replace the last line
</datafeed_signature>
with
-----END PGP SIGNATURE-----
.
- Save changes and exit Vim.




[open file in vim]
[root@spt1 work]# vim datafeed_article.sig




Done.



datafeed_article.sig
-----BEGIN PGP SIGNATURE----- iQIcBAABCgAGBQJZU/TvAAoJECL1OzZgiBhwL8YP/iKeSW4pdfD65am4Vnm26KjX sEdogn6LsqTl06IANIFspuQFA26yUb1RoRB0wKpGLCVrz1K2cOrLCQ/PQNVzOje0 dZtkAosg/kNUnkBNTjdlQKIu8zFwn2iQk6oUJacdrxpMjNHOLYPrLmDpOYm3NSfJ erfwOlVPmc8zKtImnYQ9T0LLX/Y2q/YDalj4NQEInvI1Aw+O/Mr9l0+cbyKAxpTq mAwllQgtswuYtyGX7M5cpfG2MyfUYhny0P9+dYGkdlR8eecjqtNDMyTbMZ0iSQfw DEUH6uPSvny8nluilMX0TKoXELHZw1gp7UjZV9AP1rq7b9R6E61B1i2xt9iD84c/ 4Vr+gbzwUn0DFIFxo09rTI7+3SUCJSWWswy6+BAx2P5Ga8qqYAkky+j7qO6eDu4W KfpNmjNR8S6T+duRB8rBcZIWYZnPpiiyh+DJlczRARUK0iT2wOIoUp81OLn9yiC0 adVC2v27zEwQMI7YJh6RSi7t2mEHz5ZpK3gAkRhlquHX+4ESI3rM/PlusKUquP71 DYPc1GWku/i80veu7t+577vlihFvoh02gTFLVsIGOOjxXn7KLZLanhjCxeqf0HXK AOC9lGAcAS/e0GztecXlwg0WnXhweyrk4Bx+8q+KO7QucHwYzBPt7GfY16gf0kzw nvKkCYvCLNolb4hCQkY2 =xbHy -----END PGP SIGNATURE-----







Next: Get the public key of Edgecase Datafeed.

On my local machine, open Chrome. Browse to the Edgecase Datafeed page:
edgecase.net/pages/edgecase_datafeed

Right-click "[Download public key] " and choose "Copy link address". The link address is the http link to the public key file.

Link address:
edgecase.net/pages/edgecase_datafeed/edgecase_datafeed_public_key.txt


I'll use cURL on the VPS to download the checkpoint file to the VPS.



[root@spt1 work]# curl http://edgecase.net/pages/edgecase_datafeed/edgecase_datafeed_public_key.txt > edgecase_datafeed_public_key.txt

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 101 3049 101 3049 0 0 35653 0 --:--:-- --:--:-- --:--:-- 2977k


[root@spt1 work]# ls -1

checkpoint_0.txt
datafeed_article.sig
datafeed_article.txt
edgecase_datafeed_public_key.txt






edgecase_datafeed_public_key.txt
-----BEGIN PGP PUBLIC KEY BLOCK----- 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 =e4Lh -----END PGP PUBLIC KEY BLOCK-----







Next: Make another directory "keyring_tmp" within the work directory for use as a temporary GPG keyring. Set the directory permissions for "keyring_tmp" to the permissions that GPG expects. A setting of 700 allows the user (you) to read/write/execute anything in the directory, but prevents any other user account on your system (e.g. another program) from doing so.


[root@spt1 work]# mkdir keyring_tmp


[root@spt1 work]# chmod 700 keyring_tmp







Next: Create a temporary GPG keyring in the keyring_tmp directory and import the Edgecase Datafeed public key into it. First, check that the command
gpg
calls the expected GPG version (1.4.10).


[root@spt1 work]# gpg --version

gpg (GnuPG) 1.4.10 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: ~/.gnupg Supported algorithms: Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA Cipher: 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224 Compression: Uncompressed, ZIP, ZLIB


[root@spt1 work]# gpg --no-default-keyring --keyring pubring.gpg --homedir keyring_tmp --import edgecase_datafeed_public_key.txt

gpg: keyring `keyring_tmp/secring.gpg' created gpg: keyring `keyring_tmp/pubring.gpg' created gpg: keyring_tmp/trustdb.gpg: trustdb created gpg: key 60881870: public key "edgecase_datafeed" imported gpg: Total number processed: 1 gpg: imported: 1 (RSA: 1)







Next: Check the validity of the digital signature of the checkpoint article.


[root@spt1 work]# gpg --no-default-keyring --keyring pubring.gpg --homedir keyring_tmp --verify datafeed_article.sig datafeed_article.txt

gpg: Signature made Wed 28 Jun 2017 06:26:55 PM UTC using RSA key ID 60881870 gpg: Good signature from "edgecase_datafeed" gpg: WARNING: This key is not certified with a trusted signature! gpg: There is no indication that the signature belongs to the owner. Primary key fingerprint: 112D 22BA 9DE1 60ED 6A20 E07D 22F5 3B36 6088 1870



The important result is this line:
gpg: Good signature from "edgecase_datafeed"


It means that GPG has used the Edgecase Datafeed public key to verify that the signature was created using the Edgecase Datafeed private key.







Good.




Next: Confirm the validity of the timestamp of this checkpoint article within the Bitcoin blockchain.




First, I need the SHA256 hash of the checkpoint article.




[root@spt1 work]# sha256sum --version

sha256sum (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Ulrich Drepper, Scott Miller, and David Madore.

[root@spt1 work]# sha256sum checkpoint_0.txt

1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa checkpoint_0.txt




SHA256 hash:
1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa




Next, I need to use this SHA256 hash as a Bitcoin private key and derive the corresponding Bitcoin address.


On my local machine, open Chrome. Browse to:
Recipe for generating a Bitcoin address
I'll follow the recipe, working on the VPS.


These assets are paywalled. Move to a computer that has paywall access, download these assets, and transfer them to my local machine. Place them in the work directory.


I'll use sftp to transfer them from my local machine to the VPS. Then I'll follow the recipe, using the SHA256 hash as a private key.



[root@spt1 work]# exit

logout
Connection to edgecase-test.net closed.

[some path exploration occurs here]

Admin@Admin-PC ~

$ cd /cygdrive/c/Documents\ and\ Settings/Admin/Desktop/work/PROJECTS_CURRENT/verifying_a_checkpoint_article/work


Admin@Admin-PC /cygdrive/c/Documents and Settings/Admin/Desktop/work/PROJECTS_CURRENT/verifying_a_checkpoint_article/work

$ sftp root@edgecase-test.net
Connected to edgecase-test.net.

sftp> pwd
Remote working directory: /root

sftp> cd /home/work

sftp> ls -1
checkpoint_0.txt
datafeed_article.sig
datafeed_article.txt
edgecase_datafeed_public_key.txt
keyring_tmp

sftp> lls -1
bitcoin_functions.py
bjorn_edstrom_ripemd160.py
ecdsa-0.10.tar.gz
generate_bitcoin_address_3.py
pypy_sha256.py

sftp> mkdir generate_address

sftp> ls -1
checkpoint_0.txt
datafeed_article.sig
datafeed_article.txt
edgecase_datafeed_public_key.txt
generate_address
keyring_tmp

sftp> cd generate_address/

sftp> put *
Uploading bitcoin_functions.py to /home/work/generate_address/bitcoin_functions.py bitcoin_functions.py 100% 23KB 159.4KB/s 00:00 Uploading bjorn_edstrom_ripemd160.py to /home/work/generate_address/bjorn_edstrom_ripemd160.py bjorn_edstrom_ripemd160.py 100% 14KB 197.9KB/s 00:00 Uploading ecdsa-0.10.tar.gz to /home/work/generate_address/ecdsa-0.10.tar.gz ecdsa-0.10.tar.gz 100% 44KB 303.8KB/s 00:00 Uploading generate_bitcoin_address_3.py to /home/work/generate_address/generate_bitcoin_address_3.py generate_bitcoin_address_3.py 100% 4270 96.7KB/s 00:00 Uploading pypy_sha256.py to /home/work/generate_address/pypy_sha256.py pypy_sha256.py 100% 11KB 308.8KB/s 00:00


sftp> ls -1
bitcoin_functions.py
bjorn_edstrom_ripemd160.py
ecdsa-0.10.tar.gz
generate_bitcoin_address_3.py
pypy_sha256.py

sftp> pwd
Remote working directory: /home/work/generate_address

sftp> exit

Admin@Admin-PC /cygdrive/c/Documents and Settings/Admin/Desktop/work/PROJECTS_CURRENT/verifying_a_checkpoint_article/work

$ ssh root@edgecase-test.net
Last login: Wed Jan 30 14:58:59 2019 from [IP address string]

[root@spt1 ~]# cd /home/work/generate_address


[root@spt1 generate_address]# tar -zxvf ecdsa-0.10.tar.gz

ecdsa-0.10/
ecdsa-0.10/ecdsa/
ecdsa-0.10/ecdsa/__init__.py
ecdsa-0.10/ecdsa/_version.py
ecdsa-0.10/ecdsa/curves.py
ecdsa-0.10/ecdsa/der.py
ecdsa-0.10/ecdsa/ecdsa.py
ecdsa-0.10/ecdsa/ellipticcurve.py
ecdsa-0.10/ecdsa/keys.py
ecdsa-0.10/ecdsa/numbertheory.py
ecdsa-0.10/ecdsa/rfc6979.py
ecdsa-0.10/ecdsa/six.py
ecdsa-0.10/ecdsa/test_pyecdsa.py
ecdsa-0.10/ecdsa/util.py
ecdsa-0.10/LICENSE
ecdsa-0.10/MANIFEST.in
ecdsa-0.10/NEWS
ecdsa-0.10/PKG-INFO
ecdsa-0.10/README.md
ecdsa-0.10/setup.py

[root@spt1 generate_address]# cp -r ecdsa-0.10/ecdsa ecdsa


[Perform steps 5-7 of the recipe in the Vim editor. Note: With Vim in insert mode, paste the SHA256 hash with Cygwin paste (Shift key + Insert key) into the Cygwin terminal.]
[root@spt1 generate_address]# vim generate_bitcoin_address_3.py


[root@spt1 generate_address]# python --version

Python 2.6.6

[root@spt1 generate_address]# python generate_bitcoin_address_3.py


### START GENERATION OF BITCOIN ADDRESS

Private key (hex bytes): 1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa
Private key (32 hex bytes): 1fbc45dc460d14c07bcac41b8e17649455e92d9bfda29a89ba3addeee0eccaaa
Private key (WIF): 5J4GDkski1PPpK3G8bqqcoDoF8JeojqxHpDsjKNPNU3FC1Nor3U
Bitcoin address: 17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae

### END GENERATION OF BITCOIN ADDRESS





Bitcoin address:
17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae




Now, I need to look up this address in a blockchain information service, and find out if and when some bitcoin was transferred to it.


Browse to:
live.blockcypher.com

Search for this address.

2 transactions returned.

The first transaction's id (txid) is:
b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670

It's a hyperlink. Click it. This leads to:
live.blockcypher.com/btc/tx/b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670

Click Advanced Details. Click API Call. This leads to:
api.blockcypher.com/v1/btc/main/txs/b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670?limit=50&includeHex=true

Excerpts from the raw data returned by the API call:
{ "block_hash": "0000000000000000013bd1a5f07afc8791542f0e24044e218b606f71804eca33", "block_height": 473266, "block_index": 874, "hash": "b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670", [...] "addresses": [ [...] "17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae", [...] ], "total": 118138015, "fees": 296851, "size": 835, "preference": "high", "relayed_by": "91.121.75.30:8333", "confirmed": "2017-06-28T17:28:22Z", "received": "2017-06-28T17:21:22.204Z", "ver": 1, "lock_time": 473265, "double_spend": false, "vin_sz": 1, "vout_sz": 20, "confirmations": 87517, "confidence": 1,



So:
- block height: 473266
- confirmed: 2017-06-28 17:28:22 UTC



Let's look again at the file checkpoint_0.txt:


checkpoint_0.txt
<signed_datafeed_article> <datafeed_article> <datafeed_name>edgecase_datafeed</datafeed_name> <datafeed_article_id>0</datafeed_article_id> <date>2017-06-28 <note>This is the date at the time of creation of this datafeed article. A block containing a transaction confirming this datafeed article may appear on this date or at a later date.</note> </date> <previous_checkpoint>None</previous_checkpoint> <checkpoint_article> <checkpoint_id>0</checkpoint_id> <title>checkpoint_0</title> <date>2017-06-28 <note>This is the date at the time of creation of this checkpoint article. A block containing a transaction confirming this checkpoint may appear on this date or at a later date.</note> </date> <block> <blockchain_name>bitcoin</blockchain_name> <block_height>473264 <note>This is the approximate block height at the time of creation of this checkpoint article. A transaction confirming this checkpoint will appear in a later block.</note> </block_height> </block> <content> This is the first checkpoint in the edgecase datafeed. </content> </checkpoint_article> </datafeed_article> <datafeed_signature> iQIcBAABCgAGBQJZU/TvAAoJECL1OzZgiBhwL8YP/iKeSW4pdfD65am4Vnm26KjX sEdogn6LsqTl06IANIFspuQFA26yUb1RoRB0wKpGLCVrz1K2cOrLCQ/PQNVzOje0 dZtkAosg/kNUnkBNTjdlQKIu8zFwn2iQk6oUJacdrxpMjNHOLYPrLmDpOYm3NSfJ erfwOlVPmc8zKtImnYQ9T0LLX/Y2q/YDalj4NQEInvI1Aw+O/Mr9l0+cbyKAxpTq mAwllQgtswuYtyGX7M5cpfG2MyfUYhny0P9+dYGkdlR8eecjqtNDMyTbMZ0iSQfw DEUH6uPSvny8nluilMX0TKoXELHZw1gp7UjZV9AP1rq7b9R6E61B1i2xt9iD84c/ 4Vr+gbzwUn0DFIFxo09rTI7+3SUCJSWWswy6+BAx2P5Ga8qqYAkky+j7qO6eDu4W KfpNmjNR8S6T+duRB8rBcZIWYZnPpiiyh+DJlczRARUK0iT2wOIoUp81OLn9yiC0 adVC2v27zEwQMI7YJh6RSi7t2mEHz5ZpK3gAkRhlquHX+4ESI3rM/PlusKUquP71 DYPc1GWku/i80veu7t+577vlihFvoh02gTFLVsIGOOjxXn7KLZLanhjCxeqf0HXK AOC9lGAcAS/e0GztecXlwg0WnXhweyrk4Bx+8q+KO7QucHwYzBPt7GfY16gf0kzw nvKkCYvCLNolb4hCQkY2 =xbHy </datafeed_signature> </signed_datafeed_article>





The date in the file is:
2017-06-28
The approximate block height in the file is:
473264

Compare with the actual blockchain data:
- block height: 473266
- confirmed: 2017-06-28


The dates are the same. The address is timestamped 2 blocks later than the approximate block height.


This confirms the timestamp of the checkpoint article, checkpoint_0.txt, the first checkpoint in Edgecase Datafeed.


So:
Edgecase Datafeed began on 2017-06-28 (block height 473266).



Earlier, I found that the checkpoint article signature was a valid signature made by the Edgecase Datafeed public key. Therefore the checkpoint timestamp also shows that the Edgecase Datafeed public key has existed since at least 2017-06-28.



Excellent.




Let's clean up.



On my local machine, delete the work directory.


Open a Cygwin64 Terminal and use
ssh
to log into the CentOS VPS.

Admin@Admin-PC ~

$ ssh root@edgecase-test.net
Last login: Thu Jan 31 16:27:52 2019 from [IP address string]

[root@spt1 ~]# cd /home/work


[root@spt1 work]# ls -1

checkpoint_0.txt
datafeed_article.sig
datafeed_article.txt
edgecase_datafeed_public_key.txt
generate_address
keyring_tmp

[root@spt1 work]# cd ..


[root@spt1 home]# pwd

/home

[root@spt1 home]# ls -1

work

[root@spt1 home]# rm -rf work


[root@spt1 home]# ls -1


[root@spt1 home]# exit

logout
Connection to edgecase-test.net closed.

Admin@Admin-PC ~

$








Good. That's the end of this project.















[start of notes]




When I use the command
ssh root@edgecase-test.net
,
the output includes a line describing the previous login. Example:
Last login: Tue Aug 21 12:28:53 2018 from [IP address string]

I think it's an IP address string. It usually contains digits but also sometimes (what appear to be) network hostnames.

I prefer not to publish my local router address(es). During the project, I replaced all IP address strings in
ssh
login output with the string "[IP address string]".



Changes from the original text:
- I have not always preserved the format of any excerpts from text files or man pages (e.g. removing extra spaces, line-breaking newlines, word-breaking hyphens).
- I have not always preserved the format of any excerpts from webpages on other sites (e.g. not preserving the original bold/italic styles, changing the list structures, not preserving hyperlinks).
- I have not always preserved the format of any computer output (e.g. from running bash commands). Examples: Setting input lines in bold text, adding/removing newlines in order to make a sequence of commands easier to read, using hyphens for lists and sublists instead of indentation, breaking wide tables into consecutive sections.
- I have not always recorded every instance of logging in to or exiting from a remote computer.



[end of notes]











[start of footnotes]


[0]
With a high degree of certainty. Not perfect proof, but excellent evidence.

[return to main text]

[end of footnotes]