Recent changes to this wiki:

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index c412b92..393d216 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 46 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 47 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

poll vote (watched it all, liked it)
diff --git a/blog/entry/watch_me_code_for_half_an_hour.mdwn b/blog/entry/watch_me_code_for_half_an_hour.mdwn
index 543b3af..c412b92 100644
--- a/blog/entry/watch_me_code_for_half_an_hour.mdwn
+++ b/blog/entry/watch_me_code_for_half_an_hour.mdwn
@@ -14,7 +14,7 @@ Not shown is the hour I spent the next day changing the "optimize"
 subcommand implemented here into "--auto" options that can be passed to
 [[code/git-annex]]'s get and drop commands.
 
-[[!poll 45 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
+[[!poll 46 "watched it all, liked it" 8 "watched some, boring" 4 "too long for me" 15 "too haskell for me" 12 "not interested"]]
 
 [[!meta title="watch me program for half an hour"]]
 [[!tag haskell]]

keysafe
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index aeb5fce..7a6b2a2 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -6,3 +6,8 @@ Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
 [[!tag propellor]]
+
+--
+
+Update: My presentation on [[code/keysafe]] has also been accepted for the
+Security MiniConf at LCA, January 17th.
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 4b18e32..e0f85e5 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -51,7 +51,7 @@ average of 35 minutes.
 * Repeat for next password.
 
 So, for a password with N entropy, the number of CPU-years of work
-is to crack it is: 2^(N-1)*50/60/24/365
+is to crack it is: `2^(N-1)*50/60/24/365`
 
 * Strong password (50 entropy): 53553077761 CPU-years
 * Weak password (30 entropy): 51072 CPU-years
@@ -84,10 +84,10 @@ of shards, and obtain all the encrypted keys for further cracking. So it's
 important that there not be any checksum or header in addition to the AES
 encrypted data. (AES encrypted data cannot be distinguised from random
 garbage except by block size.) Get that right, and with N keysafe users, an
-attacker would need to try 2^(N-1) combinations of shards to find one on
+attacker would need to try `2^(N-1)` combinations of shards to find one on
 average, and would need to brute force the password of each combination.
 With only 20 keysafe users, assuming all users have super-weak passwords,
-this attack takes 13107200 years of CPU work (2^19*25) to crack one. With
+this attack takes 13107200 years of CPU work `(2^19*25)` to crack one. With
 50 users, this jumps to quadrillions of years of CPU work.
 
 Colluding servers can try to correlate related objects based on access

fix identica feed
diff --git a/grep.mdwn b/grep.mdwn
index e73e432..00fe74b 100644
--- a/grep.mdwn
+++ b/grep.mdwn
@@ -8,5 +8,5 @@ on the net.
 List of feeds:
 
 * [[!aggregate expirecount=25 name="music" feedurl="http://libre.fm/rdf.php?fmt=rss&page=%2Fuser%2Fjoeyhess%2Frecent-tracks" url="http://libre.fm/user/joeyhess"]]
-* [[!aggregate expirecount=25 name="identi.ca posts" feedurl="http://tmp.joeyh.name/pump.atom" url="http://identi.ca/joeyh"]]
+* [[!aggregate expirecount=25 name="identi.ca posts" feedurl="https://pump2rss.com/feed/joeyh@identi.ca.atom" url="http://identi.ca/joeyh"]]
 * [[!aggregate expirecount=25 name="books" feedurl="http://www.goodreads.com/review/list_rss/2159448?key=afd7e8432b3f9e33edab442a7c94e95849af4527&shelf=currently-reading" url="http://www.goodreads.com/user/show/2159448"]]

blog update
diff --git a/blog/entry/drought.mdwn b/blog/entry/drought.mdwn
new file mode 100644
index 0000000..6b6b372
--- /dev/null
+++ b/blog/entry/drought.mdwn
@@ -0,0 +1,28 @@
+Drought here since August. The small cistern ran dry a month ago, which has
+never happened before. The large cistern was down to some 900 gallons. I
+don't use anywhere near the national average of 400 gallons per day. More
+like 10 gallons. So could have managed for a few more months.
+Still, this was worrying, especially as the area moved from severe to
+extreme drought according to the 
+[US Drought Monitor](http://droughtmonitor.unl.edu/).
+
+Two days of solid rain fixed it, yay! The small cistern has already
+refilled, and the large will probably be full by tomorrow.
+
+The winds preceeding that same rain storm fanned the flames that
+destroyed Gatlinburg. Earlier, fire got within 10 miles of here,
+although that may have been some kind of controlled burn.
+
+Climate change is leading to longer duration weather events in this area.
+What tended to be a couple of dry weeks in the fall, has become multiple
+months of drought and weeks of fire. What might have been a few days of
+winter weather and a few inches of snow before the front moved through has
+turned into multiple weeks of arctic air, with multiple 1 ft snowfalls.
+What might have been a few scorching summer days has become a week of
+100-110 degree temperatures. I've seen all that over the past several
+years.
+
+After this, I'm adding "additional, larger cistern" to my todo list.
+Also "larger fire break around house".
+
+[[!tag lay]]

add
diff --git a/code.mdwn b/code.mdwn
index 9d6bceb..2aa5ac7 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -50,6 +50,7 @@ people have taken them on.
 [[pentium-builder]]
 [[apt-src]]
 [[jetring]]
+[[scriptreplay]]
 
 These need new maintainers, stat!
 
diff --git a/code/scriptreplay.mdwn b/code/scriptreplay.mdwn
new file mode 100644
index 0000000..874b37e
--- /dev/null
+++ b/code/scriptreplay.mdwn
@@ -0,0 +1,31 @@
+In 2000, I [patched script](https://bugs.debian.org/68556) to
+dump out timing information, which let typescripts be
+replayed with realistic typing and output delays by a
+`scriptreplay` command I whipped up.
+
+This was not a unique idea; Anthony Towns had some code to do
+something similar. And four months later, Satoru Takabayashi
+created [ttyrec](http://0xcc.net/ttyrec/) which does much the same.
+Of screenreplay, he says:
+
+> A friend of mine told me that Mr. Joey Hess implemented the same thing.
+> If I had only known that earlier, I would have never reinvented the
+> wheel...
+
+In the end, ttyrec became the go-to tool for this purpose. Probably
+because it includes all the information in a single file, rather than the
+two files script uses (one for the terminal output and the other
+that I added for the timings)
+
+In any case, it's common now to record terminal sessions and play
+them back in real time. One of the best known uses is by
+[nethack.alt.org](https://nethack.alt.org/) for replay and live
+watching of games.
+
+I've had nothing to do with scriptreplay since I wrote it. Others have
+maintained it since. I tend to use ttyrec more myself,
+and have made a number of improvements to it, some of which have been
+included in the Debian package, but none of which seem to have gotten back
+to upstream as of yet. A number of my other patches to ttyrec, including
+using inotify to improve live playback of ttyrecord, are languishing 
+in a [git repository](https://git.joeyh.name/?p=zzattic/ttyrec.git;a=summary).

desc
diff --git a/index.mdwn b/index.mdwn
index 664493f..fe978e5 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,5 +1,5 @@
 [[!meta title="Joey Hess"]]
-[[!meta description="home page, blog, projects, interviews, and hidden jems"]]
+[[!meta description="building worthwhile things that might last"]]
 
 <div>
 <style>

desc
diff --git a/blog.mdwn b/blog.mdwn
index 89195b3..afef011 100644
--- a/blog.mdwn
+++ b/blog.mdwn
@@ -1,4 +1,5 @@
 [[!meta title="see shy jo"]]
+[[!meta description="Joey Hess's blog"]]
 
 [[!inline pages="blog/entry/* and !blog/entry/*/* and !link(foo) and 
 !link(unfinished)"

desc
diff --git a/index.mdwn b/index.mdwn
index 4cccc7e..664493f 100644
--- a/index.mdwn
+++ b/index.mdwn
@@ -1,4 +1,5 @@
 [[!meta title="Joey Hess"]]
+[[!meta description="home page, blog, projects, interviews, and hidden jems"]]
 
 <div>
 <style>

remove old cruft
diff --git a/joeyca/cacert.crt b/joeyca/cacert.crt
deleted file mode 100644
index aafcd75..0000000
--- a/joeyca/cacert.crt
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC9zCCAmCgAwIBAgIBADANBgkqhkiG9w0BAQQFADBhMQswCQYDVQQGEwJVUzEL
-MAkGA1UECBMCVE4xEDAOBgNVBAoTB2tpdGVuZXQxEjAQBgNVBAMTCUpvZXkgSGVz
-czEfMB0GCSqGSIb3DQEJARYQam9leUBraXRlbmV0Lm5ldDAeFw0wMzA3MjAwODUx
-NTVaFw0xMzA3MTcwODUxNTVaMGExCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJUTjEQ
-MA4GA1UEChMHa2l0ZW5ldDESMBAGA1UEAxMJSm9leSBIZXNzMR8wHQYJKoZIhvcN
-AQkBFhBqb2V5QGtpdGVuZXQubmV0MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQC+CdlAO61uyyqHx9XST63R9hk6aPiMXO9mnp3sHrgybpfisXizPx5l3UdGZX8t
-A59K6EjoQd1ClLOoYJdOSxH+yzQfUQ3JNsbKYkzarGEfy/D5PV6mTonzHxdF4sdj
-uGH+Ov2kiU3hxCRGpoqEagi9H+m2T7J32qAFDebqwbUDAQIDAQABo4G+MIG7MB0G
-A1UdDgQWBBQgh36YzCLs2dXfrvYuAhoSXak99zCBiwYDVR0jBIGDMIGAgBQgh36Y
-zCLs2dXfrvYuAhoSXak996FlpGMwYTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlRO
-MRAwDgYDVQQKEwdraXRlbmV0MRIwEAYDVQQDEwlKb2V5IEhlc3MxHzAdBgkqhkiG
-9w0BCQEWEGpvZXlAa2l0ZW5ldC5uZXSCAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQA4BBQUKLlXzRC0DxkbU3FHKNVRb4RvPMFdw3L7NLBR/ZM+7VS0
-5CWCTUfSXmS0mUf/kTpk7z2Mv1Sdca/br+Wm8UB90xVgHlteMri3L+qnvgu39SRO
-Y05VaIDcaDtvbDUg93eQTOkZ1pYxphN3shd0lxInHSNaijQccWokxsDJTw==
------END CERTIFICATE-----
diff --git a/joeyca/cacert.crt.asc b/joeyca/cacert.crt.asc
deleted file mode 100644
index 53a5367..0000000
--- a/joeyca/cacert.crt.asc
+++ /dev/null
@@ -1,24 +0,0 @@
------BEGIN PGP MESSAGE-----
-Version: GnuPG v1.2.2 (GNU/Linux)
-
-owFtVDuP41QUHnahwNIW09CAEMV2EcSJ8xgjrUb3FdtJrjPXr9ih8iOxHTuTd+y4
-X2m1oqBGSGyxULEdNPyAraCgXUo6tCUNHXaGGRbBlW7z6V6d8z3O+eLB/bN7569e
-HX/On14O33rxtuZxvutPN7tP/M3u8sPfn35cHUgkRf0IEc1QegoCBjmhHFUUJBYI
-gQUKQaZAEJYXAxWGyTpKYknMeAgY6wEMI8q2GWIOthiTSNa3zIIMOQoSCTRMgiBF
-FmnlBIMRDFULgqUBm7tVIFn7ic1yMgfsBqcGMleHiZ2EumQVnF+QGYW8hPS1pCue
-gBnpA81h7kJMpybcuLaWeguLHy7aaYDBtJfxGS2AQOcgG2Ez51TDckswP4GGfwIr
-jEokRwXo31R1DJBaxhsUlJKCacwJKym0bihEVHabKT8ZV5WITiE44SCnfb3qRofK
-xFYLql1kMnP6g+VEiQ6+ygGWwF4E117TajPpjvO+apsq0oyCf9ErBTVBWVMFGMGY
-DSAXMlRDQQpGncb+eFzLuWjrRkfQxCjpuFcxtUfi4nolbOVNePRWs3hrx8VV3k4F
-M5Am9sWOA21x0CHzJQsaKB2Olk4/GOm5XDsWbGYyoa9uvYGTFO5GIrNjHbevrM7C
-WF4Xch70Wttgzu0luTY6NJPYFKIcadJquSZuGItybdE0un2huQY9PPXWmWdiwJTy
-ArhsSbWSXrdyjyuFCnDIxhCyMBI6ToGG22ZgzzYHZw+ipW67iVgGDcZZqb7Gz6Ei
-4fIzCP9+z/3vh04vXUk0cwwyvA1amUNkWfQNa8PSWm3EUQ1kODx5OyBZcBccqikZ
-AScckywdVC4pJEp9geZyAYLbqHNV1hEjYyJV8UzBXRZQu7RTRyXnDINT+wYEZgYy
-AuvFP7PC3Q1LNQIMtEotzMEwtQsN8ThPPFPoyQPV0ryWdriivSAThl11CLX6hNa6
-ls5zbTRGhjnT7YXOL8xZPTFWSbdo0kNDD3y37m1q48WFCUU+t0I53U3pJhaGtfX1
-IdwLol5q4PBty1Ww7+LdwcNmKApTZoySSWPl5KtIFbZRwKe5ci3rqhvPme+Pl0m+
-xX0je/SIO20EouL/boknl/ffOatWye2aOb9Ht2fPvnrv+0ny3Qfffvb6z8ZPD9/9
-8cX5H1+fPfvmy5fnn//6Ev7y+FP1wfPf3v/h9XP9Lw==
-=C4IM
------END PGP MESSAGE-----
diff --git a/joeyca/gpgkey.asc b/joeyca/gpgkey.asc
deleted file mode 100644
index 4d00577..0000000
--- a/joeyca/gpgkey.asc
+++ /dev/null
@@ -1,1373 +0,0 @@
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: GnuPG v1.0.7 (GNU/Linux)
-
-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

(Diff truncated)
add news item for github-backup 1.20161118
diff --git a/code/github-backup/news/version_1.20160319.mdwn b/code/github-backup/news/version_1.20160319.mdwn
deleted file mode 100644
index ca3efaf..0000000
--- a/code/github-backup/news/version_1.20160319.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-github-backup 1.20160319 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Update to github-0.14.1.
-     Building with old versions is not supported due to the massive API
-     changes in this version of the github library.
-   * Added support for oath tokens."""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20161118.mdwn b/code/github-backup/news/version_1.20161118.mdwn
new file mode 100644
index 0000000..81a7226
--- /dev/null
+++ b/code/github-backup/news/version_1.20161118.mdwn
@@ -0,0 +1,3 @@
+github-backup 1.20161118 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build with recent versions of cabal."""]]
\ No newline at end of file

fix
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index 2936627..aeb5fce 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -5,4 +5,4 @@ Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
 Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
-[[!tag code/propellor]]
+[[!tag propellor]]

fix
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
index fe490d8..2936627 100644
--- a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -5,4 +5,4 @@ Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
 Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
 attend it again.
 
-[[!code/propellor]]
+[[!tag code/propellor]]

blog update
diff --git a/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
new file mode 100644
index 0000000..fe490d8
--- /dev/null
+++ b/blog/entry/Linux.Conf.Au_2017_presentation_on_Propellor.mdwn
@@ -0,0 +1,8 @@
+On January 18th, I'll be presenting 
+"Type driven configuration management with Propellor" at Linux.Conf.Au in
+Hobart, Tasmania. [Abstract](https://linux.conf.au/schedule/presentation/116/)
+
+Linux.Conf.Au is a wonderful conference, and I'm thrilled to be able to
+attend it again.
+
+[[!code/propellor]]

add news item for github-backup 1.20161110
diff --git a/code/github-backup/news/version_1.20160207.mdwn b/code/github-backup/news/version_1.20160207.mdwn
deleted file mode 100644
index 2d7fd4e..0000000
--- a/code/github-backup/news/version_1.20160207.mdwn
+++ /dev/null
@@ -1,10 +0,0 @@
-github-backup 1.20160207 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Switch to using https instead of git:// for a secure transport.
-     Note that existing git:// remotes will continue to be used.
-     Thanks, Robin Schneider.
-   * Add upper bound on github dependency, as version 0.14 has large API
-     changes and can't be used yet.
-   * Various updates to internal git and utility libraries shared
-     with git-annex.
-   * Silence build warnings with ghc 7.10."""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20161110.mdwn b/code/github-backup/news/version_1.20161110.mdwn
new file mode 100644
index 0000000..e736fdd
--- /dev/null
+++ b/code/github-backup/news/version_1.20161110.mdwn
@@ -0,0 +1,6 @@
+github-backup 1.20161110 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix build with recent versions of the directory package.
+     Thanks, James McCoy.
+   * Various updates to internal git and utility libraries shared
+     with git-annex."""]]
\ No newline at end of file

add news item for keysafe 0.20161107
diff --git a/code/keysafe/news/version_0.20160922.mdwn b/code/keysafe/news/version_0.20160922.mdwn
deleted file mode 100644
index 0cf5ac8..0000000
--- a/code/keysafe/news/version_0.20160922.mdwn
+++ /dev/null
@@ -1,17 +0,0 @@
-keysafe 0.20160922 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Keysafe now knows about 3 servers, although only 1 is currently in
-     operation. It will queue uploads to the other 2 servers until
-     they are added in a later keysafe release.
-   * Added --autostart mode, and make both keysafe --backup and
-     the Makefile install a FDO desktop autostart file to use it.
-   * In --autostart mode, retry any queued uploads.
-   * In --autostart mode, check for gpg keys that have not been
-     backed up, and offer to back them up. Only ask once per key.
-   * Changed format of ~/.keysafe/backup.log
-   * Server: Reduce number of buckets in rate limiter, avoiding ones with very low
-     proof of work.
-   * Server: Make rate limiter adapt to ongoing load more quickly -- every 15
-     minutes instead of every 60.
-   * Server: Added --backup-server and --restore-server to aid in backing
-     up keysafe servers with minimal information leakage."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161107.mdwn b/code/keysafe/news/version_0.20161107.mdwn
new file mode 100644
index 0000000..d98987e
--- /dev/null
+++ b/code/keysafe/news/version_0.20161107.mdwn
@@ -0,0 +1,14 @@
+keysafe 0.20161107 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * The third keysafe server is now available, provided by Purism.
+   * Purism's keysafe server has been vetted to Recommended level!
+   * Change default for --port to 4242.
+   * Fix --check-server to not fail when the server has not had anything
+     stored on it yet.
+   * --upload-queued: Exit nonzero if unable to upload all queued objects.
+   * --autostart: If unable to upload all queued objects initially,
+     delay between 1 and 2 hours and try again.
+   * Better suggestion when user is having difficulty thinking of a strong
+     enough password.
+   * Defer requesting secret key from gpg until just before backup, so the
+     user knows why gpg is asking for this secret key to be backed up."""]]
\ No newline at end of file

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 72b16d3..c1553c7 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -38,7 +38,39 @@ Keysafe's server list puts servers in three categories:
 
 ### Recommended
 
-**None yet!**
+* hlmjmeth356s5ekm.onion
+
+<pre>
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA1
+
+The keysafe server hlmjmeth356s5ekm.onion is provided and administered by
+Purism. It is located in the EU (Cyprus).
+
+We intend to run this server for at least 10 years (through 2027),
+or failing that, to transition any data stored on it to another
+server that is of similar or higher security.
+
+Our warrant canary is <https://puri.sm/warrant-canary/>,
+and is updated quarterly.
+-----BEGIN PGP SIGNATURE-----
+Version: GnuPG v1
+
+iQIcBAEBAgAGBQJYF8U4AAoJECPPLj0lRRT30CkP/Rn2TAeriNWO9wZcr0OHyX7B
+TJcgLy3pZXbGn6T6qmJqg3K22fTKJ7CX0dfIM+WLI9FfBtnT95q1rnzywhBGPXzj
+eD3g7r3QinIfMLBQTKyc9Ik5132uenD5h72ggVl3D+kuWv622IhaAaiVkuHc5KoR
+3/S+ImkcS/gz83UNTXnWdMs0V8+eqAjpWeYQS8Ih28AECI9f+xUUH//V9Ii/4Usv
+E3Y0hbqj8kSi4/Q6IwmFiJTKZ1FpccKhl6GIYUSLwJMJDHoI46M/AaZy0Xx9pLcU
+niSELai/7/0fY4N0TY2CbZUgH7FEhi0k8cCsGF7yTA6dqya8deKQKdUdDllcHayv
++GOAqijiSTPrRox4TPMMdurPXTsJxeJuxVdS75Lw2cFk+JaaIVS/3XEyeuGpaVKW
+wSTltyFkMx9ur5cCPT2rxoRN78HuqgiHda/Jd4c2pny7GwpUEYAznQQaBYEl2jlQ
+/Go3ZudpnWfBRRe7znazhA6mIatPY61GrNIebVlET6/NCw9sZFRjHXY3pMw1u/TY
+4eP0UQpBUed4/sot5vsZVwbn8e6eFh0S4HTdl5x1G8jN8nUZVdJJjOtACrONW+TG
+CLSNDkMgQ5slBmtZm+MzL2VYkFHCMmPerNXY1DhHjMyfLpQEIN+bho+mIyc5h/W/
+Br5jFZujcQ0u7GzqvaDB
+=RmK4
+-----END PGP SIGNATURE-----
+</pre>
 
 ### Alternate
 
@@ -75,11 +107,6 @@ lhmhvShr0WRqB8fWYPkc
 -----END PGP SIGNATURE-----
 </pre>
 
-* keysafe.puri.sm
-
-  Provided by [Purism](https://puri.sm/). Located in Cyprus.  
-  Vetting to Recommended level in progress.
-
 * thirdserver
 
   Provided by Marek Isalski at [Faelix](http://www.faelix.net/).

add rest of keysafe servers
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 334df3b..72b16d3 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -75,6 +75,17 @@ lhmhvShr0WRqB8fWYPkc
 -----END PGP SIGNATURE-----
 </pre>
 
+* keysafe.puri.sm
+
+  Provided by [Purism](https://puri.sm/). Located in Cyprus.  
+  Vetting to Recommended level in progress.
+
+* thirdserver
+
+  Provided by Marek Isalski at [Faelix](http://www.faelix.net/).
+  Currently located in UK, but planned move to CH.  
+  Vetting to Recommended level in progress.
+
 ## Detailed requirements
 
 ### Alternate

Added a comment
diff --git a/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment b/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment
new file mode 100644
index 0000000..12d39cb
--- /dev/null
+++ b/blog/entry/a_rope_ladder_to_the_dgit_treehouse/comment_2_0b2d59f84b135405e0fcd379da7bd032._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="spwhitton"
+ avatar="http://cdn.libravatar.org/avatar/9c3f08f80e67733fd506c353239569eb"
+ subject="comment 2"
+ date="2016-10-24T14:34:38Z"
+ content="""
+The latest release of dgit, 2.7, includes `dgit-maint-merge(7)`, a tutorial building on the ideas in this blog post.
+"""]]

add news item for keysafe 0.20161022
diff --git a/code/keysafe/news/version_0.20160914.mdwn b/code/keysafe/news/version_0.20160914.mdwn
deleted file mode 100644
index 9b0dcd1..0000000
--- a/code/keysafe/news/version_0.20160914.mdwn
+++ /dev/null
@@ -1,21 +0,0 @@
-keysafe 0.20160914 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Fix bug that prevented keysafe --server from running when there was no
-     controlling terminal and zenity was not installed.
-   * Added --name and --othername options.
-   * Added proof of work to client/server protocol.
-   * Server-side rate limiting and DOS protection.
-   * server: Added --months-to-fill-half-disk option, defaulting to 12.
-   * Several new dependencies.
-   * Another fix to gpg secret key list parser.
-   * Warn when uploads fail and are put in the upload queue.
-   * Warn when --uploadqueued fails to upload to servers.
-   * Fix --uploadqueued bug that prevented deletion of local queued file.
-   * Added --chaff mode which uploads random junk to servers.
-     This is useful both to test the server throttling of uploads,
-     and to make it harder for servers to know if an object actually
-     contains secret key information.
-   * Store information about backed up keys in ~/.keysafe/backup.log
-     This can be deleted by the user at any time, but it's useful
-     in case a server is known to be compromised, or a problem is found
-     with keysafe's implementation that makes a backup insecure."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161022.mdwn b/code/keysafe/news/version_0.20161022.mdwn
new file mode 100644
index 0000000..e54f26e
--- /dev/null
+++ b/code/keysafe/news/version_0.20161022.mdwn
@@ -0,0 +1,12 @@
+keysafe 0.20161022 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Add keywords to desktop file.
+     Thanks, Sean Whitton
+   * Fix use of .IP macro in manpage.
+     Thanks, Sean Whitton
+   * Fix some mispellings.
+     Thanks, Sean Whitton
+   * Makefile: Propagate LDFLAGS, CFLAGS, and CPPFLAGS through ghc.
+   * Makefile: Allow setting BUILDER=./Setup to build w/o cabal or stack.
+   * Makefile: Allow setting BUILDEROPTIONS=-j1 to avoid concurrent
+     build, which should make build reproducible."""]]
\ No newline at end of file

add news item for keysafe 0.20161007
diff --git a/code/keysafe/news/version_0.20160831.mdwn b/code/keysafe/news/version_0.20160831.mdwn
deleted file mode 100644
index 7331f21..0000000
--- a/code/keysafe/news/version_0.20160831.mdwn
+++ /dev/null
@@ -1,16 +0,0 @@
-keysafe 0.20160831 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Server implementation is ready for initial deployment.
-   * Keysafe as a client is not yet ready for production use.
-   * Removed embedded copy of secret-sharing library, since finite-field
-     only supports prime fields. This caused shares to be twice the size of
-     the input value.
-   * Reduced chunk size to 32kb due to share size doubling.
-   * Fix gpg secret key list parser to support gpg 2.
-   * Tuned argon2 hash parameters on better hardware than my fanless laptop.
-   * Improve time estimates, taking into account the number of cores.
-   * Added basic test suite.
-   * Added options: --store-directory --test --port --address
-   * Added a Makefile
-   * Added a systemd service file.
-   * Added a desktop file."""]]
\ No newline at end of file
diff --git a/code/keysafe/news/version_0.20161007.mdwn b/code/keysafe/news/version_0.20161007.mdwn
new file mode 100644
index 0000000..a7e8468
--- /dev/null
+++ b/code/keysafe/news/version_0.20161007.mdwn
@@ -0,0 +1,9 @@
+keysafe 0.20161007 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Check if --store-local directory is writable.
+   * Removed dependency on crypto-random.
+   * Added a LSB init script, for non-systemd systems.
+     (It currently uses Debian's start-stop-daemon, so would need porting
+     for other distributions.)
+   * /etc/default/keysafe is read by both the systemd service file and the
+     init script, and contains configuration for the keysafe server."""]]
\ No newline at end of file

new alien maintainer
diff --git a/code.mdwn b/code.mdwn
index 2bd4dc0..9d6bceb 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -38,6 +38,7 @@ people have taken them on.
 [[Debian]]
 [[debian-installer]]
 [[debhelper]]
+[[alien]]
 [[tasksel]]
 [[flashybrid]]
 [[wmbattery]]
@@ -54,7 +55,6 @@ These need new maintainers, stat!
 
 [[debmirror]]
 [[sleepd]]
-[[alien]]
 [[nslu2-utils]]
 [[ticker]]
 
diff --git a/code/alien.mdwn b/code/alien.mdwn
index de043f5..b3c4fad 100644
--- a/code/alien.mdwn
+++ b/code/alien.mdwn
@@ -3,47 +3,17 @@ slackware tgz  file formats. If you want to use a package from another
 distribution than the one you have installed on your system, you can use
 alien to convert it to your preferred package format and install it.
 
-Despite the large version number, alien is still (and will probably always
-be) rather experimental software. It has been used by many people for many
-years, but there are still many bugs and limitations.
-
-Alien should *not* be used to replace important system packages, like 
-sysvinit, shared libraries, or other things that are essential for the 
-functioning of your system. Many of these packages are set up differently by 
-Debian and Red Hat, and packages from the different distributions cannot be 
-used interchangably. In general, if you can't uninstall the package without
-breaking your system, don't try to replace it with an alien version.
-
 ## News
 
 [[!inline pages="code/alien/news/* and !*/Discussion" show="2"]]
 
 ## Downloading alien
 
-Alien is available as the `alien` package in Debian.
-
-Currently the best place to download the tarball is from
-<http://packages.debian.org/unstable/source/alien>
-
-Its git repository is `git://git.joeyh.name/alien`
-
-## Other things you'll need
-
-To use alien, you will need several other programs. Alien is a perl program,
-and requires perl version 5.004 or greater.
-
-To convert packages to or from rpms, you need the Red Hat Package Manager; 
-get it from [its website](http://www.rpm.org/).
-
-If you want to convert packages into debian packages, you will need the 
-dpkg, dpkg-dev, and debhelper packages, which are available on the [Debian packages site](http://packages.debian.org/).
-You'll also need gcc, and make.
+Alien's website has moved to
+<https://sourceforge.net/projects/alien-pkg-convert/>
 
-Attention, all linux users who don't use Debian:
-<a href="mailto:BABCOCK@MATH.PSU.EDU">Bruce S. Babcock</a> has put together a
-package of all the extra files you need to use alien on a non-Debian
-distribution. It's called "alien-extra", and you can download it from
-[his ftp site](ftp://ykbsb2.yk.psu.edu/pub/alien/).
+My old git repository for alien is still available at
+`git://git.joeyh.name/zzattic/alien`
 
 ----
 
diff --git a/code/alien/news/new_alien_maintainer.mdwn b/code/alien/news/new_alien_maintainer.mdwn
new file mode 100644
index 0000000..8f07460
--- /dev/null
+++ b/code/alien/news/new_alien_maintainer.mdwn
@@ -0,0 +1,5 @@
+Kyle Barry has taken over maintenance of alien.
+His versions are available from
+<https://sourceforge.net/projects/alien-pkg-convert/>
+
+This rss feed won't be updated for any new releases of alien.
diff --git a/code/alien/news/version_8.88.mdwn b/code/alien/news/version_8.88.mdwn
deleted file mode 100644
index 99c1cb8..0000000
--- a/code/alien/news/version_8.88.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-alien 8.88 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Ensure that version numbers begin with well, a number, when building a
-     deb, otherwise dpkg-deb will refuse to build it."""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.90.mdwn b/code/alien/news/version_8.90.mdwn
deleted file mode 100644
index 04f4a5c..0000000
--- a/code/alien/news/version_8.90.mdwn
+++ /dev/null
@@ -1,6 +0,0 @@
-alien 8.90 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Add --target=&lt;arch&gt; option for setting architecture. Closes: #[260948](http://bugs.debian.org/260948)
-     (Thanks, Teemu Ikonen)
-   * Add conversion from ppc64le (rpm) to ppc64el (deb).
-   * debhelper v9"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.91.mdwn b/code/alien/news/version_8.91.mdwn
deleted file mode 100644
index cadb314..0000000
--- a/code/alien/news/version_8.91.mdwn
+++ /dev/null
@@ -1,5 +0,0 @@
-alien 8.91 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Support other deb data.tar compression schemes in fallback code.
-     Closes: #[718364](http://bugs.debian.org/718364)
-     Thanks, Guillem Jover"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.92.mdwn b/code/alien/news/version_8.92.mdwn
deleted file mode 100644
index fc8a3c1..0000000
--- a/code/alien/news/version_8.92.mdwn
+++ /dev/null
@@ -1,4 +0,0 @@
-alien 8.92 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Remove suggests for lsb-rpm, which no longer exists.
-     Closes: #[756873](http://bugs.debian.org/756873)"""]]
\ No newline at end of file
diff --git a/code/alien/news/version_8.93.mdwn b/code/alien/news/version_8.93.mdwn
deleted file mode 100644
index afdb329..0000000
--- a/code/alien/news/version_8.93.mdwn
+++ /dev/null
@@ -1,3 +0,0 @@
-alien 8.93 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Alien needs a new maintainer, both in Debian and upstream."""]]
\ No newline at end of file

Suggest removing parallel
diff --git a/code/moreutils/discussion.mdwn b/code/moreutils/discussion.mdwn
index c6766eb..4cca48f 100644
--- a/code/moreutils/discussion.mdwn
+++ b/code/moreutils/discussion.mdwn
@@ -434,6 +434,8 @@ It would be great if sponge had this same feature as an option: only create the
 
 ## parallel
 
+According to ckester's comment, should we remove parallel from moreutils? The main website of moreutils says: "I'm always interested to add more to the collection, as long as they're suitably general-purpose, and don't DUPLICATE other well-known tools." -- hong
+
 Need to resolve the name conflict with GNU parallel (http://www.gnu.org/software/parallel/).  As far as I can tell, these are two distinct implementations addressing the same general problem space. --ckester
 
 ##### PATCH: make -i and -n not mutually exclusive in parallel

blog update
diff --git a/blog/entry/keysafe_with_local_shares.mdwn b/blog/entry/keysafe_with_local_shares.mdwn
new file mode 100644
index 0000000..1e2c57b
--- /dev/null
+++ b/blog/entry/keysafe_with_local_shares.mdwn
@@ -0,0 +1,56 @@
+If your gpg key is too valuable for you to feel comfortable with
+backing it up to the cloud using [[code/keysafe]], here's an alternative
+that might appeal more. 
+
+Keysafe can now back up some shares of the key to local media, and other
+shares to the cloud. You can arrange things so that the key can't be 
+restored without access to some of the local media and some of the cloud
+servers, as well as your password.
+
+For example, I have 3 USB sticks, and there are 3 keysafe servers. So let's
+make 6 shares total of my gpg secret key and require any 4 of them to
+restore it.
+
+I plug in all 3 USB sticks and look at `mount` to get the paths to them.
+Then, run keysafe, to back up the key spread amoung all 6 locations.
+
+	keysafe --backup --totalshares 6 --neededshares 4 \
+		--add-storage-directory /media/sdc1 \
+		--add-storage-directory /media/sdd1 \
+		--add-storage-directory /media/sde1
+
+Once it's done, I can remove the USB sticks, and distribute them to secure
+places.
+
+To restore, I need at least one of the USB sticks.
+(If some of the servers are down, more USB sticks will be needed.) 
+Again I tell keysafe the paths where USB stick(s) are mounted.
+
+	keysafe --restore --totalshares 6 --neededshares 4 \
+		--add-storage-directory /media/sdb1
+
+Using keysafe this way, physical access to the USB sticks is the first
+level of defense, and hopefully you'll know if that's breached. The keysafe
+password is the second level of defense, and cracking that will take a lot
+of work. Leaving plenty of time to revoke your key, etc, if it comes to
+that.
+
+I feel this is better than the methods I've been using before to back up my
+most important gpg keys. With paperkey, physical access to the printout
+immediately exposes the key. With Shamir Secret Sharing and manual
+distribution of shares, the only second line of defense is the much easier
+to crack gpg passphrase. Using OpenPGP smartcards is still a more secure
+option, but you'd need 3 smartcards to reach the same level of redundancy,
+and it's easier to get your hands on 3 USB sticks than 3 smartcards.
+
+There's another benefit to using keysafe this way. It means that sometimes,
+the data stored on the keysafe servers is not sufficient to crack a key.
+There's no way to tell, so an attacker risks doing a lot of futile work.
+
+If you're not using an OpenPGP smartcard, I encourage you to back up your
+gpg key with keysafe as described above. 
+
+Two of the three necessary keysafe servers are now in operation, and I hope
+to have a full complement of servers soon.
+
+(This was sponsored by Thomas Hochstein on [Patreon](https://patreon.com/joeyh).)

add news item for keysafe 0.20161006
diff --git a/code/keysafe/news/version_0.20160819.mdwn b/code/keysafe/news/version_0.20160819.mdwn
deleted file mode 100644
index 1fe832a..0000000
--- a/code/keysafe/news/version_0.20160819.mdwn
+++ /dev/null
@@ -1,11 +0,0 @@
-keysafe 0.20160819 released
-
-   * First release of keysafe. This is not yet ready for production use.
-   * Network support is not yet implemented, but --store-local works for
-     testing with local data storage.
-   * Data backed up with keysafe version 0.* will not be able to be restored
-     by any later version! Once the data format stabalizes, keysafe version
-     1 data will be supported by every later version.
-   * Argon2 hashes are not yet tuned for modern hardware, but only for my
-     laptop. So, cracking cost estimates may be low. To help with this
-     tuning, run `keysafe --bechmark` and send the output to me.
diff --git a/code/keysafe/news/version_0.20161006.mdwn b/code/keysafe/news/version_0.20161006.mdwn
new file mode 100644
index 0000000..2758b34
--- /dev/null
+++ b/code/keysafe/news/version_0.20161006.mdwn
@@ -0,0 +1,10 @@
+keysafe 0.20161006 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * New --add-storage-directory and --add-server options, which can be used
+     to make keysafe backup/restore using additional locations.
+   * Removed --store-local option; use --add-storage-directory instead.
+   * Fix bugs with entry of gpg keyid in the keysafe.log.
+   * Fix bug in --autostart that caused the full gpg keyid to be
+     used to generate object names, which made restores would only work
+     when --gpgkeyid was specifid.
+   * Remove embedded copy of argon2 binding, depend on fixed version of package."""]]
\ No newline at end of file

Added a comment: remove old batteries?
diff --git a/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment b/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment
new file mode 100644
index 0000000..8cbc74f
--- /dev/null
+++ b/blog/entry/battery_bank_refresh/comment_2_7d3dcf77d3454c97f849af25636ee5df._comment
@@ -0,0 +1,16 @@
+[[!comment format=mdwn
+ username="https://anarc.at/openid/"
+ nickname="anarcat"
+ subject="remove old batteries?"
+ date="2016-10-06T12:17:20Z"
+ content="""
+i am not an expert in the field, but it seems to me damaged / discharged batteries may actually be a liability. If you discharge a lead-acid battery too much, it gets damaged and charging it can't quite bring it back to its original capacity, as the terminals get full of crap. \"Too much\" varies from one battery to the other, but 11.1V is *definitely* too low, especially for a battery bank, where that voltage is more an average than the lowest charge point (which means some batteries are *lower* than 11V!).
+
+The worst about damaged batteries in a battery bank is that they bring down other batteries too: the stronger batteries will try to charge the weaker batteries and discharge faster.
+
+Another way to think about this is that every battery is also a resistance as well, even more so when it is damaged.
+
+I can't explain, however, why the two new 12V batteries wouldn't be enough to power the house, unless you have too much of a power drain - I don't know the exact setup here (how much wattage is hooked to the circuit and the exact capacity of the individual batteries) so I can't guess much...
+
+I hope that helps!
+"""]]

Added a comment: Battery bank wiring
diff --git a/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment b/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment
new file mode 100644
index 0000000..e910d4b
--- /dev/null
+++ b/blog/entry/battery_bank_refresh/comment_1_6e226a6849a21c3aa53ba2f29ada3c2d._comment
@@ -0,0 +1,32 @@
+[[!comment format=mdwn
+ username="jonatan@f5980658491f77bc917fbe2da469517bd38a9598"
+ nickname="jonatan"
+ subject="Battery bank wiring"
+ date="2016-10-06T09:21:05Z"
+ content="""
+A few recommendations from what I see there, the simplest change I would do to improve the (dis)charging of the batteries would be move one cable to the other side of the bank, like this:
+
+    +---- house 
+    |           
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +( 6v )-+( 6v )-
+    |              |
+    +(   new 12v  )-
+    |              |
+    +(   new 12v  )-
+                   -
+           house----
+
+That way the batteries \"further away\" will also get a decent charge. A good exercise is to calculate the wire length from plus to minus for all batteries. The topology above is not ideal, but usually quite enough. You should take care mixing old and new batteries, if you have a current clamp you can try monitoring the charging and see that all batteries are being utilized and no battery is being over charged.
+
+Check with a voltmeter that the 6V packs are balanced by measuring the midpoints. A temporary solution that can help if they are not is connecting all the midpoints with a thin (like 2 mm^2 or so) cable and letting them settle. If this doesn't help you may need to swap the pairs around to get them better matched
+
+Just a few suggestions to get started, hope it helps!
+"""]]

comment
diff --git a/blog/entry/battery_bank_refresh.mdwn b/blog/entry/battery_bank_refresh.mdwn
index 2d6af76..0ae1c3b 100644
--- a/blog/entry/battery_bank_refresh.mdwn
+++ b/blog/entry/battery_bank_refresh.mdwn
@@ -11,7 +11,7 @@ have a couple of good batteries amoung a dozen failing ones.
 The bank was set up like this:
 
 	+---- house ----
-        |              |
+	|              |
 	+( 6v )-+( 6v )-
 	|              |
 	+( 6v )-+( 6v )-
@@ -35,7 +35,7 @@ On a hunch, I then reconnected one bridge, like this -- and power was
 restored.
 
 	+---- house ----
-        |              |
+	|              |
 	+( 6v )-+( 6v )-
 	|              |
 	+( 6v )  ( 6v )-

blog
diff --git a/blog/entry/battery_bank_refresh.mdwn b/blog/entry/battery_bank_refresh.mdwn
new file mode 100644
index 0000000..2d6af76
--- /dev/null
+++ b/blog/entry/battery_bank_refresh.mdwn
@@ -0,0 +1,72 @@
+My house entered full power saving mode with fall. 
+Lantern light and all devices shutdown at bedtime.
+
+But, it felt early to need to do this. Comparing with my logbook for last
+year, the batteries were indeed doing much worse.
+
+I had added a couple of new batteries to the bank last winter, and they
+seemed to have helped at the time, although it's difficult to tell when you
+have a couple of good batteries amoung a dozen failing ones. 
+
+The bank was set up like this:
+
+	+---- house ----
+        |              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )-+( 6v )-
+	|              |
+	+(   new 12v  )-
+	|              |
+	+(   new 12v  )-
+
+Tried as an experiement disconnecting all the bridges between the old 6v
+battery pairs. I expected this would mean only the new 12v ones would be in
+the circuit, and so I could see how well they powered the house. Instead,
+making this change left the house without any power at all!
+
+On a hunch, I then reconnected one bridge, like this -- and power was
+restored.
+
+	+---- house ----
+        |              |
+	+( 6v )-+( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+( 6v )  ( 6v )-
+	|              |
+	+(   new 12v  )-
+	|              |
+	+(   new 12v  )-
+
+My best guess of what's going on is that the wires forming
+the positive and negative rails are not making good connections (due to
+corrosion, rust, broken wires etc), and so batteries further down are
+providing less and less power. The new 12v ones may not have been able
+to push power up to the house at all.
+
+(Or, perhaps having partially dead batteries hanging half-connected off the
+circuit has some effect that my meager electronics knowledge can't account
+for.)
+
+So got longer cables to connect the new batteries directly to the
+house, bypassing all the old stuff. That's working great -- house power
+never dropped below 11.9v last night, vs 11.1v the night before.
+
+The old battery bank might still be able to provide another day or so of
+power in a pinch, so I am going to keep them in there for now, but if
+I don't use them at all this winter I'll be recycling them. Astounding
+that those batteries were in use for [[20_years|getting_to_know_my_batteries]].
+
+[[!tag solar]]

add news item for keysafe 0.20160927
diff --git a/code/keysafe/news/version_0.20160927.mdwn b/code/keysafe/news/version_0.20160927.mdwn
new file mode 100644
index 0000000..1787aa5
--- /dev/null
+++ b/code/keysafe/news/version_0.20160927.mdwn
@@ -0,0 +1,20 @@
+keysafe 0.20160927 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Makefile: Avoid rebuilding on make install, so that sudo make install works.
+   * Added --chaff-max-delay option for slower chaffing.
+   * Fix embedded copy of Argon2 to not use Word64, fixing build on 32 bit
+     systems.
+   * Randomize the server list.
+   * Don't upload more than neededshares-1 shares to Alternate servers
+     without asking the user if they want to do this potentially dangerous
+     action.
+   * Added a second keysafe server to the server list. It's provided
+     by Marek Isalski at Faelix. Currently located in UK, but planned move
+     to CH. Currently at Alternate level until verification is complete.
+   * Server: --motd can be used to provide a Message Of The Day.
+   * Added --check-servers mode, which is useful both at the command line
+     to see what servers keysafe knows about, and as a cron job.
+   * Server: Round number of objects down to the nearest thousand, to avoid
+     leaking too much data about when objects are uploaded to servers.
+   * Filter out escape sequences and any other unusual characters when
+     writing all messages to the console."""]]
\ No newline at end of file

fix url
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 72d7e61..334df3b 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -143,7 +143,7 @@ source of disk IO.
 
 It's early days still, but keysafe's server code works well enough.
 
-* `git clone git://git.joeyh.name/code/keysafe`
+* `git clone git://git.joeyh.name/keysafe`
 * Be sure to verify the gpg signature of the git repository!
 * You will need to install keysafe from source; see its INSTALL file.
   Use `make install` to install it, including a systemd service file.

blog update
diff --git a/blog/entry/keysafe_beta_release.mdwn b/blog/entry/keysafe_beta_release.mdwn
new file mode 100644
index 0000000..b09deb2
--- /dev/null
+++ b/blog/entry/keysafe_beta_release.mdwn
@@ -0,0 +1,25 @@
+After a month of development, [[code/keysafe]] 0.20160922 is released, 
+and ready for beta testing. And it needs servers.
+
+With this release, the whole process of backing up and restoring a gpg
+secret key to keysafe servers is implemented. Keysafe is started at desktop
+login, and will notice when a gpg secret key has been created, and prompt
+to see if it should back it up.
+
+At this point, I recommend only using keysafe for lower-value secret keys,
+for several reasons:
+
+* There could be some bug that prevents keysafe from restoring a backup.
+* Keysafe's design has not been completely reviewed for security.
+* None of the keysafe servers available so far or planned to be deployed
+  soon meet all of the security requirements for a recommended keysafe server.
+  While server security is only the initial line of defense, it's still
+  important.
+
+Currently the only keysafe server is one that I'm running myself.
+Two more keysafe servers are needed for keysafe to really be usable,
+and I can't run those.
+
+If you're interested in running a keysafe server, read
+[[the_keysafe_server_requirements|code/keysafe/servers]]
+and get in touch.

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 579a55d..72d7e61 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -130,7 +130,9 @@ Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
 with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
 users, which is enough for a small keysafe server.
 
-The keysafe server uses very little memory and CPU.
+The keysafe server uses very little memory and CPU. It does rate limiting
+with client-side proof-of-work to prevent it being abused for
+general-purpose data storage.
 
 There is some disk IO overhead, because keysafe updates the mtime and ctime
 of all shards stored on the server, as frequently as every 30 minutes.
@@ -141,7 +143,7 @@ source of disk IO.
 
 It's early days still, but keysafe's server code works well enough.
 
-* git clone keysafe
+* `git clone git://git.joeyh.name/code/keysafe`
 * Be sure to verify the gpg signature of the git repository!
 * You will need to install keysafe from source; see its INSTALL file.
   Use `make install` to install it, including a systemd service file.
@@ -153,5 +155,5 @@ It's early days still, but keysafe's server code works well enough.
 * Once ready, email id@joeyh.name to get added to keysafe's server list.
 
 Here's a the [[code/propellor]] config for my own keysafe server:
-<http://source.propellor.branchable.com/?p=source.git;a=blob;f=joeyconfig.hs;h=fa37e97ba94eecf8f4cbe47d41fbc7c1cd89723b;hb=HEAD#l461>
+<http://source.propellor.branchable.com/?p=source.git;a=blob;f=joeyconfig.hs;h=15a00f7c2dffa15ed275fdd44e84e2edcc226559;hb=b9f87f0c08d94c5d43224a2c6bbacb332ebfc1b6#l460>
 --[[Joey]]

add news item for keysafe 0.20160922
diff --git a/code/keysafe/news/version_0.20160922.mdwn b/code/keysafe/news/version_0.20160922.mdwn
new file mode 100644
index 0000000..0cf5ac8
--- /dev/null
+++ b/code/keysafe/news/version_0.20160922.mdwn
@@ -0,0 +1,17 @@
+keysafe 0.20160922 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Keysafe now knows about 3 servers, although only 1 is currently in
+     operation. It will queue uploads to the other 2 servers until
+     they are added in a later keysafe release.
+   * Added --autostart mode, and make both keysafe --backup and
+     the Makefile install a FDO desktop autostart file to use it.
+   * In --autostart mode, retry any queued uploads.
+   * In --autostart mode, check for gpg keys that have not been
+     backed up, and offer to back them up. Only ask once per key.
+   * Changed format of ~/.keysafe/backup.log
+   * Server: Reduce number of buckets in rate limiter, avoiding ones with very low
+     proof of work.
+   * Server: Make rate limiter adapt to ongoing load more quickly -- every 15
+     minutes instead of every 60.
+   * Server: Added --backup-server and --restore-server to aid in backing
+     up keysafe servers with minimal information leakage."""]]
\ No newline at end of file

let's not mix
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 7c5c755..579a55d 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -80,10 +80,8 @@ lhmhvShr0WRqB8fWYPkc
 ### Alternate
 
 * Keysafe port only exposed via tor hidden service.
-* Dedicated to only running keysafe, no other services. (Other than ssh for
-  admin) (Since it's running tor, it's also ok to be a tor bridge, or
-  relay; this way unused bandwidth benefits the tor network. However, see
-  [here](https://trac.torproject.org/projects/tor/ticket/8742).)
+* Dedicated to only running keysafe, no other services. (Other than tor and 
+  ssh for admin)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

note
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index cff7c90..7c5c755 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -82,7 +82,8 @@ lhmhvShr0WRqB8fWYPkc
 * Keysafe port only exposed via tor hidden service.
 * Dedicated to only running keysafe, no other services. (Other than ssh for
   admin) (Since it's running tor, it's also ok to be a tor bridge, or
-  relay; this way unused bandwidth benefits the tor network.)
+  relay; this way unused bandwidth benefits the tor network. However, see
+  [here](https://trac.torproject.org/projects/tor/ticket/8742).)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index af743f2..cff7c90 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -100,17 +100,14 @@ lhmhvShr0WRqB8fWYPkc
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
-* Any backup does not record the whole history of the /var/lib/keysafe
-  directory. Doing so interferes with keysafe's obscuring of when shards
-  were stored on the server.
-
-  It may be useful to keep some old versions of /var/lib/keysafe so that
-  if files get accidentially deleted, they can be recovered. For example,
-  one version for each of the past 7 days, and past 4 weeks.
-  But bear in mind that this lets anyone who can access those backups
-  make guesses about what shares belong with other shares stored on other
-  servers in the same time period. See [[details]] for how that makes it 
-  somewhat easier for an attacker.
+* Any backup should take care to not leak information about what objects
+  were present on the server at multiple times in the past. That would 
+  let an attacker who can access the backups make guesses about shares
+  belong with other shares stored on other servers in the same time period.
+  See [[details]] for how that makes it somewhat easier for an attacker.
+
+  keysafe --backup-server can be used to generate encrypted files to back up,
+  in a way that is designed to avoid these problems.
 
 * Similarly, the filesystem and storage system should not allow rolling back
   to old snapshots.

more on incremental backups
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 6fdf95c..af743f2 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -100,9 +100,18 @@ lhmhvShr0WRqB8fWYPkc
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
-* Any backup is *not* incremental. Incremental backups interfere with
-  keysafe's obscuring of when shards were stored on the server, and can
-  be used in correlation attacks.
+* Any backup does not record the whole history of the /var/lib/keysafe
+  directory. Doing so interferes with keysafe's obscuring of when shards
+  were stored on the server.
+
+  It may be useful to keep some old versions of /var/lib/keysafe so that
+  if files get accidentially deleted, they can be recovered. For example,
+  one version for each of the past 7 days, and past 4 weeks.
+  But bear in mind that this lets anyone who can access those backups
+  make guesses about what shares belong with other shares stored on other
+  servers in the same time period. See [[details]] for how that makes it 
+  somewhat easier for an attacker.
+
 * Similarly, the filesystem and storage system should not allow rolling back
   to old snapshots.
 

allow servers to also run as tor bridges etc
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 554d893..6fdf95c 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -80,8 +80,9 @@ lhmhvShr0WRqB8fWYPkc
 ### Alternate
 
 * Keysafe port only exposed via tor hidden service.
-* Dedicated to only running keysafe, no other services (other than ssh for
-  admin)
+* Dedicated to only running keysafe, no other services. (Other than ssh for
+  admin) (Since it's running tor, it's also ok to be a tor bridge, or
+  relay; this way unused bandwidth benefits the tor network.)
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
 * Noone who has access to the server also has access to any Recommended

add news item for keysafe 0.20160914
diff --git a/code/keysafe/news/version_0.20160914.mdwn b/code/keysafe/news/version_0.20160914.mdwn
new file mode 100644
index 0000000..9b0dcd1
--- /dev/null
+++ b/code/keysafe/news/version_0.20160914.mdwn
@@ -0,0 +1,21 @@
+keysafe 0.20160914 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Fix bug that prevented keysafe --server from running when there was no
+     controlling terminal and zenity was not installed.
+   * Added --name and --othername options.
+   * Added proof of work to client/server protocol.
+   * Server-side rate limiting and DOS protection.
+   * server: Added --months-to-fill-half-disk option, defaulting to 12.
+   * Several new dependencies.
+   * Another fix to gpg secret key list parser.
+   * Warn when uploads fail and are put in the upload queue.
+   * Warn when --uploadqueued fails to upload to servers.
+   * Fix --uploadqueued bug that prevented deletion of local queued file.
+   * Added --chaff mode which uploads random junk to servers.
+     This is useful both to test the server throttling of uploads,
+     and to make it harder for servers to know if an object actually
+     contains secret key information.
+   * Store information about backed up keys in ~/.keysafe/backup.log
+     This can be deleted by the user at any time, but it's useful
+     in case a server is known to be compromised, or a problem is found
+     with keysafe's implementation that makes a backup insecure."""]]
\ No newline at end of file

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment b/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment
new file mode 100644
index 0000000..13ffc9e
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_7_266728691c8dc55601cdcf589a4afbd6._comment
@@ -0,0 +1,11 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 7"""
+ date="2016-09-14T01:14:15Z"
+ content="""
+Another bonus to using HMAC is that a large/distributed keysafe server cluster's
+nodes can all share the secret used to generate a request id, and then any
+node will accept a request id that was produced by any node. So that might
+be very useful in future scaling. Thanks for the help improving that part
+of this!
+"""]]

update
diff --git a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
index f3cbced..e25b393 100644
--- a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
+++ b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
@@ -5,4 +5,13 @@
  content="""
 SYN cookies rely on knowing the client's IP address. Keysafe, as a TOR hidden
 service, does not have such a means to distinguish clients.
+
+But, SYN cookie's use of a cryptographic hash makes me think of an HMAC.
+Could generate a request ID by `(hmac secret random, random)`. Then the
+server can verify incoming request IDs using the secret.
+
+That does seem to be simple enough to be worth implementing, to get rid of
+that first bloom filter. Thanks guys!
+
+"mac PoW bucket bloom"? :)
 """]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
new file mode 100644
index 0000000..f3cbced
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_6_5c7ef854b7164100cfa05df2a60ac862._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 6"""
+ date="2016-09-13T23:57:12Z"
+ content="""
+SYN cookies rely on knowing the client's IP address. Keysafe, as a TOR hidden
+service, does not have such a means to distinguish clients.
+"""]]

Added a comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment b/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment
new file mode 100644
index 0000000..8164abb
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_5_2d23a1fba91fedac5761196d26d7b211._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="mju"
+ subject="comment 5"
+ date="2016-09-13T23:23:48Z"
+ content="""
+Just a suggestion: Maybe something like the technique for syn cookies works better and faster than asymmetric cryptography.
+"""]]

update
diff --git a/blog/entry/PoW_bucket_bloom.mdwn b/blog/entry/PoW_bucket_bloom.mdwn
index 585dcb2..91b91fe 100644
--- a/blog/entry/PoW_bucket_bloom.mdwn
+++ b/blog/entry/PoW_bucket_bloom.mdwn
@@ -30,10 +30,12 @@ necessary. At the worst, a client may have to do 8-16 minutes of work to
 access a keysafe server that is under heavy load, which would not be ideal,
 but is acceptible for keysafe since it's not run very often.
 
-(If the client provides a PoW good enough to allow accessing the last token
+If the client provides a PoW good enough to allow accessing the last token
 bucket, the request will be accepted even when that bucket is drained. The
 client has done plenty of work at this point, so it would be annoying to
-reject it.)
+reject it. To prevent an attacker that is willing to burn CPU from abusing
+this loophole to flood the server with object stores, the server delays
+until the last token bucket fills back up.
 
 ----
 
@@ -81,7 +83,7 @@ will have plenty of time to complete its proof of work.
 This sounds complicated, and probably it is, but the implementation only
 took 333 lines of code. About the same number of lines that it took to
 implement the entire keysafe HTTP client and server using the amazing
-[servant](http://hackage.haskell.org/package/servant) library. 
+[servant](http://hackage.haskell.org/package/servant) library.
 
 There are a number of knobs that may need to be tuned to dial it in,
 including the size of the token buckets, their refill rate, the size of the
@@ -90,3 +92,10 @@ Servers may eventually need to adjust those on the fly, so that if someone
 decides it's worth burning large quantities of CPU to abuse keysafe for
 general data storage, the server throttles down to a rate that will take
 a very long time to fill up its disk.
+
+This protects against DOS attacks that fill up the keysafe server storage.
+It does not prevent a determined attacker, who has lots of CPU to burn,
+from flooding so many requests that legitimate clients are forced to do
+an expensive proof of work and then time out waiting for the server. But
+that's an expensive attack to keep running, and the proof of work can 
+be adjusted to make it increasingly expensive.

simplify
diff --git a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
index fc3ca90..b110b70 100644
--- a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
+++ b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
@@ -3,29 +3,5 @@
  subject="""comment 3"""
  date="2016-09-13T16:48:56Z"
  content="""
-Also, I found another use for the meta-token-bucket, as Josh calls it.
-
-Recall that, if a client provides a maximum size proof of work, it's always
-allowed to store data. This forgiveness of the last token bucket being
-drained is nice, but also problimatic.
-
-A determined attacker, who is willing to burn enough CPU (probably hundreds
-or thousands of CPUS) can flood in requests that all have maximum PoW. Such
-an attacker could pretty quickly fill up the keysafe server storage.
-That wouldn't be economical for data storage, but it would be economical to
-DOS keysafe.
-
-The meta-token-bucket though, can be tuned to guard against that.
-The keysafe server can delay generating request IDs when it's empty,
-and so throttle back such an attacker. The refill rate can be tuned
-to be such that such an attack can't store any more data than would be
-stored if keysafe didn't always accept maximum sized PoW.
-
-The meta-token-bucket can have a high burst size (tends to hundreds
-of thousands of tokens), and refill somewhat slowly (eg one token per
-minute) and so not cause any delays except for in such a DOS scenario.
-
-----
-
-(Oh yeah, asymetric crypto would be the way to go.)
+Oh yeah, asymetric crypto would be the way to go.
 """]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
deleted file mode 100644
index 9ff8c1e..0000000
--- a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
+++ /dev/null
@@ -1,25 +0,0 @@
-[[!comment format=mdwn
- username="joey"
- subject="""comment 3"""
- date="2016-09-13T16:48:56Z"
- content="""
-Also, I found another use for the meta-token-bucket, as Josh calls it.
-
-Recall that, if a client provides a maximum size proof of work, it's always
-allowed to store data. This forgiveness of the last token bucket being
-drained is "nice", but also problimatic.
-
-A determined attacker, who is willing to burn enough CPU (probably hundreds
-or thousands of CPUS) can flood in requests that all have maximum PoW. Such
-an attacker could pretty quickly fill up the keysafe server storage.
-
-The meta-token-bucket though, can be tuned to guard against that.
-The keysafe server can delay generating request IDs when it's empty,
-and so throttle back such an attacker. The refill rate can be tuned
-to be such that such an attack doesn't store any more data than would be
-stored if keysafe didn't always accept maximum sized PoW.
-
-The meta-token-bucket can have a high burst size (tends to hundreds
-of thousands of tokens), and refill somewhat slowly (eg one token per
-minute) and so not cause any delays except for in such a DOS scenario.
-"""]]
diff --git a/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
new file mode 100644
index 0000000..fc3ca90
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_4_c05ea3d9d10d17337c54227432377203._comment
@@ -0,0 +1,31 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2016-09-13T16:48:56Z"
+ content="""
+Also, I found another use for the meta-token-bucket, as Josh calls it.
+
+Recall that, if a client provides a maximum size proof of work, it's always
+allowed to store data. This forgiveness of the last token bucket being
+drained is nice, but also problimatic.
+
+A determined attacker, who is willing to burn enough CPU (probably hundreds
+or thousands of CPUS) can flood in requests that all have maximum PoW. Such
+an attacker could pretty quickly fill up the keysafe server storage.
+That wouldn't be economical for data storage, but it would be economical to
+DOS keysafe.
+
+The meta-token-bucket though, can be tuned to guard against that.
+The keysafe server can delay generating request IDs when it's empty,
+and so throttle back such an attacker. The refill rate can be tuned
+to be such that such an attack can't store any more data than would be
+stored if keysafe didn't always accept maximum sized PoW.
+
+The meta-token-bucket can have a high burst size (tends to hundreds
+of thousands of tokens), and refill somewhat slowly (eg one token per
+minute) and so not cause any delays except for in such a DOS scenario.
+
+----
+
+(Oh yeah, asymetric crypto would be the way to go.)
+"""]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
new file mode 100644
index 0000000..9ff8c1e
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_3_c05ea3d9d10d17337c54227432377203._comment
@@ -0,0 +1,25 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 3"""
+ date="2016-09-13T16:48:56Z"
+ content="""
+Also, I found another use for the meta-token-bucket, as Josh calls it.
+
+Recall that, if a client provides a maximum size proof of work, it's always
+allowed to store data. This forgiveness of the last token bucket being
+drained is "nice", but also problimatic.
+
+A determined attacker, who is willing to burn enough CPU (probably hundreds
+or thousands of CPUS) can flood in requests that all have maximum PoW. Such
+an attacker could pretty quickly fill up the keysafe server storage.
+
+The meta-token-bucket though, can be tuned to guard against that.
+The keysafe server can delay generating request IDs when it's empty,
+and so throttle back such an attacker. The refill rate can be tuned
+to be such that such an attack doesn't store any more data than would be
+stored if keysafe didn't always accept maximum sized PoW.
+
+The meta-token-bucket can have a high burst size (tends to hundreds
+of thousands of tokens), and refill somewhat slowly (eg one token per
+minute) and so not cause any delays except for in such a DOS scenario.
+"""]]

Added a comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment b/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment
new file mode 100644
index 0000000..c2370bb
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_3_610123f7b53662d2d9be2d24cf597477._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="comment 3"
+ date="2016-09-13T16:51:45Z"
+ content="""
+I was thinking of asymmetric crypto, but yeah, using additional crypto does mean much more careful analysis.
+"""]]

comment
diff --git a/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment b/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment
new file mode 100644
index 0000000..5220de0
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_2_b8c8bfe5e23ef4ea28460f7872ab1d4f._comment
@@ -0,0 +1,15 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2016-09-13T16:10:27Z"
+ content="""
+That is indeed a good idea Josh. If the bloom filter memory
+use ever comes to be a problem that would be a good way to at half it.
+
+It does add a fair bit of complexit. So many gotchas involved in
+using AES. Reusing an IV might allow key recovery attacks..
+
+The 64 mb or so that would be freed is probably going to be peanuts on the
+average keysafe server (even if it's a fairly low-spec arm box), since
+they're supposed to be bare-metal servers only running keysafe.
+"""]]

Added a comment: Signed tokens?
diff --git a/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment b/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment
new file mode 100644
index 0000000..000ee94
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom/comment_1_5b3479923bddc661d27a7c2482df9316._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="Signed tokens?"
+ date="2016-09-13T07:39:44Z"
+ content="""
+To avoid having to store not-yet-used request IDs even in a bloom filter, what about signing them using a server key, handing them to the client, and then throwing them away?  You can verify when you get the request ID back that it has a valid signature, so you've effectively let the client store it for you, indefinitely.
+
+You'd still need the mechanism to remember *used* request IDs to avoid reuse, but you wouldn't have to store unused request IDs, which reduces memory usage and potentially avoids the need for the meta-token-bucket for request IDs.
+"""]]

blog
diff --git a/blog/entry/PoW_bucket_bloom.mdwn b/blog/entry/PoW_bucket_bloom.mdwn
new file mode 100644
index 0000000..585dcb2
--- /dev/null
+++ b/blog/entry/PoW_bucket_bloom.mdwn
@@ -0,0 +1,92 @@
+[[!meta title="PoW bucket bloom: throttling anonymous clients with proof of work, token buckets, and bloom filters"]]
+
+An interesting side problem in [[code/keysafe]]'s design is that keysafe
+servers, which run as tor hidden services, allow anonymous data storage and
+retrieval. While each object is limited to 64 kb, what's to stop someone
+from making many requests and using it to store some big files?
+
+The last thing I want is a [[code/git-annex]] keysafe special remote. ;-)
+
+I've done a mash-up of three technologies to solve this,
+that I think is perhaps somewhat novel. Although it could be entirely old
+hat, or even entirely broken. (All I know so far is that the code
+compiles.) It uses proof of work, token buckets, and bloom filters.
+
+----
+
+Each request can have a proof of work attached to it, which is just a value
+that, when hashed with a salt, starts with a certain number of 0's.
+The salt includes the ID of the object being stored or retrieved.
+
+The server maintains a list of token buckets. The first can be accessed
+without any proof of work, and subsequent ones need progressively more
+proof of work to be accessed.
+
+Clients will start by making a request without a PoW, and that will often
+succeed, but when the first token bucket is being drained too fast by other
+load, the server will reject the request and demand enough proof of work
+to allow access to the second token bucket. And so on down the line if
+necessary. At the worst, a client may have to do 8-16 minutes of work to
+access a keysafe server that is under heavy load, which would not be ideal,
+but is acceptible for keysafe since it's not run very often.
+
+(If the client provides a PoW good enough to allow accessing the last token
+bucket, the request will be accepted even when that bucket is drained. The
+client has done plenty of work at this point, so it would be annoying to
+reject it.)
+
+----
+
+So far so simple really, but this has a big problem: What prevents a proof
+of work from being reused? An attacker could generate a single PoW good
+enough to access all the token buckets, and flood the server with requests
+using it, and so force everyone else to do excessive amounts of work to use
+the server.
+
+Guarding against that DOS is where the bloom filters come in. The server
+generates a random request ID, which has to be included in the PoW salt and
+sent back by the client along with the PoW. The request ID is added to a
+bloom filter, which the server can use to check if the client is providing
+a request ID that it knows about. And a second bloom filter is used to
+check if a request ID has been used by a client before, which prevents the
+DOS.
+
+Of course, when dealing with bloom filters, it's important to consider what
+happens when there's a rare false positive match. This is not a problem with
+the first bloom filter, because a false positive only lets some made-up
+request ID be used. A false positive in the second bloom filter will cause
+the server to reject the client's proof of work. But the server can just
+request more work, or send a new request ID, and the client will follow
+along.
+
+The other gotcha with bloom filters is that filling them up too far
+sets too many bits, and so false positive rates go up. To deal with this,
+keysafe just keeps count of how many request IDs it has generated, and once
+it gets to be too many to fit in a bloom filter, it makes a new, empty
+bloom filter and starts storing request IDs in it. The old bloom filter is
+still checked too, providing a grace period for old request IDs to be used.
+Using bloom filters that occupy around 32 mb of RAM, this rotation
+only has to be done every million requests of so.
+
+But, that rotation opens up another DOS! An attacker could cause lots of
+request IDs to be generated, and so force the server to rotate its bloom
+filters too quickly, which would prevent any requests from being accepted.
+To solve this DOS, just use one more token bucket, to limit the rate
+that request IDs can be generated, so that the time it would take an
+attacker to force a bloom filter rotation is long enough that any client
+will have plenty of time to complete its proof of work.
+
+----
+
+This sounds complicated, and probably it is, but the implementation only
+took 333 lines of code. About the same number of lines that it took to
+implement the entire keysafe HTTP client and server using the amazing
+[servant](http://hackage.haskell.org/package/servant) library. 
+
+There are a number of knobs that may need to be tuned to dial it in,
+including the size of the token buckets, their refill rate, the size of the
+bloom filters, and the number of argon2 iterations in the proof of work.
+Servers may eventually need to adjust those on the fly, so that if someone
+decides it's worth burning large quantities of CPU to abuse keysafe for
+general data storage, the server throttles down to a rate that will take
+a very long time to fill up its disk.

better DOS protection with bloom filters
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index aafc9b2..4b18e32 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -197,18 +197,15 @@ DOS attacks.
 
 Assuming that the client communicates with the server over http:
 
-	PUT /keysafe/objects/N?S
-	GET /keysafe/objects/N?S
+	PUT /keysafe/objects/N
+	GET /keysafe/objects/N
 
 The server's response can be either the result of the request,
 or a proof of work requirement, which specifies the difficulty D 
-(number of 0's needed), random value R, and the number of argon2
-iterations. The client provides the proof of work in S, which is a 
-string such that argon2(N,S+R) starts with a given number of 0's.
-
-The random value R is picked when the server starts up, and may be changed
-from time to time. It prevents a client from reusing proofs of work 
-between servers, and is also useful to mitigate DOS attacks.
+(number of 0's needed), random salt RS, and the number of argon2
+iterations. The client provides the proof of work in a query parameter,
+which is a string S such that argon2(N,S+RS) starts with a given number
+of 0's.
 
 (The server should only be able to control the number of iterations,
 not other argon2 parameters, to avoid forcing the client to use too much
@@ -230,18 +227,18 @@ token every minute, then the maximum allowed throughput is 4 requests
 per minute. If calculating the proof of work takes 2^D seconds on average, 
 then it will take on average 16 minutes work to access B4.
 
-Since this scheme is stateless, it lets an attacker do work once for a
-given N and then flood the server with repeated requests for N?S, reusing the
-proof of work. This is a DOS because the attacker can keep all the token
-buckets drained and so not let legitimate requests through. But, the server
-can detect when this DOS is occurring (when a proof of work allows
-accessing the last token bucket, and the bucket is empty), and pick a new R
-(and also perhaps increase the number of argon2 iterations to make the PoW
-a little bit harder). This invalidates the attacker's cached proof of work,
-and gives other clients a chance to get some requests through while the
-attacker is generating new proofs of work for the new R. Another defense
-against this attack is for the server to keep a small cache of recent N's
-(expiring after an hour) and reject repeated requests for them.
+The server can generate a different RS for each request, and can
+insert them into a bloom filter to keep track of ones it has given out.
+Bloom filter false positives are not a problem because they are quite
+rare and so it is not efficient for a client to make up RS in hope that
+there will be a false positive.
+
+To guard against DOS attacks that reuse proofs of work, the server can
+maintain a second bloom filter, putting RS into it once it's used, and
+rejecting attempts that reuse a RS. Since the bloom filter will
+(with a low probability) yield a false positive, the server should reject
+an attempt by generating a new RS' and requesting a new proof of work from
+the client.
 
 ## Avoiding correlations
 

better PoW design
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 925c16d..aafc9b2 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -18,7 +18,7 @@
 * Servers reject attempts to store an object under a name that is
   already in use.
 * Servers do not allow enumerating all objects stored,
-  and require a proof of work client puzzle to handle any request.
+  and require a proof of work to handle any request.
 * Upload S1-S3 to separate servers under the names N1-N3.
   If any of the uploads is rejected as name already in use, 
   ask user to enter a different name or password.
@@ -72,7 +72,7 @@ choose a strong password. A name that attackers are unlikely to guess
 prevents this attack, which is why keysafe prompts for not only the
 user's name, but also a more obscure name. Each name guess that the
 attacker makes takes 10 minutes of CPU time to generate N, as well
-as whatever work the servers impose to solve their client puzzle.
+as whatever proof of work the servers require.
 
 The sharding prevents a single malicious server from blindly 
 guessing weak passwords across its entire collection of objects.
@@ -147,13 +147,15 @@ in gpg to compromise the user's system.
 There's a server list shipped with the client, giving their tor onion address
 and the organization providing the server. 
 
-Three of the servers in the list are designated default servers.
+Three of the servers in the list are recommended servers.
 Shards are stored on these unless overridden by other configuration.
 
-When recovering a key, the client tries the default servers first. But, if
-it fails to recover the key using those, it goes on to try other servers on
-the list. This way we don't need to remember which servers the shards were
-stored on, and can change the default servers when necessary.
+When recovering a key, the client tries the recommended servers first. But,
+if it fails to recover the key using those, it goes on to try other servers
+on the list. This way we don't need to remember which servers the shards
+were stored on, and can change the recommended servers when necessary.
+
+See [[servers]] for more on the server list.
 
 ## Servers
 
@@ -183,38 +185,63 @@ Objects shoud be padded to a fixed size before they are encrypted, to
 prevent attackers from correlating and targeting particular objects based
 on size.
 
-## Client puzzles
+## client-server Proof of Work
+
+The Proof of Work prevents servers being flooded with requests.
+This is particularly important to prevent misuse of keysafe servers
+to store large data on them. It's also somewhat useful to prevent attackers
+guessing the name someone used to store a key; but the cost of generating
+N from a name makes the server's proof of work only a secondary line of
+defense against such an attack. Finally, PoW is useful to protect against
+DOS attacks.
 
 Assuming that the client communicates with the server over http:
 
 	PUT /keysafe/objects/N?S
 	GET /keysafe/objects/N?S
 
-Then, the S can be required to be a string such that argon2(N,S)
-starts with a given number of 0's. This allows the server to verify the
-client's proof of work without maintaining any state.
-
-The required number of 0's can be queried:
-
-	GET /keysafe/proofofwork/
+The server's response can be either the result of the request,
+or a proof of work requirement, which specifies the difficulty D 
+(number of 0's needed), random value R, and the number of argon2
+iterations. The client provides the proof of work in S, which is a 
+string such that argon2(N,S+R) starts with a given number of 0's.
 
-With a response like "zeros=4 iterations=1".
+The random value R is picked when the server starts up, and may be changed
+from time to time. It prevents a client from reusing proofs of work 
+between servers, and is also useful to mitigate DOS attacks.
 
 (The server should only be able to control the number of iterations,
 not other argon2 parameters, to avoid forcing the client to use too much
 memory. Normally, the server will keep iterations small, probably 1,
-since it does need to calculate the argon2 hash itself.)
-
-Note that this scheme lets a client do work once for a given N and then
-request that N from multiple servers, as long as they have similar zeros=
-parameters (and the same iterations= parameters). This is probably a good
-thing; it means that keysafe doesn't need to do extra work when checking
-servers to get a shard.
-
-Servers can change their proof of work parameters as needed, but that can
-cause a client that was connected to the server to generate a bad POW.
-The server can respond with 402 Payment Required in that case, so the
-client knows to retry.
+since it does need to calculate the argon2 hash once itself.)
+
+The server can use a [token bucket](https://en.wikipedia.org/wiki/Token_bucket)
+to throttle requests to a given rate. In fact, there can be a whole
+series of token buckets B0,B1.., for increasing difficulty proofs of work.
+
+A request without a proof of work is checked in B0. If that bucket is empty,
+the server responds with a proof of work requirement D=1, and
+the client makes a new request whose proof of work allows access to B1.
+If the server is under load, B1 might also be empty, and so the client 
+will have to try again with D=2 to access B2, and so on.
+
+If there are 4 buckets, and each bucket refills at the rate of a
+token every minute, then the maximum allowed throughput is 4 requests
+per minute. If calculating the proof of work takes 2^D seconds on average, 
+then it will take on average 16 minutes work to access B4.
+
+Since this scheme is stateless, it lets an attacker do work once for a
+given N and then flood the server with repeated requests for N?S, reusing the
+proof of work. This is a DOS because the attacker can keep all the token
+buckets drained and so not let legitimate requests through. But, the server
+can detect when this DOS is occurring (when a proof of work allows
+accessing the last token bucket, and the bucket is empty), and pick a new R
+(and also perhaps increase the number of argon2 iterations to make the PoW
+a little bit harder). This invalidates the attacker's cached proof of work,
+and gives other clients a chance to get some requests through while the
+attacker is generating new proofs of work for the new R. Another defense
+against this attack is for the server to keep a small cache of recent N's
+(expiring after an hour) and reject repeated requests for them.
 
 ## Avoiding correlations
 

teleconsole is yet another option
diff --git a/code/debug-me/discussion.mdwn b/code/debug-me/discussion.mdwn
index 8027f1a..ab5c469 100644
--- a/code/debug-me/discussion.mdwn
+++ b/code/debug-me/discussion.mdwn
@@ -10,6 +10,7 @@ Some similar projects you may be interested in looking at, if only for "how not
 * [Mosh][] - the mobile shell, interesting concepts of local terminal emulation and predictive capabilities
 * [Monkeysphere][] - OpenPGP web of trust applied to SSH and HTTP servers and clients
 * [watch-my-terminal][] - Allows a remote users to watch your terminal session via any modern browser (script+node on the broadcaster side, javascript on the watchers' side). Terminal emulation is quite good; it correctly renders vim, less and aptitude.
+* [teleconsole][] - can share terminal sessions through SSH or the browser through a SSH proxy
 
 [Gitso]: https://code.google.com/archive/p/gitso/
 [more recent fork]: https://github.com/AustP/Gitso
@@ -19,5 +20,6 @@ Some similar projects you may be interested in looking at, if only for "how not
 [Mosh]: https://mosh.mit.edu/
 [Monkeysphere]: http://web.monkeysphere.info
 [watch-my-terminal]: https://jasonwoof.com/gitweb/?p=watch-my-terminal.git;a=tree
+[teleconsole]: https://github.com/gravitational/teleconsole
 
 It would seem to me preferable to reuse existing components (SSH, especially) instead of reinventing the wheel too much here. So much trouble with terminal emulation and so on, as I am sure you know...

comment
diff --git a/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment b/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment
new file mode 100644
index 0000000..cbd66d5
--- /dev/null
+++ b/blog/entry/hiking_the_Roan/comment_2_4e7a05cd8a2fb55ec0122da231908be1._comment
@@ -0,0 +1,10 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2016-09-08T15:17:54Z"
+ content="""
+I actually did that hike with my laptop in my pack because I
+needed it on the larger trip for other reasons and did not want to
+leave it unattended in my car overnight. Even with trash bags to protect
+from moisture, that was very suboptimal, do not recommend.
+"""]]

note GLU/CPU comparison
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 578b5b6..4512be7 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -44,6 +44,10 @@ Compare these numbers with the cost to crack keysafe passwords
 * Weak password (30 entropy): 51072 CPU-years 
 * Super-weak password (19 entropy): 25 CPU-years 
 
+(Note that is a comparison between GPU years and CPU years; SHA-1 used by
+gpg can easily be run fast on GPUs, while keysafe uses argon2 which is
+designed to be GPU-resistent.)
+
 Big difference! Indeed, the design of gpg prevents a really expensive hash
 being used to protect against passphrase cracking, because it would slow down
 day-to-day use of gpg. Keysafe can make cracking the password much more

Added a comment: question
diff --git a/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment b/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment
new file mode 100644
index 0000000..461ef89
--- /dev/null
+++ b/blog/entry/hiking_the_Roan/comment_1_db91f5e569a74a87cff0a42b7d656906._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="jmz@2d336904dde22d29d81d9ae1644d7e9db6613317"
+ nickname="jmz"
+ subject="question"
+ date="2016-09-08T01:20:39Z"
+ content="""
+Do you take a laptop or anything while you camp? PocketChip? Or just a digital camera? Just curious, I've taken a cheap laptop once.
+"""]]

corrections
thanks, kwadronaut
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 098a017..578b5b6 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -10,7 +10,7 @@ theft, raids, and compromised printers. Gold standard.
 Using keysafe is analagous to storing the paperkey printout in a safety
 deposit box at a bank, and using a really really strong gpg passphrase.
 Since we don't trust a single bank (server), we shred the printout and
-evenly distribute the shreds amoung several banks. While the banks know the
+evenly distribute the shreds among several banks. While the banks know the
 safety deposit boxes belong to you and could put the shreds back together,
 a keysafe server has very little identifying information to go on (it only
 knows when you made the deposit).
@@ -19,10 +19,10 @@ knows when you made the deposit).
 
 So, you rely on your gpg passphrase for security.
 
-Gpg uses between 1024 (the default) and 65011712 rounds of SHA-1 hashing of
-the passphrase. In 2012, a GPU could calculate 2 billion SHA-1 hashes
-per second, so this is not much of an impediment to password cracking at
-all.
+Gpg uses between 1024 and 65011712 rounds of SHA-1 hashing of
+the passphrase, with the default probably being 65536. 
+In 2012, a GPU could calculate 2 billion SHA-1 hashes per second,
+so this is not much of an impediment to password cracking at all.
 
 Assuming 100 gpg passphrases can be tried per second, and gpg is
 configured to use the maximum rounds (which it normally is NOT):
@@ -55,7 +55,7 @@ Not recommended. Use a brain wallet.
 
 Keysafe might be more secure than a paper wallet in some situations.
 It's happened before that someone has stumbled over someone else's
-list of electrum words amoung their papers. Using keysafe avoids such
+list of electrum words among their papers. Using keysafe avoids such
 scenarios.
 
 #### How is keysafe different from other systems for private key backup/sync?

foo
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 75f59de..098a017 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -60,7 +60,8 @@ scenarios.
 
 #### How is keysafe different from other systems for private key backup/sync?
 
-Here are some similar systems:
+Here are some similar systems, and intial impressions (which may be
+inaccurate; corrections welcomed):
 
 * [Whiteout](https://blog.whiteout.io/2014/07/07/secure-pgp-key-sync-a-proposal/)
   uses a 24 letter code to encrypt the secret key. This has to be written

improve
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 1e33e4e..75f59de 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -58,7 +58,7 @@ It's happened before that someone has stumbled over someone else's
 list of electrum words amoung their papers. Using keysafe avoids such
 scenarios.
 
-#### Hw is keysafe different from other systems for private key backup/sync?
+#### How is keysafe different from other systems for private key backup/sync?
 
 Here are some similar systems:
 
@@ -75,7 +75,7 @@ Here are some similar systems:
   rate-limit logins and so avoid password cracking (except by the server).
   (This idea is worth keysafe stealing!)
 * [LEAP](https://leap.se/en/docs/tech/hard-problems#availability-problem)'s
-  [Soledad](https://leap.se/soledad) uses a large storage secret to encrypt
+  [Soledad](https://leap.se/soledad) uses a large secret to encrypt
   private keys. This can be stored in a recovery document in a recovery
   database, which anyone can make requests from. To prevent attacks,
   the recovery database delays responses, and a recovery code is needed

ideas
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 4fd7fea..925c16d 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -296,3 +296,46 @@ Note that the argon2 hash parameters to vary between versions should not be
 merely the number of rounds, as that would allow an attacker to hash for
 each version's number of rounds in one pass. Instead, vary the hash
 memory parameter.
+
+## Ideas
+
+Some ideas for improvements to keysafe.
+
+### Assisted Password-based Key Derivation
+
+An idea from [Nigori](http://www.links.org/files/nigori/nigori-protocol-01.html#anchor15):
+
+If the user has an account at some server, the server can contribute part
+of the data used to generate the key encryption key K. So not only is the
+user's keysafe password needed for key recovery, but the user has to
+authenticate to the server. As well as adding entropy to K, the server 
+can do rate limiting to prevent password guessing.
+
+Risks include:
+
+* The server becomes a target to be compromised.
+* If the server goes down, the user loses the ability to recover their gpg
+  key from keysafe.
+
+### Entangled objects
+
+An idea from Anthony Towns:
+
+Two or more objects stored on a keysafe server can be entangled.
+When one of them is requested, the server should delete the others.
+
+This could be used in several ways:
+
+* Keysafe could upload random objects entangled with a key's object,
+  and keep local records of the names of the random objects. Then if the
+  user wants to stop storing a key on keysafe servers, keysafe can request
+  the entangled objects to (hopefully) delete the real objects from the
+  server.
+* Keysafe could pick or prompt for some tripwire names that an attacker
+  might try if they were looking for a user's data. Then an attacker
+  risks deleting the data stored on the server. Although this also has 
+  DOS potential.
+* The user could pick a real name and fake name and keysafe uploads
+  objects for both. If the user is being forced to give up their keysafe
+  name and password, they could provide the fake name, and if it were
+  used, their data would get deleted from the keysafe servers.

reviewed some similar systems
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 21387eb..1e33e4e 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -57,3 +57,27 @@ Keysafe might be more secure than a paper wallet in some situations.
 It's happened before that someone has stumbled over someone else's
 list of electrum words amoung their papers. Using keysafe avoids such
 scenarios.
+
+#### Hw is keysafe different from other systems for private key backup/sync?
+
+Here are some similar systems:
+
+* [Whiteout](https://blog.whiteout.io/2014/07/07/secure-pgp-key-sync-a-proposal/)
+  uses a 24 letter code to encrypt the secret key. This has to be written
+  down to back it up. Since it is high-entropy (256 bits), the encryption
+  can be fast, and so it can be used to sync private keys between devices.
+* [Nigori](http://www.links.org/files/nigori/nigori-protocol-01.html)
+  uses a password to encrypt and SSS to split the private key.
+  Its main protection against password guessing seems be to be
+  its "Assisted Password-based Key Derivation", where some separate server
+  that the user has an account at supplies part of the encryption key after
+  the user has authenticated at the server. This allows the server to
+  rate-limit logins and so avoid password cracking (except by the server).
+  (This idea is worth keysafe stealing!)
+* [LEAP](https://leap.se/en/docs/tech/hard-problems#availability-problem)'s
+  [Soledad](https://leap.se/soledad) uses a large storage secret to encrypt
+  private keys. This can be stored in a recovery document in a recovery
+  database, which anyone can make requests from. To prevent attacks,
+  the recovery database delays responses, and a recovery code is needed
+  to access a document. The recovery code is a 16 character code that the
+  user has to write down.

foo
diff --git a/code/scroll.mdwn b/code/scroll.mdwn
index 9741937..fa21794 100644
--- a/code/scroll.mdwn
+++ b/code/scroll.mdwn
@@ -77,3 +77,5 @@ Many thanks to all the reviewers! --[[Joey]]
 ## coda
 
 [[game_designer_thoughts|scroll/thoughts]]
+
+	<paroneayea> through a rogue lens, all texts are adventures.

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 3c1e726..554d893 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -102,6 +102,8 @@ lhmhvShr0WRqB8fWYPkc
 * Any backup is *not* incremental. Incremental backups interfere with
   keysafe's obscuring of when shards were stored on the server, and can
   be used in correlation attacks.
+* Similarly, the filesystem and storage system should not allow rolling back
+  to old snapshots.
 
 ### Recommended
 

more
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 80a8d99..3c1e726 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -99,6 +99,9 @@ lhmhvShr0WRqB8fWYPkc
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
+* Any backup is *not* incremental. Incremental backups interfere with
+  keysafe's obscuring of when shards were stored on the server, and can
+  be used in correlation attacks.
 
 ### Recommended
 
@@ -113,12 +116,19 @@ lhmhvShr0WRqB8fWYPkc
 * The keysafe data store and any swap partitions are encrypted,
   and have to be manually unlocked when the server is booted.
 
-## Disk space use
+## Server scaling
 
 Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
 with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
 users, which is enough for a small keysafe server.
 
+The keysafe server uses very little memory and CPU.
+
+There is some disk IO overhead, because keysafe updates the mtime and ctime
+of all shards stored on the server, as frequently as every 30 minutes.
+Once a large number of shards are stored, this could become a significant
+source of disk IO.
+
 ## Server setup
 
 It's early days still, but keysafe's server code works well enough.

link
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 5ce512f..80a8d99 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -134,6 +134,6 @@ It's early days still, but keysafe's server code works well enough.
   Required.
 * Once ready, email id@joeyh.name to get added to keysafe's server list.
 
-A [[code/propellor]] config for a keysafe server is in propellor's
-joeyconfig.hs file, and shows how I set up my own keysafe server.
+Here's a the [[code/propellor]] config for my own keysafe server:
+<http://source.propellor.branchable.com/?p=source.git;a=blob;f=joeyconfig.hs;h=fa37e97ba94eecf8f4cbe47d41fbc7c1cd89723b;hb=HEAD#l461>
 --[[Joey]]

clarify
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index fc3c2fa..5ce512f 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -89,7 +89,7 @@ lhmhvShr0WRqB8fWYPkc
 * Commitment to either keep the server running long-term (ie, 10+ years),
   or transition the data to a replacement server that meets these
   requirements and that must not contain any related shards.
-* No open ports (other than ssh).
+* No other open ports (other than ssh).
 * Ssh authentication only by ssh key, not password.
 * Either off-server backup, or replication of shards to additional disks.
   (rsync to additional local disks would work perfectly well and avoids

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 9772e58..fc3c2fa 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -109,7 +109,7 @@ lhmhvShr0WRqB8fWYPkc
 * Warrant canary.
 * Hardware is hosted in-house. A VM at a cloud provider is right out
   because the provider could be made to give access to it without the
-  server operator knowing about it.
+  server operator knowing about it. Which would bypass the warrant canary.
 * The keysafe data store and any swap partitions are encrypted,
   and have to be manually unlocked when the server is booted.
 

server setup
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 4a77016..9772e58 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -118,3 +118,22 @@ lhmhvShr0WRqB8fWYPkc
 Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
 with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
 users, which is enough for a small keysafe server.
+
+## Server setup
+
+It's early days still, but keysafe's server code works well enough.
+
+* git clone keysafe
+* Be sure to verify the gpg signature of the git repository!
+* You will need to install keysafe from source; see its INSTALL file.
+  Use `make install` to install it, including a systemd service file.
+* `systemctl enable keysafe.service`
+* Install tor and set up a tor hidden service. Keysafe listens on port 4242
+  by default, so use that port.
+* Configure the server to meet all the requirements for Alternate or
+  Required.
+* Once ready, email id@joeyh.name to get added to keysafe's server list.
+
+A [[code/propellor]] config for a keysafe server is in propellor's
+joeyconfig.hs file, and shows how I set up my own keysafe server.
+--[[Joey]]

tweaks
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 39172f5..4a77016 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -4,7 +4,7 @@ keysafe server.
 
 ## Server categories
 
-Keysafe's server list puts servers in four categories:
+Keysafe's server list puts servers in three categories:
 
 1. **Recommended**: Servers that meet all best practices for security and
    are run by a well-known, trusted entity.
@@ -22,13 +22,7 @@ Keysafe's server list puts servers in four categories:
    store 1 share on an Alternate server, and the other 2 shares on two
    Recommended servers.
 
-3. **Readonly**: Servers that are secured to at least Alternate level of
-   security, but are not accepting new uploads.
-
-   This can be used when a server runs out of disk space, or otherwise
-   should not be used to store new keys.
-
-4. **Untrusted**: Servers that are not secured well or are run by an untrusted
+3. **Untrusted**: Servers that are not secured well or are run by an untrusted
    entity.
    
    Keysafe will never store data on Untrusted servers. 
@@ -37,7 +31,7 @@ Keysafe's server list puts servers in four categories:
    keysafe will warn the user about this problem.
    
    The only time keysafe will use untrusted servers is if it's restoring a
-   key, and cannot find enough shares on Recommended/Alternate/Readonly
+   key, and cannot find enough shares on Recommended/Alternate
    servers, and has to fall back to downloading from an Untrusted server.
 
 ## Server list
@@ -88,40 +82,39 @@ lhmhvShr0WRqB8fWYPkc
 * Keysafe port only exposed via tor hidden service.
 * Dedicated to only running keysafe, no other services (other than ssh for
   admin)
-* Run by a well known and trustworthy entity.
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
+* Noone who has access to the server also has access to any Recommended
+  server.
 * Commitment to either keep the server running long-term (ie, 10+ years),
   or transition the data to a replacement server that meets these
   requirements and that must not contain any related shards.
-* No other recommended server in keysafe's server list is run by the same
-  entity, or administered by the same people.
 * No open ports (other than ssh).
 * Ssh authentication only by ssh key, not password.
-* Either off-site backup, or replication of shards to additional disks.
-  (rsync to additional local disk would work perfectly well and avoids
+* Either off-server backup, or replication of shards to additional disks.
+  (rsync to additional local disks would work perfectly well and avoids
   the complications of RAID)
-* Any off-server backup is encrypted, and there's a well-defined procedure for
-  how the backup works and where it's stored.  
+* Any off-server backup is strongly encrypted.
   (There's a trade-off here; any backup widens the attack surface.
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
-* Enough disk space for a reasonable number of users to store keys.
-  Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
-  with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
-  users, which is probably enough to start with.
-
-### Readonly
-
-* Same as Alternate except for disk space requirements.
 
 ### Recommended
 
 * Everything in Alternate, to start with.
+* Run by a well known and trustworthy entity.
+* Noone who has access to the server also has access to any other
+  Recommended or Alternate server.
 * Warrant canary.
 * Hardware is hosted in-house. A VM at a cloud provider is right out
   because the provider could be made to give access to it without the
   server operator knowing about it.
 * The keysafe data store and any swap partitions are encrypted,
   and have to be manually unlocked when the server is booted.
+
+## Disk space use
+
+Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
+with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
+users, which is enough for a small keysafe server.

add news item for keysafe 0.20160831
diff --git a/code/keysafe/news/version_0.20160831.mdwn b/code/keysafe/news/version_0.20160831.mdwn
new file mode 100644
index 0000000..7331f21
--- /dev/null
+++ b/code/keysafe/news/version_0.20160831.mdwn
@@ -0,0 +1,16 @@
+keysafe 0.20160831 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Server implementation is ready for initial deployment.
+   * Keysafe as a client is not yet ready for production use.
+   * Removed embedded copy of secret-sharing library, since finite-field
+     only supports prime fields. This caused shares to be twice the size of
+     the input value.
+   * Reduced chunk size to 32kb due to share size doubling.
+   * Fix gpg secret key list parser to support gpg 2.
+   * Tuned argon2 hash parameters on better hardware than my fanless laptop.
+   * Improve time estimates, taking into account the number of cores.
+   * Added basic test suite.
+   * Added options: --store-directory --test --port --address
+   * Added a Makefile
+   * Added a systemd service file.
+   * Added a desktop file."""]]
\ No newline at end of file

also
diff --git a/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment b/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment
index 807bd47..bd2fd13 100644
--- a/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment
+++ b/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment
@@ -21,4 +21,8 @@ need to run 4 threads, and those should run on 4 cpus. This is factored
 into the benchmark; if the system has at least 4 cores, it expects the
 benchmark to run in 1/4th the time it would on an equivilant single core
 system.)
+
+Oh, one other thing: It would probably be good to build argon2 from source
+on the system being benchmarked. It has at least some CPU-specific
+optimisations that are disabled in the debian build for portability.
 """]]

comment
diff --git a/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment b/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment
new file mode 100644
index 0000000..807bd47
--- /dev/null
+++ b/blog/entry/keysafe_alpha_release/comment_2_778223273bd6d260a9392ca29f6df573._comment
@@ -0,0 +1,24 @@
+[[!comment format=mdwn
+ username="joey"
+ subject="""comment 2"""
+ date="2016-08-31T22:06:36Z"
+ content="""
+I am very interested in benchmark results from your 72-way system,
+especially if it has very fast CPUs. But, be sure to install keysafe from
+git and not this alpha release, as the hashes being benchmarked have
+changed and the benchmark improved.
+
+The reason the benchmark does not parallelize is because we want to
+learn how long it takes to run the operation on a single CPU core.
+
+From there we can estimate that a N core machine can perform N concurrent
+operations in the same amount of time (or somewhat longer;
+hyperthreading overheads & etc), and use that in calculating
+the expected brute-force attack cost.
+
+(Actually, it should parallelize slightly, because argon2 is configured to
+need to run 4 threads, and those should run on 4 cpus. This is factored
+into the benchmark; if the system has at least 4 cores, it expects the
+benchmark to run in 1/4th the time it would on an equivilant single core
+system.)
+"""]]

keysafe servers
diff --git a/code/keysafe.mdwn b/code/keysafe.mdwn
index 7e8bfd1..d27bfbf 100644
--- a/code/keysafe.mdwn
+++ b/code/keysafe.mdwn
@@ -68,6 +68,10 @@ Note that there is a manpage, but stack doesn't install it yet.
 
 Email <id@joeyh.name>
 
+## Servers
+
+See [[servers]] for information on the keysafe servers.
+
 ## License
 
 Keysafe is licensed under the terms of the AGPL 3+
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 34d4351..39172f5 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -1,8 +1,89 @@
-There are currently no keysafe servers. We need at least 3 for keysafe to
-work. Please contact <id@joeyh.name> if you would like to run a keysafe server.
+There are currently not enough keysafe servers. We need at least 3 for
+keysafe to work. Please contact <id@joeyh.name> if you would like to run a
+keysafe server.
 
-Requirements for a server to be included in keysafe's server list as a
-recommended server:
+## Server categories
+
+Keysafe's server list puts servers in four categories:
+
+1. **Recommended**: Servers that meet all best practices for security and
+   are run by a well-known, trusted entity.
+
+   Keysafe prefers to store data only on Recommended servers when possible.
+
+2. **Alternate**: Servers that are not secured well enough to be
+   Recommended.
+
+   Keysafe will store data on Alternate servers if it has to, but will
+   avoid storing enough data to allow the key to be recovered using only
+   the data stored on Alternate servers.
+
+   For example, with 2 of 3 shares needed to restore a key, keysafe can
+   store 1 share on an Alternate server, and the other 2 shares on two
+   Recommended servers.
+
+3. **Readonly**: Servers that are secured to at least Alternate level of
+   security, but are not accepting new uploads.
+
+   This can be used when a server runs out of disk space, or otherwise
+   should not be used to store new keys.
+
+4. **Untrusted**: Servers that are not secured well or are run by an untrusted
+   entity.
+   
+   Keysafe will never store data on Untrusted servers. 
+   
+   If a server becomes untrusted and keysafe stored data on it in the past,
+   keysafe will warn the user about this problem.
+   
+   The only time keysafe will use untrusted servers is if it's restoring a
+   key, and cannot find enough shares on Recommended/Alternate/Readonly
+   servers, and has to fall back to downloading from an Untrusted server.
+
+## Server list
+
+### Recommended
+
+**None yet!**
+
+### Alternate
+
+* keysafe.joeyh.name
+
+<pre>
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA256
+
+  keysafe.joeyh.name is provided by me, Joey Hess.
+
+  I intend to run this server for at least 10 years (through 2027),
+  or failing that, to transition any data stored on it to another
+  server that is of similar or higher security.
+
+  It is a Digital Ocean VPS, located in Indonesia. I can't tell if the
+  hosting provider is accessing the contents of the server, and so
+  this server is not securely hosted enough to be Recommended.
+-----BEGIN PGP SIGNATURE-----
+
+iQIcBAEBCAAGBQJXx0qFAAoJEMkQ2SIlEuPHyGMQALSLL7LZEpTi+zf2kPYGoBMQ
+3z3FDB9B6SaF4uN3r+XlAw2Vzas2KVLCbNkO+np7tLzC0qdY5dBLDI7+ZJXiKi2v
+iqxKICl0E8+ih8JOe0JWfoysO974I1DesEI7X6VUewwNpd35OgCuIL5RmknKrX4I
+x7gUfsONiojUKgOT0yMErUfw3VNYB0Kbzw4Xic66eIkFl5z6APMknjqvOC1196v9
+BW0rSM+OsthB9xkj7ULKQv+1LrxmwNu0+FL62qNKGObbXHayfLBGm8TT9Y7etQYD
+3zRDiUfa0m2aYu7ZRx5HSIgExVVd3YosDUFA4xsIb6N4wBbP1zS2TG2Zo5o/+3gt
+BerkQL/xkMWhIMVCYp1hWc47MenHk1MJU5EhS+duL/fnlqW2HcFanM+fOv+/ZWt6
+da2mdjSR95Ekq22BXN9eHO54AFJKLWYNdT9E5W2rlwqUoC4dqsqYGT3XWnAaKHC/
+he9+B/wdEf7165Qy+MKo/36Ib7pfhPQv4hip2cuMP9w0E6JoKZusBV5AdxRvGAGf
+GvUhvNog6v9/t+cqUp6dSTT2WVllkXJ/5deGJYLzZMJjZS3cZ75ZKr8OD5oQxr+m
+7oL6BDvxha7Q4qHo/RZgxyd/qZ7zWHTT6Tn6qNCBGUi4b6Etb0kEd5Os66WoLCSK
+lhmhvShr0WRqB8fWYPkc
+=SNGN
+-----END PGP SIGNATURE-----
+</pre>
+
+## Detailed requirements
+
+### Alternate
 
 * Keysafe port only exposed via tor hidden service.
 * Dedicated to only running keysafe, no other services (other than ssh for
@@ -10,31 +91,37 @@ recommended server:
 * Run by a well known and trustworthy entity.
 * The set of people who administer the server, and procedures for giving
   others access is well-defined.
-* No other recommended server in keysafe's server list is run by the same
-  entity, or administered by the same people. `*`
 * Commitment to either keep the server running long-term (ie, 10+ years),
   or transition the data to a replacement server that meets these
-  requirements and that must not contain any related shards. `*`
-* Warrant canary.
+  requirements and that must not contain any related shards.
+* No other recommended server in keysafe's server list is run by the same
+  entity, or administered by the same people.
 * No open ports (other than ssh).
 * Ssh authentication only by ssh key, not password.
-* The keysafe data store and any swap partitions are encrypted,
-  and have to be manually unlocked when the server is booted.
-* Hardware is hosted in-house. A VM at a cloud provider is right out
-  because the provider could be made to give access to it without the
-  server operator knowing about it.
-* RAID or other replication of shards to additional disks.
-  (rsync would work perfectly well and avoids the complications of RAID)
+* Either off-site backup, or replication of shards to additional disks.
+  (rsync to additional local disk would work perfectly well and avoids
+  the complications of RAID)
 * Any off-server backup is encrypted, and there's a well-defined procedure for
-  how the backup works and where it's stored. `*`
+  how the backup works and where it's stored.  
   (There's a trade-off here; any backup widens the attack surface.
   It may be better to run some servers without backups and adjust the
   number of shards needed to recover keys; a server losing its data
   need not be catastrophic.)
+* Enough disk space for a reasonable number of users to store keys.
+  Each key takes a minimum of 64 KiB to store, perhaps more for gpg keys
+  with lots of signatures. So 10 GiB of disk is sufficient for 160 thousand
+  users, which is probably enough to start with.
 
-Note that if a keysafe server runs out of disk space, or otherwise should
-not be used to store new keys, it can still be included in the server list,
-as a non-recommended server. Keysafe won't store data there, but it will
-download shards from the server if necessary to restore a key. A
-non-recommended server should meet all criteria above except for those
-marked with `*`.
+### Readonly
+
+* Same as Alternate except for disk space requirements.
+
+### Recommended
+
+* Everything in Alternate, to start with.
+* Warrant canary.
+* Hardware is hosted in-house. A VM at a cloud provider is right out
+  because the provider could be made to give access to it without the
+  server operator knowing about it.
+* The keysafe data store and any swap partitions are encrypted,
+  and have to be manually unlocked when the server is booted.

Added a comment: Automatic parallelism?
diff --git a/blog/entry/keysafe_alpha_release/comment_1_56c555d4e274186cd22789ddce497586._comment b/blog/entry/keysafe_alpha_release/comment_1_56c555d4e274186cd22789ddce497586._comment
new file mode 100644
index 0000000..a82a97a
--- /dev/null
+++ b/blog/entry/keysafe_alpha_release/comment_1_56c555d4e274186cd22789ddce497586._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="josh@ccccabe84317e1b7429fd465de0b38fd54925dea"
+ nickname="josh"
+ subject="Automatic parallelism?"
+ date="2016-08-31T21:02:58Z"
+ content="""
+keysafe --benchmark seems to run single-threaded.  Would you consider automatically parallelizing across all CPUs, to provide a more accurate benchmark?  I have a 72-way system I can send you benchmarks from.
+"""]]

Added a comment
diff --git a/blog/entry/late_summer/comment_1_39d29c8990dfb2d4c0d7d807e9297f53._comment b/blog/entry/late_summer/comment_1_39d29c8990dfb2d4c0d7d807e9297f53._comment
new file mode 100644
index 0000000..3703a13
--- /dev/null
+++ b/blog/entry/late_summer/comment_1_39d29c8990dfb2d4c0d7d807e9297f53._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="mr@e1f11bbd433e35f4e30d1cacaf1585fe2573f933"
+ nickname="mr"
+ subject="comment 1"
+ date="2016-08-31T19:06:06Z"
+ content="""
+Very interesting! Looking forward to hear more about off grid problems being solved with hacker skills and ethos. It must be so much easier to go off grid now than it was back when you did?
+"""]]

update
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
index 2f61176..34d4351 100644
--- a/code/keysafe/servers.mdwn
+++ b/code/keysafe/servers.mdwn
@@ -23,7 +23,9 @@ recommended server:
 * Hardware is hosted in-house. A VM at a cloud provider is right out
   because the provider could be made to give access to it without the
   server operator knowing about it.
-* Any backup is encrypted, and there's a well-defined procedure for
+* RAID or other replication of shards to additional disks.
+  (rsync would work perfectly well and avoids the complications of RAID)
+* Any off-server backup is encrypted, and there's a well-defined procedure for
   how the backup works and where it's stored. `*`
   (There's a trade-off here; any backup widens the attack surface.
   It may be better to run some servers without backups and adjust the

blog update
diff --git a/blog/entry/late_summer.mdwn b/blog/entry/late_summer.mdwn
new file mode 100644
index 0000000..bf453cc
--- /dev/null
+++ b/blog/entry/late_summer.mdwn
@@ -0,0 +1,23 @@
+With days beginning to shorten toward fall, my house is in initial power
+saving mode. Particularly, the internet gateway is powered off overnight.
+Still running electric lights until bedtime, and still using the inverter
+and other power without much conservation during the day.
+
+Indeed, I had two laptops running cpu-melting keysafe benchmarks for much
+of today and one of them had to charge up from empty too. That's why the
+house power is a little low, at 11.0 volts now, despite over 30 amp-hours
+of power having been produced on this mostly clear day. (1 week average is
+18.7 amp-hours)
+
+September/October is the tricky time where it's easy to fall off a battery
+depletion cliff and be stuck digging out for a long time. So time to start
+dusting off the conservation habits after summer's excess.
+
+----
+
+I think this is the first time I've mentioned any details of living off
+grid with a bare minimum of PV capacity in over 4 years. [[Solar]] has a
+lot of older posts about it, and I'm going to note down the typical
+milestones and events over the next 8 months.
+
+[[!tag solar]]

add solar feed
diff --git a/blog/entry/freedombox_for_a_solar_powered_house.mdwn b/blog/entry/freedombox_for_a_solar_powered_house.mdwn
index ff2745e..21afe2d 100644
--- a/blog/entry/freedombox_for_a_solar_powered_house.mdwn
+++ b/blog/entry/freedombox_for_a_solar_powered_house.mdwn
@@ -51,3 +51,5 @@ bits."]]
 
 Since the solar house is in the sticks, the result is a server I call
 "[[boxen/stick]]".
+
+[[!tag solar]]
diff --git a/blog/entry/getting_to_know_my_batteries.mdwn b/blog/entry/getting_to_know_my_batteries.mdwn
index 218e1e0..163b28c 100644
--- a/blog/entry/getting_to_know_my_batteries.mdwn
+++ b/blog/entry/getting_to_know_my_batteries.mdwn
@@ -48,6 +48,6 @@ battery capacity to get through up to a week of solid clouds in midwinter.
 
 [[!img pics/boxandpanel.jpeg size=x480 caption="battery box and solar panel"]]
 
-[[!tag diy energy battery lay]]
+[[!tag diy energy battery solar lay]]
 
 [[!meta title="getting to know my batteries"]]
diff --git a/blog/entry/infrastructure_update.mdwn b/blog/entry/infrastructure_update.mdwn
index b482374..f004497 100644
--- a/blog/entry/infrastructure_update.mdwn
+++ b/blog/entry/infrastructure_update.mdwn
@@ -24,6 +24,6 @@ I hope this was only an early taste of spring. Would be nice to have some
 more icy weather so I can put off dealing with refrigeration a little while
 longer. I have my eye on a 12v/propane fridge.
 
-[[!tag lay]]
+[[!tag lay solar]]
 
 [[!meta title="infrastructure update"]]
diff --git a/blog/entry/solar_day_2.mdwn b/blog/entry/solar_day_2.mdwn
index 2e2b224..093fe34 100644
--- a/blog/entry/solar_day_2.mdwn
+++ b/blog/entry/solar_day_2.mdwn
@@ -25,14 +25,14 @@ for the stove, and kerosine for the lanterns. And of course always the state
 of the batteries. So far, the first battery bank seems likely to last longer
 than the ice. I'll know better tomorrow.
 
-Unfortunatly I burned out the 5v power suppzly I was using to run my NSLU2
+Unfortunatly I burned out the 5v power supply I was using to run my NSLU2
 in a wiring mishap, so I have to run that on an inverter for now, and the
 batteries, though not low, can barely power both the inverter and my
 laptop. This has made staying online tricky. But I'm finding dialup
-psurpisingly tolerable, and it helps to generally slow down, too. Despite
+surpisingly tolerable, and it helps to generally slow down, too. Despite
 all the above, I got about as much real work done today as I normally
 would.
 
-[[!tag lay offgrid]] 
+[[!tag lay offgrid solar]] 
 
 [[!meta title="solar day 2"]]
diff --git a/blog/haskell.mdwn b/blog/haskell.mdwn
index 393865d..b48beb1 100644
--- a/blog/haskell.mdwn
+++ b/blog/haskell.mdwn
@@ -1,3 +1,3 @@
-The most recent haskell-related posts to [[Joey]]'s [[blog]].
+Haskell-related posts to [[Joey]]'s [[blog]].
 
-[[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=40]]
+[[!inline pages="blog/entry/* and link(haskell) and !*/Discussion" show=0]]
diff --git a/blog/solar.mdwn b/blog/solar.mdwn
new file mode 100644
index 0000000..d81458c
--- /dev/null
+++ b/blog/solar.mdwn
@@ -0,0 +1,4 @@
+Posts related to solar power and off the grid living.
+
+[[!inline pages="blog/entry/* and link(solar) and !*/Discussion"
+actions=yes show=0]]

keysafe server requirements
diff --git a/code/keysafe/servers.mdwn b/code/keysafe/servers.mdwn
new file mode 100644
index 0000000..2f61176
--- /dev/null
+++ b/code/keysafe/servers.mdwn
@@ -0,0 +1,38 @@
+There are currently no keysafe servers. We need at least 3 for keysafe to
+work. Please contact <id@joeyh.name> if you would like to run a keysafe server.
+
+Requirements for a server to be included in keysafe's server list as a
+recommended server:
+
+* Keysafe port only exposed via tor hidden service.
+* Dedicated to only running keysafe, no other services (other than ssh for
+  admin)
+* Run by a well known and trustworthy entity.
+* The set of people who administer the server, and procedures for giving
+  others access is well-defined.
+* No other recommended server in keysafe's server list is run by the same
+  entity, or administered by the same people. `*`
+* Commitment to either keep the server running long-term (ie, 10+ years),
+  or transition the data to a replacement server that meets these
+  requirements and that must not contain any related shards. `*`
+* Warrant canary.
+* No open ports (other than ssh).
+* Ssh authentication only by ssh key, not password.
+* The keysafe data store and any swap partitions are encrypted,
+  and have to be manually unlocked when the server is booted.
+* Hardware is hosted in-house. A VM at a cloud provider is right out
+  because the provider could be made to give access to it without the
+  server operator knowing about it.
+* Any backup is encrypted, and there's a well-defined procedure for
+  how the backup works and where it's stored. `*`
+  (There's a trade-off here; any backup widens the attack surface.
+  It may be better to run some servers without backups and adjust the
+  number of shards needed to recover keys; a server losing its data
+  need not be catastrophic.)
+
+Note that if a keysafe server runs out of disk space, or otherwise should
+not be used to store new keys, it can still be included in the server list,
+as a non-recommended server. Keysafe won't store data there, but it will
+download shards from the server if necessary to restore a key. A
+non-recommended server should meet all criteria above except for those
+marked with `*`.

nah
diff --git a/blog/entry/hiking_the_Roan.mdwn b/blog/entry/hiking_the_Roan.mdwn
index 374b657..421d259 100644
--- a/blog/entry/hiking_the_Roan.mdwn
+++ b/blog/entry/hiking_the_Roan.mdwn
@@ -14,5 +14,4 @@ touch, but not this trip. Good to have a goal.
 
 [[!img pics/sunsetmist.jpg size=1024x]]
 
-Near sunset, land and sky merge as the mist moves in. In the dwarf
-blackberry bushes, baby birds call for their mother.
+Near sunset, land and sky merge as the mist moves in.

up
diff --git a/blog/entry/hiking_the_Roan.mdwn b/blog/entry/hiking_the_Roan.mdwn
index 421d259..374b657 100644
--- a/blog/entry/hiking_the_Roan.mdwn
+++ b/blog/entry/hiking_the_Roan.mdwn
@@ -14,4 +14,5 @@ touch, but not this trip. Good to have a goal.
 
 [[!img pics/sunsetmist.jpg size=1024x]]
 
-Near sunset, land and sky merge as the mist moves in.
+Near sunset, land and sky merge as the mist moves in. In the dwarf
+blackberry bushes, baby birds call for their mother.

blog update
diff --git a/blog/entry/hiking_the_Roan.mdwn b/blog/entry/hiking_the_Roan.mdwn
new file mode 100644
index 0000000..421d259
--- /dev/null
+++ b/blog/entry/hiking_the_Roan.mdwn
@@ -0,0 +1,17 @@
+Three moments from earlier this week..
+
+[[!img pics/footview.jpg size=1024x]]
+
+Sprawled under a tree after three hours of hiking with a heavy,
+water-filled pack, I look past my feet at six ranges of mountains behind
+mountains behind flowers.
+
+[[!img pics/roantent.jpg size=1024x]]
+
+From my campsite, I can see the rest of the path of the Appalachian Trail
+across the Roan balds, to Big Hump mountain. It seems close enough to
+touch, but not this trip. Good to have a goal.
+
+[[!img pics/sunsetmist.jpg size=1024x]]
+
+Near sunset, land and sky merge as the mist moves in.
diff --git a/blog/pics/roanten.jpg b/blog/pics/roanten.jpg
deleted file mode 100644
index 8f2b547..0000000
Binary files a/blog/pics/roanten.jpg and /dev/null differ
diff --git a/blog/pics/roantent.jpg b/blog/pics/roantent.jpg
new file mode 100644
index 0000000..8f2b547
Binary files /dev/null and b/blog/pics/roantent.jpg differ

add
diff --git a/blog/pics/footview.jpg b/blog/pics/footview.jpg
new file mode 100644
index 0000000..3b8b693
Binary files /dev/null and b/blog/pics/footview.jpg differ
diff --git a/blog/pics/roanten.jpg b/blog/pics/roanten.jpg
new file mode 100644
index 0000000..8f2b547
Binary files /dev/null and b/blog/pics/roanten.jpg differ
diff --git a/blog/pics/sunsetmist.jpg b/blog/pics/sunsetmist.jpg
new file mode 100644
index 0000000..109447e
Binary files /dev/null and b/blog/pics/sunsetmist.jpg differ

add news item for github-backup 1.20160922
diff --git a/code/github-backup/news/version_1.20150807.mdwn b/code/github-backup/news/version_1.20150807.mdwn
deleted file mode 100644
index 13d0ccd..0000000
--- a/code/github-backup/news/version_1.20150807.mdwn
+++ /dev/null
@@ -1,8 +0,0 @@
-github-backup 1.20150807 released with [[!toggle text="these changes"]]
-[[!toggleable text="""
-   * Added bash completion.
-   * Add --no-forks flag that turns off backing up forks.
-     Thanks, Phil Ruffwind.
-   * Avoid nonzero exit due to temporary failures that can be retried next
-     time github-backup runs, so that it can be used in a cron job with eg,
-     chronic."""]]
\ No newline at end of file
diff --git a/code/github-backup/news/version_1.20160922.mdwn b/code/github-backup/news/version_1.20160922.mdwn
new file mode 100644
index 0000000..b9e1464
--- /dev/null
+++ b/code/github-backup/news/version_1.20160922.mdwn
@@ -0,0 +1,11 @@
+github-backup 1.20160922 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+   * Increase base bounds to 4.8 to get mapM\_ etc that works on Vector.
+   * Recommended build method is now to use stack, for more reliable builds.
+   * Explicitly list modules and other files in github-backup.cabal.
+   * The hackage .tar.gz now omits the debian directory and may omit other
+     source files in the future; the purpose of that tarball is to make
+     stack/cabal install work, not to be a complete source distribution.
+     Use git repository to get complete source.
+   * Various updates to internal git and utility libraries shared
+     with git-annex."""]]
\ No newline at end of file

correction
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 03005fd..21387eb 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -10,7 +10,7 @@ theft, raids, and compromised printers. Gold standard.
 Using keysafe is analagous to storing the paperkey printout in a safety
 deposit box at a bank, and using a really really strong gpg passphrase.
 Since we don't trust a single bank (server), we shred the printout and
-evenly distribute the shreds amoung three banks. While the banks know the
+evenly distribute the shreds amoung several banks. While the banks know the
 safety deposit boxes belong to you and could put the shreds back together,
 a keysafe server has very little identifying information to go on (it only
 knows when you made the deposit).

expand
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
index 2d0b91a..03005fd 100644
--- a/code/keysafe/faq.mdwn
+++ b/code/keysafe/faq.mdwn
@@ -1,5 +1,20 @@
 [[!toc]]
 
+### How does keysafe compare with paperkey?
+
+Using paperkey to print out your gpg key and locking it in a safe is a great
+solution to gpg key backup. It requires a printer, a safe, and typing in many
+numbers to restore the key. It avoids all attack methods except physical
+theft, raids, and compromised printers. Gold standard.
+
+Using keysafe is analagous to storing the paperkey printout in a safety
+deposit box at a bank, and using a really really strong gpg passphrase.
+Since we don't trust a single bank (server), we shred the printout and
+evenly distribute the shreds amoung three banks. While the banks know the
+safety deposit boxes belong to you and could put the shreds back together,
+a keysafe server has very little identifying information to go on (it only
+knows when you made the deposit).
+
 ### I copy secring.gpg to dropbox to back it up. Why bother with keysafe?
 
 So, you rely on your gpg passphrase for security.
@@ -34,13 +49,6 @@ being used to protect against passphrase cracking, because it would slow down
 day-to-day use of gpg. Keysafe can make cracking the password much more
 expensive because it's only used for backup and restore.
 
-### How does keysafe compare with paperkey?
-
-Using paperkey to print out your gpg key and locking it in a safe is a great
-solution to gpg key backup. It requires a printer, a safe, and typing in many
-numbers to restore the key. It avoids all attack methods except physical
-theft, raids, and compromised printers. Gold standard.
-
 ### Is keysafe suitable for backing up bitcoin wallets?
 
 Not recommended. Use a brain wallet.

POW
diff --git a/code/keysafe/details.mdwn b/code/keysafe/details.mdwn
index 6d7d28e..4fd7fea 100644
--- a/code/keysafe/details.mdwn
+++ b/code/keysafe/details.mdwn
@@ -176,19 +176,45 @@ desirable to store the public and secret key together. This way,
 a user does not have to publish the key to keyservers, which makes some
 attack methods much less likely to try to crack their key.
 
-So, the object size should be at least a few tens of KB. If keysafe needs
-to store a larger key, it can chunk it up, and include a count of the
-number of chunks in the first encrypted object.
+So, the object size should be at least a few tens of KB. 64kb seems
+reasonable. If keysafe needs to store a larger key, it can chunk it up.
 
 Objects shoud be padded to a fixed size before they are encrypted, to
 prevent attackers from correlating and targeting particular objects based
 on size.
 
-When a client connects to a server, it sends a request. The server
-replies with a
-[proof of work puzzle](https://en.wikipedia.org/wiki/Client_Puzzle_Protocol)
-that the client must solve to make that request.
-This can be used by servers to avoid DOS attacks.
+## Client puzzles
+
+Assuming that the client communicates with the server over http:
+
+	PUT /keysafe/objects/N?S
+	GET /keysafe/objects/N?S
+
+Then, the S can be required to be a string such that argon2(N,S)
+starts with a given number of 0's. This allows the server to verify the
+client's proof of work without maintaining any state.
+
+The required number of 0's can be queried:
+
+	GET /keysafe/proofofwork/
+
+With a response like "zeros=4 iterations=1".
+
+(The server should only be able to control the number of iterations,
+not other argon2 parameters, to avoid forcing the client to use too much
+memory. Normally, the server will keep iterations small, probably 1,
+since it does need to calculate the argon2 hash itself.)
+
+Note that this scheme lets a client do work once for a given N and then
+request that N from multiple servers, as long as they have similar zeros=
+parameters (and the same iterations= parameters). This is probably a good
+thing; it means that keysafe doesn't need to do extra work when checking
+servers to get a shard.
+
+Servers can change their proof of work parameters as needed, but that can
+cause a client that was connected to the server to generate a bad POW.
+The server can respond with 402 Payment Required in that case, so the
+client knows to retry.
 
 ## Avoiding correlations
 

add
diff --git a/code.mdwn b/code.mdwn
index ba9ad89..2bd4dc0 100644
--- a/code.mdwn
+++ b/code.mdwn
@@ -27,6 +27,7 @@ In maintenance mode mostly, but I still have my hands in it somewhat.
 [[filters]]
 [[electrum-mnemonic]]
 [[brainfuck-monad]]
+[[zxcvbn-c]]
 [[scroll]]
 
 ## Past projects
diff --git a/code/zxcvbn-c.mdwn b/code/zxcvbn-c.mdwn
new file mode 100644
index 0000000..a73cf29
--- /dev/null
+++ b/code/zxcvbn-c.mdwn
@@ -0,0 +1,6 @@
+A quick haskell interface to the zxcvbn-c password strength estimation
+library.
+
+<http://hackage.haskell.org/package/zxcvbn-c>
+
+At some point, it would be good to implement this in pure haskell.

faq
diff --git a/code/keysafe.mdwn b/code/keysafe.mdwn
index 0047cba..7e8bfd1 100644
--- a/code/keysafe.mdwn
+++ b/code/keysafe.mdwn
@@ -38,6 +38,7 @@ also makes it hard for an attacker to even find your encrypted secret key.
 
 For a more in-depth explanation, and some analysis of different attack
 vectors (and how keysafe thwarts them), see [[details]].
+Also, there's a [[FAQ]].
 
 ## News
 
@@ -71,74 +72,6 @@ Email <id@joeyh.name>
 
 Keysafe is licensed under the terms of the AGPL 3+
 
-## Comparisons with other approaches
-
-### paperkey
-
-Using paperkey to print out your gpg key and locking it in a safe is a great
-solution to gpg key backup. It requires a printer, a safe, and typing in many
-numbers to restore the key. It avoids all attack methods except physical
-theft, raids, and compromised printers. Gold standard.
-
-### storing secring.gpg in the cloud
-
-Some people copy secring.gpg to dropbox or similar to back it up,
-and rely on the gpg passphrase for security.
-
-Gpg uses between 1024 (the default) and 65011712 rounds of SHA-1 hashing of
-the passphrase. In 2012, a GPU could calculate 2 billion SHA-1 hashes
-per second, so this is not much of an impediment to password cracking at
-all.
-
-Assuming 100 gpg passphrases can be tried per second, and gpg is
-configured to use the maximum rounds (which it normally is NOT):
-
-* Strong passphrase (50 entropy): 21421231 GPU-years
-* Weak passphrase (30 entropy): 10 GPU-years
-* Super-weak passphrase (19 entropy): 2 GPU-days
-
-So this might be secure enough for some, but only with a really good
-passphrase. Probably, most people who copy their secring.gpg to
-the cloud have either a weakish passphrase, or have not tuned gpg to
-use maximum SHA-1 rounds, or both. So, they can probably be cracked in
-days to weeks.
-
-Compare these numbers with the cost to crack keysafe passwords
-(explained in [[details]]):
-
-* Strong password (50 entropy): 53553077761 CPU-years 
-* Weak password (30 entropy): 51072 CPU-years 
-* Super-weak password (19 entropy): 25 CPU-years 
-
-Big difference! Indeed, the design of gpg prevents a really expensive hash
-being used to protect against passphrase cracking, because it would slow down
-day-to-day use of gpg. Keysafe can make cracking the password much more
-expensive because it's only used for backup and restore.
-
-### non-sharded variant of keysafe
-
-Worth comparing the sharding approach with the most secure and simple
-non-sharded approach I can think of:
-
-* Generate decryption puzzle P, a byte chosen at random.
-* Generate K by argon2(password, salt=name+P), tuned to take 0.195 minutes.
-* AES encrypt (data + checksum) with K as the key.
-* upload to diverse locations using the gpg keyid as a unique ID
-  (with some complication to handle objects maliciously uploaded using
-  the same ID)
-
-The key encryption is the same as keysafe in this approach, so the
-difficulty in brute forcing an encrypted key is the same as described
-in [[details]]. Brute-forcing is only feasible for weak passwords.
-
-But brute forcing can start right away, and be performed by anyone,
-unlike with sharding where only two colluding servers can start brute
-forcing right away.
-
-So, this isn't too bad, but for all the users who use weak passwords
-(you know who you are (yes, you)), it's not as good a choice as keysafe.
-At worst, keysafe degrades to being as secure as this approach.
-
 ## Thanks
 
 Thanks to Anthony Towns for his help with keysafe's design.
diff --git a/code/keysafe/faq.mdwn b/code/keysafe/faq.mdwn
new file mode 100644
index 0000000..2d0b91a
--- /dev/null
+++ b/code/keysafe/faq.mdwn
@@ -0,0 +1,51 @@
+[[!toc]]
+
+### I copy secring.gpg to dropbox to back it up. Why bother with keysafe?
+
+So, you rely on your gpg passphrase for security.
+
+Gpg uses between 1024 (the default) and 65011712 rounds of SHA-1 hashing of
+the passphrase. In 2012, a GPU could calculate 2 billion SHA-1 hashes
+per second, so this is not much of an impediment to password cracking at
+all.
+
+Assuming 100 gpg passphrases can be tried per second, and gpg is
+configured to use the maximum rounds (which it normally is NOT):
+
+* Strong passphrase (50 entropy): 21421231 GPU-years
+* Weak passphrase (30 entropy): 10 GPU-years
+* Super-weak passphrase (19 entropy): 2 GPU-days
+
+So this might be secure enough for some, but only with a really good
+passphrase. Probably, most people who copy their secring.gpg to
+the cloud have either a weakish passphrase, or have not tuned gpg to
+use maximum SHA-1 rounds, or both. So, they can probably be cracked in
+days to weeks.
+
+Compare these numbers with the cost to crack keysafe passwords
+(explained in [[details]]):
+
+* Strong password (50 entropy): 53553077761 CPU-years 
+* Weak password (30 entropy): 51072 CPU-years 
+* Super-weak password (19 entropy): 25 CPU-years 
+
+Big difference! Indeed, the design of gpg prevents a really expensive hash
+being used to protect against passphrase cracking, because it would slow down
+day-to-day use of gpg. Keysafe can make cracking the password much more
+expensive because it's only used for backup and restore.
+
+### How does keysafe compare with paperkey?
+
+Using paperkey to print out your gpg key and locking it in a safe is a great
+solution to gpg key backup. It requires a printer, a safe, and typing in many
+numbers to restore the key. It avoids all attack methods except physical
+theft, raids, and compromised printers. Gold standard.
+
+### Is keysafe suitable for backing up bitcoin wallets?
+
+Not recommended. Use a brain wallet.
+
+Keysafe might be more secure than a paper wallet in some situations.
+It's happened before that someone has stumbled over someone else's
+list of electrum words amoung their papers. Using keysafe avoids such
+scenarios.

patreon
diff --git a/blog/entry/keysafe_alpha_release.mdwn b/blog/entry/keysafe_alpha_release.mdwn
index 30aa358..c9787ee 100644
--- a/blog/entry/keysafe_alpha_release.mdwn
+++ b/blog/entry/keysafe_alpha_release.mdwn
@@ -29,3 +29,5 @@ that's less than a year old, send me a benchmark:
 Bonus announcement: <http://hackage.haskell.org/package/zxcvbn-c/> is my
 quick Haskell interface to the C version of the zxcvbn password strength
 estimation library.
+
+PS: Past 50% of my goal on [Patreon](https://www.patreon.com/joeyh)!

typo
diff --git a/blog/entry/keysafe_alpha_release.mdwn b/blog/entry/keysafe_alpha_release.mdwn
index 86843a5..30aa358 100644
--- a/blog/entry/keysafe_alpha_release.mdwn
+++ b/blog/entry/keysafe_alpha_release.mdwn
@@ -22,7 +22,7 @@ to `~/.keysafe/objects/local/`
 
 I still need to tune the argon2 hash difficulty, and I need benchmark data
 to do so. If you have a top of the line laptop or server class machine
-that's less than a year old, send me a bechmark:
+that's less than a year old, send me a benchmark:
 
 	~/.local/bin/keysafe --benchmark | mail keysafe@joeyh.name -s benchmark