Goal
Verify the first signed article published on Edgecase Datafeed.
Contents
- Goal
- Contents
- Summary
- Project Log
Summary
I verified the first signed article published on Edgecase Datafeed.
This was datafeed article 1: "Viewpoint", by StJohn Piano.
"Signed" refers to the fact that it was signed by its author. Every datafeed article is signed by Edgecase Datafeed, but not every article is signed by its author.
Sequence:
- I verified the datafeed signature of the datafeed article, made by Edgecase Datafeed's public key.
- I verified the author signature of the signed article, made by StJohn Piano's public key.
- In a previous project, I verified the datafeed signature and timestamp of the previous checkpoint, checkpoint 0. Checkpoint 0 was signed by Edgecase Datafeed's public key and timestamped in the Bitcoin blockchain on 2017-06-28 at blockheight 473266. I did not repeat this verification in this project.
- I checked that the datafeed article "Viewpoint" includes the checkpoint id ("0") of checkpoint 0 and the transaction ID of the timestamp transaction for checkpoint 0.
- I confirmed that the SHA256 hash of the datafeed article "Viewpoint" was included in the next checkpoint, checkpoint 1.
- I verified the datafeed signature of checkpoint 1, made by Edgecase Datafeed's public key.
- I calculated the SHA256 hash of checkpoint 1 and generated the corresponding Bitcoin address. I verified that this address first appeared on the Bitcoin blockchain on 2017-06-28 at blockheight 473276.
- So: Checkpoint 1 was signed by Edgecase Datafeed's public key and timestamped in the Bitcoin blockchain on 2017-06-28 at blockheight 473276.
- Conclusion: The datafeed article "Viewpoint" was signed by StJohn Piano, then by Edgecase Datafeed, and published on Edgecase Datafeed on 2017-06-28 between the Bitcoin blockheights 473276 and 473276.
This also confirms the first timestamped digital signature on Edgecase Datafeed made by the public key of StJohn Piano. This means that StJohn Piano's public key has existed since at least 2017-06-28 between the Bitcoin blockheights 473276 and 473276.
The current date is 2019-04-24, so StJohn Piano's public key is nearly 1 year and 10 months old.
Project Log
System details:
- Name: Shovel
- Specifications: HP 6005 Pro SFF. 3 GHz x86_64 processor (AMD II x4 B95 Quad Core), 4 GB RAM, 1 TB hard drive. Running CentOS 7.6.1810 (Core).
- More information: New computer: Shovel
- Installed items: GCC 4.8.5, Make 3.82, Vim 7.4, Python 2.7.5, Python 3.3.2, Gnome 3.28.2, gedit 3.28.1, GPG 1.4.10.
Reference article:
GPG 1.4.10 Stateless Operations
Create new project directory:
verifying_the_first_signed_article_in_edgecase_datafeed
Create new work directory named "work" in the project directory.
Browse to datafeed article:
Viewpoint
In the Navigation Menu, click "Download this article".
Move the downloaded article file into the work directory.
Open a terminal. Change directory to the work directory.
[spiano@localhost work]$ ls -1
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
Here is the content of the datafeed article file:
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
<signed_datafeed_article>
<datafeed_article>
<datafeed_name>edgecase_datafeed</datafeed_name>
<datafeed_article_id>1</datafeed_article_id>
<date>2017-06-28
<note>This is the date at the time of creation of this datafeed article. A checkpoint article containing a hash of this datafeed article may be created on this date or at a later date.</note>
</date>
<previous_checkpoint>
<datafeed_article_id>0</datafeed_article_id>
<checkpoint_id>0</checkpoint_id>
<date>2017-06-28</date>
<transaction>
<blockchain_name>bitcoin</blockchain_name>
<transaction_id>b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670</transaction_id>
<block_height>473266</block_height>
<source_address>13a43uE6YPeF36Uf8pzy6x4zvZnerPtwqv</source_address>
<destination_address>17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae</destination_address>
</transaction>
</previous_checkpoint>
<signed_article>
<article>
<title>Viewpoint</title>
<author_name>stjohn_piano</author_name>
<date>2017-06-28</date>
<signed_by_author>yes</signed_by_author>
<content>
"Human behavior is economic behavior. The particulars may vary, but competition for limited resources remains a constant."
~ Nwabudike Morgan
"In an information-rich world, the wealth of information means a dearth of something else: a scarcity of whatever it is that information consumes. What information consumes is rather obvious: it consumes the attention of its recipients. Hence a wealth of information creates a poverty of attention and a need to allocate that attention efficiently among the overabundance of information sources that might consume it."
~ Herbert A. Simon
"Nature is disordered, powerful and chaotic, and through fear of the chaos we impose system on it. We abhor complexity, and seek to simplify things whenever we can by whatever means we have at hand. We need to have an overall explanation of what the universe is and how it functions. In order to achieve this overall view we develop explanatory theories which will give structure to natural phenomena: we classify nature into a coherent system which appears to do what we say it does."
~ James Burke
"Essentially, all models are wrong, but some are useful."
~ George E. P. Box
"Even a single taboo can have an all-round crippling effect upon the mind, because there is always the danger that any thought which is freely followed up may lead to the forbidden thought."
~ George Orwell
"It occurs to me that the man and his religion are one and the same thing. The unknown exists. Each man projects on the blankness the shape of his own particular world-view. He endows his creation with his personal volitions and attitudes. The religious man stating his case is in essence explaining himself. When a fanatic is contradicted he feels a threat to his own existence; he reacts violently."
~ Adam Reith, in The Wannek, by Jack Vance
"People want to feel different and special, but they also want to feel embattled. They want a compelling conflict narrative that gives their lives meaning, whether they are standing up for the 'oppressed' or standing against the tide of unwanted change. Few want what Pariser called a 'balanced diet' of information."
~ Jack Donovan
"Kergan Banbeck threw up his hands, turned once more to the sacerdote. 'How can I halt his nonsense? How can I make him see reason?'
The sacerdote reflected. 'He speaks not nonsense, but rather a language you fail to understand. You can make him understand your language by erasing all knowledge and training from his mind, and replacing it with patterns of your own.'"
~ from The Dragon Masters, by Jack Vance
"Freedom, when done properly, is not necessarily easy, or nice, or expedient, it's just freedom; and the interesting thing about it is that every other citizen has it as well, which is where, of course, the fun starts."
~ Lord Vetinari, in The Compleat Ankh-Morpork, by Terry Pratchett
Lu Tze: "Someone in Uberwald built this clock out of glass. Powered by lightning, as I recall. It somehow got down to a level where it could tick with the universe."
Lobsang Ludd: "Why did he want to do that?"
Lu Tze: "Listen, he lived in a big old castle on a crag in Uberwald. People like that don't need a reason apart from 'because I can'."
~ from Thief of Time, by Terry Pratchett
"And always, he fought the temptation to choose a clear, safe course, warning 'That path leads ever down into stagnation.'"
~ from Dune, by Frank Herbert
"Caminante, no hay camino, se hace camino al andar."
~ Antonio Machado
"It is not for me to tell you what you should have done or not done. The world in which you seek to undo the mistakes that you made is different from the world where the mistakes were made. You are now at the crossing. And you want to choose, but there is no choosing there. There's only accepting. The choosing was done a long time ago."
~ Jefe, from The Counselor, screenplay by Cormac McCarthy
King Henry VIII: "In these last days I have been thinking a great deal about loss. What loss, Your Grace, is to man most irrecoverable?"
Duke of Suffolk: "His virtue."
King Henry VIII: "No. For by his actions, he may redeem his virtue."
Duke of Suffolk: "Then his honour."
King Henry VIII: "No. For again he may find the means to recover it, even as a man recovers some fortune he has lost."
Duke of Suffolk: "Then I cannot say, Your Majesty."
King Henry VIII: "Time, Your Grace. Of all losses, time is the most irrecuperable, for it can never be redeemed."
~ from Death of a Monarchy, season 4 episode 10, The Tudors, screenplay by Michael Hirst
"'Tis all a Chequer-board of Nights and Days
Where Destiny with Men for Pieces plays:
Hither and thither moves, and mates, and slays,
And one by one back in the Closet lays."
~ from Rubaiyat of Omar Khayyam, by Edward FitzGerald
</content>
</article>
<author_signature>
iQIcBAABCgAGBQJZVAS5AAoJEC8RP+HmG9MXdTwQALi2J8aHCiajjV+dTTtVws6J
GECE4tSWdB7rreyOCvvxDULRtXiLY+vCtRoLI5yNk1lHRxjnCGpMYt90N7AZcQII
08IF8ixgHyibr3+CCTxzgfsqeacWdpL/VS5MyKQwj/vEDNWW/gnv+tfvTAPW00DR
rOv6rJHAsJxWOewfF4YgjqLyMPYIdFlCddC4sek6F4c12zC3c8ANSza1r2tX9U9/
f32DqsyqAayOxPr7HdX90FM6c0bPxSjZ6SPNGYSt+9N0oqafh9LIGfQ3fzfMv0RE
6PhdGAXnUmTHYHhQ9A93D1tJvscxX5qPASTYSlYcwjyp/yPYED5S6knhe+No0eRo
9WJCaRPYfSrohEyCgCa837HiDI49LzDf8cvQRqDGaOAW8FMbFt3TSae0XxV8/CC5
0kaW02sHcPCfNbaeqYnRQK+3KWjjgaJZcUItWq9NKX7f4VPGtO6JjoilAtiufctg
G5C/7vbmaQoPcQ3Lnu+FY3SCavSz66iX5dNx471McLfQPvntMLvjk7XNvYzZIm1o
2gTU20T7aN1/Kxg9rpjeazxJbjVk4FL/YZScveqLidzWS/vNFkZhdDWvOovvEbSc
A70VAelCAMtRLPs8o9Z1fBw6aEKSFWeaL44s1/S6ApA4m+lLrdvuCO6f3w/wJvqj
1T2KMnHmqQ36jVVsWgbA
=/JBI
</author_signature>
</signed_article>
</datafeed_article>
<datafeed_signature>
iQIcBAABCgAGBQJZVAWEAAoJECL1OzZgiBhwOoQP/AlgBl8VM3JkFsWSL+UCpNnW
P7HJhFFcFbmN5r3/XGqD0xffEXyzOLqo4RPu4FOzzua8A3S1hP3rkmvvhsedJe9E
egQaacFyg7dSJd+n/RPNn/s5HtdvnKmYz4jglIBix2gJof/5VjyIwYkdn9Vj+4ZG
7n40XoLQVf8c499mX4YvgBByltGTDFeP6eTFlcLa3kJ7ydsfVbCzcuy6vqWa33eg
kZkIfbDLJIgQCp3L5DTrvbKMWhUSvbKZGwsS67Gw02sz8KrBnaMkvIba+Xe6555a
v7w//81ZKWzIYdhnQAZ4A1bh9psCIWEb6e0kleY6qNuE15gHyHUWn2NibAmNf10Z
bcXfHgOf73zfrQOIczAHKzIBKDinSeI7nFbmRQE9ynAvlG3dZDu/deoG32/P/ADK
J5+QCRGDZoDs0t443RkW2d7Y97OtI552FDQK5wVsZknl3QKaIIbQGNfSJ6izPEB4
qtQzpnXXjrb0nJFUPC4RkiSuw0aq3mToQCMOYhkwEee71C26SqSmCuVHmeNxXksw
/1wbwxDdw9u1DwxCHLizHfpz04GsRhuxndMWT005KQo3UagfsUjlWCmQZQ/+xrI5
+vVzNlT3msPCZD8eGkYOdDoQ3/8Lm94u5Fg/+OcIlti5CPySsLMXhOmMmwxW3uDU
8r9dSmmtfx6NgTHCvodV
=FpZQ
</datafeed_signature>
</signed_datafeed_article>
I'm going to copy sections of the datafeed article file in order to produce two new files:
- a file containing the datafeed signature:
viewpoint_datafeed_article_signature.asc
- a file containing the unsigned datafeed article:
viewpoint_datafeed_article.txt
Then I will check the validity of the datafeed signature using GPG.
Copy everything between and including the first character of <datafeed_article> ("<") and the last character of </datafeed_article> (">"). Open a new text file, paste this text into it, and save it as:
- viewpoint_datafeed_article.txt
Copy everything between and including the first character of <datafeed_signature> ("<") and the last character of </datafeed_signature> (">"). Open a new text file, paste this text into it, and save it as:
- viewpoint_datafeed_article_signature.asc
In viewpoint_datafeed_article_signature.asc:
- Replace "<datafeed_signature>" with "-----BEGIN PGP SIGNATURE-----" and press enter to add a new line immediately after this replacement text. Replace "</datafeed_signature>" with "-----END PGP SIGNATURE-----".
[spiano@localhost work]$ cat viewpoint_datafeed_article_signature.asc
-----BEGIN PGP SIGNATURE-----
iQIcBAABCgAGBQJZVAWEAAoJECL1OzZgiBhwOoQP/AlgBl8VM3JkFsWSL+UCpNnW
P7HJhFFcFbmN5r3/XGqD0xffEXyzOLqo4RPu4FOzzua8A3S1hP3rkmvvhsedJe9E
egQaacFyg7dSJd+n/RPNn/s5HtdvnKmYz4jglIBix2gJof/5VjyIwYkdn9Vj+4ZG
7n40XoLQVf8c499mX4YvgBByltGTDFeP6eTFlcLa3kJ7ydsfVbCzcuy6vqWa33eg
kZkIfbDLJIgQCp3L5DTrvbKMWhUSvbKZGwsS67Gw02sz8KrBnaMkvIba+Xe6555a
v7w//81ZKWzIYdhnQAZ4A1bh9psCIWEb6e0kleY6qNuE15gHyHUWn2NibAmNf10Z
bcXfHgOf73zfrQOIczAHKzIBKDinSeI7nFbmRQE9ynAvlG3dZDu/deoG32/P/ADK
J5+QCRGDZoDs0t443RkW2d7Y97OtI552FDQK5wVsZknl3QKaIIbQGNfSJ6izPEB4
qtQzpnXXjrb0nJFUPC4RkiSuw0aq3mToQCMOYhkwEee71C26SqSmCuVHmeNxXksw
/1wbwxDdw9u1DwxCHLizHfpz04GsRhuxndMWT005KQo3UagfsUjlWCmQZQ/+xrI5
+vVzNlT3msPCZD8eGkYOdDoQ3/8Lm94u5Fg/+OcIlti5CPySsLMXhOmMmwxW3uDU
8r9dSmmtfx6NgTHCvodV
=FpZQ
-----END PGP SIGNATURE-----
Browse to:
edgecase.net/pages/edgecase_datafeed
Click "[Download public key]".
Move the downloaded file edgecase_datafeed_public_key.txt to the work directory.
I'll use operation 8 from
GPG 1.4.10 Stateless Operations
Operation name: "Verify the detached signature of a file, checking that the signature was made by a specific public key".
[spiano@localhost work]$ mkdir tmp_home && chmod 700 tmp_home
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --import edgecase_datafeed_public_key.txt
gpg: keyring `tmp_home/secring.gpg' created
gpg: keyring `tmp_home/pubring.gpg' created
gpg: tmp_home/trustdb.gpg: trustdb created
gpg: key 60881870: public key "edgecase_datafeed" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --status-fd 1 --verify viewpoint_datafeed_article_signature.asc viewpoint_datafeed_article.txt
gpg: Signature made Wed 28 Jun 2017 08:37:40 PM BST using RSA key ID 60881870
[GNUPG:] SIG_ID EarC/Qy4PKU+l3wxyKTetoepahM 2017-06-28 1498678660
[GNUPG:] GOODSIG 22F53B3660881870 edgecase_datafeed
gpg: Good signature from "edgecase_datafeed"
[GNUPG:] VALIDSIG 112D22BA9DE160ED6A20E07D22F53B3660881870 2017-06-28 1498678660 0 4 0 1 10 00 112D22BA9DE160ED6A20E07D22F53B3660881870
[GNUPG:] TRUST_UNDEFINED
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
[spiano@localhost work]$ rm -r tmp_home/
The important line is:
gpg: Good signature from "edgecase_datafeed"
This means that GPG has concluded that the digital signature from Edgecase Datafeed's public key is mathematically valid.
Next: I'll check the validity of the author's signature.
[spiano@localhost work]$ ls -1
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
edgecase_datafeed_public_key.txt
viewpoint_datafeed_article_signature.asc
viewpoint_datafeed_article.txt
Here is the content of the unsigned datafeed article file:
viewpoint_datafeed_article.txt
<datafeed_article>
<datafeed_name>edgecase_datafeed</datafeed_name>
<datafeed_article_id>1</datafeed_article_id>
<date>2017-06-28
<note>This is the date at the time of creation of this datafeed article. A checkpoint article containing a hash of this datafeed article may be created on this date or at a later date.</note>
</date>
<previous_checkpoint>
<datafeed_article_id>0</datafeed_article_id>
<checkpoint_id>0</checkpoint_id>
<date>2017-06-28</date>
<transaction>
<blockchain_name>bitcoin</blockchain_name>
<transaction_id>b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670</transaction_id>
<block_height>473266</block_height>
<source_address>13a43uE6YPeF36Uf8pzy6x4zvZnerPtwqv</source_address>
<destination_address>17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae</destination_address>
</transaction>
</previous_checkpoint>
<signed_article>
<article>
<title>Viewpoint</title>
<author_name>stjohn_piano</author_name>
<date>2017-06-28</date>
<signed_by_author>yes</signed_by_author>
<content>
"Human behavior is economic behavior. The particulars may vary, but competition for limited resources remains a constant."
~ Nwabudike Morgan
"In an information-rich world, the wealth of information means a dearth of something else: a scarcity of whatever it is that information consumes. What information consumes is rather obvious: it consumes the attention of its recipients. Hence a wealth of information creates a poverty of attention and a need to allocate that attention efficiently among the overabundance of information sources that might consume it."
~ Herbert A. Simon
"Nature is disordered, powerful and chaotic, and through fear of the chaos we impose system on it. We abhor complexity, and seek to simplify things whenever we can by whatever means we have at hand. We need to have an overall explanation of what the universe is and how it functions. In order to achieve this overall view we develop explanatory theories which will give structure to natural phenomena: we classify nature into a coherent system which appears to do what we say it does."
~ James Burke
"Essentially, all models are wrong, but some are useful."
~ George E. P. Box
"Even a single taboo can have an all-round crippling effect upon the mind, because there is always the danger that any thought which is freely followed up may lead to the forbidden thought."
~ George Orwell
"It occurs to me that the man and his religion are one and the same thing. The unknown exists. Each man projects on the blankness the shape of his own particular world-view. He endows his creation with his personal volitions and attitudes. The religious man stating his case is in essence explaining himself. When a fanatic is contradicted he feels a threat to his own existence; he reacts violently."
~ Adam Reith, in The Wannek, by Jack Vance
"People want to feel different and special, but they also want to feel embattled. They want a compelling conflict narrative that gives their lives meaning, whether they are standing up for the 'oppressed' or standing against the tide of unwanted change. Few want what Pariser called a 'balanced diet' of information."
~ Jack Donovan
"Kergan Banbeck threw up his hands, turned once more to the sacerdote. 'How can I halt his nonsense? How can I make him see reason?'
The sacerdote reflected. 'He speaks not nonsense, but rather a language you fail to understand. You can make him understand your language by erasing all knowledge and training from his mind, and replacing it with patterns of your own.'"
~ from The Dragon Masters, by Jack Vance
"Freedom, when done properly, is not necessarily easy, or nice, or expedient, it's just freedom; and the interesting thing about it is that every other citizen has it as well, which is where, of course, the fun starts."
~ Lord Vetinari, in The Compleat Ankh-Morpork, by Terry Pratchett
Lu Tze: "Someone in Uberwald built this clock out of glass. Powered by lightning, as I recall. It somehow got down to a level where it could tick with the universe."
Lobsang Ludd: "Why did he want to do that?"
Lu Tze: "Listen, he lived in a big old castle on a crag in Uberwald. People like that don't need a reason apart from 'because I can'."
~ from Thief of Time, by Terry Pratchett
"And always, he fought the temptation to choose a clear, safe course, warning 'That path leads ever down into stagnation.'"
~ from Dune, by Frank Herbert
"Caminante, no hay camino, se hace camino al andar."
~ Antonio Machado
"It is not for me to tell you what you should have done or not done. The world in which you seek to undo the mistakes that you made is different from the world where the mistakes were made. You are now at the crossing. And you want to choose, but there is no choosing there. There's only accepting. The choosing was done a long time ago."
~ Jefe, from The Counselor, screenplay by Cormac McCarthy
King Henry VIII: "In these last days I have been thinking a great deal about loss. What loss, Your Grace, is to man most irrecoverable?"
Duke of Suffolk: "His virtue."
King Henry VIII: "No. For by his actions, he may redeem his virtue."
Duke of Suffolk: "Then his honour."
King Henry VIII: "No. For again he may find the means to recover it, even as a man recovers some fortune he has lost."
Duke of Suffolk: "Then I cannot say, Your Majesty."
King Henry VIII: "Time, Your Grace. Of all losses, time is the most irrecuperable, for it can never be redeemed."
~ from Death of a Monarchy, season 4 episode 10, The Tudors, screenplay by Michael Hirst
"'Tis all a Chequer-board of Nights and Days
Where Destiny with Men for Pieces plays:
Hither and thither moves, and mates, and slays,
And one by one back in the Closet lays."
~ from Rubaiyat of Omar Khayyam, by Edward FitzGerald
</content>
</article>
<author_signature>
iQIcBAABCgAGBQJZVAS5AAoJEC8RP+HmG9MXdTwQALi2J8aHCiajjV+dTTtVws6J
GECE4tSWdB7rreyOCvvxDULRtXiLY+vCtRoLI5yNk1lHRxjnCGpMYt90N7AZcQII
08IF8ixgHyibr3+CCTxzgfsqeacWdpL/VS5MyKQwj/vEDNWW/gnv+tfvTAPW00DR
rOv6rJHAsJxWOewfF4YgjqLyMPYIdFlCddC4sek6F4c12zC3c8ANSza1r2tX9U9/
f32DqsyqAayOxPr7HdX90FM6c0bPxSjZ6SPNGYSt+9N0oqafh9LIGfQ3fzfMv0RE
6PhdGAXnUmTHYHhQ9A93D1tJvscxX5qPASTYSlYcwjyp/yPYED5S6knhe+No0eRo
9WJCaRPYfSrohEyCgCa837HiDI49LzDf8cvQRqDGaOAW8FMbFt3TSae0XxV8/CC5
0kaW02sHcPCfNbaeqYnRQK+3KWjjgaJZcUItWq9NKX7f4VPGtO6JjoilAtiufctg
G5C/7vbmaQoPcQ3Lnu+FY3SCavSz66iX5dNx471McLfQPvntMLvjk7XNvYzZIm1o
2gTU20T7aN1/Kxg9rpjeazxJbjVk4FL/YZScveqLidzWS/vNFkZhdDWvOovvEbSc
A70VAelCAMtRLPs8o9Z1fBw6aEKSFWeaL44s1/S6ApA4m+lLrdvuCO6f3w/wJvqj
1T2KMnHmqQ36jVVsWgbA
=/JBI
</author_signature>
</signed_article>
</datafeed_article>
I'm going to copy sections of the unsigned datafeed article file in order to produce two new files:
- a file containing the author signature:
viewpoint_article_signature.asc
- a file containing the unsigned article:
viewpoint_article.txt
Then I will check the validity of the author signature using GPG.
Copy everything between and including the first character of <article> ("<") and the last character of </article> (">"). Open a new text file, paste this text into it, and save it as:
- viewpoint_article.txt
Copy everything between and including the first character of <author_signature> ("<") and the last character of </author_signature> (">"). Open a new text file, paste this text into it, and save it as:
- viewpoint_article_signature.asc
In viewpoint_article_signature.asc:
- Replace "<author_signature>" with "-----BEGIN PGP SIGNATURE-----" and press enter to add a new line immediately after this replacement text. Replace "</author_signature>" with "-----END PGP SIGNATURE-----".
[spiano@localhost work]$ cat viewpoint_article_signature.asc
-----BEGIN PGP SIGNATURE-----
iQIcBAABCgAGBQJZVAS5AAoJEC8RP+HmG9MXdTwQALi2J8aHCiajjV+dTTtVws6J
GECE4tSWdB7rreyOCvvxDULRtXiLY+vCtRoLI5yNk1lHRxjnCGpMYt90N7AZcQII
08IF8ixgHyibr3+CCTxzgfsqeacWdpL/VS5MyKQwj/vEDNWW/gnv+tfvTAPW00DR
rOv6rJHAsJxWOewfF4YgjqLyMPYIdFlCddC4sek6F4c12zC3c8ANSza1r2tX9U9/
f32DqsyqAayOxPr7HdX90FM6c0bPxSjZ6SPNGYSt+9N0oqafh9LIGfQ3fzfMv0RE
6PhdGAXnUmTHYHhQ9A93D1tJvscxX5qPASTYSlYcwjyp/yPYED5S6knhe+No0eRo
9WJCaRPYfSrohEyCgCa837HiDI49LzDf8cvQRqDGaOAW8FMbFt3TSae0XxV8/CC5
0kaW02sHcPCfNbaeqYnRQK+3KWjjgaJZcUItWq9NKX7f4VPGtO6JjoilAtiufctg
G5C/7vbmaQoPcQ3Lnu+FY3SCavSz66iX5dNx471McLfQPvntMLvjk7XNvYzZIm1o
2gTU20T7aN1/Kxg9rpjeazxJbjVk4FL/YZScveqLidzWS/vNFkZhdDWvOovvEbSc
A70VAelCAMtRLPs8o9Z1fBw6aEKSFWeaL44s1/S6ApA4m+lLrdvuCO6f3w/wJvqj
1T2KMnHmqQ36jVVsWgbA
=/JBI
-----END PGP SIGNATURE-----
Browse to:
edgecase.net/pages/authors
Click "StJohn Piano", which leads to:
edgecase.net/pages/stjohn_piano
Click "[Download public key]".
Move the downloaded file stjohn_piano_public_key.txt to the work directory.
I'll use operation 8 from
GPG 1.4.10 Stateless Operations
Operation name: "Verify the detached signature of a file, checking that the signature was made by a specific public key".
[spiano@localhost work]$ mkdir tmp_home && chmod 700 tmp_home
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --import stjohn_piano_public_key.txt
gpg: keyring `tmp_home/secring.gpg' created
gpg: keyring `tmp_home/pubring.gpg' created
gpg: tmp_home/trustdb.gpg: trustdb created
gpg: key E61BD317: public key "stjohn_piano" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --status-fd 1 --verify viewpoint_article_signature.asc viewpoint_article.txt
gpg: Signature made Wed 28 Jun 2017 08:34:17 PM BST using RSA key ID E61BD317
[GNUPG:] SIG_ID OtVmbqsW3D7C/7JiFbzFbGY4UCE 2017-06-28 1498678457
[GNUPG:] GOODSIG 2F113FE1E61BD317 stjohn_piano
gpg: Good signature from "stjohn_piano"
[GNUPG:] VALIDSIG A69DD24EAB3310E2972E68462F113FE1E61BD317 2017-06-28 1498678457 0 4 0 1 10 00 A69DD24EAB3310E2972E68462F113FE1E61BD317
[GNUPG:] TRUST_UNDEFINED
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: A69D D24E AB33 10E2 972E 6846 2F11 3FE1 E61B D317
[spiano@localhost work]$ rm -r tmp_home
[spiano@localhost work]$ ls -1
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
edgecase_datafeed_public_key.txt
stjohn_piano_public_key.txt
viewpoint_article_signature.asc
viewpoint_article.txt
viewpoint_datafeed_article_signature.asc
viewpoint_datafeed_article.txt
The important line is:
gpg: Good signature from "stjohn_piano"
This means that GPG has concluded that the digital signature from StJohn Piano's public key is mathematically valid.
Next: Check timestamp of the datafeed article.
This can't be done directly. Only the timestamps of checkpoint articles are known. However, the datafeed article will be linked to the previous checkpoint and the next checkpoint.
When was the previous checkpoint created?
Here is an excerpt from the original signed datafeed article "Viewpoint":
<previous_checkpoint>
<datafeed_article_id>0</datafeed_article_id>
<checkpoint_id>0</checkpoint_id>
<date>2017-06-28</date>
<transaction>
<blockchain_name>bitcoin</blockchain_name>
<transaction_id>b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670</transaction_id>
<block_height>473266</block_height>
<source_address>13a43uE6YPeF36Uf8pzy6x4zvZnerPtwqv</source_address>
<destination_address>17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae</destination_address>
</transaction>
</previous_checkpoint>
<datafeed_article_id>0</datafeed_article_id>
<checkpoint_id>0</checkpoint_id>
<date>2017-06-28</date>
<transaction>
<blockchain_name>bitcoin</blockchain_name>
<transaction_id>b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670</transaction_id>
<block_height>473266</block_height>
<source_address>13a43uE6YPeF36Uf8pzy6x4zvZnerPtwqv</source_address>
<destination_address>17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae</destination_address>
</transaction>
</previous_checkpoint>
The previous checkpoint was checkpoint 0 in Edgecase Datafeed.
In a previous project, I verified this checkpoint.
Link: Verifying the first checkpoint article in Edgecase Datafeed
=== Results of previous project:
I confirmed that checkpoint 0 was timestamped by a Bitcoin transaction with block height 473266 and txid
b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670
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
===
This txid ("transaction_id") appears in the excerpt above, as does the blockheight 473266.
So:
- The datafeed article "Viewpoint" was published on Edgecase Datafeed after the date 2017-06-28 and the Bitcoin blockheight 473266.
Next: Verify the next checkpoint, and note its date and blockheight.
Browse to:
Viewpoint
Click "Next checkpoint", which leads to:
checkpoint 1
Click "Download this article".
The downloaded file is:
2017-06-28_edgecase_datafeed_article_2_checkpoint_1.txt
Rename it to:
datafeed_checkpoint_1.txt
Move it to the work directory.
Here is the content of checkpoint 1:
datafeed_checkpoint_1.txt
<signed_datafeed_article>
<datafeed_article>
<datafeed_name>edgecase_datafeed</datafeed_name>
<datafeed_article_id>2</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>
<datafeed_article_id>0</datafeed_article_id>
<checkpoint_id>0</checkpoint_id>
<date>2017-06-28</date>
<transaction>
<blockchain_name>bitcoin</blockchain_name>
<transaction_id>b2f093a08e80f281889bc19b1ae441d3ead93cd10e58c640202916beb25d1670</transaction_id>
<block_height>473266</block_height>
<source_address>13a43uE6YPeF36Uf8pzy6x4zvZnerPtwqv</source_address>
<destination_address>17rEGTR4ss7xhVVMwL969Y8xszS7FaFsae</destination_address>
</transaction>
</previous_checkpoint>
<checkpoint_article>
<checkpoint_id>1</checkpoint_id>
<title>checkpoint_1</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>473274
<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>
Articles included at this checkpoint: 1
<datafeed_article_description>
<datafeed_article_id>1</datafeed_article_id>
<datafeed_signing_date>2017-06-28</datafeed_signing_date>
<title>Viewpoint</title>
<author_name>stjohn_piano</author_name>
<date>2017-06-28</date>
<signed_by_author>yes</signed_by_author>
<hash>
<algorithm>SHA256</algorithm>
<hex_value>e7beffdee3ef01baedba6301a5c5b0fea010e99e2484884861e5ce9866d25c7f</hex_value>
</hash>
<number_of_characters>7411</number_of_characters>
</datafeed_article_description>
</content>
</checkpoint_article>
</datafeed_article>
<datafeed_signature>
iQIcBAABCgAGBQJZVAY9AAoJECL1OzZgiBhwam8P/j4O1sffeZgdpNb5mODyvIHt
kCnDL9VS5OTYZhAeJJzOGqLS/ks6nkChlYNMmHcYCgy6RNuDsL4QBZhYManiFumZ
8jSeGttOaQYQSg+CwO+q58iVVQp3W+cGBNe9kgAssHLasdhCKQDQKzx/nmW+W+KC
ZJyf0syGNWihgcwpIQaO2qZY5Np6uWG0pyAs1czV/q3ixhfydDTcAf9m2ZZ4OOHm
Cy4hymAu/3aDR4Kfq8iCnp/JL+bWMY3Snebw0sJ8l6EJ5LWG/zMZdAuowWpl+Jrb
OalClLTe4ailcB8Q1ro/8LVTwpy+cf2Stw01hgpc+zyNPNIdgJ/EOQyNcV60MddU
uuNt4tjf/chkbCmhvH+Zzd3JQWR87Pa0p2trEj/qgLiXY2jiU1CDBZfqBbR0+V5Z
awZDOwe7THWOafhMI8fSsWfQd16Zdm+rbue4m+N2rERcikKf1KQLPmCUNmFjQX9y
SfRgUu/gS60LkRsdp4bc3cXBQSFqEVSilX7aoqBml0TuSlb1aou+PB4kJ7knd+2/
BLbZ4CL6BRZay9ObEO+knnvpyyboNen7ObMmC0yRfXzyyVoce0Qf0r5C1VTgN33I
lqr2y8d/koHuYX5MMlQNuJUKxeOEYqlm44xI2oWiRHVca2r/dBWO1WjvNcSDko+Z
hNBrI4H9lndy/O1VxFZa
=gYRu
</datafeed_signature>
</signed_datafeed_article>
Details about the article Viewpoint are included in checkpoint 1's content.
Its SHA256 hash is:
e7beffdee3ef01baedba6301a5c5b0fea010e99e2484884861e5ce9866d25c7f
I'll confirm the hash.
[spiano@localhost work]$ ls -1
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
datafeed_checkpoint_1.txt
edgecase_datafeed_public_key.txt
stjohn_piano_public_key.txt
viewpoint_article_signature.asc
viewpoint_article.txt
viewpoint_datafeed_article_signature.asc
viewpoint_datafeed_article.txt
[spiano@localhost work]$ sha256sum 2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
e7beffdee3ef01baedba6301a5c5b0fea010e99e2484884861e5ce9866d25c7f 2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
[hash from the checkpoint article]
[spiano@localhost work]$ s1="e7beffdee3ef01baedba6301a5c5b0fea010e99e2484884861e5ce9866d25c7f"
[hash calculated just now]
[spiano@localhost work]$ s2="e7beffdee3ef01baedba6301a5c5b0fea010e99e2484884861e5ce9866d25c7f"
[check equality of hashes]
[spiano@localhost work]$ [[ "$s1" = "$s2" ]] && echo equal || echo not-equal
equal
Good. Checkpoint 1 contains the SHA256 hash of the article Viewpoint.
Calculate the SHA256 hash of checkpoint 1.
[spiano@localhost work]$ sha256sum datafeed_checkpoint_1.txt
62b0d5ec1efa901eca870b75f743b12061f85b9e687d2a8a2393712363268fd2 datafeed_checkpoint_1.txt
The SHA256 hash of checkpoint 1 is:
62b0d5ec1efa901eca870b75f743b12061f85b9e687d2a8a2393712363268fd2
Need to verify the signature of checkpoint 1, so that I know it's in Edgecase Datafeed.
I'm going to copy sections of the datafeed checkpoint file in order to produce two new files:
- a file containing the datafeed signature:
checkpoint_1_datafeed_article_signature.asc
- a file containing the unsigned datafeed article:
checkpoint_1_datafeed_article.txt
Then I will check the validity of the datafeed signature using GPG.
Copy everything between and including the first character of <datafeed_article> ("<") and the last character of </datafeed_article> (">"). Open a new text file, paste this text into it, and save it as:
- checkpoint_1_datafeed_article.txt
Copy everything between and including the first character of <datafeed_signature> ("<") and the last character of </datafeed_signature> (">"). Open a new text file, paste this text into it, and save it as:
- checkpoint_1_datafeed_article_signature.asc
In checkpoint_1_datafeed_article_signature.asc:
- Replace "<datafeed_signature>" with "-----BEGIN PGP SIGNATURE-----" and press enter to add a new line immediately after this replacement text. Replace "</datafeed_signature>" with "-----END PGP SIGNATURE-----".
[spiano@localhost work]$ cat checkpoint_1_datafeed_article_signature.asc
-----BEGIN PGP SIGNATURE-----
iQIcBAABCgAGBQJZVAY9AAoJECL1OzZgiBhwam8P/j4O1sffeZgdpNb5mODyvIHt
kCnDL9VS5OTYZhAeJJzOGqLS/ks6nkChlYNMmHcYCgy6RNuDsL4QBZhYManiFumZ
8jSeGttOaQYQSg+CwO+q58iVVQp3W+cGBNe9kgAssHLasdhCKQDQKzx/nmW+W+KC
ZJyf0syGNWihgcwpIQaO2qZY5Np6uWG0pyAs1czV/q3ixhfydDTcAf9m2ZZ4OOHm
Cy4hymAu/3aDR4Kfq8iCnp/JL+bWMY3Snebw0sJ8l6EJ5LWG/zMZdAuowWpl+Jrb
OalClLTe4ailcB8Q1ro/8LVTwpy+cf2Stw01hgpc+zyNPNIdgJ/EOQyNcV60MddU
uuNt4tjf/chkbCmhvH+Zzd3JQWR87Pa0p2trEj/qgLiXY2jiU1CDBZfqBbR0+V5Z
awZDOwe7THWOafhMI8fSsWfQd16Zdm+rbue4m+N2rERcikKf1KQLPmCUNmFjQX9y
SfRgUu/gS60LkRsdp4bc3cXBQSFqEVSilX7aoqBml0TuSlb1aou+PB4kJ7knd+2/
BLbZ4CL6BRZay9ObEO+knnvpyyboNen7ObMmC0yRfXzyyVoce0Qf0r5C1VTgN33I
lqr2y8d/koHuYX5MMlQNuJUKxeOEYqlm44xI2oWiRHVca2r/dBWO1WjvNcSDko+Z
hNBrI4H9lndy/O1VxFZa
=gYRu
-----END PGP SIGNATURE-----
I already have the public key of Edgecase Datafeed in the work directory.
- edgecase_datafeed_public_key.txt
I'll use operation 8 from
GPG 1.4.10 Stateless Operations
Operation name: "Verify the detached signature of a file, checking that the signature was made by a specific public key".
[spiano@localhost work]$ ls -1
2017-06-28_edgecase_datafeed_article_1_2017-06-28_stjohn_piano_viewpoint.txt
checkpoint_1_datafeed_article_signature.asc
checkpoint_1_datafeed_article.txt
datafeed_checkpoint_1.txt
edgecase_datafeed_public_key.txt
stjohn_piano_public_key.txt
viewpoint_article_signature.asc
viewpoint_article.txt
viewpoint_datafeed_article_signature.asc
viewpoint_datafeed_article.txt
[spiano@localhost work]$ mkdir tmp_home && chmod 700 tmp_home
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --import edgecase_datafeed_public_key.txt
gpg: keyring `tmp_home/secring.gpg' created
gpg: keyring `tmp_home/pubring.gpg' created
gpg: tmp_home/trustdb.gpg: trustdb created
gpg: key 60881870: public key "edgecase_datafeed" imported
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
[spiano@localhost work]$ gpg --no-default-keyring --homedir tmp_home --status-fd 1 --verify checkpoint_1_datafeed_article_signature.asc checkpoint_1_datafeed_article.txt
gpg: Signature made Wed 28 Jun 2017 08:40:45 PM BST using RSA key ID 60881870
[GNUPG:] SIG_ID YWGHWiO2yxIMnwBj28pfAbLyq+E 2017-06-28 1498678845
[GNUPG:] GOODSIG 22F53B3660881870 edgecase_datafeed
gpg: Good signature from "edgecase_datafeed"
[GNUPG:] VALIDSIG 112D22BA9DE160ED6A20E07D22F53B3660881870 2017-06-28 1498678845 0 4 0 1 10 00 112D22BA9DE160ED6A20E07D22F53B3660881870
[GNUPG:] TRUST_UNDEFINED
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
[spiano@localhost work]$ rm -r tmp_home
The important line is:
gpg: Good signature from "edgecase_datafeed"
This means that GPG has concluded that the digital signature from Edgecase Datafeed's public key is mathematically valid.
Next: Check the timestamp of checkpoint 1 in the Bitcoin blockchain.
The checkpoint 1 article contains:
- approximate date: 2017-06-28
- approximate block_height: 473274
Treat the SHA256 hash of checkpoint 1 as a Bitcoin private key and generate the corresponding Bitcoin address.
Bitcoin private key:
62b0d5ec1efa901eca870b75f743b12061f85b9e687d2a8a2393712363268fd2
I'll use this recipe:
Recipe for generating a Bitcoin address
Create another work directory: work2
in which to do this.
Output:
[spiano@localhost work2]$ python generate_bitcoin_address_3.py
### START GENERATION OF BITCOIN ADDRESS
Private key (hex bytes): 62b0d5ec1efa901eca870b75f743b12061f85b9e687d2a8a2393712363268fd2
Private key (32 hex bytes): 62b0d5ec1efa901eca870b75f743b12061f85b9e687d2a8a2393712363268fd2
Private key (WIF): 5JZkWDonArJN8T8Uaz8br4uCd7jCFDv8cJLQMSNo5q8M9JAVHkY
Bitcoin address: 159HcAaendN4FJSVZ3Ty9LwQabczdrmfL2
### END GENERATION OF BITCOIN ADDRESS
Bitcoin address:
159HcAaendN4FJSVZ3Ty9LwQabczdrmfL2
Browse to a blockchain information service:
live.blockcypher.com
Search for this Bitcoin address.
Result: This address page:
live.blockcypher.com/btc/address/159HcAaendN4FJSVZ3Ty9LwQabczdrmfL2
The oldest transaction shown for this address has this txid:
b81b21289e5076aa4fb0e548ce9341aa01ae9617b659ffbfc25e120d0e8fd3d4
This txid shown on the address page links to this transaction page:
live.blockcypher.com/btc/tx/b81b21289e5076aa4fb0e548ce9341aa01ae9617b659ffbfc25e120d0e8fd3d4
Click Advanced Details. Click API Call.
The information service reports that for this transaction:
- blockheight: 473276
- confirmed: 2017-06-28 18:44:22 UTC
=== Results of verifying checkpoint 1
I have confirmed that checkpoint 1 was timestamped by a Bitcoin transaction with block height 473276 and txid
b81b21289e5076aa4fb0e548ce9341aa01ae9617b659ffbfc25e120d0e8fd3d4
The article contained this date:
2017-06-28
and this approximate block height:
473274
The actual blockchain data was:
- block height: 473276
- date confirmed: 2017-06-28
===
So:
- The datafeed article "Viewpoint" was published on Edgecase Datafeed before the date 2017-06-28 and the Bitcoin blockheight 473276.
Combined with the previous result:
- The datafeed article "Viewpoint" was published on Edgecase Datafeed after the date 2017-06-28 and the Bitcoin blockheight 473266.
I see that:
- The datafeed article "Viewpoint" was published on Edgecase Datafeed on 2017-06-28 between the Bitcoin blockheights 473276 and 473276.
This also confirms the first timestamped digital signature made by the public key of StJohn Piano (this signature is the author signature of the article "Viewpoint"). This means that StJohn Piano's public key is confirmed to have existed since at least 2017-06-28 between the Bitcoin blockheights 473276 and 473276.
The current date is 2019-04-24, so StJohn Piano's public key is nearly 1 year and 10 months old.
Cleanup:
- Delete work and work2.
Excellent. That's the end of this project.
[start of notes]
Changes from the original text:
- 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.
[end of notes]
- In the Summary section: The phrase "between the Bitcoin blockheights 473276 and 473276." appears twice.
- The phrase also appears twice in the Project Log section.
- In all cases, the first number should be 473266.