Files
herolib/manual/core/concepts/name_registry.md
2024-12-25 08:40:56 +01:00

3.9 KiB

we are building a decentralized DNS system

  • the DNS system is stored in a filedb, which is a directory with subdirs where directory structure + file name, defines the key
  • we store pubkeys (32 bytes) and names (like dns names)-
  • the public key gets mapped to a unique id per filedb dir
  • each person can register 1 or more names (max 12 characters, min 3)
  • these names are unique per repo and linked to the id of the public key
  • a name can be owned by min 1, max 5 public keys (names can be co-owned) = means max 4 bytes x 5 to identify which users own a name
  • we represent database for public keys and names as directory structures
  • database for public keys
    • each pubkey as remembered in the file database in the repo on $repodir/keys gets a unique incremental key = int
    • we have max 256 dirs and 256 files, where the name is first byte expressed as hex
    • e.g. hex(999999) = 'f423f', this results in $repodir/keys/f4/23.txt
    • in each txt file we \n separate the entries (each line is pubkey\n)
    • 999999 -> f4/23 then f (remainder) gets converted back to int and this is the element in the list in 23.txt (the Xe line)
    • this means max nr of dirs:65536, max nr of elements in file = 152 items, line separated
    • this means it goes fast to process one txt file to retrieve relation between id and pubkey
    • this db allows gast retrieval of pubkey based on int (unique per file db dir)
    • the order of the lines is never changed, new data always added so we keep unique id (int)
  • database for names
    • names are ascii only with ofcourse '.' as separator
    • names are 2 levels e.g. kristof.belgium
    • we hash the name md5, take first 2 chars as identifier for directory, the next 2 chars as text file with the names
    • e.g. /data/repo1/names/aa/bb.txt (aa would be first 2 chars of md5, bb next 2 chars of md5)
    • names are in that bb.txt file (example), they are added as they come in
    • the linenr is the unique id in that file, which means each name has unique id as follows
      • aabb1 (position 1) would result to: aabb -> int + 1, e.g. position 999 would be hex2int(aabb)+999
      • this would be the unique int
    • per line we store the following: $name(lowercase, ascii):f423f,a4233:signature
      • this means 2 pub keys linked to the name
      • the link is done by an id (as described above, which can then be mapped back to pubkey)
      • the signature is secp256k1 signature which can be verified by everyone who reads this file, only 1 of users need to sign
        • the signature is on name+the id's of who owns the name (so we verify ownership)
    • the order of the lines is never changed, new data always added so we keep unique id (int)

now create the following python functions and implement above

#register pubkey in the pubkey db, return the int
def key_register(pubkey) -> int

class NamePreparation:
  name str
  pubkeys []int #position of each pubkey in the pubkey db
  signature []u8 #bytestr of the secp256k1 signature

  #sign name + int's (always concatenated in same way) with given privkey
  #the result is stored in signature on class
  def sign(privkey):
    #need to check that priv key given is part of the pubkeys

  #return str representation which is $name:f423f,a4233,...:$signature
  def str() -> str:
      ...

#name will be lowercased, trimmed space
#max 1 dot in name (2 levels in DNS, top and 1 down)
#signature is secp256k and will be verified in this function against all given pubkeys
#the first pubkey need to have signed the name + 
#returns the inique id of the name in this filedb repo
def name_register(name:str,pubkeys:[]str,privkey:...) -> int:
  #will use NamePreparation functionality
  #str() will give the right str which is added as newline to the right file in the filedb

#find the name, NotFound exception when name not found, 
#if verify on then will check the signature vs the first pubkey of the list
def name_get(id:int,verify:bool=True) -> str:

def key_get(id:int) -> PubKey: