btcinfo  

Hic inserere motto

Trivial bash shell for common lisp

December 11, 2024 — shinohai

I recently acquired a fresh laptop, and in the process of setting up sbcl I thought I best polish this little lisp function for my .sbclrc. I shall publish it here lest I forget it, and on the off chance another reader finds it useful.

(defun sh (cmd)
  "Run a shell command and return standard output if successful."
  (multiple-value-bind (stdout stderr exit)
      (uiop:run-program
       (format nil "~A" cmd)
       :output :string
       :error-output :string
       :ignore-error-status t)
    (if (zerop exit)
        stdout
        (format nil "Command failed with exit code ~A. Error: ~A" exit stderr))))

Happy holidays to all!

Tags: Lisp, Linux

Installing slimv using esthlos-v

December 30, 2021 — shinohai

Slimv stands for Superior Lisp Interaction Mode for Vim. It is a Vim plugin of 2009 vintage written by Tamas Kovacs, preserved in the form of a vpatch. This is for folx who already have vim,tmux, and sbcl installed and want a quick and reliable method for enabling a swank server in vim ala emacs.

Populate your slimv tree, mine is available at http://btc.info.gf/devel/vim/plugins/slimv/

# tree slimv/
slimv/
├── patches
│   └── slimv.genesis.vpatch
├── seals
│   └── slimv.genesis.vpatch.shinohai.sig
└── wot
    └── shinohai.asc

Using esthlos-v press slimv directly to the vim plugins directory:

`v press slimv.genesis.vpatch ~/.vim/pack/plugins/start/`

My sbcl binary is in a nonstandard location (because Gentoo) and I couldn't get the swank server to start from within vim. I remedied this with a function that starts swank in a tmux window using rlwrap:

swank() {
tmux ls | grep '>_' > /dev/null || (
  tmux new-session -d -s '>_' -n '[swank]' rlwrap /usr/local/bin/sbcl --load \
   ~/.vim/pack/plugins/start/slimv/slime/start-swank.lisp
)
exec tmux attach -t '>_'
}

Now when I open a `.lisp` file, vim presents me with a new buffer containing a REPL connected via swank:

BUT WAIT ! THERE'S MOAR !!!

Bundled with slimv is a tool called paredit which will, amongst other things,match parenthesis for you as you code. To learn more about it's features read the documentation by entering `:help paredit`

Tags: News, Lisp, Linux

A simple bip39 diceware script in common lisp

July 07, 2021 — shinohai

I'm currently bench testing a "Foundation devices" passport hardware Bitcoin wallet, because why not? While the device will happily generate bip39 seeds for you I wanted to test load a bunch of seed phrases generated offline without throwing dice all afternoon and figured a simple lisp script would suffice.

I started with this implementation of diceware. The original author provided no asdf system file or anything, but we don't need that where we're going, so a couple of quick modifications get us where we want to be here. We only need an index of 2048 for our *words* array, so we change that in the script to make it compatible with the standard bip39 wordlist.

(require 'ironclad) (defparameter *words* nil) (defparameter *prng* (ironclad:make-prng :fortuna)) (defun load-words (&optional (wd-list #P "bip39-english.txt")) "Load *words* from bip39-english.txt" (with-open-file (s wd-list) (do ((wd (read-line s nil) (read-line s nil)) ( i 0 (1+ i))) ((not wd)) (setf (aref *words* i) wd)))) (defun choose-one () "Randomly choose a single word from *words*." (aref *words* (ironclad:strong-random (length *words*) *prng*))) (defun choose-password (n) "Generate n random words for a pass phrase. Initialize *words* if needed" (unless *words* (setf *words* (make-array 2048)) (load-words)) (let (words) (dotimes (i n) (push (choose-one) words)) (reverse words)))

Grab the standard bip39 English wordlist from the "Bitcoin Core" Shithub repo, and save it in the same directory as the script naming it "bip39-english.txt".

Load up the script in your lisp REPL (I used SBCL here) and run `choose password` + the number of words you are using for your seed. I'm using 23 words in this example since most hardware wallets will calculate the final word for you.

/usr/local/bin/sbcli --load diceware.lisp REPL for SBCL version 0.1.0 Press CTRL-D or type :q to exit [sbcl]> * (choose-password 23) ("there" "image" "federal" "steak" "renew" "helmet" "attack" "medal" "seat" "game" "return" "way" "shock" "hero" "wolf" "amount" "token" "pluck" "gentle" "evoke" "burst" "siege" "ripple")

The device happily accepted the phrases generated via manual entry, calculated the 24th "checksum" word perfectly, and freed up time for me to continue trying builds of the device firmware. More to come.

Tags: Bitcoin, Lisp, Linux

ben_vulpes base58 encoding in Common Lisp

January 24, 2021 — shinohai

As the anniversary of the fall of TMSR approaches the decay of the once-proud institution is evident in the rapidly decreasing number of websites of former Lords. cascadianhacker.com, formerly operated by ben_vulpes (WoT:ben_vulpes) is sadly one of these castles specifically because the guy wrote the defacto introduction to vtronics (archived) and some interesting posts on common lisp.

One forgotten item I found particularly useful was an implementation of base58 encoding in common lisp. Sadly I could find no archive of the original article but after a bit of digging I found a copy of the code contained within saved on an old hard drive. I'm quoting it below so I have a handy reference for future projects.

(defparameter +b58-alphabet+ "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")

(defun b58-encode (bytes)
  (let ((string (make-string-output-stream))
        (bignum (loop for i to (- (length bytes) 1) summing
               (* (elt bytes i)
                  (expt 256 i)))))

   (loop while (> bignum 0) do
        (multiple-value-bind (x r) (floor bignum (length +b58-alphabet+))
          (write-char (elt +b58-alphabet+ r) string)
          (setf bignum x)))

   (loop for b across (reverse bytes) do
        (if (= 0 b)
            (write-char (elt +b58-alphabet+ 0) string)
            (return)))

   (reverse (get-output-stream-string string))))

Tags: Bitcoin, Lisp, News

Botworks - ircbot and logbot genesis

June 21, 2020 — shinohai

Alf has reminded me several times that it might be helpful to publish the sauce for my ircbot setup so this post is an attempt to do just that, and generally make it easier to install the bot components using V. My botworks tree uses trinque's lisp ircbot and logbot combo as the starting point.

A lot of good patches are scattered about on former republican blogs, though it seems I could get none of them to play nice with esthlos-v so a regrind was in order. For ircbot these are:

trinque's ircbot-genesis-kv.vpatch.

ben_vulpes' ircbot-multiple-channels-kv.vpatch.

whaack's ircbot-no-suicide-on-reconnect-kv.vpatch.

Assuming you already have SBCL and quicklisp, you can then use `V` to press ircbot and move the output to your local-projects directory:

v press ircbot-no-suicide-on-reconnect-kv out

mv out/ircbot ~/quicklisp/local-projects

The process is repeated to add the logbot system. While testing the regrinds I came upon a curious problem where adding ben_vulpes "logbot-multiple-channels" patch caused an error when trying to start logbot. Simply pressing the logbot genesis and running the bot is working, so I will continue to debug the issue and post results in a future botworks piece. The logbot requires that postgres be installed on your system, whaack has a good piece on how to do this on his blog, if you aren't familiar with setting that part up.

v press logbot-genesis-kv.vpatch

mv out/logbot ~/quicklisp/local-projects

With both of these components installed where ASDF can find them running the bot is as simple as firing up a REPL, adding your parameters and connecting to it according to the instructions in the "logbot/USAGE" file.

TODO:

Put together a better prefixed command system, the system I am currently using works but needs quite a bit of polish before being worthy of turning into a vpatch.

Cobble together a www log reader for use with the logbot system.

Links to useful lisp botworks resources:

trinque's sources: http://trinque.org/src/

ben_vulpes' post on multiple channels: http://cascadianhacker.com/correction-multiple-channel-patches-for-irclogbot

spyked's botworks vpatches: http://lucian.mogosanu.ro/src/botworks/v/patches/

whaack's post on setting up trinque's logbot: http://ztkfg.com/2019/12/setting-up-trinques-logbot-on-centos-6-with-sbcl-quicklisp-swank-and-postgres/

Tags: News, Lisp, UNIX

Notes on esthlos-v and some restructuring thereof

January 30, 2020 — shinohai

This particular post will serve as a place to put my notes on esthlos-v, which I have been reading over in an attempt to polish it up for personal use. Now there are many fine implementations of "V" out there already, and I admit mod6's "v.pl" has served me well over time, but this particular "V" is delightfully readable and the code is well commented.

Way back in ancient Greece, the word "esthlos" meant that "something exists" or at least is true. Even though the author of esthlos-v vanished into internet space some time ago, and apparently abandoned work on the project, we'll retain the original name since it seems rather fitting for a tool used to magic software into existence.

I will expound upon the contents of esthlos-v in a later piece, though for now I am adding a single new vpatch: "esthlos-v_makefile-and-vdiff.vpatch" - this patch contains simple modifications to the original Makefile so it will build both "v.lisp" and "cl-keccak" as standalone binaries at the same time, and install them if the operator so desires. A modified version of phf's original vdiff.sh that uses cl-keccak instead of sha512sum is included. This vpatch and it's corresponding seal can be found in the esthlos-v mirror here.

Tags: News, Lisp, UNIX

Essential kit items: Building SBCL on Gentoo with musl

November 08, 2019 — shinohai

Steel Bank Common Lisp is another must-have tool in my kit, since I use it to run my hybrid irc/Telegram bot and many other daily use items. In my previous post I documented how I managed to get gcc-4.9.4 massaged into shape, so this post will serve as a reference on how to do the same for SBCL so in the future I don't have to spend the day researching fixes and locating obscure patchsets.

When building many things using musl, one will often run into "undefined reference to `memcpy@GLIBC_*'" type errors, since glibc uses versioned symbols and musl does not. SBCL is no different, but fortunately a little digging turned up a working patchset on the SBCL mailing list which works beautifully, so I didn't have to spend the better part of a day cobbling one together as I did for gcc. I have preserved a copy of the patchset here and will definitely do my best to maintain these into the future should any major changes occur.

Much like Ada, SBCL requires itself or another ANSI common lisp to build. I decided to use CLISP (version 2.49.92) to perform this task, as it can be quickly built from sources using gcc only (and I didn't want to use a pre-built sbcl binary of unknown provenance). After getting clisp in place, building SBCL is mostly painless using the following steps:

I downloaded the 1.5.7 sources from my site and verified the checksums:

curl -O http://btc.info.gf/devel/gentoo/distfiles/dev-lisp/sbcl/1.5.7/sbcl-1.5.7-source.tar.bz2
curl -O http://btc.info.gf/devel/gentoo/distfiles/dev-lisp/sbcl/1.5.7/Manifest.sha512

Unpack the sources and enter the directory:

tar xjf sbcl-1.5.7-source.tar.bz2 && cd sbcl-1.5.7

Get the musl patchset and apply them:

wget -q -r -nd -N --no-parent -R "index.html*" http://btc.info.gf/devel/gentoo/distfiles/dev-lisp/sbcl/patches/
for i in *.patch; do patch -p1 < $i; done

Build using CLISP and install:

./make.sh "clisp" --fancy
./install.sh

The above recipe has so far worked quite nicely, having been tested by running the above mentioned irc bot and a few other essential lisp programs. I will update this post if/when any bugs are found or if any changes are made.

Tags: News, Linux, Lisp