Skip to content

VasiliyS/kerilex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Kerilex

This is an experimental implementation of KERI protocol that aims to be compatible with the vLEI ecosystem

The goal of this project is to build a "validator" component that allows to monitor KERI AIDs and maintain up to date key state.

It currently consists of two parts:

  • Kerilex - low-level functionality to parse and validate KELs, plus some ability to create and sign certain type of events.
  • Watcher - building blocks that can be used to create a continuously running validator.

Status

Alpha - expect continuous changes as I explore various ways to deal with asynchronous nature of KERI and its infrastructure components.

The Modules and their "shape" are changing as I try to find the optimal decomposition. Documentation is sparse and typespecs are not always defined.

Currently supported features

  • parses KERI 1.0 KELs - icp, dip, rot, drt and ixn messages along with the typical CESR attachments
  • allows creation of icp , rpy ( endpoint), qry messages along with signing.
  • Generates signers based on CESR salt, which allows to have signers identical to those generated by keripy's kli.
  • Watcher has asynchronous qry/response component (Watcher.WitnessClient) that can send and process various qry messages and collects indexed response from a mailbox
  • Watcher also has OOBI processor that will take the output of a Kerilex.KELparser.parse and, if all checks run though, will fill mnesia based tables with the processed events and output a %KeyStateCache{} containing calculated key states of AIDs that were included in the OOBI response.

How to try

Prerequisites

  1. Elixir - 1.17 and OTP27
  2. dev version of libsodium
  3. c toolchain to compile libsodium nif
  4. Rust to compile blake3
  5. setup proper variables pointing to the installed libs
    • E.g. for mac, if using brew (works on m1/m3)
      LDFLAGS=-L/opt/homebrew/include
      C_INCLUDE_PATH=/opt/homebrew/include
      CPLUS_INCLUDE_PATH=/opt/homebrew/include
      LIBRARY_PATH=/opt/homebrew/lib

from the project's root directory get and compile dependencies.

 mix deps.get
 mix deps.compile

You can either use the iex to paly with the API or use livebook to see how the Watcher functionality works.

Explore the API

mkdir -p tmp/db

iex -S mix
:mnesia.stop
:mnesia.create_schema([node()])
:mnesia.start

Watcher.KeyStateStore.init_tables

alias Watcher.{OOBI.LogsProcessor, EventEscrow}

gleif_geda_kel = File.read!("test/data/gleif-kel-july-23-24") |> Kerilex.KELParser.parse

gleif_geda_kel |> LogsProcessor.process_kel(EventEscrow.new())

output

18:23:26.910 [debug] [type: "icp", msg: "added event", result: "updated KEL", pre: "EDP1vHcw_wc4M__Fj53-cJaBnZZASd-aMTaSyWEQ-PC2", sn: 0]

18:23:26.912 [debug] [type: "rot", msg: "added event", result: "updated KEL", pre: "EDP1vHcw_wc4M__Fj53-cJaBnZZASd-aMTaSyWEQ-PC2", sn: 1]

18:23:26.913 [debug] [type: "rot", msg: "added event", result: "updated KEL", pre: "EDP1vHcw_wc4M__Fj53-cJaBnZZASd-aMTaSyWEQ-PC2", sn: 2]

18:23:26.914 [debug] [type: "dip", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 0]

18:23:26.915 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 1]

18:23:26.915 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 2]

18:23:26.916 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 3]

18:23:26.916 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 4]

18:23:26.916 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 5]

18:23:26.917 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 6]

18:23:26.917 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 7]

18:23:26.918 [debug] [type: "ixn", msg: "added event", result: "updated KEL", pre: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS", sn: 8]

18:23:26.918 [debug] [type: "rpy", msg: "added event", result: "added witness", url: "http://65.21.253.212:5623/"]

18:23:26.918 [debug] [type: "rpy", msg: "added event", result: "added witness", url: "http://8.210.213.186:5623/"]

18:23:26.919 [debug] [type: "rpy", msg: "added event", result: "added witness", url: "http://51.79.54.121:5623/"]

18:23:26.919 [debug] [type: "rpy", msg: "added event", result: "added witness", url: "http://102.37.159.99:5623/"]

18:23:26.919 [debug] [type: "rpy", msg: "added event", result: "added witness", url: "http://54.233.109.129:5623/"]

18:23:26.919 [debug] [msg: "finished processing KEL messages", kel_length: 17]
{:ok, %Watcher.EventEscrow{store: %{}},
 %Watcher.KeyStateCache{
   cache: %{
     "EDP1vHcw_wc4M__Fj53-cJaBnZZASd-aMTaSyWEQ-PC2" => %Watcher.KeyState{
       pe: "ECphNWm1_jZOupeKh6C7TlBi81BlERqbnMpyqpnS4CJY",
       te: "rot",
       se: 2,
       de: "EHsL1ldIafZC-M9-3RgLQB3m2_2F0aYIiNBGnTVoFDH2",
       fs: "2024-10-25T16:23:26.910544Z",
       k: ["DNLdWqTBKOhDO8YfE5uIaTvN-n_Jv20-5ZwK609BvG0b",
        "DL68G7IW4zT2ryLRDziYiRyvwIDyq9xssVuZ3u6w-30Y",
        "DH63RGGv_r8pQ5Di9MVblcofkBm0O8r6SUY0cqNAYqne"],
       kt: %Kerilex.Crypto.WeightedKeyThreshold{
         size: 3,
         weights: [Ratio.new(1, 3), Ratio.new(1, 3), Ratio.new(1, 3)],
         sum: Ratio.new(1, 1),
         ind_ranges: [0..2]
       },
       n: ["EPHYDUnxDH7xcAim3aYvS9bvh7JmdBDKc__w2_McXr6I",
        "EHgOexUh8AvN7rXblsSr6MJE5Gn1HPq5Mv9KFpCpllKN",
        "ECH4pTtUI653ykKb_capPBkKF3RvBZRzyb5dPfuJCfOf",
        "ELXXiPwoaWOVOTLMOAmg4IKkjFHFs3q2hsL9tHvuuC2D",
        "EAcNrjXFeGay9qqMj96FIiDdXqdWjX17QXzdJvq58Zco",
        "EF1IPGq_uF3FmywFdIQXSO4jy0QhtzREVMlPQ8PEy_As",
        "EHGlZciB0cZ627-MJrQxyw5niNzN1nKnNMDaJO7sCEvF"],
       nt: %Kerilex.Crypto.WeightedKeyThreshold{
         size: 7,
         weights: [Ratio.new(1, 3), Ratio.new(1, 3), Ratio.new(1, 3),
          Ratio.new(1, 3), Ratio.new(1, 3), Ratio.new(1, 3), Ratio.new(1, 3)],
         sum: Ratio.new(7, 3),
         ind_ranges: [0..6]
       },
       b: ["BNfDO63ZpGc3xiFb0-jIOUnbr_bA-ixMva5cZb3s4BHB",
        "BDwydI_FJJ-tvAtCl1tIu_VQqYTI3Q0JyHDhO1v2hZBt",
        "BGYJwPAzjyJgsipO7GY9ZsBTeoUJrdzjI2w_5N-Nl6gG",
        "BM4Ef3zlUzIAIx-VC8mXziIbtj-ZltM8Aor6TZzmTldj",
        "BLo6wQR73-eH5v90at_Wt8Ep_0xfz05qBjM3_B1UtKbC"],
       bt: 4,
       c: ["EO"],
       di: false,
       last_event: {"rot", 2, "EHsL1ldIafZC-M9-3RgLQB3m2_2F0aYIiNBGnTVoFDH2"}
     },
     "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS" => %Watcher.KeyState{
       pe: nil,
       te: "dip",
       se: 0,
       de: "EINmHd5g7iV-UldkkkKyBIH052bIyxZNBn9pq-zNrYoS",
       fs: "2024-10-25T16:23:26.914180Z",
       k: ["DEO7QT90CzPeCubjcAgDlYI-yudt0c_4HeAb1_RbrGiF",
        "DKu6Q_Qth7x-pztt11qXDr42B9aUjkp_v9Rq8-xXcQjF",
        "DEiPSxcuILZFxJscr_Lt8fuiidhB_HrqKxoCbZr9tQfp",
        "DIqrjqqwArsSHIX3n510DnSrYL9ULbYOpi14hEencBSC",
        "DAB9Tl0T8-638H65GMFj2G7CAr4CoExZ5xH-U1ADldFP"],
       kt: %Kerilex.Crypto.WeightedKeyThreshold{
         size: 5,
         weights: [Ratio.new(1, 2), Ratio.new(1, 2), Ratio.new(1, 2),
          Ratio.new(1, 2), Ratio.new(1, 2)],
         sum: Ratio.new(5, 2),
         ind_ranges: [0..4]
       },
       n: ["EObLskWwczY3R-ALRPWiyyThtraelnbh6MMeJ_WcR3Gd",
        "ENoI2e5f59xEF83joX__915Va-OIE7480wWyh2-8bJk7",
        "EElSAVDf2vU8aoxN50eSMNm6MrQ-Hv_2xOWC02tFrS3M",
        "EHX0Re-hExzl7mvLuRwQHEew-8oPOQh4rqXJNHBo9EyW",
        "EBGeYe1_ZgN_ly0qVY-Y1FayZkNA5Yq9LTujrh2ylKbm"],
       nt: %Kerilex.Crypto.WeightedKeyThreshold{
         size: 5,
         weights: [Ratio.new(1, 2), Ratio.new(1, 2), Ratio.new(1, 2),
          Ratio.new(1, 2), Ratio.new(1, 2)],
         sum: Ratio.new(5, 2),
         ind_ranges: [0..4]
       },
       b: ["BDkq35LUU63xnFmfhljYYRY0ymkCg7goyeCxN30tsvmS",
        "BLmvLSt1mDShWS67aJNP4gBVBhtOc3YEu8SytqVSsyfw",
        "BHxz8CDS_mNxAhAxQe1qxdEIzS625HoYgEMgqjZH_g2X",
        "BGYJwPAzjyJgsipO7GY9ZsBTeoUJrdzjI2w_5N-Nl6gG",
        "BFl6k3UznzmEVuMpBOtUUiR2RO2NZkR3mKrZkNRaZedo"],
       bt: 4,
       c: [],
       di: "EDP1vHcw_wc4M__Fj53-cJaBnZZASd-aMTaSyWEQ-PC2",
       last_event: {"ixn", 8, "EDxDCjQoH82EgDEcSAU1SD__VKoebRUgr95nFweJxMgu"}
     }
   },
   recoveries: []
 }, 17}

Livebook demo

Prerequisites

  1. Install Elixir as outlined above

  2. Install livebook

    If you are not familiar with it, livebook is analogous to the Python's Jupiter Notebook

  3. From the root directory of the Kerilex repo start iex as follows:

     iex --name [email protected] --cookie demo -S mix
  4. Start livebook

  5. Connect livebook to the running node using name and cookie as parameters.

  6. open experimental/demo/watcher.livemd file.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published