Hex Artifact Content
Not logged in

Artifact 9efe463902885bbb75d023092b182e3ed2ce1c42:


0000: 5c 20 6e 65 74 32 6f 20 6b 65 79 20 73 74 6f 72  \ net2o key stor
0010: 61 67 65 0a 0a 5c 20 43 6f 70 79 72 69 67 68 74  age..\ Copyright
0020: 20 28 43 29 20 32 30 31 30 2d 32 30 31 35 20 20   (C) 2010-2015  
0030: 20 42 65 72 6e 64 20 50 61 79 73 61 6e 0a 0a 5c   Bernd Paysan..\
0040: 20 54 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73   This program is
0050: 20 66 72 65 65 20 73 6f 66 74 77 61 72 65 3a 20   free software: 
0060: 79 6f 75 20 63 61 6e 20 72 65 64 69 73 74 72 69  you can redistri
0070: 62 75 74 65 20 69 74 20 61 6e 64 2f 6f 72 20 6d  bute it and/or m
0080: 6f 64 69 66 79 0a 5c 20 69 74 20 75 6e 64 65 72  odify.\ it under
0090: 20 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68   the terms of th
00a0: 65 20 47 4e 55 20 41 66 66 65 72 6f 20 47 65 6e  e GNU Affero Gen
00b0: 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69 63 65  eral Public Lice
00c0: 6e 73 65 20 61 73 20 70 75 62 6c 69 73 68 65 64  nse as published
00d0: 20 62 79 0a 5c 20 74 68 65 20 46 72 65 65 20 53   by.\ the Free S
00e0: 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 61 74 69  oftware Foundati
00f0: 6f 6e 2c 20 65 69 74 68 65 72 20 76 65 72 73 69  on, either versi
0100: 6f 6e 20 33 20 6f 66 20 74 68 65 20 4c 69 63 65  on 3 of the Lice
0110: 6e 73 65 2c 20 6f 72 0a 5c 20 28 61 74 20 79 6f  nse, or.\ (at yo
0120: 75 72 20 6f 70 74 69 6f 6e 29 20 61 6e 79 20 6c  ur option) any l
0130: 61 74 65 72 20 76 65 72 73 69 6f 6e 2e 0a 0a 5c  ater version...\
0140: 20 54 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73   This program is
0150: 20 64 69 73 74 72 69 62 75 74 65 64 20 69 6e 20   distributed in 
0160: 74 68 65 20 68 6f 70 65 20 74 68 61 74 20 69 74  the hope that it
0170: 20 77 69 6c 6c 20 62 65 20 75 73 65 66 75 6c 2c   will be useful,
0180: 0a 5c 20 62 75 74 20 57 49 54 48 4f 55 54 20 41  .\ but WITHOUT A
0190: 4e 59 20 57 41 52 52 41 4e 54 59 3b 20 77 69 74  NY WARRANTY; wit
01a0: 68 6f 75 74 20 65 76 65 6e 20 74 68 65 20 69 6d  hout even the im
01b0: 70 6c 69 65 64 20 77 61 72 72 61 6e 74 79 20 6f  plied warranty o
01c0: 66 0a 5c 20 4d 45 52 43 48 41 4e 54 41 42 49 4c  f.\ MERCHANTABIL
01d0: 49 54 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46  ITY or FITNESS F
01e0: 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52 20  OR A PARTICULAR 
01f0: 50 55 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68  PURPOSE.  See th
0200: 65 0a 5c 20 47 4e 55 20 41 66 66 65 72 6f 20 47  e.\ GNU Affero G
0210: 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69  eneral Public Li
0220: 63 65 6e 73 65 20 66 6f 72 20 6d 6f 72 65 20 64  cense for more d
0230: 65 74 61 69 6c 73 2e 0a 0a 5c 20 59 6f 75 20 73  etails...\ You s
0240: 68 6f 75 6c 64 20 68 61 76 65 20 72 65 63 65 69  hould have recei
0250: 76 65 64 20 61 20 63 6f 70 79 20 6f 66 20 74 68  ved a copy of th
0260: 65 20 47 4e 55 20 41 66 66 65 72 6f 20 47 65 6e  e GNU Affero Gen
0270: 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69 63 65  eral Public Lice
0280: 6e 73 65 0a 5c 20 61 6c 6f 6e 67 20 77 69 74 68  nse.\ along with
0290: 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e 20 20   this program.  
02a0: 49 66 20 6e 6f 74 2c 20 73 65 65 20 3c 68 74 74  If not, see <htt
02b0: 70 3a 2f 2f 77 77 77 2e 67 6e 75 2e 6f 72 67 2f  p://www.gnu.org/
02c0: 6c 69 63 65 6e 73 65 73 2f 3e 2e 0a 0a 72 65 71  licenses/>...req
02d0: 75 69 72 65 20 6d 6b 64 69 72 2e 66 73 0a 0a 5c  uire mkdir.fs..\
02e0: 20 61 63 63 65 70 74 20 66 6f 72 20 70 61 73 73   accept for pass
02f0: 77 6f 72 64 20 65 6e 74 72 79 0a 0a 32 20 56 61  word entry..2 Va
0300: 6c 75 65 20 70 77 2d 6c 65 76 65 6c 23 20 5c 20  lue pw-level# \ 
0310: 70 77 2d 6c 65 76 65 6c 23 20 30 20 69 73 20 6c  pw-level# 0 is l
0320: 6f 77 65 73 74 0a 0a 5b 49 46 44 45 46 5d 20 61  owest..[IFDEF] a
0330: 6e 64 72 6f 69 64 78 78 78 20 27 2a 27 20 5b 45  ndroidxxx '*' [E
0340: 4c 53 45 5d 20 27 e2 ac a4 27 20 5b 54 48 45 4e  LSE] '⬤' [THEN
0350: 5d 20 43 6f 6e 73 74 61 6e 74 20 70 77 2a 0a 0a  ] Constant pw*..
0360: 78 63 2d 76 65 63 74 6f 72 20 75 70 40 20 2d 20  xc-vector up@ - 
0370: 63 6c 61 73 73 2d 6f 20 21 0a 0a 30 20 63 65 6c  class-o !..0 cel
0380: 6c 20 75 76 61 72 20 65 73 63 2d 73 74 61 74 65  l uvar esc-state
0390: 20 64 72 6f 70 0a 0a 44 65 66 65 72 20 6f 6c 64   drop..Defer old
03a0: 2d 65 6d 69 74 20 20 77 68 61 74 27 73 20 65 6d  -emit  what's em
03b0: 69 74 20 69 73 20 6f 6c 64 2d 65 6d 69 74 0a 0a  it is old-emit..
03c0: 68 65 72 65 0a 78 63 2d 76 65 63 74 6f 72 20 40  here.xc-vector @
03d0: 20 63 65 6c 6c 2d 20 64 75 70 20 40 20 74 75 63   cell- dup @ tuc
03e0: 6b 20 2d 20 68 65 72 65 20 73 77 61 70 20 64 75  k - here swap du
03f0: 70 20 61 6c 6c 6f 74 20 6d 6f 76 65 0a 2c 20 68  p allot move., h
0400: 65 72 65 20 30 20 2c 20 43 6f 6e 73 74 61 6e 74  ere 0 , Constant
0410: 20 75 74 66 2d 38 2a 0a 0a 3a 20 2a 2d 77 69 64   utf-8*..: *-wid
0420: 74 68 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6e  th ( addr u -- n
0430: 20 29 0a 20 20 20 20 30 20 2d 72 6f 74 20 62 6f   ).    0 -rot bo
0440: 75 6e 64 73 20 3f 44 4f 20 20 49 20 63 40 20 24  unds ?DO  I c@ $
0450: 43 30 20 24 38 30 20 77 69 74 68 69 6e 20 2d 20  C0 $80 within - 
0460: 20 4c 4f 4f 50 20 3b 0a 0a 78 63 2d 76 65 63 74   LOOP ;..xc-vect
0470: 6f 72 20 40 20 20 75 74 66 2d 38 2a 20 78 63 2d  or @  utf-8* xc-
0480: 76 65 63 74 6f 72 20 21 20 27 20 2a 2d 77 69 64  vector ! ' *-wid
0490: 74 68 20 69 73 20 78 2d 77 69 64 74 68 20 20 78  th is x-width  x
04a0: 63 2d 76 65 63 74 6f 72 20 21 0a 0a 3a 20 65 6d  c-vector !..: em
04b0: 69 74 2d 70 77 2a 20 28 20 6e 20 2d 2d 20 29 0a  it-pw* ( n -- ).
04c0: 20 20 20 20 64 75 70 20 23 65 73 63 20 3d 20 49      dup #esc = I
04d0: 46 20 20 65 73 63 2d 73 74 61 74 65 20 6f 6e 20  F  esc-state on 
04e0: 20 54 48 45 4e 0a 20 20 20 20 64 75 70 20 62 6c   THEN.    dup bl
04f0: 20 3c 20 49 46 20 20 6f 6c 64 2d 65 6d 69 74 20   < IF  old-emit 
0500: 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20   EXIT  THEN.    
0510: 65 73 63 2d 73 74 61 74 65 20 40 20 49 46 20 20  esc-state @ IF  
0520: 64 75 70 20 6f 6c 64 2d 65 6d 69 74 0a 20 20 20  dup old-emit.   
0530: 20 45 4c 53 45 20 20 64 75 70 20 24 43 30 20 24   ELSE  dup $C0 $
0540: 38 30 20 77 69 74 68 69 6e 20 49 46 0a 09 20 20  80 within IF..  
0550: 20 20 5b 20 70 77 2a 20 27 20 78 65 6d 69 74 20    [ pw* ' xemit 
0560: 24 74 6d 70 0a 09 20 20 20 20 62 6f 75 6e 64 73  $tmp..    bounds
0570: 20 5b 3f 44 4f 5d 20 5b 49 5d 20 63 40 20 5d 4c   [?DO] [I] c@ ]L
0580: 20 6f 6c 64 2d 65 6d 69 74 20 5b 20 5b 4c 4f 4f   old-emit [ [LOO
0590: 50 5d 20 5d 0a 09 54 48 45 4e 0a 20 20 20 20 54  P] ]..THEN.    T
05a0: 48 45 4e 0a 20 20 20 20 74 6f 75 70 70 65 72 20  HEN.    toupper 
05b0: 27 41 27 20 27 5b 27 20 77 69 74 68 69 6e 20 49  'A' '[' within I
05c0: 46 20 20 65 73 63 2d 73 74 61 74 65 20 6f 66 66  F  esc-state off
05d0: 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 74 79 70 65    THEN ;..: type
05e0: 2d 70 77 2a 20 28 20 61 64 64 72 20 75 20 2d 2d  -pw* ( addr u --
05f0: 20 29 20 20 32 64 75 70 20 62 6c 20 73 6b 69 70   )  2dup bl skip
0600: 20 6e 69 70 20 30 3d 0a 20 20 20 20 49 46 20 20   nip 0=.    IF  
0610: 20 20 62 6f 75 6e 64 73 20 55 2b 44 4f 20 20 62    bounds U+DO  b
0620: 6c 20 6f 6c 64 2d 65 6d 69 74 20 20 20 20 4c 4f  l old-emit    LO
0630: 4f 50 0a 20 20 20 20 45 4c 53 45 20 20 62 6f 75  OP.    ELSE  bou
0640: 6e 64 73 20 55 2b 44 4f 20 20 49 20 63 40 20 65  nds U+DO  I c@ e
0650: 6d 69 74 2d 70 77 2a 20 20 4c 4f 4f 50 20 20 54  mit-pw*  LOOP  T
0660: 48 45 4e 20 3b 0a 0a 3a 20 61 63 63 65 70 74 2a  HEN ;..: accept*
0670: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 75 27 20   ( addr u -- u' 
0680: 29 0a 20 20 20 20 5c 47 20 61 63 63 65 70 74 2d  ).    \G accept-
0690: 6c 69 6b 65 20 69 6e 70 75 74 2c 20 62 75 74 20  like input, but 
06a0: 74 79 70 65 73 20 2a 20 69 6e 73 74 65 61 64 20  types * instead 
06b0: 6f 66 20 74 68 65 20 63 68 61 72 61 63 74 65 72  of the character
06c0: 0a 20 20 20 20 5c 47 20 64 6f 6e 27 74 20 73 61  .    \G don't sa
06d0: 76 65 20 69 6e 74 6f 20 68 69 73 74 6f 72 79 0a  ve into history.
06e0: 20 20 20 20 68 69 73 74 6f 72 79 20 3e 72 20 20      history >r  
06f0: 77 68 61 74 27 73 20 74 79 70 65 20 3e 72 20 20  what's type >r  
0700: 77 68 61 74 27 73 20 65 6d 69 74 20 69 73 20 6f  what's emit is o
0710: 6c 64 2d 65 6d 69 74 0a 20 20 20 20 75 74 66 2d  ld-emit.    utf-
0720: 38 2a 20 78 63 2d 76 65 63 74 6f 72 20 21 40 20  8* xc-vector !@ 
0730: 3e 72 20 20 5b 27 5d 20 74 79 70 65 2d 70 77 2a  >r  ['] type-pw*
0740: 20 69 73 20 74 79 70 65 20 20 5b 27 5d 20 65 6d   is type  ['] em
0750: 69 74 2d 70 77 2a 20 69 73 20 65 6d 69 74 0a 20  it-pw* is emit. 
0760: 20 20 20 30 20 74 6f 20 68 69 73 74 6f 72 79 0a     0 to history.
0770: 20 20 20 20 5b 27 5d 20 61 63 63 65 70 74 20 63      ['] accept c
0780: 61 74 63 68 0a 20 20 20 20 72 3e 20 78 63 2d 76  atch.    r> xc-v
0790: 65 63 74 6f 72 20 21 20 20 77 68 61 74 27 73 20  ector !  what's 
07a0: 6f 6c 64 2d 65 6d 69 74 20 69 73 20 65 6d 69 74  old-emit is emit
07b0: 20 20 72 3e 20 69 73 20 74 79 70 65 20 20 72 3e    r> is type  r>
07c0: 20 74 6f 20 68 69 73 74 6f 72 79 0a 20 20 20 20   to history.    
07d0: 74 68 72 6f 77 20 2d 31 20 30 20 61 74 2d 64 65  throw -1 0 at-de
07e0: 6c 74 61 78 79 20 73 70 61 63 65 20 3b 0a 0a 5c  ltaxy space ;..\
07f0: 20 4b 65 79 73 20 61 72 65 20 70 61 73 73 77 6f   Keys are passwo
0800: 72 64 73 20 61 6e 64 20 70 72 69 76 61 74 65 20  rds and private 
0810: 6b 65 79 73 20 28 73 65 6c 66 2d 6b 65 79 65 64  keys (self-keyed
0820: 2c 20 69 2e 65 2e 20 70 72 69 76 61 74 65 2a 70  , i.e. private*p
0830: 75 62 6c 69 63 20 6b 65 79 29 0a 0a 63 6d 64 2d  ublic key)..cmd-
0840: 62 75 66 30 20 75 63 6c 61 73 73 20 63 6d 64 62  buf0 uclass cmdb
0850: 75 66 2d 6f 0a 20 20 20 20 6d 61 78 64 61 74 61  uf-o.    maxdata
0860: 20 2d 0a 20 20 20 20 6b 65 79 2d 73 61 6c 74 23   -.    key-salt#
0870: 20 75 76 61 72 20 6b 65 79 70 61 63 6b 0a 20 20   uvar keypack.  
0880: 20 20 6b 65 79 70 61 63 6b 23 20 20 75 76 61 72    keypack#  uvar
0890: 20 6b 65 79 70 61 63 6b 2d 62 75 66 0a 20 20 20   keypack-buf.   
08a0: 20 6b 65 79 2d 63 6b 73 75 6d 23 20 75 76 61 72   key-cksum# uvar
08b0: 20 6b 65 79 70 61 63 6b 2d 63 68 6b 73 75 6d 0a   keypack-chksum.
08c0: 65 6e 64 2d 63 6c 61 73 73 20 63 6d 64 2d 6b 65  end-class cmd-ke
08d0: 79 62 75 66 2d 63 0a 0a 63 6d 64 2d 6b 65 79 62  ybuf-c..cmd-keyb
08e0: 75 66 2d 63 20 6e 65 77 20 63 6f 64 65 2d 6b 65  uf-c new code-ke
08f0: 79 5e 20 21 0a 27 20 63 6f 64 65 2d 6b 65 79 5e  y^ !.' code-key^
0900: 20 63 6d 64 62 75 66 3a 20 63 6f 64 65 2d 6b 65   cmdbuf: code-ke
0910: 79 0a 0a 63 6f 64 65 2d 6b 65 79 0a 63 6d 64 30  y..code-key.cmd0
0920: 6c 6f 63 6b 20 30 20 70 74 68 72 65 61 64 5f 6d  lock 0 pthread_m
0930: 75 74 65 78 5f 69 6e 69 74 20 64 72 6f 70 0a 0a  utex_init drop..
0940: 3a 6e 6f 6e 61 6d 65 20 28 20 2d 2d 20 61 64 64  :noname ( -- add
0950: 72 20 75 20 29 20 6b 65 79 70 61 63 6b 2d 62 75  r u ) keypack-bu
0960: 66 20 63 6d 64 62 75 66 23 20 40 20 3b 20 74 6f  f cmdbuf# @ ; to
0970: 20 63 6d 64 62 75 66 24 0a 3a 6e 6f 6e 61 6d 65   cmdbuf$.:noname
0980: 20 28 20 2d 2d 20 6e 20 29 20 20 6b 65 79 70 61   ( -- n )  keypa
0990: 63 6b 23 20 63 6d 64 62 75 66 23 20 40 20 2d 20  ck# cmdbuf# @ - 
09a0: 3b 20 74 6f 20 6d 61 78 73 74 72 69 6e 67 0a 0a  ; to maxstring..
09b0: 63 6f 64 65 30 2d 62 75 66 0a 0a 3a 6e 6f 6e 61  code0-buf..:nona
09c0: 6d 65 20 64 65 66 65 72 73 20 61 6c 6c 6f 63 2d  me defers alloc-
09d0: 63 6f 64 65 2d 62 75 66 73 0a 20 20 20 20 63 6d  code-bufs.    cm
09e0: 64 2d 6b 65 79 62 75 66 2d 63 20 6e 65 77 20 63  d-keybuf-c new c
09f0: 6f 64 65 2d 6b 65 79 5e 20 21 20 3b 20 69 73 20  ode-key^ ! ; is 
0a00: 61 6c 6c 6f 63 2d 63 6f 64 65 2d 62 75 66 73 0a  alloc-code-bufs.
0a10: 3a 6e 6f 6e 61 6d 65 20 64 65 66 65 72 73 20 66  :noname defers f
0a20: 72 65 65 2d 63 6f 64 65 2d 62 75 66 73 0a 20 20  ree-code-bufs.  
0a30: 20 20 63 6f 64 65 2d 6b 65 79 5e 20 40 20 2e 64    code-key^ @ .d
0a40: 69 73 70 6f 73 65 20 3b 20 69 73 20 66 72 65 65  ispose ; is free
0a50: 2d 63 6f 64 65 2d 62 75 66 73 0a 0a 5c 20 68 61  -code-bufs..\ ha
0a60: 73 68 65 64 20 6b 65 79 20 64 61 74 61 20 62 61  shed key data ba
0a70: 73 65 0a 0a 55 73 65 72 20 3e 73 74 6f 72 65 6b  se..User >storek
0a80: 65 79 0a 0a 63 6d 64 2d 63 6c 61 73 73 20 63 6c  ey..cmd-class cl
0a90: 61 73 73 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b  ass.    field: k
0aa0: 65 2d 73 6b 20 20 20 20 20 20 20 5c 20 73 65 63  e-sk       \ sec
0ab0: 72 65 74 20 6b 65 79 0a 20 20 20 20 66 69 65 6c  ret key.    fiel
0ac0: 64 3a 20 6b 65 2d 70 6b 20 20 20 20 20 20 20 5c  d: ke-pk       \
0ad0: 20 70 75 62 6c 69 63 20 6b 65 79 0a 20 20 20 20   public key.    
0ae0: 66 69 65 6c 64 3a 20 6b 65 2d 74 79 70 65 20 20  field: ke-type  
0af0: 20 20 20 5c 20 6b 65 79 20 74 79 70 65 0a 20 20     \ key type.  
0b00: 20 20 66 69 65 6c 64 3a 20 6b 65 2d 6e 69 63 6b    field: ke-nick
0b10: 20 20 20 20 20 5c 20 6b 65 79 20 6e 69 63 6b 0a       \ key nick.
0b20: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 6e 69      field: ke-ni
0b30: 63 6b 23 20 20 20 20 5c 20 74 6f 20 61 76 6f 69  ck#    \ to avoi
0b40: 64 20 63 6f 6c 69 73 73 69 6f 6e 73 2c 20 61 64  d colissions, ad
0b50: 64 20 61 20 6e 75 6d 62 65 72 20 68 65 72 65 0a  d a number here.
0b60: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 70 73      field: ke-ps
0b70: 6b 20 20 20 20 20 20 5c 20 70 72 65 73 68 61 72  k      \ preshar
0b80: 65 64 20 6b 65 79 20 66 6f 72 20 73 74 61 74 65  ed key for state
0b90: 6c 65 73 73 20 63 6f 6d 6d 75 6e 69 63 61 74 69  less communicati
0ba0: 6f 6e 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b 65  on.    field: ke
0bb0: 2d 70 72 6f 66 20 20 20 20 20 5c 20 70 72 6f 66  -prof     \ prof
0bc0: 69 6c 65 20 6f 62 6a 65 63 74 0a 20 20 20 20 66  ile object.    f
0bd0: 69 65 6c 64 3a 20 6b 65 2d 73 65 6c 66 73 69 67  ield: ke-selfsig
0be0: 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 73  .    field: ke-s
0bf0: 69 67 73 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b  igs.    field: k
0c00: 65 2d 69 6d 70 6f 72 74 20 20 20 5c 20 74 79 70  e-import   \ typ
0c10: 65 20 6f 66 20 6b 65 79 20 69 6d 70 6f 72 74 0a  e of key import.
0c20: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 73 74      field: ke-st
0c30: 6f 72 65 6b 65 79 20 5c 20 75 73 65 64 20 74 6f  orekey \ used to
0c40: 20 65 6e 63 72 79 70 74 20 6f 6e 20 73 74 6f 72   encrypt on stor
0c50: 61 67 65 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b  age.    field: k
0c60: 65 2d 6d 61 73 6b 20 20 20 5c 20 70 65 72 6d 69  e-mask   \ permi
0c70: 73 73 69 6f 6e 20 6d 61 73 6b 0a 20 20 20 20 36  ssion mask.    6
0c80: 34 66 69 65 6c 64 3a 20 6b 65 2d 6f 66 66 73 65  4field: ke-offse
0c90: 74 20 5c 20 6f 66 66 73 65 74 20 69 6e 20 6b 65  t \ offset in ke
0ca0: 79 20 66 69 6c 65 0a 20 20 20 20 30 20 2b 66 69  y file.    0 +fi
0cb0: 65 6c 64 20 6b 65 2d 65 6e 64 0a 65 6e 64 2d 63  eld ke-end.end-c
0cc0: 6c 61 73 73 20 6b 65 79 2d 65 6e 74 72 79 0a 0a  lass key-entry..
0cd0: 3a 20 66 72 65 65 2d 6b 65 79 20 28 20 6f 3a 6b  : free-key ( o:k
0ce0: 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20  ey -- o:key ).  
0cf0: 20 20 5c 67 20 66 72 65 65 20 61 6c 6c 20 70 61    \g free all pa
0d00: 72 74 73 20 6f 66 20 74 68 65 20 73 75 62 6b 65  rts of the subke
0d10: 79 0a 20 20 20 20 6b 65 2d 73 6b 20 73 65 63 2d  y.    ke-sk sec-
0d20: 6f 66 66 0a 20 20 20 20 6b 65 2d 70 6b 20 24 6f  off.    ke-pk $o
0d30: 66 66 0a 20 20 20 20 6b 65 2d 6e 69 63 6b 20 24  ff.    ke-nick $
0d40: 6f 66 66 0a 20 20 20 20 6b 65 2d 70 73 6b 20 73  off.    ke-psk s
0d50: 65 63 2d 6f 66 66 0a 20 20 20 20 6b 65 2d 73 65  ec-off.    ke-se
0d60: 6c 66 73 69 67 20 24 6f 66 66 0a 20 20 20 20 6b  lfsig $off.    k
0d70: 65 2d 73 69 67 73 20 24 5b 5d 6f 66 66 20 3b 0a  e-sigs $[]off ;.
0d80: 0a 56 61 72 69 61 62 6c 65 20 6b 65 79 2d 65 6e  .Variable key-en
0d90: 74 72 79 2d 74 61 62 6c 65 0a 0a 5c 20 6b 65 79  try-table..\ key
0da0: 20 63 6c 61 73 73 0a 0a 30 0a 65 6e 75 6d 20 6b   class..0.enum k
0db0: 65 79 23 61 6e 6f 6e 0a 65 6e 75 6d 20 6b 65 79  ey#anon.enum key
0dc0: 23 75 73 65 72 0a 65 6e 75 6d 20 6b 65 79 23 67  #user.enum key#g
0dd0: 72 6f 75 70 0a 64 72 6f 70 0a 0a 5c 20 6b 65 79  roup.drop..\ key
0de0: 20 69 6d 70 6f 72 74 20 74 79 70 65 0a 0a 30 0a   import type..0.
0df0: 65 6e 75 6d 20 69 6d 70 6f 72 74 23 73 65 6c 66  enum import#self
0e00: 20 20 20 20 20 20 5c 20 70 72 69 76 61 74 65 20        \ private 
0e10: 6b 65 79 0a 65 6e 75 6d 20 69 6d 70 6f 72 74 23  key.enum import#
0e20: 6d 61 6e 75 61 6c 20 20 20 20 5c 20 6d 61 6e 75  manual    \ manu
0e30: 61 6c 20 69 6d 70 6f 72 74 0a 65 6e 75 6d 20 69  al import.enum i
0e40: 6d 70 6f 72 74 23 73 63 61 6e 20 20 20 20 20 20  mport#scan      
0e50: 5c 20 73 63 61 6e 20 69 6d 70 6f 72 74 0a 65 6e  \ scan import.en
0e60: 75 6d 20 69 6d 70 6f 72 74 23 63 68 61 74 20 20  um import#chat  
0e70: 20 20 20 20 5c 20 63 68 61 74 20 69 6d 70 6f 72      \ chat impor
0e80: 74 0a 65 6e 75 6d 20 69 6d 70 6f 72 74 23 64 68  t.enum import#dh
0e90: 74 20 20 20 20 20 20 20 5c 20 64 68 74 20 69 6d  t       \ dht im
0ea0: 70 6f 72 74 0a 65 6e 75 6d 20 69 6d 70 6f 72 74  port.enum import
0eb0: 23 69 6e 76 69 74 65 64 20 20 20 5c 20 69 6e 76  #invited   \ inv
0ec0: 69 74 61 74 69 6f 6e 20 69 6d 70 6f 72 74 0a 65  itation import.e
0ed0: 6e 75 6d 20 69 6d 70 6f 72 74 23 75 6e 74 72 75  num import#untru
0ee0: 73 74 65 64 20 5c 20 6d 75 73 74 20 62 65 20 6c  sted \ must be l
0ef0: 61 73 74 0a 64 72 6f 70 0a 0a 56 61 72 69 61 62  ast.drop..Variab
0f00: 6c 65 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 20  le import-type  
0f10: 69 6d 70 6f 72 74 23 75 6e 74 72 75 73 74 65 64  import#untrusted
0f20: 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 21 0a 0a   import-type !..
0f30: 43 72 65 61 74 65 20 3e 69 6d 2d 63 6f 6c 6f 72  Create >im-color
0f40: 20 20 24 42 36 30 20 2c 20 24 44 36 30 20 2c 20    $B60 , $D60 , 
0f50: 24 39 36 30 20 2c 20 24 43 36 30 20 2c 20 24 41  $960 , $C60 , $A
0f60: 36 30 20 2c 20 24 38 42 31 20 2c 20 24 45 36 30  60 , $8B1 , $E60
0f70: 20 2c 0a 44 4f 45 53 3e 20 73 77 61 70 20 63 65   ,.DOES> swap ce
0f80: 6c 6c 73 20 2b 20 40 20 61 74 74 72 21 20 3b 0a  lls + @ attr! ;.
0f90: 0a 5c 20 73 61 6d 70 6c 65 20 6b 65 79 0a 0a 30  .\ sample key..0
0fa0: 20 56 61 6c 75 65 20 73 61 6d 70 6c 65 2d 6b 65   Value sample-ke
0fb0: 79 0a 0a 56 61 72 69 61 62 6c 65 20 6b 65 79 2d  y..Variable key-
0fc0: 74 61 62 6c 65 20 5c 20 6b 65 79 20 68 61 73 68  table \ key hash
0fd0: 20 74 61 62 6c 65 0a 56 61 72 69 61 62 6c 65 20   table.Variable 
0fe0: 6e 69 63 6b 2d 74 61 62 6c 65 20 5c 20 6e 69 63  nick-table \ nic
0ff0: 6b 20 68 61 73 68 20 74 61 62 6c 65 0a 0a 36 34  k hash table..64
1000: 56 61 72 69 61 62 6c 65 20 6b 65 79 2d 72 65 61  Variable key-rea
1010: 64 2d 6f 66 66 73 65 74 0a 0a 3a 20 63 75 72 72  d-offset..: curr
1020: 65 6e 74 2d 6b 65 79 20 28 20 61 64 64 72 20 75  ent-key ( addr u
1030: 20 2d 2d 20 6f 20 29 0a 20 20 20 20 32 64 75 70   -- o ).    2dup
1040: 20 6b 65 79 7c 20 6b 65 79 2d 74 61 62 6c 65 20   key| key-table 
1050: 23 40 20 64 72 6f 70 0a 20 20 20 20 64 75 70 20  #@ drop.    dup 
1060: 30 3d 20 49 46 20 20 64 72 6f 70 20 2e 22 20 75  0= IF  drop ." u
1070: 6e 6b 6e 6f 77 6e 20 6b 65 79 3a 20 22 20 38 35  nknown key: " 85
1080: 74 79 70 65 20 63 72 20 20 30 20 45 58 49 54 20  type cr  0 EXIT 
1090: 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b 20   THEN.    cell+ 
10a0: 3e 6f 20 6b 65 2d 70 6b 20 24 21 20 6f 20 6f 3e  >o ke-pk $! o o>
10b0: 20 3b 0a 0a 56 61 72 69 61 62 6c 65 20 73 69 6d   ;..Variable sim
10c0: 2d 6e 69 63 6b 21 0a 0a 3a 20 6e 69 63 6b 21 20  -nick!..: nick! 
10d0: 28 20 2d 2d 20 29 20 73 69 6d 2d 6e 69 63 6b 21  ( -- ) sim-nick!
10e0: 20 40 20 3f 45 58 49 54 20 20 6f 20 7b 20 77 5e   @ ?EXIT  o { w^
10f0: 20 6f 70 74 72 20 7d 0a 20 20 20 20 6b 65 2d 6e   optr }.    ke-n
1100: 69 63 6b 20 24 40 20 6e 69 63 6b 2d 74 61 62 6c  ick $@ nick-tabl
1110: 65 20 23 40 20 64 30 3d 20 49 46 0a 09 6f 70 74  e #@ d0= IF..opt
1120: 72 20 63 65 6c 6c 20 6b 65 2d 6e 69 63 6b 20 24  r cell ke-nick $
1130: 40 20 6e 69 63 6b 2d 74 61 62 6c 65 20 23 21 20  @ nick-table #! 
1140: 30 0a 20 20 20 20 45 4c 53 45 0a 09 6c 61 73 74  0.    ELSE..last
1150: 23 20 63 65 6c 6c 2b 20 24 40 6c 65 6e 20 63 65  # cell+ $@len ce
1160: 6c 6c 2f 0a 09 6f 70 74 72 20 63 65 6c 6c 20 6c  ll/..optr cell l
1170: 61 73 74 23 20 63 65 6c 6c 2b 20 24 2b 21 0a 20  ast# cell+ $+!. 
1180: 20 20 20 54 48 45 4e 20 20 6b 65 2d 6e 69 63 6b     THEN  ke-nick
1190: 23 20 21 20 3b 0a 0a 3a 20 23 2e 6e 69 63 6b 20  # ! ;..: #.nick 
11a0: 28 20 68 61 73 68 20 2d 2d 20 29 0a 20 20 20 20  ( hash -- ).    
11b0: 64 75 70 20 24 40 20 74 79 70 65 20 27 23 27 20  dup $@ type '#' 
11c0: 65 6d 69 74 20 63 65 6c 6c 2b 20 24 40 6c 65 6e  emit cell+ $@len
11d0: 20 63 65 6c 6c 2f 20 2e 20 3b 0a 0a 3a 20 6b 65   cell/ . ;..: ke
11e0: 79 3a 6e 65 77 20 28 20 61 64 64 72 20 75 20 2d  y:new ( addr u -
11f0: 2d 20 6f 20 29 0a 20 20 20 20 5c 47 20 63 72 65  - o ).    \G cre
1200: 61 74 65 20 6e 65 77 20 6b 65 79 2c 20 61 64 64  ate new key, add
1210: 72 20 75 20 69 73 20 74 68 65 20 70 75 62 6c 69  r u is the publi
1220: 63 20 6b 65 79 0a 20 20 20 20 73 61 6d 70 6c 65  c key.    sample
1230: 2d 6b 65 79 20 3e 6f 0a 20 20 20 20 6b 65 79 2d  -key >o.    key-
1240: 65 6e 74 72 79 2d 74 61 62 6c 65 20 40 20 74 6f  entry-table @ to
1250: 6b 65 6e 2d 74 61 62 6c 65 20 21 0a 20 20 20 20  ken-table !.    
1260: 6b 65 2d 73 6b 20 6b 65 2d 65 6e 64 20 6f 76 65  ke-sk ke-end ove
1270: 72 20 2d 20 65 72 61 73 65 20 20 3e 73 74 6f 72  r - erase  >stor
1280: 65 6b 65 79 20 40 20 6b 65 2d 73 74 6f 72 65 6b  ekey @ ke-storek
1290: 65 79 20 21 0a 20 20 20 20 6b 65 79 2d 72 65 61  ey !.    key-rea
12a0: 64 2d 6f 66 66 73 65 74 20 36 34 40 20 6b 65 2d  d-offset 64@ ke-
12b0: 6f 66 66 73 65 74 20 36 34 21 0a 20 20 20 20 69  offset 64!.    i
12c0: 6d 70 6f 72 74 2d 74 79 70 65 20 40 20 6b 65 2d  mport-type @ ke-
12d0: 69 6d 70 6f 72 74 20 21 0a 20 20 20 20 6b 65 79  import !.    key
12e0: 70 61 63 6b 2d 61 6c 6c 23 20 6e 3e 36 34 20 6b  pack-all# n>64 k
12f0: 65 79 2d 72 65 61 64 2d 6f 66 66 73 65 74 20 36  ey-read-offset 6
1300: 34 2b 21 20 6f 20 63 65 6c 6c 2d 20 6b 65 2d 65  4+! o cell- ke-e
1310: 6e 64 20 6f 76 65 72 20 2d 0a 20 20 20 20 32 6f  nd over -.    2o
1320: 76 65 72 20 6b 65 79 7c 20 6b 65 79 2d 74 61 62  ver key| key-tab
1330: 6c 65 20 23 21 20 6f 3e 0a 20 20 20 20 63 75 72  le #! o>.    cur
1340: 72 65 6e 74 2d 6b 65 79 20 3b 0a 0a 30 20 56 61  rent-key ;..0 Va
1350: 6c 75 65 20 6c 61 73 74 2d 6b 65 79 0a 0a 3a 20  lue last-key..: 
1360: 6b 65 79 3f 6e 65 77 20 28 20 61 64 64 72 20 75  key?new ( addr u
1370: 20 2d 2d 20 6f 20 29 0a 20 20 20 20 5c 47 20 43   -- o ).    \G C
1380: 72 65 61 74 65 20 6f 72 20 6c 6f 6f 6b 75 70 20  reate or lookup 
1390: 6e 65 77 20 6b 65 79 0a 20 20 20 20 32 64 75 70  new key.    2dup
13a0: 20 6b 65 79 7c 20 6b 65 79 2d 74 61 62 6c 65 20   key| key-table 
13b0: 23 40 20 64 72 6f 70 0a 20 20 20 20 64 75 70 20  #@ drop.    dup 
13c0: 30 3d 20 49 46 20 20 64 72 6f 70 20 6b 65 79 3a  0= IF  drop key:
13d0: 6e 65 77 20 20 45 4c 53 45 20 20 6e 69 70 20 6e  new  ELSE  nip n
13e0: 69 70 20 63 65 6c 6c 2b 20 20 54 48 45 4e 0a 20  ip cell+  THEN. 
13f0: 20 20 20 64 75 70 20 74 6f 20 6c 61 73 74 2d 6b     dup to last-k
1400: 65 79 20 3b 0a 0a 5c 20 73 65 61 72 63 68 20 66  ey ;..\ search f
1410: 6f 72 20 6b 65 79 73 20 2d 20 6e 6f 74 20 6f 70  or keys - not op
1420: 74 69 6d 69 7a 65 64 0a 0a 3a 20 23 73 70 6c 69  timized..: #spli
1430: 74 20 28 20 61 64 64 72 20 75 20 2d 2d 20 61 64  t ( addr u -- ad
1440: 64 72 20 75 20 6e 20 29 0a 20 20 20 20 5b 3a 20  dr u n ).    [: 
1450: 32 64 75 70 20 27 23 27 20 2d 73 63 61 6e 20 6e  2dup '#' -scan n
1460: 69 70 20 3e 72 0a 20 20 20 20 20 20 72 40 20 30  ip >r.      r@ 0
1470: 3d 20 49 46 20 20 72 64 72 6f 70 20 30 20 20 45  = IF  rdrop 0  E
1480: 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 20 20  XIT  THEN.      
1490: 30 2e 20 32 6f 76 65 72 20 72 40 20 2f 73 74 72  0. 2over r@ /str
14a0: 69 6e 67 20 3e 6e 75 6d 62 65 72 0a 20 20 20 20  ing >number.    
14b0: 20 20 30 3d 20 49 46 20 20 6e 69 70 20 64 72 6f    0= IF  nip dro
14c0: 70 20 6e 69 70 20 72 3e 20 31 2d 20 73 77 61 70  p nip r> 1- swap
14d0: 20 20 45 4c 53 45 0a 09 20 20 72 64 72 6f 70 20    ELSE..  rdrop 
14e0: 64 72 6f 70 20 32 64 72 6f 70 20 30 20 20 20 54  drop 2drop 0   T
14f0: 48 45 4e 20 3b 5d 20 23 31 30 20 62 61 73 65 2d  HEN ;] #10 base-
1500: 65 78 65 63 75 74 65 20 3b 0a 0a 3a 20 6e 69 63  execute ;..: nic
1510: 6b 2d 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d  k-key ( addr u -
1520: 2d 20 6f 20 2f 20 30 20 29 20 5c 20 73 65 61 72  - o / 0 ) \ sear
1530: 63 68 20 66 6f 72 20 6b 65 79 20 6e 69 63 6b 6e  ch for key nickn
1540: 61 6d 65 0a 20 20 20 20 23 73 70 6c 69 74 20 3e  ame.    #split >
1550: 72 20 6e 69 63 6b 2d 74 61 62 6c 65 20 23 40 20  r nick-table #@ 
1560: 32 64 75 70 20 64 30 3d 20 49 46 20 20 72 64 72  2dup d0= IF  rdr
1570: 6f 70 20 64 72 6f 70 20 20 45 58 49 54 20 20 54  op drop  EXIT  T
1580: 48 45 4e 0a 20 20 20 20 72 3e 20 63 65 6c 6c 73  HEN.    r> cells
1590: 20 73 61 66 65 2f 73 74 72 69 6e 67 20 30 3d 20   safe/string 0= 
15a0: 49 46 20 20 64 72 6f 70 20 30 20 20 45 58 49 54  IF  drop 0  EXIT
15b0: 20 20 54 48 45 4e 20 20 40 20 3b 0a 0a 3a 20 73    THEN  @ ;..: s
15c0: 65 63 72 65 74 2d 6b 65 79 73 23 20 28 20 2d 2d  ecret-keys# ( --
15d0: 20 6e 20 29 0a 20 20 20 20 30 20 6b 65 79 2d 74   n ).    0 key-t
15e0: 61 62 6c 65 20 5b 3a 20 63 65 6c 6c 2b 20 24 40  able [: cell+ $@
15f0: 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 20 6b   drop cell+ >o k
1600: 65 2d 73 6b 20 40 20 30 3c 3e 20 2d 20 6f 3e 20  e-sk @ 0<> - o> 
1610: 3b 5d 20 23 6d 61 70 20 3b 0a 3a 20 73 65 63 72  ;] #map ;.: secr
1620: 65 74 2d 6b 65 79 20 28 20 6e 20 2d 2d 20 6f 2f  et-key ( n -- o/
1630: 30 20 29 0a 20 20 20 20 30 20 74 75 63 6b 20 6b  0 ).    0 tuck k
1640: 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63 65 6c 6c  ey-table [: cell
1650: 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20  + $@ drop cell+ 
1660: 3e 6f 20 6b 65 2d 73 6b 20 40 20 49 46 0a 09 20  >o ke-sk @ IF.. 
1670: 20 32 64 75 70 20 3d 20 49 46 20 20 72 6f 74 20   2dup = IF  rot 
1680: 64 72 6f 70 20 6f 20 2d 72 6f 74 20 20 54 48 45  drop o -rot  THE
1690: 4e 20 20 31 2b 0a 20 20 20 20 20 20 54 48 45 4e  N  1+.      THEN
16a0: 20 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 32 64 72    o> ;] #map 2dr
16b0: 6f 70 20 3b 0a 3a 20 2e 6e 69 63 6b 2d 62 61 73  op ;.: .nick-bas
16c0: 65 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20  e ( o:key -- ). 
16d0: 20 20 20 6b 65 2d 6e 69 63 6b 20 24 2e 20 20 6b     ke-nick $.  k
16e0: 65 2d 6e 69 63 6b 23 20 40 20 3f 64 75 70 2d 49  e-nick# @ ?dup-I
16f0: 46 20 20 27 23 27 20 65 6d 69 74 20 30 20 2e 72  F  '#' emit 0 .r
1700: 20 20 54 48 45 4e 20 3b 0a 3a 20 2e 6e 69 63 6b    THEN ;.: .nick
1710: 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 20 20 20   ( o:key -- )   
1720: 6b 65 2d 69 6d 70 6f 72 74 20 40 20 3e 69 6d 2d  ke-import @ >im-
1730: 63 6f 6c 6f 72 20 2e 6e 69 63 6b 2d 62 61 73 65  color .nick-base
1740: 20 3c 64 65 66 61 75 6c 74 3e 20 3b 0a 0a 3a 20   <default> ;..: 
1750: 6e 69 63 6b 3e 70 6b 20 28 20 6e 69 63 6b 20 75  nick>pk ( nick u
1760: 20 2d 2d 20 70 6b 20 75 20 29 0a 20 20 20 20 6e   -- pk u ).    n
1770: 69 63 6b 2d 6b 65 79 20 3f 64 75 70 2d 49 46 20  ick-key ?dup-IF 
1780: 2e 6b 65 2d 70 6b 20 24 40 20 45 4c 53 45 20 30  .ke-pk $@ ELSE 0
1790: 20 30 20 54 48 45 4e 20 3b 0a 3a 20 68 6f 73 74   0 THEN ;.: host
17a0: 2e 6e 69 63 6b 3e 70 6b 20 28 20 61 64 64 72 20  .nick>pk ( addr 
17b0: 75 20 2d 2d 20 70 6b 20 75 27 20 29 0a 20 20 20  u -- pk u' ).   
17c0: 20 27 2e 27 20 24 73 70 6c 69 74 20 64 75 70 20   '.' $split dup 
17d0: 30 3d 20 49 46 20 20 32 73 77 61 70 20 20 54 48  0= IF  2swap  TH
17e0: 45 4e 20 5b 3a 20 6e 69 63 6b 3e 70 6b 20 74 79  EN [: nick>pk ty
17f0: 70 65 20 74 79 70 65 20 3b 5d 20 24 74 6d 70 20  pe type ;] $tmp 
1800: 3b 0a 0a 3a 20 6b 65 79 2d 65 78 69 73 74 3f 20  ;..: key-exist? 
1810: 28 20 61 64 64 72 20 75 20 2d 2d 20 6f 2f 30 20  ( addr u -- o/0 
1820: 29 0a 20 20 20 20 6b 65 79 2d 74 61 62 6c 65 20  ).    key-table 
1830: 23 40 20 49 46 20 20 63 65 6c 6c 2b 20 20 54 48  #@ IF  cell+  TH
1840: 45 4e 20 3b 20 0a 0a 5c 20 70 65 72 6d 69 73 73  EN ; ..\ permiss
1850: 69 6f 6e 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e  ion modification
1860: 0a 0a 32 36 20 62 75 66 66 65 72 3a 20 70 65 72  ..26 buffer: per
1870: 6d 2d 63 68 61 72 73 0a 30 20 70 65 72 6d 24 20  m-chars.0 perm$ 
1880: 63 6f 75 6e 74 20 62 6f 75 6e 64 73 20 5b 44 4f  count bounds [DO
1890: 5d 20 64 75 70 20 5b 49 5d 20 63 40 20 27 61 27  ] dup [I] c@ 'a'
18a0: 20 2d 20 70 65 72 6d 2d 63 68 61 72 73 20 2b 20   - perm-chars + 
18b0: 63 21 20 31 2b 20 5b 4c 4f 4f 50 5d 20 64 72 6f  c! 1+ [LOOP] dro
18c0: 70 0a 0a 3a 20 2e 70 65 72 6d 20 28 20 70 65 72  p..: .perm ( per
18d0: 6d 69 73 73 69 6f 6e 20 2d 2d 20 29 20 20 31 20  mission -- )  1 
18e0: 70 65 72 6d 24 20 63 6f 75 6e 74 20 62 6f 75 6e  perm$ count boun
18f0: 64 73 20 44 4f 0a 09 32 64 75 70 20 61 6e 64 20  ds DO..2dup and 
1900: 30 3c 3e 20 49 20 63 40 20 27 2d 27 20 72 6f 74  0<> I c@ '-' rot
1910: 20 73 65 6c 65 63 74 20 65 6d 69 74 20 32 2a 0a   select emit 2*.
1920: 20 20 20 20 4c 4f 4f 50 20 20 32 64 72 6f 70 20      LOOP  2drop 
1930: 3b 0a 3a 20 70 65 72 6d 61 6e 64 20 28 20 70 65  ;.: permand ( pe
1940: 72 6d 61 6e 64 20 70 65 72 6d 6f 72 20 6e 65 77  rmand permor new
1950: 20 2d 2d 20 70 65 72 6d 61 6e 64 27 20 70 65 72   -- permand' per
1960: 6d 6f 72 20 29 0a 20 20 20 20 69 6e 76 65 72 74  mor ).    invert
1970: 20 74 75 63 6b 20 61 6e 64 20 3e 72 20 61 6e 64   tuck and >r and
1980: 20 72 3e 20 3b 0a 3a 20 3e 70 65 72 6d 2d 6d 6f   r> ;.: >perm-mo
1990: 64 20 28 20 70 65 72 6d 61 6e 64 20 70 65 72 6d  d ( permand perm
19a0: 6f 72 20 2d 2d 20 70 65 72 6d 61 6e 64 27 20 70  or -- permand' p
19b0: 65 72 6d 6f 72 20 29 0a 20 20 20 20 73 77 61 70  ermor ).    swap
19c0: 20 64 75 70 20 30 3d 20 49 46 20 20 64 72 6f 70   dup 0= IF  drop
19d0: 20 64 75 70 20 69 6e 76 65 72 74 20 20 54 48 45   dup invert  THE
19e0: 4e 20 73 77 61 70 20 3b 0a 3a 20 3e 70 65 72 6d  N swap ;.: >perm
19f0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 70 65 72   ( addr u -- per
1a00: 6d 61 6e 64 20 70 65 72 6d 6f 72 20 29 0a 20 20  mand permor ).  
1a10: 20 20 5c 67 20 70 61 72 73 65 20 70 65 72 6d 69    \g parse permi
1a20: 73 73 69 6f 6e 73 3a 20 2b 20 61 64 64 73 2c 20  ssions: + adds, 
1a30: 2d 20 72 65 6d 6f 76 65 73 20 70 65 72 6d 69 73  - removes permis
1a40: 73 69 6f 6e 73 2c 0a 20 20 20 20 5c 67 20 6e 6f  sions,.    \g no
1a50: 20 6d 6f 64 69 66 69 65 72 20 73 65 74 73 20 70   modifier sets p
1a60: 65 72 6d 69 73 73 6f 6e 73 2e 0a 20 20 20 20 30  ermissons..    0
1a70: 20 30 20 5b 27 5d 20 6f 72 20 7b 20 78 74 20 7d   0 ['] or { xt }
1a80: 0a 20 20 20 20 32 73 77 61 70 20 62 6f 75 6e 64  .    2swap bound
1a90: 73 20 3f 44 4f 0a 09 49 20 63 40 20 63 61 73 65  s ?DO..I c@ case
1aa0: 0a 09 20 20 20 20 27 2b 27 20 6f 66 20 20 3e 70  ..    '+' of  >p
1ab0: 65 72 6d 2d 6d 6f 64 20 5b 27 5d 20 6f 72 20 74  erm-mod ['] or t
1ac0: 6f 20 78 74 20 65 6e 64 6f 66 0a 09 20 20 20 20  o xt endof..    
1ad0: 27 2d 27 20 6f 66 20 20 3e 70 65 72 6d 2d 6d 6f  '-' of  >perm-mo
1ae0: 64 20 5b 27 5d 20 70 65 72 6d 61 6e 64 20 74 6f  d ['] permand to
1af0: 20 78 74 20 20 65 6e 64 6f 66 0a 09 20 20 20 20   xt  endof..    
1b00: 27 3d 27 20 6f 66 20 20 32 64 72 6f 70 20 70 65  '=' of  2drop pe
1b10: 72 6d 25 64 65 66 61 75 6c 74 20 64 75 70 20 5b  rm%default dup [
1b20: 27 5d 20 6f 72 20 74 6f 20 78 74 20 20 65 6e 64  '] or to xt  end
1b30: 6f 66 0a 09 20 20 20 20 27 61 27 20 2d 20 64 75  of..    'a' - du
1b40: 70 20 27 7a 27 20 75 3c 3d 20 20 49 46 0a 09 09  p 'z' u<=  IF...
1b50: 70 65 72 6d 2d 63 68 61 72 73 20 2b 20 63 40 20  perm-chars + c@ 
1b60: 31 20 73 77 61 70 20 6c 73 68 69 66 74 20 78 74  1 swap lshift xt
1b70: 20 65 78 65 63 75 74 65 20 30 0a 09 20 20 20 20   execute 0..    
1b80: 54 48 45 4e 20 20 65 6e 64 63 61 73 65 0a 20 20  THEN  endcase.  
1b90: 20 20 4c 4f 4f 50 20 3b 0a 0a 5c 20 6b 65 79 20    LOOP ;..\ key 
1ba0: 64 69 73 70 6c 61 79 0a 0a 56 61 72 69 61 62 6c  display..Variabl
1bb0: 65 20 73 74 72 69 63 74 2d 6b 65 79 73 20 20 73  e strict-keys  s
1bc0: 74 72 69 63 74 2d 6b 65 79 73 20 6f 6e 0a 0a 5b  trict-keys on..[
1bd0: 49 46 55 4e 44 45 46 5d 20 6d 61 67 65 6e 74 61  IFUNDEF] magenta
1be0: 20 20 62 72 6f 77 6e 20 63 6f 6e 73 74 61 6e 74    brown constant
1bf0: 20 6d 61 67 65 6e 74 61 20 5b 54 48 45 4e 5d 0a   magenta [THEN].
1c00: 5b 49 46 44 45 46 5d 20 67 6c 2d 74 79 70 65 20  [IFDEF] gl-type 
1c10: 3a 20 62 67 7c 20 3e 62 67 20 6f 72 20 3b 20 5b  : bg| >bg or ; [
1c20: 45 4c 53 45 5d 20 3a 20 62 67 7c 20 64 72 6f 70  ELSE] : bg| drop
1c30: 20 3b 20 5b 54 48 45 4e 5d 0a 0a 43 72 65 61 74   ; [THEN]..Creat
1c40: 65 20 38 35 63 6f 6c 6f 72 73 2d 62 77 0a 30 20  e 85colors-bw.0 
1c50: 2c 20 69 6e 76 65 72 73 20 2c 0a 69 6e 76 65 72  , invers ,.inver
1c60: 73 20 2c 20 30 20 2c 0a 30 20 2c 20 69 6e 76 65  s , 0 ,.0 , inve
1c70: 72 73 20 2c 0a 69 6e 76 65 72 73 20 2c 20 30 20  rs ,.invers , 0 
1c80: 2c 0a 43 72 65 61 74 65 20 38 35 63 6f 6c 6f 72  ,.Create 85color
1c90: 73 2d 63 6c 0a 79 65 6c 6c 6f 77 20 3e 66 67 20  s-cl.yellow >fg 
1ca0: 62 6c 75 65 20 3e 62 67 20 6f 72 20 62 6f 6c 64  blue >bg or bold
1cb0: 20 6f 72 20 2c 20 72 65 64 20 3e 66 67 20 77 68   or , red >fg wh
1cc0: 69 74 65 20 62 67 7c 20 2c 0a 62 6c 61 63 6b 20  ite bg| ,.black 
1cd0: 3e 66 67 20 63 79 61 6e 20 62 67 7c 20 2c 20 67  >fg cyan bg| , g
1ce0: 72 65 65 6e 20 3e 66 67 20 62 6c 61 63 6b 20 3e  reen >fg black >
1cf0: 62 67 20 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 0a  bg or bold or ,.
1d00: 77 68 69 74 65 20 3e 66 67 20 62 6c 61 63 6b 20  white >fg black 
1d10: 3e 62 67 20 6f 72 20 62 6f 6c 64 20 6f 72 20 2c  >bg or bold or ,
1d20: 20 6d 61 67 65 6e 74 61 20 3e 66 67 20 79 65 6c   magenta >fg yel
1d30: 6c 6f 77 20 62 67 7c 20 2c 0a 62 6c 75 65 20 3e  low bg| ,.blue >
1d40: 66 67 20 79 65 6c 6c 6f 77 20 62 67 7c 20 2c 20  fg yellow bg| , 
1d50: 63 79 61 6e 20 3e 66 67 20 72 65 64 20 3e 62 67  cyan >fg red >bg
1d60: 20 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 0a 0a 5b   or bold or ,..[
1d70: 49 46 44 45 46 5d 20 67 6c 2d 74 79 70 65 20 38  IFDEF] gl-type 8
1d80: 35 63 6f 6c 6f 72 73 2d 63 6c 20 5b 45 4c 53 45  5colors-cl [ELSE
1d90: 5d 20 38 35 63 6f 6c 6f 72 73 2d 62 77 20 5b 54  ] 85colors-bw [T
1da0: 48 45 4e 5d 20 56 61 6c 75 65 20 38 35 63 6f 6c  HEN] Value 85col
1db0: 6f 72 73 0a 0a 3a 20 2e 62 6c 61 63 6b 38 35 20  ors..: .black85 
1dc0: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20  ( addr u -- ).  
1dd0: 20 20 5b 20 62 6c 61 63 6b 20 3e 62 67 20 62 6c    [ black >bg bl
1de0: 61 63 6b 20 3e 66 67 20 6f 72 20 5d 4c 20 61 74  ack >fg or ]L at
1df0: 74 72 21 20 20 20 38 35 74 79 70 65 20 3c 64 65  tr!   85type <de
1e00: 66 61 75 6c 74 3e 20 3b 0a 3a 20 2e 73 74 72 69  fault> ;.: .stri
1e10: 70 65 38 35 20 28 20 61 64 64 72 20 75 20 2d 2d  pe85 ( addr u --
1e20: 20 29 20 20 30 20 2d 72 6f 74 20 62 6f 75 6e 64   )  0 -rot bound
1e30: 73 20 3f 44 4f 0a 09 63 72 20 64 75 70 20 63 65  s ?DO..cr dup ce
1e40: 6c 6c 73 20 38 35 63 6f 6c 6f 72 73 20 2b 20 40  lls 85colors + @
1e50: 20 61 74 74 72 21 20 31 2b 0a 09 49 20 34 20 38   attr! 1+..I 4 8
1e60: 35 74 79 70 65 20 20 64 75 70 20 63 65 6c 6c 73  5type  dup cells
1e70: 20 38 35 63 6f 6c 6f 72 73 20 2b 20 40 20 61 74   85colors + @ at
1e80: 74 72 21 20 31 2b 0a 20 20 20 20 49 20 34 20 2b  tr! 1+.    I 4 +
1e90: 20 34 20 38 35 74 79 70 65 20 3c 64 65 66 61 75   4 85type <defau
1ea0: 6c 74 3e 20 38 20 2b 4c 4f 4f 50 20 20 64 72 6f  lt> 8 +LOOP  dro
1eb0: 70 20 3b 0a 3a 20 2e 69 6d 70 6f 72 74 38 35 20  p ;.: .import85 
1ec0: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20  ( addr u -- ).  
1ed0: 20 20 6b 65 2d 69 6d 70 6f 72 74 20 40 20 3e 69    ke-import @ >i
1ee0: 6d 2d 63 6f 6c 6f 72 20 38 35 74 79 70 65 20 3c  m-color 85type <
1ef0: 64 65 66 61 75 6c 74 3e 20 3b 0a 3a 20 2e 72 73  default> ;.: .rs
1f00: 6b 20 28 20 6e 69 63 6b 20 75 20 2d 2d 20 29 0a  k ( nick u -- ).
1f10: 20 20 20 20 73 6b 72 65 76 20 24 32 30 20 2e 73      skrev $20 .s
1f20: 74 72 69 70 65 38 35 20 73 70 61 63 65 20 74 79  tripe85 space ty
1f30: 70 65 20 2e 22 20 20 28 6b 65 65 70 20 6f 66 66  pe ."  (keep off
1f40: 6c 69 6e 65 20 63 6f 70 79 21 29 22 20 63 72 20  line copy!)" cr 
1f50: 3b 0a 3a 20 2e 6b 65 79 20 28 20 61 64 64 72 20  ;.: .key ( addr 
1f60: 75 20 2d 2d 20 29 20 64 72 6f 70 20 63 65 6c 6c  u -- ) drop cell
1f70: 2b 20 3e 6f 0a 20 20 20 20 2e 22 20 6e 69 63 6b  + >o.    ." nick
1f80: 3a 20 22 20 2e 6e 69 63 6b 20 63 72 0a 20 20 20  : " .nick cr.   
1f90: 20 2e 22 20 70 75 62 6b 65 79 3a 20 22 20 6b 65   ." pubkey: " ke
1fa0: 2d 70 6b 20 24 40 20 38 35 74 79 70 65 20 63 72  -pk $@ 85type cr
1fb0: 0a 20 20 20 20 6b 65 2d 73 6b 20 40 20 49 46 20  .    ke-sk @ IF 
1fc0: 20 2e 22 20 73 65 63 6b 65 79 3a 20 22 20 6b 65   ." seckey: " ke
1fd0: 2d 73 6b 20 40 20 6b 65 79 73 69 7a 65 0a 09 2e  -sk @ keysize...
1fe0: 62 6c 61 63 6b 38 35 20 2e 22 20 20 28 6b 65 65  black85 ."  (kee
1ff0: 70 20 73 65 63 72 65 74 21 29 22 20 63 72 20 20  p secret!)" cr  
2000: 54 48 45 4e 0a 20 20 20 20 2e 22 20 63 72 65 61  THEN.    ." crea
2010: 74 65 64 3a 20 22 20 6b 65 2d 73 65 6c 66 73 69  ted: " ke-selfsi
2020: 67 20 24 40 20 64 72 6f 70 20 36 34 40 20 2e 73  g $@ drop 64@ .s
2030: 69 67 64 61 74 65 20 63 72 0a 20 20 20 20 2e 22  igdate cr.    ."
2040: 20 65 78 70 69 72 65 73 3a 20 22 20 6b 65 2d 73   expires: " ke-s
2050: 65 6c 66 73 69 67 20 24 40 20 64 72 6f 70 20 36  elfsig $@ drop 6
2060: 34 27 2b 20 36 34 40 20 2e 73 69 67 64 61 74 65  4'+ 64@ .sigdate
2070: 20 63 72 0a 20 20 20 20 2e 22 20 70 65 72 6d 3a   cr.    ." perm:
2080: 20 22 20 6b 65 2d 6d 61 73 6b 20 40 20 2e 70 65   " ke-mask @ .pe
2090: 72 6d 20 63 72 0a 20 20 20 20 6f 3e 20 3b 0a 3a  rm cr.    o> ;.:
20a0: 20 2e 6b 65 79 2d 72 65 73 74 20 28 20 6f 3a 6b   .key-rest ( o:k
20b0: 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20  ey -- o:key ).  
20c0: 20 20 6b 65 2d 70 6b 20 24 40 20 6b 65 79 7c 20    ke-pk $@ key| 
20d0: 2e 69 6d 70 6f 72 74 38 35 0a 20 20 20 20 6b 65  .import85.    ke
20e0: 2d 73 65 6c 66 73 69 67 20 24 40 20 2e 73 69 67  -selfsig $@ .sig
20f0: 64 61 74 65 73 0a 20 20 20 20 73 70 61 63 65 20  dates.    space 
2100: 6b 65 2d 6d 61 73 6b 20 40 20 2e 70 65 72 6d 20  ke-mask @ .perm 
2110: 73 70 61 63 65 20 2e 6e 69 63 6b 20 3b 0a 3a 20  space .nick ;.: 
2120: 2e 6b 65 79 2d 6c 69 73 74 20 28 20 6f 3a 6b 65  .key-list ( o:ke
2130: 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20 20  y -- o:key ).   
2140: 20 6b 65 2d 6f 66 66 73 65 74 20 36 34 40 20 36   ke-offset 64@ 6
2150: 34 3e 64 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23  4>d keypack-all#
2160: 20 66 6d 2f 6d 6f 64 20 6e 69 70 20 32 20 2e 72   fm/mod nip 2 .r
2170: 20 73 70 61 63 65 0a 20 20 20 20 2e 6b 65 79 2d   space.    .key-
2180: 72 65 73 74 20 63 72 20 3b 0a 3a 20 2e 73 65 63  rest cr ;.: .sec
2190: 72 65 74 2d 6e 69 63 6b 73 20 28 20 2d 2d 20 29  ret-nicks ( -- )
21a0: 0a 20 20 20 20 30 20 6b 65 79 2d 74 61 62 6c 65  .    0 key-table
21b0: 20 5b 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f   [: cell+ $@ dro
21c0: 70 20 63 65 6c 6c 2b 20 3e 6f 20 6b 65 2d 73 6b  p cell+ >o ke-sk
21d0: 20 40 20 49 46 0a 09 20 20 64 75 70 20 32 20 2e   @ IF..  dup 2 .
21e0: 72 20 73 70 61 63 65 20 2e 6b 65 79 2d 72 65 73  r space .key-res
21f0: 74 20 63 72 20 31 2b 0a 20 20 20 20 20 20 54 48  t cr 1+.      TH
2200: 45 4e 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 64 72  EN o> ;] #map dr
2210: 6f 70 20 3b 0a 3a 20 2e 6b 65 79 2d 69 6e 76 69  op ;.: .key-invi
2220: 74 65 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 6f 3a  te ( o:key -- o:
2230: 6b 65 79 20 29 0a 20 20 20 20 6b 65 2d 70 6b 20  key ).    ke-pk 
2240: 24 40 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e 0a  $@ keysize umin.
2250: 20 20 20 20 6b 65 2d 69 6d 70 6f 72 74 20 40 20      ke-import @ 
2260: 3e 69 6d 2d 63 6f 6c 6f 72 20 38 35 74 79 70 65  >im-color 85type
2270: 20 3c 64 65 66 61 75 6c 74 3e 0a 20 20 20 20 73   <default>.    s
2280: 70 61 63 65 20 2e 6e 69 63 6b 20 20 63 72 20 3b  pace .nick  cr ;
2290: 0a 3a 20 2e 6b 65 79 2d 73 68 6f 72 74 20 28 20  .: .key-short ( 
22a0: 6f 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29  o:key -- o:key )
22b0: 0a 20 20 20 20 6b 65 2d 6e 69 63 6b 20 24 2e 20  .    ke-nick $. 
22c0: 6b 65 2d 70 72 6f 66 20 24 40 6c 65 6e 20 49 46  ke-prof $@len IF
22d0: 20 2e 22 20 20 70 72 6f 66 69 6c 65 3a 20 22 20   ."  profile: " 
22e0: 6b 65 2d 70 72 6f 66 20 24 40 20 38 35 74 79 70  ke-prof $@ 85typ
22f0: 65 20 54 48 45 4e 20 3b 0a 3a 20 6c 69 73 74 2d  e THEN ;.: list-
2300: 6b 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20  keys ( -- ).    
2310: 6b 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63 65 6c  key-table [: cel
2320: 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b  l+ $@ drop cell+
2330: 20 2e 2e 6b 65 79 2d 6c 69 73 74 20 3b 5d 20 23   ..key-list ;] #
2340: 6d 61 70 20 3b 0a 0a 3a 20 64 75 6d 70 6b 65 79  map ;..: dumpkey
2350: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 64   ( addr u -- ) d
2360: 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a 20 20 20  rop cell+ >o.   
2370: 20 2e 5c 22 20 78 5c 22 20 22 20 6b 65 2d 70 6b   .\" x\" " ke-pk
2380: 20 24 40 20 38 35 74 79 70 65 20 2e 5c 22 20 5c   $@ 85type .\" \
2390: 22 20 6b 65 79 3f 6e 65 77 22 20 63 72 0a 20 20  " key?new" cr.  
23a0: 20 20 6b 65 2d 73 6b 20 40 20 49 46 20 20 2e 5c    ke-sk @ IF  .\
23b0: 22 20 78 5c 22 20 22 20 6b 65 2d 73 6b 20 40 20  " x\" " ke-sk @ 
23c0: 6b 65 79 73 69 7a 65 20 38 35 74 79 70 65 20 2e  keysize 85type .
23d0: 5c 22 20 5c 22 20 6b 65 2d 73 6b 20 73 65 63 21  \" \" ke-sk sec!
23e0: 20 2b 73 65 63 6b 65 79 22 20 63 72 20 20 54 48   +seckey" cr  TH
23f0: 45 4e 0a 20 20 20 20 27 22 27 20 65 6d 69 74 20  EN.    '"' emit 
2400: 2e 6e 69 63 6b 20 2e 5c 22 20 5c 22 20 6b 65 2d  .nick .\" \" ke-
2410: 6e 69 63 6b 20 24 21 20 22 0a 20 20 20 20 6b 65  nick $! ".    ke
2420: 2d 73 65 6c 66 73 69 67 20 24 40 20 64 72 6f 70  -selfsig $@ drop
2430: 20 36 34 40 20 36 34 3e 64 20 5b 3a 20 27 24 27   64@ 64>d [: '$'
2440: 20 65 6d 69 74 20 30 20 75 64 2e 72 20 3b 5d 20   emit 0 ud.r ;] 
2450: 24 31 30 20 62 61 73 65 2d 65 78 65 63 75 74 65  $10 base-execute
2460: 0a 20 20 20 20 2e 22 20 2e 20 64 3e 36 34 20 6b  .    ." . d>64 k
2470: 65 2d 66 69 72 73 74 21 20 22 20 6b 65 2d 74 79  e-first! " ke-ty
2480: 70 65 20 40 20 2e 20 2e 22 20 6b 65 2d 74 79 70  pe @ . ." ke-typ
2490: 65 20 21 22 20 20 63 72 20 6f 3e 20 3b 0a 0a 3a  e !"  cr o> ;..:
24a0: 20 2e 6b 65 79 73 20 28 20 2d 2d 20 29 20 6b 65   .keys ( -- ) ke
24b0: 79 2d 74 61 62 6c 65 20 5b 3a 20 2e 22 20 69 6e  y-table [: ." in
24c0: 64 65 78 3a 20 22 20 64 75 70 20 24 40 20 38 35  dex: " dup $@ 85
24d0: 74 79 70 65 20 63 72 20 63 65 6c 6c 2b 20 24 40  type cr cell+ $@
24e0: 20 2e 6b 65 79 20 3b 5d 20 23 6d 61 70 20 3b 0a   .key ;] #map ;.
24f0: 3a 20 64 75 6d 70 6b 65 79 73 20 28 20 2d 2d 20  : dumpkeys ( -- 
2500: 29 20 6b 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63  ) key-table [: c
2510: 65 6c 6c 2b 20 24 40 20 64 75 6d 70 6b 65 79 20  ell+ $@ dumpkey 
2520: 3b 5d 20 23 6d 61 70 20 3b 0a 0a 3a 20 6b 65 79  ;] #map ;..: key
2530: 3e 6e 69 63 6b 20 28 20 61 64 64 72 6b 65 79 20  >nick ( addrkey 
2540: 75 31 20 2d 2d 20 6e 69 63 6b 20 75 32 20 29 0a  u1 -- nick u2 ).
2550: 20 20 20 20 6b 65 79 2d 74 61 62 6c 65 20 23 40      key-table #@
2560: 20 30 3d 20 49 46 20 20 64 72 6f 70 20 22 22 20   0= IF  drop "" 
2570: 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20   EXIT  THEN.    
2580: 63 65 6c 6c 2b 20 2e 6b 65 2d 6e 69 63 6b 20 24  cell+ .ke-nick $
2590: 40 20 3b 0a 0a 3a 20 2e 6b 65 79 23 20 28 20 61  @ ;..: .key# ( a
25a0: 64 64 72 20 75 20 2d 2d 20 29 20 6b 65 79 7c 0a  ddr u -- ) key|.
25b0: 20 20 20 20 2e 22 20 4b 65 79 20 27 22 20 6b 65      ." Key '" ke
25c0: 79 2d 74 61 62 6c 65 20 23 40 20 30 3d 20 49 46  y-table #@ 0= IF
25d0: 20 64 72 6f 70 20 45 58 49 54 20 54 48 45 4e 0a   drop EXIT THEN.
25e0: 20 20 20 20 63 65 6c 6c 2b 20 2e 2e 6e 69 63 6b      cell+ ..nick
25f0: 20 2e 22 20 27 20 6f 6b 22 20 63 72 20 3b 0a 0a   ." ' ok" cr ;..
2600: 44 65 66 65 72 20 64 68 74 2d 6e 69 63 6b 3f 0a  Defer dht-nick?.
2610: 65 76 65 6e 74 3a 20 2d 3e 73 65 61 72 63 68 2d  event: ->search-
2620: 6b 65 79 20 20 6b 65 79 7c 20 6f 76 65 72 20 3e  key  key| over >
2630: 72 20 64 68 74 2d 6e 69 63 6b 3f 20 72 3e 20 66  r dht-nick? r> f
2640: 72 65 65 20 74 68 72 6f 77 20 3b 0a 0a 3a 20 2e  ree throw ;..: .
2650: 75 6e 6b 65 79 2d 69 64 20 28 20 61 64 64 72 20  unkey-id ( addr 
2660: 75 20 2d 2d 20 29 20 3c 65 72 72 3e 20 38 20 75  u -- ) <err> 8 u
2670: 6d 69 6e 20 38 35 74 79 70 65 20 2e 22 20 28 75  min 85type ." (u
2680: 6e 6b 6e 6f 77 6e 29 22 20 3c 64 65 66 61 75 6c  nknown)" <defaul
2690: 74 3e 20 3b 0a 0a 3a 20 2e 6b 65 79 2d 69 64 20  t> ;..: .key-id 
26a0: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b 65  ( addr u -- ) ke
26b0: 79 7c 20 32 64 75 70 20 6b 65 79 2d 74 61 62 6c  y| 2dup key-tabl
26c0: 65 20 23 40 20 30 3d 0a 20 20 20 20 49 46 20 20  e #@ 0=.    IF  
26d0: 64 72 6f 70 20 75 70 40 20 72 65 63 65 69 76 65  drop up@ receive
26e0: 72 2d 74 61 73 6b 20 3d 20 49 46 0a 09 20 20 20  r-task = IF..   
26f0: 20 3c 65 76 65 6e 74 20 32 64 75 70 20 73 61 76   <event 2dup sav
2700: 65 2d 6d 65 6d 20 65 24 2c 20 2d 3e 73 65 61 72  e-mem e$, ->sear
2710: 63 68 2d 6b 65 79 20 5b 20 75 70 40 20 5d 6c 20  ch-key [ up@ ]l 
2720: 65 76 65 6e 74 3e 0a 09 20 20 20 20 2e 75 6e 6b  event>..    .unk
2730: 65 79 2d 69 64 20 45 58 49 54 20 20 54 48 45 4e  ey-id EXIT  THEN
2740: 0a 09 32 64 75 70 20 5b 27 5d 20 64 68 74 2d 6e  ..2dup ['] dht-n
2750: 69 63 6b 3f 20 63 6d 64 2d 6e 65 73 74 0a 09 32  ick? cmd-nest..2
2760: 64 75 70 20 6b 65 79 2d 74 61 62 6c 65 20 23 40  dup key-table #@
2770: 20 30 3d 20 49 46 20 20 64 72 6f 70 20 2e 75 6e   0= IF  drop .un
2780: 6b 65 79 2d 69 64 20 45 58 49 54 20 20 54 48 45  key-id EXIT  THE
2790: 4e 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c  N  THEN.    cell
27a0: 2b 20 2e 2e 6e 69 63 6b 20 32 64 72 6f 70 20 3b  + ..nick 2drop ;
27b0: 0a 0a 3a 20 2e 73 69 6d 70 6c 65 2d 69 64 20 28  ..: .simple-id (
27c0: 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b 65 79   addr u -- ) key
27d0: 7c 20 6b 65 79 3e 6e 69 63 6b 20 74 79 70 65 20  | key>nick type 
27e0: 3b 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64 64  ;..:noname ( add
27f0: 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6f 20 49  r u -- ).    o I
2800: 46 20 20 70 75 62 6b 65 79 20 40 20 49 46 0a 09  F  pubkey @ IF..
2810: 20 20 20 20 32 64 75 70 20 70 75 62 6b 65 79 20      2dup pubkey 
2820: 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 30 3d 20  $@ key| str= 0= 
2830: 49 46 0a 09 09 5b 3a 20 2e 22 20 77 61 6e 74 3a  IF...[: ." want:
2840: 20 22 20 70 75 62 6b 65 79 20 24 40 20 6b 65 79   " pubkey $@ key
2850: 7c 20 38 35 74 79 70 65 20 63 72 0a 09 09 20 20  | 85type cr...  
2860: 2e 22 20 67 6f 74 20 3a 20 22 20 32 64 75 70 20  ." got : " 2dup 
2870: 38 35 74 79 70 65 20 63 72 20 3b 5d 20 24 65 72  85type cr ;] $er
2880: 72 0a 09 09 74 72 75 65 20 21 21 77 72 6f 6e 67  r...true !!wrong
2890: 2d 6b 65 79 21 21 0a 09 20 20 20 20 54 48 45 4e  -key!!..    THEN
28a0: 0a 09 20 20 20 20 63 6f 6e 6e 65 63 74 28 20 2e  ..    connect( .
28b0: 6b 65 79 23 20 29 65 6c 73 65 28 20 32 64 72 6f  key# )else( 2dro
28c0: 70 20 29 20 20 45 58 49 54 0a 09 54 48 45 4e 20  p )  EXIT..THEN 
28d0: 20 54 48 45 4e 0a 20 20 20 20 32 64 75 70 20 6b   THEN.    2dup k
28e0: 65 79 2d 65 78 69 73 74 3f 20 64 75 70 20 30 3d  ey-exist? dup 0=
28f0: 20 49 46 0a 09 64 72 6f 70 20 73 74 72 69 63 74   IF..drop strict
2900: 2d 6b 65 79 73 20 40 20 21 21 75 6e 6b 6e 6f 77  -keys @ !!unknow
2910: 6e 2d 6b 65 79 21 21 0a 09 2e 22 20 55 6e 6b 6e  n-key!!..." Unkn
2920: 6f 77 6e 20 6b 65 79 20 22 20 38 35 74 79 70 65  own key " 85type
2930: 20 63 72 0a 20 20 20 20 45 4c 53 45 0a 09 6f 20   cr.    ELSE..o 
2940: 49 46 20 20 2e 6b 65 2d 6d 61 73 6b 20 40 20 70  IF  .ke-mask @ p
2950: 65 72 6d 2d 6d 61 73 6b 20 21 20 20 45 4c 53 45  erm-mask !  ELSE
2960: 20 20 64 72 6f 70 20 20 54 48 45 4e 0a 09 63 6f    drop  THEN..co
2970: 6e 6e 65 63 74 28 20 2e 6b 65 79 23 20 29 65 6c  nnect( .key# )el
2980: 73 65 28 20 32 64 72 6f 70 20 29 0a 20 20 20 20  se( 2drop ).    
2990: 54 48 45 4e 20 3b 20 49 53 20 63 68 65 63 6b 2d  THEN ; IS check-
29a0: 6b 65 79 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 70  key..:noname ( p
29b0: 6b 63 20 2d 2d 20 73 6b 63 20 29 0a 20 20 20 20  kc -- skc ).    
29c0: 6b 65 79 73 69 7a 65 20 6b 65 79 2d 74 61 62 6c  keysize key-tabl
29d0: 65 20 23 40 20 30 3d 20 21 21 75 6e 6b 6e 6f 77  e #@ 0= !!unknow
29e0: 6e 2d 6b 65 79 21 21 0a 20 20 20 20 63 65 6c 6c  n-key!!.    cell
29f0: 2b 20 2e 6b 65 2d 73 6b 20 73 65 63 40 20 30 3d  + .ke-sk sec@ 0=
2a00: 20 21 21 75 6e 6b 6e 6f 77 6e 2d 6b 65 79 21 21   !!unknown-key!!
2a10: 20 3b 20 69 73 20 73 65 61 72 63 68 2d 6b 65 79   ; is search-key
2a20: 0a 0a 5c 20 61 70 70 6c 79 20 70 65 72 6d 69 73  ..\ apply permis
2a30: 73 69 6f 6e 73 0a 0a 3a 20 61 70 70 6c 79 2d 70  sions..: apply-p
2a40: 65 72 6d 69 73 73 69 6f 6e 20 28 20 70 65 72 6d  ermission ( perm
2a50: 61 6e 64 20 70 65 72 6d 6f 72 20 6f 3a 6b 65 79  and permor o:key
2a60: 20 2d 2d 20 70 65 72 6d 61 6e 64 20 70 65 72 6d   -- permand perm
2a70: 6f 72 20 6f 3a 6b 65 79 20 29 0a 20 20 20 20 6f  or o:key ).    o
2a80: 76 65 72 20 6b 65 2d 6d 61 73 6b 20 40 20 61 6e  ver ke-mask @ an
2a90: 64 20 6f 76 65 72 20 6f 72 20 6b 65 2d 6d 61 73  d over or ke-mas
2aa0: 6b 20 21 20 2e 6b 65 79 2d 6c 69 73 74 20 3b 0a  k ! .key-list ;.
2ab0: 0a 5c 20 67 65 74 20 70 61 73 73 70 68 72 61 73  .\ get passphras
2ac0: 65 0a 0a 33 20 56 61 6c 75 65 20 70 61 73 73 70  e..3 Value passp
2ad0: 68 72 61 73 65 2d 72 65 74 72 79 23 0a 24 31 30  hrase-retry#.$10
2ae0: 30 20 43 6f 6e 73 74 61 6e 74 20 6d 61 78 2d 70  0 Constant max-p
2af0: 61 73 73 70 68 72 61 73 65 23 20 5c 20 32 35 36  assphrase# \ 256
2b00: 20 63 68 61 72 61 63 74 65 72 73 20 73 68 6f 75   characters shou
2b10: 6c 64 20 62 65 20 65 6e 6f 75 67 68 2e 2e 2e 0a  ld be enough....
2b20: 6d 61 78 2d 70 61 73 73 70 68 72 61 73 65 23 20  max-passphrase# 
2b30: 62 75 66 66 65 72 3a 20 70 61 73 73 70 68 72 61  buffer: passphra
2b40: 73 65 0a 0a 3a 20 70 61 73 73 70 68 72 61 73 65  se..: passphrase
2b50: 2d 69 6e 20 28 20 2d 2d 20 61 64 64 72 20 75 20  -in ( -- addr u 
2b60: 29 0a 20 20 20 20 70 61 73 73 70 68 72 61 73 65  ).    passphrase
2b70: 20 64 75 70 20 6d 61 78 2d 70 61 73 73 70 68 72   dup max-passphr
2b80: 61 73 65 23 20 61 63 63 65 70 74 2a 20 3b 0a 0a  ase# accept* ;..
2b90: 3a 20 3e 70 61 73 73 70 68 72 61 73 65 20 28 20  : >passphrase ( 
2ba0: 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 20 75  addr u -- addr u
2bb0: 20 29 0a 20 20 20 20 5c 47 20 63 72 65 61 74 65   ).    \G create
2bc0: 20 61 20 35 31 32 20 62 69 74 20 68 61 73 68 20   a 512 bit hash 
2bd0: 6f 66 20 74 68 65 20 70 61 73 73 70 68 72 61 73  of the passphras
2be0: 65 0a 20 20 20 20 6e 6f 2d 6b 65 79 20 3e 63 3a  e.    no-key >c:
2bf0: 6b 65 79 20 63 3a 68 61 73 68 0a 20 20 20 20 6b  key c:hash.    k
2c00: 65 63 63 61 6b 2d 70 61 64 64 65 64 20 63 3a 6b  eccak-padded c:k
2c10: 65 79 3e 20 6b 65 63 63 61 6b 2d 70 61 64 64 65  ey> keccak-padde
2c20: 64 20 6b 65 63 63 61 6b 23 6d 61 78 20 32 2f 20  d keccak#max 2/ 
2c30: 3b 0a 0a 3a 20 67 65 74 2d 70 61 73 73 70 68 72  ;..: get-passphr
2c40: 61 73 65 20 28 20 2d 2d 20 61 64 64 72 20 75 20  ase ( -- addr u 
2c50: 29 0a 20 20 20 20 70 61 73 73 70 68 72 61 73 65  ).    passphrase
2c60: 2d 69 6e 20 3e 70 61 73 73 70 68 72 61 73 65 20  -in >passphrase 
2c70: 3b 0a 0a 56 61 72 69 61 62 6c 65 20 6b 65 79 73  ;..Variable keys
2c80: 0a 0a 3a 20 6c 61 73 74 6b 65 79 40 20 28 20 2d  ..: lastkey@ ( -
2c90: 2d 20 61 64 64 72 20 75 20 29 20 6b 65 79 73 20  - addr u ) keys 
2ca0: 24 5b 5d 23 20 31 2d 20 6b 65 79 73 20 73 65 63  $[]# 1- keys sec
2cb0: 5b 5d 40 20 3b 0a 3a 20 6b 65 79 3e 64 65 66 61  []@ ;.: key>defa
2cc0: 75 6c 74 20 28 20 2d 2d 20 29 20 6c 61 73 74 6b  ult ( -- ) lastk
2cd0: 65 79 40 20 64 72 6f 70 20 3e 73 74 6f 72 65 6b  ey@ drop >storek
2ce0: 65 79 20 21 20 3b 0a 3a 20 2b 6b 65 79 20 28 20  ey ! ;.: +key ( 
2cf0: 61 64 64 72 20 75 20 2d 2d 20 29 20 6b 65 79 73  addr u -- ) keys
2d00: 20 73 65 63 2b 5b 5d 21 20 3b 0a 3a 20 2b 70 61   sec+[]! ;.: +pa
2d10: 73 73 70 68 72 61 73 65 20 28 20 2d 2d 20 29 20  ssphrase ( -- ) 
2d20: 20 67 65 74 2d 70 61 73 73 70 68 72 61 73 65 20   get-passphrase 
2d30: 2b 6b 65 79 20 3b 0a 3a 20 2b 63 68 65 63 6b 70  +key ;.: +checkp
2d40: 68 72 61 73 65 20 28 20 2d 2d 20 66 6c 61 67 20  hrase ( -- flag 
2d50: 29 20 67 65 74 2d 70 61 73 73 70 68 72 61 73 65  ) get-passphrase
2d60: 20 6b 65 79 73 20 24 5b 5d 23 20 31 2d 20 6b 65   keys $[]# 1- ke
2d70: 79 73 20 73 65 63 5b 5d 40 20 73 74 72 3d 20 3b  ys sec[]@ str= ;
2d80: 0a 3a 20 2b 6e 65 77 70 68 72 61 73 65 20 28 20  .: +newphrase ( 
2d90: 2d 2d 20 29 0a 20 20 20 20 42 45 47 49 4e 0a 09  -- ).    BEGIN..
2da0: 2e 22 20 50 61 73 73 70 68 72 61 73 65 3a 20 22  ." Passphrase: "
2db0: 20 2b 70 61 73 73 70 68 72 61 73 65 20 63 72 0a   +passphrase cr.
2dc0: 09 2e 22 20 52 65 74 79 70 65 20 70 6c 73 3a 20  .." Retype pls: 
2dd0: 22 20 2b 63 68 65 63 6b 70 68 72 61 73 65 20 30  " +checkphrase 0
2de0: 3d 20 57 48 49 4c 45 0a 09 20 20 20 20 2e 22 20  = WHILE..    ." 
2df0: 20 64 69 64 6e 27 74 20 6d 61 74 63 68 2c 20 74   didn't match, t
2e00: 72 79 20 61 67 61 69 6e 20 70 6c 65 61 73 65 22  ry again please"
2e10: 20 63 72 0a 20 20 20 20 52 45 50 45 41 54 20 63   cr.    REPEAT c
2e20: 72 20 3b 0a 0a 3a 20 22 3e 70 61 73 73 70 68 72  r ;..: ">passphr
2e30: 61 73 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20  ase ( addr u -- 
2e40: 29 20 3e 70 61 73 73 70 68 72 61 73 65 20 2b 6b  ) >passphrase +k
2e50: 65 79 20 3b 0a 3a 20 2b 73 65 63 6b 65 79 20 28  ey ;.: +seckey (
2e60: 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d 73 6b 20   -- ).    ke-sk 
2e70: 40 20 6b 65 2d 70 6b 20 24 40 20 64 72 6f 70 20  @ ke-pk $@ drop 
2e80: 6b 65 79 70 61 64 20 65 64 2d 64 68 20 2b 6b 65  keypad ed-dh +ke
2e90: 79 20 3b 0a 0a 22 22 20 22 3e 70 61 73 73 70 68  y ;.."" ">passph
2ea0: 72 61 73 65 20 5c 20 66 6f 6c 6c 6f 77 69 6e 67  rase \ following
2eb0: 20 74 68 65 20 65 6e 63 72 79 70 74 2d 65 76 65   the encrypt-eve
2ec0: 72 79 74 68 69 6e 67 20 70 61 72 61 64 69 67 6d  rything paradigm
2ed0: 2c 0a 5c 20 6e 6f 20 70 61 73 73 77 6f 72 64 20  ,.\ no password 
2ee0: 69 73 20 74 68 65 20 65 6d 70 74 79 20 73 74 72  is the empty str
2ef0: 69 6e 67 21 20 20 49 74 27 73 20 73 74 69 6c 6c  ing!  It's still
2f00: 20 65 6e 63 72 79 70 74 65 64 20 3b 2d 29 21 0a   encrypted ;-)!.
2f10: 0a 5c 20 61 20 73 65 63 72 65 74 20 6b 65 79 20  .\ a secret key 
2f20: 6a 75 73 74 20 6e 65 65 64 73 20 61 20 6e 69 63  just needs a nic
2f30: 6b 20 61 6e 64 20 61 20 74 79 70 65 2e 0a 5c 20  k and a type..\ 
2f40: 53 65 63 72 65 74 20 6b 65 79 73 20 63 61 6e 20  Secret keys can 
2f50: 62 65 20 70 65 72 73 6f 6e 73 20 61 6e 64 20 67  be persons and g
2f60: 72 6f 75 70 73 2e 0a 0a 5c 20 61 20 70 75 62 6c  roups...\ a publ
2f70: 69 63 20 6b 65 79 20 6e 65 65 64 73 20 6d 6f 72  ic key needs mor
2f80: 65 3a 20 6e 69 63 6b 2c 20 74 79 70 65 2c 20 70  e: nick, type, p
2f90: 72 6f 66 69 6c 65 2e 0a 5c 20 54 68 65 20 70 72  rofile..\ The pr
2fa0: 6f 66 69 6c 65 20 69 73 20 61 20 73 74 72 75 63  ofile is a struc
2fb0: 74 75 72 65 64 20 64 6f 63 75 6d 65 6e 74 2c 20  tured document, 
2fc0: 69 2e 65 2e 20 70 6f 69 6e 74 65 64 20 74 6f 20  i.e. pointed to 
2fd0: 62 79 20 61 20 68 61 73 68 2e 0a 0a 5c 20 61 20  by a hash...\ a 
2fe0: 73 69 67 6e 61 74 75 72 65 20 63 6f 6e 74 61 69  signature contai
2ff0: 6e 73 20 61 20 70 75 62 6b 65 79 2c 20 61 20 63  ns a pubkey, a c
3000: 68 65 63 6b 62 6f 78 20 62 69 74 6d 61 73 6b 2c  heckbox bitmask,
3010: 0a 5c 20 61 20 64 61 74 65 2c 20 61 6e 20 65 78  .\ a date, an ex
3020: 70 69 72 61 74 69 6f 6e 20 64 61 74 65 2c 20 74  piration date, t
3030: 68 65 20 73 69 67 6e 65 72 27 73 20 70 75 62 6b  he signer's pubk
3040: 65 79 20 61 6e 64 20 74 68 65 20 73 69 67 6e 61  ey and the signa
3050: 74 75 72 65 20 69 74 73 65 6c 66 0a 5c 20 28 72  ture itself.\ (r
3060: 2b 73 29 2e 20 20 54 68 65 72 65 20 69 73 20 61  +s).  There is a
3070: 6e 20 6f 70 74 69 6f 6e 61 6c 20 73 69 67 6e 69  n optional signi
3080: 6e 67 20 70 72 6f 74 6f 63 6f 6c 20 64 6f 63 75  ng protocol docu
3090: 6d 65 6e 74 20 28 68 61 73 68 29 2e 0a 0a 5c 20  ment (hash)...\ 
30a0: 77 65 20 73 74 6f 72 65 20 65 61 63 68 20 69 74  we store each it
30b0: 65 6d 20 69 6e 20 61 20 32 35 36 20 62 79 74 65  em in a 256 byte
30c0: 73 20 65 6e 63 72 79 70 74 65 64 20 73 74 72 69  s encrypted stri
30d0: 6e 67 2c 20 69 2e 65 2e 20 77 69 74 68 20 61 20  ng, i.e. with a 
30e0: 31 36 0a 5c 20 62 79 74 65 20 73 61 6c 74 20 61  16.\ byte salt a
30f0: 6e 64 20 61 20 31 36 20 62 79 74 65 20 63 68 65  nd a 16 byte che
3100: 63 6b 73 75 6d 2e 0a 0a 3a 20 6b 65 2d 6c 61 73  cksum...: ke-las
3110: 74 21 20 28 20 36 34 64 61 74 65 20 2d 2d 20 29  t! ( 64date -- )
3120: 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73 69 67 20  .    ke-selfsig 
3130: 24 40 6c 65 6e 20 24 31 30 20 75 6d 61 78 20 6b  $@len $10 umax k
3140: 65 2d 73 65 6c 66 73 69 67 20 24 21 6c 65 6e 0a  e-selfsig $!len.
3150: 20 20 20 20 6b 65 2d 73 65 6c 66 73 69 67 20 24      ke-selfsig $
3160: 40 20 64 72 6f 70 20 36 34 27 2b 20 36 34 21 20  @ drop 64'+ 64! 
3170: 3b 0a 3a 20 6b 65 2d 66 69 72 73 74 21 20 28 20  ;.: ke-first! ( 
3180: 36 34 64 61 74 65 20 2d 2d 20 29 20 36 34 23 2d  64date -- ) 64#-
3190: 31 20 6b 65 2d 6c 61 73 74 21 0a 20 20 20 20 6b  1 ke-last!.    k
31a0: 65 2d 73 65 6c 66 73 69 67 20 24 40 20 64 72 6f  e-selfsig $@ dro
31b0: 70 20 36 34 21 20 3b 0a 0a 73 63 6f 70 65 7b 20  p 64! ;..scope{ 
31c0: 6e 65 74 32 6f 2d 62 61 73 65 0a 0a 63 6d 64 2d  net2o-base..cmd-
31d0: 74 61 62 6c 65 20 24 40 20 69 6e 68 65 72 69 74  table $@ inherit
31e0: 2d 74 61 62 6c 65 20 6b 65 79 2d 65 6e 74 72 79  -table key-entry
31f0: 2d 74 61 62 6c 65 0a 5c 67 20 0a 5c 67 20 23 23  -table.\g .\g ##
3200: 23 20 6b 65 79 20 73 74 6f 72 61 67 65 20 63 6f  # key storage co
3210: 6d 6d 61 6e 64 73 20 23 23 23 0a 5c 67 20 0a 24  mmands ###.\g .$
3220: 31 31 20 6e 65 74 32 6f 3a 20 70 72 69 76 6b 65  11 net2o: privke
3230: 79 20 28 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20  y ( $:string -- 
3240: 29 0a 20 20 20 20 5c 67 20 70 72 69 76 61 74 65  ).    \g private
3250: 20 6b 65 79 0a 20 20 20 20 5c 20 64 6f 65 73 20   key.    \ does 
3260: 6e 6f 74 20 6e 65 65 64 20 74 6f 20 62 65 20 73  not need to be s
3270: 69 67 6e 65 64 2c 20 74 68 65 20 73 65 63 72 65  igned, the secre
3280: 74 20 6b 65 79 20 76 65 72 69 66 69 65 73 20 69  t key verifies i
3290: 74 73 65 6c 66 0a 20 20 20 20 21 21 75 6e 73 69  tself.    !!unsi
32a0: 67 6e 65 64 3f 20 24 34 30 20 21 21 3e 3d 6f 72  gned? $40 !!>=or
32b0: 64 65 72 3f 20 24 3e 20 6f 76 65 72 20 6b 65 79  der? $> over key
32c0: 70 61 64 20 73 6b 3e 70 6b 20 5c 20 67 65 6e 65  pad sk>pk \ gene
32d0: 72 61 74 65 20 70 75 62 6b 65 79 0a 20 20 20 20  rate pubkey.    
32e0: 6b 65 79 70 61 64 20 6b 65 2d 70 6b 20 24 40 20  keypad ke-pk $@ 
32f0: 64 72 6f 70 20 6b 65 79 73 69 7a 65 20 74 75 63  drop keysize tuc
3300: 6b 20 73 74 72 3d 20 30 3d 20 21 21 77 72 6f 6e  k str= 0= !!wron
3310: 67 2d 6b 65 79 21 21 0a 20 20 20 20 6b 65 2d 73  g-key!!.    ke-s
3320: 6b 20 73 65 63 21 20 2b 73 65 63 6b 65 79 20 3b  k sec! +seckey ;
3330: 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 74 79 70 65  .+net2o: keytype
3340: 20 28 20 6e 20 2d 2d 20 29 20 20 20 20 20 20 20   ( n -- )       
3350: 20 20 20 20 21 21 73 69 67 6e 65 64 3f 20 20 20      !!signed?   
3360: 31 20 21 21 3e 6f 72 64 65 72 3f 20 36 34 3e 6e  1 !!>order? 64>n
3370: 20 6b 65 2d 74 79 70 65 20 21 20 3b 0a 5c 67 20   ke-type ! ;.\g 
3380: 6b 65 79 20 74 79 70 65 20 28 30 3a 20 61 6e 6f  key type (0: ano
3390: 6e 2c 20 31 3a 20 75 73 65 72 2c 20 32 3a 20 67  n, 1: user, 2: g
33a0: 72 6f 75 70 29 0a 2b 6e 65 74 32 6f 3a 20 6b 65  roup).+net2o: ke
33b0: 79 6e 69 63 6b 20 28 20 24 3a 73 74 72 69 6e 67  ynick ( $:string
33c0: 20 2d 2d 20 29 20 20 20 20 21 21 73 69 67 6e 65   -- )    !!signe
33d0: 64 3f 20 20 20 32 20 21 21 3e 6f 72 64 65 72 3f  d?   2 !!>order?
33e0: 20 24 3e 20 6b 65 2d 6e 69 63 6b 20 24 21 0a 20   $> ke-nick $!. 
33f0: 20 20 20 6e 69 63 6b 21 20 3b 0a 5c 67 20 6b 65     nick! ;.\g ke
3400: 79 20 6e 69 63 6b 0a 2b 6e 65 74 32 6f 3a 20 6b  y nick.+net2o: k
3410: 65 79 70 72 6f 66 69 6c 65 20 28 20 24 3a 73 74  eyprofile ( $:st
3420: 72 69 6e 67 20 2d 2d 20 29 20 21 21 73 69 67 6e  ring -- ) !!sign
3430: 65 64 3f 20 20 20 34 20 21 21 3e 6f 72 64 65 72  ed?   4 !!>order
3440: 3f 20 24 3e 20 6b 65 2d 70 72 6f 66 20 24 21 20  ? $> ke-prof $! 
3450: 3b 0a 5c 67 20 6b 65 79 20 70 72 6f 66 69 6c 65  ;.\g key profile
3460: 20 28 68 61 73 68 20 6f 66 20 61 20 72 65 73 6f   (hash of a reso
3470: 75 72 63 65 29 0a 2b 6e 65 74 32 6f 3a 20 6b 65  urce).+net2o: ke
3480: 79 6d 61 73 6b 20 28 20 78 20 2d 2d 20 29 20 20  ymask ( x -- )  
3490: 20 20 20 20 20 20 20 21 21 75 6e 73 69 67 6e 65         !!unsigne
34a0: 64 3f 20 24 32 30 20 21 21 3e 3d 6f 72 64 65 72  d? $20 !!>=order
34b0: 3f 20 36 34 3e 6e 20 6b 65 2d 6d 61 73 6b 20 21  ? 64>n ke-mask !
34c0: 20 3b 0a 5c 67 20 6b 65 79 20 61 63 63 65 73 73   ;.\g key access
34d0: 20 72 69 67 68 74 20 6d 61 73 6b 0a 2b 6e 65 74   right mask.+net
34e0: 32 6f 3a 20 6b 65 79 70 73 6b 20 28 20 24 3a 73  2o: keypsk ( $:s
34f0: 74 72 69 6e 67 20 2d 2d 20 29 20 20 20 20 20 21  tring -- )     !
3500: 21 73 69 67 6e 65 64 3f 20 20 20 38 20 21 21 3e  !signed?   8 !!>
3510: 6f 72 64 65 72 3f 20 24 3e 20 6b 65 2d 70 73 6b  order? $> ke-psk
3520: 20 73 65 63 21 20 3b 0a 5c 67 20 70 72 65 73 68   sec! ;.\g presh
3530: 61 72 65 64 20 6b 65 79 2c 20 75 73 65 64 20 66  ared key, used f
3540: 6f 72 20 44 48 54 20 65 6e 63 72 79 70 74 69 6f  or DHT encryptio
3550: 6e 0a 2b 6e 65 74 32 6f 3a 20 2b 6b 65 79 73 69  n.+net2o: +keysi
3560: 67 20 28 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20  g ( $:string -- 
3570: 29 20 20 21 21 75 6e 73 69 67 6e 65 64 3f 20 24  )  !!unsigned? $
3580: 31 30 20 21 21 3e 3d 6f 72 64 65 72 3f 20 24 3e  10 !!>=order? $>
3590: 20 6b 65 2d 73 69 67 73 20 24 2b 5b 5d 21 20 3b   ke-sigs $+[]! ;
35a0: 0a 5c 67 20 61 64 64 20 61 20 6b 65 79 20 73 69  .\g add a key si
35b0: 67 6e 61 74 75 72 65 0a 2b 6e 65 74 32 6f 3a 20  gnature.+net2o: 
35c0: 6b 65 79 69 6d 70 6f 72 74 20 28 20 6e 20 2d 2d  keyimport ( n --
35d0: 20 29 20 20 20 20 20 20 20 21 21 75 6e 73 69 67   )       !!unsig
35e0: 6e 65 64 3f 20 24 31 30 20 21 21 3e 3d 6f 72 64  ned? $10 !!>=ord
35f0: 65 72 3f 0a 20 20 20 20 70 77 2d 6c 65 76 65 6c  er?.    pw-level
3600: 23 20 30 3c 20 49 46 20 20 36 34 3e 6e 20 69 6d  # 0< IF  64>n im
3610: 70 6f 72 74 23 75 6e 74 72 75 73 74 65 64 20 75  port#untrusted u
3620: 6d 69 6e 20 6b 65 2d 69 6d 70 6f 72 74 20 21 0a  min ke-import !.
3630: 20 20 20 20 45 4c 53 45 20 20 36 34 64 72 6f 70      ELSE  64drop
3640: 20 20 54 48 45 4e 20 3b 0a 7d 73 63 6f 70 65 0a    THEN ;.}scope.
3650: 0a 67 65 6e 2d 74 61 62 6c 65 20 24 66 72 65 65  .gen-table $free
3660: 7a 65 0a 27 20 63 6f 6e 74 65 78 74 2d 74 61 62  ze.' context-tab
3670: 6c 65 20 69 73 20 67 65 6e 2d 74 61 62 6c 65 0a  le is gen-table.
3680: 0a 3a 20 6b 65 79 3a 6e 65 73 74 2d 73 69 67 20  .: key:nest-sig 
3690: 28 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72  ( addr u -- addr
36a0: 20 75 27 20 66 6c 61 67 20 29 0a 20 20 20 20 70   u' flag ).    p
36b0: 6b 32 2d 73 69 67 3f 20 64 75 70 20 3f 45 58 49  k2-sig? dup ?EXI
36c0: 54 20 64 72 6f 70 0a 20 20 20 20 32 64 75 70 20  T drop.    2dup 
36d0: 2b 20 73 69 67 73 69 7a 65 23 20 2d 20 73 69 67  + sigsize# - sig
36e0: 73 69 7a 65 23 20 3e 24 0a 20 20 20 20 73 69 67  size# >$.    sig
36f0: 70 6b 32 73 69 7a 65 23 20 2d 20 32 64 75 70 20  pk2size# - 2dup 
3700: 2b 20 6b 65 79 73 69 7a 65 32 20 6b 65 79 3f 6e  + keysize2 key?n
3710: 65 77 20 6e 3a 3e 6f 20 24 3e 20 6b 65 2d 73 65  ew n:>o $> ke-se
3720: 6c 66 73 69 67 20 24 21 0a 20 20 20 20 73 69 6d  lfsig $!.    sim
3730: 2d 6e 69 63 6b 21 20 6f 66 66 20 63 2d 73 74 61  -nick! off c-sta
3740: 74 65 20 6f 66 66 20 73 69 67 2d 6f 6b 20 3b 0a  te off sig-ok ;.
3750: 27 20 6b 65 79 3a 6e 65 73 74 2d 73 69 67 20 6b  ' key:nest-sig k
3760: 65 79 2d 65 6e 74 72 79 20 74 6f 20 6e 65 73 74  ey-entry to nest
3770: 2d 73 69 67 0a 0a 6b 65 79 2d 65 6e 74 72 79 20  -sig..key-entry 
3780: 27 20 6e 65 77 20 73 74 61 74 69 63 2d 61 20 77  ' new static-a w
3790: 69 74 68 2d 61 6c 6c 6f 63 61 74 65 72 20 74 6f  ith-allocater to
37a0: 20 73 61 6d 70 6c 65 2d 6b 65 79 0a 73 61 6d 70   sample-key.samp
37b0: 6c 65 2d 6b 65 79 20 3e 6f 20 6b 65 79 2d 65 6e  le-key >o key-en
37c0: 74 72 79 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65  try-table @ toke
37d0: 6e 2d 74 61 62 6c 65 20 21 20 6f 3e 0a 0a 3a 20  n-table ! o>..: 
37e0: 6b 65 79 3a 63 6f 64 65 20 28 20 2d 2d 20 29 0a  key:code ( -- ).
37f0: 20 20 20 20 63 6f 64 65 2d 6b 65 79 20 20 63 6d      code-key  cm
3800: 64 6c 6f 63 6b 20 6c 6f 63 6b 0a 20 20 20 20 6b  dlock lock.    k
3810: 65 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61  eypack keypack-a
3820: 6c 6c 23 20 65 72 61 73 65 0a 20 20 20 20 63 6d  ll# erase.    cm
3830: 64 72 65 73 65 74 20 61 6c 73 6f 20 6e 65 74 32  dreset also net2
3840: 6f 2d 62 61 73 65 20 3b 0a 63 6f 6d 70 3a 20 3a  o-base ;.comp: :
3850: 2c 20 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73  , also net2o-bas
3860: 65 20 3b 0a 0a 73 63 6f 70 65 7b 20 6e 65 74 32  e ;..scope{ net2
3870: 6f 2d 62 61 73 65 0a 0a 3a 20 65 6e 64 3a 6b 65  o-base..: end:ke
3880: 79 20 28 20 2d 2d 20 29 0a 20 20 20 20 65 6e 64  y ( -- ).    end
3890: 77 69 74 68 20 70 72 65 76 69 6f 75 73 20 63 6d  with previous cm
38a0: 64 6c 6f 63 6b 20 75 6e 6c 6f 63 6b 20 3b 0a 63  dlock unlock ;.c
38b0: 6f 6d 70 3a 20 3a 2c 20 70 72 65 76 69 6f 75 73  omp: :, previous
38c0: 20 3b 0a 0a 7d 73 63 6f 70 65 0a 0a 3a 20 6b 65   ;..}scope..: ke
38d0: 79 2d 63 72 79 70 74 20 28 20 2d 2d 20 29 0a 20  y-crypt ( -- ). 
38e0: 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79 70 61     keypack keypa
38f0: 63 6b 2d 61 6c 6c 23 0a 20 20 20 20 3e 73 74 6f  ck-all#.    >sto
3900: 72 65 6b 65 79 20 73 65 63 40 20 64 75 70 20 24  rekey sec@ dup $
3910: 32 30 20 75 3c 3d 20 5c 20 69 73 20 61 20 73 65  20 u<= \ is a se
3920: 63 72 65 74 2c 20 6e 6f 20 6e 65 65 64 20 74 6f  cret, no need to
3930: 20 62 65 20 73 6c 6f 77 0a 20 20 20 20 49 46 20   be slow.    IF 
3940: 20 65 6e 63 72 79 70 74 24 20 20 45 4c 53 45 20   encrypt$  ELSE 
3950: 20 70 77 2d 6c 65 76 65 6c 23 20 65 6e 63 72 79   pw-level# encry
3960: 70 74 2d 70 77 24 20 20 54 48 45 4e 20 3b 0a 0a  pt-pw$  THEN ;..
3970: 30 20 56 61 6c 75 65 20 6b 65 79 2d 73 66 64 20  0 Value key-sfd 
3980: 5c 20 73 65 63 72 65 74 20 6b 65 79 73 0a 30 20  \ secret keys.0 
3990: 56 61 6c 75 65 20 6b 65 79 2d 70 66 64 20 5c 20  Value key-pfd \ 
39a0: 70 75 62 6b 65 79 73 0a 0a 3a 20 3f 6b 65 79 2d  pubkeys..: ?key-
39b0: 73 66 64 20 28 20 2d 2d 20 66 64 20 29 20 6b 65  sfd ( -- fd ) ke
39c0: 79 2d 73 66 64 20 22 7e 2f 2e 6e 65 74 32 6f 2f  y-sfd "~/.net2o/
39d0: 73 65 63 6b 65 79 73 2e 6b 32 6f 22 20 3f 66 64  seckeys.k2o" ?fd
39e0: 20 64 75 70 20 74 6f 20 6b 65 79 2d 73 66 64 20   dup to key-sfd 
39f0: 3b 0a 3a 20 3f 6b 65 79 2d 70 66 64 20 28 20 2d  ;.: ?key-pfd ( -
3a00: 2d 20 66 64 20 29 20 6b 65 79 2d 70 66 64 20 22  - fd ) key-pfd "
3a10: 7e 2f 2e 6e 65 74 32 6f 2f 70 75 62 6b 65 79 73  ~/.net2o/pubkeys
3a20: 2e 6b 32 6f 22 20 3f 66 64 20 64 75 70 20 74 6f  .k2o" ?fd dup to
3a30: 20 6b 65 79 2d 70 66 64 20 3b 0a 0a 3a 20 6b 65   key-pfd ;..: ke
3a40: 79 3e 73 66 69 6c 65 20 28 20 2d 2d 20 29 0a 20  y>sfile ( -- ). 
3a50: 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79 70 61     keypack keypa
3a60: 63 6b 2d 61 6c 6c 23 20 3f 6b 65 79 2d 73 66 64  ck-all# ?key-sfd
3a70: 20 61 70 70 65 6e 64 2d 66 69 6c 65 20 6b 65 2d   append-file ke-
3a80: 6f 66 66 73 65 74 20 36 34 21 20 3b 0a 3a 20 6b  offset 64! ;.: k
3a90: 65 79 3e 70 66 69 6c 65 20 28 20 2d 2d 20 29 0a  ey>pfile ( -- ).
3aa0: 20 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79 70      keypack keyp
3ab0: 61 63 6b 2d 61 6c 6c 23 20 3f 6b 65 79 2d 70 66  ack-all# ?key-pf
3ac0: 64 20 61 70 70 65 6e 64 2d 66 69 6c 65 20 6b 65  d append-file ke
3ad0: 2d 6f 66 66 73 65 74 20 36 34 21 20 3b 0a 0a 3a  -offset 64! ;..:
3ae0: 20 6b 65 79 3e 73 66 69 6c 65 40 70 6f 73 20 28   key>sfile@pos (
3af0: 20 36 34 70 6f 73 20 2d 2d 20 29 20 36 34 64 75   64pos -- ) 64du
3b00: 70 20 36 34 23 2d 31 20 36 34 3d 20 49 46 20 20  p 64#-1 64= IF  
3b10: 36 34 64 72 6f 70 20 6b 65 79 3e 73 66 69 6c 65  64drop key>sfile
3b20: 0a 20 20 20 20 45 4c 53 45 20 20 36 34 3e 72 20  .    ELSE  64>r 
3b30: 6b 65 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d  keypack keypack-
3b40: 61 6c 6c 23 20 36 34 72 3e 20 3f 6b 65 79 2d 73  all# 64r> ?key-s
3b50: 66 64 20 77 72 69 74 65 40 70 6f 73 2d 66 69 6c  fd write@pos-fil
3b60: 65 20 20 54 48 45 4e 20 3b 0a 3a 20 6b 65 79 3e  e  THEN ;.: key>
3b70: 70 66 69 6c 65 40 70 6f 73 20 28 20 36 34 70 6f  pfile@pos ( 64po
3b80: 73 20 2d 2d 20 29 20 36 34 64 75 70 20 36 34 23  s -- ) 64dup 64#
3b90: 2d 31 20 36 34 3d 20 49 46 20 20 36 34 64 72 6f  -1 64= IF  64dro
3ba0: 70 20 6b 65 79 3e 70 66 69 6c 65 0a 20 20 20 20  p key>pfile.    
3bb0: 45 4c 53 45 20 20 36 34 3e 72 20 6b 65 79 70 61  ELSE  64>r keypa
3bc0: 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20  ck keypack-all# 
3bd0: 36 34 72 3e 20 3f 6b 65 79 2d 70 66 64 20 77 72  64r> ?key-pfd wr
3be0: 69 74 65 40 70 6f 73 2d 66 69 6c 65 20 20 54 48  ite@pos-file  TH
3bf0: 45 4e 20 3b 0a 0a 3a 20 72 6e 64 3e 73 66 69 6c  EN ;..: rnd>sfil
3c00: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79  e ( -- ).    key
3c10: 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c  pack keypack-all
3c20: 23 20 3e 72 6e 67 24 20 6b 65 79 3e 73 66 69 6c  # >rng$ key>sfil
3c30: 65 20 3b 0a 3a 20 72 6e 64 3e 70 66 69 6c 65 20  e ;.: rnd>pfile 
3c40: 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 70 61  ( -- ).    keypa
3c50: 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20  ck keypack-all# 
3c60: 3e 72 6e 67 24 20 6b 65 79 3e 70 66 69 6c 65 20  >rng$ key>pfile 
3c70: 3b 0a 0a 3a 20 3e 6b 65 79 73 20 28 20 2d 2d 20  ;..: >keys ( -- 
3c80: 29 0a 20 20 20 20 5c 47 20 61 64 64 20 73 68 61  ).    \G add sha
3c90: 72 65 64 20 73 65 63 72 65 74 20 74 6f 20 6c 69  red secret to li
3ca0: 73 74 20 6f 66 20 70 6f 73 73 69 62 6c 65 20 6b  st of possible k
3cb0: 65 79 73 0a 20 20 20 20 73 6b 63 20 70 6b 63 20  eys.    skc pkc 
3cc0: 6b 65 79 70 61 64 20 65 64 2d 64 68 20 2b 6b 65  keypad ed-dh +ke
3cd0: 79 20 3b 0a 0a 5c 20 6b 65 79 20 67 65 6e 65 72  y ;..\ key gener
3ce0: 61 74 69 6f 6e 0a 5c 20 66 6f 72 20 72 65 70 72  ation.\ for repr
3cf0: 6f 64 75 63 69 62 69 6c 69 74 79 20 6f 66 20 74  oducibility of t
3d00: 68 65 20 73 65 6c 66 73 69 67 2c 20 61 6c 77 61  he selfsig, alwa
3d10: 79 73 20 75 73 65 20 74 68 65 20 73 61 6d 65 20  ys use the same 
3d20: 6f 72 64 65 72 3a 0a 5c 20 22 70 75 62 6b 65 79  order:.\ "pubkey
3d30: 22 20 6e 65 77 6b 65 79 20 3c 6e 3e 20 6b 65 79  " newkey <n> key
3d40: 74 79 70 65 20 22 6e 69 63 6b 22 20 6b 65 79 6e  type "nick" keyn
3d50: 69 63 6b 20 22 73 69 67 22 20 6b 65 79 73 65 6c  ick "sig" keysel
3d60: 66 73 69 67 0a 0a 55 73 65 72 20 70 6b 2b 73 69  fsig..User pk+si
3d70: 67 24 0a 0a 6b 65 79 73 69 7a 65 32 20 43 6f 6e  g$..keysize2 Con
3d80: 73 74 61 6e 74 20 70 6b 72 6b 23 0a 0a 3a 20 5d  stant pkrk#..: ]
3d90: 70 6b 2b 73 69 67 6e 20 28 20 61 64 64 72 20 75  pk+sign ( addr u
3da0: 20 2d 2d 20 29 20 2b 63 6d 64 62 75 66 20 5d 73   -- ) +cmdbuf ]s
3db0: 69 67 6e 20 3b 0a 0a 3a 20 70 61 63 6b 2d 6b 65  ign ;..: pack-ke
3dc0: 79 20 28 20 74 79 70 65 20 6e 69 63 6b 20 75 20  y ( type nick u 
3dd0: 2d 2d 20 29 0a 20 20 20 20 6e 6f 77 3e 6e 65 76  -- ).    now>nev
3de0: 65 72 0a 20 20 20 20 6b 65 79 3a 63 6f 64 65 0a  er.    key:code.
3df0: 20 20 20 20 20 20 73 69 67 6e 5b 0a 20 20 20 20        sign[.    
3e00: 20 20 72 6f 74 20 75 6c 69 74 2c 20 6b 65 79 74    rot ulit, keyt
3e10: 79 70 65 20 24 2c 20 6b 65 79 6e 69 63 6b 0a 20  ype $, keynick. 
3e20: 20 20 20 20 20 70 6b 63 20 70 6b 72 6b 23 20 5d       pkc pkrk# ]
3e30: 70 6b 2b 73 69 67 6e 0a 20 20 20 20 20 20 73 6b  pk+sign.      sk
3e40: 63 20 6b 65 79 73 69 7a 65 20 24 2c 20 70 72 69  c keysize $, pri
3e50: 76 6b 65 79 0a 20 20 20 20 65 6e 64 3a 6b 65 79  vkey.    end:key
3e60: 20 3b 0a 0a 61 6c 73 6f 20 6e 65 74 32 6f 2d 62   ;..also net2o-b
3e70: 61 73 65 0a 3a 20 70 61 63 6b 2d 63 6f 72 65 20  ase.: pack-core 
3e80: 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 20 5c 20 63  ( o:key -- ) \ c
3e90: 6f 72 65 20 77 69 74 68 6f 75 74 20 6b 65 79 0a  ore without key.
3ea0: 20 20 20 20 6b 65 2d 74 79 70 65 20 40 20 75 6c      ke-type @ ul
3eb0: 69 74 2c 20 6b 65 79 74 79 70 65 0a 20 20 20 20  it, keytype.    
3ec0: 6b 65 2d 6e 69 63 6b 20 24 40 20 24 2c 20 6b 65  ke-nick $@ $, ke
3ed0: 79 6e 69 63 6b 0a 20 20 20 20 6b 65 2d 70 73 6b  ynick.    ke-psk
3ee0: 20 73 65 63 40 20 64 75 70 20 49 46 20 20 24 2c   sec@ dup IF  $,
3ef0: 20 6b 65 79 70 73 6b 20 20 45 4c 53 45 20 20 32   keypsk  ELSE  2
3f00: 64 72 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 6b  drop  THEN.    k
3f10: 65 2d 70 72 6f 66 20 24 40 20 64 75 70 20 49 46  e-prof $@ dup IF
3f20: 20 20 24 2c 20 6b 65 79 70 72 6f 66 69 6c 65 20    $, keyprofile 
3f30: 20 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 48   ELSE  2drop  TH
3f40: 45 4e 20 3b 0a 0a 3a 20 70 61 63 6b 2d 63 6f 72  EN ;..: pack-cor
3f50: 65 6b 65 79 20 28 20 6f 3a 6b 65 79 20 2d 2d 20  ekey ( o:key -- 
3f60: 29 0a 20 20 20 20 73 69 67 6e 5b 0a 20 20 20 20  ).    sign[.    
3f70: 70 61 63 6b 2d 63 6f 72 65 0a 20 20 20 20 6b 65  pack-core.    ke
3f80: 2d 70 6b 20 24 40 20 2b 63 6d 64 62 75 66 0a 20  -pk $@ +cmdbuf. 
3f90: 20 20 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 40     ke-selfsig $@
3fa0: 20 2b 63 6d 64 62 75 66 20 63 6d 64 2d 72 65 73   +cmdbuf cmd-res
3fb0: 6f 6c 76 65 3e 20 32 64 72 6f 70 20 6e 65 73 74  olve> 2drop nest
3fc0: 73 69 67 0a 20 20 20 20 6b 65 2d 69 6d 70 6f 72  sig.    ke-impor
3fd0: 74 20 40 20 75 6c 69 74 2c 20 6b 65 79 69 6d 70  t @ ulit, keyimp
3fe0: 6f 72 74 0a 20 20 20 20 6b 65 2d 6d 61 73 6b 20  ort.    ke-mask 
3ff0: 40 20 75 6c 69 74 2c 20 6b 65 79 6d 61 73 6b 0a  @ ulit, keymask.
4000: 20 20 20 20 6b 65 2d 73 74 6f 72 65 6b 65 79 20      ke-storekey 
4010: 40 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 3b 0a  @ >storekey ! ;.
4020: 70 72 65 76 69 6f 75 73 0a 0a 3a 20 70 61 63 6b  previous..: pack
4030: 2d 70 75 62 6b 65 79 20 28 20 6f 3a 6b 65 79 20  -pubkey ( o:key 
4040: 2d 2d 20 29 0a 20 20 20 20 6b 65 79 3a 63 6f 64  -- ).    key:cod
4050: 65 0a 20 20 20 20 20 20 70 61 63 6b 2d 63 6f 72  e.      pack-cor
4060: 65 6b 65 79 0a 20 20 20 20 65 6e 64 3a 6b 65 79  ekey.    end:key
4070: 20 3b 0a 3a 20 70 61 63 6b 2d 73 65 63 6b 65 79   ;.: pack-seckey
4080: 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20   ( o:key -- ).  
4090: 20 20 6b 65 79 3a 63 6f 64 65 0a 20 20 20 20 20    key:code.     
40a0: 20 70 61 63 6b 2d 63 6f 72 65 6b 65 79 0a 20 20   pack-corekey.  
40b0: 20 20 20 20 6b 65 2d 73 6b 20 73 65 63 40 20 24      ke-sk sec@ $
40c0: 2c 20 70 72 69 76 6b 65 79 0a 20 20 20 20 65 6e  , privkey.    en
40d0: 64 3a 6b 65 79 20 3b 0a 3a 20 6b 65 79 6e 69 63  d:key ;.: keynic
40e0: 6b 24 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 61 64  k$ ( o:key -- ad
40f0: 64 72 20 75 20 29 0a 20 20 20 20 5c 67 20 67 65  dr u ).    \g ge
4100: 74 20 74 68 65 20 61 6e 6e 6f 74 61 74 69 6f 6e  t the annotation
4110: 73 20 77 69 74 68 20 73 69 67 6e 61 74 75 72 65  s with signature
4120: 0a 20 20 20 20 5b 27 5d 20 70 61 63 6b 2d 63 6f  .    ['] pack-co
4130: 72 65 20 67 65 6e 2d 63 6d 64 24 20 32 64 72 6f  re gen-cmd$ 2dro
4140: 70 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73 69 67  p.    ke-selfsig
4150: 20 24 40 20 74 6d 70 24 20 24 2b 21 20 74 6d 70   $@ tmp$ $+! tmp
4160: 24 20 24 40 20 3b 0a 3a 20 6b 65 79 70 6b 32 6e  $ $@ ;.: keypk2n
4170: 69 63 6b 24 20 28 20 6f 3a 6b 65 79 20 2d 2d 20  ick$ ( o:key -- 
4180: 61 64 64 72 20 75 20 29 0a 20 20 20 20 5c 67 20  addr u ).    \g 
4190: 67 65 74 20 74 68 65 20 61 6e 6e 6f 74 61 74 69  get the annotati
41a0: 6f 6e 73 20 77 69 74 68 20 73 69 67 6e 61 74 75  ons with signatu
41b0: 72 65 0a 20 20 20 20 5b 27 5d 20 70 61 63 6b 2d  re.    ['] pack-
41c0: 63 6f 72 65 20 67 65 6e 2d 63 6d 64 24 20 32 64  core gen-cmd$ 2d
41d0: 72 6f 70 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40  rop.    ke-pk $@
41e0: 20 74 6d 70 24 20 24 2b 21 20 6b 65 2d 73 65 6c   tmp$ $+! ke-sel
41f0: 66 73 69 67 20 24 40 20 74 6d 70 24 20 24 2b 21  fsig $@ tmp$ $+!
4200: 20 74 6d 70 24 20 24 40 20 3b 0a 3a 20 6d 79 6e   tmp$ $@ ;.: myn
4210: 69 63 6b 2d 6b 65 79 20 28 20 2d 2d 20 6f 20 29  ick-key ( -- o )
4220: 0a 20 20 20 20 70 6b 63 20 6b 65 79 73 69 7a 65  .    pkc keysize
4230: 20 6b 65 79 2d 74 61 62 6c 65 20 23 40 20 64 72   key-table #@ dr
4240: 6f 70 20 63 65 6c 6c 2b 20 3b 0a 3a 20 6d 79 6e  op cell+ ;.: myn
4250: 69 63 6b 24 20 28 20 2d 2d 20 61 64 64 72 20 75  ick$ ( -- addr u
4260: 20 29 0a 20 20 20 20 5c 67 20 67 65 74 20 6d 79   ).    \g get my
4270: 20 6e 69 63 6b 20 77 69 74 68 20 73 69 67 6e 61   nick with signa
4280: 74 75 72 65 0a 20 20 20 20 6d 79 6e 69 63 6b 2d  ture.    mynick-
4290: 6b 65 79 20 2e 6b 65 79 6e 69 63 6b 24 20 3b 0a  key .keynick$ ;.
42a0: 3a 20 6d 79 70 6b 32 6e 69 63 6b 24 20 28 20 6f  : mypk2nick$ ( o
42b0: 3a 6b 65 79 20 2d 2d 20 61 64 64 72 20 75 20 29  :key -- addr u )
42c0: 0a 20 20 20 20 5c 67 20 67 65 74 20 6d 79 20 6e  .    \g get my n
42d0: 69 63 6b 20 77 69 74 68 20 73 69 67 6e 61 74 75  ick with signatu
42e0: 72 65 0a 20 20 20 20 6d 79 6e 69 63 6b 2d 6b 65  re.    mynick-ke
42f0: 79 20 2e 6b 65 79 70 6b 32 6e 69 63 6b 24 20 3b  y .keypk2nick$ ;
4300: 0a 0a 56 61 72 69 61 62 6c 65 20 63 70 2d 74 6d  ..Variable cp-tm
4310: 70 0a 0a 3a 20 73 61 76 65 2d 70 75 62 6b 65 79  p..: save-pubkey
4320: 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79  s ( -- ).    key
4330: 2d 70 66 64 20 3f 64 75 70 2d 49 46 20 20 63 6c  -pfd ?dup-IF  cl
4340: 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 20 20  ose-file throw  
4350: 54 48 45 4e 0a 20 20 20 20 3f 2e 6e 65 74 32 6f  THEN.    ?.net2o
4360: 0a 20 20 20 20 22 7e 2f 2e 6e 65 74 32 6f 2f 70  .    "~/.net2o/p
4370: 75 62 6b 65 79 73 2e 6b 32 6f 22 20 5b 3a 20 74  ubkeys.k2o" [: t
4380: 6f 20 6b 65 79 2d 70 66 64 0a 20 20 20 20 20 20  o key-pfd.      
4390: 6b 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63 65 6c  key-table [: cel
43a0: 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b  l+ $@ drop cell+
43b0: 20 3e 6f 0a 09 6b 65 2d 73 6b 20 73 65 63 40 20   >o..ke-sk sec@ 
43c0: 64 30 3d 20 49 46 20 20 70 61 63 6b 2d 70 75 62  d0= IF  pack-pub
43d0: 6b 65 79 0a 09 20 20 20 20 66 6c 75 73 68 28 20  key..    flush( 
43e0: 2e 22 20 73 61 76 69 6e 67 20 22 20 2e 6e 69 63  ." saving " .nic
43f0: 6b 20 66 6f 72 74 68 3a 63 72 20 29 0a 09 20 20  k forth:cr )..  
4400: 20 20 6b 65 79 2d 63 72 79 70 74 20 6b 65 2d 6f    key-crypt ke-o
4410: 66 66 73 65 74 20 36 34 40 20 6b 65 79 3e 70 66  ffset 64@ key>pf
4420: 69 6c 65 40 70 6f 73 0a 09 54 48 45 4e 20 6f 3e  ile@pos..THEN o>
4430: 20 3b 5d 20 23 6d 61 70 0a 20 20 20 20 30 20 74   ;] #map.    0 t
4440: 6f 20 6b 65 79 2d 70 66 64 20 3b 5d 20 73 61 76  o key-pfd ;] sav
4450: 65 2d 66 69 6c 65 20 20 3f 6b 65 79 2d 70 66 64  e-file  ?key-pfd
4460: 20 64 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65 2d   drop ;..: save-
4470: 73 65 63 6b 65 79 73 20 28 20 2d 2d 20 29 0a 20  seckeys ( -- ). 
4480: 20 20 20 6b 65 79 2d 73 66 64 20 3f 64 75 70 2d     key-sfd ?dup-
4490: 49 46 20 20 63 6c 6f 73 65 2d 66 69 6c 65 20 74  IF  close-file t
44a0: 68 72 6f 77 20 20 54 48 45 4e 0a 20 20 20 20 3f  hrow  THEN.    ?
44b0: 2e 6e 65 74 32 6f 0a 20 20 20 20 22 7e 2f 2e 6e  .net2o.    "~/.n
44c0: 65 74 32 6f 2f 73 65 63 6b 65 79 73 2e 6b 32 6f  et2o/seckeys.k2o
44d0: 22 20 5b 3a 20 74 6f 20 6b 65 79 2d 73 66 64 0a  " [: to key-sfd.
44e0: 20 20 20 20 20 20 6b 65 79 2d 74 61 62 6c 65 20        key-table 
44f0: 5b 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70  [: cell+ $@ drop
4500: 20 63 65 6c 6c 2b 20 3e 6f 0a 09 6b 65 2d 73 6b   cell+ >o..ke-sk
4510: 20 73 65 63 40 20 64 30 3c 3e 20 49 46 20 20 70   sec@ d0<> IF  p
4520: 61 63 6b 2d 73 65 63 6b 65 79 0a 09 20 20 20 20  ack-seckey..    
4530: 6b 65 79 2d 63 72 79 70 74 20 6b 65 2d 6f 66 66  key-crypt ke-off
4540: 73 65 74 20 36 34 40 20 6b 65 79 3e 73 66 69 6c  set 64@ key>sfil
4550: 65 40 70 6f 73 0a 09 54 48 45 4e 20 6f 3e 20 3b  e@pos..THEN o> ;
4560: 5d 20 23 6d 61 70 0a 20 20 20 20 30 20 74 6f 20  ] #map.    0 to 
4570: 6b 65 79 2d 73 66 64 20 3b 5d 20 73 61 76 65 2d  key-sfd ;] save-
4580: 66 69 6c 65 20 20 3f 6b 65 79 2d 73 66 64 20 64  file  ?key-sfd d
4590: 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65 2d 6b 65  rop ;..: save-ke
45a0: 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 73 61  ys ( -- ).    sa
45b0: 76 65 2d 70 75 62 6b 65 79 73 20 73 61 76 65 2d  ve-pubkeys save-
45c0: 73 65 63 6b 65 79 73 20 3b 0a 0a 3a 20 2b 67 65  seckeys ;..: +ge
45d0: 6e 2d 6b 65 79 73 20 28 20 6e 69 63 6b 20 75 20  n-keys ( nick u 
45e0: 74 79 70 65 20 2d 2d 20 29 0a 20 20 20 20 67 65  type -- ).    ge
45f0: 6e 2d 6b 65 79 73 20 20 36 34 23 2d 31 20 6b 65  n-keys  64#-1 ke
4600: 79 2d 72 65 61 64 2d 6f 66 66 73 65 74 20 36 34  y-read-offset 64
4610: 21 20 20 70 6b 63 20 6b 65 79 73 69 7a 65 32 20  !  pkc keysize2 
4620: 6b 65 79 3a 6e 65 77 20 3e 6f 0a 20 20 20 20 69  key:new >o.    i
4630: 6d 70 6f 72 74 23 73 65 6c 66 20 6b 65 2d 69 6d  mport#self ke-im
4640: 70 6f 72 74 20 21 20 20 6b 65 2d 74 79 70 65 20  port !  ke-type 
4650: 21 20 20 6b 65 2d 6e 69 63 6b 20 24 21 20 20 6e  !  ke-nick $!  n
4660: 69 63 6b 21 0a 20 20 20 20 73 6b 63 20 6b 65 79  ick!.    skc key
4670: 73 69 7a 65 20 6b 65 2d 73 6b 20 73 65 63 21 20  size ke-sk sec! 
4680: 20 2b 73 65 63 6b 65 79 0a 20 20 20 20 5b 20 61   +seckey.    [ a
4690: 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 20 5d  lso net2o-base ]
46a0: 0a 20 20 20 20 5b 3a 20 6b 65 2d 74 79 70 65 20  .    [: ke-type 
46b0: 40 20 75 6c 69 74 2c 20 6b 65 79 74 79 70 65 20  @ ulit, keytype 
46c0: 6b 65 2d 6e 69 63 6b 20 24 40 20 24 2c 20 6b 65  ke-nick $@ $, ke
46d0: 79 6e 69 63 6b 20 3b 5d 20 67 65 6e 2d 63 6d 64  ynick ;] gen-cmd
46e0: 24 0a 20 20 20 20 5b 20 70 72 65 76 69 6f 75 73  $.    [ previous
46f0: 20 5d 20 5b 3a 20 74 79 70 65 20 70 6b 63 20 6b   ] [: type pkc k
4700: 65 79 73 69 7a 65 32 20 74 79 70 65 20 3b 5d 20  eysize2 type ;] 
4710: 24 74 6d 70 0a 20 20 20 20 6e 6f 77 3e 6e 65 76  $tmp.    now>nev
4720: 65 72 20 63 3a 30 6b 65 79 20 63 3a 68 61 73 68  er c:0key c:hash
4730: 20 5b 27 5d 20 2e 73 69 67 20 24 74 6d 70 20 6b   ['] .sig $tmp k
4740: 65 2d 73 65 6c 66 73 69 67 20 24 21 0a 20 20 20  e-selfsig $!.   
4750: 20 6f 3e 20 3b 0a 0a 3a 20 2b 6b 65 79 70 61 69   o> ;..: +keypai
4760: 72 20 28 20 74 79 70 65 20 6e 69 63 6b 20 75 20  r ( type nick u 
4770: 2d 2d 20 29 20 2b 70 61 73 73 70 68 72 61 73 65  -- ) +passphrase
4780: 20 2b 67 65 6e 2d 6b 65 79 73 20 3b 0a 0a 3a 20   +gen-keys ;..: 
4790: 2e 72 76 6b 20 2e 22 20 50 6c 65 61 73 65 20 77  .rvk ." Please w
47a0: 72 69 74 65 20 64 6f 77 6e 20 72 65 76 6f 6b 65  rite down revoke
47b0: 20 6b 65 79 3a 20 22 20 63 72 0a 20 20 20 20 73   key: " cr.    s
47c0: 6b 72 65 76 20 24 32 30 20 62 6f 75 6e 64 73 20  krev $20 bounds 
47d0: 44 4f 20 20 2e 22 20 5c 20 22 20 49 20 34 20 38  DO  ." \ " I 4 8
47e0: 35 74 79 70 65 20 73 70 61 63 65 20 49 20 34 20  5type space I 4 
47f0: 2b 20 34 20 38 35 74 79 70 65 20 63 72 20 38 20  + 4 85type cr 8 
4800: 2b 4c 4f 4f 50 20 3b 0a 0a 24 34 30 20 62 75 66  +LOOP ;..$40 buf
4810: 66 65 72 3a 20 6e 69 63 6b 2d 62 75 66 0a 0a 3a  fer: nick-buf..:
4820: 20 67 65 74 2d 6e 69 63 6b 20 28 20 2d 2d 20 61   get-nick ( -- a
4830: 64 64 72 20 75 20 29 0a 20 20 20 20 2e 22 20 6e  ddr u ).    ." n
4840: 69 63 6b 3a 20 22 20 6e 69 63 6b 2d 62 75 66 20  ick: " nick-buf 
4850: 24 34 30 20 61 63 63 65 70 74 20 6e 69 63 6b 2d  $40 accept nick-
4860: 62 75 66 20 73 77 61 70 20 63 72 20 3b 0a 3a 20  buf swap cr ;.: 
4870: 6d 61 6b 65 2d 6b 65 79 20 28 20 2d 2d 20 29 0a  make-key ( -- ).
4880: 20 20 20 20 6b 65 79 23 75 73 65 72 20 67 65 74      key#user get
4890: 2d 6e 69 63 6b 0a 20 20 20 20 2e 22 20 70 61 73  -nick.    ." pas
48a0: 73 70 68 72 61 73 65 3a 20 22 20 2b 70 61 73 73  sphrase: " +pass
48b0: 70 68 72 61 73 65 20 6b 65 79 3e 64 65 66 61 75  phrase key>defau
48c0: 6c 74 0a 20 20 20 20 63 72 20 2b 67 65 6e 2d 6b  lt.    cr +gen-k
48d0: 65 79 73 20 2e 72 76 6b 20 3b 0a 0a 5c 20 72 65  eys .rvk ;..\ re
48e0: 61 64 20 6b 65 79 20 66 69 6c 65 0a 0a 3a 20 74  ad key file..: t
48f0: 72 79 2d 64 65 63 72 79 70 74 2d 6b 65 79 20 28  ry-decrypt-key (
4900: 20 6b 65 79 20 75 31 20 2d 2d 20 61 64 64 72 20   key u1 -- addr 
4910: 75 32 20 66 6c 61 67 20 29 0a 20 20 20 20 6b 65  u2 flag ).    ke
4920: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 64 20  ypack keypack-d 
4930: 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 6d 6f 76  keypack-all# mov
4940: 65 0a 20 20 20 20 6b 65 79 70 61 63 6b 2d 64 20  e.    keypack-d 
4950: 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 32 73 77  keypack-all# 2sw
4960: 61 70 0a 20 20 20 20 64 75 70 20 24 32 30 20 3d  ap.    dup $20 =
4970: 20 49 46 20 20 64 65 63 72 79 70 74 24 20 20 45   IF  decrypt$  E
4980: 4c 53 45 0a 09 6b 65 79 70 61 63 6b 20 63 40 20  LSE..keypack c@ 
4990: 24 46 20 61 6e 64 20 70 77 2d 6c 65 76 65 6c 23  $F and pw-level#
49a0: 20 3c 3d 20 49 46 20 20 64 65 63 72 79 70 74 2d   <= IF  decrypt-
49b0: 70 77 24 0a 09 45 4c 53 45 20 20 32 64 72 6f 70  pw$..ELSE  2drop
49c0: 20 66 61 6c 73 65 20 20 54 48 45 4e 0a 20 20 20   false  THEN.   
49d0: 20 54 48 45 4e 20 3b 0a 0a 3a 20 74 72 79 2d 64   THEN ;..: try-d
49e0: 65 63 72 79 70 74 20 28 20 2d 2d 20 61 64 64 72  ecrypt ( -- addr
49f0: 20 75 20 2f 20 30 20 30 20 29 0a 20 20 20 20 6b   u / 0 0 ).    k
4a00: 65 79 73 20 24 5b 5d 23 20 30 20 3f 44 4f 0a 09  eys $[]# 0 ?DO..
4a10: 49 20 6b 65 79 73 20 73 65 63 5b 5d 40 20 74 72  I keys sec[]@ tr
4a20: 79 2d 64 65 63 72 79 70 74 2d 6b 65 79 20 49 46  y-decrypt-key IF
4a30: 0a 09 20 20 20 20 49 20 6b 65 79 73 20 24 5b 5d  ..    I keys $[]
4a40: 20 40 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 75   @ >storekey ! u
4a50: 6e 6c 6f 6f 70 20 20 45 58 49 54 20 20 54 48 45  nloop  EXIT  THE
4a60: 4e 0a 09 32 64 72 6f 70 0a 20 20 20 20 4c 4f 4f  N..2drop.    LOO
4a70: 50 20 20 30 20 30 20 3b 0a 0a 3a 20 3f 70 65 72  P  0 0 ;..: ?per
4a80: 6d 20 28 20 2d 2d 20 29 0a 20 20 20 20 6c 61 73  m ( -- ).    las
4a90: 74 2d 6b 65 79 20 3e 6f 20 6b 65 2d 6d 61 73 6b  t-key >o ke-mask
4aa0: 20 40 20 30 3d 20 49 46 0a 09 6b 65 2d 73 6b 20   @ 0= IF..ke-sk 
4ab0: 73 65 63 40 20 6e 69 70 20 49 46 20 20 70 65 72  sec@ nip IF  per
4ac0: 6d 25 6d 79 73 65 6c 66 20 20 45 4c 53 45 20 20  m%myself  ELSE  
4ad0: 70 65 72 6d 25 64 65 66 61 75 6c 74 20 20 54 48  perm%default  TH
4ae0: 45 4e 20 20 6b 65 2d 6d 61 73 6b 20 21 0a 20 20  EN  ke-mask !.  
4af0: 20 20 54 48 45 4e 20 6f 3e 20 3b 0a 0a 3a 20 64    THEN o> ;..: d
4b00: 6f 2d 6b 65 79 20 28 20 61 64 64 72 20 75 20 2f  o-key ( addr u /
4b10: 20 30 20 30 20 20 2d 2d 20 29 0a 20 20 20 20 64   0 0  -- ).    d
4b20: 75 70 20 30 3d 20 49 46 20 20 32 64 72 6f 70 20  up 0= IF  2drop 
4b30: 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20   EXIT  THEN.    
4b40: 73 61 6d 70 6c 65 2d 6b 65 79 20 2e 64 6f 2d 63  sample-key .do-c
4b50: 6d 64 2d 6c 6f 6f 70 20 3f 70 65 72 6d 20 3b 0a  md-loop ?perm ;.
4b60: 0a 3a 20 2e 6b 65 79 24 20 28 20 61 64 64 72 20  .: .key$ ( addr 
4b70: 75 20 2d 2d 20 29 0a 20 20 20 20 73 61 6d 70 6c  u -- ).    sampl
4b80: 65 2d 6b 65 79 20 3e 6f 20 20 6b 65 2d 73 6b 20  e-key >o  ke-sk 
4b90: 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d 20 65 72  ke-end over - er
4ba0: 61 73 65 0a 20 20 20 20 73 69 67 6e 65 64 2d 76  ase.    signed-v
4bb0: 61 6c 20 76 61 6c 69 64 61 74 65 64 20 6f 72 21  al validated or!
4bc0: 20 20 63 2d 73 74 61 74 65 20 6f 66 66 20 20 6e    c-state off  n
4bd0: 65 73 74 2d 63 6d 64 2d 6c 6f 6f 70 0a 20 20 20  est-cmd-loop.   
4be0: 20 73 69 67 6e 65 64 2d 76 61 6c 20 69 6e 76 65   signed-val inve
4bf0: 72 74 20 76 61 6c 69 64 61 74 65 64 20 61 6e 64  rt validated and
4c00: 21 0a 20 20 20 20 2e 6b 65 79 2d 73 68 6f 72 74  !.    .key-short
4c10: 20 66 72 65 65 2d 6b 65 79 20 6f 3e 20 3b 0a 0a   free-key o> ;..
4c20: 3a 20 72 65 61 64 2d 6b 65 79 73 2d 6c 6f 6f 70  : read-keys-loop
4c30: 20 28 20 66 64 20 2d 2d 20 29 20 20 63 6f 64 65   ( fd -- )  code
4c40: 2d 6b 65 79 0a 20 20 20 20 3e 72 20 30 2e 20 72  -key.    >r 0. r
4c50: 40 20 72 65 70 6f 73 69 74 69 6f 6e 2d 66 69 6c  @ reposition-fil
4c60: 65 20 74 68 72 6f 77 0a 20 20 20 20 42 45 47 49  e throw.    BEGI
4c70: 4e 0a 09 72 40 20 66 69 6c 65 2d 70 6f 73 69 74  N..r@ file-posit
4c80: 69 6f 6e 20 74 68 72 6f 77 20 64 3e 36 34 20 6b  ion throw d>64 k
4c90: 65 79 2d 72 65 61 64 2d 6f 66 66 73 65 74 20 36  ey-read-offset 6
4ca0: 34 21 0a 09 6b 65 79 70 61 63 6b 20 6b 65 79 70  4!..keypack keyp
4cb0: 61 63 6b 2d 61 6c 6c 23 20 72 40 20 72 65 61 64  ack-all# r@ read
4cc0: 2d 66 69 6c 65 20 74 68 72 6f 77 0a 09 6b 65 79  -file throw..key
4cd0: 70 61 63 6b 2d 61 6c 6c 23 20 3d 20 57 48 49 4c  pack-all# = WHIL
4ce0: 45 20 20 74 72 79 2d 64 65 63 72 79 70 74 20 64  E  try-decrypt d
4cf0: 6f 2d 6b 65 79 0a 20 20 20 20 52 45 50 45 41 54  o-key.    REPEAT
4d00: 20 20 72 64 72 6f 70 20 20 63 6f 64 65 30 2d 62    rdrop  code0-b
4d10: 75 66 20 3b 0a 3a 20 72 65 61 64 2d 6b 65 79 2d  uf ;.: read-key-
4d20: 6c 6f 6f 70 20 28 20 2d 2d 20 29 0a 20 20 20 20  loop ( -- ).    
4d30: 69 6d 70 6f 72 74 23 73 65 6c 66 20 69 6d 70 6f  import#self impo
4d40: 72 74 2d 74 79 70 65 20 21 0a 20 20 20 20 3f 6b  rt-type !.    ?k
4d50: 65 79 2d 73 66 64 20 72 65 61 64 2d 6b 65 79 73  ey-sfd read-keys
4d60: 2d 6c 6f 6f 70 20 3b 0a 3a 20 72 65 61 64 2d 70  -loop ;.: read-p
4d70: 6b 65 79 2d 6c 6f 6f 70 20 28 20 2d 2d 20 29 0a  key-loop ( -- ).
4d80: 20 20 20 20 70 77 2d 6c 65 76 65 6c 23 20 3e 72      pw-level# >r
4d90: 20 2d 31 20 74 6f 20 70 77 2d 6c 65 76 65 6c 23   -1 to pw-level#
4da0: 20 20 69 6d 70 6f 72 74 23 6d 61 6e 75 61 6c 20    import#manual 
4db0: 69 6d 70 6f 72 74 2d 74 79 70 65 20 21 0a 20 20  import-type !.  
4dc0: 20 20 3f 6b 65 79 2d 70 66 64 20 72 65 61 64 2d    ?key-pfd read-
4dd0: 6b 65 79 73 2d 6c 6f 6f 70 0a 20 20 20 20 72 3e  keys-loop.    r>
4de0: 20 74 6f 20 70 77 2d 6c 65 76 65 6c 23 20 20 3b   to pw-level#  ;
4df0: 0a 0a 3a 20 72 65 61 64 2d 6b 65 79 73 20 28 20  ..: read-keys ( 
4e00: 2d 2d 20 29 0a 20 20 20 20 72 65 61 64 2d 6b 65  -- ).    read-ke
4e10: 79 2d 6c 6f 6f 70 20 72 65 61 64 2d 70 6b 65 79  y-loop read-pkey
4e20: 2d 6c 6f 6f 70 20 69 6d 70 6f 72 74 23 75 6e 74  -loop import#unt
4e30: 72 75 73 74 65 64 20 69 6d 70 6f 72 74 2d 74 79  rusted import-ty
4e40: 70 65 20 21 20 3b 0a 0a 3a 20 72 65 61 64 2d 70  pe ! ;..: read-p
4e50: 6b 32 6b 65 79 24 20 28 20 61 64 64 72 20 75 20  k2key$ ( addr u 
4e60: 2d 2d 20 29 0a 20 20 20 20 5c 67 20 72 65 61 64  -- ).    \g read
4e70: 20 61 20 6e 65 73 74 65 64 20 6b 65 79 20 69 6e   a nested key in
4e80: 74 6f 20 73 61 6d 70 6c 65 2d 6b 65 79 0a 20 20  to sample-key.  
4e90: 20 20 73 61 6d 70 6c 65 2d 6b 65 79 20 3e 6f 20    sample-key >o 
4ea0: 63 2d 73 74 61 74 65 20 6f 66 66 20 20 73 69 6d  c-state off  sim
4eb0: 2d 6e 69 63 6b 21 20 6f 6e 0a 20 20 20 20 70 6b  -nick! on.    pk
4ec0: 32 2d 73 69 67 3f 20 21 21 73 69 67 21 21 20 73  2-sig? !!sig!! s
4ed0: 69 67 70 6b 32 73 69 7a 65 23 20 2d 20 32 64 75  igpk2size# - 2du
4ee0: 70 20 2b 20 3e 72 20 64 6f 2d 6e 65 73 74 73 69  p + >r do-nestsi
4ef0: 67 0a 20 20 20 20 72 40 20 6b 65 79 73 69 7a 65  g.    r@ keysize
4f00: 32 20 6b 65 2d 70 6b 20 24 21 0a 20 20 20 20 72  2 ke-pk $!.    r
4f10: 3e 20 6b 65 79 73 69 7a 65 32 20 2b 20 73 69 67  > keysize2 + sig
4f20: 73 69 7a 65 23 20 6b 65 2d 73 65 6c 66 73 69 67  size# ke-selfsig
4f30: 20 24 21 0a 20 20 20 20 6f 3e 20 20 73 69 6d 2d   $!.    o>  sim-
4f40: 6e 69 63 6b 21 20 6f 66 66 20 3b 0a 0a 3a 20 2e  nick! off ;..: .
4f50: 70 6b 32 6b 65 79 24 20 28 20 61 64 64 72 20 75  pk2key$ ( addr u
4f60: 20 2d 2d 20 29 0a 20 20 20 20 72 65 61 64 2d 70   -- ).    read-p
4f70: 6b 32 6b 65 79 24 20 73 61 6d 70 6c 65 2d 6b 65  k2key$ sample-ke
4f80: 79 20 3e 6f 20 2e 6b 65 79 2d 69 6e 76 69 74 65  y >o .key-invite
4f90: 20 66 72 65 65 2d 6b 65 79 20 6f 3e 20 3b 0a 0a   free-key o> ;..
4fa0: 5c 20 73 65 6c 65 63 74 20 6b 65 79 20 62 79 20  \ select key by 
4fb0: 6e 69 63 6b 0a 0a 3a 20 3e 72 61 77 2d 6b 65 79  nick..: >raw-key
4fc0: 20 28 20 6f 20 2d 2d 20 29 0a 20 20 20 20 64 75   ( o -- ).    du
4fd0: 70 20 30 3d 20 21 21 6e 6f 2d 6e 69 63 6b 21 21  p 0= !!no-nick!!
4fe0: 20 3e 6f 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40   >o.    ke-pk $@
4ff0: 20 70 6b 63 20 73 77 61 70 20 70 6b 72 6b 23 20   pkc swap pkrk# 
5000: 75 6d 69 6e 20 6d 6f 76 65 0a 20 20 20 20 6b 65  umin move.    ke
5010: 2d 70 73 6b 20 73 65 63 40 20 6d 79 2d 30 6b 65  -psk sec@ my-0ke
5020: 79 20 73 65 63 21 0a 20 20 20 20 6b 65 2d 73 6b  y sec!.    ke-sk
5030: 20 73 65 63 40 20 73 6b 63 20 73 77 61 70 20 6b   sec@ skc swap k
5040: 65 79 7c 20 6d 6f 76 65 0a 20 20 20 20 3e 73 6b  ey| move.    >sk
5050: 73 69 67 20 6f 3e 20 3b 0a 0a 3a 20 3e 6b 65 79  sig o> ;..: >key
5060: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20   ( addr u -- ). 
5070: 20 20 20 6b 65 79 2d 74 61 62 6c 65 20 40 20 30     key-table @ 0
5080: 3d 20 49 46 20 20 72 65 61 64 2d 6b 65 79 73 20  = IF  read-keys 
5090: 20 54 48 45 4e 0a 20 20 20 20 6e 69 63 6b 2d 6b   THEN.    nick-k
50a0: 65 79 20 3e 72 61 77 2d 6b 65 79 20 3b 0a 0a 3a  ey >raw-key ;..:
50b0: 20 69 27 6d 20 28 20 22 6e 61 6d 65 22 20 2d 2d   i'm ( "name" --
50c0: 20 29 20 70 61 72 73 65 2d 6e 61 6d 65 20 3e 6b   ) parse-name >k
50d0: 65 79 20 3b 0a 3a 20 70 6b 27 20 28 20 22 6e 61  ey ;.: pk' ( "na
50e0: 6d 65 22 20 2d 2d 20 61 64 64 72 20 75 20 29 0a  me" -- addr u ).
50f0: 20 20 20 20 70 61 72 73 65 2d 6e 61 6d 65 20 6e      parse-name n
5100: 69 63 6b 3e 70 6b 20 3b 0a 0a 3a 20 64 65 73 74  ick>pk ;..: dest
5110: 2d 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d  -key ( addr u --
5120: 20 29 20 64 75 70 20 30 3d 20 49 46 20 20 32 64   ) dup 0= IF  2d
5130: 72 6f 70 20 20 45 58 49 54 20 20 54 48 45 4e 0a  rop  EXIT  THEN.
5140: 20 20 20 20 6e 69 63 6b 2d 6b 65 79 20 3e 6f 20      nick-key >o 
5150: 6f 20 30 3d 20 21 21 75 6e 6b 6e 6f 77 6e 2d 6b  o 0= !!unknown-k
5160: 65 79 21 21 0a 20 20 20 20 6b 65 2d 70 73 6b 20  ey!!.    ke-psk 
5170: 73 65 63 40 20 73 74 61 74 65 23 20 75 6d 69 6e  sec@ state# umin
5180: 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 6b 65  .    ke-pk $@ ke
5190: 79 7c 20 6f 3e 0a 20 20 20 20 70 75 62 6b 65 79  y| o>.    pubkey
51a0: 20 24 21 20 20 64 65 73 74 2d 30 6b 65 79 20 73   $!  dest-0key s
51b0: 65 63 21 20 3b 0a 0a 3a 20 64 65 73 74 2d 70 6b  ec! ;..: dest-pk
51c0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b   ( addr u -- ) k
51d0: 65 79 32 7c 20 32 64 75 70 20 6b 65 79 7c 20 6b  ey2| 2dup key| k
51e0: 65 79 2d 74 61 62 6c 65 20 23 40 20 30 3d 20 49  ey-table #@ 0= I
51f0: 46 0a 09 64 72 6f 70 20 6b 65 79 7c 20 70 75 62  F..drop key| pub
5200: 6b 65 79 20 24 21 20 20 70 65 72 6d 25 75 6e 6b  key $!  perm%unk
5210: 6e 6f 77 6e 20 70 65 72 6d 2d 6d 61 73 6b 20 21  nown perm-mask !
5220: 0a 20 20 20 20 45 4c 53 45 20 20 63 65 6c 6c 2b  .    ELSE  cell+
5230: 20 3e 6f 0a 09 6b 65 2d 6d 61 73 6b 20 40 0a 09   >o..ke-mask @..
5240: 6b 65 2d 70 73 6b 20 73 65 63 40 20 73 74 61 74  ke-psk sec@ stat
5250: 65 23 20 75 6d 69 6e 0a 09 6b 65 2d 70 6b 20 24  e# umin..ke-pk $
5260: 40 20 6b 65 79 7c 20 6f 3e 0a 09 70 75 62 6b 65  @ key| o>..pubke
5270: 79 20 24 21 20 20 64 65 73 74 2d 30 6b 65 79 20  y $!  dest-0key 
5280: 73 65 63 21 20 20 70 65 72 6d 2d 6d 61 73 6b 20  sec!  perm-mask 
5290: 21 20 20 32 64 72 6f 70 20 20 54 48 45 4e 20 3b  !  2drop  THEN ;
52a0: 0a 0a 3a 20 72 65 70 6c 61 63 65 2d 6b 65 79 20  ..: replace-key 
52b0: 31 20 2f 73 74 72 69 6e 67 20 7b 20 72 65 76 2d  1 /string { rev-
52c0: 61 64 64 72 20 75 20 2d 2d 20 6f 20 7d 20 5c 20  addr u -- o } \ 
52d0: 72 65 76 6f 63 61 74 69 6f 6e 20 74 69 63 6b 65  revocation ticke
52e0: 74 0a 20 20 20 20 6b 65 79 28 20 2e 22 20 52 65  t.    key( ." Re
52f0: 70 6c 61 63 65 3a 22 20 63 72 20 6f 20 63 65 6c  place:" cr o cel
5300: 6c 2d 20 30 20 2e 6b 65 79 20 29 0a 20 20 20 20  l- 0 .key ).    
5310: 69 6d 70 6f 72 74 23 73 65 6c 66 20 69 6d 70 6f  import#self impo
5320: 72 74 2d 74 79 70 65 20 21 0a 20 20 20 20 73 22  rt-type !.    s"
5330: 20 23 72 65 76 6f 6b 65 64 22 20 64 75 70 20 3e   #revoked" dup >
5340: 72 20 6b 65 2d 6e 69 63 6b 20 24 2b 21 0a 20 20  r ke-nick $+!.  
5350: 20 20 6b 65 2d 6e 69 63 6b 20 24 40 20 72 3e 20    ke-nick $@ r> 
5360: 2d 20 6b 65 2d 70 72 6f 66 20 24 40 20 6b 65 2d  - ke-prof $@ ke-
5370: 70 73 6b 20 73 65 63 40 20 6b 65 2d 73 69 67 73  psk sec@ ke-sigs
5380: 20 6b 65 2d 74 79 70 65 20 40 0a 20 20 20 20 72   ke-type @.    r
5390: 65 76 2d 61 64 64 72 20 70 6b 72 6b 23 20 6b 65  ev-addr pkrk# ke
53a0: 79 3f 6e 65 77 20 3e 6f 0a 20 20 20 20 6b 65 2d  y?new >o.    ke-
53b0: 74 79 70 65 20 21 20 5b 3a 20 6b 65 2d 73 69 67  type ! [: ke-sig
53c0: 73 20 24 2b 5b 5d 21 20 3b 5d 20 24 5b 5d 6d 61  s $+[]! ;] $[]ma
53d0: 70 20 6b 65 2d 70 73 6b 20 73 65 63 21 20 6b 65  p ke-psk sec! ke
53e0: 2d 70 72 6f 66 20 24 21 20 6b 65 2d 6e 69 63 6b  -prof $! ke-nick
53f0: 20 24 21 0a 20 20 20 20 72 65 76 2d 61 64 64 72   $!.    rev-addr
5400: 20 70 6b 72 6b 23 20 6b 65 2d 70 6b 20 24 21 0a   pkrk# ke-pk $!.
5410: 20 20 20 20 72 65 76 2d 61 64 64 72 20 75 20 2b      rev-addr u +
5420: 20 31 2d 20 64 75 70 20 63 40 20 32 2a 20 2d 20   1- dup c@ 2* - 
5430: 24 31 30 20 2d 20 24 31 30 20 6b 65 2d 73 65 6c  $10 - $10 ke-sel
5440: 66 73 69 67 20 24 21 0a 20 20 20 20 6b 65 79 28  fsig $!.    key(
5450: 20 2e 22 20 77 69 74 68 3a 22 20 63 72 20 6f 20   ." with:" cr o 
5460: 63 65 6c 6c 2d 20 30 20 2e 6b 65 79 20 29 20 6f  cell- 0 .key ) o
5470: 20 6f 3e 0a 20 20 20 20 69 6d 70 6f 72 74 23 75   o>.    import#u
5480: 6e 74 72 75 73 74 65 64 20 69 6d 70 6f 72 74 2d  ntrusted import-
5490: 74 79 70 65 20 21 20 3b 0a 0a 3a 20 72 65 6e 65  type ! ;..: rene
54a0: 77 2d 6b 65 79 20 28 20 72 65 76 61 64 64 72 20  w-key ( revaddr 
54b0: 75 31 20 6b 65 79 61 64 64 72 20 75 32 20 2d 2d  u1 keyaddr u2 --
54c0: 20 6f 20 29 0a 20 20 20 20 63 75 72 72 65 6e 74   o ).    current
54d0: 2d 6b 65 79 20 3e 6f 20 72 65 70 6c 61 63 65 2d  -key >o replace-
54e0: 6b 65 79 20 6f 3e 0a 20 20 20 20 3e 6f 20 73 6b  key o>.    >o sk
54f0: 63 20 6b 65 79 73 69 7a 65 20 6b 65 2d 73 6b 20  c keysize ke-sk 
5500: 73 65 63 21 20 6f 20 6f 3e 20 3b 0a 0a 5c 20 72  sec! o o> ;..\ r
5510: 65 76 6f 6b 61 74 69 6f 6e 0a 0a 34 20 64 61 74  evokation..4 dat
5520: 65 73 69 7a 65 23 20 2b 20 6b 65 79 73 69 7a 65  esize# + keysize
5530: 20 39 20 2a 20 2b 20 43 6f 6e 73 74 61 6e 74 20   9 * + Constant 
5540: 72 65 76 73 69 7a 65 23 0a 0a 56 61 72 69 61 62  revsize#..Variab
5550: 6c 65 20 72 65 76 74 6f 6b 65 6e 0a 0a 3a 20 30  le revtoken..: 0
5560: 6f 6c 64 6b 65 79 20 28 20 2d 2d 20 29 20 5c 20  oldkey ( -- ) \ 
5570: 70 75 62 6b 65 79 73 20 63 61 6e 20 73 74 61 79  pubkeys can stay
5580: 0a 20 20 20 20 6f 6c 64 73 6b 63 20 6b 65 79 73  .    oldskc keys
5590: 69 7a 65 20 65 72 61 73 65 20 20 6f 6c 64 73 6b  ize erase  oldsk
55a0: 72 65 76 20 6b 65 79 73 69 7a 65 20 65 72 61 73  rev keysize eras
55b0: 65 20 3b 0a 0a 3a 20 6b 65 79 6d 6f 76 65 20 28  e ;..: keymove (
55c0: 20 61 64 64 72 31 20 61 64 64 72 32 20 2d 2d 20   addr1 addr2 -- 
55d0: 29 20 20 6b 65 79 73 69 7a 65 20 6d 6f 76 65 20  )  keysize move 
55e0: 3b 0a 0a 3a 20 72 65 76 6f 6b 65 2d 76 65 72 69  ;..: revoke-veri
55f0: 66 79 20 28 20 61 64 64 72 20 75 31 20 70 6b 20  fy ( addr u1 pk 
5600: 73 74 72 69 6e 67 20 75 32 20 2d 2d 20 61 64 64  string u2 -- add
5610: 72 20 75 20 66 6c 61 67 20 29 20 72 6f 74 20 3e  r u flag ) rot >
5620: 72 20 32 3e 72 20 63 3a 30 6b 65 79 0a 20 20 20  r 2>r c:0key.   
5630: 20 73 69 67 6f 6e 6c 79 73 69 7a 65 23 20 2d 20   sigonlysize# - 
5640: 32 64 75 70 20 32 72 3e 20 3e 6b 65 79 65 64 2d  2dup 2r> >keyed-
5650: 68 61 73 68 0a 20 20 20 20 73 69 67 64 61 74 65  hash.    sigdate
5660: 20 2b 64 61 74 65 0a 20 20 20 20 32 64 75 70 20   +date.    2dup 
5670: 2b 20 72 3e 20 65 64 2d 76 65 72 69 66 79 20 3b  + r> ed-verify ;
5680: 0a 0a 3a 20 3e 72 65 76 6f 6b 65 20 28 20 73 6b  ..: >revoke ( sk
5690: 72 65 76 20 2d 2d 20 29 20 20 73 6b 72 65 76 20  rev -- )  skrev 
56a0: 6b 65 79 6d 6f 76 65 20 20 63 68 65 63 6b 2d 72  keymove  check-r
56b0: 65 76 3f 20 30 3d 20 21 21 6e 6f 74 2d 6d 79 2d  ev? 0= !!not-my-
56c0: 72 65 76 73 6b 21 21 20 3b 0a 0a 3a 20 2b 72 65  revsk!! ;..: +re
56d0: 76 73 69 67 6e 20 28 20 73 6b 20 70 6b 20 2d 2d  vsign ( sk pk --
56e0: 20 29 20 20 73 6b 73 69 67 20 2d 72 6f 74 20 65   )  sksig -rot e
56f0: 64 2d 73 69 67 6e 20 72 65 76 74 6f 6b 65 6e 20  d-sign revtoken 
5700: 24 2b 21 20 62 6c 20 72 65 76 74 6f 6b 65 6e 20  $+! bl revtoken 
5710: 63 24 2b 21 20 3b 0a 0a 3a 20 73 69 67 6e 2d 74  c$+! ;..: sign-t
5720: 6f 6b 65 6e 2c 20 28 20 73 6b 20 70 6b 20 73 74  oken, ( sk pk st
5730: 72 69 6e 67 20 75 32 20 2d 2d 20 29 0a 20 20 20  ring u2 -- ).   
5740: 20 63 3a 30 6b 65 79 20 72 65 76 74 6f 6b 65 6e   c:0key revtoken
5750: 20 24 40 20 32 73 77 61 70 20 3e 6b 65 79 65 64   $@ 2swap >keyed
5760: 2d 68 61 73 68 0a 20 20 20 20 73 69 67 64 61 74  -hash.    sigdat
5770: 65 20 2b 64 61 74 65 20 2b 72 65 76 73 69 67 6e  e +date +revsign
5780: 20 3b 0a 0a 3a 20 72 65 76 6f 6b 65 2d 6b 65 79   ;..: revoke-key
5790: 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20   ( -- addr u ). 
57a0: 20 20 20 73 6b 63 20 6f 6c 64 73 6b 63 20 6b 65     skc oldskc ke
57b0: 79 6d 6f 76 65 20 20 70 6b 63 20 6f 6c 64 70 6b  ymove  pkc oldpk
57c0: 63 20 6b 65 79 6d 6f 76 65 20 20 73 6b 72 65 76  c keymove  skrev
57d0: 20 6f 6c 64 73 6b 72 65 76 20 6b 65 79 6d 6f 76   oldskrev keymov
57e0: 65 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e.              
57f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5800: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 20 62               \ b
5810: 61 63 6b 75 70 20 6b 65 79 73 0a 20 20 20 20 6f  ackup keys.    o
5820: 6c 64 73 6b 72 65 76 20 6f 6c 64 70 6b 72 65 76  ldskrev oldpkrev
5830: 20 73 6b 3e 70 6b 20 20 20 20 20 20 20 20 20 20   sk>pk          
5840: 20 20 20 20 20 20 5c 20 67 65 6e 65 72 61 74 65        \ generate
5850: 20 72 65 76 6f 6b 61 74 69 6f 6e 20 70 75 62 6b   revokation pubk
5860: 65 79 0a 20 20 20 20 67 65 6e 2d 6b 65 79 73 20  ey.    gen-keys 
5870: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5880: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 20                \ 
5890: 67 65 6e 65 72 61 74 65 20 6e 65 77 20 6b 65 79  generate new key
58a0: 73 0a 20 20 20 20 70 6b 63 20 6b 65 79 73 69 7a  s.    pkc keysiz
58b0: 65 32 20 72 65 76 74 6f 6b 65 6e 20 24 21 20 20  e2 revtoken $!  
58c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 20 6d               \ m
58d0: 79 20 6e 65 77 20 6b 65 79 0a 20 20 20 20 6f 6c  y new key.    ol
58e0: 64 70 6b 72 65 76 20 6b 65 79 73 69 7a 65 20 72  dpkrev keysize r
58f0: 65 76 74 6f 6b 65 6e 20 24 2b 21 20 20 20 20 20  evtoken $+!     
5900: 20 20 20 20 20 5c 20 72 65 76 6f 6b 65 20 74 6f       \ revoke to
5910: 6b 65 6e 0a 20 20 20 20 6f 6c 64 73 6b 72 65 76  ken.    oldskrev
5920: 20 6f 6c 64 70 6b 72 65 76 20 22 72 65 76 6f 6b   oldpkrev "revok
5930: 65 22 20 73 69 67 6e 2d 74 6f 6b 65 6e 2c 20 5c  e" sign-token, \
5940: 20 72 65 76 6f 6b 65 20 73 69 67 6e 61 74 75 72   revoke signatur
5950: 65 0a 20 20 20 20 73 6b 63 20 70 6b 63 20 22 73  e.    skc pkc "s
5960: 65 6c 66 73 69 67 6e 22 20 73 69 67 6e 2d 74 6f  elfsign" sign-to
5970: 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 5c 20 73  ken,         \ s
5980: 65 6c 66 20 73 69 67 6e 65 64 20 77 69 74 68 20  elf signed with 
5990: 6e 65 77 20 6b 65 79 0a 20 20 20 20 22 21 22 20  new key.    "!" 
59a0: 72 65 76 74 6f 6b 65 6e 20 30 20 24 69 6e 73 20  revtoken 0 $ins 
59b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59c0: 20 20 20 5c 20 22 21 22 20 2b 20 6f 6c 64 6b 65     \ "!" + oldke
59d0: 79 6c 65 6e 2b 6e 65 77 6b 65 79 6c 65 6e 20 74  ylen+newkeylen t
59e0: 6f 20 66 6c 61 67 20 72 65 76 6f 6b 61 74 69 6f  o flag revokatio
59f0: 6e 0a 20 20 20 20 72 65 76 74 6f 6b 65 6e 20 24  n.    revtoken $
5a00: 40 20 67 65 6e 3e 68 6f 73 74 20 32 64 72 6f 70  @ gen>host 2drop
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 20 73               \ s
5a20: 69 67 6e 20 68 6f 73 74 20 69 6e 66 6f 72 6d 61  ign host informa
5a30: 74 69 6f 6e 20 77 69 74 68 20 6f 6c 64 20 6b 65  tion with old ke
5a40: 79 0a 20 20 20 20 73 69 67 64 61 74 65 20 2b 64  y.    sigdate +d
5a50: 61 74 65 20 73 69 67 64 61 74 65 20 64 61 74 65  ate sigdate date
5a60: 73 69 7a 65 23 20 72 65 76 74 6f 6b 65 6e 20 24  size# revtoken $
5a70: 2b 21 0a 20 20 20 20 6f 6c 64 73 6b 63 20 6f 6c  +!.    oldskc ol
5a80: 64 70 6b 63 20 2b 72 65 76 73 69 67 6e 0a 20 20  dpkc +revsign.  
5a90: 20 20 30 6f 6c 64 6b 65 79 20 72 65 76 74 6f 6b    0oldkey revtok
5aa0: 65 6e 20 24 40 20 3b 0a 0a 5c 20 69 6e 76 69 74  en $@ ;..\ invit
5ab0: 61 74 69 6f 6e 0a 0a 56 61 72 69 61 62 6c 65 20  ation..Variable 
5ac0: 69 6e 76 69 74 61 74 69 6f 6e 73 0a 56 61 72 69  invitations.Vari
5ad0: 61 62 6c 65 20 62 6c 6f 63 6b 2d 74 61 62 6c 65  able block-table
5ae0: 0a 0a 65 76 65 6e 74 3a 20 2d 3e 69 6e 76 69 74  ..event: ->invit
5af0: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a  e ( addr u -- ).
5b00: 20 20 20 20 2e 22 20 69 6e 76 69 74 65 20 6d 65      ." invite me
5b10: 3a 20 22 20 6f 76 65 72 20 3e 72 20 2e 70 6b 32  : " over >r .pk2
5b20: 6b 65 79 24 20 72 3e 20 66 72 65 65 20 74 68 72  key$ r> free thr
5b30: 6f 77 20 63 74 72 6c 20 4c 20 69 6e 73 6b 65 79  ow ctrl L inskey
5b40: 20 3b 0a 65 76 65 6e 74 3a 20 2d 3e 77 61 6b 65   ;.event: ->wake
5b50: 6d 65 20 28 20 6f 20 2d 2d 20 29 20 3c 65 76 65  me ( o -- ) <eve
5b60: 6e 74 20 2d 3e 77 61 6b 65 20 65 76 65 6e 74 3e  nt ->wake event>
5b70: 20 3b 0a 0a 3a 20 70 6b 32 6b 65 79 24 2d 61 64   ;..: pk2key$-ad
5b80: 64 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a  d ( addr u -- ).
5b90: 20 20 20 20 73 61 6d 70 6c 65 2d 6b 65 79 20 3e      sample-key >
5ba0: 6f 20 69 6d 70 6f 72 74 23 69 6e 76 69 74 65 64  o import#invited
5bb0: 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 21 20 63   import-type ! c
5bc0: 6d 64 3a 6e 65 73 74 73 69 67 20 6f 3e 0a 20 20  md:nestsig o>.  
5bd0: 20 20 69 6d 70 6f 72 74 23 75 6e 74 72 75 73 74    import#untrust
5be0: 65 64 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 21  ed import-type !
5bf0: 20 20 73 61 76 65 2d 70 75 62 6b 65 79 73 20 3b    save-pubkeys ;
5c00: 0a 0a 3a 20 62 6c 6f 63 6b 2d 61 64 64 20 28 20  ..: block-add ( 
5c10: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20  addr u -- ).    
5c20: 73 69 67 70 6b 32 73 69 7a 65 23 20 2d 20 2b 20  sigpk2size# - + 
5c30: 6b 65 79 73 69 7a 65 20 32 64 75 70 20 62 6c 6f  keysize 2dup blo
5c40: 63 6b 2d 74 61 62 6c 65 20 23 21 0a 20 20 20 20  ck-table #!.    
5c50: 28 20 74 62 64 3a 20 73 61 76 65 2d 62 6c 6f 63  ( tbd: save-bloc
5c60: 6b 6c 69 73 74 20 29 20 3b 0a 0a 3a 20 70 72 6f  klist ) ;..: pro
5c70: 63 65 73 73 2d 69 6e 76 69 74 61 74 69 6f 6e 20  cess-invitation 
5c80: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20  ( addr u -- ).  
5c90: 20 20 6b 65 79 20 63 61 73 65 0a 09 27 79 27 20    key case..'y' 
5ca0: 6f 66 20 20 70 6b 32 6b 65 79 24 2d 61 64 64 20  of  pk2key$-add 
5cb0: 2e 22 20 61 64 64 65 64 22 20 20 20 20 65 6e 64  ." added"    end
5cc0: 6f 66 0a 09 27 6e 27 20 6f 66 20 20 32 64 72 6f  of..'n' of  2dro
5cd0: 70 20 20 20 20 20 20 20 2e 22 20 69 67 6e 6f 72  p       ." ignor
5ce0: 65 64 22 20 20 65 6e 64 6f 66 0a 09 27 62 27 20  ed"  endof..'b' 
5cf0: 6f 66 20 20 62 6c 6f 63 6b 2d 61 64 64 20 20 20  of  block-add   
5d00: 2e 22 20 62 6c 6f 63 6b 65 64 22 20 20 65 6e 64  ." blocked"  end
5d10: 6f 66 0a 09 32 64 72 6f 70 0a 20 20 20 20 65 6e  of..2drop.    en
5d20: 64 63 61 73 65 20 3b 0a 0a 3a 20 66 69 6c 74 65  dcase ;..: filte
5d30: 72 2d 69 6e 76 69 74 61 74 69 6f 6e 3f 20 28 20  r-invitation? ( 
5d40: 61 64 64 72 20 75 20 2d 2d 20 66 6c 61 67 20 29  addr u -- flag )
5d50: 0a 20 20 20 20 73 69 67 70 6b 32 73 69 7a 65 23  .    sigpk2size#
5d60: 20 2d 20 2b 0a 20 20 20 20 64 75 70 20 6b 65 79   - +.    dup key
5d70: 73 69 7a 65 20 62 6c 6f 63 6b 2d 74 61 62 6c 65  size block-table
5d80: 20 23 40 20 6e 69 70 20 6b 65 79 73 69 7a 65 20   #@ nip keysize 
5d90: 3d 0a 20 20 20 20 49 46 20 64 72 6f 70 20 74 72  =.    IF drop tr
5da0: 75 65 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20  ue  EXIT  THEN. 
5db0: 20 20 20 6b 65 79 73 69 7a 65 20 6b 65 79 2d 74     keysize key-t
5dc0: 61 62 6c 65 20 23 40 20 64 30 3c 3e 20 3b 20 5c  able #@ d0<> ; \
5dd0: 20 61 6c 72 65 61 64 79 20 74 68 65 72 65 0a 0a   already there..
5de0: 3a 20 2e 69 6e 76 69 74 61 74 69 6f 6e 73 20 28  : .invitations (
5df0: 20 2d 2d 20 29 0a 20 20 20 20 69 6e 76 69 74 61   -- ).    invita
5e00: 74 69 6f 6e 73 20 5b 3a 20 2e 22 20 69 6e 76 69  tions [: ." invi
5e10: 74 65 20 28 79 2f 6e 2f 62 29 3f 20 22 20 32 64  te (y/n/b)? " 2d
5e20: 75 70 20 2e 70 6b 32 6b 65 79 24 20 70 72 6f 63  up .pk2key$ proc
5e30: 65 73 73 2d 69 6e 76 69 74 61 74 69 6f 6e 0a 20  ess-invitation. 
5e40: 20 20 20 3b 5d 20 24 5b 5d 6d 61 70 20 20 69 6e     ;] $[]map  in
5e50: 76 69 74 61 74 69 6f 6e 73 20 24 5b 5d 6f 66 66  vitations $[]off
5e60: 20 3b 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 61 64   ;..:noname ( ad
5e70: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 32 64  dr u -- ).    2d
5e80: 75 70 20 66 69 6c 74 65 72 2d 69 6e 76 69 74 61  up filter-invita
5e90: 74 69 6f 6e 3f 20 49 46 20 20 32 64 72 6f 70 20  tion? IF  2drop 
5ea0: 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 32  EXIT  THEN.    2
5eb0: 64 75 70 20 69 6e 76 69 74 61 74 69 6f 6e 73 20  dup invitations 
5ec0: 24 69 6e 73 5b 5d 73 69 67 20 73 61 76 65 2d 6d  $ins[]sig save-m
5ed0: 65 6d 20 5b 20 75 70 40 20 5d 6c 20 3c 68 69 64  em [ up@ ]l <hid
5ee0: 65 3e 0a 20 20 20 20 3c 65 76 65 6e 74 20 65 24  e>.    <event e$
5ef0: 2c 20 2d 3e 69 6e 76 69 74 65 20 75 70 40 20 65  , ->invite up@ e
5f00: 6c 69 74 2c 20 2d 3e 77 61 6b 65 6d 65 20 5b 20  lit, ->wakeme [ 
5f10: 75 70 40 20 5d 6c 20 65 76 65 6e 74 3e 20 73 74  up@ ]l event> st
5f20: 6f 70 0a 3b 20 69 73 20 3e 69 6e 76 69 74 61 74  op.; is >invitat
5f30: 69 6f 6e 73 0a 3a 20 73 65 6e 64 2d 69 6e 76 69  ions.: send-invi
5f40: 74 61 74 69 6f 6e 20 28 20 70 6b 20 75 20 2d 2d  tation ( pk u --
5f50: 20 29 0a 20 20 20 20 73 65 74 75 70 21 20 6d 79   ).    setup! my
5f60: 70 6b 32 6e 69 63 6b 24 20 32 3e 72 0a 20 20 20  pk2nick$ 2>r.   
5f70: 20 67 65 6e 2d 74 6d 70 6b 65 79 73 20 64 72 6f   gen-tmpkeys dro
5f80: 70 20 74 73 6b 63 20 73 77 61 70 20 6b 65 79 70  p tskc swap keyp
5f90: 61 64 20 65 64 2d 64 68 20 64 6f 2d 6b 65 79 70  ad ed-dh do-keyp
5fa0: 61 64 20 73 65 63 21 0a 20 20 20 20 6e 65 74 32  ad sec!.    net2
5fb0: 6f 2d 63 6f 64 65 30 0a 20 20 20 20 74 70 6b 63  o-code0.    tpkc
5fc0: 20 6b 65 79 73 69 7a 65 20 24 2c 20 6f 6e 65 73   keysize $, ones
5fd0: 68 6f 74 2d 74 6d 70 6b 65 79 0a 20 20 20 20 6e  hot-tmpkey.    n
5fe0: 65 73 74 5b 20 32 72 3e 20 24 2c 20 69 6e 76 69  est[ 2r> $, invi
5ff0: 74 65 20 5d 74 6d 70 6e 65 73 74 0a 20 20 20 20  te ]tmpnest.    
6000: 63 6f 6f 6b 69 65 2b 72 65 71 75 65 73 74 0a 20  cookie+request. 
6010: 20 20 20 65 6e 64 2d 63 6f 64 65 7c 20 3b 0a 0a     end-code| ;..
6020: 30 20 5b 49 46 5d 0a 4c 6f 63 61 6c 20 56 61 72  0 [IF].Local Var
6030: 69 61 62 6c 65 73 3a 0a 66 6f 72 74 68 2d 6c 6f  iables:.forth-lo
6040: 63 61 6c 2d 77 6f 72 64 73 3a 0a 20 20 20 20 28  cal-words:.    (
6050: 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f 3a 22  .     (("net2o:"
6060: 20 22 2b 6e 65 74 32 6f 3a 22 29 20 64 65 66 69   "+net2o:") defi
6070: 6e 69 74 69 6f 6e 2d 73 74 61 72 74 65 72 20 28  nition-starter (
6080: 66 6f 6e 74 2d 6c 6f 63 6b 2d 6b 65 79 77 6f 72  font-lock-keywor
6090: 64 2d 66 61 63 65 20 2e 20 31 29 0a 20 20 20 20  d-face . 1).    
60a0: 20 20 22 5b 20 5c 74 5c 6e 5d 22 20 74 20 6e 61    "[ \t\n]" t na
60b0: 6d 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 66 75  me (font-lock-fu
60c0: 6e 63 74 69 6f 6e 2d 6e 61 6d 65 2d 66 61 63 65  nction-name-face
60d0: 20 2e 20 33 29 29 0a 20 20 20 20 20 28 28 22 64   . 3)).     (("d
60e0: 65 62 75 67 3a 22 20 22 66 69 65 6c 64 3a 22 20  ebug:" "field:" 
60f0: 22 32 66 69 65 6c 64 3a 22 20 22 73 66 66 69 65  "2field:" "sffie
6100: 6c 64 3a 22 20 22 64 66 66 69 65 6c 64 3a 22 20  ld:" "dffield:" 
6110: 22 36 34 66 69 65 6c 64 3a 22 20 22 75 76 61 72  "64field:" "uvar
6120: 22 20 22 75 76 61 6c 75 65 22 29 20 6e 6f 6e 2d  " "uvalue") non-
6130: 69 6d 6d 65 64 69 61 74 65 20 28 66 6f 6e 74 2d  immediate (font-
6140: 6c 6f 63 6b 2d 74 79 70 65 2d 66 61 63 65 20 2e  lock-type-face .
6150: 20 32 29 0a 20 20 20 20 20 20 22 5b 20 5c 74 5c   2).      "[ \t\
6160: 6e 5d 22 20 74 20 6e 61 6d 65 20 28 66 6f 6e 74  n]" t name (font
6170: 2d 6c 6f 63 6b 2d 76 61 72 69 61 62 6c 65 2d 6e  -lock-variable-n
6180: 61 6d 65 2d 66 61 63 65 20 2e 20 33 29 29 0a 20  ame-face . 3)). 
6190: 20 20 20 20 28 22 5b 61 2d 7a 30 2d 39 5d 2b 28      ("[a-z0-9]+(
61a0: 22 20 69 6d 6d 65 64 69 61 74 65 20 28 66 6f 6e  " immediate (fon
61b0: 74 2d 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e 74 2d 66  t-lock-comment-f
61c0: 61 63 65 20 2e 20 31 29 0a 20 20 20 20 20 20 22  ace . 1).      "
61d0: 29 22 20 6e 69 6c 20 63 6f 6d 6d 65 6e 74 20 28  )" nil comment (
61e0: 66 6f 6e 74 2d 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e  font-lock-commen
61f0: 74 2d 66 61 63 65 20 2e 20 31 29 29 0a 20 20 20  t-face . 1)).   
6200: 20 29 0a 66 6f 72 74 68 2d 6c 6f 63 61 6c 2d 69   ).forth-local-i
6210: 6e 64 65 6e 74 2d 77 6f 72 64 73 3a 0a 20 20 20  ndent-words:.   
6220: 20 28 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f   (.     (("net2o
6230: 3a 22 20 22 2b 6e 65 74 32 6f 3a 22 29 20 28 30  :" "+net2o:") (0
6240: 20 2e 20 32 29 20 28 30 20 2e 20 32 29 20 6e 6f   . 2) (0 . 2) no
6250: 6e 2d 69 6d 6d 65 64 69 61 74 65 29 0a 20 20 20  n-immediate).   
6260: 20 20 28 28 22 5b 3a 22 20 22 6b 65 79 3a 63 6f    (("[:" "key:co
6270: 64 65 22 29 20 28 30 20 2e 20 31 29 20 28 30 20  de") (0 . 1) (0 
6280: 2e 20 31 29 20 69 6d 6d 65 64 69 61 74 65 29 0a  . 1) immediate).
6290: 20 20 20 20 20 28 28 22 3b 5d 22 20 22 65 6e 64       ((";]" "end
62a0: 3a 6b 65 79 22 29 20 28 2d 31 20 2e 20 30 29 20  :key") (-1 . 0) 
62b0: 28 30 20 2e 20 2d 31 29 20 69 6d 6d 65 64 69 61  (0 . -1) immedia
62c0: 74 65 29 0a 20 20 20 20 29 0a 45 6e 64 3a 0a 5b  te).    ).End:.[
62d0: 54 48 45 4e 5d                                   THEN]