Hex Artifact Content
Not logged in

Artifact 3d63bd6a5434f454b4e665aff3b154ec7fd49905:


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 33 2d 32 30 31 35 20 20   (C) 2013-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 73 63 6f 70  word entry..scop
0300: 65 7b 20 63 6f 6e 66 69 67 0a 56 61 72 69 61 62  e{ config.Variab
0310: 6c 65 20 70 77 2d 6c 65 76 65 6c 23 20 32 20 70  le pw-level# 2 p
0320: 77 2d 6c 65 76 65 6c 23 20 21 20 5c 20 70 77 2d  w-level# ! \ pw-
0330: 6c 65 76 65 6c 23 20 30 20 69 73 20 6c 6f 77 65  level# 0 is lowe
0340: 73 74 0a 56 61 72 69 61 62 6c 65 20 70 77 2d 6d  st.Variable pw-m
0350: 61 78 6c 65 76 65 6c 23 20 34 20 70 77 2d 6d 61  axlevel# 4 pw-ma
0360: 78 6c 65 76 65 6c 23 20 21 20 5c 20 70 77 2d 6d  xlevel# ! \ pw-m
0370: 61 78 6c 65 76 65 6c 23 20 69 73 20 74 68 65 20  axlevel# is the 
0380: 6d 61 78 69 6d 75 6d 20 63 68 65 63 6b 65 64 0a  maximum checked.
0390: 7d 73 63 6f 70 65 0a 0a 5b 49 46 44 45 46 5d 20  }scope..[IFDEF] 
03a0: 6d 73 6c 69 6e 75 78 20 27 2a 27 20 5b 45 4c 53  mslinux '*' [ELS
03b0: 45 5d 20 27 e2 80 a2 27 20 5b 54 48 45 4e 5d 20  E] '...' [THEN] 
03c0: 43 6f 6e 73 74 61 6e 74 20 70 77 2a 0a 0a 78 63  Constant pw*..xc
03d0: 2d 76 65 63 74 6f 72 20 75 70 40 20 2d 20 63 6c  -vector up@ - cl
03e0: 61 73 73 2d 6f 20 21 0a 0a 30 20 63 65 6c 6c 20  ass-o !..0 cell 
03f0: 75 76 61 72 20 65 73 63 2d 73 74 61 74 65 20 64  uvar esc-state d
0400: 72 6f 70 0a 0a 44 65 66 65 72 20 6f 6c 64 2d 65  rop..Defer old-e
0410: 6d 69 74 20 20 77 68 61 74 27 73 20 65 6d 69 74  mit  what's emit
0420: 20 69 73 20 6f 6c 64 2d 65 6d 69 74 0a 0a 68 65   is old-emit..he
0430: 72 65 0a 78 63 2d 76 65 63 74 6f 72 20 40 20 63  re.xc-vector @ c
0440: 65 6c 6c 2d 20 64 75 70 20 40 20 74 75 63 6b 20  ell- dup @ tuck 
0450: 2d 20 68 65 72 65 20 73 77 61 70 20 64 75 70 20  - here swap dup 
0460: 61 6c 6c 6f 74 20 6d 6f 76 65 0a 2c 20 68 65 72  allot move., her
0470: 65 20 30 20 2c 20 43 6f 6e 73 74 61 6e 74 20 75  e 0 , Constant u
0480: 74 66 2d 38 2a 0a 0a 78 63 2d 76 65 63 74 6f 72  tf-8*..xc-vector
0490: 20 40 20 20 75 74 66 2d 38 2a 20 78 63 2d 76 65   @  utf-8* xc-ve
04a0: 63 74 6f 72 20 21 20 27 20 2a 2d 77 69 64 74 68  ctor ! ' *-width
04b0: 20 69 73 20 78 2d 77 69 64 74 68 20 20 78 63 2d   is x-width  xc-
04c0: 76 65 63 74 6f 72 20 21 0a 0a 3a 20 65 6d 69 74  vector !..: emit
04d0: 2d 70 77 2a 20 28 20 6e 20 2d 2d 20 29 0a 20 20  -pw* ( n -- ).  
04e0: 20 20 64 75 70 20 23 65 73 63 20 3d 20 49 46 20    dup #esc = IF 
04f0: 20 65 73 63 2d 73 74 61 74 65 20 6f 6e 20 20 54   esc-state on  T
0500: 48 45 4e 0a 20 20 20 20 64 75 70 20 62 6c 20 3c  HEN.    dup bl <
0510: 20 49 46 20 20 6f 6c 64 2d 65 6d 69 74 20 20 45   IF  old-emit  E
0520: 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 65 73  XIT  THEN.    es
0530: 63 2d 73 74 61 74 65 20 40 20 49 46 20 20 64 75  c-state @ IF  du
0540: 70 20 6f 6c 64 2d 65 6d 69 74 0a 09 74 6f 75 70  p old-emit..toup
0550: 70 65 72 20 27 41 27 20 27 5b 27 20 77 69 74 68  per 'A' '[' with
0560: 69 6e 20 49 46 20 20 65 73 63 2d 73 74 61 74 65  in IF  esc-state
0570: 20 6f 66 66 20 20 54 48 45 4e 0a 20 20 20 20 45   off  THEN.    E
0580: 4c 53 45 20 20 24 43 30 20 24 38 30 20 77 69 74  LSE  $C0 $80 wit
0590: 68 69 6e 20 49 46 0a 09 20 20 20 20 5b 20 70 77  hin IF..    [ pw
05a0: 2a 20 27 20 78 65 6d 69 74 20 24 74 6d 70 0a 09  * ' xemit $tmp..
05b0: 20 20 20 20 62 6f 75 6e 64 73 20 5b 3f 44 4f 5d      bounds [?DO]
05c0: 20 5b 49 5d 20 63 40 20 5d 4c 20 6f 6c 64 2d 65   [I] c@ ]L old-e
05d0: 6d 69 74 20 5b 20 5b 4c 4f 4f 50 5d 20 5d 0a 09  mit [ [LOOP] ]..
05e0: 54 48 45 4e 0a 20 20 20 20 54 48 45 4e 20 3b 0a  THEN.    THEN ;.
05f0: 0a 3a 20 74 79 70 65 2d 70 77 2a 20 28 20 61 64  .: type-pw* ( ad
0600: 64 72 20 75 20 2d 2d 20 29 20 20 32 64 75 70 20  dr u -- )  2dup 
0610: 62 6c 20 73 6b 69 70 20 6e 69 70 20 30 3d 0a 20  bl skip nip 0=. 
0620: 20 20 20 49 46 20 20 20 20 62 6f 75 6e 64 73 20     IF    bounds 
0630: 55 2b 44 4f 20 20 62 6c 20 6f 6c 64 2d 65 6d 69  U+DO  bl old-emi
0640: 74 20 20 20 20 4c 4f 4f 50 0a 20 20 20 20 45 4c  t    LOOP.    EL
0650: 53 45 20 20 62 6f 75 6e 64 73 20 55 2b 44 4f 20  SE  bounds U+DO 
0660: 20 49 20 63 40 20 65 6d 69 74 2d 70 77 2a 20 20   I c@ emit-pw*  
0670: 4c 4f 4f 50 20 20 54 48 45 4e 20 3b 0a 0a 3a 20  LOOP  THEN ;..: 
0680: 61 63 63 65 70 74 2a 20 28 20 61 64 64 72 20 75  accept* ( addr u
0690: 20 2d 2d 20 75 27 20 29 0a 20 20 20 20 5c 47 20   -- u' ).    \G 
06a0: 61 63 63 65 70 74 2d 6c 69 6b 65 20 69 6e 70 75  accept-like inpu
06b0: 74 2c 20 62 75 74 20 74 79 70 65 73 20 2a 20 69  t, but types * i
06c0: 6e 73 74 65 61 64 20 6f 66 20 74 68 65 20 63 68  nstead of the ch
06d0: 61 72 61 63 74 65 72 0a 20 20 20 20 5c 47 20 64  aracter.    \G d
06e0: 6f 6e 27 74 20 73 61 76 65 20 69 6e 74 6f 20 68  on't save into h
06f0: 69 73 74 6f 72 79 0a 20 20 20 20 68 69 73 74 6f  istory.    histo
0700: 72 79 20 3e 72 20 20 77 68 61 74 27 73 20 74 79  ry >r  what's ty
0710: 70 65 20 3e 72 20 20 77 68 61 74 27 73 20 65 6d  pe >r  what's em
0720: 69 74 20 69 73 20 6f 6c 64 2d 65 6d 69 74 0a 20  it is old-emit. 
0730: 20 20 20 75 74 66 2d 38 2a 20 78 63 2d 76 65 63     utf-8* xc-vec
0740: 74 6f 72 20 21 40 20 3e 72 20 20 5b 27 5d 20 74  tor !@ >r  ['] t
0750: 79 70 65 2d 70 77 2a 20 69 73 20 74 79 70 65 20  ype-pw* is type 
0760: 20 5b 27 5d 20 65 6d 69 74 2d 70 77 2a 20 69 73   ['] emit-pw* is
0770: 20 65 6d 69 74 0a 20 20 20 20 30 20 74 6f 20 68   emit.    0 to h
0780: 69 73 74 6f 72 79 0a 20 20 20 20 5b 27 5d 20 61  istory.    ['] a
0790: 63 63 65 70 74 20 63 61 74 63 68 0a 20 20 20 20  ccept catch.    
07a0: 72 3e 20 78 63 2d 76 65 63 74 6f 72 20 21 20 20  r> xc-vector !  
07b0: 77 68 61 74 27 73 20 6f 6c 64 2d 65 6d 69 74 20  what's old-emit 
07c0: 69 73 20 65 6d 69 74 20 20 72 3e 20 69 73 20 74  is emit  r> is t
07d0: 79 70 65 20 20 72 3e 20 74 6f 20 68 69 73 74 6f  ype  r> to histo
07e0: 72 79 0a 20 20 20 20 74 68 72 6f 77 20 2d 31 20  ry.    throw -1 
07f0: 30 20 61 74 2d 64 65 6c 74 61 78 79 20 73 70 61  0 at-deltaxy spa
0800: 63 65 20 3b 0a 0a 5c 20 4b 65 79 73 20 61 72 65  ce ;..\ Keys are
0810: 20 70 61 73 73 77 6f 72 64 73 20 61 6e 64 20 70   passwords and p
0820: 72 69 76 61 74 65 20 6b 65 79 73 20 28 73 65 6c  rivate keys (sel
0830: 66 2d 6b 65 79 65 64 2c 20 69 2e 65 2e 20 70 72  f-keyed, i.e. pr
0840: 69 76 61 74 65 2a 70 75 62 6c 69 63 20 6b 65 79  ivate*public key
0850: 29 0a 0a 63 6d 64 2d 62 75 66 30 20 75 63 6c 61  )..cmd-buf0 ucla
0860: 73 73 20 63 6d 64 62 75 66 2d 6f 0a 20 20 20 20  ss cmdbuf-o.    
0870: 6d 61 78 64 61 74 61 20 2d 0a 20 20 20 20 6b 65  maxdata -.    ke
0880: 79 2d 73 61 6c 74 23 20 75 76 61 72 20 6b 65 79  y-salt# uvar key
0890: 70 61 63 6b 0a 20 20 20 20 6b 65 79 70 61 63 6b  pack.    keypack
08a0: 23 20 20 75 76 61 72 20 6b 65 79 70 61 63 6b 2d  #  uvar keypack-
08b0: 62 75 66 0a 20 20 20 20 6b 65 79 2d 63 6b 73 75  buf.    key-cksu
08c0: 6d 23 20 75 76 61 72 20 6b 65 79 70 61 63 6b 2d  m# uvar keypack-
08d0: 63 68 6b 73 75 6d 0a 65 6e 64 2d 63 6c 61 73 73  chksum.end-class
08e0: 20 63 6d 64 2d 6b 65 79 62 75 66 2d 63 0a 0a 63   cmd-keybuf-c..c
08f0: 6d 64 2d 6b 65 79 62 75 66 2d 63 20 27 20 6e 65  md-keybuf-c ' ne
0900: 77 20 73 74 61 74 69 63 2d 61 20 77 69 74 68 2d  w static-a with-
0910: 61 6c 6c 6f 63 61 74 65 72 20 63 6f 64 65 2d 6b  allocater code-k
0920: 65 79 5e 20 21 0a 27 20 63 6f 64 65 2d 6b 65 79  ey^ !.' code-key
0930: 5e 20 63 6d 64 62 75 66 3a 20 63 6f 64 65 2d 6b  ^ cmdbuf: code-k
0940: 65 79 0a 0a 63 6f 64 65 2d 6b 65 79 0a 63 6d 64  ey..code-key.cmd
0950: 30 6c 6f 63 6b 20 30 20 70 74 68 72 65 61 64 5f  0lock 0 pthread_
0960: 6d 75 74 65 78 5f 69 6e 69 74 20 64 72 6f 70 0a  mutex_init drop.
0970: 0a 3a 6e 6f 6e 61 6d 65 20 28 20 2d 2d 20 61 64  .:noname ( -- ad
0980: 64 72 20 75 20 29 20 6b 65 79 70 61 63 6b 2d 62  dr u ) keypack-b
0990: 75 66 20 63 6d 64 62 75 66 23 20 40 20 3b 20 74  uf cmdbuf# @ ; t
09a0: 6f 20 63 6d 64 62 75 66 24 0a 3a 6e 6f 6e 61 6d  o cmdbuf$.:nonam
09b0: 65 20 28 20 2d 2d 20 6e 20 29 20 20 6b 65 79 70  e ( -- n )  keyp
09c0: 61 63 6b 23 20 63 6d 64 62 75 66 23 20 40 20 2d  ack# cmdbuf# @ -
09d0: 20 3b 20 74 6f 20 6d 61 78 73 74 72 69 6e 67 0a   ; to maxstring.
09e0: 0a 63 6f 64 65 30 2d 62 75 66 0a 0a 3a 6e 6f 6e  .code0-buf..:non
09f0: 61 6d 65 20 64 65 66 65 72 73 20 61 6c 6c 6f 63  ame defers alloc
0a00: 2d 63 6f 64 65 2d 62 75 66 73 0a 20 20 20 20 63  -code-bufs.    c
0a10: 6d 64 2d 6b 65 79 62 75 66 2d 63 20 6e 65 77 20  md-keybuf-c new 
0a20: 63 6f 64 65 2d 6b 65 79 5e 20 21 20 3b 20 69 73  code-key^ ! ; is
0a30: 20 61 6c 6c 6f 63 2d 63 6f 64 65 2d 62 75 66 73   alloc-code-bufs
0a40: 0a 3a 6e 6f 6e 61 6d 65 20 64 65 66 65 72 73 20  .:noname defers 
0a50: 66 72 65 65 2d 63 6f 64 65 2d 62 75 66 73 0a 20  free-code-bufs. 
0a60: 20 20 20 63 6f 64 65 2d 6b 65 79 5e 20 40 20 2e     code-key^ @ .
0a70: 64 69 73 70 6f 73 65 20 3b 20 69 73 20 66 72 65  dispose ; is fre
0a80: 65 2d 63 6f 64 65 2d 62 75 66 73 0a 0a 5c 20 68  e-code-bufs..\ h
0a90: 61 73 68 65 64 20 6b 65 79 20 64 61 74 61 20 62  ashed key data b
0aa0: 61 73 65 0a 0a 56 61 72 69 61 62 6c 65 20 67 72  ase..Variable gr
0ab0: 6f 75 70 73 5b 5d 20 5c 20 6e 61 6d 65 73 20 6f  oups[] \ names o
0ac0: 66 20 67 72 6f 75 70 73 2c 20 73 6f 72 74 65 64  f groups, sorted
0ad0: 20 62 79 20 6f 72 64 65 72 20 69 6e 20 67 72 6f   by order in gro
0ae0: 75 70 73 20 66 69 6c 65 0a 0a 55 73 65 72 20 3e  ups file..User >
0af0: 73 74 6f 72 65 6b 65 79 0a 56 61 72 69 61 62 6c  storekey.Variabl
0b00: 65 20 64 65 66 61 75 6c 74 6b 65 79 0a 0a 3a 20  e defaultkey..: 
0b10: 66 72 65 65 2d 6b 65 79 20 28 20 6f 3a 6b 65 79  free-key ( o:key
0b20: 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20 20 20   -- o:key ).    
0b30: 5c 67 20 66 72 65 65 20 61 6c 6c 20 70 61 72 74  \g free all part
0b40: 73 20 6f 66 20 74 68 65 20 73 75 62 6b 65 79 0a  s of the subkey.
0b50: 20 20 20 20 6b 65 2d 73 6b 20 73 65 63 2d 6f 66      ke-sk sec-of
0b60: 66 0a 20 20 20 20 6b 65 2d 70 6b 20 24 6f 66 66  f.    ke-pk $off
0b70: 0a 20 20 20 20 6b 65 2d 6e 69 63 6b 20 24 6f 66  .    ke-nick $of
0b80: 66 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73 69 67  f.    ke-selfsig
0b90: 20 24 6f 66 66 0a 20 20 20 20 6b 65 2d 73 69 67   $off.    ke-sig
0ba0: 73 5b 5d 20 24 5b 5d 6f 66 66 0a 20 20 20 20 6b  s[] $[]off.    k
0bb0: 65 2d 70 65 74 73 5b 5d 20 24 5b 5d 6f 66 66 0a  e-pets[] $[]off.
0bc0: 20 20 20 20 6b 65 2d 70 65 74 73 23 20 24 6f 66      ke-pets# $of
0bd0: 66 20 3b 0a 0a 5c 20 6b 65 79 20 63 6c 61 73 73  f ;..\ key class
0be0: 0a 0a 30 0a 65 6e 75 6d 20 6b 65 79 23 61 6e 6f  ..0.enum key#ano
0bf0: 6e 0a 65 6e 75 6d 20 6b 65 79 23 75 73 65 72 0a  n.enum key#user.
0c00: 65 6e 75 6d 20 6b 65 79 23 67 72 6f 75 70 0a 64  enum key#group.d
0c10: 72 6f 70 0a 0a 5c 20 6b 65 79 20 69 6d 70 6f 72  rop..\ key impor
0c20: 74 20 74 79 70 65 0a 0a 30 0a 65 6e 75 6d 20 69  t type..0.enum i
0c30: 6d 70 6f 72 74 23 73 65 6c 66 20 20 20 20 20 20  mport#self      
0c40: 5c 20 70 72 69 76 61 74 65 20 6b 65 79 0a 65 6e  \ private key.en
0c50: 75 6d 20 69 6d 70 6f 72 74 23 6d 61 6e 75 61 6c  um import#manual
0c60: 20 20 20 20 5c 20 6d 61 6e 75 61 6c 20 69 6d 70      \ manual imp
0c70: 6f 72 74 0a 65 6e 75 6d 20 69 6d 70 6f 72 74 23  ort.enum import#
0c80: 73 63 61 6e 20 20 20 20 20 20 5c 20 73 63 61 6e  scan      \ scan
0c90: 20 69 6d 70 6f 72 74 0a 65 6e 75 6d 20 69 6d 70   import.enum imp
0ca0: 6f 72 74 23 63 68 61 74 20 20 20 20 20 20 5c 20  ort#chat      \ 
0cb0: 73 65 65 6e 20 69 6e 20 63 68 61 74 0a 65 6e 75  seen in chat.enu
0cc0: 6d 20 69 6d 70 6f 72 74 23 64 68 74 20 20 20 20  m import#dht    
0cd0: 20 20 20 5c 20 64 68 74 20 69 6d 70 6f 72 74 0a     \ dht import.
0ce0: 65 6e 75 6d 20 69 6d 70 6f 72 74 23 69 6e 76 69  enum import#invi
0cf0: 74 65 64 20 20 20 5c 20 69 6e 76 69 74 61 74 69  ted   \ invitati
0d00: 6f 6e 20 69 6d 70 6f 72 74 0a 65 6e 75 6d 20 69  on import.enum i
0d10: 6d 70 6f 72 74 23 75 6e 74 72 75 73 74 65 64 20  mport#untrusted 
0d20: 5c 20 6d 75 73 74 20 62 65 20 6c 61 73 74 0a 64  \ must be last.d
0d30: 72 6f 70 0a 24 31 46 20 65 6e 75 6d 20 69 6d 70  rop.$1F enum imp
0d40: 6f 72 74 23 6e 65 77 20 20 20 5c 20 6e 65 77 20  ort#new   \ new 
0d50: 66 6f 72 6d 61 74 0a 64 72 6f 70 0a 0a 43 72 65  format.drop..Cre
0d60: 61 74 65 20 69 6d 70 6f 72 74 73 24 20 24 32 30  ate imports$ $20
0d70: 20 61 6c 6c 6f 74 20 69 6d 70 6f 72 74 73 24 20   allot imports$ 
0d80: 24 32 30 20 62 6c 20 66 69 6c 6c 0a 22 49 6d 73  $20 bl fill."Ims
0d90: 63 64 69 75 22 20 69 6d 70 6f 72 74 73 24 20 73  cdiu" imports$ s
0da0: 77 61 70 20 6d 6f 76 65 0a 0a 56 61 72 69 61 62  wap move..Variab
0db0: 6c 65 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 20  le import-type  
0dc0: 69 6d 70 6f 72 74 23 6e 65 77 20 69 6d 70 6f 72  import#new impor
0dd0: 74 2d 74 79 70 65 20 21 0a 0a 43 72 65 61 74 65  t-type !..Create
0de0: 20 3e 69 6d 2d 63 6f 6c 6f 72 20 20 24 42 36 30   >im-color  $B60
0df0: 20 2c 20 24 44 36 30 20 2c 20 24 39 36 30 20 2c   , $D60 , $960 ,
0e00: 20 24 43 36 30 20 2c 20 24 41 36 30 20 2c 20 24   $C60 , $A60 , $
0e10: 38 42 31 20 2c 20 24 45 36 30 20 2c 0a 44 4f 45  8B1 , $E60 ,.DOE
0e20: 53 3e 20 73 77 61 70 20 38 20 63 65 6c 6c 73 20  S> swap 8 cells 
0e30: 30 20 44 4f 20 20 64 75 70 20 31 20 61 6e 64 20  0 DO  dup 1 and 
0e40: 49 46 20 20 64 72 6f 70 20 49 20 4c 45 41 56 45  IF  drop I LEAVE
0e50: 20 20 54 48 45 4e 20 20 32 2f 20 20 4c 4f 4f 50    THEN  2/  LOOP
0e60: 0a 20 20 63 65 6c 6c 73 20 2b 20 40 20 61 74 74  .  cells + @ att
0e70: 72 21 20 3b 0a 0a 3a 20 2e 69 6d 70 6f 72 74 73  r! ;..: .imports
0e80: 20 28 20 6d 61 73 6b 20 2d 2d 20 29 0a 20 20 20   ( mask -- ).   
0e90: 20 69 6d 70 6f 72 74 73 24 20 69 6d 70 6f 72 74   imports$ import
0ea0: 23 6e 65 77 20 62 6f 75 6e 64 73 20 44 4f 0a 09  #new bounds DO..
0eb0: 31 20 49 20 69 6d 70 6f 72 74 73 24 20 2d 20 6c  1 I imports$ - l
0ec0: 73 68 69 66 74 20 3e 69 6d 2d 63 6f 6c 6f 72 0a  shift >im-color.
0ed0: 09 64 75 70 20 31 20 61 6e 64 20 49 46 20 20 49  .dup 1 and IF  I
0ee0: 20 63 40 20 65 6d 69 74 20 20 54 48 45 4e 20 20   c@ emit  THEN  
0ef0: 32 2f 20 4c 4f 4f 50 0a 20 20 20 20 64 72 6f 70  2/ LOOP.    drop
0f00: 20 3c 64 65 66 61 75 6c 74 3e 20 3b 0a 0a 43 72   <default> ;..Cr
0f10: 65 61 74 65 20 69 6d 70 6f 72 74 2d 6e 61 6d 65  eate import-name
0f20: 24 0a 22 49 20 6d 79 73 65 6c 66 22 20 73 2c 20  $."I myself" s, 
0f30: 22 6d 61 6e 75 61 6c 22 20 73 2c 20 22 73 63 61  "manual" s, "sca
0f40: 6e 22 20 73 2c 20 22 63 68 61 74 22 20 73 2c 20  n" s, "chat" s, 
0f50: 22 64 68 74 22 20 73 2c 20 22 69 6e 76 69 74 65  "dht" s, "invite
0f60: 64 22 20 73 2c 20 22 75 6e 74 72 75 73 74 65 64  d" s, "untrusted
0f70: 22 20 73 2c 0a 0a 3a 20 2e 69 6d 70 6f 72 74 2d  " s,..: .import-
0f80: 63 6f 6c 6f 72 73 20 28 20 2d 2d 20 29 0a 20 20  colors ( -- ).  
0f90: 20 20 69 6d 70 6f 72 74 2d 6e 61 6d 65 24 0a 20    import-name$. 
0fa0: 20 20 20 69 6d 70 6f 72 74 23 75 6e 74 72 75 73     import#untrus
0fb0: 74 65 64 20 31 2b 20 30 20 3f 44 4f 0a 09 31 20  ted 1+ 0 ?DO..1 
0fc0: 49 20 6c 73 68 69 66 74 20 3e 69 6d 2d 63 6f 6c  I lshift >im-col
0fd0: 6f 72 20 63 6f 75 6e 74 20 32 64 75 70 20 74 79  or count 2dup ty
0fe0: 70 65 20 3c 64 65 66 61 75 6c 74 3e 20 73 70 61  pe <default> spa
0ff0: 63 65 20 2b 20 61 6c 69 67 6e 65 64 0a 20 20 20  ce + aligned.   
1000: 20 4c 4f 4f 50 20 64 72 6f 70 20 3b 0a 0a 5c 20   LOOP drop ;..\ 
1010: 73 61 6d 70 6c 65 20 6b 65 79 0a 0a 6b 65 79 2d  sample key..key-
1020: 65 6e 74 72 79 20 27 20 6e 65 77 20 73 74 61 74  entry ' new stat
1030: 69 63 2d 61 20 77 69 74 68 2d 61 6c 6c 6f 63 61  ic-a with-alloca
1040: 74 65 72 20 43 6f 6e 73 74 61 6e 74 20 73 61 6d  ter Constant sam
1050: 70 6c 65 2d 6b 65 79 0a 0a 56 61 72 69 61 62 6c  ple-key..Variabl
1060: 65 20 6b 65 79 23 20 5c 20 6b 65 79 20 68 61 73  e key# \ key has
1070: 68 20 74 61 62 6c 65 0a 56 61 72 69 61 62 6c 65  h table.Variable
1080: 20 6e 69 63 6b 23 20 5c 20 6e 69 63 6b 20 68 61   nick# \ nick ha
1090: 73 68 20 74 61 62 6c 65 0a 0a 36 34 56 61 72 69  sh table..64Vari
10a0: 61 62 6c 65 20 6b 65 79 2d 72 65 61 64 2d 6f 66  able key-read-of
10b0: 66 73 65 74 0a 0a 3a 20 63 75 72 72 65 6e 74 2d  fset..: current-
10c0: 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20  key ( addr u -- 
10d0: 6f 20 29 0a 20 20 20 20 32 64 75 70 20 6b 65 79  o ).    2dup key
10e0: 7c 20 6b 65 79 23 20 23 40 20 64 72 6f 70 0a 20  | key# #@ drop. 
10f0: 20 20 20 64 75 70 20 30 3d 20 49 46 20 20 64 72     dup 0= IF  dr
1100: 6f 70 20 2e 22 20 75 6e 6b 6e 6f 77 6e 20 6b 65  op ." unknown ke
1110: 79 3a 20 22 20 38 35 74 79 70 65 20 63 72 20 20  y: " 85type cr  
1120: 30 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20  0 EXIT  THEN.   
1130: 20 63 65 6c 6c 2b 20 3e 6f 20 6b 65 2d 70 6b 20   cell+ >o ke-pk 
1140: 24 21 20 6f 20 6f 3e 20 3b 0a 0a 56 61 72 69 61  $! o o> ;..Varia
1150: 62 6c 65 20 73 69 6d 2d 6e 69 63 6b 21 0a 0a 3a  ble sim-nick!..:
1160: 20 6e 69 63 6b 21 20 28 20 2d 2d 20 29 20 73 69   nick! ( -- ) si
1170: 6d 2d 6e 69 63 6b 21 20 40 20 3f 45 58 49 54 20  m-nick! @ ?EXIT 
1180: 20 6f 20 7b 20 77 5e 20 6f 70 74 72 20 7d 0a 20   o { w^ optr }. 
1190: 20 20 20 6b 65 2d 6e 69 63 6b 20 24 40 20 6e 69     ke-nick $@ ni
11a0: 63 6b 23 20 23 40 20 64 30 3d 20 49 46 0a 09 6f  ck# #@ d0= IF..o
11b0: 70 74 72 20 63 65 6c 6c 20 6b 65 2d 6e 69 63 6b  ptr cell ke-nick
11c0: 20 24 40 20 6e 69 63 6b 23 20 23 21 20 30 0a 20   $@ nick# #! 0. 
11d0: 20 20 20 45 4c 53 45 0a 09 6c 61 73 74 23 20 63     ELSE..last# c
11e0: 65 6c 6c 2b 20 24 40 6c 65 6e 20 63 65 6c 6c 2f  ell+ $@len cell/
11f0: 0a 09 6f 70 74 72 20 63 65 6c 6c 20 6c 61 73 74  ..optr cell last
1200: 23 20 63 65 6c 6c 2b 20 24 2b 21 0a 20 20 20 20  # cell+ $+!.    
1210: 54 48 45 4e 20 20 6b 65 2d 6e 69 63 6b 23 20 21  THEN  ke-nick# !
1220: 20 3b 0a 0a 3a 20 23 2e 6e 69 63 6b 20 28 20 68   ;..: #.nick ( h
1230: 61 73 68 20 2d 2d 20 29 0a 20 20 20 20 64 75 70  ash -- ).    dup
1240: 20 24 40 20 74 79 70 65 20 27 23 27 20 65 6d 69   $@ type '#' emi
1250: 74 20 63 65 6c 6c 2b 20 24 40 6c 65 6e 20 63 65  t cell+ $@len ce
1260: 6c 6c 2f 20 2e 20 3b 0a 0a 3a 20 6c 61 73 74 2d  ll/ . ;..: last-
1270: 70 65 74 40 20 28 20 2d 2d 20 61 64 64 72 20 75  pet@ ( -- addr u
1280: 20 29 0a 20 20 20 20 6b 65 2d 70 65 74 73 5b 5d   ).    ke-pets[]
1290: 20 24 5b 5d 23 20 3f 64 75 70 2d 49 46 20 20 31   $[]# ?dup-IF  1
12a0: 2d 20 6b 65 2d 70 65 74 73 5b 5d 20 24 5b 5d 40  - ke-pets[] $[]@
12b0: 20 20 45 4c 53 45 20 20 23 30 2e 20 20 54 48 45    ELSE  #0.  THE
12c0: 4e 20 3b 0a 0a 3a 20 70 65 74 21 20 28 20 2d 2d  N ;..: pet! ( --
12d0: 20 29 20 73 69 6d 2d 6e 69 63 6b 21 20 40 20 3f   ) sim-nick! @ ?
12e0: 45 58 49 54 20 20 6f 20 7b 20 77 5e 20 6f 70 74  EXIT  o { w^ opt
12f0: 72 20 7d 0a 20 20 20 20 6c 61 73 74 2d 70 65 74  r }.    last-pet
1300: 40 20 6e 69 63 6b 23 20 23 40 20 64 30 3d 20 49  @ nick# #@ d0= I
1310: 46 0a 09 6f 70 74 72 20 63 65 6c 6c 20 6c 61 73  F..optr cell las
1320: 74 2d 70 65 74 40 20 6e 69 63 6b 23 20 23 21 20  t-pet@ nick# #! 
1330: 30 0a 20 20 20 20 45 4c 53 45 0a 09 6c 61 73 74  0.    ELSE..last
1340: 23 20 63 65 6c 6c 2b 20 24 40 6c 65 6e 20 63 65  # cell+ $@len ce
1350: 6c 6c 2f 0a 09 6f 70 74 72 20 63 65 6c 6c 20 6c  ll/..optr cell l
1360: 61 73 74 23 20 63 65 6c 6c 2b 20 24 2b 21 0a 20  ast# cell+ $+!. 
1370: 20 20 20 54 48 45 4e 20 20 6b 65 2d 70 65 74 73     THEN  ke-pets
1380: 5b 5d 20 24 5b 5d 23 20 31 2d 20 6b 65 2d 70 65  [] $[]# 1- ke-pe
1390: 74 73 23 20 24 5b 5d 20 21 20 3b 0a 0a 3a 20 6b  ts# $[] ! ;..: k
13a0: 65 79 3a 6e 65 77 20 28 20 61 64 64 72 20 75 20  ey:new ( addr u 
13b0: 2d 2d 20 6f 20 29 0a 20 20 20 20 5c 47 20 63 72  -- o ).    \G cr
13c0: 65 61 74 65 20 6e 65 77 20 6b 65 79 2c 20 61 64  eate new key, ad
13d0: 64 72 20 75 20 69 73 20 74 68 65 20 70 75 62 6c  dr u is the publ
13e0: 69 63 20 6b 65 79 0a 20 20 20 20 73 61 6d 70 6c  ic key.    sampl
13f0: 65 2d 6b 65 79 20 3e 6f 20 20 6b 65 2d 73 6b 20  e-key >o  ke-sk 
1400: 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d 20 65 72  ke-end over - er
1410: 61 73 65 0a 20 20 20 20 6b 65 79 2d 65 6e 74 72  ase.    key-entr
1420: 79 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65 6e 2d  y-table @ token-
1430: 74 61 62 6c 65 20 21 0a 20 20 20 20 3e 73 74 6f  table !.    >sto
1440: 72 65 6b 65 79 20 40 20 6b 65 2d 73 74 6f 72 65  rekey @ ke-store
1450: 6b 65 79 20 21 0a 20 20 20 20 6b 65 79 2d 72 65  key !.    key-re
1460: 61 64 2d 6f 66 66 73 65 74 20 36 34 40 20 6b 65  ad-offset 64@ ke
1470: 2d 6f 66 66 73 65 74 20 36 34 21 0a 20 20 20 20  -offset 64!.    
1480: 31 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 40 20  1 import-type @ 
1490: 6c 73 68 69 66 74 20 5b 20 31 20 69 6d 70 6f 72  lshift [ 1 impor
14a0: 74 23 6e 65 77 20 6c 73 68 69 66 74 20 5d 4c 20  t#new lshift ]L 
14b0: 6f 72 20 6b 65 2d 69 6d 70 6f 72 74 73 20 21 0a  or ke-imports !.
14c0: 20 20 20 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23      keypack-all#
14d0: 20 6e 3e 36 34 20 6b 65 79 2d 72 65 61 64 2d 6f   n>64 key-read-o
14e0: 66 66 73 65 74 20 36 34 2b 21 20 6f 20 63 65 6c  ffset 64+! o cel
14f0: 6c 2d 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d  l- ke-end over -
1500: 0a 20 20 20 20 32 6f 76 65 72 20 6b 65 79 7c 20  .    2over key| 
1510: 6b 65 79 23 20 23 21 20 6f 3e 0a 20 20 20 20 63  key# #! o>.    c
1520: 75 72 72 65 6e 74 2d 6b 65 79 20 3b 0a 0a 30 20  urrent-key ;..0 
1530: 56 61 6c 75 65 20 6c 61 73 74 2d 6b 65 79 0a 0a  Value last-key..
1540: 3a 20 6b 65 79 3f 6e 65 77 20 28 20 61 64 64 72  : key?new ( addr
1550: 20 75 20 2d 2d 20 6f 20 29 0a 20 20 20 20 5c 47   u -- o ).    \G
1560: 20 43 72 65 61 74 65 20 6f 72 20 6c 6f 6f 6b 75   Create or looku
1570: 70 20 6e 65 77 20 6b 65 79 0a 20 20 20 20 32 64  p new key.    2d
1580: 75 70 20 6b 65 79 7c 20 6b 65 79 23 20 23 40 20  up key| key# #@ 
1590: 64 72 6f 70 0a 20 20 20 20 64 75 70 20 30 3d 20  drop.    dup 0= 
15a0: 49 46 20 20 64 72 6f 70 20 6b 65 79 3a 6e 65 77  IF  drop key:new
15b0: 0a 20 20 20 20 45 4c 53 45 20 20 6e 69 70 20 6e  .    ELSE  nip n
15c0: 69 70 20 63 65 6c 6c 2b 20 20 31 20 69 6d 70 6f  ip cell+  1 impo
15d0: 72 74 2d 74 79 70 65 20 40 20 6c 73 68 69 66 74  rt-type @ lshift
15e0: 20 6f 76 65 72 20 2e 6b 65 2d 69 6d 70 6f 72 74   over .ke-import
15f0: 73 20 6f 72 21 20 20 54 48 45 4e 0a 20 20 20 20  s or!  THEN.    
1600: 64 75 70 20 74 6f 20 6c 61 73 74 2d 6b 65 79 20  dup to last-key 
1610: 3b 0a 0a 5c 20 73 65 61 72 63 68 20 66 6f 72 20  ;..\ search for 
1620: 6b 65 79 73 20 2d 20 6e 6f 74 20 6f 70 74 69 6d  keys - not optim
1630: 69 7a 65 64 0a 0a 3a 20 23 73 70 6c 69 74 20 28  ized..: #split (
1640: 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 20   addr u -- addr 
1650: 75 20 6e 20 29 0a 20 20 20 20 5b 3a 20 32 64 75  u n ).    [: 2du
1660: 70 20 27 23 27 20 2d 73 63 61 6e 20 6e 69 70 20  p '#' -scan nip 
1670: 3e 72 0a 20 20 20 20 20 20 72 40 20 30 3d 20 49  >r.      r@ 0= I
1680: 46 20 20 72 64 72 6f 70 20 30 20 20 45 58 49 54  F  rdrop 0  EXIT
1690: 20 20 54 48 45 4e 0a 20 20 20 20 20 20 23 30 2e    THEN.      #0.
16a0: 20 32 6f 76 65 72 20 72 40 20 2f 73 74 72 69 6e   2over r@ /strin
16b0: 67 20 3e 6e 75 6d 62 65 72 0a 20 20 20 20 20 20  g >number.      
16c0: 30 3d 20 49 46 20 20 6e 69 70 20 64 72 6f 70 20  0= IF  nip drop 
16d0: 6e 69 70 20 72 3e 20 31 2d 20 73 77 61 70 20 20  nip r> 1- swap  
16e0: 45 4c 53 45 0a 09 20 20 72 64 72 6f 70 20 64 72  ELSE..  rdrop dr
16f0: 6f 70 20 32 64 72 6f 70 20 30 20 20 20 54 48 45  op 2drop 0   THE
1700: 4e 20 3b 5d 20 23 31 30 20 62 61 73 65 2d 65 78  N ;] #10 base-ex
1710: 65 63 75 74 65 20 3b 0a 0a 3a 20 6e 69 63 6b 2d  ecute ;..: nick-
1720: 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20  key ( addr u -- 
1730: 6f 20 2f 20 30 20 29 20 5c 20 73 65 61 72 63 68  o / 0 ) \ search
1740: 20 66 6f 72 20 6b 65 79 20 6e 69 63 6b 6e 61 6d   for key nicknam
1750: 65 0a 20 20 20 20 23 73 70 6c 69 74 20 3e 72 20  e.    #split >r 
1760: 6e 69 63 6b 23 20 23 40 20 32 64 75 70 20 64 30  nick# #@ 2dup d0
1770: 3d 20 49 46 20 20 72 64 72 6f 70 20 64 72 6f 70  = IF  rdrop drop
1780: 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20    EXIT  THEN.   
1790: 20 72 3e 20 63 65 6c 6c 73 20 73 61 66 65 2f 73   r> cells safe/s
17a0: 74 72 69 6e 67 20 30 3d 20 49 46 20 20 64 72 6f  tring 0= IF  dro
17b0: 70 20 30 20 20 45 58 49 54 20 20 54 48 45 4e 20  p 0  EXIT  THEN 
17c0: 20 40 20 3b 0a 0a 3a 20 73 65 63 72 65 74 2d 6b   @ ;..: secret-k
17d0: 65 79 73 23 20 28 20 2d 2d 20 6e 20 29 0a 20 20  eys# ( -- n ).  
17e0: 20 20 30 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c    0 key# [: cell
17f0: 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20  + $@ drop cell+ 
1800: 3e 6f 20 6b 65 2d 73 6b 20 40 20 30 3c 3e 20 2d  >o ke-sk @ 0<> -
1810: 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 3b 0a 3a 20   o> ;] #map ;.: 
1820: 73 65 63 72 65 74 2d 6b 65 79 20 28 20 6e 20 2d  secret-key ( n -
1830: 2d 20 6f 2f 30 20 29 0a 20 20 20 20 30 20 74 75  - o/0 ).    0 tu
1840: 63 6b 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b  ck key# [: cell+
1850: 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e   $@ drop cell+ >
1860: 6f 20 6b 65 2d 73 6b 20 40 20 49 46 0a 09 20 20  o ke-sk @ IF..  
1870: 32 64 75 70 20 3d 20 49 46 20 20 72 6f 74 20 64  2dup = IF  rot d
1880: 72 6f 70 20 6f 20 2d 72 6f 74 20 20 54 48 45 4e  rop o -rot  THEN
1890: 20 20 31 2b 0a 20 20 20 20 20 20 54 48 45 4e 20    1+.      THEN 
18a0: 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 32 64 72 6f   o> ;] #map 2dro
18b0: 70 20 3b 0a 3a 20 2e 23 20 28 20 6e 20 2d 2d 20  p ;.: .# ( n -- 
18c0: 29 20 3f 64 75 70 2d 49 46 20 20 27 23 27 20 65  ) ?dup-IF  '#' e
18d0: 6d 69 74 20 30 20 2e 72 20 20 54 48 45 4e 20 3b  mit 0 .r  THEN ;
18e0: 0a 3a 20 2e 6e 69 63 6b 2d 62 61 73 65 20 28 20  .: .nick-base ( 
18f0: 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 6b  o:key -- ).    k
1900: 65 2d 6e 69 63 6b 20 24 2e 20 20 6b 65 2d 6e 69  e-nick $.  ke-ni
1910: 63 6b 23 20 40 20 2e 23 20 3b 0a 3a 20 2e 70 65  ck# @ .# ;.: .pe
1920: 74 2d 62 61 73 65 20 28 20 6f 3a 6b 65 79 20 2d  t-base ( o:key -
1930: 2d 20 29 0a 20 20 20 20 30 20 6b 65 2d 70 65 74  - ).    0 ke-pet
1940: 73 5b 5d 20 5b 3a 20 73 70 61 63 65 20 74 79 70  s[] [: space typ
1950: 65 0a 20 20 20 20 20 20 64 75 70 20 6b 65 2d 70  e.      dup ke-p
1960: 65 74 73 23 20 24 5b 5d 20 40 20 2e 23 20 20 31  ets# $[] @ .#  1
1970: 2b 20 3b 5d 20 24 5b 5d 6d 61 70 20 64 72 6f 70  + ;] $[]map drop
1980: 20 3b 0a 3a 20 2e 70 65 74 30 2d 62 61 73 65 20   ;.: .pet0-base 
1990: 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20  ( o:key -- ).   
19a0: 20 6b 65 2d 70 65 74 73 5b 5d 20 24 5b 5d 23 20   ke-pets[] $[]# 
19b0: 49 46 20 20 30 20 6b 65 2d 70 65 74 73 5b 5d 20  IF  0 ke-pets[] 
19c0: 24 5b 5d 40 20 74 79 70 65 20 30 20 6b 65 2d 70  $[]@ type 0 ke-p
19d0: 65 74 73 23 20 24 5b 5d 20 40 20 2e 23 0a 20 20  ets# $[] @ .#.  
19e0: 20 20 45 4c 53 45 20 20 2e 6e 69 63 6b 2d 62 61    ELSE  .nick-ba
19f0: 73 65 20 20 54 48 45 4e 20 3b 0a 3a 20 2e 72 65  se  THEN ;.: .re
1a00: 61 6c 2d 6e 69 63 6b 20 28 20 6f 3a 6b 65 79 20  al-nick ( o:key 
1a10: 2d 2d 20 29 20 20 20 6b 65 2d 69 6d 70 6f 72 74  -- )   ke-import
1a20: 73 20 40 20 3e 69 6d 2d 63 6f 6c 6f 72 20 2e 6e  s @ >im-color .n
1a30: 69 63 6b 2d 62 61 73 65 20 3c 64 65 66 61 75 6c  ick-base <defaul
1a40: 74 3e 20 3b 0a 3a 20 2e 6e 69 63 6b 20 28 20 6f  t> ;.: .nick ( o
1a50: 3a 6b 65 79 20 2d 2d 20 29 20 20 20 6b 65 2d 69  :key -- )   ke-i
1a60: 6d 70 6f 72 74 73 20 40 20 3e 69 6d 2d 63 6f 6c  mports @ >im-col
1a70: 6f 72 20 2e 70 65 74 30 2d 62 61 73 65 20 3c 64  or .pet0-base <d
1a80: 65 66 61 75 6c 74 3e 20 3b 0a 3a 20 2e 6e 69 63  efault> ;.: .nic
1a90: 6b 2b 70 65 74 20 28 20 6f 3a 6b 65 79 20 2d 2d  k+pet ( o:key --
1aa0: 20 29 0a 20 20 20 20 6b 65 2d 69 6d 70 6f 72 74   ).    ke-import
1ab0: 73 20 40 20 3e 69 6d 2d 63 6f 6c 6f 72 20 2e 6e  s @ >im-color .n
1ac0: 69 63 6b 2d 62 61 73 65 20 2e 70 65 74 2d 62 61  ick-base .pet-ba
1ad0: 73 65 20 3c 64 65 66 61 75 6c 74 3e 20 3b 0a 0a  se <default> ;..
1ae0: 3a 20 6e 69 63 6b 3e 70 6b 20 28 20 6e 69 63 6b  : nick>pk ( nick
1af0: 20 75 20 2d 2d 20 70 6b 20 75 20 29 0a 20 20 20   u -- pk u ).   
1b00: 20 6e 69 63 6b 2d 6b 65 79 20 3f 64 75 70 2d 49   nick-key ?dup-I
1b10: 46 20 2e 6b 65 2d 70 6b 20 24 40 20 45 4c 53 45  F .ke-pk $@ ELSE
1b20: 20 30 20 30 20 54 48 45 4e 20 3b 0a 3a 20 68 6f   0 0 THEN ;.: ho
1b30: 73 74 2e 6e 69 63 6b 3e 70 6b 20 28 20 61 64 64  st.nick>pk ( add
1b40: 72 20 75 20 2d 2d 20 70 6b 20 75 27 20 29 0a 20  r u -- pk u' ). 
1b50: 20 20 20 27 2e 27 20 24 73 70 6c 69 74 20 64 75     '.' $split du
1b60: 70 20 30 3d 20 49 46 20 20 32 73 77 61 70 20 20  p 0= IF  2swap  
1b70: 54 48 45 4e 20 5b 3a 20 6e 69 63 6b 3e 70 6b 20  THEN [: nick>pk 
1b80: 74 79 70 65 20 74 79 70 65 20 3b 5d 20 24 74 6d  type type ;] $tm
1b90: 70 20 3b 0a 0a 3a 20 6b 65 79 2d 65 78 69 73 74  p ;..: key-exist
1ba0: 3f 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6f 2f  ? ( addr u -- o/
1bb0: 30 20 29 0a 20 20 20 20 6b 65 79 23 20 23 40 20  0 ).    key# #@ 
1bc0: 49 46 20 20 63 65 6c 6c 2b 20 20 54 48 45 4e 20  IF  cell+  THEN 
1bd0: 3b 20 0a 0a 5c 20 70 65 72 6d 69 73 73 69 6f 6e  ; ..\ permission
1be0: 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 0a 0a 32   modification..2
1bf0: 36 20 62 75 66 66 65 72 3a 20 70 65 72 6d 2d 63  6 buffer: perm-c
1c00: 68 61 72 73 0a 30 20 70 65 72 6d 24 20 63 6f 75  hars.0 perm$ cou
1c10: 6e 74 20 62 6f 75 6e 64 73 20 5b 44 4f 5d 20 64  nt bounds [DO] d
1c20: 75 70 20 5b 49 5d 20 63 40 20 27 61 27 20 2d 20  up [I] c@ 'a' - 
1c30: 70 65 72 6d 2d 63 68 61 72 73 20 2b 20 63 21 20  perm-chars + c! 
1c40: 31 2b 20 5b 4c 4f 4f 50 5d 20 64 72 6f 70 0a 0a  1+ [LOOP] drop..
1c50: 3a 20 2e 70 65 72 6d 20 28 20 70 65 72 6d 69 73  : .perm ( permis
1c60: 73 69 6f 6e 20 2d 2d 20 29 20 20 31 20 70 65 72  sion -- )  1 per
1c70: 6d 24 20 63 6f 75 6e 74 20 62 6f 75 6e 64 73 20  m$ count bounds 
1c80: 44 4f 0a 09 32 64 75 70 20 61 6e 64 20 30 3c 3e  DO..2dup and 0<>
1c90: 20 49 20 63 40 20 27 2d 27 20 72 6f 74 20 73 65   I c@ '-' rot se
1ca0: 6c 65 63 74 20 65 6d 69 74 20 32 2a 0a 20 20 20  lect emit 2*.   
1cb0: 20 4c 4f 4f 50 20 20 32 64 72 6f 70 20 3b 0a 3a   LOOP  2drop ;.:
1cc0: 20 70 65 72 6d 61 6e 64 20 28 20 70 65 72 6d 61   permand ( perma
1cd0: 6e 64 20 70 65 72 6d 6f 72 20 6e 65 77 20 2d 2d  nd permor new --
1ce0: 20 70 65 72 6d 61 6e 64 27 20 70 65 72 6d 6f 72   permand' permor
1cf0: 20 29 0a 20 20 20 20 69 6e 76 65 72 74 20 74 75   ).    invert tu
1d00: 63 6b 20 61 6e 64 20 3e 72 20 61 6e 64 20 72 3e  ck and >r and r>
1d10: 20 3b 0a 3a 20 3e 70 65 72 6d 2d 6d 6f 64 20 28   ;.: >perm-mod (
1d20: 20 70 65 72 6d 61 6e 64 20 70 65 72 6d 6f 72 20   permand permor 
1d30: 2d 2d 20 70 65 72 6d 61 6e 64 27 20 70 65 72 6d  -- permand' perm
1d40: 6f 72 20 29 0a 20 20 20 20 73 77 61 70 20 64 75  or ).    swap du
1d50: 70 20 30 3d 20 49 46 20 20 64 72 6f 70 20 64 75  p 0= IF  drop du
1d60: 70 20 69 6e 76 65 72 74 20 20 54 48 45 4e 20 73  p invert  THEN s
1d70: 77 61 70 20 3b 0a 3a 20 3e 70 65 72 6d 20 28 20  wap ;.: >perm ( 
1d80: 61 64 64 72 20 75 20 2d 2d 20 70 65 72 6d 61 6e  addr u -- perman
1d90: 64 20 70 65 72 6d 6f 72 20 29 0a 20 20 20 20 5c  d permor ).    \
1da0: 47 20 70 61 72 73 65 20 70 65 72 6d 69 73 73 69  G parse permissi
1db0: 6f 6e 73 3a 20 2b 20 61 64 64 73 2c 20 2d 20 72  ons: + adds, - r
1dc0: 65 6d 6f 76 65 73 20 70 65 72 6d 69 73 73 69 6f  emoves permissio
1dd0: 6e 73 2c 0a 20 20 20 20 5c 47 20 6e 6f 20 6d 6f  ns,.    \G no mo
1de0: 64 69 66 69 65 72 20 73 65 74 73 20 70 65 72 6d  difier sets perm
1df0: 69 73 73 6f 6e 73 2e 0a 20 20 20 20 30 20 30 20  issons..    0 0 
1e00: 5b 27 5d 20 6f 72 20 7b 20 78 74 20 7d 0a 20 20  ['] or { xt }.  
1e10: 20 20 32 73 77 61 70 20 62 6f 75 6e 64 73 20 3f    2swap bounds ?
1e20: 44 4f 0a 09 49 20 63 40 20 63 61 73 65 0a 09 20  DO..I c@ case.. 
1e30: 20 20 20 27 2b 27 20 6f 66 20 20 3e 70 65 72 6d     '+' of  >perm
1e40: 2d 6d 6f 64 20 5b 27 5d 20 6f 72 20 74 6f 20 78  -mod ['] or to x
1e50: 74 20 65 6e 64 6f 66 0a 09 20 20 20 20 27 2d 27  t endof..    '-'
1e60: 20 6f 66 20 20 3e 70 65 72 6d 2d 6d 6f 64 20 5b   of  >perm-mod [
1e70: 27 5d 20 70 65 72 6d 61 6e 64 20 74 6f 20 78 74  '] permand to xt
1e80: 20 20 65 6e 64 6f 66 0a 09 20 20 20 20 27 3d 27    endof..    '='
1e90: 20 6f 66 20 20 32 64 72 6f 70 20 70 65 72 6d 25   of  2drop perm%
1ea0: 64 65 66 61 75 6c 74 20 64 75 70 20 5b 27 5d 20  default dup ['] 
1eb0: 6f 72 20 74 6f 20 78 74 20 20 65 6e 64 6f 66 0a  or to xt  endof.
1ec0: 09 20 20 20 20 27 61 27 20 2d 20 64 75 70 20 27  .    'a' - dup '
1ed0: 7a 27 20 75 3c 3d 20 20 49 46 0a 09 09 70 65 72  z' u<=  IF...per
1ee0: 6d 2d 63 68 61 72 73 20 2b 20 63 40 20 31 20 73  m-chars + c@ 1 s
1ef0: 77 61 70 20 6c 73 68 69 66 74 20 78 74 20 65 78  wap lshift xt ex
1f00: 65 63 75 74 65 0a 09 09 30 20 28 20 64 75 6d 6d  ecute...0 ( dumm
1f10: 79 20 66 6f 72 20 65 6e 64 63 61 73 65 20 29 0a  y for endcase ).
1f20: 09 20 20 20 20 54 48 45 4e 20 20 65 6e 64 63 61  .    THEN  endca
1f30: 73 65 0a 20 20 20 20 4c 4f 4f 50 20 3b 0a 3a 20  se.    LOOP ;.: 
1f40: 2e 70 65 72 6d 61 6e 64 6f 72 20 28 20 70 65 72  .permandor ( per
1f50: 6d 61 6e 64 20 70 65 72 6d 6f 72 20 2d 2d 20 29  mand permor -- )
1f60: 0a 20 20 20 20 30 20 7b 20 2b 2d 20 7d 0a 20 20  .    0 { +- }.  
1f70: 20 20 31 20 70 65 72 6d 24 20 63 6f 75 6e 74 20    1 perm$ count 
1f80: 62 6f 75 6e 64 73 20 44 4f 20 20 3e 72 0a 09 6f  bounds DO  >r..o
1f90: 76 65 72 20 72 40 20 61 6e 64 20 30 3d 20 49 46  ver r@ and 0= IF
1fa0: 20 20 27 2d 27 20 64 75 70 20 2b 2d 20 3c 3e 20    '-' dup +- <> 
1fb0: 49 46 20 20 64 75 70 20 74 6f 20 2b 2d 20 65 6d  IF  dup to +- em
1fc0: 69 74 0a 09 20 20 20 20 45 4c 53 45 20 20 64 72  it..    ELSE  dr
1fd0: 6f 70 20 20 54 48 45 4e 20 72 3e 20 20 49 20 63  op  THEN r>  I c
1fe0: 40 20 65 6d 69 74 20 20 3e 72 20 54 48 45 4e 0a  @ emit  >r THEN.
1ff0: 09 64 75 70 20 20 72 40 20 61 6e 64 20 20 20 20  .dup  r@ and    
2000: 49 46 20 20 27 2b 27 20 64 75 70 20 2b 2d 20 3c  IF  '+' dup +- <
2010: 3e 20 49 46 20 20 64 75 70 20 74 6f 20 2b 2d 20  > IF  dup to +- 
2020: 65 6d 69 74 0a 09 20 20 20 20 45 4c 53 45 20 20  emit..    ELSE  
2030: 64 72 6f 70 20 20 54 48 45 4e 20 72 3e 20 20 49  drop  THEN r>  I
2040: 20 63 40 20 65 6d 69 74 20 20 3e 72 20 54 48 45   c@ emit  >r THE
2050: 4e 0a 09 72 3e 20 32 2a 0a 20 20 20 20 4c 4f 4f  N..r> 2*.    LOO
2060: 50 20 20 64 72 6f 70 20 32 64 72 6f 70 20 3b 0a  P  drop 2drop ;.
2070: 0a 5c 20 72 65 61 64 20 69 6e 20 70 65 72 6d 69  .\ read in permi
2080: 73 73 69 6f 6e 20 67 72 6f 75 70 73 2c 20 67 72  ssion groups, gr
2090: 6f 75 70 73 20 69 73 20 69 6e 20 74 68 65 20 2e  oups is in the .
20a0: 6e 65 74 32 6f 20 64 69 72 65 63 74 6f 72 79 0a  net2o directory.
20b0: 0a 3a 20 3e 67 72 6f 75 70 2d 69 64 20 28 20 61  .: >group-id ( a
20c0: 64 64 72 20 75 20 2d 2d 20 69 64 2f 2d 31 20 29  ddr u -- id/-1 )
20d0: 0a 20 20 20 20 2d 31 20 30 20 67 72 6f 75 70 73  .    -1 0 groups
20e0: 5b 5d 20 5b 3a 20 32 73 77 61 70 20 32 3e 72 20  [] [: 2swap 2>r 
20f0: 32 20 63 65 6c 6c 73 20 2f 73 74 72 69 6e 67 0a  2 cells /string.
2100: 20 20 20 20 20 20 32 6f 76 65 72 20 73 74 72 69        2over stri
2110: 6e 67 2d 70 72 65 66 69 78 3f 20 49 46 20 20 32  ng-prefix? IF  2
2120: 72 3e 20 6e 69 70 20 64 75 70 0a 20 20 20 20 20  r> nip dup.     
2130: 20 45 4c 53 45 20 20 32 72 3e 20 20 54 48 45 4e   ELSE  2r>  THEN
2140: 20 20 31 2b 20 3b 5d 20 24 5b 5d 6d 61 70 0a 20    1+ ;] $[]map. 
2150: 20 20 20 32 6e 69 70 20 64 72 6f 70 20 3b 0a 0a     2nip drop ;..
2160: 3a 20 3e 67 72 6f 75 70 73 20 28 20 61 64 64 72  : >groups ( addr
2170: 20 75 20 70 61 6e 64 20 70 6f 72 20 2d 2d 20 29   u pand por -- )
2180: 0a 20 20 20 20 73 22 20 22 20 67 72 6f 75 70 73  .    s" " groups
2190: 5b 5d 20 24 2b 5b 5d 21 0a 20 20 20 20 5b 3a 20  [] $+[]!.    [: 
21a0: 7b 20 64 5e 20 70 61 6e 64 6f 72 20 7d 20 70 61  { d^ pandor } pa
21b0: 6e 64 6f 72 20 32 20 63 65 6c 6c 73 20 74 79 70  ndor 2 cells typ
21c0: 65 20 20 74 79 70 65 20 3b 5d 0a 20 20 20 20 67  e  type ;].    g
21d0: 72 6f 75 70 73 5b 5d 20 64 75 70 20 24 5b 5d 23  roups[] dup $[]#
21e0: 20 31 2d 20 73 77 61 70 20 24 5b 5d 20 24 65 78   1- swap $[] $ex
21f0: 65 63 20 3b 0a 0a 3a 20 69 6e 69 74 2d 67 72 6f  ec ;..: init-gro
2200: 75 70 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 22  ups ( -- ).    "
2210: 6d 79 73 65 6c 66 22 20 20 70 65 72 6d 25 6d 79  myself"  perm%my
2220: 73 65 6c 66 20 20 64 75 70 20 3e 67 72 6f 75 70  self  dup >group
2230: 73 0a 20 20 20 20 22 70 65 65 72 22 20 20 20 20  s.    "peer"    
2240: 70 65 72 6d 25 64 65 66 61 75 6c 74 20 64 75 70  perm%default dup
2250: 20 3e 67 72 6f 75 70 73 0a 20 20 20 20 22 64 68   >groups.    "dh
2260: 74 22 20 20 20 20 20 70 65 72 6d 25 64 68 74 72  t"     perm%dhtr
2270: 6f 6f 74 20 64 75 70 20 3e 67 72 6f 75 70 73 0a  oot dup >groups.
2280: 20 20 20 20 22 75 6e 6b 6e 6f 77 6e 22 20 70 65      "unknown" pe
2290: 72 6d 25 75 6e 6b 6e 6f 77 6e 20 64 75 70 20 3e  rm%unknown dup >
22a0: 67 72 6f 75 70 73 0a 20 20 20 20 22 62 6c 6f 63  groups.    "bloc
22b0: 6b 65 64 22 20 70 65 72 6d 25 62 6c 6f 63 6b 65  ked" perm%blocke
22c0: 64 20 70 65 72 6d 25 69 6e 64 69 72 65 63 74 20  d perm%indirect 
22d0: 6f 72 20 64 75 70 20 3e 67 72 6f 75 70 73 20 3b  or dup >groups ;
22e0: 0a 0a 3a 20 2e 67 72 6f 75 70 73 20 28 20 2d 2d  ..: .groups ( --
22f0: 20 29 0a 20 20 20 20 67 72 6f 75 70 73 5b 5d 20   ).    groups[] 
2300: 5b 3a 20 32 64 75 70 20 32 20 63 65 6c 6c 73 20  [: 2dup 2 cells 
2310: 2f 73 74 72 69 6e 67 20 74 79 70 65 20 73 70 61  /string type spa
2320: 63 65 0a 20 20 20 20 20 20 64 72 6f 70 20 32 40  ce.      drop 2@
2330: 20 2e 70 65 72 6d 61 6e 64 6f 72 20 63 72 20 3b   .permandor cr ;
2340: 5d 20 24 5b 5d 6d 61 70 20 3b 0a 0a 3a 20 2e 69  ] $[]map ;..: .i
2350: 6e 2d 67 72 6f 75 70 73 20 28 20 61 64 64 72 20  n-groups ( addr 
2360: 75 20 2d 2d 20 29 0a 20 20 20 20 62 6f 75 6e 64  u -- ).    bound
2370: 73 20 3f 44 4f 0a 09 49 20 70 40 2b 20 49 20 2d  s ?DO..I p@+ I -
2380: 20 3e 72 20 36 34 3e 6e 20 67 72 6f 75 70 73 5b   >r 64>n groups[
2390: 5d 20 24 5b 5d 40 20 32 20 63 65 6c 6c 73 20 2f  ] $[]@ 2 cells /
23a0: 73 74 72 69 6e 67 20 73 70 61 63 65 20 74 79 70  string space typ
23b0: 65 0a 20 20 20 20 72 3e 20 2b 4c 4f 4f 50 20 3b  e.    r> +LOOP ;
23c0: 0a 0a 3a 20 77 72 69 74 65 2d 67 72 6f 75 70 73  ..: write-groups
23d0: 20 28 20 2d 2d 20 29 0a 20 20 20 20 5b 3a 20 2e   ( -- ).    [: .
23e0: 22 20 67 72 6f 75 70 73 2b 22 20 67 65 74 70 69  " groups+" getpi
23f0: 64 20 30 20 2e 72 20 3b 5d 20 24 74 6d 70 20 2e  d 0 .r ;] $tmp .
2400: 6e 65 74 32 6f 2f 20 32 64 75 70 20 77 2f 6f 20  net2o/ 2dup w/o 
2410: 63 72 65 61 74 65 2d 66 69 6c 65 20 74 68 72 6f  create-file thro
2420: 77 20 3e 72 0a 20 20 20 20 5b 27 5d 20 2e 67 72  w >r.    ['] .gr
2430: 6f 75 70 73 20 72 40 20 6f 75 74 66 69 6c 65 2d  oups r@ outfile-
2440: 65 78 65 63 75 74 65 0a 20 20 20 20 72 3e 20 63  execute.    r> c
2450: 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 20  lose-file throw 
2460: 27 2b 27 20 2d 73 63 61 6e 20 31 2d 20 3e 62 61  '+' -scan 1- >ba
2470: 63 6b 75 70 20 3b 0a 0a 3a 20 67 72 6f 75 70 2d  ckup ;..: group-
2480: 6c 69 6e 65 20 28 20 2d 2d 20 29 0a 20 20 20 20  line ( -- ).    
2490: 70 61 72 73 65 2d 6e 61 6d 65 20 70 61 72 73 65  parse-name parse
24a0: 2d 6e 61 6d 65 20 3e 70 65 72 6d 20 3e 67 72 6f  -name >perm >gro
24b0: 75 70 73 20 3b 0a 0a 3a 20 72 65 61 64 2d 67 72  ups ;..: read-gr
24c0: 6f 75 70 73 2d 6c 6f 6f 70 20 28 20 2d 2d 20 29  oups-loop ( -- )
24d0: 0a 20 20 20 20 42 45 47 49 4e 20 20 72 65 66 69  .    BEGIN  refi
24e0: 6c 6c 20 20 57 48 49 4c 45 20 20 67 72 6f 75 70  ll  WHILE  group
24f0: 2d 6c 69 6e 65 20 20 52 45 50 45 41 54 20 3b 0a  -line  REPEAT ;.
2500: 0a 3a 20 72 65 61 64 2d 67 72 6f 75 70 73 20 28  .: read-groups (
2510: 20 2d 2d 20 29 0a 20 20 20 20 22 67 72 6f 75 70   -- ).    "group
2520: 73 22 20 2e 6e 65 74 32 6f 2f 20 32 64 75 70 20  s" .net2o/ 2dup 
2530: 66 69 6c 65 2d 73 74 61 74 75 73 20 6e 69 70 20  file-status nip 
2540: 6e 6f 2d 66 69 6c 65 23 20 3d 20 49 46 0a 09 69  no-file# = IF..i
2550: 6e 69 74 2d 67 72 6f 75 70 73 20 77 72 69 74 65  nit-groups write
2560: 2d 67 72 6f 75 70 73 20 32 64 72 6f 70 20 20 45  -groups 2drop  E
2570: 58 49 54 0a 20 20 20 20 54 48 45 4e 20 20 3e 69  XIT.    THEN  >i
2580: 6e 63 6c 75 64 65 64 20 74 68 72 6f 77 0a 20 20  ncluded throw.  
2590: 20 20 5b 27 5d 20 72 65 61 64 2d 67 72 6f 75 70    ['] read-group
25a0: 73 2d 6c 6f 6f 70 20 65 78 65 63 75 74 65 2d 70  s-loop execute-p
25b0: 61 72 73 69 6e 67 2d 6e 61 6d 65 64 2d 66 69 6c  arsing-named-fil
25c0: 65 20 3b 0a 0a 3a 20 67 72 6f 75 70 73 3e 6d 61  e ;..: groups>ma
25d0: 73 6b 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6d  sk ( addr u -- m
25e0: 61 73 6b 20 29 0a 20 20 20 20 30 20 2d 72 6f 74  ask ).    0 -rot
25f0: 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 49 20 70   bounds ?DO..I p
2600: 40 2b 20 49 20 2d 20 3e 72 0a 09 36 34 3e 6e 20  @+ I - >r..64>n 
2610: 64 75 70 20 67 72 6f 75 70 73 5b 5d 20 24 5b 5d  dup groups[] $[]
2620: 23 20 75 3e 3d 20 21 21 6e 6f 2d 67 72 6f 75 70  # u>= !!no-group
2630: 21 21 0a 09 67 72 6f 75 70 73 5b 5d 20 24 5b 5d  !!..groups[] $[]
2640: 40 20 64 72 6f 70 20 32 40 20 3e 72 20 61 6e 64  @ drop 2@ >r and
2650: 20 72 3e 20 6f 72 0a 20 20 20 20 72 3e 20 2b 4c   r> or.    r> +L
2660: 4f 4f 50 20 3b 0a 0a 3a 20 3f 3e 67 72 6f 75 70  OOP ;..: ?>group
2670: 73 20 28 20 6d 61 73 6b 20 2d 2d 20 6d 61 73 6b  s ( mask -- mask
2680: 27 20 29 0a 20 20 20 20 6b 65 2d 67 72 6f 75 70  ' ).    ke-group
2690: 73 20 24 40 6c 65 6e 20 30 3d 20 49 46 0a 09 67  s $@len 0= IF..g
26a0: 72 6f 75 70 73 5b 5d 20 24 5b 5d 23 20 30 20 44  roups[] $[]# 0 D
26b0: 4f 0a 09 20 20 20 20 64 75 70 20 49 20 67 72 6f  O..    dup I gro
26c0: 75 70 73 5b 5d 20 24 5b 5d 40 20 64 72 6f 70 20  ups[] $[]@ drop 
26d0: 40 0a 09 20 20 20 20 6f 72 20 6f 76 65 72 20 3d  @..    or over =
26e0: 20 49 46 0a 09 09 49 20 6b 65 2d 67 72 6f 75 70   IF...I ke-group
26f0: 73 20 63 24 2b 21 0a 09 09 49 20 67 72 6f 75 70  s c$+!...I group
2700: 73 5b 5d 20 24 5b 5d 40 20 64 72 6f 70 20 63 65  s[] $[]@ drop ce
2710: 6c 6c 2b 20 40 20 69 6e 76 65 72 74 20 61 6e 64  ll+ @ invert and
2720: 0a 09 20 20 20 20 54 48 45 4e 0a 09 4c 4f 4f 50  ..    THEN..LOOP
2730: 0a 20 20 20 20 54 48 45 4e 20 20 64 72 6f 70 20  .    THEN  drop 
2740: 3b 0a 0a 3a 6e 6f 6e 61 6d 65 20 64 65 66 65 72  ;..:noname defer
2750: 73 20 27 63 6f 6c 64 20 20 67 72 6f 75 70 73 5b  s 'cold  groups[
2760: 5d 20 6f 66 66 20 72 65 61 64 2d 67 72 6f 75 70  ] off read-group
2770: 73 20 3b 20 69 73 20 27 63 6f 6c 64 0a 0a 5c 20  s ; is 'cold..\ 
2780: 6b 65 79 20 64 69 73 70 6c 61 79 0a 0a 5b 49 46  key display..[IF
2790: 55 4e 44 45 46 5d 20 6d 61 67 65 6e 74 61 20 20  UNDEF] magenta  
27a0: 62 72 6f 77 6e 20 63 6f 6e 73 74 61 6e 74 20 6d  brown constant m
27b0: 61 67 65 6e 74 61 20 5b 54 48 45 4e 5d 0a 5b 49  agenta [THEN].[I
27c0: 46 44 45 46 5d 20 67 6c 2d 74 79 70 65 20 3a 20  FDEF] gl-type : 
27d0: 62 67 7c 20 3e 62 67 20 6f 72 20 3b 20 5b 45 4c  bg| >bg or ; [EL
27e0: 53 45 5d 20 3a 20 62 67 7c 20 64 72 6f 70 20 3b  SE] : bg| drop ;
27f0: 20 5b 54 48 45 4e 5d 0a 0a 43 72 65 61 74 65 20   [THEN]..Create 
2800: 38 35 63 6f 6c 6f 72 73 2d 62 77 0a 30 20 2c 20  85colors-bw.0 , 
2810: 69 6e 76 65 72 73 20 2c 0a 69 6e 76 65 72 73 20  invers ,.invers 
2820: 2c 20 30 20 2c 0a 30 20 2c 20 69 6e 76 65 72 73  , 0 ,.0 , invers
2830: 20 2c 0a 69 6e 76 65 72 73 20 2c 20 30 20 2c 0a   ,.invers , 0 ,.
2840: 43 72 65 61 74 65 20 38 35 63 6f 6c 6f 72 73 2d  Create 85colors-
2850: 63 6c 0a 79 65 6c 6c 6f 77 20 3e 66 67 20 62 6c  cl.yellow >fg bl
2860: 75 65 20 3e 62 67 20 6f 72 20 62 6f 6c 64 20 6f  ue >bg or bold o
2870: 72 20 2c 20 72 65 64 20 3e 66 67 20 77 68 69 74  r , red >fg whit
2880: 65 20 62 67 7c 20 2c 0a 62 6c 61 63 6b 20 3e 66  e bg| ,.black >f
2890: 67 20 63 79 61 6e 20 62 67 7c 20 2c 20 67 72 65  g cyan bg| , gre
28a0: 65 6e 20 3e 66 67 20 62 6c 61 63 6b 20 3e 62 67  en >fg black >bg
28b0: 20 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 0a 77 68   or bold or ,.wh
28c0: 69 74 65 20 3e 66 67 20 62 6c 61 63 6b 20 3e 62  ite >fg black >b
28d0: 67 20 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 20 6d  g or bold or , m
28e0: 61 67 65 6e 74 61 20 3e 66 67 20 79 65 6c 6c 6f  agenta >fg yello
28f0: 77 20 62 67 7c 20 2c 0a 62 6c 75 65 20 3e 66 67  w bg| ,.blue >fg
2900: 20 79 65 6c 6c 6f 77 20 62 67 7c 20 2c 20 63 79   yellow bg| , cy
2910: 61 6e 20 3e 66 67 20 72 65 64 20 3e 62 67 20 6f  an >fg red >bg o
2920: 72 20 62 6f 6c 64 20 6f 72 20 2c 0a 0a 5b 49 46  r bold or ,..[IF
2930: 44 45 46 5d 20 67 6c 2d 74 79 70 65 20 38 35 63  DEF] gl-type 85c
2940: 6f 6c 6f 72 73 2d 63 6c 20 5b 45 4c 53 45 5d 20  olors-cl [ELSE] 
2950: 38 35 63 6f 6c 6f 72 73 2d 62 77 20 5b 54 48 45  85colors-bw [THE
2960: 4e 5d 20 56 61 6c 75 65 20 38 35 63 6f 6c 6f 72  N] Value 85color
2970: 73 0a 0a 3a 20 2e 73 74 72 69 70 65 38 35 20 28  s..: .stripe85 (
2980: 20 61 64 64 72 20 75 20 2d 2d 20 29 20 20 30 20   addr u -- )  0 
2990: 2d 72 6f 74 20 62 6f 75 6e 64 73 20 3f 44 4f 0a  -rot bounds ?DO.
29a0: 09 64 75 70 20 63 65 6c 6c 73 20 38 35 63 6f 6c  .dup cells 85col
29b0: 6f 72 73 20 2b 20 40 20 61 74 74 72 21 20 31 2b  ors + @ attr! 1+
29c0: 0a 09 49 20 34 20 38 35 74 79 70 65 20 20 64 75  ..I 4 85type  du
29d0: 70 20 63 65 6c 6c 73 20 38 35 63 6f 6c 6f 72 73  p cells 85colors
29e0: 20 2b 20 40 20 61 74 74 72 21 20 31 2b 0a 20 20   + @ attr! 1+.  
29f0: 20 20 49 20 34 20 2b 20 34 20 38 35 74 79 70 65    I 4 + 4 85type
2a00: 20 3c 64 65 66 61 75 6c 74 3e 20 63 72 20 38 20   <default> cr 8 
2a10: 2b 4c 4f 4f 50 20 20 64 72 6f 70 20 3b 0a 3a 20  +LOOP  drop ;.: 
2a20: 2e 69 6d 70 6f 72 74 38 35 20 28 20 61 64 64 72  .import85 ( addr
2a30: 20 75 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d 69   u -- ).    ke-i
2a40: 6d 70 6f 72 74 73 20 40 20 3e 69 6d 2d 63 6f 6c  mports @ >im-col
2a50: 6f 72 20 38 35 74 79 70 65 20 3c 64 65 66 61 75  or 85type <defau
2a60: 6c 74 3e 20 3b 0a 3a 20 2e 72 73 6b 20 28 20 6e  lt> ;.: .rsk ( n
2a70: 69 63 6b 20 75 20 2d 2d 20 29 0a 20 20 20 20 73  ick u -- ).    s
2a80: 6b 72 65 76 20 24 32 30 20 2e 73 74 72 69 70 65  krev $20 .stripe
2a90: 38 35 20 73 70 61 63 65 20 74 79 70 65 20 2e 22  85 space type ."
2aa0: 20 20 28 6b 65 65 70 20 6f 66 66 6c 69 6e 65 20    (keep offline 
2ab0: 63 6f 70 79 21 29 22 20 63 72 20 3b 0a 3a 20 2e  copy!)" cr ;.: .
2ac0: 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20  key ( addr u -- 
2ad0: 29 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a  ) drop cell+ >o.
2ae0: 20 20 20 20 2e 22 20 6e 69 63 6b 3a 20 20 20 22      ." nick:   "
2af0: 20 2e 6e 69 63 6b 20 63 72 0a 20 20 20 20 2e 22   .nick cr.    ."
2b00: 20 70 75 62 6b 65 79 3a 20 22 20 6b 65 2d 70 6b   pubkey: " ke-pk
2b10: 20 24 40 20 38 35 74 79 70 65 20 63 72 0a 20 20   $@ 85type cr.  
2b20: 20 20 6b 65 2d 73 6b 20 40 20 49 46 0a 09 2e 22    ke-sk @ IF..."
2b30: 20 73 65 63 6b 65 79 3a 20 22 20 6b 65 2d 73 6b   seckey: " ke-sk
2b40: 20 73 65 63 40 20 2e 62 6c 61 63 6b 38 35 20 2e   sec@ .black85 .
2b50: 22 20 20 28 6b 65 65 70 20 73 65 63 72 65 74 21  "  (keep secret!
2b60: 29 22 20 63 72 20 20 54 48 45 4e 0a 20 20 20 20  )" cr  THEN.    
2b70: 2e 22 20 76 61 6c 69 64 3a 20 20 22 20 6b 65 2d  ." valid:  " ke-
2b80: 73 65 6c 66 73 69 67 20 24 40 20 2e 73 69 67 64  selfsig $@ .sigd
2b90: 61 74 65 73 20 63 72 0a 20 20 20 20 2e 22 20 67  ates cr.    ." g
2ba0: 72 6f 75 70 73 3a 20 22 20 6b 65 2d 67 72 6f 75  roups: " ke-grou
2bb0: 70 73 20 24 40 20 2e 69 6e 2d 67 72 6f 75 70 73  ps $@ .in-groups
2bc0: 20 63 72 0a 20 20 20 20 2e 22 20 70 65 72 6d 3a   cr.    ." perm:
2bd0: 20 20 20 22 20 6b 65 2d 6d 61 73 6b 20 40 20 2e     " ke-mask @ .
2be0: 70 65 72 6d 20 63 72 0a 20 20 20 20 6f 3e 20 3b  perm cr.    o> ;
2bf0: 0a 3a 20 2e 6b 65 79 2d 72 65 73 74 20 28 20 6f  .: .key-rest ( o
2c00: 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a  :key -- o:key ).
2c10: 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 6b 65 79      ke-pk $@ key
2c20: 7c 20 2e 69 6d 70 6f 72 74 38 35 0a 20 20 20 20  | .import85.    
2c30: 6b 65 2d 73 65 6c 66 73 69 67 20 24 40 20 73 70  ke-selfsig $@ sp
2c40: 61 63 65 20 2e 73 69 67 64 61 74 65 73 0a 20 20  ace .sigdates.  
2c50: 20 20 6b 65 2d 67 72 6f 75 70 73 20 24 40 20 32    ke-groups $@ 2
2c60: 64 75 70 20 2e 69 6e 2d 67 72 6f 75 70 73 20 67  dup .in-groups g
2c70: 72 6f 75 70 73 3e 6d 61 73 6b 20 69 6e 76 65 72  roups>mask inver
2c80: 74 0a 20 20 20 20 73 70 61 63 65 20 6b 65 2d 6d  t.    space ke-m
2c90: 61 73 6b 20 40 20 61 6e 64 20 2d 31 20 73 77 61  ask @ and -1 swa
2ca0: 70 20 2e 70 65 72 6d 61 6e 64 6f 72 0a 20 20 20  p .permandor.   
2cb0: 20 23 74 61 62 20 65 6d 69 74 20 6b 65 2d 69 6d   #tab emit ke-im
2cc0: 70 6f 72 74 73 20 40 20 2e 69 6d 70 6f 72 74 73  ports @ .imports
2cd0: 0a 20 20 20 20 73 70 61 63 65 20 2e 6e 69 63 6b  .    space .nick
2ce0: 2b 70 65 74 20 3b 0a 3a 20 2e 6b 65 79 2d 6c 69  +pet ;.: .key-li
2cf0: 73 74 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 6f 3a  st ( o:key -- o:
2d00: 6b 65 79 20 29 0a 20 20 20 20 6b 65 2d 6f 66 66  key ).    ke-off
2d10: 73 65 74 20 36 34 40 20 36 34 3e 64 20 6b 65 79  set 64@ 64>d key
2d20: 70 61 63 6b 2d 61 6c 6c 23 20 66 6d 2f 6d 6f 64  pack-all# fm/mod
2d30: 20 6e 69 70 20 33 20 2e 72 20 73 70 61 63 65 0a   nip 3 .r space.
2d40: 20 20 20 20 2e 6b 65 79 2d 72 65 73 74 20 63 72      .key-rest cr
2d50: 20 3b 0a 3a 20 2e 73 65 63 72 65 74 2d 6e 69 63   ;.: .secret-nic
2d60: 6b 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 30 20  ks ( -- ).    0 
2d70: 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b 20 24 40  key# [: cell+ $@
2d80: 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 20 6b   drop cell+ >o k
2d90: 65 2d 73 6b 20 40 20 49 46 0a 09 20 20 5b 3a 20  e-sk @ IF..  [: 
2da0: 64 75 70 20 31 20 2e 72 20 3b 5d 20 23 33 36 20  dup 1 .r ;] #36 
2db0: 62 61 73 65 2d 65 78 65 63 75 74 65 20 73 70 61  base-execute spa
2dc0: 63 65 20 2e 6b 65 79 2d 72 65 73 74 20 63 72 20  ce .key-rest cr 
2dd0: 31 2b 0a 20 20 20 20 20 20 54 48 45 4e 20 6f 3e  1+.      THEN o>
2de0: 20 3b 5d 20 23 6d 61 70 20 64 72 6f 70 20 3b 0a   ;] #map drop ;.
2df0: 3a 20 2e 6b 65 79 2d 69 6e 76 69 74 65 20 28 20  : .key-invite ( 
2e00: 6f 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29  o:key -- o:key )
2e10: 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 6b 65  .    ke-pk $@ ke
2e20: 79 73 69 7a 65 20 75 6d 69 6e 0a 20 20 20 20 6b  ysize umin.    k
2e30: 65 2d 69 6d 70 6f 72 74 73 20 40 20 3e 69 6d 2d  e-imports @ >im-
2e40: 63 6f 6c 6f 72 20 38 35 74 79 70 65 20 3c 64 65  color 85type <de
2e50: 66 61 75 6c 74 3e 0a 20 20 20 20 73 70 61 63 65  fault>.    space
2e60: 20 2e 6e 69 63 6b 20 73 70 61 63 65 20 3b 0a 3a   .nick space ;.:
2e70: 20 2e 6b 65 79 2d 73 68 6f 72 74 20 28 20 6f 3a   .key-short ( o:
2e80: 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20  key -- o:key ). 
2e90: 20 20 20 6b 65 2d 6e 69 63 6b 20 24 2e 20 6b 65     ke-nick $. ke
2ea0: 2d 70 72 6f 66 20 24 40 6c 65 6e 20 49 46 20 2e  -prof $@len IF .
2eb0: 22 20 20 70 72 6f 66 69 6c 65 3a 20 22 20 6b 65  "  profile: " ke
2ec0: 2d 70 72 6f 66 20 24 40 20 38 35 74 79 70 65 20  -prof $@ 85type 
2ed0: 54 48 45 4e 20 3b 0a 3a 20 6c 69 73 74 2d 6b 65  THEN ;.: list-ke
2ee0: 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 2e 22  ys ( -- ).    ."
2ef0: 20 63 6f 6c 6f 72 73 3a 20 22 20 2e 69 6d 70 6f   colors: " .impo
2f00: 72 74 2d 63 6f 6c 6f 72 73 20 63 72 0a 20 20 20  rt-colors cr.   
2f10: 20 2e 22 20 6e 75 6d 20 70 75 62 6b 65 79 20 20   ." num pubkey  
2f20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f40: 20 64 61 74 65 20 20 20 20 20 20 20 20 20 20 20   date           
2f50: 20 20 20 20 20 20 20 20 20 20 67 72 70 2b 70 65            grp+pe
2f60: 72 6d 09 68 20 6e 69 63 6b 22 20 63 72 0a 20 20  rm.h nick" cr.  
2f70: 20 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b 20    key# [: cell+ 
2f80: 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 2e 2e  $@ drop cell+ ..
2f90: 6b 65 79 2d 6c 69 73 74 20 3b 5d 20 23 6d 61 70  key-list ;] #map
2fa0: 20 3b 0a 3a 20 6c 69 73 74 2d 6e 69 63 6b 73 20   ;.: list-nicks 
2fb0: 28 20 2d 2d 20 29 0a 20 20 20 20 6e 69 63 6b 23  ( -- ).    nick#
2fc0: 20 5b 3a 20 64 75 70 20 24 2e 20 2e 22 20 3a 22   [: dup $. ." :"
2fd0: 20 63 72 20 63 65 6c 6c 2b 20 24 40 20 62 6f 75   cr cell+ $@ bou
2fe0: 6e 64 73 20 3f 44 4f 0a 09 20 20 49 20 40 20 2e  nds ?DO..  I @ .
2ff0: 2e 6b 65 79 2d 6c 69 73 74 20 20 63 65 6c 6c 20  .key-list  cell 
3000: 2b 4c 4f 4f 50 20 3b 5d 20 23 6d 61 70 20 3b 0a  +LOOP ;] #map ;.
3010: 0a 3a 20 64 75 6d 70 6b 65 79 20 28 20 61 64 64  .: dumpkey ( add
3020: 72 20 75 20 2d 2d 20 29 20 64 72 6f 70 20 63 65  r u -- ) drop ce
3030: 6c 6c 2b 20 3e 6f 0a 20 20 20 20 2e 5c 22 20 78  ll+ >o.    .\" x
3040: 5c 22 20 22 20 6b 65 2d 70 6b 20 24 40 20 38 35  \" " ke-pk $@ 85
3050: 74 79 70 65 20 2e 5c 22 20 5c 22 20 6b 65 79 3f  type .\" \" key?
3060: 6e 65 77 22 20 63 72 0a 20 20 20 20 6b 65 2d 73  new" cr.    ke-s
3070: 6b 20 40 20 49 46 20 20 2e 5c 22 20 78 5c 22 20  k @ IF  .\" x\" 
3080: 22 20 6b 65 2d 73 6b 20 40 20 6b 65 79 73 69 7a  " ke-sk @ keysiz
3090: 65 20 38 35 74 79 70 65 20 2e 5c 22 20 5c 22 20  e 85type .\" \" 
30a0: 6b 65 2d 73 6b 20 73 65 63 21 20 2b 73 65 63 6b  ke-sk sec! +seck
30b0: 65 79 22 20 63 72 20 20 54 48 45 4e 0a 20 20 20  ey" cr  THEN.   
30c0: 20 27 22 27 20 65 6d 69 74 20 2e 6e 69 63 6b 20   '"' emit .nick 
30d0: 2e 5c 22 20 5c 22 20 6b 65 2d 6e 69 63 6b 20 24  .\" \" ke-nick $
30e0: 21 20 22 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73  ! ".    ke-selfs
30f0: 69 67 20 24 40 20 64 72 6f 70 20 36 34 40 20 36  ig $@ drop 64@ 6
3100: 34 3e 64 20 5b 3a 20 27 24 27 20 65 6d 69 74 20  4>d [: '$' emit 
3110: 30 20 75 64 2e 72 20 3b 5d 20 24 31 30 20 62 61  0 ud.r ;] $10 ba
3120: 73 65 2d 65 78 65 63 75 74 65 0a 20 20 20 20 2e  se-execute.    .
3130: 22 20 2e 20 64 3e 36 34 20 6b 65 2d 66 69 72 73  " . d>64 ke-firs
3140: 74 21 20 22 20 6b 65 2d 74 79 70 65 20 40 20 2e  t! " ke-type @ .
3150: 20 2e 22 20 6b 65 2d 74 79 70 65 20 21 22 20 20   ." ke-type !"  
3160: 63 72 20 6f 3e 20 3b 0a 0a 3a 20 2e 6b 65 79 73  cr o> ;..: .keys
3170: 20 28 20 2d 2d 20 29 20 6b 65 79 23 20 5b 3a 20   ( -- ) key# [: 
3180: 2e 22 20 69 6e 64 65 78 3a 20 22 20 64 75 70 20  ." index: " dup 
3190: 24 40 20 38 35 74 79 70 65 20 63 72 20 63 65 6c  $@ 85type cr cel
31a0: 6c 2b 20 24 40 20 2e 6b 65 79 20 3b 5d 20 23 6d  l+ $@ .key ;] #m
31b0: 61 70 20 3b 0a 3a 20 64 75 6d 70 6b 65 79 73 20  ap ;.: dumpkeys 
31c0: 28 20 2d 2d 20 29 20 6b 65 79 23 20 5b 3a 20 63  ( -- ) key# [: c
31d0: 65 6c 6c 2b 20 24 40 20 64 75 6d 70 6b 65 79 20  ell+ $@ dumpkey 
31e0: 3b 5d 20 23 6d 61 70 20 3b 0a 0a 3a 20 6b 65 79  ;] #map ;..: key
31f0: 3e 6e 69 63 6b 20 28 20 61 64 64 72 6b 65 79 20  >nick ( addrkey 
3200: 75 31 20 2d 2d 20 6e 69 63 6b 20 75 32 20 29 0a  u1 -- nick u2 ).
3210: 20 20 20 20 5c 47 20 63 6f 6e 76 65 72 74 20 6b      \G convert k
3220: 65 79 20 74 6f 20 6e 69 63 6b 0a 20 20 20 20 6b  ey to nick.    k
3230: 65 79 7c 20 6b 65 79 23 20 23 40 20 30 3d 20 49  ey| key# #@ 0= I
3240: 46 20 20 64 72 6f 70 20 23 30 2e 20 20 45 58 49  F  drop #0.  EXI
3250: 54 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c  T  THEN.    cell
3260: 2b 20 2e 6b 65 2d 6e 69 63 6b 20 24 40 20 3b 0a  + .ke-nick $@ ;.
3270: 3a 20 6b 65 79 3e 6b 65 79 20 28 20 61 64 64 72  : key>key ( addr
3280: 6b 65 79 20 75 31 20 2d 2d 20 6b 65 79 20 75 32  key u1 -- key u2
3290: 20 29 0a 20 20 20 20 5c 47 20 65 78 70 61 6e 64   ).    \G expand
32a0: 20 6b 65 79 20 74 6f 20 66 75 6c 6c 20 73 69 7a   key to full siz
32b0: 65 20 61 6e 64 20 63 68 65 63 6b 20 69 66 20 77  e and check if w
32c0: 65 20 6b 6e 6f 77 20 69 74 0a 20 20 20 20 6b 65  e know it.    ke
32d0: 79 7c 20 6b 65 79 23 20 23 40 20 30 3d 20 49 46  y| key# #@ 0= IF
32e0: 20 20 64 72 6f 70 20 23 30 2e 20 20 45 58 49 54    drop #0.  EXIT
32f0: 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b    THEN.    cell+
3300: 20 2e 6b 65 2d 70 6b 20 24 40 20 3b 0a 0a 3a 20   .ke-pk $@ ;..: 
3310: 2e 6b 65 79 23 20 28 20 61 64 64 72 20 75 20 2d  .key# ( addr u -
3320: 2d 20 29 20 6b 65 79 7c 0a 20 20 20 20 2e 22 20  - ) key|.    ." 
3330: 4b 65 79 20 27 22 20 6b 65 79 23 20 23 40 20 30  Key '" key# #@ 0
3340: 3d 20 49 46 20 64 72 6f 70 20 45 58 49 54 20 54  = IF drop EXIT T
3350: 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b 20 2e 2e  HEN.    cell+ ..
3360: 6e 69 63 6b 20 2e 22 20 27 20 6f 6b 22 20 63 72  nick ." ' ok" cr
3370: 20 3b 0a 0a 44 65 66 65 72 20 64 68 74 2d 6e 69   ;..Defer dht-ni
3380: 63 6b 3f 0a 65 76 65 6e 74 3a 20 2d 3e 73 65 61  ck?.event: ->sea
3390: 72 63 68 2d 6b 65 79 20 20 6b 65 79 7c 20 6f 76  rch-key  key| ov
33a0: 65 72 20 3e 72 20 64 68 74 2d 6e 69 63 6b 3f 20  er >r dht-nick? 
33b0: 72 3e 20 66 72 65 65 20 74 68 72 6f 77 20 3b 0a  r> free throw ;.
33c0: 0a 3a 20 2e 75 6e 6b 65 79 2d 69 64 20 28 20 61  .: .unkey-id ( a
33d0: 64 64 72 20 75 20 2d 2d 20 29 20 3c 65 72 72 3e  ddr u -- ) <err>
33e0: 20 38 20 75 6d 69 6e 20 38 35 74 79 70 65 20 2e   8 umin 85type .
33f0: 22 20 28 75 6e 6b 6e 6f 77 6e 29 22 20 3c 64 65  " (unknown)" <de
3400: 66 61 75 6c 74 3e 20 3b 0a 0a 56 61 72 69 61 62  fault> ;..Variab
3410: 6c 65 20 75 6e 6b 65 79 2d 69 64 23 0a 23 36 30  le unkey-id#.#60
3420: 2e 30 30 30 2e 30 30 30 2e 30 30 30 20 64 3e 36  .000.000.000 d>6
3430: 34 20 36 34 43 6f 6e 73 74 61 6e 74 20 75 6e 6b  4 64Constant unk
3440: 65 79 2d 74 6f 23 0a 3a 20 3f 75 6e 6b 65 79 20  ey-to#.: ?unkey 
3450: 28 20 61 64 64 72 20 75 20 2d 2d 20 66 6c 61 67  ( addr u -- flag
3460: 20 29 0a 20 20 20 20 75 6e 6b 65 79 2d 69 64 23   ).    unkey-id#
3470: 20 23 40 0a 20 20 20 20 49 46 20 20 36 34 40 20   #@.    IF  64@ 
3480: 75 6e 6b 65 79 2d 74 6f 23 20 36 34 2b 20 74 69  unkey-to# 64+ ti
3490: 63 6b 73 20 36 34 2d 20 36 34 2d 30 3e 3d 20 20  cks 64- 64-0>=  
34a0: 54 48 45 4e 20 20 30 3d 20 3b 0a 20 20 20 20 0a  THEN  0= ;.    .
34b0: 3a 20 2e 6b 65 79 2d 69 64 20 28 20 61 64 64 72  : .key-id ( addr
34c0: 20 75 20 2d 2d 20 29 20 6b 65 79 7c 20 32 64 75   u -- ) key| 2du
34d0: 70 20 6b 65 79 23 20 23 40 20 30 3d 0a 20 20 20  p key# #@ 0=.   
34e0: 20 49 46 20 20 64 72 6f 70 20 75 70 40 20 72 65   IF  drop up@ re
34f0: 63 65 69 76 65 72 2d 74 61 73 6b 20 3d 20 49 46  ceiver-task = IF
3500: 0a 09 20 20 20 20 3c 65 76 65 6e 74 20 32 64 75  ..    <event 2du
3510: 70 20 73 61 76 65 2d 6d 65 6d 20 65 24 2c 20 2d  p save-mem e$, -
3520: 3e 73 65 61 72 63 68 2d 6b 65 79 20 6d 61 69 6e  >search-key main
3530: 2d 75 70 40 20 65 76 65 6e 74 3e 0a 09 20 20 20  -up@ event>..   
3540: 20 2e 75 6e 6b 65 79 2d 69 64 20 45 58 49 54 20   .unkey-id EXIT 
3550: 20 54 48 45 4e 0a 09 32 64 75 70 20 3f 75 6e 6b   THEN..2dup ?unk
3560: 65 79 20 20 49 46 0a 09 20 20 20 20 74 69 63 6b  ey  IF..    tick
3570: 73 20 7b 20 36 34 5e 20 74 78 20 7d 20 74 78 20  s { 64^ tx } tx 
3580: 31 20 36 34 73 20 32 6f 76 65 72 20 75 6e 6b 65  1 64s 2over unke
3590: 79 2d 69 64 23 20 23 21 0a 09 20 20 20 20 63 6f  y-id# #!..    co
35a0: 6e 6e 65 63 74 69 6f 6e 20 3e 72 20 32 64 75 70  nnection >r 2dup
35b0: 20 5b 27 5d 20 64 68 74 2d 6e 69 63 6b 3f 20 63   ['] dht-nick? c
35c0: 6d 64 2d 6e 65 73 74 20 72 3e 20 74 6f 20 63 6f  md-nest r> to co
35d0: 6e 6e 65 63 74 69 6f 6e 0a 09 20 20 20 20 32 64  nnection..    2d
35e0: 75 70 20 6b 65 79 23 20 23 40 20 30 3d 20 49 46  up key# #@ 0= IF
35f0: 20 20 64 72 6f 70 20 2e 75 6e 6b 65 79 2d 69 64    drop .unkey-id
3600: 20 45 58 49 54 0a 09 20 20 20 20 45 4c 53 45 20   EXIT..    ELSE 
3610: 20 3e 72 20 32 64 75 70 20 75 6e 6b 65 79 2d 69   >r 2dup unkey-i
3620: 64 23 20 23 6f 66 66 20 72 3e 20 20 54 48 45 4e  d# #off r>  THEN
3630: 0a 09 45 4c 53 45 20 20 2e 75 6e 6b 65 79 2d 69  ..ELSE  .unkey-i
3640: 64 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20  d  EXIT  THEN.  
3650: 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b    THEN.    cell+
3660: 20 2e 2e 6e 69 63 6b 20 32 64 72 6f 70 20 3b 0a   ..nick 2drop ;.
3670: 0a 3a 20 2e 63 6f 6e 2d 69 64 20 28 20 6f 3a 63  .: .con-id ( o:c
3680: 6f 6e 6e 65 63 74 69 6f 6e 20 2d 2d 20 29 20 70  onnection -- ) p
3690: 75 62 6b 65 79 20 24 40 20 2e 6b 65 79 2d 69 64  ubkey $@ .key-id
36a0: 20 3b 0a 0a 3a 20 2e 73 69 6d 70 6c 65 2d 69 64   ;..: .simple-id
36b0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b   ( addr u -- ) k
36c0: 65 79 3e 6e 69 63 6b 20 74 79 70 65 20 3b 0a 0a  ey>nick type ;..
36d0: 3a 20 63 68 65 63 6b 2d 6b 65 79 20 28 20 61 64  : check-key ( ad
36e0: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6f 20  dr u -- ).    o 
36f0: 49 46 20 20 70 75 62 6b 65 79 20 40 20 49 46 0a  IF  pubkey @ IF.
3700: 09 20 20 20 20 32 64 75 70 20 70 75 62 6b 65 79  .    2dup pubkey
3710: 20 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 30 3d   $@ key| str= 0=
3720: 20 49 46 0a 09 09 5b 3a 20 2e 22 20 77 61 6e 74   IF...[: ." want
3730: 3a 20 22 20 70 75 62 6b 65 79 20 24 40 20 6b 65  : " pubkey $@ ke
3740: 79 7c 20 38 35 74 79 70 65 20 63 72 0a 09 09 20  y| 85type cr... 
3750: 20 2e 22 20 67 6f 74 20 3a 20 22 20 32 64 75 70   ." got : " 2dup
3760: 20 38 35 74 79 70 65 20 63 72 20 3b 5d 20 24 65   85type cr ;] $e
3770: 72 72 0a 09 09 74 72 75 65 20 21 21 77 72 6f 6e  rr...true !!wron
3780: 67 2d 6b 65 79 21 21 0a 09 20 20 20 20 54 48 45  g-key!!..    THE
3790: 4e 0a 09 20 20 20 20 63 6f 6e 6e 65 63 74 28 20  N..    connect( 
37a0: 2e 6b 65 79 23 20 29 65 6c 73 65 28 20 32 64 72  .key# )else( 2dr
37b0: 6f 70 20 29 20 20 45 58 49 54 0a 09 54 48 45 4e  op )  EXIT..THEN
37c0: 20 20 54 48 45 4e 0a 20 20 20 20 32 64 75 70 20    THEN.    2dup 
37d0: 6b 65 79 2d 65 78 69 73 74 3f 0a 20 20 20 20 3f  key-exist?.    ?
37e0: 64 75 70 2d 30 3d 2d 49 46 20 20 70 65 72 6d 25  dup-0=-IF  perm%
37f0: 75 6e 6b 6e 6f 77 6e 20 20 45 4c 53 45 20 20 2e  unknown  ELSE  .
3800: 6b 65 2d 6d 61 73 6b 20 40 20 20 54 48 45 4e 20  ke-mask @  THEN 
3810: 20 74 6d 70 2d 70 65 72 6d 20 21 0a 20 20 20 20   tmp-perm !.    
3820: 63 6f 6e 6e 65 63 74 28 20 32 64 75 70 20 2e 6b  connect( 2dup .k
3830: 65 79 23 20 29 0a 20 20 20 20 74 6d 70 2d 70 65  ey# ).    tmp-pe
3840: 72 6d 20 40 20 70 65 72 6d 25 62 6c 6f 63 6b 65  rm @ perm%blocke
3850: 64 20 61 6e 64 20 49 46 0a 09 5b 3a 20 2e 22 20  d and IF..[: ." 
3860: 55 6e 6b 6e 6f 77 6e 20 6b 65 79 2c 20 63 6f 6e  Unknown key, con
3870: 6e 65 63 74 69 6f 6e 20 72 65 66 75 73 65 64 3a  nection refused:
3880: 20 22 20 38 35 74 79 70 65 20 63 72 20 3b 5d 20   " 85type cr ;] 
3890: 24 65 72 72 0a 09 74 72 75 65 20 21 21 63 6f 6e  $err..true !!con
38a0: 6e 65 63 74 2d 70 65 72 6d 21 21 0a 20 20 20 20  nect-perm!!.    
38b0: 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 48 45  ELSE  2drop  THE
38c0: 4e 20 3b 0a 0a 3a 20 73 65 61 72 63 68 2d 6b 65  N ;..: search-ke
38d0: 79 20 28 20 70 6b 63 20 2d 2d 20 6f 20 73 6b 63  y ( pkc -- o skc
38e0: 20 29 0a 20 20 20 20 6b 65 79 73 69 7a 65 20 6b   ).    keysize k
38f0: 65 79 23 20 23 40 20 30 3d 20 21 21 75 6e 6b 6e  ey# #@ 0= !!unkn
3900: 6f 77 6e 2d 6b 65 79 21 21 0a 20 20 20 20 63 65  own-key!!.    ce
3910: 6c 6c 2b 20 64 75 70 20 2e 6b 65 2d 73 6b 20 73  ll+ dup .ke-sk s
3920: 65 63 40 20 30 3d 20 21 21 75 6e 6b 6e 6f 77 6e  ec@ 0= !!unknown
3930: 2d 6b 65 79 21 21 20 3b 0a 0a 5c 20 61 70 70 6c  -key!! ;..\ appl
3940: 79 20 70 65 72 6d 69 73 73 69 6f 6e 73 26 67 72  y permissions&gr
3950: 6f 75 70 73 0a 0a 3a 20 61 70 70 6c 79 2d 70 65  oups..: apply-pe
3960: 72 6d 69 73 73 69 6f 6e 20 28 20 70 65 72 6d 61  rmission ( perma
3970: 6e 64 20 70 65 72 6d 6f 72 20 6f 3a 6b 65 79 20  nd permor o:key 
3980: 2d 2d 20 70 65 72 6d 61 6e 64 20 70 65 72 6d 6f  -- permand permo
3990: 72 20 6f 3a 6b 65 79 20 29 0a 20 20 20 20 6f 76  r o:key ).    ov
39a0: 65 72 20 6b 65 2d 6d 61 73 6b 20 40 20 61 6e 64  er ke-mask @ and
39b0: 20 6f 76 65 72 20 6f 72 20 6b 65 2d 6d 61 73 6b   over or ke-mask
39c0: 20 21 20 2e 6b 65 79 2d 6c 69 73 74 20 3b 0a 0a   ! .key-list ;..
39d0: 3a 20 2d 67 72 6f 75 70 2d 70 65 72 6d 20 28 20  : -group-perm ( 
39e0: 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 6b  o:key -- ).    k
39f0: 65 2d 67 72 6f 75 70 73 20 24 40 20 67 72 6f 75  e-groups $@ grou
3a00: 70 73 3e 6d 61 73 6b 20 69 6e 76 65 72 74 20 6b  ps>mask invert k
3a10: 65 2d 6d 61 73 6b 20 61 6e 64 21 20 3b 0a 3a 20  e-mask and! ;.: 
3a20: 2b 67 72 6f 75 70 2d 70 65 72 6d 20 28 20 6f 3a  +group-perm ( o:
3a30: 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d  key -- ).    ke-
3a40: 67 72 6f 75 70 73 20 24 40 20 67 72 6f 75 70 73  groups $@ groups
3a50: 3e 6d 61 73 6b 20 20 20 20 20 20 20 20 6b 65 2d  >mask        ke-
3a60: 6d 61 73 6b 20 6f 72 21 20 3b 0a 0a 3a 20 61 64  mask or! ;..: ad
3a70: 64 2d 67 72 6f 75 70 20 28 20 69 64 20 6f 3a 6b  d-group ( id o:k
3a80: 65 79 20 2d 2d 20 29 0a 20 20 20 20 64 75 70 20  ey -- ).    dup 
3a90: 2d 31 20 3d 20 21 21 6e 6f 2d 67 72 6f 75 70 21  -1 = !!no-group!
3aa0: 21 20 2d 67 72 6f 75 70 2d 70 65 72 6d 20 75 3e  ! -group-perm u>
3ab0: 36 34 20 63 6d 64 74 6d 70 24 20 6b 65 2d 67 72  64 cmdtmp$ ke-gr
3ac0: 6f 75 70 73 20 24 2b 21 20 2b 67 72 6f 75 70 2d  oups $+! +group-
3ad0: 70 65 72 6d 20 3b 0a 3a 20 73 65 74 2d 67 72 6f  perm ;.: set-gro
3ae0: 75 70 20 28 20 69 64 20 6f 3a 6b 65 79 20 2d 2d  up ( id o:key --
3af0: 20 29 0a 20 20 20 20 64 75 70 20 2d 31 20 3d 20   ).    dup -1 = 
3b00: 21 21 6e 6f 2d 67 72 6f 75 70 21 21 20 2d 67 72  !!no-group!! -gr
3b10: 6f 75 70 2d 70 65 72 6d 20 75 3e 36 34 20 63 6d  oup-perm u>64 cm
3b20: 64 74 6d 70 24 20 6b 65 2d 67 72 6f 75 70 73 20  dtmp$ ke-groups 
3b30: 24 21 20 2b 67 72 6f 75 70 2d 70 65 72 6d 20 3b  $! +group-perm ;
3b40: 0a 3a 20 73 75 62 2d 67 72 6f 75 70 20 28 20 69  .: sub-group ( i
3b50: 64 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20  d o:key -- ).   
3b60: 20 64 75 70 20 2d 31 20 3d 20 21 21 6e 6f 2d 67   dup -1 = !!no-g
3b70: 72 6f 75 70 21 21 20 2d 67 72 6f 75 70 2d 70 65  roup!! -group-pe
3b80: 72 6d 20 75 3e 36 34 20 63 6d 64 74 6d 70 24 20  rm u>64 cmdtmp$ 
3b90: 6b 65 2d 67 72 6f 75 70 73 20 24 40 20 32 6f 76  ke-groups $@ 2ov
3ba0: 65 72 20 73 65 61 72 63 68 0a 20 20 20 20 49 46  er search.    IF
3bb0: 20 20 20 6e 69 70 20 3e 72 20 6e 69 70 20 6b 65     nip >r nip ke
3bc0: 2d 67 72 6f 75 70 73 20 64 75 70 20 24 40 6c 65  -groups dup $@le
3bd0: 6e 20 72 3e 20 2d 20 72 6f 74 20 24 64 65 6c 0a  n r> - rot $del.
3be0: 20 20 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20      ELSE  2drop 
3bf0: 32 64 72 6f 70 20 20 54 48 45 4e 20 2b 67 72 6f  2drop  THEN +gro
3c00: 75 70 2d 70 65 72 6d 20 3b 0a 0a 3a 20 61 70 70  up-perm ;..: app
3c10: 6c 79 2d 67 72 6f 75 70 20 28 20 61 64 64 72 20  ly-group ( addr 
3c20: 75 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20  u o:key -- ).   
3c30: 20 6f 76 65 72 20 63 40 20 27 2b 27 20 3d 20 49   over c@ '+' = I
3c40: 46 20 20 31 20 2f 73 74 72 69 6e 67 20 3e 67 72  F  1 /string >gr
3c50: 6f 75 70 2d 69 64 20 61 64 64 2d 67 72 6f 75 70  oup-id add-group
3c60: 20 2e 6b 65 79 2d 6c 69 73 74 20 20 45 58 49 54   .key-list  EXIT
3c70: 20 20 54 48 45 4e 0a 20 20 20 20 6f 76 65 72 20    THEN.    over 
3c80: 63 40 20 27 2d 27 20 3d 20 49 46 20 20 31 20 2f  c@ '-' = IF  1 /
3c90: 73 74 72 69 6e 67 20 3e 67 72 6f 75 70 2d 69 64  string >group-id
3ca0: 20 73 75 62 2d 67 72 6f 75 70 20 2e 6b 65 79 2d   sub-group .key-
3cb0: 6c 69 73 74 20 20 45 58 49 54 20 20 54 48 45 4e  list  EXIT  THEN
3cc0: 0a 20 20 20 20 3e 67 72 6f 75 70 2d 69 64 20 73  .    >group-id s
3cd0: 65 74 2d 67 72 6f 75 70 20 2e 6b 65 79 2d 6c 69  et-group .key-li
3ce0: 73 74 20 3b 0a 0a 5c 20 67 65 74 20 70 61 73 73  st ;..\ get pass
3cf0: 70 68 72 61 73 65 0a 0a 33 20 56 61 6c 75 65 20  phrase..3 Value 
3d00: 70 61 73 73 70 68 72 61 73 65 2d 72 65 74 72 79  passphrase-retry
3d10: 23 0a 24 31 30 30 20 43 6f 6e 73 74 61 6e 74 20  #.$100 Constant 
3d20: 6d 61 78 2d 70 61 73 73 70 68 72 61 73 65 23 20  max-passphrase# 
3d30: 5c 20 32 35 36 20 63 68 61 72 61 63 74 65 72 73  \ 256 characters
3d40: 20 73 68 6f 75 6c 64 20 62 65 20 65 6e 6f 75 67   should be enoug
3d50: 68 2e 2e 2e 0a 6d 61 78 2d 70 61 73 73 70 68 72  h....max-passphr
3d60: 61 73 65 23 20 62 75 66 66 65 72 3a 20 70 61 73  ase# buffer: pas
3d70: 73 70 68 72 61 73 65 0a 0a 3a 20 70 61 73 73 70  sphrase..: passp
3d80: 68 72 61 73 65 2d 69 6e 20 28 20 61 64 64 72 20  hrase-in ( addr 
3d90: 75 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20  u -- addr u ).  
3da0: 20 20 22 50 41 53 53 50 48 52 41 53 45 22 20 67    "PASSPHRASE" g
3db0: 65 74 65 6e 76 20 32 64 75 70 20 64 30 3d 20 49  etenv 2dup d0= I
3dc0: 46 20 20 32 64 72 6f 70 20 74 79 70 65 0a 09 70  F  2drop type..p
3dd0: 61 73 73 70 68 72 61 73 65 20 64 75 70 20 6d 61  assphrase dup ma
3de0: 78 2d 70 61 73 73 70 68 72 61 73 65 23 20 61 63  x-passphrase# ac
3df0: 63 65 70 74 2a 20 63 72 0a 20 20 20 20 45 4c 53  cept* cr.    ELS
3e00: 45 20 20 32 6e 69 70 20 20 54 48 45 4e 20 3b 0a  E  2nip  THEN ;.
3e10: 0a 3a 20 3e 70 61 73 73 70 68 72 61 73 65 20 28  .: >passphrase (
3e20: 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 20   addr u -- addr 
3e30: 75 20 29 0a 20 20 20 20 5c 47 20 63 72 65 61 74  u ).    \G creat
3e40: 65 20 61 20 35 31 32 20 62 69 74 20 68 61 73 68  e a 512 bit hash
3e50: 20 6f 66 20 74 68 65 20 70 61 73 73 70 68 72 61   of the passphra
3e60: 73 65 0a 20 20 20 20 6e 6f 2d 6b 65 79 20 3e 63  se.    no-key >c
3e70: 3a 6b 65 79 20 63 3a 68 61 73 68 0a 20 20 20 20  :key c:hash.    
3e80: 6b 65 63 63 61 6b 2d 70 61 64 64 65 64 20 63 3a  keccak-padded c:
3e90: 6b 65 79 3e 20 6b 65 63 63 61 6b 2d 70 61 64 64  key> keccak-padd
3ea0: 65 64 20 6b 65 63 63 61 6b 23 6d 61 78 20 32 2f  ed keccak#max 2/
3eb0: 20 3b 0a 0a 3a 20 67 65 74 2d 70 61 73 73 70 68   ;..: get-passph
3ec0: 72 61 73 65 20 28 20 61 64 64 72 20 75 20 2d 2d  rase ( addr u --
3ed0: 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 70 61   addr u ).    pa
3ee0: 73 73 70 68 72 61 73 65 2d 69 6e 20 3e 70 61 73  ssphrase-in >pas
3ef0: 73 70 68 72 61 73 65 20 3b 0a 0a 56 61 72 69 61  sphrase ;..Varia
3f00: 62 6c 65 20 6b 65 79 73 0a 0a 3a 20 6c 61 73 74  ble keys..: last
3f10: 6b 65 79 40 20 28 20 2d 2d 20 61 64 64 72 20 75  key@ ( -- addr u
3f20: 20 29 20 6b 65 79 73 20 24 5b 5d 23 20 31 2d 20   ) keys $[]# 1- 
3f30: 6b 65 79 73 20 73 65 63 5b 5d 40 20 3b 0a 3a 20  keys sec[]@ ;.: 
3f40: 6b 65 79 3e 64 65 66 61 75 6c 74 20 28 20 2d 2d  key>default ( --
3f50: 20 29 20 6c 61 73 74 6b 65 79 40 20 64 72 6f 70   ) lastkey@ drop
3f60: 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 3b 0a 3a   >storekey ! ;.:
3f70: 20 2b 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d   +key ( addr u -
3f80: 2d 20 29 20 6b 65 79 73 20 73 65 63 2b 5b 5d 21  - ) keys sec+[]!
3f90: 20 3b 0a 3a 20 2b 70 61 73 73 70 68 72 61 73 65   ;.: +passphrase
3fa0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 20   ( addr u -- )  
3fb0: 67 65 74 2d 70 61 73 73 70 68 72 61 73 65 20 2b  get-passphrase +
3fc0: 6b 65 79 20 3b 0a 3a 20 2b 63 68 65 63 6b 70 68  key ;.: +checkph
3fd0: 72 61 73 65 20 28 20 61 64 64 72 20 75 20 2d 2d  rase ( addr u --
3fe0: 20 66 6c 61 67 20 29 20 67 65 74 2d 70 61 73 73   flag ) get-pass
3ff0: 70 68 72 61 73 65 20 6c 61 73 74 6b 65 79 40 20  phrase lastkey@ 
4000: 73 74 72 3d 20 3b 0a 3a 20 2b 6e 65 77 70 68 72  str= ;.: +newphr
4010: 61 73 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 42  ase ( -- ).    B
4020: 45 47 49 4e 0a 09 73 22 20 50 61 73 73 70 68 72  EGIN..s" Passphr
4030: 61 73 65 3a 20 22 20 2b 70 61 73 73 70 68 72 61  ase: " +passphra
4040: 73 65 0a 09 73 22 20 52 65 74 79 70 65 20 70 6c  se..s" Retype pl
4050: 73 3a 20 22 20 2b 63 68 65 63 6b 70 68 72 61 73  s: " +checkphras
4060: 65 20 30 3d 20 57 48 49 4c 45 0a 09 20 20 20 20  e 0= WHILE..    
4070: 63 72 20 2e 22 20 20 64 69 64 6e 27 74 20 6d 61  cr ."  didn't ma
4080: 74 63 68 2c 20 74 72 79 20 61 67 61 69 6e 20 70  tch, try again p
4090: 6c 65 61 73 65 22 20 63 72 0a 20 20 20 20 52 45  lease" cr.    RE
40a0: 50 45 41 54 20 63 72 20 3b 0a 0a 3a 20 22 3e 70  PEAT cr ;..: ">p
40b0: 61 73 73 70 68 72 61 73 65 20 28 20 61 64 64 72  assphrase ( addr
40c0: 20 75 20 2d 2d 20 29 20 3e 70 61 73 73 70 68 72   u -- ) >passphr
40d0: 61 73 65 20 2b 6b 65 79 20 3b 0a 3a 20 3e 73 65  ase +key ;.: >se
40e0: 63 6b 65 79 20 28 20 2d 2d 20 61 64 64 72 20 75  ckey ( -- addr u
40f0: 20 29 0a 20 20 20 20 6b 65 2d 73 6b 20 40 20 6b   ).    ke-sk @ k
4100: 65 2d 70 6b 20 24 40 20 64 72 6f 70 20 6b 65 79  e-pk $@ drop key
4110: 70 61 64 20 65 64 2d 64 68 20 3b 0a 3a 20 2b 73  pad ed-dh ;.: +s
4120: 65 63 6b 65 79 20 28 20 2d 2d 20 29 20 3e 73 65  eckey ( -- ) >se
4130: 63 6b 65 79 20 2b 6b 65 79 20 3b 0a 0a 5c 20 22  ckey +key ;..\ "
4140: 22 20 22 3e 70 61 73 73 70 68 72 61 73 65 20 5c  " ">passphrase \
4150: 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 65   following the e
4160: 6e 63 72 79 70 74 2d 65 76 65 72 79 74 68 69 6e  ncrypt-everythin
4170: 67 20 70 61 72 61 64 69 67 6d 2c 0a 5c 20 6e 6f  g paradigm,.\ no
4180: 20 70 61 73 73 77 6f 72 64 20 69 73 20 74 68 65   password is the
4190: 20 65 6d 70 74 79 20 73 74 72 69 6e 67 21 20 20   empty string!  
41a0: 49 74 27 73 20 73 74 69 6c 6c 20 65 6e 63 72 79  It's still encry
41b0: 70 74 65 64 20 3b 2d 29 21 0a 0a 5c 20 61 20 73  pted ;-)!..\ a s
41c0: 65 63 72 65 74 20 6b 65 79 20 6a 75 73 74 20 6e  ecret key just n
41d0: 65 65 64 73 20 61 20 6e 69 63 6b 20 61 6e 64 20  eeds a nick and 
41e0: 61 20 74 79 70 65 2e 0a 5c 20 53 65 63 72 65 74  a type..\ Secret
41f0: 20 6b 65 79 73 20 63 61 6e 20 62 65 20 70 65 72   keys can be per
4200: 73 6f 6e 73 20 61 6e 64 20 67 72 6f 75 70 73 2e  sons and groups.
4210: 0a 0a 5c 20 61 20 70 75 62 6c 69 63 20 6b 65 79  ..\ a public key
4220: 20 6e 65 65 64 73 20 6d 6f 72 65 3a 20 6e 69 63   needs more: nic
4230: 6b 2c 20 74 79 70 65 2c 20 70 72 6f 66 69 6c 65  k, type, profile
4240: 2e 0a 5c 20 54 68 65 20 70 72 6f 66 69 6c 65 20  ..\ The profile 
4250: 69 73 20 61 20 73 74 72 75 63 74 75 72 65 64 20  is a structured 
4260: 64 6f 63 75 6d 65 6e 74 2c 20 69 2e 65 2e 20 70  document, i.e. p
4270: 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 61 20 68  ointed to by a h
4280: 61 73 68 2e 0a 0a 5c 20 61 20 73 69 67 6e 61 74  ash...\ a signat
4290: 75 72 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 70  ure contains a p
42a0: 75 62 6b 65 79 2c 20 61 20 63 68 65 63 6b 62 6f  ubkey, a checkbo
42b0: 78 20 62 69 74 6d 61 73 6b 2c 0a 5c 20 61 20 64  x bitmask,.\ a d
42c0: 61 74 65 2c 20 61 6e 20 65 78 70 69 72 61 74 69  ate, an expirati
42d0: 6f 6e 20 64 61 74 65 2c 20 74 68 65 20 73 69 67  on date, the sig
42e0: 6e 65 72 27 73 20 70 75 62 6b 65 79 20 61 6e 64  ner's pubkey and
42f0: 20 74 68 65 20 73 69 67 6e 61 74 75 72 65 20 69   the signature i
4300: 74 73 65 6c 66 0a 5c 20 28 72 2b 73 29 2e 20 20  tself.\ (r+s).  
4310: 54 68 65 72 65 20 69 73 20 61 6e 20 6f 70 74 69  There is an opti
4320: 6f 6e 61 6c 20 73 69 67 6e 69 6e 67 20 70 72 6f  onal signing pro
4330: 74 6f 63 6f 6c 20 64 6f 63 75 6d 65 6e 74 20 28  tocol document (
4340: 68 61 73 68 29 2e 0a 0a 5c 20 77 65 20 73 74 6f  hash)...\ we sto
4350: 72 65 20 65 61 63 68 20 69 74 65 6d 20 69 6e 20  re each item in 
4360: 61 20 32 35 36 20 62 79 74 65 73 20 65 6e 63 72  a 256 bytes encr
4370: 79 70 74 65 64 20 73 74 72 69 6e 67 2c 20 69 2e  ypted string, i.
4380: 65 2e 20 77 69 74 68 20 61 20 31 36 0a 5c 20 62  e. with a 16.\ b
4390: 79 74 65 20 73 61 6c 74 20 61 6e 64 20 61 20 31  yte salt and a 1
43a0: 36 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 2e  6 byte checksum.
43b0: 0a 0a 3a 20 6b 65 2d 6c 61 73 74 21 20 28 20 36  ..: ke-last! ( 6
43c0: 34 64 61 74 65 20 2d 2d 20 29 0a 20 20 20 20 6b  4date -- ).    k
43d0: 65 2d 73 65 6c 66 73 69 67 20 24 40 6c 65 6e 20  e-selfsig $@len 
43e0: 24 31 30 20 75 6d 61 78 20 6b 65 2d 73 65 6c 66  $10 umax ke-self
43f0: 73 69 67 20 24 21 6c 65 6e 0a 20 20 20 20 6b 65  sig $!len.    ke
4400: 2d 73 65 6c 66 73 69 67 20 24 40 20 64 72 6f 70  -selfsig $@ drop
4410: 20 36 34 27 2b 20 36 34 21 20 3b 0a 3a 20 6b 65   64'+ 64! ;.: ke
4420: 2d 66 69 72 73 74 21 20 28 20 36 34 64 61 74 65  -first! ( 64date
4430: 20 2d 2d 20 29 20 36 34 23 2d 31 20 6b 65 2d 6c   -- ) 64#-1 ke-l
4440: 61 73 74 21 0a 20 20 20 20 6b 65 2d 73 65 6c 66  ast!.    ke-self
4450: 73 69 67 20 24 40 20 64 72 6f 70 20 36 34 21 20  sig $@ drop 64! 
4460: 3b 0a 0a 73 63 6f 70 65 7b 20 6e 65 74 32 6f 2d  ;..scope{ net2o-
4470: 62 61 73 65 0a 0a 63 6d 64 2d 74 61 62 6c 65 20  base..cmd-table 
4480: 24 40 20 69 6e 68 65 72 69 74 2d 74 61 62 6c 65  $@ inherit-table
4490: 20 6b 65 79 2d 65 6e 74 72 79 2d 74 61 62 6c 65   key-entry-table
44a0: 0a 5c 67 20 0a 5c 67 20 23 23 23 20 6b 65 79 20  .\g .\g ### key 
44b0: 73 74 6f 72 61 67 65 20 63 6f 6d 6d 61 6e 64 73  storage commands
44c0: 20 23 23 23 0a 5c 67 20 0a 24 31 31 20 6e 65 74   ###.\g .$11 net
44d0: 32 6f 3a 20 70 72 69 76 6b 65 79 20 28 20 24 3a  2o: privkey ( $:
44e0: 73 74 72 69 6e 67 20 2d 2d 20 29 0a 20 20 20 20  string -- ).    
44f0: 5c 67 20 70 72 69 76 61 74 65 20 6b 65 79 0a 20  \g private key. 
4500: 20 20 20 5c 20 64 6f 65 73 20 6e 6f 74 20 6e 65     \ does not ne
4510: 65 64 20 74 6f 20 62 65 20 73 69 67 6e 65 64 2c  ed to be signed,
4520: 20 74 68 65 20 73 65 63 72 65 74 20 6b 65 79 20   the secret key 
4530: 76 65 72 69 66 69 65 73 20 69 74 73 65 6c 66 0a  verifies itself.
4540: 20 20 20 20 21 21 75 6e 73 69 67 6e 65 64 3f 20      !!unsigned? 
4550: 24 34 30 20 21 21 3e 3d 6f 72 64 65 72 3f 0a 20  $40 !!>=order?. 
4560: 20 20 20 6b 65 79 70 61 63 6b 20 63 40 20 24 46     keypack c@ $F
4570: 20 61 6e 64 20 6b 65 2d 70 77 6c 65 76 65 6c 20   and ke-pwlevel 
4580: 21 0a 20 20 20 20 24 3e 20 6f 76 65 72 20 6b 65  !.    $> over ke
4590: 79 70 61 64 20 73 6b 3e 70 6b 20 5c 20 67 65 6e  ypad sk>pk \ gen
45a0: 65 72 61 74 65 20 70 75 62 6b 65 79 0a 20 20 20  erate pubkey.   
45b0: 20 6b 65 79 70 61 64 20 6b 65 2d 70 6b 20 24 40   keypad ke-pk $@
45c0: 20 64 72 6f 70 20 6b 65 79 73 69 7a 65 20 74 75   drop keysize tu
45d0: 63 6b 20 73 74 72 3d 20 30 3d 20 21 21 77 72 6f  ck str= 0= !!wro
45e0: 6e 67 2d 6b 65 79 21 21 0a 20 20 20 20 6b 65 2d  ng-key!!.    ke-
45f0: 73 6b 20 73 65 63 21 20 2b 73 65 63 6b 65 79 20  sk sec! +seckey 
4600: 22 5c 30 22 20 6b 65 2d 67 72 6f 75 70 73 20 24  "\0" ke-groups $
4610: 21 20 30 20 67 72 6f 75 70 73 5b 5d 20 24 5b 5d  ! 0 groups[] $[]
4620: 40 20 64 72 6f 70 20 40 20 6b 65 2d 6d 61 73 6b  @ drop @ ke-mask
4630: 20 21 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79   ! ;.+net2o: key
4640: 74 79 70 65 20 28 20 6e 20 2d 2d 20 29 20 20 20  type ( n -- )   
4650: 20 20 20 20 20 20 20 20 21 21 73 69 67 6e 65 64          !!signed
4660: 3f 20 20 20 31 20 21 21 3e 6f 72 64 65 72 3f 20  ?   1 !!>order? 
4670: 36 34 3e 6e 20 6b 65 2d 74 79 70 65 20 21 20 3b  64>n ke-type ! ;
4680: 0a 20 20 20 20 5c 67 20 6b 65 79 20 74 79 70 65  .    \g key type
4690: 20 28 30 3a 20 61 6e 6f 6e 2c 20 31 3a 20 75 73   (0: anon, 1: us
46a0: 65 72 2c 20 32 3a 20 67 72 6f 75 70 29 0a 2b 6e  er, 2: group).+n
46b0: 65 74 32 6f 3a 20 6b 65 79 6e 69 63 6b 20 28 20  et2o: keynick ( 
46c0: 24 3a 73 74 72 69 6e 67 20 2d 2d 20 29 20 20 20  $:string -- )   
46d0: 20 21 21 73 69 67 6e 65 64 3f 20 20 20 32 20 21   !!signed?   2 !
46e0: 21 3e 6f 72 64 65 72 3f 20 24 3e 20 6b 65 2d 6e  !>order? $> ke-n
46f0: 69 63 6b 20 24 21 0a 20 20 20 20 5c 67 20 6b 65  ick $!.    \g ke
4700: 79 20 6e 69 63 6b 0a 20 20 20 20 6e 69 63 6b 21  y nick.    nick!
4710: 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 70 72   ;.+net2o: keypr
4720: 6f 66 69 6c 65 20 28 20 24 3a 73 74 72 69 6e 67  ofile ( $:string
4730: 20 2d 2d 20 29 20 21 21 73 69 67 6e 65 64 3f 20   -- ) !!signed? 
4740: 20 20 34 20 21 21 3e 6f 72 64 65 72 3f 20 24 3e    4 !!>order? $>
4750: 20 6b 65 2d 70 72 6f 66 20 24 21 20 3b 0a 20 20   ke-prof $! ;.  
4760: 20 20 5c 67 20 6b 65 79 20 70 72 6f 66 69 6c 65    \g key profile
4770: 20 28 68 61 73 68 20 6f 66 20 61 20 72 65 73 6f   (hash of a reso
4780: 75 72 63 65 29 0a 2b 6e 65 74 32 6f 3a 20 6b 65  urce).+net2o: ke
4790: 79 6d 61 73 6b 20 28 20 78 20 2d 2d 20 29 20 20  ymask ( x -- )  
47a0: 20 20 20 20 20 20 20 21 21 75 6e 73 69 67 6e 65         !!unsigne
47b0: 64 3f 20 24 34 30 20 21 21 3e 3d 6f 72 64 65 72  d? $40 !!>=order
47c0: 3f 20 36 34 3e 6e 0a 20 20 20 20 5c 67 20 6b 65  ? 64>n.    \g ke
47d0: 79 20 61 63 63 65 73 73 20 72 69 67 68 74 20 6d  y access right m
47e0: 61 73 6b 0a 20 20 20 20 31 20 69 6d 70 6f 72 74  ask.    1 import
47f0: 2d 74 79 70 65 20 40 20 6c 73 68 69 66 74 0a 20  -type @ lshift. 
4800: 20 20 20 5b 20 31 20 69 6d 70 6f 72 74 23 73 65     [ 1 import#se
4810: 6c 66 20 6c 73 68 69 66 74 20 31 20 69 6d 70 6f  lf lshift 1 impo
4820: 72 74 23 6e 65 77 20 6c 73 68 69 66 74 20 6f 72  rt#new lshift or
4830: 20 5d 4c 0a 20 20 20 20 61 6e 64 20 30 3d 20 49   ]L.    and 0= I
4840: 46 20 20 64 72 6f 70 20 70 65 72 6d 25 64 65 66  F  drop perm%def
4850: 61 75 6c 74 20 20 54 48 45 4e 20 20 64 75 70 20  ault  THEN  dup 
4860: 6b 65 2d 6d 61 73 6b 20 6f 72 21 20 3f 3e 67 72  ke-mask or! ?>gr
4870: 6f 75 70 73 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b  oups ;.+net2o: k
4880: 65 79 67 72 6f 75 70 73 20 28 20 24 3a 67 72 6f  eygroups ( $:gro
4890: 75 70 73 20 2d 2d 20 29 20 21 21 75 6e 73 69 67  ups -- ) !!unsig
48a0: 6e 65 64 3f 20 24 32 30 20 21 21 3e 6f 72 64 65  ned? $20 !!>orde
48b0: 72 3f 20 24 3e 0a 20 20 20 20 5c 67 20 61 63 63  r? $>.    \g acc
48c0: 65 73 73 20 67 72 6f 75 70 73 0a 20 20 20 20 31  ess groups.    1
48d0: 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 40 20 6c   import-type @ l
48e0: 73 68 69 66 74 0a 20 20 20 20 5b 20 31 20 69 6d  shift.    [ 1 im
48f0: 70 6f 72 74 23 73 65 6c 66 20 6c 73 68 69 66 74  port#self lshift
4900: 20 31 20 69 6d 70 6f 72 74 23 6e 65 77 20 6c 73   1 import#new ls
4910: 68 69 66 74 20 6f 72 20 5d 4c 0a 20 20 20 20 61  hift or ]L.    a
4920: 6e 64 20 30 3d 20 49 46 20 20 32 64 72 6f 70 20  nd 0= IF  2drop 
4930: 22 5c 78 30 31 22 20 20 54 48 45 4e 0a 20 20 20  "\x01"  THEN.   
4940: 20 32 64 75 70 20 6b 65 2d 67 72 6f 75 70 73 20   2dup ke-groups 
4950: 24 21 20 67 72 6f 75 70 73 3e 6d 61 73 6b 20 6b  $! groups>mask k
4960: 65 2d 6d 61 73 6b 20 21 20 3b 0a 2b 6e 65 74 32  e-mask ! ;.+net2
4970: 6f 3a 20 2b 6b 65 79 73 69 67 20 28 20 24 3a 73  o: +keysig ( $:s
4980: 74 72 69 6e 67 20 2d 2d 20 29 20 20 21 21 75 6e  tring -- )  !!un
4990: 73 69 67 6e 65 64 3f 20 24 31 30 20 21 21 3e 3d  signed? $10 !!>=
49a0: 6f 72 64 65 72 3f 20 24 3e 20 6b 65 2d 73 69 67  order? $> ke-sig
49b0: 73 5b 5d 20 24 2b 5b 5d 21 20 3b 0a 20 20 20 20  s[] $+[]! ;.    
49c0: 5c 67 20 61 64 64 20 61 20 6b 65 79 20 73 69 67  \g add a key sig
49d0: 6e 61 74 75 72 65 0a 2b 6e 65 74 32 6f 3a 20 6b  nature.+net2o: k
49e0: 65 79 69 6d 70 6f 72 74 20 28 20 6e 20 2d 2d 20  eyimport ( n -- 
49f0: 29 20 20 20 20 20 20 20 21 21 75 6e 73 69 67 6e  )       !!unsign
4a00: 65 64 3f 20 24 31 30 20 21 21 3e 3d 6f 72 64 65  ed? $10 !!>=orde
4a10: 72 3f 0a 20 20 20 20 63 6f 6e 66 69 67 3a 70 77  r?.    config:pw
4a20: 2d 6c 65 76 65 6c 23 20 40 20 30 3c 20 49 46 20  -level# @ 0< IF 
4a30: 20 36 34 3e 6e 0a 09 64 75 70 20 5b 20 31 20 69   64>n..dup [ 1 i
4a40: 6d 70 6f 72 74 23 6e 65 77 20 6c 73 68 69 66 74  mport#new lshift
4a50: 20 5d 4c 20 61 6e 64 20 30 3d 20 49 46 0a 09 20   ]L and 0= IF.. 
4a60: 20 20 20 69 6d 70 6f 72 74 23 75 6e 74 72 75 73     import#untrus
4a70: 74 65 64 20 75 6d 69 6e 20 31 20 73 77 61 70 20  ted umin 1 swap 
4a80: 6c 73 68 69 66 74 20 5b 20 31 20 69 6d 70 6f 72  lshift [ 1 impor
4a90: 74 23 6e 65 77 20 6c 73 68 69 66 74 20 5d 4c 20  t#new lshift ]L 
4aa0: 6f 72 0a 09 45 4c 53 45 0a 09 20 20 20 20 5b 20  or..ELSE..    [ 
4ab0: 32 20 69 6d 70 6f 72 74 23 75 6e 74 72 75 73 74  2 import#untrust
4ac0: 65 64 20 6c 73 68 69 66 74 20 31 2d 20 31 20 69  ed lshift 1- 1 i
4ad0: 6d 70 6f 72 74 23 6e 65 77 20 6c 73 68 69 66 74  mport#new lshift
4ae0: 20 6f 72 20 5d 4c 20 61 6e 64 0a 09 54 48 45 4e   or ]L and..THEN
4af0: 0a 09 6b 65 2d 69 6d 70 6f 72 74 73 20 6f 72 21  ..ke-imports or!
4b00: 0a 20 20 20 20 45 4c 53 45 20 20 36 34 64 72 6f  .    ELSE  64dro
4b10: 70 20 20 54 48 45 4e 20 3b 0a 2b 6e 65 74 32 6f  p  THEN ;.+net2o
4b20: 3a 20 72 73 6b 6b 65 79 20 28 20 24 3a 73 74 72  : rskkey ( $:str
4b30: 69 6e 67 20 2d 2d 2d 20 29 0a 20 20 20 20 5c 67  ing --- ).    \g
4b40: 20 72 65 76 6f 6b 65 20 6b 65 79 2c 20 74 65 6d   revoke key, tem
4b50: 70 6f 72 61 72 69 6c 79 20 73 74 6f 72 65 64 0a  porarily stored.
4b60: 20 20 20 20 5c 20 64 6f 65 73 20 6e 6f 74 20 6e      \ does not n
4b70: 65 65 64 20 74 6f 20 62 65 20 73 69 67 6e 65 64  eed to be signed
4b80: 2c 20 74 68 65 20 72 65 76 6f 6b 65 20 6b 65 79  , the revoke key
4b90: 20 76 65 72 69 66 69 65 73 20 69 74 73 65 6c 66   verifies itself
4ba0: 0a 20 20 20 20 21 21 75 6e 73 69 67 6e 65 64 3f  .    !!unsigned?
4bb0: 20 24 38 30 20 21 21 3e 3d 6f 72 64 65 72 3f 0a   $80 !!>=order?.
4bc0: 20 20 20 20 24 3e 20 32 64 75 70 20 73 6b 72 65      $> 2dup skre
4bd0: 76 20 73 77 61 70 20 6b 65 79 7c 20 6d 6f 76 65  v swap key| move
4be0: 20 6b 65 2d 70 6b 20 24 40 20 64 72 6f 70 20 63   ke-pk $@ drop c
4bf0: 68 65 63 6b 2d 72 65 76 3f 20 30 3d 20 21 21 6e  heck-rev? 0= !!n
4c00: 6f 74 2d 6d 79 2d 72 65 76 73 6b 21 21 0a 20 20  ot-my-revsk!!.  
4c10: 20 20 70 6b 72 65 76 20 6b 65 79 73 69 7a 65 32    pkrev keysize2
4c20: 20 65 72 61 73 65 20 20 6b 65 2d 72 73 6b 20 73   erase  ke-rsk s
4c30: 65 63 21 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b 65  ec! ;.+net2o: ke
4c40: 79 70 65 74 20 28 20 24 3a 73 74 72 69 6e 67 20  ypet ( $:string 
4c50: 2d 2d 20 29 20 20 21 21 75 6e 73 69 67 6e 65 64  -- )  !!unsigned
4c60: 3f 20 20 24 3e 0a 20 20 20 20 63 6f 6e 66 69 67  ?  $>.    config
4c70: 3a 70 77 2d 6c 65 76 65 6c 23 20 40 20 30 3c 20  :pw-level# @ 0< 
4c80: 49 46 20 20 6b 65 2d 70 65 74 73 5b 5d 20 24 2b  IF  ke-pets[] $+
4c90: 5b 5d 21 20 70 65 74 21 20 20 45 4c 53 45 20 20  []! pet!  ELSE  
4ca0: 32 64 72 6f 70 20 20 54 48 45 4e 20 3b 0a 7d 73  2drop  THEN ;.}s
4cb0: 63 6f 70 65 0a 0a 67 65 6e 2d 74 61 62 6c 65 20  cope..gen-table 
4cc0: 24 66 72 65 65 7a 65 0a 27 20 63 6f 6e 74 65 78  $freeze.' contex
4cd0: 74 2d 74 61 62 6c 65 20 69 73 20 67 65 6e 2d 74  t-table is gen-t
4ce0: 61 62 6c 65 0a 0a 3a 20 6b 65 79 3a 6e 65 73 74  able..: key:nest
4cf0: 2d 73 69 67 20 28 20 61 64 64 72 20 75 20 2d 2d  -sig ( addr u --
4d00: 20 61 64 64 72 20 75 27 20 66 6c 61 67 20 29 0a   addr u' flag ).
4d10: 20 20 20 20 70 6b 32 2d 73 69 67 3f 20 64 75 70      pk2-sig? dup
4d20: 20 3f 45 58 49 54 20 64 72 6f 70 0a 20 20 20 20   ?EXIT drop.    
4d30: 32 64 75 70 20 2b 20 73 69 67 73 69 7a 65 23 20  2dup + sigsize# 
4d40: 2d 20 73 69 67 73 69 7a 65 23 20 3e 24 0a 20 20  - sigsize# >$.  
4d50: 20 20 73 69 67 70 6b 32 73 69 7a 65 23 20 2d 20    sigpk2size# - 
4d60: 32 64 75 70 20 2b 20 6b 65 79 73 69 7a 65 32 20  2dup + keysize2 
4d70: 6b 65 79 3f 6e 65 77 20 6e 3a 3e 6f 20 24 3e 20  key?new n:>o $> 
4d80: 6b 65 2d 73 65 6c 66 73 69 67 20 24 21 0a 20 20  ke-selfsig $!.  
4d90: 20 20 73 69 6d 2d 6e 69 63 6b 21 20 6f 66 66 20    sim-nick! off 
4da0: 63 2d 73 74 61 74 65 20 6f 66 66 20 73 69 67 2d  c-state off sig-
4db0: 6f 6b 20 3b 0a 27 20 6b 65 79 3a 6e 65 73 74 2d  ok ;.' key:nest-
4dc0: 73 69 67 20 6b 65 79 2d 65 6e 74 72 79 20 74 6f  sig key-entry to
4dd0: 20 6e 65 73 74 2d 73 69 67 0a 0a 73 61 6d 70 6c   nest-sig..sampl
4de0: 65 2d 6b 65 79 20 3e 6f 20 6b 65 79 2d 65 6e 74  e-key >o key-ent
4df0: 72 79 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65 6e  ry-table @ token
4e00: 2d 74 61 62 6c 65 20 21 20 6f 3e 0a 0a 3a 20 6b  -table ! o>..: k
4e10: 65 79 3a 63 6f 64 65 20 28 20 2d 2d 20 29 0a 20  ey:code ( -- ). 
4e20: 20 20 20 63 6f 64 65 2d 6b 65 79 20 20 63 6d 64     code-key  cmd
4e30: 6c 6f 63 6b 20 6c 6f 63 6b 0a 20 20 20 20 6b 65  lock lock.    ke
4e40: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
4e50: 6c 23 20 65 72 61 73 65 0a 20 20 20 20 63 6d 64  l# erase.    cmd
4e60: 72 65 73 65 74 20 69 6e 69 74 2d 72 65 70 6c 79  reset init-reply
4e70: 20 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65   also net2o-base
4e80: 20 3b 0a 63 6f 6d 70 3a 20 3a 2c 20 61 6c 73 6f   ;.comp: :, also
4e90: 20 6e 65 74 32 6f 2d 62 61 73 65 20 3b 0a 0a 73   net2o-base ;..s
4ea0: 63 6f 70 65 7b 20 6e 65 74 32 6f 2d 62 61 73 65  cope{ net2o-base
4eb0: 0a 0a 3a 20 65 6e 64 3a 6b 65 79 20 28 20 2d 2d  ..: end:key ( --
4ec0: 20 29 0a 20 20 20 20 65 6e 64 2d 77 69 74 68 20   ).    end-with 
4ed0: 70 72 65 76 69 6f 75 73 20 63 6d 64 6c 6f 63 6b  previous cmdlock
4ee0: 20 75 6e 6c 6f 63 6b 20 3b 0a 63 6f 6d 70 3a 20   unlock ;.comp: 
4ef0: 3a 2c 20 70 72 65 76 69 6f 75 73 20 3b 0a 0a 7d  :, previous ;..}
4f00: 73 63 6f 70 65 0a 0a 3a 20 6b 65 79 2d 63 72 79  scope..: key-cry
4f10: 70 74 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65  pt ( -- ).    ke
4f20: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
4f30: 6c 23 0a 20 20 20 20 3e 73 74 6f 72 65 6b 65 79  l#.    >storekey
4f40: 20 73 65 63 40 20 64 75 70 20 24 32 30 20 75 3c   sec@ dup $20 u<
4f50: 3d 20 5c 20 69 73 20 61 20 73 65 63 72 65 74 2c  = \ is a secret,
4f60: 20 6e 6f 20 6e 65 65 64 20 74 6f 20 62 65 20 73   no need to be s
4f70: 6c 6f 77 0a 20 20 20 20 49 46 20 20 65 6e 63 72  low.    IF  encr
4f80: 79 70 74 24 20 20 45 4c 53 45 20 20 63 6f 6e 66  ypt$  ELSE  conf
4f90: 69 67 3a 70 77 2d 6c 65 76 65 6c 23 20 40 20 65  ig:pw-level# @ e
4fa0: 6e 63 72 79 70 74 2d 70 77 24 20 20 54 48 45 4e  ncrypt-pw$  THEN
4fb0: 20 3b 0a 0a 30 20 56 61 6c 75 65 20 6b 65 79 2d   ;..0 Value key-
4fc0: 73 66 64 20 5c 20 73 65 63 72 65 74 20 6b 65 79  sfd \ secret key
4fd0: 73 0a 30 20 56 61 6c 75 65 20 6b 65 79 2d 70 66  s.0 Value key-pf
4fe0: 64 20 5c 20 70 75 62 6b 65 79 73 0a 0a 5c 20 6c  d \ pubkeys..\ l
4ff0: 65 67 61 63 79 20 66 6f 72 20 65 61 72 6c 79 20  egacy for early 
5000: 76 65 72 73 69 6f 6e 73 20 6f 66 20 6e 65 74 32  versions of net2
5010: 6f 20 70 72 69 6f 72 20 32 30 31 36 30 36 30 36  o prior 20160606
5020: 0a 0a 3a 20 6e 65 74 32 6f 3e 6b 65 79 73 20 7b  ..: net2o>keys {
5030: 20 61 64 64 72 20 75 20 2d 2d 20 7d 0a 20 20 20   addr u -- }.   
5040: 20 61 64 64 72 20 75 20 2e 6e 65 74 32 6f 2f 20   addr u .net2o/ 
5050: 20 61 64 64 72 20 75 20 2e 6b 65 79 73 2f 20 72   addr u .keys/ r
5060: 65 6e 61 6d 65 2d 66 69 6c 65 20 64 72 6f 70 20  ename-file drop 
5070: 3b 0a 3a 20 3f 6c 65 67 61 63 79 2d 6b 65 79 73  ;.: ?legacy-keys
5080: 20 28 20 66 6c 61 67 20 2d 2d 20 29 0a 20 20 20   ( flag -- ).   
5090: 20 5c 20 21 21 46 49 58 4d 45 21 21 20 6e 65 65   \ !!FIXME!! nee
50a0: 64 73 20 74 6f 20 62 65 20 72 65 6d 6f 76 65 64  ds to be removed
50b0: 20 77 68 65 6e 20 61 6c 6c 20 63 75 72 72 65 6e   when all curren
50c0: 74 20 75 73 65 72 73 0a 20 20 20 20 5c 20 68 61  t users.    \ ha
50d0: 76 65 20 6d 69 67 72 61 74 65 64 0a 20 20 20 20  ve migrated.    
50e0: 49 46 0a 09 22 70 75 62 6b 65 79 73 2e 6b 32 6f  IF.."pubkeys.k2o
50f0: 22 20 6e 65 74 32 6f 3e 6b 65 79 73 0a 09 22 73  " net2o>keys.."s
5100: 65 63 6b 65 79 73 2e 6b 32 6f 22 20 6e 65 74 32  eckeys.k2o" net2
5110: 6f 3e 6b 65 79 73 0a 20 20 20 20 54 48 45 4e 20  o>keys.    THEN 
5120: 3b 0a 0a 3a 20 67 65 6e 2d 6b 65 79 73 2d 64 69  ;..: gen-keys-di
5130: 72 20 28 20 2d 2d 20 29 0a 20 20 20 20 69 6e 69  r ( -- ).    ini
5140: 74 2d 64 69 72 73 20 3f 2e 6e 65 74 32 6f 2f 6b  t-dirs ?.net2o/k
5150: 65 79 73 20 3f 6c 65 67 61 63 79 2d 6b 65 79 73  eys ?legacy-keys
5160: 0a 20 20 20 20 67 72 6f 75 70 73 5b 5d 20 24 5b  .    groups[] $[
5170: 5d 23 20 30 3d 20 49 46 20 20 72 65 61 64 2d 67  ]# 0= IF  read-g
5180: 72 6f 75 70 73 20 20 54 48 45 4e 20 3b 0a 0a 3a  roups  THEN ;..:
5190: 20 3f 66 64 2d 6b 65 79 73 20 28 20 66 64 20 61   ?fd-keys ( fd a
51a0: 64 64 72 20 75 20 2d 2d 20 66 64 27 20 29 20 7b  ddr u -- fd' ) {
51b0: 20 61 64 64 72 20 75 20 7d 20 64 75 70 20 3f 45   addr u } dup ?E
51c0: 58 49 54 20 64 72 6f 70 0a 20 20 20 20 67 65 6e  XIT drop.    gen
51d0: 2d 6b 65 79 73 2d 64 69 72 0a 20 20 20 20 61 64  -keys-dir.    ad
51e0: 64 72 20 75 20 72 2f 77 20 6f 70 65 6e 2d 66 69  dr u r/w open-fi
51f0: 6c 65 20 64 75 70 20 6e 6f 2d 66 69 6c 65 23 20  le dup no-file# 
5200: 3d 20 49 46 0a 09 32 64 72 6f 70 20 61 64 64 72  = IF..2drop addr
5210: 20 75 20 72 2f 77 20 63 72 65 61 74 65 2d 66 69   u r/w create-fi
5220: 6c 65 0a 20 20 20 20 54 48 45 4e 20 20 74 68 72  le.    THEN  thr
5230: 6f 77 20 3b 0a 0a 3a 20 3f 6b 65 79 2d 73 66 64  ow ;..: ?key-sfd
5240: 20 28 20 2d 2d 20 66 64 20 29 0a 20 20 20 20 6b   ( -- fd ).    k
5250: 65 79 2d 73 66 64 20 22 73 65 63 6b 65 79 73 2e  ey-sfd "seckeys.
5260: 6b 32 6f 22 20 2e 6b 65 79 73 2f 20 3f 66 64 2d  k2o" .keys/ ?fd-
5270: 6b 65 79 73 20 64 75 70 20 74 6f 20 6b 65 79 2d  keys dup to key-
5280: 73 66 64 20 3b 0a 3a 20 3f 6b 65 79 2d 70 66 64  sfd ;.: ?key-pfd
5290: 20 28 20 2d 2d 20 66 64 20 29 0a 20 20 20 20 6b   ( -- fd ).    k
52a0: 65 79 2d 70 66 64 20 22 70 75 62 6b 65 79 73 2e  ey-pfd "pubkeys.
52b0: 6b 32 6f 22 20 2e 6b 65 79 73 2f 20 3f 66 64 2d  k2o" .keys/ ?fd-
52c0: 6b 65 79 73 20 64 75 70 20 74 6f 20 6b 65 79 2d  keys dup to key-
52d0: 70 66 64 20 3b 0a 0a 3a 20 6b 65 79 3e 73 66 69  pfd ;..: key>sfi
52e0: 6c 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65  le ( -- ).    ke
52f0: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
5300: 6c 23 20 3f 6b 65 79 2d 73 66 64 20 61 70 70 65  l# ?key-sfd appe
5310: 6e 64 2d 66 69 6c 65 20 6b 65 2d 6f 66 66 73 65  nd-file ke-offse
5320: 74 20 36 34 21 20 3b 0a 3a 20 6b 65 79 3e 70 66  t 64! ;.: key>pf
5330: 69 6c 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b  ile ( -- ).    k
5340: 65 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61  eypack keypack-a
5350: 6c 6c 23 20 3f 6b 65 79 2d 70 66 64 20 61 70 70  ll# ?key-pfd app
5360: 65 6e 64 2d 66 69 6c 65 20 6b 65 2d 6f 66 66 73  end-file ke-offs
5370: 65 74 20 36 34 21 20 3b 0a 0a 3a 20 6b 65 79 3e  et 64! ;..: key>
5380: 73 66 69 6c 65 40 70 6f 73 20 28 20 36 34 70 6f  sfile@pos ( 64po
5390: 73 20 2d 2d 20 29 20 36 34 64 75 70 20 36 34 23  s -- ) 64dup 64#
53a0: 2d 31 20 36 34 3d 20 49 46 20 20 36 34 64 72 6f  -1 64= IF  64dro
53b0: 70 20 6b 65 79 3e 73 66 69 6c 65 0a 20 20 20 20  p key>sfile.    
53c0: 45 4c 53 45 20 20 36 34 3e 72 20 6b 65 79 70 61  ELSE  64>r keypa
53d0: 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20  ck keypack-all# 
53e0: 36 34 72 3e 20 3f 6b 65 79 2d 73 66 64 20 77 72  64r> ?key-sfd wr
53f0: 69 74 65 40 70 6f 73 2d 66 69 6c 65 20 20 54 48  ite@pos-file  TH
5400: 45 4e 20 3b 0a 3a 20 6b 65 79 3e 70 66 69 6c 65  EN ;.: key>pfile
5410: 40 70 6f 73 20 28 20 36 34 70 6f 73 20 2d 2d 20  @pos ( 64pos -- 
5420: 29 20 36 34 64 75 70 20 36 34 23 2d 31 20 36 34  ) 64dup 64#-1 64
5430: 3d 20 49 46 20 20 36 34 64 72 6f 70 20 6b 65 79  = IF  64drop key
5440: 3e 70 66 69 6c 65 0a 20 20 20 20 45 4c 53 45 20  >pfile.    ELSE 
5450: 20 36 34 3e 72 20 6b 65 79 70 61 63 6b 20 6b 65   64>r keypack ke
5460: 79 70 61 63 6b 2d 61 6c 6c 23 20 36 34 72 3e 20  ypack-all# 64r> 
5470: 3f 6b 65 79 2d 70 66 64 20 77 72 69 74 65 40 70  ?key-pfd write@p
5480: 6f 73 2d 66 69 6c 65 20 20 54 48 45 4e 20 3b 0a  os-file  THEN ;.
5490: 0a 3a 20 72 6e 64 3e 73 66 69 6c 65 20 28 20 2d  .: rnd>sfile ( -
54a0: 2d 20 29 0a 20 20 20 20 6b 65 79 70 61 63 6b 20  - ).    keypack 
54b0: 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e  keypack-all# >rn
54c0: 67 24 20 6b 65 79 3e 73 66 69 6c 65 20 3b 0a 3a  g$ key>sfile ;.:
54d0: 20 72 6e 64 3e 70 66 69 6c 65 20 28 20 2d 2d 20   rnd>pfile ( -- 
54e0: 29 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b 65  ).    keypack ke
54f0: 79 70 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e 67 24  ypack-all# >rng$
5500: 20 6b 65 79 3e 70 66 69 6c 65 20 3b 0a 0a 5c 20   key>pfile ;..\ 
5510: 6b 65 79 20 67 65 6e 65 72 61 74 69 6f 6e 0a 5c  key generation.\
5520: 20 66 6f 72 20 72 65 70 72 6f 64 75 63 69 62 69   for reproducibi
5530: 6c 69 74 79 20 6f 66 20 74 68 65 20 73 65 6c 66  lity of the self
5540: 73 69 67 2c 20 61 6c 77 61 79 73 20 75 73 65 20  sig, always use 
5550: 74 68 65 20 73 61 6d 65 20 6f 72 64 65 72 3a 0a  the same order:.
5560: 5c 20 22 70 75 62 6b 65 79 22 20 6e 65 77 6b 65  \ "pubkey" newke
5570: 79 20 3c 6e 3e 20 6b 65 79 74 79 70 65 20 22 6e  y <n> keytype "n
5580: 69 63 6b 22 20 6b 65 79 6e 69 63 6b 20 22 73 69  ick" keynick "si
5590: 67 22 20 6b 65 79 73 65 6c 66 73 69 67 0a 0a 55  g" keyselfsig..U
55a0: 73 65 72 20 70 6b 2b 73 69 67 24 0a 0a 6b 65 79  ser pk+sig$..key
55b0: 73 69 7a 65 32 20 43 6f 6e 73 74 61 6e 74 20 70  size2 Constant p
55c0: 6b 72 6b 23 0a 0a 3a 20 5d 70 6b 2b 73 69 67 6e  krk#..: ]pk+sign
55d0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 2b   ( addr u -- ) +
55e0: 63 6d 64 62 75 66 20 5d 73 69 67 6e 20 3b 0a 0a  cmdbuf ]sign ;..
55f0: 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a  also net2o-base.
5600: 3a 20 70 61 63 6b 2d 63 6f 72 65 20 28 20 6f 3a  : pack-core ( o:
5610: 6b 65 79 20 2d 2d 20 29 20 5c 20 63 6f 72 65 20  key -- ) \ core 
5620: 77 69 74 68 6f 75 74 20 6b 65 79 0a 20 20 20 20  without key.    
5630: 6b 65 2d 74 79 70 65 20 40 20 75 6c 69 74 2c 20  ke-type @ ulit, 
5640: 6b 65 79 74 79 70 65 0a 20 20 20 20 6b 65 2d 6e  keytype.    ke-n
5650: 69 63 6b 20 24 40 20 24 2c 20 6b 65 79 6e 69 63  ick $@ $, keynic
5660: 6b 0a 20 20 20 20 6b 65 2d 70 72 6f 66 20 24 40  k.    ke-prof $@
5670: 20 64 75 70 20 49 46 20 20 24 2c 20 6b 65 79 70   dup IF  $, keyp
5680: 72 6f 66 69 6c 65 20 20 45 4c 53 45 20 20 32 64  rofile  ELSE  2d
5690: 72 6f 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 70  rop  THEN ;..: p
56a0: 61 63 6b 2d 73 69 67 6e 6b 65 79 20 28 20 6f 3a  ack-signkey ( o:
56b0: 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 73 69 67  key -- ).    sig
56c0: 6e 5b 0a 20 20 20 20 70 61 63 6b 2d 63 6f 72 65  n[.    pack-core
56d0: 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 2b 63  .    ke-pk $@ +c
56e0: 6d 64 62 75 66 0a 20 20 20 20 6b 65 2d 73 65 6c  mdbuf.    ke-sel
56f0: 66 73 69 67 20 24 40 20 2b 63 6d 64 62 75 66 20  fsig $@ +cmdbuf 
5700: 63 6d 64 2d 72 65 73 6f 6c 76 65 3e 20 32 64 72  cmd-resolve> 2dr
5710: 6f 70 20 6e 65 73 74 73 69 67 20 3b 0a 0a 3a 20  op nestsig ;..: 
5720: 70 61 63 6b 2d 63 6f 72 65 6b 65 79 20 28 20 6f  pack-corekey ( o
5730: 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 70 61  :key -- ).    pa
5740: 63 6b 2d 73 69 67 6e 6b 65 79 0a 20 20 20 20 6b  ck-signkey.    k
5750: 65 2d 69 6d 70 6f 72 74 73 20 40 20 75 6c 69 74  e-imports @ ulit
5760: 2c 20 6b 65 79 69 6d 70 6f 72 74 0a 20 20 20 20  , keyimport.    
5770: 6b 65 2d 6d 61 73 6b 20 40 20 20 6b 65 2d 67 72  ke-mask @  ke-gr
5780: 6f 75 70 73 20 24 40 6c 65 6e 20 49 46 0a 09 6b  oups $@len IF..k
5790: 65 2d 67 72 6f 75 70 73 20 24 40 20 32 64 75 70  e-groups $@ 2dup
57a0: 20 24 2c 20 6b 65 79 67 72 6f 75 70 73 0a 09 67   $, keygroups..g
57b0: 72 6f 75 70 73 3e 6d 61 73 6b 20 69 6e 76 65 72  roups>mask inver
57c0: 74 20 61 6e 64 20 20 54 48 45 4e 0a 20 20 20 20  t and  THEN.    
57d0: 3f 64 75 70 2d 49 46 20 20 6e 6c 69 74 2c 20 6b  ?dup-IF  nlit, k
57e0: 65 79 6d 61 73 6b 20 20 54 48 45 4e 0a 20 20 20  eymask  THEN.   
57f0: 20 6b 65 2d 70 65 74 73 5b 5d 20 5b 3a 20 24 2c   ke-pets[] [: $,
5800: 20 6b 65 79 70 65 74 20 3b 5d 20 24 5b 5d 6d 61   keypet ;] $[]ma
5810: 70 0a 20 20 20 20 6b 65 2d 73 74 6f 72 65 6b 65  p.    ke-storeke
5820: 79 20 40 20 3e 73 74 6f 72 65 6b 65 79 20 21 20  y @ >storekey ! 
5830: 3b 0a 70 72 65 76 69 6f 75 73 0a 0a 3a 20 70 61  ;.previous..: pa
5840: 63 6b 2d 70 75 62 6b 65 79 20 28 20 6f 3a 6b 65  ck-pubkey ( o:ke
5850: 79 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 3a 63  y -- ).    key:c
5860: 6f 64 65 0a 20 20 20 20 20 20 70 61 63 6b 2d 63  ode.      pack-c
5870: 6f 72 65 6b 65 79 0a 20 20 20 20 65 6e 64 3a 6b  orekey.    end:k
5880: 65 79 20 3b 0a 3a 20 70 61 63 6b 2d 6f 75 74 6b  ey ;.: pack-outk
5890: 65 79 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a  ey ( o:key -- ).
58a0: 20 20 20 20 6b 65 79 3a 63 6f 64 65 0a 20 20 20      key:code.   
58b0: 20 20 20 22 6e 32 6f 22 20 6e 65 74 32 6f 2d 62     "n2o" net2o-b
58c0: 61 73 65 3a 34 63 63 2c 0a 20 20 20 20 20 20 70  ase:4cc,.      p
58d0: 61 63 6b 2d 73 69 67 6e 6b 65 79 0a 20 20 20 20  ack-signkey.    
58e0: 65 6e 64 3a 6b 65 79 20 3b 0a 3a 20 70 61 63 6b  end:key ;.: pack
58f0: 2d 73 65 63 6b 65 79 20 28 20 6f 3a 6b 65 79 20  -seckey ( o:key 
5900: 2d 2d 20 29 0a 20 20 20 20 6b 65 79 3a 63 6f 64  -- ).    key:cod
5910: 65 0a 20 20 20 20 20 20 70 61 63 6b 2d 63 6f 72  e.      pack-cor
5920: 65 6b 65 79 0a 20 20 20 20 20 20 6b 65 2d 73 6b  ekey.      ke-sk
5930: 20 73 65 63 40 20 73 65 63 24 2c 20 70 72 69 76   sec@ sec$, priv
5940: 6b 65 79 0a 20 20 20 20 20 20 6b 65 2d 72 73 6b  key.      ke-rsk
5950: 20 73 65 63 40 20 64 75 70 20 49 46 20 20 73 65   sec@ dup IF  se
5960: 63 24 2c 20 72 73 6b 6b 65 79 20 20 45 4c 53 45  c$, rskkey  ELSE
5970: 20 20 32 64 72 6f 70 20 20 54 48 45 4e 0a 20 20    2drop  THEN.  
5980: 20 20 65 6e 64 3a 6b 65 79 20 3b 0a 3a 20 6b 65    end:key ;.: ke
5990: 79 6e 69 63 6b 24 20 28 20 6f 3a 6b 65 79 20 2d  ynick$ ( o:key -
59a0: 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 5c  - addr u ).    \
59b0: 47 20 67 65 74 20 74 68 65 20 61 6e 6e 6f 74 61  G get the annota
59c0: 74 69 6f 6e 73 20 77 69 74 68 20 73 69 67 6e 61  tions with signa
59d0: 74 75 72 65 0a 20 20 20 20 5b 27 5d 20 70 61 63  ture.    ['] pac
59e0: 6b 2d 63 6f 72 65 20 67 65 6e 2d 63 6d 64 24 20  k-core gen-cmd$ 
59f0: 32 64 72 6f 70 0a 20 20 20 20 6b 65 2d 73 65 6c  2drop.    ke-sel
5a00: 66 73 69 67 20 24 40 20 74 6d 70 24 20 24 2b 21  fsig $@ tmp$ $+!
5a10: 20 74 6d 70 24 20 24 40 20 3b 0a 3a 20 6b 65 79   tmp$ $@ ;.: key
5a20: 70 6b 32 6e 69 63 6b 24 20 28 20 6f 3a 6b 65 79  pk2nick$ ( o:key
5a30: 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20   -- addr u ).   
5a40: 20 5c 47 20 67 65 74 20 74 68 65 20 61 6e 6e 6f   \G get the anno
5a50: 74 61 74 69 6f 6e 73 20 77 69 74 68 20 73 69 67  tations with sig
5a60: 6e 61 74 75 72 65 0a 20 20 20 20 5b 27 5d 20 70  nature.    ['] p
5a70: 61 63 6b 2d 63 6f 72 65 20 67 65 6e 2d 63 6d 64  ack-core gen-cmd
5a80: 24 20 32 64 72 6f 70 0a 20 20 20 20 6b 65 2d 70  $ 2drop.    ke-p
5a90: 6b 20 24 40 20 74 6d 70 24 20 24 2b 21 20 6b 65  k $@ tmp$ $+! ke
5aa0: 2d 73 65 6c 66 73 69 67 20 24 40 20 74 6d 70 24  -selfsig $@ tmp$
5ab0: 20 24 2b 21 20 74 6d 70 24 20 24 40 20 3b 0a 3a   $+! tmp$ $@ ;.:
5ac0: 20 6d 79 6e 69 63 6b 2d 6b 65 79 20 28 20 2d 2d   mynick-key ( --
5ad0: 20 6f 20 29 0a 20 20 20 20 70 6b 40 20 6b 65 79   o ).    pk@ key
5ae0: 7c 20 6b 65 79 23 20 23 40 20 64 72 6f 70 20 63  | key# #@ drop c
5af0: 65 6c 6c 2b 20 3b 0a 3a 20 6d 79 6e 69 63 6b 24  ell+ ;.: mynick$
5b00: 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20   ( -- addr u ). 
5b10: 20 20 20 5c 47 20 67 65 74 20 6d 79 20 6e 69 63     \G get my nic
5b20: 6b 20 77 69 74 68 20 73 69 67 6e 61 74 75 72 65  k with signature
5b30: 0a 20 20 20 20 6d 79 6e 69 63 6b 2d 6b 65 79 20  .    mynick-key 
5b40: 2e 6b 65 79 6e 69 63 6b 24 20 3b 0a 3a 20 6d 79  .keynick$ ;.: my
5b50: 70 6b 32 6e 69 63 6b 24 20 28 20 6f 3a 6b 65 79  pk2nick$ ( o:key
5b60: 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20   -- addr u ).   
5b70: 20 5c 47 20 67 65 74 20 6d 79 20 6e 69 63 6b 20   \G get my nick 
5b80: 77 69 74 68 20 73 69 67 6e 61 74 75 72 65 0a 20  with signature. 
5b90: 20 20 20 6d 79 6e 69 63 6b 2d 6b 65 79 20 2e 6b     mynick-key .k
5ba0: 65 79 70 6b 32 6e 69 63 6b 24 20 3b 0a 3a 20 6b  eypk2nick$ ;.: k
5bb0: 65 79 2d 73 69 67 6e 20 28 20 6f 3a 6b 65 79 20  ey-sign ( o:key 
5bc0: 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20 20 20 5b  -- o:key ).    [
5bd0: 27 5d 20 70 61 63 6b 2d 63 6f 72 65 20 67 65 6e  '] pack-core gen
5be0: 2d 63 6d 64 24 0a 20 20 20 20 5b 3a 20 74 79 70  -cmd$.    [: typ
5bf0: 65 20 6b 65 2d 70 6b 20 24 40 20 74 79 70 65 20  e ke-pk $@ type 
5c00: 3b 5d 20 24 74 6d 70 0a 20 20 20 20 6e 6f 77 3e  ;] $tmp.    now>
5c10: 6e 65 76 65 72 20 63 3a 30 6b 65 79 20 63 3a 68  never c:0key c:h
5c20: 61 73 68 20 5b 27 5d 20 2e 73 69 67 20 24 74 6d  ash ['] .sig $tm
5c30: 70 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 21 20  p ke-selfsig $! 
5c40: 3b 0a 0a 56 61 72 69 61 62 6c 65 20 63 70 2d 74  ;..Variable cp-t
5c50: 6d 70 0a 0a 3a 20 73 61 76 65 2d 70 75 62 6b 65  mp..: save-pubke
5c60: 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65  ys ( -- ).    ke
5c70: 79 2d 70 66 64 20 3f 64 75 70 2d 49 46 20 20 63  y-pfd ?dup-IF  c
5c80: 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 20  lose-file throw 
5c90: 20 54 48 45 4e 0a 20 20 20 20 22 70 75 62 6b 65   THEN.    "pubke
5ca0: 79 73 2e 6b 32 6f 22 20 2e 6b 65 79 73 2f 20 5b  ys.k2o" .keys/ [
5cb0: 3a 20 74 6f 20 6b 65 79 2d 70 66 64 0a 20 20 20  : to key-pfd.   
5cc0: 20 20 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b     key# [: cell+
5cd0: 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e   $@ drop cell+ >
5ce0: 6f 0a 09 6b 65 2d 73 6b 20 73 65 63 40 20 64 30  o..ke-sk sec@ d0
5cf0: 3d 20 49 46 20 20 70 61 63 6b 2d 70 75 62 6b 65  = IF  pack-pubke
5d00: 79 0a 09 20 20 20 20 66 6c 75 73 68 28 20 2e 22  y..    flush( ."
5d10: 20 73 61 76 69 6e 67 20 22 20 2e 6e 69 63 6b 20   saving " .nick 
5d20: 66 6f 72 74 68 3a 63 72 20 29 0a 09 20 20 20 20  forth:cr )..    
5d30: 6b 65 79 2d 63 72 79 70 74 20 6b 65 2d 6f 66 66  key-crypt ke-off
5d40: 73 65 74 20 36 34 40 20 6b 65 79 3e 70 66 69 6c  set 64@ key>pfil
5d50: 65 40 70 6f 73 0a 09 54 48 45 4e 20 6f 3e 20 3b  e@pos..THEN o> ;
5d60: 5d 20 23 6d 61 70 0a 20 20 20 20 30 20 74 6f 20  ] #map.    0 to 
5d70: 6b 65 79 2d 70 66 64 20 3b 5d 20 73 61 76 65 2d  key-pfd ;] save-
5d80: 66 69 6c 65 20 20 3f 6b 65 79 2d 70 66 64 20 64  file  ?key-pfd d
5d90: 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65 2d 73 65  rop ;..: save-se
5da0: 63 6b 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20  ckeys ( -- ).   
5db0: 20 6b 65 79 2d 73 66 64 20 3f 64 75 70 2d 49 46   key-sfd ?dup-IF
5dc0: 20 20 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72    close-file thr
5dd0: 6f 77 20 20 54 48 45 4e 0a 20 20 20 20 22 73 65  ow  THEN.    "se
5de0: 63 6b 65 79 73 2e 6b 32 6f 22 20 2e 6b 65 79 73  ckeys.k2o" .keys
5df0: 2f 20 5b 3a 20 74 6f 20 6b 65 79 2d 73 66 64 0a  / [: to key-sfd.
5e00: 20 20 20 20 20 20 6b 65 79 23 20 5b 3a 20 63 65        key# [: ce
5e10: 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c  ll+ $@ drop cell
5e20: 2b 20 3e 6f 0a 09 6b 65 2d 73 6b 20 73 65 63 40  + >o..ke-sk sec@
5e30: 20 64 30 3c 3e 20 49 46 20 20 70 61 63 6b 2d 73   d0<> IF  pack-s
5e40: 65 63 6b 65 79 0a 09 20 20 20 20 63 6f 6e 66 69  eckey..    confi
5e50: 67 3a 70 77 2d 6c 65 76 65 6c 23 20 40 20 3e 72  g:pw-level# @ >r
5e60: 20 20 6b 65 2d 70 77 6c 65 76 65 6c 20 40 20 63    ke-pwlevel @ c
5e70: 6f 6e 66 69 67 3a 70 77 2d 6c 65 76 65 6c 23 20  onfig:pw-level# 
5e80: 21 0a 09 20 20 20 20 6b 65 79 2d 63 72 79 70 74  !..    key-crypt
5e90: 20 6b 65 2d 6f 66 66 73 65 74 20 36 34 40 20 6b   ke-offset 64@ k
5ea0: 65 79 3e 73 66 69 6c 65 40 70 6f 73 0a 09 20 20  ey>sfile@pos..  
5eb0: 20 20 72 3e 20 63 6f 6e 66 69 67 3a 70 77 2d 6c    r> config:pw-l
5ec0: 65 76 65 6c 23 20 21 0a 09 54 48 45 4e 20 6f 3e  evel# !..THEN o>
5ed0: 20 3b 5d 20 23 6d 61 70 0a 20 20 20 20 30 20 74   ;] #map.    0 t
5ee0: 6f 20 6b 65 79 2d 73 66 64 20 3b 5d 20 73 61 76  o key-sfd ;] sav
5ef0: 65 2d 66 69 6c 65 20 20 3f 6b 65 79 2d 73 66 64  e-file  ?key-sfd
5f00: 20 64 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65 2d   drop ;..: save-
5f10: 6b 65 79 73 20 28 20 2d 2d 20 29 20 20 3f 2e 6e  keys ( -- )  ?.n
5f20: 65 74 32 6f 2f 6b 65 79 73 0a 20 20 20 20 73 61  et2o/keys.    sa
5f30: 76 65 2d 70 75 62 6b 65 79 73 20 73 61 76 65 2d  ve-pubkeys save-
5f40: 73 65 63 6b 65 79 73 20 3b 0a 0a 5c 20 72 65 73  seckeys ;..\ res
5f50: 70 6f 6e 64 20 74 6f 20 73 63 61 6e 6e 69 6e 67  pond to scanning
5f60: 20 6b 65 79 73 0a 0a 74 72 75 65 20 56 61 6c 75   keys..true Valu
5f70: 65 20 73 63 61 6e 2d 6f 6e 63 65 3f 0a 0a 3a 20  e scan-once?..: 
5f80: 73 63 61 6e 6e 65 64 2d 6b 65 79 20 28 20 61 64  scanned-key ( ad
5f90: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 2e 22  dr u -- ).    ."
5fa0: 20 73 63 61 6e 6e 65 64 20 22 20 20 32 64 75 70   scanned "  2dup
5fb0: 20 2e 6b 65 79 2d 69 64 20 63 72 0a 20 20 20 20   .key-id cr.    
5fc0: 6b 65 79 7c 20 6b 65 79 23 20 23 40 20 49 46 0a  key| key# #@ IF.
5fd0: 09 63 65 6c 6c 2b 20 3e 6f 20 5b 20 31 20 69 6d  .cell+ >o [ 1 im
5fe0: 70 6f 72 74 23 73 63 61 6e 20 6c 73 68 69 66 74  port#scan lshift
5ff0: 20 5d 4c 20 6b 65 2d 69 6d 70 6f 72 74 73 20 6f   ]L ke-imports o
6000: 72 21 20 2e 6b 65 79 2d 6c 69 73 74 20 63 72 20  r! .key-list cr 
6010: 6f 3e 0a 09 73 61 76 65 2d 6b 65 79 73 0a 09 5b  o>..save-keys..[
6020: 49 46 44 45 46 5d 20 61 6e 64 72 6f 69 64 20 5b  IFDEF] android [
6030: 20 61 6c 73 6f 20 61 6e 64 72 6f 69 64 20 5d 0a   also android ].
6040: 09 20 20 20 20 6c 65 76 65 6c 23 20 40 20 30 3e  .    level# @ 0>
6050: 20 73 63 61 6e 2d 6f 6e 63 65 3f 20 61 6e 64 20   scan-once? and 
6060: 6c 65 76 65 6c 23 20 2b 21 20 20 5b 20 70 72 65  level# +!  [ pre
6070: 76 69 6f 75 73 20 5d 0a 09 5b 54 48 45 4e 5d 0a  vious ]..[THEN].
6080: 20 20 20 20 45 4c 53 45 20 20 64 72 6f 70 20 20      ELSE  drop  
6090: 54 48 45 4e 20 3b 0a 0a 5c 20 67 65 6e 65 72 61  THEN ;..\ genera
60a0: 74 65 20 6b 65 79 73 0a 0a 3a 20 73 6b 73 69 67  te keys..: sksig
60b0: 21 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d  ! ( -- ).    ke-
60c0: 70 6b 20 24 40 20 6b 65 2d 73 6b 20 73 65 63 40  pk $@ ke-sk sec@
60d0: 20 63 3a 30 6b 65 79 20 3e 6b 65 79 65 64 2d 68   c:0key >keyed-h
60e0: 61 73 68 20 6b 65 79 70 61 64 20 24 32 30 20 6b  ash keypad $20 k
60f0: 65 63 63 61 6b 3e 0a 20 20 20 20 6b 65 79 70 61  eccak>.    keypa
6100: 64 20 6b 65 79 73 69 7a 65 20 6b 65 2d 73 6b 73  d keysize ke-sks
6110: 69 67 20 73 65 63 21 20 3b 0a 0a 3a 20 2b 67 65  ig sec! ;..: +ge
6120: 6e 2d 6b 65 79 73 20 28 20 6e 69 63 6b 20 75 20  n-keys ( nick u 
6130: 74 79 70 65 20 2d 2d 20 29 0a 20 20 20 20 67 65  type -- ).    ge
6140: 6e 2d 6b 65 79 73 20 20 36 34 23 2d 31 20 6b 65  n-keys  64#-1 ke
6150: 79 2d 72 65 61 64 2d 6f 66 66 73 65 74 20 36 34  y-read-offset 64
6160: 21 20 20 70 6b 63 20 6b 65 79 73 69 7a 65 32 20  !  pkc keysize2 
6170: 6b 65 79 3a 6e 65 77 20 3e 6f 0a 20 20 20 20 5b  key:new >o.    [
6180: 20 31 20 69 6d 70 6f 72 74 23 73 65 6c 66 20 6c   1 import#self l
6190: 73 68 69 66 74 20 31 20 69 6d 70 6f 72 74 23 6e  shift 1 import#n
61a0: 65 77 20 6c 73 68 69 66 74 20 6f 72 20 5d 4c 20  ew lshift or ]L 
61b0: 6b 65 2d 69 6d 70 6f 72 74 73 20 21 0a 20 20 20  ke-imports !.   
61c0: 20 6b 65 2d 74 79 70 65 20 21 20 20 6b 65 2d 6e   ke-type !  ke-n
61d0: 69 63 6b 20 24 21 20 20 6e 69 63 6b 21 0a 20 20  ick $!  nick!.  
61e0: 20 20 63 6f 6e 66 69 67 3a 70 77 2d 6c 65 76 65    config:pw-leve
61f0: 6c 23 20 40 20 6b 65 2d 70 77 6c 65 76 65 6c 20  l# @ ke-pwlevel 
6200: 21 20 20 70 65 72 6d 25 6d 79 73 65 6c 66 20 6b  !  perm%myself k
6210: 65 2d 6d 61 73 6b 20 21 0a 20 20 20 20 73 6b 63  e-mask !.    skc
6220: 20 6b 65 79 73 69 7a 65 20 6b 65 2d 73 6b 20 73   keysize ke-sk s
6230: 65 63 21 20 20 2b 73 65 63 6b 65 79 0a 20 20 20  ec!  +seckey.   
6240: 20 73 6b 72 65 76 20 6b 65 79 73 69 7a 65 20 6b   skrev keysize k
6250: 65 2d 72 73 6b 20 73 65 63 21 0a 20 20 20 20 73  e-rsk sec!.    s
6260: 6b 73 69 67 21 20 6b 65 79 2d 73 69 67 6e 20 6f  ksig! key-sign o
6270: 3e 20 3b 0a 0a 24 34 30 20 62 75 66 66 65 72 3a  > ;..$40 buffer:
6280: 20 6e 69 63 6b 2d 62 75 66 0a 0a 3a 20 67 65 74   nick-buf..: get
6290: 2d 6e 69 63 6b 20 28 20 2d 2d 20 61 64 64 72 20  -nick ( -- addr 
62a0: 75 20 29 0a 20 20 20 20 2e 22 20 6e 69 63 6b 3a  u ).    ." nick:
62b0: 20 22 20 6e 69 63 6b 2d 62 75 66 20 24 34 30 20   " nick-buf $40 
62c0: 61 63 63 65 70 74 20 6e 69 63 6b 2d 62 75 66 20  accept nick-buf 
62d0: 73 77 61 70 20 2d 74 72 61 69 6c 69 6e 67 20 63  swap -trailing c
62e0: 72 20 3b 0a 0a 66 61 6c 73 65 20 76 61 6c 75 65  r ;..false value
62f0: 20 3f 79 65 73 0a 3a 20 79 65 73 3f 20 28 20 61   ?yes.: yes? ( a
6300: 64 64 72 20 75 20 2d 2d 20 66 6c 61 67 20 29 0a  ddr u -- flag ).
6310: 20 20 20 20 3f 79 65 73 20 49 46 20 20 32 64 72      ?yes IF  2dr
6320: 6f 70 20 74 72 75 65 20 20 45 4c 53 45 20 20 74  op true  ELSE  t
6330: 79 70 65 20 2e 22 20 20 28 79 2f 4e 29 22 20 6b  ype ."  (y/N)" k
6340: 65 79 20 63 72 20 27 79 27 20 3d 20 20 54 48 45  ey cr 'y' =  THE
6350: 4e 20 3b 0a 0a 3a 20 3f 72 73 6b 20 28 20 2d 2d  N ;..: ?rsk ( --
6360: 20 29 0a 20 20 20 20 70 6b 40 20 6b 65 79 7c 20   ).    pk@ key| 
6370: 6b 65 79 2d 65 78 69 73 74 3f 20 64 75 70 20 30  key-exist? dup 0
6380: 3d 20 49 46 20 20 64 72 6f 70 20 20 45 58 49 54  = IF  drop  EXIT
6390: 20 20 54 48 45 4e 0a 20 20 20 20 3e 6f 20 6b 65    THEN.    >o ke
63a0: 2d 72 73 6b 20 73 65 63 40 20 64 75 70 20 30 3d  -rsk sec@ dup 0=
63b0: 20 49 46 20 20 32 64 72 6f 70 20 6f 3e 20 20 45   IF  2drop o>  E
63c0: 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 2e 22  XIT  THEN.    ."
63d0: 20 59 6f 75 20 73 74 69 6c 6c 20 68 61 76 65 6e   You still haven
63e0: 27 74 20 73 74 6f 72 65 64 20 79 6f 75 72 20 72  't stored your r
63f0: 65 76 6f 6b 65 20 6b 65 79 20 73 65 63 75 72 65  evoke key secure
6400: 6c 79 20 6f 66 66 2d 6c 69 6e 65 2e 22 20 63 72  ly off-line." cr
6410: 0a 20 20 20 20 73 22 20 50 61 70 65 72 20 61 6e  .    s" Paper an
6420: 64 20 70 65 6e 63 69 6c 20 72 65 61 64 79 3f 22  d pencil ready?"
6430: 20 79 65 73 3f 20 49 46 0a 09 2e 73 74 72 69 70   yes? IF...strip
6440: 65 38 35 0a 09 73 22 20 57 72 69 74 74 65 6e 20  e85..s" Written 
6450: 64 6f 77 6e 3f 22 20 79 65 73 3f 20 49 46 0a 09  down?" yes? IF..
6460: 20 20 20 20 73 22 20 59 6f 75 20 77 6f 6e 27 74      s" You won't
6470: 20 73 65 65 20 74 68 69 73 20 61 67 61 69 6e 21   see this again!
6480: 20 44 65 6c 65 74 65 3f 22 20 79 65 73 3f 0a 09   Delete?" yes?..
6490: 20 20 20 20 49 46 20 6b 65 2d 72 73 6b 20 73 65      IF ke-rsk se
64a0: 63 2d 6f 66 66 20 20 73 61 76 65 2d 6b 65 79 73  c-off  save-keys
64b0: 0a 09 09 2e 22 20 72 65 76 6f 6b 65 20 6b 65 79  ...." revoke key
64c0: 20 64 65 6c 65 74 65 64 2e 22 20 63 72 20 6f 3e   deleted." cr o>
64d0: 20 20 45 58 49 54 20 20 54 48 45 4e 20 20 54 48    EXIT  THEN  TH
64e0: 45 4e 0a 20 20 20 20 45 4c 53 45 20 20 32 64 72  EN.    ELSE  2dr
64f0: 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 2e 22 20  op  THEN.    ." 
6500: 49 27 6d 20 6b 65 65 70 69 6e 67 20 79 6f 75 72  I'm keeping your
6510: 20 72 65 76 6f 6b 65 20 6b 65 79 2e 20 20 54 68   revoke key.  Th
6520: 69 73 20 77 69 6c 6c 20 73 68 6f 77 20 75 70 20  is will show up 
6530: 61 67 61 69 6e 2e 22 20 63 72 20 6f 3e 20 3b 0a  again." cr o> ;.
6540: 0a 5c 20 72 65 61 64 20 6b 65 79 20 66 69 6c 65  .\ read key file
6550: 0a 0a 3a 20 74 72 79 2d 64 65 63 72 79 70 74 2d  ..: try-decrypt-
6560: 6b 65 79 20 28 20 6b 65 79 20 75 31 20 2d 2d 20  key ( key u1 -- 
6570: 61 64 64 72 20 75 32 20 66 6c 61 67 20 29 0a 20  addr u2 flag ). 
6580: 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79 70 61     keypack keypa
6590: 63 6b 2d 64 20 6b 65 79 70 61 63 6b 2d 61 6c 6c  ck-d keypack-all
65a0: 23 20 6d 6f 76 65 0a 20 20 20 20 6b 65 79 70 61  # move.    keypa
65b0: 63 6b 2d 64 20 6b 65 79 70 61 63 6b 2d 61 6c 6c  ck-d keypack-all
65c0: 23 20 32 73 77 61 70 0a 20 20 20 20 64 75 70 20  # 2swap.    dup 
65d0: 24 32 30 20 3d 20 49 46 20 20 64 65 63 72 79 70  $20 = IF  decryp
65e0: 74 24 20 20 45 4c 53 45 0a 09 6b 65 79 70 61 63  t$  ELSE..keypac
65f0: 6b 20 63 40 20 24 46 20 61 6e 64 20 63 6f 6e 66  k c@ $F and conf
6600: 69 67 3a 70 77 2d 6d 61 78 6c 65 76 65 6c 23 20  ig:pw-maxlevel# 
6610: 40 20 3c 3d 0a 09 49 46 20 20 64 65 63 72 79 70  @ <=..IF  decryp
6620: 74 2d 70 77 24 20 20 45 4c 53 45 20 20 32 64 72  t-pw$  ELSE  2dr
6630: 6f 70 20 66 61 6c 73 65 20 20 54 48 45 4e 0a 20  op false  THEN. 
6640: 20 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 74 72 79     THEN ;..: try
6650: 2d 64 65 63 72 79 70 74 20 28 20 66 6c 61 67 20  -decrypt ( flag 
6660: 2d 2d 20 61 64 64 72 20 75 20 2f 20 30 20 30 20  -- addr u / 0 0 
6670: 29 20 7b 20 66 6c 61 67 20 7d 0a 20 20 20 20 6b  ) { flag }.    k
6680: 65 79 73 20 24 5b 5d 23 20 30 20 3f 44 4f 0a 09  eys $[]# 0 ?DO..
6690: 49 20 6b 65 79 73 20 73 65 63 5b 5d 40 20 64 75  I keys sec[]@ du
66a0: 70 20 6b 65 79 73 69 7a 65 20 3d 20 66 6c 61 67  p keysize = flag
66b0: 20 78 6f 72 20 49 46 0a 09 20 20 20 20 74 72 79   xor IF..    try
66c0: 2d 64 65 63 72 79 70 74 2d 6b 65 79 20 49 46 0a  -decrypt-key IF.
66d0: 09 09 49 20 6b 65 79 73 20 24 5b 5d 20 40 20 64  ..I keys $[] @ d
66e0: 75 70 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 64  up >storekey ! d
66f0: 65 66 61 75 6c 74 6b 65 79 20 21 0a 09 09 75 6e  efaultkey !...un
6700: 6c 6f 6f 70 20 20 45 58 49 54 20 20 54 48 45 4e  loop  EXIT  THEN
6710: 20 20 54 48 45 4e 0a 09 32 64 72 6f 70 0a 20 20    THEN..2drop.  
6720: 20 20 4c 4f 4f 50 20 20 30 20 30 20 3b 0a 0a 3a    LOOP  0 0 ;..:
6730: 20 3f 70 65 72 6d 20 28 20 6f 3a 6b 65 79 20 2d   ?perm ( o:key -
6740: 2d 20 29 0a 20 20 20 20 6b 65 2d 73 6b 20 73 65  - ).    ke-sk se
6750: 63 40 20 6e 69 70 20 64 75 70 20 49 46 20 20 70  c@ nip dup IF  p
6760: 65 72 6d 25 6d 79 73 65 6c 66 20 20 45 4c 53 45  erm%myself  ELSE
6770: 20 20 70 65 72 6d 25 64 65 66 61 75 6c 74 20 20    perm%default  
6780: 54 48 45 4e 20 20 6b 65 2d 6d 61 73 6b 20 21 0a  THEN  ke-mask !.
6790: 20 20 20 20 49 46 20 20 22 5c 78 30 30 22 20 20      IF  "\x00"  
67a0: 45 4c 53 45 20 20 22 5c 78 30 31 22 20 20 54 48  ELSE  "\x01"  TH
67b0: 45 4e 20 20 6b 65 2d 67 72 6f 75 70 73 20 24 21  EN  ke-groups $!
67c0: 20 3b 0a 0a 3a 20 64 6f 2d 6b 65 79 20 28 20 61   ;..: do-key ( a
67d0: 64 64 72 20 75 20 2f 20 30 20 30 20 20 2d 2d 20  ddr u / 0 0  -- 
67e0: 29 0a 20 20 20 20 64 75 70 20 30 3d 20 49 46 20  ).    dup 0= IF 
67f0: 20 32 64 72 6f 70 20 20 45 58 49 54 20 20 54 48   2drop  EXIT  TH
6800: 45 4e 0a 20 20 20 20 73 61 6d 70 6c 65 2d 6b 65  EN.    sample-ke
6810: 79 20 3e 6f 20 6b 65 2d 73 6b 20 6b 65 2d 65 6e  y >o ke-sk ke-en
6820: 64 20 6f 76 65 72 20 2d 20 65 72 61 73 65 20 20  d over - erase  
6830: 64 6f 2d 63 6d 64 2d 6c 6f 6f 70 20 6f 3e 20 3b  do-cmd-loop o> ;
6840: 0a 0a 3a 20 2e 6b 65 79 24 20 28 20 61 64 64 72  ..: .key$ ( addr
6850: 20 75 20 2d 2d 20 29 0a 20 20 20 20 73 61 6d 70   u -- ).    samp
6860: 6c 65 2d 6b 65 79 20 3e 6f 20 20 6b 65 2d 73 6b  le-key >o  ke-sk
6870: 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d 20 65   ke-end over - e
6880: 72 61 73 65 0a 20 20 20 20 73 69 67 6e 65 64 2d  rase.    signed-
6890: 76 61 6c 20 76 61 6c 69 64 61 74 65 64 20 6f 72  val validated or
68a0: 21 20 20 63 2d 73 74 61 74 65 20 6f 66 66 20 20  !  c-state off  
68b0: 6e 65 73 74 2d 63 6d 64 2d 6c 6f 6f 70 0a 20 20  nest-cmd-loop.  
68c0: 20 20 73 69 67 6e 65 64 2d 76 61 6c 20 69 6e 76    signed-val inv
68d0: 65 72 74 20 76 61 6c 69 64 61 74 65 64 20 61 6e  ert validated an
68e0: 64 21 0a 20 20 20 20 2e 6b 65 79 2d 73 68 6f 72  d!.    .key-shor
68f0: 74 20 66 72 65 65 2d 6b 65 79 20 6f 3e 20 3b 0a  t free-key o> ;.
6900: 0a 3a 20 72 65 61 64 2d 6b 65 79 73 2d 6c 6f 6f  .: read-keys-loo
6910: 70 20 28 20 66 64 20 2d 2d 20 29 20 20 63 6f 64  p ( fd -- )  cod
6920: 65 2d 6b 65 79 0a 20 20 20 20 3e 72 20 23 30 2e  e-key.    >r #0.
6930: 20 72 40 20 72 65 70 6f 73 69 74 69 6f 6e 2d 66   r@ reposition-f
6940: 69 6c 65 20 74 68 72 6f 77 0a 20 20 20 20 42 45  ile throw.    BE
6950: 47 49 4e 0a 09 72 40 20 66 69 6c 65 2d 70 6f 73  GIN..r@ file-pos
6960: 69 74 69 6f 6e 20 74 68 72 6f 77 20 64 3e 36 34  ition throw d>64
6970: 20 6b 65 79 2d 72 65 61 64 2d 6f 66 66 73 65 74   key-read-offset
6980: 20 36 34 21 0a 09 6b 65 79 70 61 63 6b 20 6b 65   64!..keypack ke
6990: 79 70 61 63 6b 2d 61 6c 6c 23 20 72 40 20 72 65  ypack-all# r@ re
69a0: 61 64 2d 66 69 6c 65 20 74 68 72 6f 77 0a 09 6b  ad-file throw..k
69b0: 65 79 70 61 63 6b 2d 61 6c 6c 23 20 3d 20 57 48  eypack-all# = WH
69c0: 49 4c 45 0a 09 20 20 20 20 69 6d 70 6f 72 74 2d  ILE..    import-
69d0: 74 79 70 65 20 40 20 69 6d 70 6f 72 74 23 73 65  type @ import#se
69e0: 6c 66 20 3d 20 74 72 79 2d 64 65 63 72 79 70 74  lf = try-decrypt
69f0: 20 64 6f 2d 6b 65 79 0a 20 20 20 20 52 45 50 45   do-key.    REPE
6a00: 41 54 20 20 72 64 72 6f 70 20 20 63 6f 64 65 30  AT  rdrop  code0
6a10: 2d 62 75 66 20 3b 0a 3a 20 72 65 61 64 2d 6b 65  -buf ;.: read-ke
6a20: 79 2d 6c 6f 6f 70 20 28 20 2d 2d 20 29 0a 20 20  y-loop ( -- ).  
6a30: 20 20 69 6d 70 6f 72 74 23 73 65 6c 66 20 69 6d    import#self im
6a40: 70 6f 72 74 2d 74 79 70 65 20 21 0a 20 20 20 20  port-type !.    
6a50: 3f 6b 65 79 2d 73 66 64 20 72 65 61 64 2d 6b 65  ?key-sfd read-ke
6a60: 79 73 2d 6c 6f 6f 70 20 3b 0a 3a 20 72 65 61 64  ys-loop ;.: read
6a70: 2d 70 6b 65 79 2d 6c 6f 6f 70 20 28 20 2d 2d 20  -pkey-loop ( -- 
6a80: 29 0a 20 20 20 20 6c 61 73 74 6b 65 79 40 20 64  ).    lastkey@ d
6a90: 72 6f 70 20 64 65 66 61 75 6c 74 6b 65 79 20 21  rop defaultkey !
6aa0: 20 5c 20 61 74 20 6c 65 61 73 74 20 6f 6e 65 20   \ at least one 
6ab0: 64 65 66 61 75 6c 74 20 6b 65 79 20 61 76 61 69  default key avai
6ac0: 6c 61 62 6c 65 0a 20 20 20 20 2d 31 20 63 6f 6e  lable.    -1 con
6ad0: 66 69 67 3a 70 77 2d 6c 65 76 65 6c 23 0a 20 20  fig:pw-level#.  
6ae0: 20 20 5b 3a 20 69 6d 70 6f 72 74 23 6e 65 77 20    [: import#new 
6af0: 69 6d 70 6f 72 74 2d 74 79 70 65 20 21 20 3f 6b  import-type ! ?k
6b00: 65 79 2d 70 66 64 20 72 65 61 64 2d 6b 65 79 73  ey-pfd read-keys
6b10: 2d 6c 6f 6f 70 20 3b 5d 20 21 77 72 61 70 70 65  -loop ;] !wrappe
6b20: 72 20 3b 0a 0a 3a 20 72 65 61 64 2d 6b 65 79 73  r ;..: read-keys
6b30: 20 28 20 2d 2d 20 29 0a 20 20 20 20 72 65 61 64   ( -- ).    read
6b40: 2d 6b 65 79 2d 6c 6f 6f 70 20 72 65 61 64 2d 70  -key-loop read-p
6b50: 6b 65 79 2d 6c 6f 6f 70 20 69 6d 70 6f 72 74 23  key-loop import#
6b60: 6e 65 77 20 69 6d 70 6f 72 74 2d 74 79 70 65 20  new import-type 
6b70: 21 20 3b 0a 0a 3a 20 72 65 61 64 2d 70 6b 32 6b  ! ;..: read-pk2k
6b80: 65 79 24 20 28 20 61 64 64 72 20 75 20 2d 2d 20  ey$ ( addr u -- 
6b90: 29 0a 20 20 20 20 5c 67 20 72 65 61 64 20 61 20  ).    \g read a 
6ba0: 6e 65 73 74 65 64 20 6b 65 79 20 69 6e 74 6f 20  nested key into 
6bb0: 73 61 6d 70 6c 65 2d 6b 65 79 0a 20 20 20 20 73  sample-key.    s
6bc0: 61 6d 70 6c 65 2d 6b 65 79 20 3e 6f 20 63 2d 73  ample-key >o c-s
6bd0: 74 61 74 65 20 6f 66 66 20 20 73 69 6d 2d 6e 69  tate off  sim-ni
6be0: 63 6b 21 20 6f 6e 0a 20 20 20 20 70 6b 32 2d 73  ck! on.    pk2-s
6bf0: 69 67 3f 20 21 21 73 69 67 21 21 20 73 69 67 70  ig? !!sig!! sigp
6c00: 6b 32 73 69 7a 65 23 20 2d 20 32 64 75 70 20 2b  k2size# - 2dup +
6c10: 20 3e 72 20 64 6f 2d 6e 65 73 74 73 69 67 0a 20   >r do-nestsig. 
6c20: 20 20 20 72 40 20 6b 65 79 73 69 7a 65 32 20 6b     r@ keysize2 k
6c30: 65 2d 70 6b 20 24 21 0a 20 20 20 20 72 3e 20 6b  e-pk $!.    r> k
6c40: 65 79 73 69 7a 65 32 20 2b 20 73 69 67 73 69 7a  eysize2 + sigsiz
6c50: 65 23 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 21  e# ke-selfsig $!
6c60: 0a 20 20 20 20 6f 3e 20 20 73 69 6d 2d 6e 69 63  .    o>  sim-nic
6c70: 6b 21 20 6f 66 66 20 3b 0a 0a 3a 20 2e 70 6b 32  k! off ;..: .pk2
6c80: 6b 65 79 24 20 28 20 61 64 64 72 20 75 20 2d 2d  key$ ( addr u --
6c90: 20 29 0a 20 20 20 20 72 65 61 64 2d 70 6b 32 6b   ).    read-pk2k
6ca0: 65 79 24 20 73 61 6d 70 6c 65 2d 6b 65 79 20 3e  ey$ sample-key >
6cb0: 6f 0a 20 20 20 20 5b 20 31 20 69 6d 70 6f 72 74  o.    [ 1 import
6cc0: 23 69 6e 76 69 74 65 64 20 6c 73 68 69 66 74 20  #invited lshift 
6cd0: 31 20 69 6d 70 6f 72 74 23 6e 65 77 20 6c 73 68  1 import#new lsh
6ce0: 69 66 74 20 6f 72 20 5d 4c 20 6b 65 2d 69 6d 70  ift or ]L ke-imp
6cf0: 6f 72 74 73 20 21 0a 20 20 20 20 2e 6b 65 79 2d  orts !.    .key-
6d00: 69 6e 76 69 74 65 20 66 72 65 65 2d 6b 65 79 20  invite free-key 
6d10: 6f 3e 20 3b 0a 0a 5c 20 73 65 6c 65 63 74 20 6b  o> ;..\ select k
6d20: 65 79 20 62 79 20 6e 69 63 6b 0a 0a 3a 20 3e 72  ey by nick..: >r
6d30: 61 77 2d 6b 65 79 20 28 20 6f 20 2d 2d 20 29 0a  aw-key ( o -- ).
6d40: 20 20 20 20 64 75 70 20 30 3d 20 21 21 6e 6f 2d      dup 0= !!no-
6d50: 6e 69 63 6b 21 21 20 64 75 70 20 6d 79 2d 6b 65  nick!! dup my-ke
6d60: 79 2d 64 65 66 61 75 6c 74 20 21 20 3e 6f 0a 20  y-default ! >o. 
6d70: 20 20 20 73 6b 73 69 67 21 0a 20 20 20 20 6b 65     sksig!.    ke
6d80: 2d 70 6b 20 24 40 20 70 6b 63 20 70 6b 72 6b 23  -pk $@ pkc pkrk#
6d90: 20 73 6d 6f 76 65 0a 20 20 20 20 6b 65 2d 73 6b   smove.    ke-sk
6da0: 20 73 65 63 40 20 73 6b 63 20 73 77 61 70 20 6b   sec@ skc swap k
6db0: 65 79 7c 20 6d 6f 76 65 0a 20 20 20 20 6b 65 2d  ey| move.    ke-
6dc0: 73 6b 73 69 67 20 73 65 63 40 20 73 6b 73 69 67  sksig sec@ sksig
6dd0: 20 6b 65 79 73 69 7a 65 20 73 6d 6f 76 65 20 6f   keysize smove o
6de0: 3e 20 3b 0a 0a 3a 20 3e 6b 65 79 20 28 20 61 64  > ;..: >key ( ad
6df0: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6b 65  dr u -- ).    ke
6e00: 79 23 20 40 20 30 3d 20 49 46 20 20 72 65 61 64  y# @ 0= IF  read
6e10: 2d 6b 65 79 73 20 20 54 48 45 4e 0a 20 20 20 20  -keys  THEN.    
6e20: 6e 69 63 6b 2d 6b 65 79 20 3e 72 61 77 2d 6b 65  nick-key >raw-ke
6e30: 79 20 3b 0a 0a 3a 20 69 27 6d 20 28 20 22 6e 61  y ;..: i'm ( "na
6e40: 6d 65 22 20 2d 2d 20 29 20 70 61 72 73 65 2d 6e  me" -- ) parse-n
6e50: 61 6d 65 20 3e 6b 65 79 20 3b 0a 3a 20 70 6b 27  ame >key ;.: pk'
6e60: 20 28 20 22 6e 61 6d 65 22 20 2d 2d 20 61 64 64   ( "name" -- add
6e70: 72 20 75 20 29 0a 20 20 20 20 70 61 72 73 65 2d  r u ).    parse-
6e80: 6e 61 6d 65 20 6e 69 63 6b 3e 70 6b 20 3b 0a 0a  name nick>pk ;..
6e90: 3a 20 64 65 73 74 2d 6b 65 79 20 28 20 61 64 64  : dest-key ( add
6ea0: 72 20 75 20 2d 2d 20 29 20 64 75 70 20 30 3d 20  r u -- ) dup 0= 
6eb0: 49 46 20 20 32 64 72 6f 70 20 20 45 58 49 54 20  IF  2drop  EXIT 
6ec0: 20 54 48 45 4e 0a 20 20 20 20 6e 69 63 6b 2d 6b   THEN.    nick-k
6ed0: 65 79 20 3e 6f 20 6f 20 30 3d 20 21 21 75 6e 6b  ey >o o 0= !!unk
6ee0: 6e 6f 77 6e 2d 6b 65 79 21 21 0a 20 20 20 20 6b  nown-key!!.    k
6ef0: 65 2d 70 6b 20 24 40 20 6f 3e 0a 20 20 20 20 70  e-pk $@ o>.    p
6f00: 75 62 6b 65 79 20 24 21 20 3b 0a 0a 3a 20 64 65  ubkey $! ;..: de
6f10: 73 74 2d 70 6b 20 28 20 61 64 64 72 20 75 20 2d  st-pk ( addr u -
6f20: 2d 20 29 20 6b 65 79 32 7c 20 32 64 75 70 20 6b  - ) key2| 2dup k
6f30: 65 79 7c 20 6b 65 79 23 20 23 40 20 30 3d 20 49  ey| key# #@ 0= I
6f40: 46 0a 09 64 72 6f 70 20 70 75 62 6b 65 79 20 24  F..drop pubkey $
6f50: 21 20 20 70 65 72 6d 25 75 6e 6b 6e 6f 77 6e 20  !  perm%unknown 
6f60: 70 65 72 6d 2d 6d 61 73 6b 20 21 0a 20 20 20 20  perm-mask !.    
6f70: 45 4c 53 45 20 20 63 65 6c 6c 2b 20 3e 6f 0a 09  ELSE  cell+ >o..
6f80: 6b 65 2d 6d 61 73 6b 20 40 0a 09 6b 65 2d 70 6b  ke-mask @..ke-pk
6f90: 20 24 40 20 6f 3e 0a 09 70 75 62 6b 65 79 20 24   $@ o>..pubkey $
6fa0: 21 20 20 70 65 72 6d 2d 6d 61 73 6b 20 21 20 20  !  perm-mask !  
6fb0: 32 64 72 6f 70 20 20 54 48 45 4e 20 3b 0a 0a 3a  2drop  THEN ;..:
6fc0: 20 72 65 70 6c 61 63 65 2d 6b 65 79 20 31 20 2f   replace-key 1 /
6fd0: 73 74 72 69 6e 67 20 7b 20 72 65 76 2d 61 64 64  string { rev-add
6fe0: 72 20 75 20 2d 2d 20 6f 20 7d 20 5c 20 72 65 76  r u -- o } \ rev
6ff0: 6f 63 61 74 69 6f 6e 20 74 69 63 6b 65 74 0a 20  ocation ticket. 
7000: 20 20 20 6b 65 79 28 20 2e 22 20 52 65 70 6c 61     key( ." Repla
7010: 63 65 3a 22 20 63 72 20 6f 20 63 65 6c 6c 2d 20  ce:" cr o cell- 
7020: 30 20 2e 6b 65 79 20 29 0a 20 20 20 20 69 6d 70  0 .key ).    imp
7030: 6f 72 74 23 73 65 6c 66 20 69 6d 70 6f 72 74 2d  ort#self import-
7040: 74 79 70 65 20 21 0a 20 20 20 20 73 22 20 23 72  type !.    s" #r
7050: 65 76 6f 6b 65 64 22 20 64 75 70 20 3e 72 20 6b  evoked" dup >r k
7060: 65 2d 6e 69 63 6b 20 24 2b 21 0a 20 20 20 20 6b  e-nick $+!.    k
7070: 65 2d 6e 69 63 6b 20 24 40 20 72 3e 20 2d 20 6b  e-nick $@ r> - k
7080: 65 2d 70 72 6f 66 20 24 40 20 6b 65 2d 73 69 67  e-prof $@ ke-sig
7090: 73 5b 5d 20 6b 65 2d 74 79 70 65 20 40 0a 20 20  s[] ke-type @.  
70a0: 20 20 72 65 76 2d 61 64 64 72 20 70 6b 72 6b 23    rev-addr pkrk#
70b0: 20 6b 65 79 3f 6e 65 77 20 3e 6f 0a 20 20 20 20   key?new >o.    
70c0: 6b 65 2d 74 79 70 65 20 21 20 5b 3a 20 6b 65 2d  ke-type ! [: ke-
70d0: 73 69 67 73 5b 5d 20 24 2b 5b 5d 21 20 3b 5d 20  sigs[] $+[]! ;] 
70e0: 24 5b 5d 6d 61 70 20 6b 65 2d 70 72 6f 66 20 24  $[]map ke-prof $
70f0: 21 20 6b 65 2d 6e 69 63 6b 20 24 21 0a 20 20 20  ! ke-nick $!.   
7100: 20 72 65 76 2d 61 64 64 72 20 70 6b 72 6b 23 20   rev-addr pkrk# 
7110: 6b 65 2d 70 6b 20 24 21 0a 20 20 20 20 72 65 76  ke-pk $!.    rev
7120: 2d 61 64 64 72 20 75 20 2b 20 31 2d 20 64 75 70  -addr u + 1- dup
7130: 20 63 40 20 32 2a 20 2d 20 24 31 30 20 2d 20 24   c@ 2* - $10 - $
7140: 31 30 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 21  10 ke-selfsig $!
7150: 0a 20 20 20 20 6b 65 79 28 20 2e 22 20 77 69 74  .    key( ." wit
7160: 68 3a 22 20 63 72 20 6f 20 63 65 6c 6c 2d 20 30  h:" cr o cell- 0
7170: 20 2e 6b 65 79 20 29 20 6f 20 6f 3e 0a 20 20 20   .key ) o o>.   
7180: 20 69 6d 70 6f 72 74 23 6e 65 77 20 69 6d 70 6f   import#new impo
7190: 72 74 2d 74 79 70 65 20 21 20 3b 0a 0a 3a 20 72  rt-type ! ;..: r
71a0: 65 6e 65 77 2d 6b 65 79 20 28 20 72 65 76 61 64  enew-key ( revad
71b0: 64 72 20 75 31 20 6b 65 79 61 64 64 72 20 75 32  dr u1 keyaddr u2
71c0: 20 2d 2d 20 6f 20 29 0a 20 20 20 20 63 75 72 72   -- o ).    curr
71d0: 65 6e 74 2d 6b 65 79 20 3e 6f 20 72 65 70 6c 61  ent-key >o repla
71e0: 63 65 2d 6b 65 79 20 6f 3e 0a 20 20 20 20 3e 6f  ce-key o>.    >o
71f0: 20 73 6b 63 20 6b 65 79 73 69 7a 65 20 6b 65 2d   skc keysize ke-
7200: 73 6b 20 73 65 63 21 20 6f 20 6f 3e 20 3b 0a 0a  sk sec! o o> ;..
7210: 5c 20 67 65 6e 65 72 61 74 65 20 6e 65 77 20 6b  \ generate new k
7220: 65 79 0a 0a 3a 20 6f 75 74 2d 6b 65 79 20 28 20  ey..: out-key ( 
7230: 6f 20 2d 2d 20 29 0a 20 20 20 20 3e 6f 20 70 61  o -- ).    >o pa
7240: 63 6b 2d 6f 75 74 6b 65 79 20 5b 27 5d 20 2e 6e  ck-outkey ['] .n
7250: 69 63 6b 2d 62 61 73 65 20 24 74 6d 70 20 66 6e  ick-base $tmp fn
7260: 2d 73 61 6e 69 74 69 7a 65 20 6f 3e 0a 20 20 20  -sanitize o>.   
7270: 20 5b 3a 20 2e 22 20 7e 2f 22 20 74 79 70 65 20   [: ." ~/" type 
7280: 2e 22 20 2e 6e 32 6f 22 20 3b 5d 20 24 74 6d 70  ." .n2o" ;] $tmp
7290: 20 77 2f 6f 20 63 72 65 61 74 65 2d 66 69 6c 65   w/o create-file
72a0: 20 74 68 72 6f 77 0a 20 20 20 20 3e 72 20 63 6d   throw.    >r cm
72b0: 64 62 75 66 24 20 72 40 20 77 72 69 74 65 2d 66  dbuf$ r@ write-f
72c0: 69 6c 65 20 74 68 72 6f 77 20 72 3e 20 63 6c 6f  ile throw r> clo
72d0: 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 20 3b 0a  se-file throw ;.
72e0: 3a 20 6f 75 74 2d 6d 65 20 28 20 2d 2d 20 29 0a  : out-me ( -- ).
72f0: 20 20 20 20 70 6b 40 20 6b 65 79 7c 20 6b 65 79      pk@ key| key
7300: 23 20 23 40 20 30 3d 20 21 21 75 6e 6b 6e 6f 77  # #@ 0= !!unknow
7310: 6e 2d 6b 65 79 21 21 0a 20 20 20 20 63 65 6c 6c  n-key!!.    cell
7320: 2b 20 6f 75 74 2d 6b 65 79 20 3b 0a 0a 56 61 72  + out-key ;..Var
7330: 69 61 62 6c 65 20 64 68 74 72 6f 6f 74 2e 6e 32  iable dhtroot.n2
7340: 6f 0a 0a 3a 20 2b 64 68 74 72 6f 6f 74 20 28 20  o..: +dhtroot ( 
7350: 2d 2d 20 29 0a 20 20 20 20 64 65 66 61 75 6c 74  -- ).    default
7360: 6b 65 79 20 40 20 3e 73 74 6f 72 65 6b 65 79 20  key @ >storekey 
7370: 21 0a 20 20 20 20 69 6d 70 6f 72 74 23 6d 61 6e  !.    import#man
7380: 75 61 6c 20 69 6d 70 6f 72 74 2d 74 79 70 65 20  ual import-type 
7390: 21 20 20 36 34 23 2d 31 20 6b 65 79 2d 72 65 61  !  64#-1 key-rea
73a0: 64 2d 6f 66 66 73 65 74 20 36 34 21 0a 20 20 20  d-offset 64!.   
73b0: 20 64 68 74 72 6f 6f 74 2e 6e 32 6f 20 24 40 20   dhtroot.n2o $@ 
73c0: 64 6f 2d 6b 65 79 0a 20 20 20 20 6c 61 73 74 2d  do-key.    last-
73d0: 6b 65 79 20 3e 6f 20 22 5c 78 30 32 22 20 6b 65  key >o "\x02" ke
73e0: 2d 67 72 6f 75 70 73 20 24 21 20 70 65 72 6d 25  -groups $! perm%
73f0: 64 68 74 72 6f 6f 74 20 6b 65 2d 6d 61 73 6b 20  dhtroot ke-mask 
7400: 21 20 6f 3e 0a 20 20 20 20 69 6d 70 6f 72 74 23  ! o>.    import#
7410: 6e 65 77 20 69 6d 70 6f 72 74 2d 74 79 70 65 20  new import-type 
7420: 21 20 3b 0a 0a 3a 20 6e 65 77 2d 6b 65 79 20 28  ! ;..: new-key (
7430: 20 6e 69 63 6b 61 64 64 72 20 75 20 2d 2d 20 29   nickaddr u -- )
7440: 0a 20 20 20 20 3f 63 68 65 63 6b 2d 72 6e 67 20  .    ?check-rng 
7450: 5c 20 62 65 66 6f 72 65 20 67 65 6e 65 72 61 74  \ before generat
7460: 69 6e 67 20 61 20 6b 65 79 2c 20 63 68 65 63 6b  ing a key, check
7470: 20 74 68 65 20 72 6e 67 20 66 6f 72 20 68 65 61   the rng for hea
7480: 6c 74 68 0a 20 20 20 20 2b 6e 65 77 70 68 72 61  lth.    +newphra
7490: 73 65 20 6b 65 79 3e 64 65 66 61 75 6c 74 0a 20  se key>default. 
74a0: 20 20 20 6b 65 79 23 75 73 65 72 20 2b 67 65 6e     key#user +gen
74b0: 2d 6b 65 79 73 0a 20 20 20 20 73 65 63 72 65 74  -keys.    secret
74c0: 2d 6b 65 79 73 23 20 31 2d 20 73 65 63 72 65 74  -keys# 1- secret
74d0: 2d 6b 65 79 20 3e 72 61 77 2d 6b 65 79 20 20 6c  -key >raw-key  l
74e0: 61 73 74 6b 65 79 40 20 64 72 6f 70 20 64 65 66  astkey@ drop def
74f0: 61 75 6c 74 6b 65 79 20 21 0a 20 20 20 20 6f 75  aultkey !.    ou
7500: 74 2d 6d 65 20 2b 64 68 74 72 6f 6f 74 20 73 61  t-me +dhtroot sa
7510: 76 65 2d 6b 65 79 73 20 3b 0a 0a 5c 20 72 65 76  ve-keys ;..\ rev
7520: 6f 6b 61 74 69 6f 6e 0a 0a 34 20 64 61 74 65 73  okation..4 dates
7530: 69 7a 65 23 20 2b 20 6b 65 79 73 69 7a 65 20 39  ize# + keysize 9
7540: 20 2a 20 2b 20 43 6f 6e 73 74 61 6e 74 20 72 65   * + Constant re
7550: 76 73 69 7a 65 23 0a 0a 56 61 72 69 61 62 6c 65  vsize#..Variable
7560: 20 72 65 76 74 6f 6b 65 6e 0a 0a 3a 20 30 6f 6c   revtoken..: 0ol
7570: 64 6b 65 79 20 28 20 2d 2d 20 29 20 5c 20 70 75  dkey ( -- ) \ pu
7580: 62 6b 65 79 73 20 63 61 6e 20 73 74 61 79 0a 20  bkeys can stay. 
7590: 20 20 20 6f 6c 64 73 6b 63 20 6b 65 79 73 69 7a     oldskc keysiz
75a0: 65 20 65 72 61 73 65 20 20 6f 6c 64 73 6b 72 65  e erase  oldskre
75b0: 76 20 6b 65 79 73 69 7a 65 20 65 72 61 73 65 20  v keysize erase 
75c0: 3b 0a 0a 3a 20 6b 65 79 6d 6f 76 65 20 28 20 61  ;..: keymove ( a
75d0: 64 64 72 31 20 61 64 64 72 32 20 2d 2d 20 29 20  ddr1 addr2 -- ) 
75e0: 20 6b 65 79 73 69 7a 65 20 6d 6f 76 65 20 3b 0a   keysize move ;.
75f0: 0a 3a 20 72 65 76 6f 6b 65 2d 76 65 72 69 66 79  .: revoke-verify
7600: 20 28 20 61 64 64 72 20 75 31 20 70 6b 20 73 74   ( addr u1 pk st
7610: 72 69 6e 67 20 75 32 20 2d 2d 20 61 64 64 72 20  ring u2 -- addr 
7620: 75 20 66 6c 61 67 20 29 20 72 6f 74 20 3e 72 20  u flag ) rot >r 
7630: 32 3e 72 20 63 3a 30 6b 65 79 0a 20 20 20 20 73  2>r c:0key.    s
7640: 69 67 6f 6e 6c 79 73 69 7a 65 23 20 2d 20 32 64  igonlysize# - 2d
7650: 75 70 20 32 72 3e 20 3e 6b 65 79 65 64 2d 68 61  up 2r> >keyed-ha
7660: 73 68 0a 20 20 20 20 73 69 67 64 61 74 65 20 2b  sh.    sigdate +
7670: 64 61 74 65 0a 20 20 20 20 32 64 75 70 20 2b 20  date.    2dup + 
7680: 72 3e 20 65 64 2d 76 65 72 69 66 79 20 3b 0a 0a  r> ed-verify ;..
7690: 3a 20 3e 72 65 76 6f 6b 65 20 28 20 73 6b 72 65  : >revoke ( skre
76a0: 76 20 2d 2d 20 29 20 20 73 6b 72 65 76 20 6b 65  v -- )  skrev ke
76b0: 79 6d 6f 76 65 20 20 70 6b 63 20 63 68 65 63 6b  ymove  pkc check
76c0: 2d 72 65 76 3f 20 30 3d 20 21 21 6e 6f 74 2d 6d  -rev? 0= !!not-m
76d0: 79 2d 72 65 76 73 6b 21 21 20 3b 0a 0a 3a 20 2b  y-revsk!! ;..: +
76e0: 72 65 76 73 69 67 6e 20 28 20 73 6b 20 70 6b 20  revsign ( sk pk 
76f0: 2d 2d 20 29 20 20 73 6b 73 69 67 20 2d 72 6f 74  -- )  sksig -rot
7700: 20 65 64 2d 73 69 67 6e 20 72 65 76 74 6f 6b 65   ed-sign revtoke
7710: 6e 20 24 2b 21 20 62 6c 20 72 65 76 74 6f 6b 65  n $+! bl revtoke
7720: 6e 20 63 24 2b 21 20 3b 0a 0a 3a 20 73 69 67 6e  n c$+! ;..: sign
7730: 2d 74 6f 6b 65 6e 2c 20 28 20 73 6b 20 70 6b 20  -token, ( sk pk 
7740: 73 74 72 69 6e 67 20 75 32 20 2d 2d 20 29 0a 20  string u2 -- ). 
7750: 20 20 20 63 3a 30 6b 65 79 20 72 65 76 74 6f 6b     c:0key revtok
7760: 65 6e 20 24 40 20 32 73 77 61 70 20 3e 6b 65 79  en $@ 2swap >key
7770: 65 64 2d 68 61 73 68 0a 20 20 20 20 73 69 67 64  ed-hash.    sigd
7780: 61 74 65 20 2b 64 61 74 65 20 2b 72 65 76 73 69  ate +date +revsi
7790: 67 6e 20 3b 0a 0a 3a 20 72 65 76 6f 6b 65 2d 6b  gn ;..: revoke-k
77a0: 65 79 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29  ey ( -- addr u )
77b0: 0a 20 20 20 20 73 6b 63 20 6f 6c 64 73 6b 63 20  .    skc oldskc 
77c0: 6b 65 79 6d 6f 76 65 20 20 70 6b 63 20 6f 6c 64  keymove  pkc old
77d0: 70 6b 63 20 6b 65 79 6d 6f 76 65 20 20 73 6b 72  pkc keymove  skr
77e0: 65 76 20 6f 6c 64 73 6b 72 65 76 20 6b 65 79 6d  ev oldskrev keym
77f0: 6f 76 65 0a 20 20 20 20 20 20 20 20 20 20 20 20  ove.            
7800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7810: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
7820: 20 62 61 63 6b 75 70 20 6b 65 79 73 0a 20 20 20   backup keys.   
7830: 20 6f 6c 64 73 6b 72 65 76 20 6f 6c 64 70 6b 72   oldskrev oldpkr
7840: 65 76 20 73 6b 3e 70 6b 20 20 20 20 20 20 20 20  ev sk>pk        
7850: 20 20 20 20 20 20 20 20 5c 20 67 65 6e 65 72 61          \ genera
7860: 74 65 20 72 65 76 6f 6b 61 74 69 6f 6e 20 70 75  te revokation pu
7870: 62 6b 65 79 0a 20 20 20 20 67 65 6e 2d 6b 65 79  bkey.    gen-key
7880: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
7890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
78a0: 5c 20 67 65 6e 65 72 61 74 65 20 6e 65 77 20 6b  \ generate new k
78b0: 65 79 73 0a 20 20 20 20 70 6b 63 20 6b 65 79 73  eys.    pkc keys
78c0: 69 7a 65 32 20 72 65 76 74 6f 6b 65 6e 20 24 21  ize2 revtoken $!
78d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5c                 \
78e0: 20 6d 79 20 6e 65 77 20 6b 65 79 0a 20 20 20 20   my new key.    
78f0: 6f 6c 64 70 6b 72 65 76 20 6b 65 79 73 69 7a 65  oldpkrev keysize
7900: 20 72 65 76 74 6f 6b 65 6e 20 24 2b 21 20 20 20   revtoken $+!   
7910: 20 20 20 20 20 20 20 5c 20 72 65 76 6f 6b 65 20         \ revoke 
7920: 74 6f 6b 65 6e 0a 20 20 20 20 6f 6c 64 73 6b 72  token.    oldskr
7930: 65 76 20 6f 6c 64 70 6b 72 65 76 20 22 72 65 76  ev oldpkrev "rev
7940: 6f 6b 65 22 20 73 69 67 6e 2d 74 6f 6b 65 6e 2c  oke" sign-token,
7950: 20 5c 20 72 65 76 6f 6b 65 20 73 69 67 6e 61 74   \ revoke signat
7960: 75 72 65 0a 20 20 20 20 73 6b 63 20 70 6b 63 20  ure.    skc pkc 
7970: 22 73 65 6c 66 73 69 67 6e 22 20 73 69 67 6e 2d  "selfsign" sign-
7980: 74 6f 6b 65 6e 2c 20 20 20 20 20 20 20 20 20 5c  token,         \
7990: 20 73 65 6c 66 20 73 69 67 6e 65 64 20 77 69 74   self signed wit
79a0: 68 20 6e 65 77 20 6b 65 79 0a 20 20 20 20 22 21  h new key.    "!
79b0: 22 20 72 65 76 74 6f 6b 65 6e 20 30 20 24 69 6e  " revtoken 0 $in
79c0: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s               
79d0: 20 20 20 20 20 5c 20 22 21 22 20 2b 20 6f 6c 64       \ "!" + old
79e0: 6b 65 79 6c 65 6e 2b 6e 65 77 6b 65 79 6c 65 6e  keylen+newkeylen
79f0: 20 74 6f 20 66 6c 61 67 20 72 65 76 6f 6b 61 74   to flag revokat
7a00: 69 6f 6e 0a 20 20 20 20 72 65 76 74 6f 6b 65 6e  ion.    revtoken
7a10: 20 24 40 20 67 65 6e 3e 68 6f 73 74 20 32 64 72   $@ gen>host 2dr
7a20: 6f 70 20 20 20 20 20 20 20 20 20 20 20 20 20 5c  op             \
7a30: 20 73 69 67 6e 20 68 6f 73 74 20 69 6e 66 6f 72   sign host infor
7a40: 6d 61 74 69 6f 6e 20 77 69 74 68 20 6f 6c 64 20  mation with old 
7a50: 6b 65 79 0a 20 20 20 20 73 69 67 64 61 74 65 20  key.    sigdate 
7a60: 2b 64 61 74 65 20 73 69 67 64 61 74 65 20 64 61  +date sigdate da
7a70: 74 65 73 69 7a 65 23 20 72 65 76 74 6f 6b 65 6e  tesize# revtoken
7a80: 20 24 2b 21 0a 20 20 20 20 6f 6c 64 73 6b 63 20   $+!.    oldskc 
7a90: 6f 6c 64 70 6b 63 20 2b 72 65 76 73 69 67 6e 0a  oldpkc +revsign.
7aa0: 20 20 20 20 30 6f 6c 64 6b 65 79 20 72 65 76 74      0oldkey revt
7ab0: 6f 6b 65 6e 20 24 40 20 3b 0a 0a 5c 20 69 6e 76  oken $@ ;..\ inv
7ac0: 69 74 61 74 69 6f 6e 0a 0a 56 61 72 69 61 62 6c  itation..Variabl
7ad0: 65 20 69 6e 76 69 74 61 74 69 6f 6e 73 0a 0a 65  e invitations..e
7ae0: 76 65 6e 74 3a 20 2d 3e 69 6e 76 69 74 65 20 28  vent: ->invite (
7af0: 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20   addr u -- ).   
7b00: 20 2e 22 20 69 6e 76 69 74 65 20 6d 65 3a 20 22   ." invite me: "
7b10: 20 6f 76 65 72 20 3e 72 20 2e 70 6b 32 6b 65 79   over >r .pk2key
7b20: 24 20 63 72 20 72 3e 20 66 72 65 65 20 74 68 72  $ cr r> free thr
7b30: 6f 77 20 63 74 72 6c 20 4c 20 69 6e 73 6b 65 79  ow ctrl L inskey
7b40: 20 3b 0a 65 76 65 6e 74 3a 20 2d 3e 77 61 6b 65   ;.event: ->wake
7b50: 6d 65 20 28 20 6f 20 2d 2d 20 29 20 3c 65 76 65  me ( o -- ) <eve
7b60: 6e 74 20 2d 3e 77 61 6b 65 20 65 76 65 6e 74 3e  nt ->wake event>
7b70: 20 3b 0a 0a 3a 20 70 6b 32 6b 65 79 24 2d 61 64   ;..: pk2key$-ad
7b80: 64 20 28 20 61 64 64 72 20 75 20 70 65 72 6d 20  d ( addr u perm 
7b90: 2d 2d 20 29 20 7b 20 70 65 72 6d 20 7d 0a 20 20  -- ) { perm }.  
7ba0: 20 20 73 61 6d 70 6c 65 2d 6b 65 79 20 3e 6f 20    sample-key >o 
7bb0: 69 6d 70 6f 72 74 23 69 6e 76 69 74 65 64 20 69  import#invited i
7bc0: 6d 70 6f 72 74 2d 74 79 70 65 20 21 20 63 6d 64  mport-type ! cmd
7bd0: 3a 6e 65 73 74 73 69 67 0a 20 20 20 20 70 65 72  :nestsig.    per
7be0: 6d 20 6b 65 2d 6d 61 73 6b 20 21 0a 20 20 20 20  m ke-mask !.    
7bf0: 69 6d 70 6f 72 74 23 6e 65 77 20 69 6d 70 6f 72  import#new impor
7c00: 74 2d 74 79 70 65 20 21 20 20 73 61 76 65 2d 70  t-type !  save-p
7c10: 75 62 6b 65 79 73 20 6f 3e 20 3b 0a 0a 3a 20 78  ubkeys o> ;..: x
7c20: 2d 65 72 61 73 65 20 28 20 6c 65 6e 20 2d 2d 20  -erase ( len -- 
7c30: 29 0a 20 20 20 20 64 75 70 20 78 62 61 63 6b 2d  ).    dup xback-
7c40: 72 65 73 74 6f 72 65 20 20 64 75 70 20 73 70 61  restore  dup spa
7c50: 63 65 73 20 20 78 62 61 63 6b 2d 72 65 73 74 6f  ces  xback-resto
7c60: 72 65 20 3b 0a 0a 3a 20 69 6e 76 69 74 65 2d 6b  re ;..: invite-k
7c70: 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6b  ey ( addr u -- k
7c80: 65 79 20 29 0a 20 20 20 20 32 64 75 70 20 78 2d  ey ).    2dup x-
7c90: 77 69 64 74 68 20 7b 20 61 64 64 72 20 75 20 6c  width { addr u l
7ca0: 65 6e 20 7d 0a 20 20 20 20 42 45 47 49 4e 20 20  en }.    BEGIN  
7cb0: 61 64 64 72 20 75 20 74 79 70 65 20 6b 65 79 20  addr u type key 
7cc0: 20 6c 65 6e 20 78 2d 65 72 61 73 65 0a 09 64 75   len x-erase..du
7cd0: 70 20 63 74 72 6c 20 5a 20 3d 0a 20 20 20 20 57  p ctrl Z =.    W
7ce0: 48 49 4c 45 20 20 64 72 6f 70 20 20 42 45 47 49  HILE  drop  BEGI
7cf0: 4e 20 20 6b 65 79 20 63 74 72 6c 20 4c 20 3d 20  N  key ctrl L = 
7d00: 20 55 4e 54 49 4c 20 20 52 45 50 45 41 54 20 3b   UNTIL  REPEAT ;
7d10: 0a 0a 3a 20 70 72 6f 63 65 73 73 2d 69 6e 76 69  ..: process-invi
7d20: 74 61 74 69 6f 6e 20 28 20 61 64 64 72 20 75 20  tation ( addr u 
7d30: 2d 2d 20 29 0a 20 20 20 20 73 22 20 69 6e 76 69  -- ).    s" invi
7d40: 74 65 20 28 79 2f 6e 2f 62 29 3f 22 20 69 6e 76  te (y/n/b)?" inv
7d50: 69 74 65 2d 6b 65 79 0a 20 20 20 20 63 61 73 65  ite-key.    case
7d60: 0a 09 27 79 27 20 6f 66 20 20 70 65 72 6d 25 64  ..'y' of  perm%d
7d70: 65 66 61 75 6c 74 20 70 6b 32 6b 65 79 24 2d 61  efault pk2key$-a
7d80: 64 64 20 20 2e 22 20 61 64 64 65 64 22 20 63 72  dd  ." added" cr
7d90: 20 20 20 65 6e 64 6f 66 0a 09 27 62 27 20 6f 66     endof..'b' of
7da0: 20 20 70 65 72 6d 25 62 6c 6f 63 6b 65 64 20 70    perm%blocked p
7db0: 6b 32 6b 65 79 24 2d 61 64 64 20 20 2e 22 20 62  k2key$-add  ." b
7dc0: 6c 6f 63 6b 65 64 22 20 63 72 20 65 6e 64 6f 66  locked" cr endof
7dd0: 0a 09 32 64 72 6f 70 20 2e 22 20 69 67 6e 6f 72  ..2drop ." ignor
7de0: 65 64 22 20 63 72 0a 20 20 20 20 65 6e 64 63 61  ed" cr.    endca
7df0: 73 65 20 3b 0a 0a 3a 20 66 69 6c 74 65 72 2d 69  se ;..: filter-i
7e00: 6e 76 69 74 61 74 69 6f 6e 3f 20 28 20 61 64 64  nvitation? ( add
7e10: 72 20 75 20 2d 2d 20 66 6c 61 67 20 29 0a 20 20  r u -- flag ).  
7e20: 20 20 73 69 67 70 6b 32 73 69 7a 65 23 20 2d 20    sigpk2size# - 
7e30: 2b 20 6b 65 79 73 69 7a 65 20 6b 65 79 23 20 23  + keysize key# #
7e40: 40 20 64 30 3c 3e 20 3b 20 5c 20 61 6c 72 65 61  @ d0<> ; \ alrea
7e50: 64 79 20 74 68 65 72 65 0a 0a 3a 20 2e 69 6e 76  dy there..: .inv
7e60: 69 74 61 74 69 6f 6e 73 20 28 20 2d 2d 20 29 0a  itations ( -- ).
7e70: 20 20 20 20 69 6e 76 69 74 61 74 69 6f 6e 73 20      invitations 
7e80: 5b 3a 20 32 64 75 70 20 2e 70 6b 32 6b 65 79 24  [: 2dup .pk2key$
7e90: 20 63 72 20 70 72 6f 63 65 73 73 2d 69 6e 76 69   cr process-invi
7ea0: 74 61 74 69 6f 6e 20 3b 5d 20 24 5b 5d 6d 61 70  tation ;] $[]map
7eb0: 0a 20 20 20 20 69 6e 76 69 74 61 74 69 6f 6e 73  .    invitations
7ec0: 20 24 5b 5d 6f 66 66 20 3b 0a 0a 3a 20 3e 69 6e   $[]off ;..: >in
7ed0: 76 69 74 61 74 69 6f 6e 73 20 28 20 61 64 64 72  vitations ( addr
7ee0: 20 75 20 2d 2d 20 29 0a 20 20 20 20 32 64 75 70   u -- ).    2dup
7ef0: 20 66 69 6c 74 65 72 2d 69 6e 76 69 74 61 74 69   filter-invitati
7f00: 6f 6e 3f 20 49 46 20 20 32 64 72 6f 70 20 45 58  on? IF  2drop EX
7f10: 49 54 20 20 54 48 45 4e 0a 20 20 20 20 69 6e 76  IT  THEN.    inv
7f20: 69 74 61 74 69 6f 6e 73 20 24 5b 5d 23 20 3e 72  itations $[]# >r
7f30: 0a 20 20 20 20 32 64 75 70 20 69 6e 76 69 74 61  .    2dup invita
7f40: 74 69 6f 6e 73 20 24 69 6e 73 5b 5d 73 69 67 20  tions $ins[]sig 
7f50: 64 72 6f 70 0a 20 20 20 20 69 6e 76 69 74 61 74  drop.    invitat
7f60: 69 6f 6e 73 20 24 5b 5d 23 20 72 3e 20 3c 3e 20  ions $[]# r> <> 
7f70: 49 46 0a 09 73 61 76 65 2d 6d 65 6d 20 6d 61 69  IF..save-mem mai
7f80: 6e 2d 75 70 40 20 3c 68 69 64 65 3e 0a 09 3c 65  n-up@ <hide>..<e
7f90: 76 65 6e 74 20 65 24 2c 20 2d 3e 69 6e 76 69 74  vent e$, ->invit
7fa0: 65 20 75 70 40 20 65 6c 69 74 2c 20 2d 3e 77 61  e up@ elit, ->wa
7fb0: 6b 65 6d 65 20 6d 61 69 6e 2d 75 70 40 20 65 76  keme main-up@ ev
7fc0: 65 6e 74 3e 20 73 74 6f 70 0a 20 20 20 20 45 4c  ent> stop.    EL
7fd0: 53 45 20 20 32 64 72 6f 70 20 20 54 48 45 4e 20  SE  2drop  THEN 
7fe0: 3b 0a 0a 3a 20 73 65 6e 64 2d 69 6e 76 69 74 61  ;..: send-invita
7ff0: 74 69 6f 6e 20 28 20 70 6b 20 75 20 2d 2d 20 29  tion ( pk u -- )
8000: 0a 20 20 20 20 73 65 74 75 70 21 20 6d 79 70 6b  .    setup! mypk
8010: 32 6e 69 63 6b 24 20 32 3e 72 0a 20 20 20 20 67  2nick$ 2>r.    g
8020: 65 6e 2d 74 6d 70 6b 65 79 73 20 64 72 6f 70 20  en-tmpkeys drop 
8030: 74 73 6b 63 20 73 77 61 70 20 6b 65 79 70 61 64  tskc swap keypad
8040: 20 65 64 2d 64 68 20 64 6f 2d 6b 65 79 70 61 64   ed-dh do-keypad
8050: 20 73 65 63 21 0a 20 20 20 20 6e 65 74 32 6f 2d   sec!.    net2o-
8060: 63 6f 64 65 30 0a 20 20 20 20 74 70 6b 63 20 6b  code0.    tpkc k
8070: 65 79 73 69 7a 65 20 24 2c 20 6f 6e 65 73 68 6f  eysize $, onesho
8080: 74 2d 74 6d 70 6b 65 79 0a 20 20 20 20 6e 65 73  t-tmpkey.    nes
8090: 74 5b 20 32 72 3e 20 24 2c 20 69 6e 76 69 74 65  t[ 2r> $, invite
80a0: 20 5d 74 6d 70 6e 65 73 74 0a 20 20 20 20 63 6f   ]tmpnest.    co
80b0: 6f 6b 69 65 2b 72 65 71 75 65 73 74 0a 20 20 20  okie+request.   
80c0: 20 65 6e 64 2d 63 6f 64 65 7c 20 3b 0a 0a 5c 20   end-code| ;..\ 
80d0: 6b 65 79 20 61 70 69 20 68 65 6c 70 65 72 73 0a  key api helpers.
80e0: 0a 3a 20 64 65 6c 2d 6c 61 73 74 2d 6b 65 79 20  .: del-last-key 
80f0: 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 73 20  ( -- ).    keys 
8100: 24 5b 5d 23 20 31 2d 20 6b 65 79 73 20 24 5b 5d  $[]# 1- keys $[]
8110: 20 73 65 63 2d 6f 66 66 0a 20 20 20 20 6b 65 79   sec-off.    key
8120: 73 20 24 40 6c 65 6e 20 63 65 6c 6c 2d 20 6b 65  s $@len cell- ke
8130: 79 73 20 24 21 6c 65 6e 20 3b 0a 0a 3a 20 73 74  ys $!len ;..: st
8140: 6f 72 65 6b 65 79 21 20 28 20 2d 2d 20 29 0a 20  orekey! ( -- ). 
8150: 20 20 20 3e 73 65 63 6b 65 79 20 6b 65 79 73 20     >seckey keys 
8160: 24 5b 5d 23 20 30 20 3f 44 4f 20 20 32 64 75 70  $[]# 0 ?DO  2dup
8170: 20 49 20 6b 65 79 73 20 73 65 63 5b 5d 40 20 73   I keys sec[]@ s
8180: 74 72 3d 20 49 46 0a 09 20 20 20 20 49 20 6b 65  tr= IF..    I ke
8190: 79 73 20 73 65 63 5b 5d 40 20 64 72 6f 70 20 3e  ys sec[]@ drop >
81a0: 73 74 6f 72 65 6b 65 79 20 21 20 20 4c 45 41 56  storekey !  LEAV
81b0: 45 20 20 54 48 45 4e 20 20 4c 4f 4f 50 20 20 32  E  THEN  LOOP  2
81c0: 64 72 6f 70 20 3b 0a 0a 3a 20 63 68 6f 6f 73 65  drop ;..: choose
81d0: 2d 6b 65 79 20 28 20 2d 2d 20 6f 20 29 0a 20 20  -key ( -- o ).  
81e0: 20 20 30 20 42 45 47 49 4e 20 20 64 72 6f 70 0a    0 BEGIN  drop.
81f0: 09 2e 22 20 43 68 6f 6f 73 65 20 6b 65 79 20 62  .." Choose key b
8200: 79 20 6e 75 6d 62 65 72 3a 22 20 63 72 20 2e 73  y number:" cr .s
8210: 65 63 72 65 74 2d 6e 69 63 6b 73 0a 09 42 45 47  ecret-nicks..BEG
8220: 49 4e 20 20 6b 65 79 20 64 75 70 20 62 6c 20 3c  IN  key dup bl <
8230: 20 57 48 49 4c 45 20 20 64 72 6f 70 20 20 52 45   WHILE  drop  RE
8240: 50 45 41 54 20 5c 20 73 77 61 6c 6c 6f 77 20 63  PEAT \ swallow c
8250: 6f 6e 74 72 6f 6c 20 6b 65 79 73 0a 09 5b 27 5d  ontrol keys..[']
8260: 20 64 69 67 69 74 3f 20 23 33 36 20 62 61 73 65   digit? #36 base
8270: 2d 65 78 65 63 75 74 65 20 30 3d 20 49 46 20 2d  -execute 0= IF -
8280: 31 20 54 48 45 4e 0a 09 73 65 63 72 65 74 2d 6b  1 THEN..secret-k
8290: 65 79 20 64 75 70 20 30 3d 20 57 48 49 4c 45 0a  ey dup 0= WHILE.
82a0: 09 20 20 20 20 2e 22 20 50 6c 65 61 73 65 20 65  .    ." Please e
82b0: 6e 74 65 72 20 61 20 62 61 73 65 2d 33 36 20 6e  nter a base-36 n
82c0: 75 6d 62 65 72 20 62 65 74 77 65 65 6e 20 30 20  umber between 0 
82d0: 61 6e 64 20 22 0a 09 20 20 20 20 73 65 63 72 65  and "..    secre
82e0: 74 2d 6b 65 79 73 23 20 31 2d 20 5b 27 5d 20 2e  t-keys# 1- ['] .
82f0: 20 23 33 36 20 62 61 73 65 2d 65 78 65 63 75 74   #36 base-execut
8300: 65 20 63 72 20 20 72 64 72 6f 70 0a 20 20 20 20  e cr  rdrop.    
8310: 52 45 50 45 41 54 0a 20 20 20 20 64 75 70 20 2e  REPEAT.    dup .
8320: 73 74 6f 72 65 6b 65 79 21 20 20 3e 73 74 6f 72  storekey!  >stor
8330: 65 6b 65 79 20 40 20 64 65 66 61 75 6c 74 6b 65  ekey @ defaultke
8340: 79 20 21 0a 20 20 20 20 2e 22 20 3d 3d 3d 3d 20  y !.    ." ==== 
8350: 6b 65 79 20 22 20 64 75 70 20 2e 2e 6e 69 63 6b  key " dup ..nick
8360: 20 2e 22 20 20 63 68 6f 73 65 6e 20 3d 3d 3d 3d   ."  chosen ====
8370: 22 20 63 72 20 3b 0a 0a 5c 20 77 69 6c 6c 20 61  " cr ;..\ will a
8380: 73 6b 20 66 6f 72 20 79 6f 75 72 20 70 61 73 73  sk for your pass
8390: 77 6f 72 64 20 61 6e 64 20 69 66 20 70 6f 73 73  word and if poss
83a0: 69 62 6c 65 20 61 75 74 6f 2d 73 65 6c 65 63 74  ible auto-select
83b0: 20 79 6f 75 72 20 69 64 0a 0a 56 61 72 69 61 62   your id..Variab
83c0: 6c 65 20 74 72 69 65 73 23 0a 23 31 30 20 56 61  le tries#.#10 Va
83d0: 6c 75 65 20 6d 61 78 74 72 69 65 73 23 0a 0a 3a  lue maxtries#..:
83e0: 20 67 65 74 2d 73 6b 63 20 28 20 2d 2d 20 29 0a   get-skc ( -- ).
83f0: 20 20 20 20 73 65 63 72 65 74 2d 6b 65 79 73 23      secret-keys#
8400: 20 3f 45 58 49 54 20 20 74 72 69 65 73 23 20 6f   ?EXIT  tries# o
8410: 66 66 0a 20 20 20 20 64 65 62 75 67 2d 76 65 63  ff.    debug-vec
8420: 74 6f 72 20 40 20 6f 70 2d 76 65 63 74 6f 72 20  tor @ op-vector 
8430: 21 40 20 3e 72 20 3c 64 65 66 61 75 6c 74 3e 0a  !@ >r <default>.
8440: 20 20 20 20 73 65 63 72 65 74 2d 6b 65 79 73 23      secret-keys#
8450: 0a 20 20 20 20 42 45 47 49 4e 20 20 64 75 70 20  .    BEGIN  dup 
8460: 30 3d 20 74 72 69 65 73 23 20 40 20 6d 61 78 74  0= tries# @ maxt
8470: 72 69 65 73 23 20 75 3c 20 61 6e 64 20 20 57 48  ries# u< and  WH
8480: 49 4c 45 20 64 72 6f 70 0a 09 20 20 20 20 73 22  ILE drop..    s"
8490: 20 50 61 73 73 70 68 72 61 73 65 3a 20 22 20 2b   Passphrase: " +
84a0: 70 61 73 73 70 68 72 61 73 65 20 20 20 21 74 69  passphrase   !ti
84b0: 6d 65 0a 09 20 20 20 20 72 65 61 64 2d 6b 65 79  me..    read-key
84c0: 73 20 73 65 63 72 65 74 2d 6b 65 79 73 23 20 64  s secret-keys# d
84d0: 75 70 20 30 3d 20 49 46 0a 09 09 5c 20 66 61 69  up 0= IF...\ fai
84e0: 6c 20 72 69 67 68 74 20 61 66 74 65 72 20 74 68  l right after th
84f0: 65 20 66 69 72 73 74 20 74 72 79 20 69 66 20 50  e first try if P
8500: 41 53 53 50 48 52 41 53 45 20 69 73 20 75 73 65  ASSPHRASE is use
8510: 64 0a 09 09 5c 20 61 6e 64 20 67 69 76 65 20 74  d...\ and give t
8520: 68 65 20 6d 61 78 69 6d 75 6d 20 77 61 69 74 69  he maximum waiti
8530: 6e 67 20 70 65 6e 61 6c 74 79 20 69 6e 20 74 68  ng penalty in th
8540: 61 74 20 63 61 73 65 0a 09 09 31 20 6d 61 78 74  at case...1 maxt
8550: 72 69 65 73 23 20 73 22 20 50 41 53 53 50 48 52  ries# s" PASSPHR
8560: 41 53 45 22 20 67 65 74 65 6e 76 20 64 30 3d 20  ASE" getenv d0= 
8570: 73 65 6c 65 63 74 20 74 72 69 65 73 23 20 2b 21  select tries# +!
8580: 0a 09 09 3c 65 72 72 3e 20 2e 22 20 54 72 79 23  ...<err> ." Try#
8590: 20 22 20 74 72 69 65 73 23 20 40 20 30 20 2e 72   " tries# @ 0 .r
85a0: 20 27 2f 27 20 65 6d 69 74 20 6d 61 78 74 72 69   '/' emit maxtri
85b0: 65 73 23 20 2e 0a 09 09 2e 22 20 66 61 69 6c 65  es# ....." faile
85c0: 64 2c 20 6e 6f 20 6b 65 79 20 66 6f 75 6e 64 2c  d, no key found,
85d0: 20 77 61 69 74 69 6e 67 20 22 0a 09 09 23 31 20   waiting "...#1 
85e0: 74 72 69 65 73 23 20 40 20 32 2a 20 6c 73 68 69  tries# @ 2* lshi
85f0: 66 74 20 64 75 70 20 2e 20 2e 22 20 6d 73 2e 2e  ft dup . ." ms..
8600: 2e 22 20 6d 73 20 20 3c 64 65 66 61 75 6c 74 3e  ." ms  <default>
8610: 20 63 72 0a 09 09 64 65 6c 2d 6c 61 73 74 2d 6b   cr...del-last-k
8620: 65 79 0a 09 20 20 20 20 54 48 45 4e 0a 20 20 20  ey..    THEN.   
8630: 20 52 45 50 45 41 54 0a 20 20 20 20 64 75 70 20   REPEAT.    dup 
8640: 30 3d 20 49 46 20 20 23 2d 35 36 20 74 68 72 6f  0= IF  #-56 thro
8650: 77 20 20 54 48 45 4e 0a 20 20 20 20 31 20 3d 20  w  THEN.    1 = 
8660: 49 46 20 20 30 20 73 65 63 72 65 74 2d 6b 65 79  IF  0 secret-key
8670: 0a 09 2e 22 20 3d 3d 3d 3d 20 6f 70 65 6e 65 64  ..." ==== opened
8680: 3a 20 22 20 64 75 70 20 2e 2e 6e 69 63 6b 20 2e  : " dup ..nick .
8690: 22 20 20 69 6e 20 22 20 2e 74 69 6d 65 20 2e 22  "  in " .time ."
86a0: 20 3d 3d 3d 3d 22 20 63 72 0a 20 20 20 20 45 4c   ====" cr.    EL
86b0: 53 45 20 20 2e 22 20 3d 3d 3d 3d 20 6f 70 65 6e  SE  ." ==== open
86c0: 65 64 20 69 6e 20 22 20 2e 74 69 6d 65 20 2e 22  ed in " .time ."
86d0: 20 3d 3d 3d 3d 22 20 63 72 20 63 68 6f 6f 73 65   ====" cr choose
86e0: 2d 6b 65 79 20 20 54 48 45 4e 0a 20 20 20 20 3e  -key  THEN.    >
86f0: 72 61 77 2d 6b 65 79 20 3f 72 73 6b 20 20 20 72  raw-key ?rsk   r
8700: 3e 20 6f 70 2d 76 65 63 74 6f 72 20 21 20 3b 0a  > op-vector ! ;.
8710: 0a 73 63 6f 70 65 3a 20 6e 32 6f 0a 46 6f 72 77  .scope: n2o.Forw
8720: 61 72 64 20 68 65 6c 70 0a 7d 73 63 6f 70 65 0a  ard help.}scope.
8730: 0a 3a 20 67 65 74 2d 6d 79 2d 6b 65 79 20 28 20  .: get-my-key ( 
8740: 2d 2d 20 78 74 20 29 0a 20 20 20 20 67 65 6e 2d  -- xt ).    gen-
8750: 6b 65 79 73 2d 64 69 72 20 20 22 73 65 63 6b 65  keys-dir  "secke
8760: 79 73 2e 6b 32 6f 22 20 2e 6b 65 79 73 2f 20 32  ys.k2o" .keys/ 2
8770: 64 75 70 20 66 69 6c 65 2d 73 74 61 74 75 73 20  dup file-status 
8780: 6e 69 70 0a 20 20 20 20 30 3d 20 49 46 20 20 72  nip.    0= IF  r
8790: 2f 6f 20 6f 70 65 6e 2d 66 69 6c 65 20 74 68 72  /o open-file thr
87a0: 6f 77 20 3e 72 20 72 40 20 66 69 6c 65 2d 73 69  ow >r r@ file-si
87b0: 7a 65 20 74 68 72 6f 77 20 64 30 3d 0a 09 72 3e  ze throw d0=..r>
87c0: 20 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f   close-file thro
87d0: 77 20 20 45 4c 53 45 20 20 74 72 75 65 20 20 54  w  ELSE  true  T
87e0: 48 45 4e 0a 20 20 20 20 49 46 20 20 5b 3a 20 2e  HEN.    IF  [: .
87f0: 22 20 47 65 6e 65 72 61 74 65 20 61 20 6e 65 77  " Generate a new
8800: 20 6b 65 79 70 61 69 72 3a 22 20 63 72 0a 09 20   keypair:" cr.. 
8810: 20 67 65 74 2d 6e 69 63 6b 20 64 75 70 20 30 3d   get-nick dup 0=
8820: 20 23 2d 35 36 20 61 6e 64 20 74 68 72 6f 77 20   #-56 and throw 
8830: 5c 20 65 6d 70 74 79 20 6e 69 63 6b 3a 20 70 72  \ empty nick: pr
8840: 65 74 65 6e 64 20 74 6f 20 71 75 69 74 0a 09 20  etend to quit.. 
8850: 20 6e 65 77 2d 6b 65 79 20 2e 6b 65 79 73 20 3f   new-key .keys ?
8860: 72 73 6b 20 3b 5d 0a 20 20 20 20 45 4c 53 45 20  rsk ;].    ELSE 
8870: 20 5b 27 5d 20 67 65 74 2d 73 6b 63 20 20 54 48   ['] get-skc  TH
8880: 45 4e 20 3b 0a 0a 3a 20 2e 6b 65 79 69 6e 66 6f  EN ;..: .keyinfo
8890: 20 28 20 2d 2d 20 29 0a 20 20 20 20 3c 77 61 72   ( -- ).    <war
88a0: 6e 3e 20 2e 22 20 3d 3d 3d 3d 20 4e 6f 20 6b 65  n> ." ==== No ke
88b0: 79 20 6f 70 65 6e 65 64 20 3d 3d 3d 3d 22 20 63  y opened ====" c
88c0: 72 0a 20 20 20 20 3c 69 6e 66 6f 3e 20 2e 22 20  r.    <info> ." 
88d0: 67 65 6e 65 72 61 74 65 20 61 20 6e 65 77 20 6f  generate a new o
88e0: 6e 65 20 77 69 74 68 20 27 6b 65 79 67 65 6e 27  ne with 'keygen'
88f0: 22 20 63 72 20 3c 64 65 66 61 75 6c 74 3e 20 3b  " cr <default> ;
8900: 0a 0a 3a 20 67 65 74 2d 6d 65 20 28 20 2d 2d 20  ..: get-me ( -- 
8910: 29 0a 20 20 20 20 67 65 74 2d 6d 79 2d 6b 65 79  ).    get-my-key
8920: 20 63 61 74 63 68 20 64 75 70 20 23 2d 35 36 20   catch dup #-56 
8930: 3d 20 49 46 20 64 72 6f 70 20 2e 6b 65 79 69 6e  = IF drop .keyin
8940: 66 6f 20 45 4c 53 45 20 74 68 72 6f 77 20 54 48  fo ELSE throw TH
8950: 45 4e 20 3b 0a 0a 3a 20 3f 67 65 74 2d 6d 65 20  EN ;..: ?get-me 
8960: 28 20 2d 2d 20 29 0a 20 20 20 20 5c 47 20 74 68  ( -- ).    \G th
8970: 69 73 20 76 65 72 73 69 6f 6e 20 6f 66 20 67 65  is version of ge
8980: 74 2d 6d 65 20 66 61 69 6c 73 20 68 61 72 64 20  t-me fails hard 
8990: 69 66 20 6e 6f 20 6b 65 79 20 69 73 20 6f 70 65  if no key is ope
89a0: 6e 65 64 0a 20 20 20 20 67 65 74 2d 6d 79 2d 6b  ned.    get-my-k
89b0: 65 79 20 63 61 74 63 68 20 23 2d 35 36 20 3d 20  ey catch #-56 = 
89c0: 49 46 0a 09 2e 6b 65 79 69 6e 66 6f 20 74 72 75  IF...keyinfo tru
89d0: 65 20 21 21 6e 6f 2d 6b 65 79 2d 6f 70 65 6e 21  e !!no-key-open!
89e0: 21 0a 20 20 20 20 54 48 45 4e 20 3b 0a 0a 30 20  !.    THEN ;..0 
89f0: 5b 49 46 5d 0a 4c 6f 63 61 6c 20 56 61 72 69 61  [IF].Local Varia
8a00: 62 6c 65 73 3a 0a 66 6f 72 74 68 2d 6c 6f 63 61  bles:.forth-loca
8a10: 6c 2d 77 6f 72 64 73 3a 0a 20 20 20 20 28 0a 20  l-words:.    (. 
8a20: 20 20 20 20 28 28 22 6e 65 74 32 6f 3a 22 20 22      (("net2o:" "
8a30: 2b 6e 65 74 32 6f 3a 22 29 20 64 65 66 69 6e 69  +net2o:") defini
8a40: 74 69 6f 6e 2d 73 74 61 72 74 65 72 20 28 66 6f  tion-starter (fo
8a50: 6e 74 2d 6c 6f 63 6b 2d 6b 65 79 77 6f 72 64 2d  nt-lock-keyword-
8a60: 66 61 63 65 20 2e 20 31 29 0a 20 20 20 20 20 20  face . 1).      
8a70: 22 5b 20 5c 74 5c 6e 5d 22 20 74 20 6e 61 6d 65  "[ \t\n]" t name
8a80: 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 66 75 6e 63   (font-lock-func
8a90: 74 69 6f 6e 2d 6e 61 6d 65 2d 66 61 63 65 20 2e  tion-name-face .
8aa0: 20 33 29 29 0a 20 20 20 20 20 28 28 22 64 65 62   3)).     (("deb
8ab0: 75 67 3a 22 20 22 66 69 65 6c 64 3a 22 20 22 32  ug:" "field:" "2
8ac0: 66 69 65 6c 64 3a 22 20 22 73 66 66 69 65 6c 64  field:" "sffield
8ad0: 3a 22 20 22 64 66 66 69 65 6c 64 3a 22 20 22 36  :" "dffield:" "6
8ae0: 34 66 69 65 6c 64 3a 22 20 22 75 76 61 72 22 20  4field:" "uvar" 
8af0: 22 75 76 61 6c 75 65 22 29 20 6e 6f 6e 2d 69 6d  "uvalue") non-im
8b00: 6d 65 64 69 61 74 65 20 28 66 6f 6e 74 2d 6c 6f  mediate (font-lo
8b10: 63 6b 2d 74 79 70 65 2d 66 61 63 65 20 2e 20 32  ck-type-face . 2
8b20: 29 0a 20 20 20 20 20 20 22 5b 20 5c 74 5c 6e 5d  ).      "[ \t\n]
8b30: 22 20 74 20 6e 61 6d 65 20 28 66 6f 6e 74 2d 6c  " t name (font-l
8b40: 6f 63 6b 2d 76 61 72 69 61 62 6c 65 2d 6e 61 6d  ock-variable-nam
8b50: 65 2d 66 61 63 65 20 2e 20 33 29 29 0a 20 20 20  e-face . 3)).   
8b60: 20 20 28 22 5b 61 2d 7a 30 2d 39 5d 2b 28 22 20    ("[a-z0-9]+(" 
8b70: 69 6d 6d 65 64 69 61 74 65 20 28 66 6f 6e 74 2d  immediate (font-
8b80: 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e 74 2d 66 61 63  lock-comment-fac
8b90: 65 20 2e 20 31 29 0a 20 20 20 20 20 20 22 29 22  e . 1).      ")"
8ba0: 20 6e 69 6c 20 63 6f 6d 6d 65 6e 74 20 28 66 6f   nil comment (fo
8bb0: 6e 74 2d 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e 74 2d  nt-lock-comment-
8bc0: 66 61 63 65 20 2e 20 31 29 29 0a 20 20 20 20 29  face . 1)).    )
8bd0: 0a 66 6f 72 74 68 2d 6c 6f 63 61 6c 2d 69 6e 64  .forth-local-ind
8be0: 65 6e 74 2d 77 6f 72 64 73 3a 0a 20 20 20 20 28  ent-words:.    (
8bf0: 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f 3a 22  .     (("net2o:"
8c00: 20 22 2b 6e 65 74 32 6f 3a 22 29 20 28 30 20 2e   "+net2o:") (0 .
8c10: 20 32 29 20 28 30 20 2e 20 32 29 20 6e 6f 6e 2d   2) (0 . 2) non-
8c20: 69 6d 6d 65 64 69 61 74 65 29 0a 20 20 20 20 20  immediate).     
8c30: 28 28 22 5b 3a 22 20 22 6b 65 79 3a 63 6f 64 65  (("[:" "key:code
8c40: 22 29 20 28 30 20 2e 20 31 29 20 28 30 20 2e 20  ") (0 . 1) (0 . 
8c50: 31 29 20 69 6d 6d 65 64 69 61 74 65 29 0a 20 20  1) immediate).  
8c60: 20 20 20 28 28 22 3b 5d 22 20 22 65 6e 64 3a 6b     ((";]" "end:k
8c70: 65 79 22 29 20 28 2d 31 20 2e 20 30 29 20 28 30  ey") (-1 . 0) (0
8c80: 20 2e 20 2d 31 29 20 69 6d 6d 65 64 69 61 74 65   . -1) immediate
8c90: 29 0a 20 20 20 20 29 0a 45 6e 64 3a 0a 5b 54 48  ).    ).End:.[TH
8ca0: 45 4e 5d                                         EN]