kee

Offline IOU signer with QR as transport
git clone git://holbrook.no/kee-gtk4.git
Info | Log | Files | Refs | README | LICENSE

README (11193B)


      1 kee
      2 
      3 The upstream respository is git://holbrook.no/kee-gtk4.git
      4 
      5 I am building a cryptographically counter-signed IOU application with
      6 linux phones (GTK4, phosh) as the primary targets.
      7 
      8 It will maintain bi-lateral mutual channels of credit and collateral.
      9 Each change is linked as a chain, and documentation for each change in
     10 embedded as email-link MIME structures
     11 
     12 It is currently in alpha state, and does not yet have a friendly
     13 introduction.
     14 
     15 See "Protocol" and "Concepts" headings below for more details on what
     16 this actually is aiming to become.
     17 
     18 What it can do (currently)
     19 
     20 The UI state is still fragmented and does not yet implement a ful
     21 sequence of actions for creating and mutually signing ledger.
     22 
     23 However, a ledger can be created, counter-signed and imported by
     24 restarting UI as Alice, Bob and Alice respectively, and manually use the
     25 import option.
     26 
     27 What it does have is:
     28 
     29 -   GTK interface pages for
     30     -   Unlock wallet key
     31     -   List IOUs
     32     -   List IOU details and deltas (transactions)
     33     -   Import data and/or delta (QR or pasted text)
     34     -   Import summary and accept page
     35     -   Create new ledger entry page
     36 -   Testdata generator for tests and demonstrating state of UI:
     37     -   Create keys for Alice and (main) Bob, as well as two additional
     38         Bobs
     39     -   Symlinks to use (main) Bob key instead of Alice as identity for
     40         UI
     41     -   A configurable number of randomized ledger entries and deltas
     42 -   CLI tool:
     43     -   Show details about a ledger entry
     44     -   Sign a ledger delta
     45 
     46 Dependencies
     47 
     48 Below are the library versions of the archlinux component packages I am
     49 using for dependencies and tooling while working on my own system.
     50 
     51   package           version
     52   ----------------- ---------
     53   gcc               13.2.1
     54   graphicsmagick    1.3.42
     55   gst-plugins-bad   1.24.0
     56   gst-plugins-good  1.24.0
     57   gstreamer         1.24.0
     58   gtk4              4.12.5
     59   libb64            1.2.1
     60   libgcrypt         1.10.3
     61   qrencode          4.1.1
     62   libxdg-basedir    1.2.3
     63   lmdb              0.9.32
     64   openldap          2.6.7
     65   rustup            1.26.0
     66   zbar              0.23.90
     67   zlib              1.3.1
     68 
     69 The gst-plugins-bad provides libgstzbar.so, used as part of QR scanning.
     70 
     71 Other sources
     72 
     73 The code expects objects from these source trees to be available
     74 somehow:
     75 
     76   project          upstream source                                                                                      version               tar.gz sha256
     77   ---------------- ---------------------------------------------------------------------------------------------------- --------------------- ------------------------------------------------------------------
     78   liblash*         https://holbrook.no/src/liblash (193dd4032e8088ada2dc9dcedab8d7486e9305f5)                           0.1.0                 333cdf49bb7e9f44b37e5bc9f594a01e4b3b8ecb3fcd3d9ffec3ea6dcdeaec7b
     79   libcmime         https://github.com/spmfilter/libcmime.git (dd21eb096d162656e30243f60fc4bc35ad39ae6e)                 0.2.2                 18a8d46ebec575a79212acc2dc6af7fd7bdeba3a9b85a70677ed0b7785c5c04e
     80   gst-plugins-rs   https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs (a84bbc66f30573b62871db163c48afef75adf6ec)   1.22.10 (gstreamer)   691d5d52f59ec6322a2f6ddc1039ef47c9ac5e6328e2df1ef920629b46c659df
     81 
     82 You can close liblash with git clone git://holbrook.no/liblash
     83 
     84 (*liblash is now bundled in the src/aux directory)
     85 
     86 Building
     87 
     88 There are instructions on building and running with qemu and Debian
     89 Bookworm (12) in README.qemu.adoc
     90 
     91 There is no magic pathfinder implemented currently. Thus, you must
     92 configure the environment for building and linking the external sources
     93 yourself.
     94 
     95 Here is what I use in my local setup.
     96 
     97 libcmime
     98 
     99 I can't seem to set the cmake build prefix so that the libcmime.pc file
    100 is generated correctly. Unfortunately, pkg-config is thus off the table.
    101 
    102     git clone -b 0.2.2 https://github.com/spmfilter/libcmime.git
    103     https://github.com/spmfilter/libcmime.git
    104     mkdir -p libcmime/build
    105     cd libcmime/build
    106     cmake ..
    107     make install DESTDIR=.
    108 
    109 Your include path, relative to the repository root directory, will be
    110 <repo_root>/build/usr/include/lib64 and your ld path will be
    111 build/usr/include/lib64.
    112 
    113 libgstgtk4 (gst-plugin-rs)
    114 
    115 The gtk4 part of the code uses the gtk4paintablesink gstreamer plugin
    116 (for QR scanning). It is part of the gst-plugins-rs source above, built
    117 as the libgstgtk4.so shared library file.
    118 
    119 The specific package to build is gst-plugin-gtk4, which builds the
    120 plugin at version 0.9.13.
    121 
    122 I was able to build with toolchain 1.75-x86_64-unknown-linux-gnu.
    123 
    124     rustup default 1.75.0
    125     cargo install cargo-c
    126     git clone -b gstreamer-1.22.10 https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs
    127     cd gst-plugins-rs
    128     cargo cbuild -p gst-plugin-gtk4
    129 
    130 Environment
    131 
    132     #!/bin/bash
    133 
    134     set -x
    135 
    136     export GST_PLUGIN_PATH=/home/lash/src/build/gst-plugins-rs/target/x86_64-unknown-linux-gnu/debug/
    137     export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64/pkgconfig
    138     export LIBRARY_PATH=$LIBRARY_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64:/home/lash/src/home/liblash/src
    139     export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64:/home/lash/src/home/liblash/src
    140     export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/include:/home/lash/src/home/liblash/src
    141 
    142     make run
    143 
    144     set +x
    145 
    146 Here is some background if you need:
    147 
    148 -   C_INCLUDE_PATH
    149 -   LIBRARY_PATH
    150 -   LD_LIBRARY_PATH
    151 -   Difference between LD_LIBRARY_PATH and LIBRARY_PATH
    152 -   PKG_CONFIG_PATH
    153 -   GST_PLUGIN_PATH
    154 -   cargo-c
    155 
    156 Running
    157 
    158 In order to run the GTK application in its current condition, generated
    159 test data should be used as data path.
    160 
    161 Take care to install python dependencies in requirements.txt before the
    162 first command. Using a virtual environment is recommended. The author is
    163 using python 3.12.x.
    164 
    165     make testdata
    166     export KEE_PATH=$(realpath ./testdata)
    167     make run
    168 
    169 The testdata contains private keys for both Alice and Bob in the
    170 generated entries. To start as Bob, add before running:
    171 
    172     export KEE_KEY_PATH=$(realpath ./testdata/crypt_reverse)
    173 
    174 Protocol
    175 
    176 TODO: The terms need to be tightened up; don't use different terms for
    177 same thing.
    178 
    179 The serialization format of the credit issuance is defined in
    180 src/asb1/schema_entry.txt. The serialization method is der-encoding.
    181 
    182 More about asn1 here: https://luca.ntop.org/Teaching/Appunti/asn1.html.
    183 
    184 The protocol uses Elliptic Curve signatures. The curve used is Ed25519.
    185 
    186 Concepts
    187 
    188 The protocol consists of a series of ledgers, each with two
    189 participants, Alice and Bob.
    190 
    191 Alice and Bob are identified by their public keys.
    192 
    193 The protocol tracks an amount of credit issued by one party to another.
    194 
    195 The ledger may also define an amount of collateral that has been pledged
    196 against the credit.
    197 
    198 Credit and collateral are defined by a unit of account, which is defined
    199 for the entire ledger.
    200 
    201 Each credit issuance consists of one or more deltas (KeeEntry) changing
    202 the balance of the credit, and some identical metadata (KeeEntryHead)
    203 embedded in each one, together called an entry item.
    204 
    205 Creating a new entry
    206 
    207 We call the creator of the entry Alice.
    208 
    209 The default values of signatureRequest and signatureResponse is an empty
    210 octet string (length 0).
    211 
    212 The default value for response is False.
    213 
    214 If the entry is the first in the ledger, the value of parent is 64
    215 0-bytes. If not, it is the sha512 sum of the preceding entry item.
    216 
    217 Alice generates the entry item and signs it:
    218 
    219     head = der(KeeEntryHead)
    220     headsum = sha512(head)
    221     entry = der(KeeEntry)
    222     msg = sha512(concat(head, entry)
    223     sig = sign(msg) # TODO verify whether an additional sha512 on the message is performed by the internals
    224     copy(KeeEntry.signatureRequest, sig)
    225 
    226 Counter-signing an entry
    227 
    228 Alice shares KeeEntryHead and KeeEntry with Bob.
    229 
    230 Bob verifies Alice's signature.
    231 
    232 If Bob accepts the contents of the entry item, he sets response to True.
    233 
    234 Bob proceeds to sign the entry item:
    235 
    236     set(KeeEntry.response, bobs_decision)
    237     head = der(KeeEntryHead)
    238     headsum = sha512(head)
    239     entry = der(KeeEntry)
    240     msg = sha512(concat(head, entry)
    241     sig = sign(msg)
    242     copy(KeeEntry.signatureResponse, sig)
    243 
    244 Bob then adds the counter-signed entry item to his persistent storage.
    245 
    246 Sharing the result
    247 
    248 Bob shares KeeEntryHead and KeeEntry with Alice.
    249 
    250 Alice verifies both signatures.
    251 
    252 Alice adds the counter-signed entry_item to her persistent storage.
    253 
    254 Alice and Bob now have the same ledger state, adjusted by the deltas in
    255 the entry item.
    256 
    257 Sanity checks
    258 
    259 Checking that the delta in an entry item makes sense is the
    260 responsibility of both parties, e.g. that the delta does not incur a
    261 negative credit value.
    262 
    263 Descriptive content
    264 
    265 Both the KeeEntryHead and KeeEntry structures include an optional body
    266 value, which is a sha512 hash of some content offering some description
    267 of what the ledger and individual changes consist of. If no description
    268 is provided, 64 0-bytes are used for the data field.
    269 
    270 This implementation uses, as previously mentioned, MIME-structures for
    271 this purpose.
    272 
    273 Data carriers
    274 
    275 A final implementation should define several ways of sharing content,
    276 including:
    277 
    278 -   Copy and paste
    279 -   File sharing
    280 -   Network retrieval
    281 -   QR codes This implementation uses QR codes to exchange signature
    282     requests and signatures.
    283 
    284 QR exchange
    285 
    286 A separate transport container, KeeTransport, is used for this exchange,
    287 as well as some additional encoding.
    288 
    289     container = KeeTransport(KeeEntryHead, KeeEntry)
    290     raw = der(container)
    291     compressed = zlib_compress(raw)
    292     payload = base64(compressed)
    293     transport = concat(0x02, readable) # 0x02 = KEE_CMD_LEDGER, defined in src/transport.h
    294     qrencode(transport)
    295 
    296 Sharing descriptive content
    297 
    298 Descriptive content is currently not shared as part of the signature
    299 exchange.
    300 
    301 Since decriptive content can potentially be of some size, a transport
    302 protocol should be considered which can span multiple sequential QR
    303 codes, and allow of the same kind of offline exchange as the signature
    304 exchange itself.
    305 
    306 Examples
    307 
    308 The make testdata script creates several useful data examples:
    309 
    310 -   testdata/mdb which is the persistent storage of a ledger and
    311     required indicies. Can be easily viewed using the mdb_dump command.
    312     Key prefixes are defined in src/db.h:enum DbKey
    313 -   testdata/crypt contains alice and bob's private and public keys in
    314     sexp format, as well as an encrypted version of the private keys. The
    315     encryption used is CHACHA20-POLY1305, and password for both keys is
    316     1234. The kee.key symlink points to the private key (Alice) used by
    317     the GTK application.
    318 -   testdata/crypt_reverse contains a symlink kee.key to Bob's encrypted
    319     private key, enabling use of the GTK application as Bob.
    320 -   testdata/import Three files respresenting all phases of the entry
    321     item format:
    322     -   request - without signatures.
    323     -   response - with Alice's signature.
    324     -   final - with both signatures.
    325 -   testdata/resource All descriptive content for the generated ledgers
    326     and entry items.
    327 
    328 License
    329 
    330 GPLv3