Hex Artifact Content
Not logged in

Artifact bc75482f006083c5410c0fe4db47a4e6ef66ff11:


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: 61 6e 64 72 6f 69 64 78 78 78 20 27 2a 27 20 5b  androidxxx '*' [
03b0: 45 4c 53 45 5d 20 27 e2 80 a2 27 20 5b 54 48 45  ELSE] '•' [THE
03c0: 4e 5d 20 43 6f 6e 73 74 61 6e 74 20 70 77 2a 0a  N] Constant pw*.
03d0: 0a 78 63 2d 76 65 63 74 6f 72 20 75 70 40 20 2d  .xc-vector up@ -
03e0: 20 63 6c 61 73 73 2d 6f 20 21 0a 0a 30 20 63 65   class-o !..0 ce
03f0: 6c 6c 20 75 76 61 72 20 65 73 63 2d 73 74 61 74  ll uvar esc-stat
0400: 65 20 64 72 6f 70 0a 0a 44 65 66 65 72 20 6f 6c  e drop..Defer ol
0410: 64 2d 65 6d 69 74 20 20 77 68 61 74 27 73 20 65  d-emit  what's e
0420: 6d 69 74 20 69 73 20 6f 6c 64 2d 65 6d 69 74 0a  mit is old-emit.
0430: 0a 68 65 72 65 0a 78 63 2d 76 65 63 74 6f 72 20  .here.xc-vector 
0440: 40 20 63 65 6c 6c 2d 20 64 75 70 20 40 20 74 75  @ cell- dup @ tu
0450: 63 6b 20 2d 20 68 65 72 65 20 73 77 61 70 20 64  ck - here swap d
0460: 75 70 20 61 6c 6c 6f 74 20 6d 6f 76 65 0a 2c 20  up allot move., 
0470: 68 65 72 65 20 30 20 2c 20 43 6f 6e 73 74 61 6e  here 0 , Constan
0480: 74 20 75 74 66 2d 38 2a 0a 0a 78 63 2d 76 65 63  t utf-8*..xc-vec
0490: 74 6f 72 20 40 20 20 75 74 66 2d 38 2a 20 78 63  tor @  utf-8* xc
04a0: 2d 76 65 63 74 6f 72 20 21 20 27 20 2a 2d 77 69  -vector ! ' *-wi
04b0: 64 74 68 20 69 73 20 78 2d 77 69 64 74 68 20 20  dth is x-width  
04c0: 78 63 2d 76 65 63 74 6f 72 20 21 0a 0a 3a 20 65  xc-vector !..: e
04d0: 6d 69 74 2d 70 77 2a 20 28 20 6e 20 2d 2d 20 29  mit-pw* ( n -- )
04e0: 0a 20 20 20 20 64 75 70 20 23 65 73 63 20 3d 20  .    dup #esc = 
04f0: 49 46 20 20 65 73 63 2d 73 74 61 74 65 20 6f 6e  IF  esc-state on
0500: 20 20 54 48 45 4e 0a 20 20 20 20 64 75 70 20 62    THEN.    dup b
0510: 6c 20 3c 20 49 46 20 20 6f 6c 64 2d 65 6d 69 74  l < IF  old-emit
0520: 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20    EXIT  THEN.   
0530: 20 65 73 63 2d 73 74 61 74 65 20 40 20 49 46 20   esc-state @ IF 
0540: 20 64 75 70 20 6f 6c 64 2d 65 6d 69 74 0a 20 20   dup old-emit.  
0550: 20 20 45 4c 53 45 20 20 64 75 70 20 24 43 30 20    ELSE  dup $C0 
0560: 24 38 30 20 77 69 74 68 69 6e 20 49 46 0a 09 20  $80 within IF.. 
0570: 20 20 20 5b 20 70 77 2a 20 27 20 78 65 6d 69 74     [ pw* ' xemit
0580: 20 24 74 6d 70 0a 09 20 20 20 20 62 6f 75 6e 64   $tmp..    bound
0590: 73 20 5b 3f 44 4f 5d 20 5b 49 5d 20 63 40 20 5d  s [?DO] [I] c@ ]
05a0: 4c 20 6f 6c 64 2d 65 6d 69 74 20 5b 20 5b 4c 4f  L old-emit [ [LO
05b0: 4f 50 5d 20 5d 0a 09 54 48 45 4e 0a 20 20 20 20  OP] ]..THEN.    
05c0: 54 48 45 4e 0a 20 20 20 20 74 6f 75 70 70 65 72  THEN.    toupper
05d0: 20 27 41 27 20 27 5b 27 20 77 69 74 68 69 6e 20   'A' '[' within 
05e0: 49 46 20 20 65 73 63 2d 73 74 61 74 65 20 6f 66  IF  esc-state of
05f0: 66 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 74 79 70  f  THEN ;..: typ
0600: 65 2d 70 77 2a 20 28 20 61 64 64 72 20 75 20 2d  e-pw* ( addr u -
0610: 2d 20 29 20 20 32 64 75 70 20 62 6c 20 73 6b 69  - )  2dup bl ski
0620: 70 20 6e 69 70 20 30 3d 0a 20 20 20 20 49 46 20  p nip 0=.    IF 
0630: 20 20 20 62 6f 75 6e 64 73 20 55 2b 44 4f 20 20     bounds U+DO  
0640: 62 6c 20 6f 6c 64 2d 65 6d 69 74 20 20 20 20 4c  bl old-emit    L
0650: 4f 4f 50 0a 20 20 20 20 45 4c 53 45 20 20 62 6f  OOP.    ELSE  bo
0660: 75 6e 64 73 20 55 2b 44 4f 20 20 49 20 63 40 20  unds U+DO  I c@ 
0670: 65 6d 69 74 2d 70 77 2a 20 20 4c 4f 4f 50 20 20  emit-pw*  LOOP  
0680: 54 48 45 4e 20 3b 0a 0a 3a 20 61 63 63 65 70 74  THEN ;..: accept
0690: 2a 20 28 20 61 64 64 72 20 75 20 2d 2d 20 75 27  * ( addr u -- u'
06a0: 20 29 0a 20 20 20 20 5c 47 20 61 63 63 65 70 74   ).    \G accept
06b0: 2d 6c 69 6b 65 20 69 6e 70 75 74 2c 20 62 75 74  -like input, but
06c0: 20 74 79 70 65 73 20 2a 20 69 6e 73 74 65 61 64   types * instead
06d0: 20 6f 66 20 74 68 65 20 63 68 61 72 61 63 74 65   of the characte
06e0: 72 0a 20 20 20 20 5c 47 20 64 6f 6e 27 74 20 73  r.    \G don't s
06f0: 61 76 65 20 69 6e 74 6f 20 68 69 73 74 6f 72 79  ave into history
0700: 0a 20 20 20 20 68 69 73 74 6f 72 79 20 3e 72 20  .    history >r 
0710: 20 77 68 61 74 27 73 20 74 79 70 65 20 3e 72 20   what's type >r 
0720: 20 77 68 61 74 27 73 20 65 6d 69 74 20 69 73 20   what's emit is 
0730: 6f 6c 64 2d 65 6d 69 74 0a 20 20 20 20 75 74 66  old-emit.    utf
0740: 2d 38 2a 20 78 63 2d 76 65 63 74 6f 72 20 21 40  -8* xc-vector !@
0750: 20 3e 72 20 20 5b 27 5d 20 74 79 70 65 2d 70 77   >r  ['] type-pw
0760: 2a 20 69 73 20 74 79 70 65 20 20 5b 27 5d 20 65  * is type  ['] e
0770: 6d 69 74 2d 70 77 2a 20 69 73 20 65 6d 69 74 0a  mit-pw* is emit.
0780: 20 20 20 20 30 20 74 6f 20 68 69 73 74 6f 72 79      0 to history
0790: 0a 20 20 20 20 5b 27 5d 20 61 63 63 65 70 74 20  .    ['] accept 
07a0: 63 61 74 63 68 0a 20 20 20 20 72 3e 20 78 63 2d  catch.    r> xc-
07b0: 76 65 63 74 6f 72 20 21 20 20 77 68 61 74 27 73  vector !  what's
07c0: 20 6f 6c 64 2d 65 6d 69 74 20 69 73 20 65 6d 69   old-emit is emi
07d0: 74 20 20 72 3e 20 69 73 20 74 79 70 65 20 20 72  t  r> is type  r
07e0: 3e 20 74 6f 20 68 69 73 74 6f 72 79 0a 20 20 20  > to history.   
07f0: 20 74 68 72 6f 77 20 2d 31 20 30 20 61 74 2d 64   throw -1 0 at-d
0800: 65 6c 74 61 78 79 20 73 70 61 63 65 20 3b 0a 0a  eltaxy space ;..
0810: 5c 20 4b 65 79 73 20 61 72 65 20 70 61 73 73 77  \ Keys are passw
0820: 6f 72 64 73 20 61 6e 64 20 70 72 69 76 61 74 65  ords and private
0830: 20 6b 65 79 73 20 28 73 65 6c 66 2d 6b 65 79 65   keys (self-keye
0840: 64 2c 20 69 2e 65 2e 20 70 72 69 76 61 74 65 2a  d, i.e. private*
0850: 70 75 62 6c 69 63 20 6b 65 79 29 0a 0a 63 6d 64  public key)..cmd
0860: 2d 62 75 66 30 20 75 63 6c 61 73 73 20 63 6d 64  -buf0 uclass cmd
0870: 62 75 66 2d 6f 0a 20 20 20 20 6d 61 78 64 61 74  buf-o.    maxdat
0880: 61 20 2d 0a 20 20 20 20 6b 65 79 2d 73 61 6c 74  a -.    key-salt
0890: 23 20 75 76 61 72 20 6b 65 79 70 61 63 6b 0a 20  # uvar keypack. 
08a0: 20 20 20 6b 65 79 70 61 63 6b 23 20 20 75 76 61     keypack#  uva
08b0: 72 20 6b 65 79 70 61 63 6b 2d 62 75 66 0a 20 20  r keypack-buf.  
08c0: 20 20 6b 65 79 2d 63 6b 73 75 6d 23 20 75 76 61    key-cksum# uva
08d0: 72 20 6b 65 79 70 61 63 6b 2d 63 68 6b 73 75 6d  r keypack-chksum
08e0: 0a 65 6e 64 2d 63 6c 61 73 73 20 63 6d 64 2d 6b  .end-class cmd-k
08f0: 65 79 62 75 66 2d 63 0a 0a 63 6d 64 2d 6b 65 79  eybuf-c..cmd-key
0900: 62 75 66 2d 63 20 27 20 6e 65 77 20 73 74 61 74  buf-c ' new stat
0910: 69 63 2d 61 20 77 69 74 68 2d 61 6c 6c 6f 63 61  ic-a with-alloca
0920: 74 65 72 20 63 6f 64 65 2d 6b 65 79 5e 20 21 0a  ter code-key^ !.
0930: 27 20 63 6f 64 65 2d 6b 65 79 5e 20 63 6d 64 62  ' code-key^ cmdb
0940: 75 66 3a 20 63 6f 64 65 2d 6b 65 79 0a 0a 63 6f  uf: code-key..co
0950: 64 65 2d 6b 65 79 0a 63 6d 64 30 6c 6f 63 6b 20  de-key.cmd0lock 
0960: 30 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  0 pthread_mutex_
0970: 69 6e 69 74 20 64 72 6f 70 0a 0a 3a 6e 6f 6e 61  init drop..:nona
0980: 6d 65 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29  me ( -- addr u )
0990: 20 6b 65 79 70 61 63 6b 2d 62 75 66 20 63 6d 64   keypack-buf cmd
09a0: 62 75 66 23 20 40 20 3b 20 74 6f 20 63 6d 64 62  buf# @ ; to cmdb
09b0: 75 66 24 0a 3a 6e 6f 6e 61 6d 65 20 28 20 2d 2d  uf$.:noname ( --
09c0: 20 6e 20 29 20 20 6b 65 79 70 61 63 6b 23 20 63   n )  keypack# c
09d0: 6d 64 62 75 66 23 20 40 20 2d 20 3b 20 74 6f 20  mdbuf# @ - ; to 
09e0: 6d 61 78 73 74 72 69 6e 67 0a 0a 63 6f 64 65 30  maxstring..code0
09f0: 2d 62 75 66 0a 0a 3a 6e 6f 6e 61 6d 65 20 64 65  -buf..:noname de
0a00: 66 65 72 73 20 61 6c 6c 6f 63 2d 63 6f 64 65 2d  fers alloc-code-
0a10: 62 75 66 73 0a 20 20 20 20 63 6d 64 2d 6b 65 79  bufs.    cmd-key
0a20: 62 75 66 2d 63 20 6e 65 77 20 63 6f 64 65 2d 6b  buf-c new code-k
0a30: 65 79 5e 20 21 20 3b 20 69 73 20 61 6c 6c 6f 63  ey^ ! ; is alloc
0a40: 2d 63 6f 64 65 2d 62 75 66 73 0a 3a 6e 6f 6e 61  -code-bufs.:nona
0a50: 6d 65 20 64 65 66 65 72 73 20 66 72 65 65 2d 63  me defers free-c
0a60: 6f 64 65 2d 62 75 66 73 0a 20 20 20 20 63 6f 64  ode-bufs.    cod
0a70: 65 2d 6b 65 79 5e 20 40 20 2e 64 69 73 70 6f 73  e-key^ @ .dispos
0a80: 65 20 3b 20 69 73 20 66 72 65 65 2d 63 6f 64 65  e ; is free-code
0a90: 2d 62 75 66 73 0a 0a 5c 20 68 61 73 68 65 64 20  -bufs..\ hashed 
0aa0: 6b 65 79 20 64 61 74 61 20 62 61 73 65 0a 0a 56  key data base..V
0ab0: 61 72 69 61 62 6c 65 20 67 72 6f 75 70 73 5b 5d  ariable groups[]
0ac0: 20 5c 20 6e 61 6d 65 73 20 6f 66 20 67 72 6f 75   \ names of grou
0ad0: 70 73 2c 20 73 6f 72 74 65 64 20 62 79 20 6f 72  ps, sorted by or
0ae0: 64 65 72 20 69 6e 20 67 72 6f 75 70 73 20 66 69  der in groups fi
0af0: 6c 65 0a 0a 55 73 65 72 20 3e 73 74 6f 72 65 6b  le..User >storek
0b00: 65 79 0a 56 61 72 69 61 62 6c 65 20 64 65 66 61  ey.Variable defa
0b10: 75 6c 74 6b 65 79 0a 0a 63 6d 64 2d 63 6c 61 73  ultkey..cmd-clas
0b20: 73 20 63 6c 61 73 73 0a 20 20 20 20 66 69 65 6c  s class.    fiel
0b30: 64 3a 20 6b 65 2d 73 6b 20 20 20 20 20 20 20 5c  d: ke-sk       \
0b40: 20 73 65 63 72 65 74 20 6b 65 79 0a 20 20 20 20   secret key.    
0b50: 66 69 65 6c 64 3a 20 6b 65 2d 70 6b 20 20 20 20  field: ke-pk    
0b60: 20 20 20 5c 20 70 75 62 6c 69 63 20 6b 65 79 0a     \ public key.
0b70: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 72 73      field: ke-rs
0b80: 6b 20 20 20 20 20 20 5c 20 72 65 76 6f 6b 65 20  k      \ revoke 
0b90: 73 65 63 72 65 74 20 28 74 65 6d 70 6f 72 61 72  secret (temporar
0ba0: 69 6c 79 20 73 74 6f 72 65 64 29 0a 20 20 20 20  ily stored).    
0bb0: 66 69 65 6c 64 3a 20 6b 65 2d 74 79 70 65 20 20  field: ke-type  
0bc0: 20 20 20 5c 20 6b 65 79 20 74 79 70 65 0a 20 20     \ key type.  
0bd0: 20 20 66 69 65 6c 64 3a 20 6b 65 2d 6e 69 63 6b    field: ke-nick
0be0: 20 20 20 20 20 5c 20 6b 65 79 20 6e 69 63 6b 0a       \ key nick.
0bf0: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 6e 69      field: ke-ni
0c00: 63 6b 23 20 20 20 20 5c 20 74 6f 20 61 76 6f 69  ck#    \ to avoi
0c10: 64 20 63 6f 6c 69 73 73 69 6f 6e 73 2c 20 61 64  d colissions, ad
0c20: 64 20 61 20 6e 75 6d 62 65 72 20 68 65 72 65 0a  d a number here.
0c30: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 70 65      field: ke-pe
0c40: 74 73 20 20 20 20 20 5c 20 6b 65 79 20 70 65 74  ts     \ key pet
0c50: 6e 61 6d 65 73 0a 20 20 20 20 66 69 65 6c 64 3a  names.    field:
0c60: 20 6b 65 2d 70 65 74 73 23 20 20 20 20 5c 20 74   ke-pets#    \ t
0c70: 6f 20 61 76 6f 69 64 20 63 6f 6c 69 73 73 69 6f  o avoid colissio
0c80: 6e 73 2c 20 61 64 64 20 61 20 6e 75 6d 62 65 72  ns, add a number
0c90: 20 68 65 72 65 0a 20 20 20 20 66 69 65 6c 64 3a   here.    field:
0ca0: 20 6b 65 2d 70 72 6f 66 20 20 20 20 20 5c 20 70   ke-prof     \ p
0cb0: 72 6f 66 69 6c 65 20 6f 62 6a 65 63 74 0a 20 20  rofile object.  
0cc0: 20 20 66 69 65 6c 64 3a 20 6b 65 2d 73 65 6c 66    field: ke-self
0cd0: 73 69 67 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b  sig.    field: k
0ce0: 65 2d 73 69 67 73 0a 20 20 20 20 66 69 65 6c 64  e-sigs.    field
0cf0: 3a 20 6b 65 2d 69 6d 70 6f 72 74 73 20 20 5c 20  : ke-imports  \ 
0d00: 62 69 74 6d 61 73 6b 20 6f 66 20 6b 65 79 20 69  bitmask of key i
0d10: 6d 70 6f 72 74 0a 20 20 20 20 66 69 65 6c 64 3a  mport.    field:
0d20: 20 6b 65 2d 73 74 6f 72 65 6b 65 79 20 5c 20 75   ke-storekey \ u
0d30: 73 65 64 20 74 6f 20 65 6e 63 72 79 70 74 20 6f  sed to encrypt o
0d40: 6e 20 73 74 6f 72 61 67 65 0a 20 20 20 20 66 69  n storage.    fi
0d50: 65 6c 64 3a 20 6b 65 2d 6d 61 73 6b 20 20 20 20  eld: ke-mask    
0d60: 20 5c 20 70 65 72 6d 69 73 73 69 6f 6e 20 6d 61   \ permission ma
0d70: 73 6b 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b 65  sk.    field: ke
0d80: 2d 67 72 6f 75 70 73 20 20 20 5c 20 70 72 65 6d  -groups   \ prem
0d90: 69 73 73 69 6f 6e 20 67 72 6f 75 70 73 0a 20 20  ission groups.  
0da0: 20 20 36 34 66 69 65 6c 64 3a 20 6b 65 2d 6f 66    64field: ke-of
0db0: 66 73 65 74 20 5c 20 6f 66 66 73 65 74 20 69 6e  fset \ offset in
0dc0: 20 6b 65 79 20 66 69 6c 65 0a 20 20 20 20 66 69   key file.    fi
0dd0: 65 6c 64 3a 20 6b 65 2d 70 77 6c 65 76 65 6c 20  eld: ke-pwlevel 
0de0: 20 5c 20 70 61 73 73 77 6f 72 64 20 73 74 72 65   \ password stre
0df0: 6e 67 74 68 20 6c 65 76 65 6c 0a 20 20 20 20 30  ngth level.    0
0e00: 20 2b 66 69 65 6c 64 20 6b 65 2d 65 6e 64 0a 65   +field ke-end.e
0e10: 6e 64 2d 63 6c 61 73 73 20 6b 65 79 2d 65 6e 74  nd-class key-ent
0e20: 72 79 0a 0a 3a 20 66 72 65 65 2d 6b 65 79 20 28  ry..: free-key (
0e30: 20 6f 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20   o:key -- o:key 
0e40: 29 0a 20 20 20 20 5c 67 20 66 72 65 65 20 61 6c  ).    \g free al
0e50: 6c 20 70 61 72 74 73 20 6f 66 20 74 68 65 20 73  l parts of the s
0e60: 75 62 6b 65 79 0a 20 20 20 20 6b 65 2d 73 6b 20  ubkey.    ke-sk 
0e70: 73 65 63 2d 6f 66 66 0a 20 20 20 20 6b 65 2d 70  sec-off.    ke-p
0e80: 6b 20 24 6f 66 66 0a 20 20 20 20 6b 65 2d 6e 69  k $off.    ke-ni
0e90: 63 6b 20 24 6f 66 66 0a 20 20 20 20 6b 65 2d 73  ck $off.    ke-s
0ea0: 65 6c 66 73 69 67 20 24 6f 66 66 0a 20 20 20 20  elfsig $off.    
0eb0: 6b 65 2d 73 69 67 73 20 24 5b 5d 6f 66 66 0a 20  ke-sigs $[]off. 
0ec0: 20 20 20 6b 65 2d 70 65 74 73 20 24 5b 5d 6f 66     ke-pets $[]of
0ed0: 66 0a 20 20 20 20 6b 65 2d 70 65 74 73 23 20 24  f.    ke-pets# $
0ee0: 6f 66 66 20 3b 0a 0a 5c 20 6b 65 79 20 63 6c 61  off ;..\ key cla
0ef0: 73 73 0a 0a 30 0a 65 6e 75 6d 20 6b 65 79 23 61  ss..0.enum key#a
0f00: 6e 6f 6e 0a 65 6e 75 6d 20 6b 65 79 23 75 73 65  non.enum key#use
0f10: 72 0a 65 6e 75 6d 20 6b 65 79 23 67 72 6f 75 70  r.enum key#group
0f20: 0a 64 72 6f 70 0a 0a 5c 20 6b 65 79 20 69 6d 70  .drop..\ key imp
0f30: 6f 72 74 20 74 79 70 65 0a 0a 30 0a 65 6e 75 6d  ort type..0.enum
0f40: 20 69 6d 70 6f 72 74 23 73 65 6c 66 20 20 20 20   import#self    
0f50: 20 20 5c 20 70 72 69 76 61 74 65 20 6b 65 79 0a    \ private key.
0f60: 65 6e 75 6d 20 69 6d 70 6f 72 74 23 6d 61 6e 75  enum import#manu
0f70: 61 6c 20 20 20 20 5c 20 6d 61 6e 75 61 6c 20 69  al    \ manual i
0f80: 6d 70 6f 72 74 0a 65 6e 75 6d 20 69 6d 70 6f 72  mport.enum impor
0f90: 74 23 73 63 61 6e 20 20 20 20 20 20 5c 20 73 63  t#scan      \ sc
0fa0: 61 6e 20 69 6d 70 6f 72 74 0a 65 6e 75 6d 20 69  an import.enum i
0fb0: 6d 70 6f 72 74 23 63 68 61 74 20 20 20 20 20 20  mport#chat      
0fc0: 5c 20 73 65 65 6e 20 69 6e 20 63 68 61 74 0a 65  \ seen in chat.e
0fd0: 6e 75 6d 20 69 6d 70 6f 72 74 23 64 68 74 20 20  num import#dht  
0fe0: 20 20 20 20 20 5c 20 64 68 74 20 69 6d 70 6f 72       \ dht impor
0ff0: 74 0a 65 6e 75 6d 20 69 6d 70 6f 72 74 23 69 6e  t.enum import#in
1000: 76 69 74 65 64 20 20 20 5c 20 69 6e 76 69 74 61  vited   \ invita
1010: 74 69 6f 6e 20 69 6d 70 6f 72 74 0a 65 6e 75 6d  tion import.enum
1020: 20 69 6d 70 6f 72 74 23 75 6e 74 72 75 73 74 65   import#untruste
1030: 64 20 5c 20 6d 75 73 74 20 62 65 20 6c 61 73 74  d \ must be last
1040: 0a 64 72 6f 70 0a 24 31 46 20 65 6e 75 6d 20 69  .drop.$1F enum i
1050: 6d 70 6f 72 74 23 6e 65 77 20 20 20 5c 20 6e 65  mport#new   \ ne
1060: 77 20 66 6f 72 6d 61 74 0a 64 72 6f 70 0a 0a 43  w format.drop..C
1070: 72 65 61 74 65 20 69 6d 70 6f 72 74 73 24 20 24  reate imports$ $
1080: 32 30 20 61 6c 6c 6f 74 20 69 6d 70 6f 72 74 73  20 allot imports
1090: 24 20 24 32 30 20 62 6c 20 66 69 6c 6c 0a 22 49  $ $20 bl fill."I
10a0: 6d 73 63 64 69 75 22 20 69 6d 70 6f 72 74 73 24  mscdiu" imports$
10b0: 20 73 77 61 70 20 6d 6f 76 65 0a 0a 56 61 72 69   swap move..Vari
10c0: 61 62 6c 65 20 69 6d 70 6f 72 74 2d 74 79 70 65  able import-type
10d0: 20 20 69 6d 70 6f 72 74 23 6e 65 77 20 69 6d 70    import#new imp
10e0: 6f 72 74 2d 74 79 70 65 20 21 0a 0a 43 72 65 61  ort-type !..Crea
10f0: 74 65 20 3e 69 6d 2d 63 6f 6c 6f 72 20 20 24 42  te >im-color  $B
1100: 36 30 20 2c 20 24 44 36 30 20 2c 20 24 39 36 30  60 , $D60 , $960
1110: 20 2c 20 24 43 36 30 20 2c 20 24 41 36 30 20 2c   , $C60 , $A60 ,
1120: 20 24 38 42 31 20 2c 20 24 45 36 30 20 2c 0a 44   $8B1 , $E60 ,.D
1130: 4f 45 53 3e 20 73 77 61 70 20 38 20 63 65 6c 6c  OES> swap 8 cell
1140: 73 20 30 20 44 4f 20 20 64 75 70 20 31 20 61 6e  s 0 DO  dup 1 an
1150: 64 20 49 46 20 20 64 72 6f 70 20 49 20 4c 45 41  d IF  drop I LEA
1160: 56 45 20 20 54 48 45 4e 20 20 32 2f 20 20 4c 4f  VE  THEN  2/  LO
1170: 4f 50 0a 20 20 63 65 6c 6c 73 20 2b 20 40 20 61  OP.  cells + @ a
1180: 74 74 72 21 20 3b 0a 0a 3a 20 2e 69 6d 70 6f 72  ttr! ;..: .impor
1190: 74 73 20 28 20 6d 61 73 6b 20 2d 2d 20 29 0a 20  ts ( mask -- ). 
11a0: 20 20 20 69 6d 70 6f 72 74 73 24 20 69 6d 70 6f     imports$ impo
11b0: 72 74 23 6e 65 77 20 62 6f 75 6e 64 73 20 44 4f  rt#new bounds DO
11c0: 0a 09 64 75 70 20 31 20 61 6e 64 20 49 46 20 20  ..dup 1 and IF  
11d0: 49 20 63 40 20 65 6d 69 74 20 20 54 48 45 4e 20  I c@ emit  THEN 
11e0: 20 32 2f 20 4c 4f 4f 50 0a 20 20 20 20 64 72 6f   2/ LOOP.    dro
11f0: 70 20 3b 0a 0a 5c 20 73 61 6d 70 6c 65 20 6b 65  p ;..\ sample ke
1200: 79 0a 0a 6b 65 79 2d 65 6e 74 72 79 20 27 20 6e  y..key-entry ' n
1210: 65 77 20 73 74 61 74 69 63 2d 61 20 77 69 74 68  ew static-a with
1220: 2d 61 6c 6c 6f 63 61 74 65 72 20 43 6f 6e 73 74  -allocater Const
1230: 61 6e 74 20 73 61 6d 70 6c 65 2d 6b 65 79 0a 0a  ant sample-key..
1240: 56 61 72 69 61 62 6c 65 20 6b 65 79 23 20 5c 20  Variable key# \ 
1250: 6b 65 79 20 68 61 73 68 20 74 61 62 6c 65 0a 56  key hash table.V
1260: 61 72 69 61 62 6c 65 20 6e 69 63 6b 23 20 5c 20  ariable nick# \ 
1270: 6e 69 63 6b 20 68 61 73 68 20 74 61 62 6c 65 0a  nick hash table.
1280: 0a 36 34 56 61 72 69 61 62 6c 65 20 6b 65 79 2d  .64Variable key-
1290: 72 65 61 64 2d 6f 66 66 73 65 74 0a 0a 3a 20 63  read-offset..: c
12a0: 75 72 72 65 6e 74 2d 6b 65 79 20 28 20 61 64 64  urrent-key ( add
12b0: 72 20 75 20 2d 2d 20 6f 20 29 0a 20 20 20 20 32  r u -- o ).    2
12c0: 64 75 70 20 6b 65 79 7c 20 6b 65 79 23 20 23 40  dup key| key# #@
12d0: 20 64 72 6f 70 0a 20 20 20 20 64 75 70 20 30 3d   drop.    dup 0=
12e0: 20 49 46 20 20 64 72 6f 70 20 2e 22 20 75 6e 6b   IF  drop ." unk
12f0: 6e 6f 77 6e 20 6b 65 79 3a 20 22 20 38 35 74 79  nown key: " 85ty
1300: 70 65 20 63 72 20 20 30 20 45 58 49 54 20 20 54  pe cr  0 EXIT  T
1310: 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b 20 3e 6f  HEN.    cell+ >o
1320: 20 6b 65 2d 70 6b 20 24 21 20 6f 20 6f 3e 20 3b   ke-pk $! o o> ;
1330: 0a 0a 56 61 72 69 61 62 6c 65 20 73 69 6d 2d 6e  ..Variable sim-n
1340: 69 63 6b 21 0a 0a 3a 20 6e 69 63 6b 21 20 28 20  ick!..: nick! ( 
1350: 2d 2d 20 29 20 73 69 6d 2d 6e 69 63 6b 21 20 40  -- ) sim-nick! @
1360: 20 3f 45 58 49 54 20 20 6f 20 7b 20 77 5e 20 6f   ?EXIT  o { w^ o
1370: 70 74 72 20 7d 0a 20 20 20 20 6b 65 2d 6e 69 63  ptr }.    ke-nic
1380: 6b 20 24 40 20 6e 69 63 6b 23 20 23 40 20 64 30  k $@ nick# #@ d0
1390: 3d 20 49 46 0a 09 6f 70 74 72 20 63 65 6c 6c 20  = IF..optr cell 
13a0: 6b 65 2d 6e 69 63 6b 20 24 40 20 6e 69 63 6b 23  ke-nick $@ nick#
13b0: 20 23 21 20 30 0a 20 20 20 20 45 4c 53 45 0a 09   #! 0.    ELSE..
13c0: 6c 61 73 74 23 20 63 65 6c 6c 2b 20 24 40 6c 65  last# cell+ $@le
13d0: 6e 20 63 65 6c 6c 2f 0a 09 6f 70 74 72 20 63 65  n cell/..optr ce
13e0: 6c 6c 20 6c 61 73 74 23 20 63 65 6c 6c 2b 20 24  ll last# cell+ $
13f0: 2b 21 0a 20 20 20 20 54 48 45 4e 20 20 6b 65 2d  +!.    THEN  ke-
1400: 6e 69 63 6b 23 20 21 20 3b 0a 0a 3a 20 23 2e 6e  nick# ! ;..: #.n
1410: 69 63 6b 20 28 20 68 61 73 68 20 2d 2d 20 29 0a  ick ( hash -- ).
1420: 20 20 20 20 64 75 70 20 24 40 20 74 79 70 65 20      dup $@ type 
1430: 27 23 27 20 65 6d 69 74 20 63 65 6c 6c 2b 20 24  '#' emit cell+ $
1440: 40 6c 65 6e 20 63 65 6c 6c 2f 20 2e 20 3b 0a 0a  @len cell/ . ;..
1450: 3a 20 6c 61 73 74 2d 70 65 74 40 20 28 20 2d 2d  : last-pet@ ( --
1460: 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 6b 65   addr u ).    ke
1470: 2d 70 65 74 73 20 24 5b 5d 23 20 3f 64 75 70 2d  -pets $[]# ?dup-
1480: 49 46 20 20 31 2d 20 6b 65 2d 70 65 74 73 20 24  IF  1- ke-pets $
1490: 5b 5d 40 20 20 45 4c 53 45 20 20 23 30 2e 20 20  []@  ELSE  #0.  
14a0: 54 48 45 4e 20 3b 0a 0a 3a 20 70 65 74 21 20 28  THEN ;..: pet! (
14b0: 20 2d 2d 20 29 20 73 69 6d 2d 6e 69 63 6b 21 20   -- ) sim-nick! 
14c0: 40 20 3f 45 58 49 54 20 20 6f 20 7b 20 77 5e 20  @ ?EXIT  o { w^ 
14d0: 6f 70 74 72 20 7d 0a 20 20 20 20 6c 61 73 74 2d  optr }.    last-
14e0: 70 65 74 40 20 6e 69 63 6b 23 20 23 40 20 64 30  pet@ nick# #@ d0
14f0: 3d 20 49 46 0a 09 6f 70 74 72 20 63 65 6c 6c 20  = IF..optr cell 
1500: 6c 61 73 74 2d 70 65 74 40 20 6e 69 63 6b 23 20  last-pet@ nick# 
1510: 23 21 20 30 0a 20 20 20 20 45 4c 53 45 0a 09 6c  #! 0.    ELSE..l
1520: 61 73 74 23 20 63 65 6c 6c 2b 20 24 40 6c 65 6e  ast# cell+ $@len
1530: 20 63 65 6c 6c 2f 0a 09 6f 70 74 72 20 63 65 6c   cell/..optr cel
1540: 6c 20 6c 61 73 74 23 20 63 65 6c 6c 2b 20 24 2b  l last# cell+ $+
1550: 21 0a 20 20 20 20 54 48 45 4e 20 20 6b 65 2d 70  !.    THEN  ke-p
1560: 65 74 73 20 24 5b 5d 23 20 31 2d 20 6b 65 2d 70  ets $[]# 1- ke-p
1570: 65 74 73 23 20 24 5b 5d 20 21 20 3b 0a 0a 3a 20  ets# $[] ! ;..: 
1580: 6b 65 79 3a 6e 65 77 20 28 20 61 64 64 72 20 75  key:new ( addr u
1590: 20 2d 2d 20 6f 20 29 0a 20 20 20 20 5c 47 20 63   -- o ).    \G c
15a0: 72 65 61 74 65 20 6e 65 77 20 6b 65 79 2c 20 61  reate new key, a
15b0: 64 64 72 20 75 20 69 73 20 74 68 65 20 70 75 62  ddr u is the pub
15c0: 6c 69 63 20 6b 65 79 0a 20 20 20 20 73 61 6d 70  lic key.    samp
15d0: 6c 65 2d 6b 65 79 20 3e 6f 20 20 6b 65 2d 73 6b  le-key >o  ke-sk
15e0: 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d 20 65   ke-end over - e
15f0: 72 61 73 65 0a 20 20 20 20 6b 65 79 2d 65 6e 74  rase.    key-ent
1600: 72 79 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65 6e  ry-table @ token
1610: 2d 74 61 62 6c 65 20 21 0a 20 20 20 20 3e 73 74  -table !.    >st
1620: 6f 72 65 6b 65 79 20 40 20 6b 65 2d 73 74 6f 72  orekey @ ke-stor
1630: 65 6b 65 79 20 21 0a 20 20 20 20 6b 65 79 2d 72  ekey !.    key-r
1640: 65 61 64 2d 6f 66 66 73 65 74 20 36 34 40 20 6b  ead-offset 64@ k
1650: 65 2d 6f 66 66 73 65 74 20 36 34 21 0a 20 20 20  e-offset 64!.   
1660: 20 31 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 40   1 import-type @
1670: 20 6c 73 68 69 66 74 20 5b 20 31 20 69 6d 70 6f   lshift [ 1 impo
1680: 72 74 23 6e 65 77 20 6c 73 68 69 66 74 20 5d 4c  rt#new lshift ]L
1690: 20 6f 72 20 6b 65 2d 69 6d 70 6f 72 74 73 20 21   or ke-imports !
16a0: 0a 20 20 20 20 6b 65 79 70 61 63 6b 2d 61 6c 6c  .    keypack-all
16b0: 23 20 6e 3e 36 34 20 6b 65 79 2d 72 65 61 64 2d  # n>64 key-read-
16c0: 6f 66 66 73 65 74 20 36 34 2b 21 20 6f 20 63 65  offset 64+! o ce
16d0: 6c 6c 2d 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20  ll- ke-end over 
16e0: 2d 0a 20 20 20 20 32 6f 76 65 72 20 6b 65 79 7c  -.    2over key|
16f0: 20 6b 65 79 23 20 23 21 20 6f 3e 0a 20 20 20 20   key# #! o>.    
1700: 63 75 72 72 65 6e 74 2d 6b 65 79 20 3b 0a 0a 30  current-key ;..0
1710: 20 56 61 6c 75 65 20 6c 61 73 74 2d 6b 65 79 0a   Value last-key.
1720: 0a 3a 20 6b 65 79 3f 6e 65 77 20 28 20 61 64 64  .: key?new ( add
1730: 72 20 75 20 2d 2d 20 6f 20 29 0a 20 20 20 20 5c  r u -- o ).    \
1740: 47 20 43 72 65 61 74 65 20 6f 72 20 6c 6f 6f 6b  G Create or look
1750: 75 70 20 6e 65 77 20 6b 65 79 0a 20 20 20 20 32  up new key.    2
1760: 64 75 70 20 6b 65 79 7c 20 6b 65 79 23 20 23 40  dup key| key# #@
1770: 20 64 72 6f 70 0a 20 20 20 20 64 75 70 20 30 3d   drop.    dup 0=
1780: 20 49 46 20 20 64 72 6f 70 20 6b 65 79 3a 6e 65   IF  drop key:ne
1790: 77 0a 20 20 20 20 45 4c 53 45 20 20 6e 69 70 20  w.    ELSE  nip 
17a0: 6e 69 70 20 63 65 6c 6c 2b 20 20 31 20 69 6d 70  nip cell+  1 imp
17b0: 6f 72 74 2d 74 79 70 65 20 40 20 6c 73 68 69 66  ort-type @ lshif
17c0: 74 20 6f 76 65 72 20 2e 6b 65 2d 69 6d 70 6f 72  t over .ke-impor
17d0: 74 73 20 6f 72 21 20 20 54 48 45 4e 0a 20 20 20  ts or!  THEN.   
17e0: 20 64 75 70 20 74 6f 20 6c 61 73 74 2d 6b 65 79   dup to last-key
17f0: 20 3b 0a 0a 5c 20 73 65 61 72 63 68 20 66 6f 72   ;..\ search for
1800: 20 6b 65 79 73 20 2d 20 6e 6f 74 20 6f 70 74 69   keys - not opti
1810: 6d 69 7a 65 64 0a 0a 3a 20 23 73 70 6c 69 74 20  mized..: #split 
1820: 28 20 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72  ( addr u -- addr
1830: 20 75 20 6e 20 29 0a 20 20 20 20 5b 3a 20 32 64   u n ).    [: 2d
1840: 75 70 20 27 23 27 20 2d 73 63 61 6e 20 6e 69 70  up '#' -scan nip
1850: 20 3e 72 0a 20 20 20 20 20 20 72 40 20 30 3d 20   >r.      r@ 0= 
1860: 49 46 20 20 72 64 72 6f 70 20 30 20 20 45 58 49  IF  rdrop 0  EXI
1870: 54 20 20 54 48 45 4e 0a 20 20 20 20 20 20 23 30  T  THEN.      #0
1880: 2e 20 32 6f 76 65 72 20 72 40 20 2f 73 74 72 69  . 2over r@ /stri
1890: 6e 67 20 3e 6e 75 6d 62 65 72 0a 20 20 20 20 20  ng >number.     
18a0: 20 30 3d 20 49 46 20 20 6e 69 70 20 64 72 6f 70   0= IF  nip drop
18b0: 20 6e 69 70 20 72 3e 20 31 2d 20 73 77 61 70 20   nip r> 1- swap 
18c0: 20 45 4c 53 45 0a 09 20 20 72 64 72 6f 70 20 64   ELSE..  rdrop d
18d0: 72 6f 70 20 32 64 72 6f 70 20 30 20 20 20 54 48  rop 2drop 0   TH
18e0: 45 4e 20 3b 5d 20 23 31 30 20 62 61 73 65 2d 65  EN ;] #10 base-e
18f0: 78 65 63 75 74 65 20 3b 0a 0a 3a 20 6e 69 63 6b  xecute ;..: nick
1900: 2d 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d  -key ( addr u --
1910: 20 6f 20 2f 20 30 20 29 20 5c 20 73 65 61 72 63   o / 0 ) \ searc
1920: 68 20 66 6f 72 20 6b 65 79 20 6e 69 63 6b 6e 61  h for key nickna
1930: 6d 65 0a 20 20 20 20 23 73 70 6c 69 74 20 3e 72  me.    #split >r
1940: 20 6e 69 63 6b 23 20 23 40 20 32 64 75 70 20 64   nick# #@ 2dup d
1950: 30 3d 20 49 46 20 20 72 64 72 6f 70 20 64 72 6f  0= IF  rdrop dro
1960: 70 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20  p  EXIT  THEN.  
1970: 20 20 72 3e 20 63 65 6c 6c 73 20 73 61 66 65 2f    r> cells safe/
1980: 73 74 72 69 6e 67 20 30 3d 20 49 46 20 20 64 72  string 0= IF  dr
1990: 6f 70 20 30 20 20 45 58 49 54 20 20 54 48 45 4e  op 0  EXIT  THEN
19a0: 20 20 40 20 3b 0a 0a 3a 20 73 65 63 72 65 74 2d    @ ;..: secret-
19b0: 6b 65 79 73 23 20 28 20 2d 2d 20 6e 20 29 0a 20  keys# ( -- n ). 
19c0: 20 20 20 30 20 6b 65 79 23 20 5b 3a 20 63 65 6c     0 key# [: cel
19d0: 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b  l+ $@ drop cell+
19e0: 20 3e 6f 20 6b 65 2d 73 6b 20 40 20 30 3c 3e 20   >o ke-sk @ 0<> 
19f0: 2d 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 3b 0a 3a  - o> ;] #map ;.:
1a00: 20 73 65 63 72 65 74 2d 6b 65 79 20 28 20 6e 20   secret-key ( n 
1a10: 2d 2d 20 6f 2f 30 20 29 0a 20 20 20 20 30 20 74  -- o/0 ).    0 t
1a20: 75 63 6b 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c  uck key# [: cell
1a30: 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20  + $@ drop cell+ 
1a40: 3e 6f 20 6b 65 2d 73 6b 20 40 20 49 46 0a 09 20  >o ke-sk @ IF.. 
1a50: 20 32 64 75 70 20 3d 20 49 46 20 20 72 6f 74 20   2dup = IF  rot 
1a60: 64 72 6f 70 20 6f 20 2d 72 6f 74 20 20 54 48 45  drop o -rot  THE
1a70: 4e 20 20 31 2b 0a 20 20 20 20 20 20 54 48 45 4e  N  1+.      THEN
1a80: 20 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 32 64 72    o> ;] #map 2dr
1a90: 6f 70 20 3b 0a 3a 20 2e 23 20 28 20 6e 20 2d 2d  op ;.: .# ( n --
1aa0: 20 29 20 3f 64 75 70 2d 49 46 20 20 27 23 27 20   ) ?dup-IF  '#' 
1ab0: 65 6d 69 74 20 30 20 2e 72 20 20 54 48 45 4e 20  emit 0 .r  THEN 
1ac0: 3b 0a 3a 20 2e 6e 69 63 6b 2d 62 61 73 65 20 28  ;.: .nick-base (
1ad0: 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20   o:key -- ).    
1ae0: 6b 65 2d 6e 69 63 6b 20 24 2e 20 20 6b 65 2d 6e  ke-nick $.  ke-n
1af0: 69 63 6b 23 20 40 20 2e 23 20 3b 0a 3a 20 2e 70  ick# @ .# ;.: .p
1b00: 65 74 2d 62 61 73 65 20 28 20 6f 3a 6b 65 79 20  et-base ( o:key 
1b10: 2d 2d 20 29 0a 20 20 20 20 30 20 6b 65 2d 70 65  -- ).    0 ke-pe
1b20: 74 73 20 5b 3a 20 73 70 61 63 65 20 74 79 70 65  ts [: space type
1b30: 0a 20 20 20 20 20 20 64 75 70 20 6b 65 2d 70 65  .      dup ke-pe
1b40: 74 73 23 20 24 5b 5d 20 40 20 2e 23 20 20 31 2b  ts# $[] @ .#  1+
1b50: 20 3b 5d 20 24 5b 5d 6d 61 70 20 64 72 6f 70 20   ;] $[]map drop 
1b60: 3b 0a 3a 20 2e 70 65 74 30 2d 62 61 73 65 20 28  ;.: .pet0-base (
1b70: 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20   o:key -- ).    
1b80: 6b 65 2d 70 65 74 73 20 24 5b 5d 23 20 49 46 20  ke-pets $[]# IF 
1b90: 20 30 20 6b 65 2d 70 65 74 73 20 24 5b 5d 40 20   0 ke-pets $[]@ 
1ba0: 74 79 70 65 20 30 20 6b 65 2d 70 65 74 73 23 20  type 0 ke-pets# 
1bb0: 24 5b 5d 20 40 20 2e 23 0a 20 20 20 20 45 4c 53  $[] @ .#.    ELS
1bc0: 45 20 20 2e 6e 69 63 6b 2d 62 61 73 65 20 20 54  E  .nick-base  T
1bd0: 48 45 4e 20 3b 0a 3a 20 2e 72 65 61 6c 2d 6e 69  HEN ;.: .real-ni
1be0: 63 6b 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 20  ck ( o:key -- ) 
1bf0: 20 20 6b 65 2d 69 6d 70 6f 72 74 73 20 40 20 3e    ke-imports @ >
1c00: 69 6d 2d 63 6f 6c 6f 72 20 2e 6e 69 63 6b 2d 62  im-color .nick-b
1c10: 61 73 65 20 3c 64 65 66 61 75 6c 74 3e 20 3b 0a  ase <default> ;.
1c20: 3a 20 2e 6e 69 63 6b 20 28 20 6f 3a 6b 65 79 20  : .nick ( o:key 
1c30: 2d 2d 20 29 20 20 20 6b 65 2d 69 6d 70 6f 72 74  -- )   ke-import
1c40: 73 20 40 20 3e 69 6d 2d 63 6f 6c 6f 72 20 2e 70  s @ >im-color .p
1c50: 65 74 30 2d 62 61 73 65 20 3c 64 65 66 61 75 6c  et0-base <defaul
1c60: 74 3e 20 3b 0a 3a 20 2e 6e 69 63 6b 2b 70 65 74  t> ;.: .nick+pet
1c70: 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20   ( o:key -- ).  
1c80: 20 20 6b 65 2d 69 6d 70 6f 72 74 73 20 40 20 3e    ke-imports @ >
1c90: 69 6d 2d 63 6f 6c 6f 72 20 2e 6e 69 63 6b 2d 62  im-color .nick-b
1ca0: 61 73 65 20 2e 70 65 74 2d 62 61 73 65 20 3c 64  ase .pet-base <d
1cb0: 65 66 61 75 6c 74 3e 20 3b 0a 0a 3a 20 6e 69 63  efault> ;..: nic
1cc0: 6b 3e 70 6b 20 28 20 6e 69 63 6b 20 75 20 2d 2d  k>pk ( nick u --
1cd0: 20 70 6b 20 75 20 29 0a 20 20 20 20 6e 69 63 6b   pk u ).    nick
1ce0: 2d 6b 65 79 20 3f 64 75 70 2d 49 46 20 2e 6b 65  -key ?dup-IF .ke
1cf0: 2d 70 6b 20 24 40 20 45 4c 53 45 20 30 20 30 20  -pk $@ ELSE 0 0 
1d00: 54 48 45 4e 20 3b 0a 3a 20 68 6f 73 74 2e 6e 69  THEN ;.: host.ni
1d10: 63 6b 3e 70 6b 20 28 20 61 64 64 72 20 75 20 2d  ck>pk ( addr u -
1d20: 2d 20 70 6b 20 75 27 20 29 0a 20 20 20 20 27 2e  - pk u' ).    '.
1d30: 27 20 24 73 70 6c 69 74 20 64 75 70 20 30 3d 20  ' $split dup 0= 
1d40: 49 46 20 20 32 73 77 61 70 20 20 54 48 45 4e 20  IF  2swap  THEN 
1d50: 5b 3a 20 6e 69 63 6b 3e 70 6b 20 74 79 70 65 20  [: nick>pk type 
1d60: 74 79 70 65 20 3b 5d 20 24 74 6d 70 20 3b 0a 0a  type ;] $tmp ;..
1d70: 3a 20 6b 65 79 2d 65 78 69 73 74 3f 20 28 20 61  : key-exist? ( a
1d80: 64 64 72 20 75 20 2d 2d 20 6f 2f 30 20 29 0a 20  ddr u -- o/0 ). 
1d90: 20 20 20 6b 65 79 23 20 23 40 20 49 46 20 20 63     key# #@ IF  c
1da0: 65 6c 6c 2b 20 20 54 48 45 4e 20 3b 20 0a 0a 5c  ell+  THEN ; ..\
1db0: 20 70 65 72 6d 69 73 73 69 6f 6e 20 6d 6f 64 69   permission modi
1dc0: 66 69 63 61 74 69 6f 6e 0a 0a 32 36 20 62 75 66  fication..26 buf
1dd0: 66 65 72 3a 20 70 65 72 6d 2d 63 68 61 72 73 0a  fer: perm-chars.
1de0: 30 20 70 65 72 6d 24 20 63 6f 75 6e 74 20 62 6f  0 perm$ count bo
1df0: 75 6e 64 73 20 5b 44 4f 5d 20 64 75 70 20 5b 49  unds [DO] dup [I
1e00: 5d 20 63 40 20 27 61 27 20 2d 20 70 65 72 6d 2d  ] c@ 'a' - perm-
1e10: 63 68 61 72 73 20 2b 20 63 21 20 31 2b 20 5b 4c  chars + c! 1+ [L
1e20: 4f 4f 50 5d 20 64 72 6f 70 0a 0a 3a 20 2e 70 65  OOP] drop..: .pe
1e30: 72 6d 20 28 20 70 65 72 6d 69 73 73 69 6f 6e 20  rm ( permission 
1e40: 2d 2d 20 29 20 20 31 20 70 65 72 6d 24 20 63 6f  -- )  1 perm$ co
1e50: 75 6e 74 20 62 6f 75 6e 64 73 20 44 4f 0a 09 32  unt bounds DO..2
1e60: 64 75 70 20 61 6e 64 20 30 3c 3e 20 49 20 63 40  dup and 0<> I c@
1e70: 20 27 2d 27 20 72 6f 74 20 73 65 6c 65 63 74 20   '-' rot select 
1e80: 65 6d 69 74 20 32 2a 0a 20 20 20 20 4c 4f 4f 50  emit 2*.    LOOP
1e90: 20 20 32 64 72 6f 70 20 3b 0a 3a 20 70 65 72 6d    2drop ;.: perm
1ea0: 61 6e 64 20 28 20 70 65 72 6d 61 6e 64 20 70 65  and ( permand pe
1eb0: 72 6d 6f 72 20 6e 65 77 20 2d 2d 20 70 65 72 6d  rmor new -- perm
1ec0: 61 6e 64 27 20 70 65 72 6d 6f 72 20 29 0a 20 20  and' permor ).  
1ed0: 20 20 69 6e 76 65 72 74 20 74 75 63 6b 20 61 6e    invert tuck an
1ee0: 64 20 3e 72 20 61 6e 64 20 72 3e 20 3b 0a 3a 20  d >r and r> ;.: 
1ef0: 3e 70 65 72 6d 2d 6d 6f 64 20 28 20 70 65 72 6d  >perm-mod ( perm
1f00: 61 6e 64 20 70 65 72 6d 6f 72 20 2d 2d 20 70 65  and permor -- pe
1f10: 72 6d 61 6e 64 27 20 70 65 72 6d 6f 72 20 29 0a  rmand' permor ).
1f20: 20 20 20 20 73 77 61 70 20 64 75 70 20 30 3d 20      swap dup 0= 
1f30: 49 46 20 20 64 72 6f 70 20 64 75 70 20 69 6e 76  IF  drop dup inv
1f40: 65 72 74 20 20 54 48 45 4e 20 73 77 61 70 20 3b  ert  THEN swap ;
1f50: 0a 3a 20 3e 70 65 72 6d 20 28 20 61 64 64 72 20  .: >perm ( addr 
1f60: 75 20 2d 2d 20 70 65 72 6d 61 6e 64 20 70 65 72  u -- permand per
1f70: 6d 6f 72 20 29 0a 20 20 20 20 5c 47 20 70 61 72  mor ).    \G par
1f80: 73 65 20 70 65 72 6d 69 73 73 69 6f 6e 73 3a 20  se permissions: 
1f90: 2b 20 61 64 64 73 2c 20 2d 20 72 65 6d 6f 76 65  + adds, - remove
1fa0: 73 20 70 65 72 6d 69 73 73 69 6f 6e 73 2c 0a 20  s permissions,. 
1fb0: 20 20 20 5c 47 20 6e 6f 20 6d 6f 64 69 66 69 65     \G no modifie
1fc0: 72 20 73 65 74 73 20 70 65 72 6d 69 73 73 6f 6e  r sets permisson
1fd0: 73 2e 0a 20 20 20 20 30 20 30 20 5b 27 5d 20 6f  s..    0 0 ['] o
1fe0: 72 20 7b 20 78 74 20 7d 0a 20 20 20 20 32 73 77  r { xt }.    2sw
1ff0: 61 70 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 49  ap bounds ?DO..I
2000: 20 63 40 20 63 61 73 65 0a 09 20 20 20 20 27 2b   c@ case..    '+
2010: 27 20 6f 66 20 20 3e 70 65 72 6d 2d 6d 6f 64 20  ' of  >perm-mod 
2020: 5b 27 5d 20 6f 72 20 74 6f 20 78 74 20 65 6e 64  ['] or to xt end
2030: 6f 66 0a 09 20 20 20 20 27 2d 27 20 6f 66 20 20  of..    '-' of  
2040: 3e 70 65 72 6d 2d 6d 6f 64 20 5b 27 5d 20 70 65  >perm-mod ['] pe
2050: 72 6d 61 6e 64 20 74 6f 20 78 74 20 20 65 6e 64  rmand to xt  end
2060: 6f 66 0a 09 20 20 20 20 27 3d 27 20 6f 66 20 20  of..    '=' of  
2070: 32 64 72 6f 70 20 70 65 72 6d 25 64 65 66 61 75  2drop perm%defau
2080: 6c 74 20 64 75 70 20 5b 27 5d 20 6f 72 20 74 6f  lt dup ['] or to
2090: 20 78 74 20 20 65 6e 64 6f 66 0a 09 20 20 20 20   xt  endof..    
20a0: 27 61 27 20 2d 20 64 75 70 20 27 7a 27 20 75 3c  'a' - dup 'z' u<
20b0: 3d 20 20 49 46 0a 09 09 70 65 72 6d 2d 63 68 61  =  IF...perm-cha
20c0: 72 73 20 2b 20 63 40 20 31 20 73 77 61 70 20 6c  rs + c@ 1 swap l
20d0: 73 68 69 66 74 20 78 74 20 65 78 65 63 75 74 65  shift xt execute
20e0: 0a 09 09 30 20 28 20 64 75 6d 6d 79 20 66 6f 72  ...0 ( dummy for
20f0: 20 65 6e 64 63 61 73 65 20 29 0a 09 20 20 20 20   endcase )..    
2100: 54 48 45 4e 20 20 65 6e 64 63 61 73 65 0a 20 20  THEN  endcase.  
2110: 20 20 4c 4f 4f 50 20 3b 0a 3a 20 2e 70 65 72 6d    LOOP ;.: .perm
2120: 61 6e 64 6f 72 20 28 20 70 65 72 6d 61 6e 64 20  andor ( permand 
2130: 70 65 72 6d 6f 72 20 2d 2d 20 29 0a 20 20 20 20  permor -- ).    
2140: 30 20 7b 20 2b 2d 20 7d 0a 20 20 20 20 31 20 70  0 { +- }.    1 p
2150: 65 72 6d 24 20 63 6f 75 6e 74 20 62 6f 75 6e 64  erm$ count bound
2160: 73 20 44 4f 20 20 3e 72 0a 09 6f 76 65 72 20 72  s DO  >r..over r
2170: 40 20 61 6e 64 20 30 3d 20 49 46 20 20 27 2d 27  @ and 0= IF  '-'
2180: 20 64 75 70 20 2b 2d 20 3c 3e 20 49 46 20 20 64   dup +- <> IF  d
2190: 75 70 20 74 6f 20 2b 2d 20 65 6d 69 74 0a 09 20  up to +- emit.. 
21a0: 20 20 20 45 4c 53 45 20 20 64 72 6f 70 20 20 54     ELSE  drop  T
21b0: 48 45 4e 20 72 3e 20 20 49 20 63 40 20 65 6d 69  HEN r>  I c@ emi
21c0: 74 20 20 3e 72 20 54 48 45 4e 0a 09 64 75 70 20  t  >r THEN..dup 
21d0: 20 72 40 20 61 6e 64 20 20 20 20 49 46 20 20 27   r@ and    IF  '
21e0: 2b 27 20 64 75 70 20 2b 2d 20 3c 3e 20 49 46 20  +' dup +- <> IF 
21f0: 20 64 75 70 20 74 6f 20 2b 2d 20 65 6d 69 74 0a   dup to +- emit.
2200: 09 20 20 20 20 45 4c 53 45 20 20 64 72 6f 70 20  .    ELSE  drop 
2210: 20 54 48 45 4e 20 72 3e 20 20 49 20 63 40 20 65   THEN r>  I c@ e
2220: 6d 69 74 20 20 3e 72 20 54 48 45 4e 0a 09 72 3e  mit  >r THEN..r>
2230: 20 32 2a 0a 20 20 20 20 4c 4f 4f 50 20 20 64 72   2*.    LOOP  dr
2240: 6f 70 20 32 64 72 6f 70 20 3b 0a 0a 5c 20 72 65  op 2drop ;..\ re
2250: 61 64 20 69 6e 20 70 65 72 6d 69 73 73 69 6f 6e  ad in permission
2260: 20 67 72 6f 75 70 73 2c 20 67 72 6f 75 70 73 20   groups, groups 
2270: 69 73 20 69 6e 20 74 68 65 20 2e 6e 65 74 32 6f  is in the .net2o
2280: 20 64 69 72 65 63 74 6f 72 79 0a 0a 3a 20 3e 67   directory..: >g
2290: 72 6f 75 70 73 20 28 20 61 64 64 72 20 75 20 70  roups ( addr u p
22a0: 61 6e 64 20 70 6f 72 20 2d 2d 20 29 0a 20 20 20  and por -- ).   
22b0: 20 73 22 20 22 20 67 72 6f 75 70 73 5b 5d 20 24   s" " groups[] $
22c0: 2b 5b 5d 21 0a 20 20 20 20 5b 3a 20 7b 20 64 5e  +[]!.    [: { d^
22d0: 20 70 61 6e 64 6f 72 20 7d 20 70 61 6e 64 6f 72   pandor } pandor
22e0: 20 32 20 63 65 6c 6c 73 20 74 79 70 65 20 20 74   2 cells type  t
22f0: 79 70 65 20 3b 5d 0a 20 20 20 20 67 72 6f 75 70  ype ;].    group
2300: 73 5b 5d 20 64 75 70 20 24 5b 5d 23 20 31 2d 20  s[] dup $[]# 1- 
2310: 73 77 61 70 20 24 5b 5d 20 24 65 78 65 63 20 3b  swap $[] $exec ;
2320: 0a 0a 3a 20 69 6e 69 74 2d 67 72 6f 75 70 73 20  ..: init-groups 
2330: 28 20 2d 2d 20 29 0a 20 20 20 20 22 6d 79 73 65  ( -- ).    "myse
2340: 6c 66 22 20 20 70 65 72 6d 25 6d 79 73 65 6c 66  lf"  perm%myself
2350: 20 20 64 75 70 20 3e 67 72 6f 75 70 73 0a 20 20    dup >groups.  
2360: 20 20 22 70 65 65 72 22 20 20 20 20 70 65 72 6d    "peer"    perm
2370: 25 64 65 66 61 75 6c 74 20 64 75 70 20 3e 67 72  %default dup >gr
2380: 6f 75 70 73 0a 20 20 20 20 22 75 6e 6b 6e 6f 77  oups.    "unknow
2390: 6e 22 20 70 65 72 6d 25 75 6e 6b 6e 6f 77 6e 20  n" perm%unknown 
23a0: 64 75 70 20 3e 67 72 6f 75 70 73 0a 20 20 20 20  dup >groups.    
23b0: 22 62 6c 6f 63 6b 65 64 22 20 70 65 72 6d 25 62  "blocked" perm%b
23c0: 6c 6f 63 6b 65 64 20 64 75 70 20 3e 67 72 6f 75  locked dup >grou
23d0: 70 73 20 3b 0a 0a 69 6e 69 74 2d 67 72 6f 75 70  ps ;..init-group
23e0: 73 0a 0a 3a 20 2e 67 72 6f 75 70 73 20 28 20 2d  s..: .groups ( -
23f0: 2d 20 29 0a 20 20 20 20 67 72 6f 75 70 73 5b 5d  - ).    groups[]
2400: 20 5b 3a 20 32 64 75 70 20 32 20 63 65 6c 6c 73   [: 2dup 2 cells
2410: 20 2f 73 74 72 69 6e 67 20 74 79 70 65 20 73 70   /string type sp
2420: 61 63 65 0a 20 20 20 20 20 20 64 72 6f 70 20 32  ace.      drop 2
2430: 40 20 2e 70 65 72 6d 61 6e 64 6f 72 20 63 72 20  @ .permandor cr 
2440: 3b 5d 20 24 5b 5d 6d 61 70 20 3b 0a 0a 3a 20 2e  ;] $[]map ;..: .
2450: 69 6e 2d 67 72 6f 75 70 73 20 28 20 61 64 64 72  in-groups ( addr
2460: 20 75 20 2d 2d 20 29 0a 20 20 20 20 62 6f 75 6e   u -- ).    boun
2470: 64 73 20 3f 44 4f 0a 09 49 20 70 40 2b 20 49 20  ds ?DO..I p@+ I 
2480: 2d 20 3e 72 20 36 34 3e 6e 20 67 72 6f 75 70 73  - >r 64>n groups
2490: 5b 5d 20 24 5b 5d 40 20 32 20 63 65 6c 6c 73 20  [] $[]@ 2 cells 
24a0: 2f 73 74 72 69 6e 67 20 74 79 70 65 20 73 70 61  /string type spa
24b0: 63 65 0a 20 20 20 20 72 3e 20 2b 4c 4f 4f 50 20  ce.    r> +LOOP 
24c0: 3b 0a 0a 3a 20 77 72 69 74 65 2d 67 72 6f 75 70  ;..: write-group
24d0: 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 22 67 72  s ( -- ).    "gr
24e0: 6f 75 70 73 22 20 2e 6e 65 74 32 6f 2f 20 77 2f  oups" .net2o/ w/
24f0: 6f 20 63 72 65 61 74 65 2d 66 69 6c 65 20 74 68  o create-file th
2500: 72 6f 77 20 3e 72 0a 20 20 20 20 5b 27 5d 20 2e  row >r.    ['] .
2510: 67 72 6f 75 70 73 20 72 40 20 6f 75 74 66 69 6c  groups r@ outfil
2520: 65 2d 65 78 65 63 75 74 65 0a 20 20 20 20 72 3e  e-execute.    r>
2530: 20 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f   close-file thro
2540: 77 20 3b 0a 0a 3a 20 67 72 6f 75 70 2d 6c 69 6e  w ;..: group-lin
2550: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 70 61 72  e ( -- ).    par
2560: 73 65 2d 6e 61 6d 65 20 70 61 72 73 65 2d 6e 61  se-name parse-na
2570: 6d 65 20 3e 70 65 72 6d 20 3e 67 72 6f 75 70 73  me >perm >groups
2580: 20 3b 0a 0a 3a 20 72 65 61 64 2d 67 72 6f 75 70   ;..: read-group
2590: 73 2d 6c 6f 6f 70 20 28 20 2d 2d 20 29 0a 20 20  s-loop ( -- ).  
25a0: 20 20 42 45 47 49 4e 20 20 72 65 66 69 6c 6c 20    BEGIN  refill 
25b0: 20 57 48 49 4c 45 20 20 67 72 6f 75 70 2d 6c 69   WHILE  group-li
25c0: 6e 65 20 20 52 45 50 45 41 54 20 3b 0a 0a 3a 20  ne  REPEAT ;..: 
25d0: 72 65 61 64 2d 67 72 6f 75 70 73 20 28 20 2d 2d  read-groups ( --
25e0: 20 29 0a 20 20 20 20 22 67 72 6f 75 70 73 22 20   ).    "groups" 
25f0: 2e 6e 65 74 32 6f 2f 20 32 64 75 70 20 66 69 6c  .net2o/ 2dup fil
2600: 65 2d 73 74 61 74 75 73 20 6e 69 70 20 6e 6f 2d  e-status nip no-
2610: 66 69 6c 65 23 20 3d 20 49 46 0a 09 69 6e 69 74  file# = IF..init
2620: 2d 67 72 6f 75 70 73 20 77 72 69 74 65 2d 67 72  -groups write-gr
2630: 6f 75 70 73 0a 20 20 20 20 54 48 45 4e 20 20 3e  oups.    THEN  >
2640: 69 6e 63 6c 75 64 65 64 20 74 68 72 6f 77 0a 20  included throw. 
2650: 20 20 20 5b 27 5d 20 72 65 61 64 2d 67 72 6f 75     ['] read-grou
2660: 70 73 2d 6c 6f 6f 70 20 65 78 65 63 75 74 65 2d  ps-loop execute-
2670: 70 61 72 73 69 6e 67 2d 6e 61 6d 65 64 2d 66 69  parsing-named-fi
2680: 6c 65 20 3b 0a 0a 3a 20 67 72 6f 75 70 73 3e 6d  le ;..: groups>m
2690: 61 73 6b 20 28 20 61 64 64 72 20 75 20 2d 2d 20  ask ( addr u -- 
26a0: 6d 61 73 6b 20 29 0a 20 20 20 20 30 20 2d 72 6f  mask ).    0 -ro
26b0: 74 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 49 20  t bounds ?DO..I 
26c0: 70 40 2b 20 49 20 2d 20 3e 72 0a 09 36 34 3e 6e  p@+ I - >r..64>n
26d0: 20 64 75 70 20 67 72 6f 75 70 73 5b 5d 20 24 5b   dup groups[] $[
26e0: 5d 23 20 75 3e 3d 20 21 21 6e 6f 2d 67 72 6f 75  ]# u>= !!no-grou
26f0: 70 21 21 0a 09 67 72 6f 75 70 73 5b 5d 20 24 5b  p!!..groups[] $[
2700: 5d 40 20 64 72 6f 70 20 32 40 20 3e 72 20 61 6e  ]@ drop 2@ >r an
2710: 64 20 72 3e 20 6f 72 0a 20 20 20 20 72 3e 20 2b  d r> or.    r> +
2720: 4c 4f 4f 50 20 3b 0a 0a 3a 20 3f 3e 67 72 6f 75  LOOP ;..: ?>grou
2730: 70 73 20 28 20 6d 61 73 6b 20 2d 2d 20 6d 61 73  ps ( mask -- mas
2740: 6b 27 20 29 0a 20 20 20 20 6b 65 2d 67 72 6f 75  k' ).    ke-grou
2750: 70 73 20 24 40 6c 65 6e 20 30 3d 20 49 46 0a 09  ps $@len 0= IF..
2760: 34 20 30 20 44 4f 0a 09 20 20 20 20 64 75 70 20  4 0 DO..    dup 
2770: 49 20 67 72 6f 75 70 73 5b 5d 20 24 5b 5d 40 20  I groups[] $[]@ 
2780: 64 72 6f 70 20 63 65 6c 6c 2b 20 40 0a 09 20 20  drop cell+ @..  
2790: 20 20 6f 72 20 6f 76 65 72 20 3d 20 49 46 0a 09    or over = IF..
27a0: 09 49 20 6b 65 2d 67 72 6f 75 70 73 20 63 24 2b  .I ke-groups c$+
27b0: 21 20 49 20 67 72 6f 75 70 73 5b 5d 20 24 5b 5d  ! I groups[] $[]
27c0: 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 40 20 69  @ drop cell+ @ i
27d0: 6e 76 65 72 74 20 61 6e 64 0a 09 20 20 20 20 54  nvert and..    T
27e0: 48 45 4e 0a 09 4c 4f 4f 50 0a 20 20 20 20 54 48  HEN..LOOP.    TH
27f0: 45 4e 20 20 64 72 6f 70 20 3b 0a 0a 5c 20 6b 65  EN  drop ;..\ ke
2800: 79 20 64 69 73 70 6c 61 79 0a 0a 5b 49 46 55 4e  y display..[IFUN
2810: 44 45 46 5d 20 6d 61 67 65 6e 74 61 20 20 62 72  DEF] magenta  br
2820: 6f 77 6e 20 63 6f 6e 73 74 61 6e 74 20 6d 61 67  own constant mag
2830: 65 6e 74 61 20 5b 54 48 45 4e 5d 0a 5b 49 46 44  enta [THEN].[IFD
2840: 45 46 5d 20 67 6c 2d 74 79 70 65 20 3a 20 62 67  EF] gl-type : bg
2850: 7c 20 3e 62 67 20 6f 72 20 3b 20 5b 45 4c 53 45  | >bg or ; [ELSE
2860: 5d 20 3a 20 62 67 7c 20 64 72 6f 70 20 3b 20 5b  ] : bg| drop ; [
2870: 54 48 45 4e 5d 0a 0a 43 72 65 61 74 65 20 38 35  THEN]..Create 85
2880: 63 6f 6c 6f 72 73 2d 62 77 0a 30 20 2c 20 69 6e  colors-bw.0 , in
2890: 76 65 72 73 20 2c 0a 69 6e 76 65 72 73 20 2c 20  vers ,.invers , 
28a0: 30 20 2c 0a 30 20 2c 20 69 6e 76 65 72 73 20 2c  0 ,.0 , invers ,
28b0: 0a 69 6e 76 65 72 73 20 2c 20 30 20 2c 0a 43 72  .invers , 0 ,.Cr
28c0: 65 61 74 65 20 38 35 63 6f 6c 6f 72 73 2d 63 6c  eate 85colors-cl
28d0: 0a 79 65 6c 6c 6f 77 20 3e 66 67 20 62 6c 75 65  .yellow >fg blue
28e0: 20 3e 62 67 20 6f 72 20 62 6f 6c 64 20 6f 72 20   >bg or bold or 
28f0: 2c 20 72 65 64 20 3e 66 67 20 77 68 69 74 65 20  , red >fg white 
2900: 62 67 7c 20 2c 0a 62 6c 61 63 6b 20 3e 66 67 20  bg| ,.black >fg 
2910: 63 79 61 6e 20 62 67 7c 20 2c 20 67 72 65 65 6e  cyan bg| , green
2920: 20 3e 66 67 20 62 6c 61 63 6b 20 3e 62 67 20 6f   >fg black >bg o
2930: 72 20 62 6f 6c 64 20 6f 72 20 2c 0a 77 68 69 74  r bold or ,.whit
2940: 65 20 3e 66 67 20 62 6c 61 63 6b 20 3e 62 67 20  e >fg black >bg 
2950: 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 20 6d 61 67  or bold or , mag
2960: 65 6e 74 61 20 3e 66 67 20 79 65 6c 6c 6f 77 20  enta >fg yellow 
2970: 62 67 7c 20 2c 0a 62 6c 75 65 20 3e 66 67 20 79  bg| ,.blue >fg y
2980: 65 6c 6c 6f 77 20 62 67 7c 20 2c 20 63 79 61 6e  ellow bg| , cyan
2990: 20 3e 66 67 20 72 65 64 20 3e 62 67 20 6f 72 20   >fg red >bg or 
29a0: 62 6f 6c 64 20 6f 72 20 2c 0a 0a 5b 49 46 44 45  bold or ,..[IFDE
29b0: 46 5d 20 67 6c 2d 74 79 70 65 20 38 35 63 6f 6c  F] gl-type 85col
29c0: 6f 72 73 2d 63 6c 20 5b 45 4c 53 45 5d 20 38 35  ors-cl [ELSE] 85
29d0: 63 6f 6c 6f 72 73 2d 62 77 20 5b 54 48 45 4e 5d  colors-bw [THEN]
29e0: 20 56 61 6c 75 65 20 38 35 63 6f 6c 6f 72 73 0a   Value 85colors.
29f0: 0a 3a 20 2e 73 74 72 69 70 65 38 35 20 28 20 61  .: .stripe85 ( a
2a00: 64 64 72 20 75 20 2d 2d 20 29 20 20 30 20 2d 72  ddr u -- )  0 -r
2a10: 6f 74 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 64  ot bounds ?DO..d
2a20: 75 70 20 63 65 6c 6c 73 20 38 35 63 6f 6c 6f 72  up cells 85color
2a30: 73 20 2b 20 40 20 61 74 74 72 21 20 31 2b 0a 09  s + @ attr! 1+..
2a40: 49 20 34 20 38 35 74 79 70 65 20 20 64 75 70 20  I 4 85type  dup 
2a50: 63 65 6c 6c 73 20 38 35 63 6f 6c 6f 72 73 20 2b  cells 85colors +
2a60: 20 40 20 61 74 74 72 21 20 31 2b 0a 20 20 20 20   @ attr! 1+.    
2a70: 49 20 34 20 2b 20 34 20 38 35 74 79 70 65 20 3c  I 4 + 4 85type <
2a80: 64 65 66 61 75 6c 74 3e 20 63 72 20 38 20 2b 4c  default> cr 8 +L
2a90: 4f 4f 50 20 20 64 72 6f 70 20 3b 0a 3a 20 2e 69  OOP  drop ;.: .i
2aa0: 6d 70 6f 72 74 38 35 20 28 20 61 64 64 72 20 75  mport85 ( addr u
2ab0: 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d 69 6d 70   -- ).    ke-imp
2ac0: 6f 72 74 73 20 40 20 3e 69 6d 2d 63 6f 6c 6f 72  orts @ >im-color
2ad0: 20 38 35 74 79 70 65 20 3c 64 65 66 61 75 6c 74   85type <default
2ae0: 3e 20 3b 0a 3a 20 2e 72 73 6b 20 28 20 6e 69 63  > ;.: .rsk ( nic
2af0: 6b 20 75 20 2d 2d 20 29 0a 20 20 20 20 73 6b 72  k u -- ).    skr
2b00: 65 76 20 24 32 30 20 2e 73 74 72 69 70 65 38 35  ev $20 .stripe85
2b10: 20 73 70 61 63 65 20 74 79 70 65 20 2e 22 20 20   space type ."  
2b20: 28 6b 65 65 70 20 6f 66 66 6c 69 6e 65 20 63 6f  (keep offline co
2b30: 70 79 21 29 22 20 63 72 20 3b 0a 3a 20 2e 6b 65  py!)" cr ;.: .ke
2b40: 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20  y ( addr u -- ) 
2b50: 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a 20 20  drop cell+ >o.  
2b60: 20 20 2e 22 20 6e 69 63 6b 3a 20 20 20 22 20 2e    ." nick:   " .
2b70: 6e 69 63 6b 20 63 72 0a 20 20 20 20 2e 22 20 70  nick cr.    ." p
2b80: 75 62 6b 65 79 3a 20 22 20 6b 65 2d 70 6b 20 24  ubkey: " ke-pk $
2b90: 40 20 38 35 74 79 70 65 20 63 72 0a 20 20 20 20  @ 85type cr.    
2ba0: 6b 65 2d 73 6b 20 40 20 49 46 0a 09 2e 22 20 73  ke-sk @ IF..." s
2bb0: 65 63 6b 65 79 3a 20 22 20 6b 65 2d 73 6b 20 73  eckey: " ke-sk s
2bc0: 65 63 40 20 2e 62 6c 61 63 6b 38 35 20 2e 22 20  ec@ .black85 ." 
2bd0: 20 28 6b 65 65 70 20 73 65 63 72 65 74 21 29 22   (keep secret!)"
2be0: 20 63 72 20 20 54 48 45 4e 0a 20 20 20 20 2e 22   cr  THEN.    ."
2bf0: 20 76 61 6c 69 64 3a 20 20 22 20 6b 65 2d 73 65   valid:  " ke-se
2c00: 6c 66 73 69 67 20 24 40 20 2e 73 69 67 64 61 74  lfsig $@ .sigdat
2c10: 65 73 20 63 72 0a 20 20 20 20 2e 22 20 67 72 6f  es cr.    ." gro
2c20: 75 70 73 3a 20 22 20 6b 65 2d 67 72 6f 75 70 73  ups: " ke-groups
2c30: 20 24 40 20 2e 69 6e 2d 67 72 6f 75 70 73 20 63   $@ .in-groups c
2c40: 72 0a 20 20 20 20 2e 22 20 70 65 72 6d 3a 20 20  r.    ." perm:  
2c50: 20 22 20 6b 65 2d 6d 61 73 6b 20 40 20 2e 70 65   " ke-mask @ .pe
2c60: 72 6d 20 63 72 0a 20 20 20 20 6f 3e 20 3b 0a 3a  rm cr.    o> ;.:
2c70: 20 2e 6b 65 79 2d 72 65 73 74 20 28 20 6f 3a 6b   .key-rest ( o:k
2c80: 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20  ey -- o:key ).  
2c90: 20 20 6b 65 2d 70 6b 20 24 40 20 6b 65 79 7c 20    ke-pk $@ key| 
2ca0: 2e 69 6d 70 6f 72 74 38 35 0a 20 20 20 20 6b 65  .import85.    ke
2cb0: 2d 73 65 6c 66 73 69 67 20 24 40 20 73 70 61 63  -selfsig $@ spac
2cc0: 65 20 2e 73 69 67 64 61 74 65 73 0a 20 20 20 20  e .sigdates.    
2cd0: 73 70 61 63 65 20 6b 65 2d 67 72 6f 75 70 73 20  space ke-groups 
2ce0: 24 40 20 2e 69 6e 2d 67 72 6f 75 70 73 0a 20 20  $@ .in-groups.  
2cf0: 20 20 6b 65 2d 6d 61 73 6b 20 40 20 2e 70 65 72    ke-mask @ .per
2d00: 6d 0a 20 20 20 20 73 70 61 63 65 20 6b 65 2d 69  m.    space ke-i
2d10: 6d 70 6f 72 74 73 20 40 20 2e 69 6d 70 6f 72 74  mports @ .import
2d20: 73 0a 20 20 20 20 73 70 61 63 65 20 2e 6e 69 63  s.    space .nic
2d30: 6b 2b 70 65 74 20 3b 0a 3a 20 2e 6b 65 79 2d 6c  k+pet ;.: .key-l
2d40: 69 73 74 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 6f  ist ( o:key -- o
2d50: 3a 6b 65 79 20 29 0a 20 20 20 20 6b 65 2d 6f 66  :key ).    ke-of
2d60: 66 73 65 74 20 36 34 40 20 36 34 3e 64 20 6b 65  fset 64@ 64>d ke
2d70: 79 70 61 63 6b 2d 61 6c 6c 23 20 66 6d 2f 6d 6f  ypack-all# fm/mo
2d80: 64 20 6e 69 70 20 33 20 2e 72 20 73 70 61 63 65  d nip 3 .r space
2d90: 0a 20 20 20 20 2e 6b 65 79 2d 72 65 73 74 20 63  .    .key-rest c
2da0: 72 20 3b 0a 3a 20 2e 73 65 63 72 65 74 2d 6e 69  r ;.: .secret-ni
2db0: 63 6b 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 30  cks ( -- ).    0
2dc0: 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b 20 24   key# [: cell+ $
2dd0: 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 20  @ drop cell+ >o 
2de0: 6b 65 2d 73 6b 20 40 20 49 46 0a 09 20 20 5b 3a  ke-sk @ IF..  [:
2df0: 20 64 75 70 20 31 20 2e 72 20 3b 5d 20 23 33 36   dup 1 .r ;] #36
2e00: 20 62 61 73 65 2d 65 78 65 63 75 74 65 20 73 70   base-execute sp
2e10: 61 63 65 20 2e 6b 65 79 2d 72 65 73 74 20 63 72  ace .key-rest cr
2e20: 20 31 2b 0a 20 20 20 20 20 20 54 48 45 4e 20 6f   1+.      THEN o
2e30: 3e 20 3b 5d 20 23 6d 61 70 20 64 72 6f 70 20 3b  > ;] #map drop ;
2e40: 0a 3a 20 2e 6b 65 79 2d 69 6e 76 69 74 65 20 28  .: .key-invite (
2e50: 20 6f 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20   o:key -- o:key 
2e60: 29 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 6b  ).    ke-pk $@ k
2e70: 65 79 73 69 7a 65 20 75 6d 69 6e 0a 20 20 20 20  eysize umin.    
2e80: 6b 65 2d 69 6d 70 6f 72 74 73 20 40 20 3e 69 6d  ke-imports @ >im
2e90: 2d 63 6f 6c 6f 72 20 38 35 74 79 70 65 20 3c 64  -color 85type <d
2ea0: 65 66 61 75 6c 74 3e 0a 20 20 20 20 73 70 61 63  efault>.    spac
2eb0: 65 20 2e 6e 69 63 6b 20 73 70 61 63 65 20 3b 0a  e .nick space ;.
2ec0: 3a 20 2e 6b 65 79 2d 73 68 6f 72 74 20 28 20 6f  : .key-short ( o
2ed0: 3a 6b 65 79 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a  :key -- o:key ).
2ee0: 20 20 20 20 6b 65 2d 6e 69 63 6b 20 24 2e 20 6b      ke-nick $. k
2ef0: 65 2d 70 72 6f 66 20 24 40 6c 65 6e 20 49 46 20  e-prof $@len IF 
2f00: 2e 22 20 20 70 72 6f 66 69 6c 65 3a 20 22 20 6b  ."  profile: " k
2f10: 65 2d 70 72 6f 66 20 24 40 20 38 35 74 79 70 65  e-prof $@ 85type
2f20: 20 54 48 45 4e 20 3b 0a 3a 20 6c 69 73 74 2d 6b   THEN ;.: list-k
2f30: 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 2e  eys ( -- ).    .
2f40: 22 20 6e 75 6d 20 70 75 62 6b 65 79 20 20 20 20  " num pubkey    
2f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2f60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 64                 d
2f70: 61 74 65 20 20 20 20 20 20 20 20 20 20 20 20 20  ate             
2f80: 20 20 20 20 20 20 20 20 67 72 6f 75 70 2b 70 65          group+pe
2f90: 72 6d 20 68 20 6e 69 63 6b 22 20 63 72 0a 20 20  rm h nick" cr.  
2fa0: 20 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c 2b 20    key# [: cell+ 
2fb0: 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20 2e 2e  $@ drop cell+ ..
2fc0: 6b 65 79 2d 6c 69 73 74 20 3b 5d 20 23 6d 61 70  key-list ;] #map
2fd0: 20 3b 0a 3a 20 6c 69 73 74 2d 6e 69 63 6b 73 20   ;.: list-nicks 
2fe0: 28 20 2d 2d 20 29 0a 20 20 20 20 6e 69 63 6b 23  ( -- ).    nick#
2ff0: 20 5b 3a 20 64 75 70 20 24 2e 20 2e 22 20 3a 22   [: dup $. ." :"
3000: 20 63 72 20 63 65 6c 6c 2b 20 24 40 20 62 6f 75   cr cell+ $@ bou
3010: 6e 64 73 20 3f 44 4f 0a 09 20 20 49 20 40 20 2e  nds ?DO..  I @ .
3020: 2e 6b 65 79 2d 6c 69 73 74 20 20 63 65 6c 6c 20  .key-list  cell 
3030: 2b 4c 4f 4f 50 20 3b 5d 20 23 6d 61 70 20 3b 0a  +LOOP ;] #map ;.
3040: 0a 3a 20 64 75 6d 70 6b 65 79 20 28 20 61 64 64  .: dumpkey ( add
3050: 72 20 75 20 2d 2d 20 29 20 64 72 6f 70 20 63 65  r u -- ) drop ce
3060: 6c 6c 2b 20 3e 6f 0a 20 20 20 20 2e 5c 22 20 78  ll+ >o.    .\" x
3070: 5c 22 20 22 20 6b 65 2d 70 6b 20 24 40 20 38 35  \" " ke-pk $@ 85
3080: 74 79 70 65 20 2e 5c 22 20 5c 22 20 6b 65 79 3f  type .\" \" key?
3090: 6e 65 77 22 20 63 72 0a 20 20 20 20 6b 65 2d 73  new" cr.    ke-s
30a0: 6b 20 40 20 49 46 20 20 2e 5c 22 20 78 5c 22 20  k @ IF  .\" x\" 
30b0: 22 20 6b 65 2d 73 6b 20 40 20 6b 65 79 73 69 7a  " ke-sk @ keysiz
30c0: 65 20 38 35 74 79 70 65 20 2e 5c 22 20 5c 22 20  e 85type .\" \" 
30d0: 6b 65 2d 73 6b 20 73 65 63 21 20 2b 73 65 63 6b  ke-sk sec! +seck
30e0: 65 79 22 20 63 72 20 20 54 48 45 4e 0a 20 20 20  ey" cr  THEN.   
30f0: 20 27 22 27 20 65 6d 69 74 20 2e 6e 69 63 6b 20   '"' emit .nick 
3100: 2e 5c 22 20 5c 22 20 6b 65 2d 6e 69 63 6b 20 24  .\" \" ke-nick $
3110: 21 20 22 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73  ! ".    ke-selfs
3120: 69 67 20 24 40 20 64 72 6f 70 20 36 34 40 20 36  ig $@ drop 64@ 6
3130: 34 3e 64 20 5b 3a 20 27 24 27 20 65 6d 69 74 20  4>d [: '$' emit 
3140: 30 20 75 64 2e 72 20 3b 5d 20 24 31 30 20 62 61  0 ud.r ;] $10 ba
3150: 73 65 2d 65 78 65 63 75 74 65 0a 20 20 20 20 2e  se-execute.    .
3160: 22 20 2e 20 64 3e 36 34 20 6b 65 2d 66 69 72 73  " . d>64 ke-firs
3170: 74 21 20 22 20 6b 65 2d 74 79 70 65 20 40 20 2e  t! " ke-type @ .
3180: 20 2e 22 20 6b 65 2d 74 79 70 65 20 21 22 20 20   ." ke-type !"  
3190: 63 72 20 6f 3e 20 3b 0a 0a 3a 20 2e 6b 65 79 73  cr o> ;..: .keys
31a0: 20 28 20 2d 2d 20 29 20 6b 65 79 23 20 5b 3a 20   ( -- ) key# [: 
31b0: 2e 22 20 69 6e 64 65 78 3a 20 22 20 64 75 70 20  ." index: " dup 
31c0: 24 40 20 38 35 74 79 70 65 20 63 72 20 63 65 6c  $@ 85type cr cel
31d0: 6c 2b 20 24 40 20 2e 6b 65 79 20 3b 5d 20 23 6d  l+ $@ .key ;] #m
31e0: 61 70 20 3b 0a 3a 20 64 75 6d 70 6b 65 79 73 20  ap ;.: dumpkeys 
31f0: 28 20 2d 2d 20 29 20 6b 65 79 23 20 5b 3a 20 63  ( -- ) key# [: c
3200: 65 6c 6c 2b 20 24 40 20 64 75 6d 70 6b 65 79 20  ell+ $@ dumpkey 
3210: 3b 5d 20 23 6d 61 70 20 3b 0a 0a 3a 20 6b 65 79  ;] #map ;..: key
3220: 3e 6e 69 63 6b 20 28 20 61 64 64 72 6b 65 79 20  >nick ( addrkey 
3230: 75 31 20 2d 2d 20 6e 69 63 6b 20 75 32 20 29 0a  u1 -- nick u2 ).
3240: 20 20 20 20 5c 47 20 63 6f 6e 76 65 72 74 20 6b      \G convert k
3250: 65 79 20 74 6f 20 6e 69 63 6b 0a 20 20 20 20 6b  ey to nick.    k
3260: 65 79 7c 20 6b 65 79 23 20 23 40 20 30 3d 20 49  ey| key# #@ 0= I
3270: 46 20 20 64 72 6f 70 20 23 30 2e 20 20 45 58 49  F  drop #0.  EXI
3280: 54 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c  T  THEN.    cell
3290: 2b 20 2e 6b 65 2d 6e 69 63 6b 20 24 40 20 3b 0a  + .ke-nick $@ ;.
32a0: 3a 20 6b 65 79 3e 6b 65 79 20 28 20 61 64 64 72  : key>key ( addr
32b0: 6b 65 79 20 75 31 20 2d 2d 20 6b 65 79 20 75 32  key u1 -- key u2
32c0: 20 29 0a 20 20 20 20 5c 47 20 65 78 70 61 6e 64   ).    \G expand
32d0: 20 6b 65 79 20 74 6f 20 66 75 6c 6c 20 73 69 7a   key to full siz
32e0: 65 20 61 6e 64 20 63 68 65 63 6b 20 69 66 20 77  e and check if w
32f0: 65 20 6b 6e 6f 77 20 69 74 0a 20 20 20 20 6b 65  e know it.    ke
3300: 79 7c 20 6b 65 79 23 20 23 40 20 30 3d 20 49 46  y| key# #@ 0= IF
3310: 20 20 64 72 6f 70 20 23 30 2e 20 20 45 58 49 54    drop #0.  EXIT
3320: 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b    THEN.    cell+
3330: 20 2e 6b 65 2d 70 6b 20 24 40 20 3b 0a 0a 3a 20   .ke-pk $@ ;..: 
3340: 2e 6b 65 79 23 20 28 20 61 64 64 72 20 75 20 2d  .key# ( addr u -
3350: 2d 20 29 20 6b 65 79 7c 0a 20 20 20 20 2e 22 20  - ) key|.    ." 
3360: 4b 65 79 20 27 22 20 6b 65 79 23 20 23 40 20 30  Key '" key# #@ 0
3370: 3d 20 49 46 20 64 72 6f 70 20 45 58 49 54 20 54  = IF drop EXIT T
3380: 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b 20 2e 2e  HEN.    cell+ ..
3390: 6e 69 63 6b 20 2e 22 20 27 20 6f 6b 22 20 63 72  nick ." ' ok" cr
33a0: 20 3b 0a 0a 44 65 66 65 72 20 64 68 74 2d 6e 69   ;..Defer dht-ni
33b0: 63 6b 3f 0a 65 76 65 6e 74 3a 20 2d 3e 73 65 61  ck?.event: ->sea
33c0: 72 63 68 2d 6b 65 79 20 20 6b 65 79 7c 20 6f 76  rch-key  key| ov
33d0: 65 72 20 3e 72 20 64 68 74 2d 6e 69 63 6b 3f 20  er >r dht-nick? 
33e0: 72 3e 20 66 72 65 65 20 74 68 72 6f 77 20 3b 0a  r> free throw ;.
33f0: 0a 3a 20 2e 75 6e 6b 65 79 2d 69 64 20 28 20 61  .: .unkey-id ( a
3400: 64 64 72 20 75 20 2d 2d 20 29 20 3c 65 72 72 3e  ddr u -- ) <err>
3410: 20 38 20 75 6d 69 6e 20 38 35 74 79 70 65 20 2e   8 umin 85type .
3420: 22 20 28 75 6e 6b 6e 6f 77 6e 29 22 20 3c 64 65  " (unknown)" <de
3430: 66 61 75 6c 74 3e 20 3b 0a 0a 56 61 72 69 61 62  fault> ;..Variab
3440: 6c 65 20 75 6e 6b 65 79 2d 69 64 23 0a 23 36 30  le unkey-id#.#60
3450: 2e 30 30 30 2e 30 30 30 2e 30 30 30 20 64 3e 36  .000.000.000 d>6
3460: 34 20 36 34 43 6f 6e 73 74 61 6e 74 20 75 6e 6b  4 64Constant unk
3470: 65 79 2d 74 6f 23 0a 3a 20 3f 75 6e 6b 65 79 20  ey-to#.: ?unkey 
3480: 28 20 61 64 64 72 20 75 20 2d 2d 20 66 6c 61 67  ( addr u -- flag
3490: 20 29 0a 20 20 20 20 75 6e 6b 65 79 2d 69 64 23   ).    unkey-id#
34a0: 20 23 40 0a 20 20 20 20 49 46 20 20 36 34 40 20   #@.    IF  64@ 
34b0: 75 6e 6b 65 79 2d 74 6f 23 20 36 34 2b 20 74 69  unkey-to# 64+ ti
34c0: 63 6b 73 20 36 34 2d 20 36 34 2d 30 3e 3d 20 20  cks 64- 64-0>=  
34d0: 54 48 45 4e 20 20 30 3d 20 3b 0a 20 20 20 20 0a  THEN  0= ;.    .
34e0: 3a 20 2e 6b 65 79 2d 69 64 20 28 20 61 64 64 72  : .key-id ( addr
34f0: 20 75 20 2d 2d 20 29 20 6b 65 79 7c 20 32 64 75   u -- ) key| 2du
3500: 70 20 6b 65 79 23 20 23 40 20 30 3d 0a 20 20 20  p key# #@ 0=.   
3510: 20 49 46 20 20 64 72 6f 70 20 75 70 40 20 72 65   IF  drop up@ re
3520: 63 65 69 76 65 72 2d 74 61 73 6b 20 3d 20 49 46  ceiver-task = IF
3530: 0a 09 20 20 20 20 3c 65 76 65 6e 74 20 32 64 75  ..    <event 2du
3540: 70 20 73 61 76 65 2d 6d 65 6d 20 65 24 2c 20 2d  p save-mem e$, -
3550: 3e 73 65 61 72 63 68 2d 6b 65 79 20 6d 61 69 6e  >search-key main
3560: 2d 75 70 40 20 65 76 65 6e 74 3e 0a 09 20 20 20  -up@ event>..   
3570: 20 2e 75 6e 6b 65 79 2d 69 64 20 45 58 49 54 20   .unkey-id EXIT 
3580: 20 54 48 45 4e 0a 09 32 64 75 70 20 3f 75 6e 6b   THEN..2dup ?unk
3590: 65 79 20 20 49 46 0a 09 20 20 20 20 74 69 63 6b  ey  IF..    tick
35a0: 73 20 7b 20 36 34 5e 20 74 78 20 7d 20 74 78 20  s { 64^ tx } tx 
35b0: 31 20 36 34 73 20 32 6f 76 65 72 20 75 6e 6b 65  1 64s 2over unke
35c0: 79 2d 69 64 23 20 23 21 0a 09 20 20 20 20 63 6f  y-id# #!..    co
35d0: 6e 6e 65 63 74 69 6f 6e 20 3e 72 20 32 64 75 70  nnection >r 2dup
35e0: 20 5b 27 5d 20 64 68 74 2d 6e 69 63 6b 3f 20 63   ['] dht-nick? c
35f0: 6d 64 2d 6e 65 73 74 20 72 3e 20 74 6f 20 63 6f  md-nest r> to co
3600: 6e 6e 65 63 74 69 6f 6e 0a 09 20 20 20 20 32 64  nnection..    2d
3610: 75 70 20 6b 65 79 23 20 23 40 20 30 3d 20 49 46  up key# #@ 0= IF
3620: 20 20 64 72 6f 70 20 2e 75 6e 6b 65 79 2d 69 64    drop .unkey-id
3630: 20 45 58 49 54 0a 09 20 20 20 20 45 4c 53 45 20   EXIT..    ELSE 
3640: 20 3e 72 20 32 64 75 70 20 75 6e 6b 65 79 2d 69   >r 2dup unkey-i
3650: 64 23 20 23 6f 66 66 20 72 3e 20 20 54 48 45 4e  d# #off r>  THEN
3660: 0a 09 45 4c 53 45 20 20 2e 75 6e 6b 65 79 2d 69  ..ELSE  .unkey-i
3670: 64 20 20 45 58 49 54 20 20 54 48 45 4e 0a 20 20  d  EXIT  THEN.  
3680: 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c 6c 2b    THEN.    cell+
3690: 20 2e 2e 6e 69 63 6b 20 32 64 72 6f 70 20 3b 0a   ..nick 2drop ;.
36a0: 0a 3a 20 2e 63 6f 6e 2d 69 64 20 28 20 6f 3a 63  .: .con-id ( o:c
36b0: 6f 6e 6e 65 63 74 69 6f 6e 20 2d 2d 20 29 20 70  onnection -- ) p
36c0: 75 62 6b 65 79 20 24 40 20 2e 6b 65 79 2d 69 64  ubkey $@ .key-id
36d0: 20 3b 0a 0a 3a 20 2e 73 69 6d 70 6c 65 2d 69 64   ;..: .simple-id
36e0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b   ( addr u -- ) k
36f0: 65 79 3e 6e 69 63 6b 20 74 79 70 65 20 3b 0a 0a  ey>nick type ;..
3700: 3a 20 63 68 65 63 6b 2d 6b 65 79 20 28 20 61 64  : check-key ( ad
3710: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 6f 20  dr u -- ).    o 
3720: 49 46 20 20 70 75 62 6b 65 79 20 40 20 49 46 0a  IF  pubkey @ IF.
3730: 09 20 20 20 20 32 64 75 70 20 70 75 62 6b 65 79  .    2dup pubkey
3740: 20 24 40 20 6b 65 79 7c 20 73 74 72 3d 20 30 3d   $@ key| str= 0=
3750: 20 49 46 0a 09 09 5b 3a 20 2e 22 20 77 61 6e 74   IF...[: ." want
3760: 3a 20 22 20 70 75 62 6b 65 79 20 24 40 20 6b 65  : " pubkey $@ ke
3770: 79 7c 20 38 35 74 79 70 65 20 63 72 0a 09 09 20  y| 85type cr... 
3780: 20 2e 22 20 67 6f 74 20 3a 20 22 20 32 64 75 70   ." got : " 2dup
3790: 20 38 35 74 79 70 65 20 63 72 20 3b 5d 20 24 65   85type cr ;] $e
37a0: 72 72 0a 09 09 74 72 75 65 20 21 21 77 72 6f 6e  rr...true !!wron
37b0: 67 2d 6b 65 79 21 21 0a 09 20 20 20 20 54 48 45  g-key!!..    THE
37c0: 4e 0a 09 20 20 20 20 63 6f 6e 6e 65 63 74 28 20  N..    connect( 
37d0: 2e 6b 65 79 23 20 29 65 6c 73 65 28 20 32 64 72  .key# )else( 2dr
37e0: 6f 70 20 29 20 20 45 58 49 54 0a 09 54 48 45 4e  op )  EXIT..THEN
37f0: 20 20 54 48 45 4e 0a 20 20 20 20 32 64 75 70 20    THEN.    2dup 
3800: 6b 65 79 2d 65 78 69 73 74 3f 0a 20 20 20 20 3f  key-exist?.    ?
3810: 64 75 70 2d 30 3d 2d 49 46 20 20 70 65 72 6d 25  dup-0=-IF  perm%
3820: 75 6e 6b 6e 6f 77 6e 20 20 45 4c 53 45 20 20 2e  unknown  ELSE  .
3830: 6b 65 2d 6d 61 73 6b 20 40 20 20 54 48 45 4e 20  ke-mask @  THEN 
3840: 20 74 6d 70 2d 70 65 72 6d 20 21 0a 20 20 20 20   tmp-perm !.    
3850: 63 6f 6e 6e 65 63 74 28 20 32 64 75 70 20 2e 6b  connect( 2dup .k
3860: 65 79 23 20 29 0a 20 20 20 20 74 6d 70 2d 70 65  ey# ).    tmp-pe
3870: 72 6d 20 40 20 70 65 72 6d 25 62 6c 6f 63 6b 65  rm @ perm%blocke
3880: 64 20 61 6e 64 20 49 46 0a 09 5b 3a 20 2e 22 20  d and IF..[: ." 
3890: 55 6e 6b 6e 6f 77 6e 20 6b 65 79 2c 20 63 6f 6e  Unknown key, con
38a0: 6e 65 63 74 69 6f 6e 20 72 65 66 75 73 65 64 3a  nection refused:
38b0: 20 22 20 38 35 74 79 70 65 20 63 72 20 3b 5d 20   " 85type cr ;] 
38c0: 24 65 72 72 0a 09 74 72 75 65 20 21 21 63 6f 6e  $err..true !!con
38d0: 6e 65 63 74 2d 70 65 72 6d 21 21 0a 20 20 20 20  nect-perm!!.    
38e0: 45 4c 53 45 20 20 32 64 72 6f 70 20 20 54 48 45  ELSE  2drop  THE
38f0: 4e 20 3b 0a 0a 3a 20 73 65 61 72 63 68 2d 6b 65  N ;..: search-ke
3900: 79 20 28 20 70 6b 63 20 2d 2d 20 73 6b 63 20 29  y ( pkc -- skc )
3910: 0a 20 20 20 20 6b 65 79 73 69 7a 65 20 6b 65 79  .    keysize key
3920: 23 20 23 40 20 30 3d 20 21 21 75 6e 6b 6e 6f 77  # #@ 0= !!unknow
3930: 6e 2d 6b 65 79 21 21 0a 20 20 20 20 63 65 6c 6c  n-key!!.    cell
3940: 2b 20 2e 6b 65 2d 73 6b 20 73 65 63 40 20 30 3d  + .ke-sk sec@ 0=
3950: 20 21 21 75 6e 6b 6e 6f 77 6e 2d 6b 65 79 21 21   !!unknown-key!!
3960: 20 3b 0a 0a 5c 20 61 70 70 6c 79 20 70 65 72 6d   ;..\ apply perm
3970: 69 73 73 69 6f 6e 73 0a 0a 3a 20 61 70 70 6c 79  issions..: apply
3980: 2d 70 65 72 6d 69 73 73 69 6f 6e 20 28 20 70 65  -permission ( pe
3990: 72 6d 61 6e 64 20 70 65 72 6d 6f 72 20 6f 3a 6b  rmand permor o:k
39a0: 65 79 20 2d 2d 20 70 65 72 6d 61 6e 64 20 70 65  ey -- permand pe
39b0: 72 6d 6f 72 20 6f 3a 6b 65 79 20 29 0a 20 20 20  rmor o:key ).   
39c0: 20 6f 76 65 72 20 6b 65 2d 6d 61 73 6b 20 40 20   over ke-mask @ 
39d0: 61 6e 64 20 6f 76 65 72 20 6f 72 20 6b 65 2d 6d  and over or ke-m
39e0: 61 73 6b 20 21 20 2e 6b 65 79 2d 6c 69 73 74 20  ask ! .key-list 
39f0: 3b 0a 0a 5c 20 67 65 74 20 70 61 73 73 70 68 72  ;..\ get passphr
3a00: 61 73 65 0a 0a 33 20 56 61 6c 75 65 20 70 61 73  ase..3 Value pas
3a10: 73 70 68 72 61 73 65 2d 72 65 74 72 79 23 0a 24  sphrase-retry#.$
3a20: 31 30 30 20 43 6f 6e 73 74 61 6e 74 20 6d 61 78  100 Constant max
3a30: 2d 70 61 73 73 70 68 72 61 73 65 23 20 5c 20 32  -passphrase# \ 2
3a40: 35 36 20 63 68 61 72 61 63 74 65 72 73 20 73 68  56 characters sh
3a50: 6f 75 6c 64 20 62 65 20 65 6e 6f 75 67 68 2e 2e  ould be enough..
3a60: 2e 0a 6d 61 78 2d 70 61 73 73 70 68 72 61 73 65  ..max-passphrase
3a70: 23 20 62 75 66 66 65 72 3a 20 70 61 73 73 70 68  # buffer: passph
3a80: 72 61 73 65 0a 0a 3a 20 70 61 73 73 70 68 72 61  rase..: passphra
3a90: 73 65 2d 69 6e 20 28 20 61 64 64 72 20 75 20 2d  se-in ( addr u -
3aa0: 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 22  - addr u ).    "
3ab0: 50 41 53 53 50 48 52 41 53 45 22 20 67 65 74 65  PASSPHRASE" gete
3ac0: 6e 76 20 32 64 75 70 20 64 30 3d 20 49 46 20 20  nv 2dup d0= IF  
3ad0: 32 64 72 6f 70 20 74 79 70 65 0a 09 70 61 73 73  2drop type..pass
3ae0: 70 68 72 61 73 65 20 64 75 70 20 6d 61 78 2d 70  phrase dup max-p
3af0: 61 73 73 70 68 72 61 73 65 23 20 61 63 63 65 70  assphrase# accep
3b00: 74 2a 20 63 72 0a 20 20 20 20 45 4c 53 45 20 20  t* cr.    ELSE  
3b10: 32 6e 69 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20  2nip  THEN ;..: 
3b20: 3e 70 61 73 73 70 68 72 61 73 65 20 28 20 61 64  >passphrase ( ad
3b30: 64 72 20 75 20 2d 2d 20 61 64 64 72 20 75 20 29  dr u -- addr u )
3b40: 0a 20 20 20 20 5c 47 20 63 72 65 61 74 65 20 61  .    \G create a
3b50: 20 35 31 32 20 62 69 74 20 68 61 73 68 20 6f 66   512 bit hash of
3b60: 20 74 68 65 20 70 61 73 73 70 68 72 61 73 65 0a   the passphrase.
3b70: 20 20 20 20 6e 6f 2d 6b 65 79 20 3e 63 3a 6b 65      no-key >c:ke
3b80: 79 20 63 3a 68 61 73 68 0a 20 20 20 20 6b 65 63  y c:hash.    kec
3b90: 63 61 6b 2d 70 61 64 64 65 64 20 63 3a 6b 65 79  cak-padded c:key
3ba0: 3e 20 6b 65 63 63 61 6b 2d 70 61 64 64 65 64 20  > keccak-padded 
3bb0: 6b 65 63 63 61 6b 23 6d 61 78 20 32 2f 20 3b 0a  keccak#max 2/ ;.
3bc0: 0a 3a 20 67 65 74 2d 70 61 73 73 70 68 72 61 73  .: get-passphras
3bd0: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 61 64  e ( addr u -- ad
3be0: 64 72 20 75 20 29 0a 20 20 20 20 70 61 73 73 70  dr u ).    passp
3bf0: 68 72 61 73 65 2d 69 6e 20 3e 70 61 73 73 70 68  hrase-in >passph
3c00: 72 61 73 65 20 3b 0a 0a 56 61 72 69 61 62 6c 65  rase ;..Variable
3c10: 20 6b 65 79 73 0a 0a 3a 20 6c 61 73 74 6b 65 79   keys..: lastkey
3c20: 40 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29 20  @ ( -- addr u ) 
3c30: 6b 65 79 73 20 24 5b 5d 23 20 31 2d 20 6b 65 79  keys $[]# 1- key
3c40: 73 20 73 65 63 5b 5d 40 20 3b 0a 3a 20 6b 65 79  s sec[]@ ;.: key
3c50: 3e 64 65 66 61 75 6c 74 20 28 20 2d 2d 20 29 20  >default ( -- ) 
3c60: 6c 61 73 74 6b 65 79 40 20 64 72 6f 70 20 3e 73  lastkey@ drop >s
3c70: 74 6f 72 65 6b 65 79 20 21 20 3b 0a 3a 20 2b 6b  torekey ! ;.: +k
3c80: 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29  ey ( addr u -- )
3c90: 20 6b 65 79 73 20 73 65 63 2b 5b 5d 21 20 3b 0a   keys sec+[]! ;.
3ca0: 3a 20 2b 70 61 73 73 70 68 72 61 73 65 20 28 20  : +passphrase ( 
3cb0: 61 64 64 72 20 75 20 2d 2d 20 29 20 20 67 65 74  addr u -- )  get
3cc0: 2d 70 61 73 73 70 68 72 61 73 65 20 2b 6b 65 79  -passphrase +key
3cd0: 20 3b 0a 3a 20 2b 63 68 65 63 6b 70 68 72 61 73   ;.: +checkphras
3ce0: 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20 66 6c  e ( addr u -- fl
3cf0: 61 67 20 29 20 67 65 74 2d 70 61 73 73 70 68 72  ag ) get-passphr
3d00: 61 73 65 20 6c 61 73 74 6b 65 79 40 20 73 74 72  ase lastkey@ str
3d10: 3d 20 3b 0a 3a 20 2b 6e 65 77 70 68 72 61 73 65  = ;.: +newphrase
3d20: 20 28 20 2d 2d 20 29 0a 20 20 20 20 42 45 47 49   ( -- ).    BEGI
3d30: 4e 0a 09 73 22 20 50 61 73 73 70 68 72 61 73 65  N..s" Passphrase
3d40: 3a 20 22 20 2b 70 61 73 73 70 68 72 61 73 65 0a  : " +passphrase.
3d50: 09 73 22 20 52 65 74 79 70 65 20 70 6c 73 3a 20  .s" Retype pls: 
3d60: 22 20 2b 63 68 65 63 6b 70 68 72 61 73 65 20 30  " +checkphrase 0
3d70: 3d 20 57 48 49 4c 45 0a 09 20 20 20 20 63 72 20  = WHILE..    cr 
3d80: 2e 22 20 20 64 69 64 6e 27 74 20 6d 61 74 63 68  ."  didn't match
3d90: 2c 20 74 72 79 20 61 67 61 69 6e 20 70 6c 65 61  , try again plea
3da0: 73 65 22 20 63 72 0a 20 20 20 20 52 45 50 45 41  se" cr.    REPEA
3db0: 54 20 63 72 20 3b 0a 0a 3a 20 22 3e 70 61 73 73  T cr ;..: ">pass
3dc0: 70 68 72 61 73 65 20 28 20 61 64 64 72 20 75 20  phrase ( addr u 
3dd0: 2d 2d 20 29 20 3e 70 61 73 73 70 68 72 61 73 65  -- ) >passphrase
3de0: 20 2b 6b 65 79 20 3b 0a 3a 20 3e 73 65 63 6b 65   +key ;.: >secke
3df0: 79 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a  y ( -- addr u ).
3e00: 20 20 20 20 6b 65 2d 73 6b 20 40 20 6b 65 2d 70      ke-sk @ ke-p
3e10: 6b 20 24 40 20 64 72 6f 70 20 6b 65 79 70 61 64  k $@ drop keypad
3e20: 20 65 64 2d 64 68 20 3b 0a 3a 20 2b 73 65 63 6b   ed-dh ;.: +seck
3e30: 65 79 20 28 20 2d 2d 20 29 20 3e 73 65 63 6b 65  ey ( -- ) >secke
3e40: 79 20 2b 6b 65 79 20 3b 0a 0a 5c 20 22 22 20 22  y +key ;..\ "" "
3e50: 3e 70 61 73 73 70 68 72 61 73 65 20 5c 20 66 6f  >passphrase \ fo
3e60: 6c 6c 6f 77 69 6e 67 20 74 68 65 20 65 6e 63 72  llowing the encr
3e70: 79 70 74 2d 65 76 65 72 79 74 68 69 6e 67 20 70  ypt-everything p
3e80: 61 72 61 64 69 67 6d 2c 0a 5c 20 6e 6f 20 70 61  aradigm,.\ no pa
3e90: 73 73 77 6f 72 64 20 69 73 20 74 68 65 20 65 6d  ssword is the em
3ea0: 70 74 79 20 73 74 72 69 6e 67 21 20 20 49 74 27  pty string!  It'
3eb0: 73 20 73 74 69 6c 6c 20 65 6e 63 72 79 70 74 65  s still encrypte
3ec0: 64 20 3b 2d 29 21 0a 0a 5c 20 61 20 73 65 63 72  d ;-)!..\ a secr
3ed0: 65 74 20 6b 65 79 20 6a 75 73 74 20 6e 65 65 64  et key just need
3ee0: 73 20 61 20 6e 69 63 6b 20 61 6e 64 20 61 20 74  s a nick and a t
3ef0: 79 70 65 2e 0a 5c 20 53 65 63 72 65 74 20 6b 65  ype..\ Secret ke
3f00: 79 73 20 63 61 6e 20 62 65 20 70 65 72 73 6f 6e  ys can be person
3f10: 73 20 61 6e 64 20 67 72 6f 75 70 73 2e 0a 0a 5c  s and groups...\
3f20: 20 61 20 70 75 62 6c 69 63 20 6b 65 79 20 6e 65   a public key ne
3f30: 65 64 73 20 6d 6f 72 65 3a 20 6e 69 63 6b 2c 20  eds more: nick, 
3f40: 74 79 70 65 2c 20 70 72 6f 66 69 6c 65 2e 0a 5c  type, profile..\
3f50: 20 54 68 65 20 70 72 6f 66 69 6c 65 20 69 73 20   The profile is 
3f60: 61 20 73 74 72 75 63 74 75 72 65 64 20 64 6f 63  a structured doc
3f70: 75 6d 65 6e 74 2c 20 69 2e 65 2e 20 70 6f 69 6e  ument, i.e. poin
3f80: 74 65 64 20 74 6f 20 62 79 20 61 20 68 61 73 68  ted to by a hash
3f90: 2e 0a 0a 5c 20 61 20 73 69 67 6e 61 74 75 72 65  ...\ a signature
3fa0: 20 63 6f 6e 74 61 69 6e 73 20 61 20 70 75 62 6b   contains a pubk
3fb0: 65 79 2c 20 61 20 63 68 65 63 6b 62 6f 78 20 62  ey, a checkbox b
3fc0: 69 74 6d 61 73 6b 2c 0a 5c 20 61 20 64 61 74 65  itmask,.\ a date
3fd0: 2c 20 61 6e 20 65 78 70 69 72 61 74 69 6f 6e 20  , an expiration 
3fe0: 64 61 74 65 2c 20 74 68 65 20 73 69 67 6e 65 72  date, the signer
3ff0: 27 73 20 70 75 62 6b 65 79 20 61 6e 64 20 74 68  's pubkey and th
4000: 65 20 73 69 67 6e 61 74 75 72 65 20 69 74 73 65  e signature itse
4010: 6c 66 0a 5c 20 28 72 2b 73 29 2e 20 20 54 68 65  lf.\ (r+s).  The
4020: 72 65 20 69 73 20 61 6e 20 6f 70 74 69 6f 6e 61  re is an optiona
4030: 6c 20 73 69 67 6e 69 6e 67 20 70 72 6f 74 6f 63  l signing protoc
4040: 6f 6c 20 64 6f 63 75 6d 65 6e 74 20 28 68 61 73  ol document (has
4050: 68 29 2e 0a 0a 5c 20 77 65 20 73 74 6f 72 65 20  h)...\ we store 
4060: 65 61 63 68 20 69 74 65 6d 20 69 6e 20 61 20 32  each item in a 2
4070: 35 36 20 62 79 74 65 73 20 65 6e 63 72 79 70 74  56 bytes encrypt
4080: 65 64 20 73 74 72 69 6e 67 2c 20 69 2e 65 2e 20  ed string, i.e. 
4090: 77 69 74 68 20 61 20 31 36 0a 5c 20 62 79 74 65  with a 16.\ byte
40a0: 20 73 61 6c 74 20 61 6e 64 20 61 20 31 36 20 62   salt and a 16 b
40b0: 79 74 65 20 63 68 65 63 6b 73 75 6d 2e 0a 0a 3a  yte checksum...:
40c0: 20 6b 65 2d 6c 61 73 74 21 20 28 20 36 34 64 61   ke-last! ( 64da
40d0: 74 65 20 2d 2d 20 29 0a 20 20 20 20 6b 65 2d 73  te -- ).    ke-s
40e0: 65 6c 66 73 69 67 20 24 40 6c 65 6e 20 24 31 30  elfsig $@len $10
40f0: 20 75 6d 61 78 20 6b 65 2d 73 65 6c 66 73 69 67   umax ke-selfsig
4100: 20 24 21 6c 65 6e 0a 20 20 20 20 6b 65 2d 73 65   $!len.    ke-se
4110: 6c 66 73 69 67 20 24 40 20 64 72 6f 70 20 36 34  lfsig $@ drop 64
4120: 27 2b 20 36 34 21 20 3b 0a 3a 20 6b 65 2d 66 69  '+ 64! ;.: ke-fi
4130: 72 73 74 21 20 28 20 36 34 64 61 74 65 20 2d 2d  rst! ( 64date --
4140: 20 29 20 36 34 23 2d 31 20 6b 65 2d 6c 61 73 74   ) 64#-1 ke-last
4150: 21 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73 69 67  !.    ke-selfsig
4160: 20 24 40 20 64 72 6f 70 20 36 34 21 20 3b 0a 0a   $@ drop 64! ;..
4170: 73 63 6f 70 65 7b 20 6e 65 74 32 6f 2d 62 61 73  scope{ net2o-bas
4180: 65 0a 0a 63 6d 64 2d 74 61 62 6c 65 20 24 40 20  e..cmd-table $@ 
4190: 69 6e 68 65 72 69 74 2d 74 61 62 6c 65 20 6b 65  inherit-table ke
41a0: 79 2d 65 6e 74 72 79 2d 74 61 62 6c 65 0a 5c 67  y-entry-table.\g
41b0: 20 0a 5c 67 20 23 23 23 20 6b 65 79 20 73 74 6f   .\g ### key sto
41c0: 72 61 67 65 20 63 6f 6d 6d 61 6e 64 73 20 23 23  rage commands ##
41d0: 23 0a 5c 67 20 0a 24 31 31 20 6e 65 74 32 6f 3a  #.\g .$11 net2o:
41e0: 20 70 72 69 76 6b 65 79 20 28 20 24 3a 73 74 72   privkey ( $:str
41f0: 69 6e 67 20 2d 2d 20 29 0a 20 20 20 20 5c 67 20  ing -- ).    \g 
4200: 70 72 69 76 61 74 65 20 6b 65 79 0a 20 20 20 20  private key.    
4210: 5c 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20  \ does not need 
4220: 74 6f 20 62 65 20 73 69 67 6e 65 64 2c 20 74 68  to be signed, th
4230: 65 20 73 65 63 72 65 74 20 6b 65 79 20 76 65 72  e secret key ver
4240: 69 66 69 65 73 20 69 74 73 65 6c 66 0a 20 20 20  ifies itself.   
4250: 20 21 21 75 6e 73 69 67 6e 65 64 3f 20 24 34 30   !!unsigned? $40
4260: 20 21 21 3e 3d 6f 72 64 65 72 3f 0a 20 20 20 20   !!>=order?.    
4270: 6b 65 79 70 61 63 6b 20 63 40 20 24 46 20 61 6e  keypack c@ $F an
4280: 64 20 6b 65 2d 70 77 6c 65 76 65 6c 20 21 0a 20  d ke-pwlevel !. 
4290: 20 20 20 24 3e 20 6f 76 65 72 20 6b 65 79 70 61     $> over keypa
42a0: 64 20 73 6b 3e 70 6b 20 5c 20 67 65 6e 65 72 61  d sk>pk \ genera
42b0: 74 65 20 70 75 62 6b 65 79 0a 20 20 20 20 6b 65  te pubkey.    ke
42c0: 79 70 61 64 20 6b 65 2d 70 6b 20 24 40 20 64 72  ypad ke-pk $@ dr
42d0: 6f 70 20 6b 65 79 73 69 7a 65 20 74 75 63 6b 20  op keysize tuck 
42e0: 73 74 72 3d 20 30 3d 20 21 21 77 72 6f 6e 67 2d  str= 0= !!wrong-
42f0: 6b 65 79 21 21 0a 20 20 20 20 6b 65 2d 73 6b 20  key!!.    ke-sk 
4300: 73 65 63 21 20 2b 73 65 63 6b 65 79 20 3b 0a 2b  sec! +seckey ;.+
4310: 6e 65 74 32 6f 3a 20 6b 65 79 74 79 70 65 20 28  net2o: keytype (
4320: 20 6e 20 2d 2d 20 29 20 20 20 20 20 20 20 20 20   n -- )         
4330: 20 20 21 21 73 69 67 6e 65 64 3f 20 20 20 31 20    !!signed?   1 
4340: 21 21 3e 6f 72 64 65 72 3f 20 36 34 3e 6e 20 6b  !!>order? 64>n k
4350: 65 2d 74 79 70 65 20 21 20 3b 0a 20 20 20 20 5c  e-type ! ;.    \
4360: 67 20 6b 65 79 20 74 79 70 65 20 28 30 3a 20 61  g key type (0: a
4370: 6e 6f 6e 2c 20 31 3a 20 75 73 65 72 2c 20 32 3a  non, 1: user, 2:
4380: 20 67 72 6f 75 70 29 0a 2b 6e 65 74 32 6f 3a 20   group).+net2o: 
4390: 6b 65 79 6e 69 63 6b 20 28 20 24 3a 73 74 72 69  keynick ( $:stri
43a0: 6e 67 20 2d 2d 20 29 20 20 20 20 21 21 73 69 67  ng -- )    !!sig
43b0: 6e 65 64 3f 20 20 20 32 20 21 21 3e 6f 72 64 65  ned?   2 !!>orde
43c0: 72 3f 20 24 3e 20 6b 65 2d 6e 69 63 6b 20 24 21  r? $> ke-nick $!
43d0: 0a 20 20 20 20 5c 67 20 6b 65 79 20 6e 69 63 6b  .    \g key nick
43e0: 0a 20 20 20 20 6e 69 63 6b 21 20 3b 0a 2b 6e 65  .    nick! ;.+ne
43f0: 74 32 6f 3a 20 6b 65 79 70 72 6f 66 69 6c 65 20  t2o: keyprofile 
4400: 28 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20 29 20  ( $:string -- ) 
4410: 21 21 73 69 67 6e 65 64 3f 20 20 20 34 20 21 21  !!signed?   4 !!
4420: 3e 6f 72 64 65 72 3f 20 24 3e 20 6b 65 2d 70 72  >order? $> ke-pr
4430: 6f 66 20 24 21 20 3b 0a 20 20 20 20 5c 67 20 6b  of $! ;.    \g k
4440: 65 79 20 70 72 6f 66 69 6c 65 20 28 68 61 73 68  ey profile (hash
4450: 20 6f 66 20 61 20 72 65 73 6f 75 72 63 65 29 0a   of a resource).
4460: 2b 6e 65 74 32 6f 3a 20 6b 65 79 6d 61 73 6b 20  +net2o: keymask 
4470: 28 20 78 20 2d 2d 20 29 20 20 20 20 20 20 20 20  ( x -- )        
4480: 20 21 21 75 6e 73 69 67 6e 65 64 3f 20 24 34 30   !!unsigned? $40
4490: 20 21 21 3e 3d 6f 72 64 65 72 3f 20 36 34 3e 6e   !!>=order? 64>n
44a0: 0a 20 20 20 20 5c 67 20 6b 65 79 20 61 63 63 65  .    \g key acce
44b0: 73 73 20 72 69 67 68 74 20 6d 61 73 6b 0a 20 20  ss right mask.  
44c0: 20 20 31 20 69 6d 70 6f 72 74 2d 74 79 70 65 20    1 import-type 
44d0: 40 20 6c 73 68 69 66 74 0a 20 20 20 20 5b 20 31  @ lshift.    [ 1
44e0: 20 69 6d 70 6f 72 74 23 73 65 6c 66 20 6c 73 68   import#self lsh
44f0: 69 66 74 20 31 20 69 6d 70 6f 72 74 23 6e 65 77  ift 1 import#new
4500: 20 6c 73 68 69 66 74 20 6f 72 20 5d 4c 0a 20 20   lshift or ]L.  
4510: 20 20 61 6e 64 20 49 46 20 20 64 75 70 20 6b 65    and IF  dup ke
4520: 2d 6d 61 73 6b 20 6f 72 21 20 3f 3e 67 72 6f 75  -mask or! ?>grou
4530: 70 73 20 20 45 4c 53 45 20 20 64 72 6f 70 20 20  ps  ELSE  drop  
4540: 54 48 45 4e 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b  THEN ;.+net2o: k
4550: 65 79 67 72 6f 75 70 73 20 28 20 24 3a 67 72 6f  eygroups ( $:gro
4560: 75 70 73 20 2d 2d 20 29 20 21 21 75 6e 73 69 67  ups -- ) !!unsig
4570: 6e 65 64 3f 20 24 32 30 20 21 21 3e 6f 72 64 65  ned? $20 !!>orde
4580: 72 3f 20 24 3e 0a 20 20 20 20 5c 67 20 61 63 63  r? $>.    \g acc
4590: 65 73 73 20 67 72 6f 75 70 73 0a 20 20 20 20 31  ess groups.    1
45a0: 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 40 20 6c   import-type @ l
45b0: 73 68 69 66 74 0a 20 20 20 20 5b 20 31 20 69 6d  shift.    [ 1 im
45c0: 70 6f 72 74 23 73 65 6c 66 20 6c 73 68 69 66 74  port#self lshift
45d0: 20 31 20 69 6d 70 6f 72 74 23 6e 65 77 20 6c 73   1 import#new ls
45e0: 68 69 66 74 20 6f 72 20 5d 4c 0a 20 20 20 20 61  hift or ]L.    a
45f0: 6e 64 20 49 46 20 20 20 32 64 75 70 20 6b 65 2d  nd IF   2dup ke-
4600: 67 72 6f 75 70 73 20 24 21 20 67 72 6f 75 70 73  groups $! groups
4610: 3e 6d 61 73 6b 20 6b 65 2d 6d 61 73 6b 20 21 0a  >mask ke-mask !.
4620: 20 20 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20      ELSE  2drop 
4630: 20 54 48 45 4e 20 3b 0a 2b 6e 65 74 32 6f 3a 20   THEN ;.+net2o: 
4640: 2b 6b 65 79 73 69 67 20 28 20 24 3a 73 74 72 69  +keysig ( $:stri
4650: 6e 67 20 2d 2d 20 29 20 20 21 21 75 6e 73 69 67  ng -- )  !!unsig
4660: 6e 65 64 3f 20 24 31 30 20 21 21 3e 3d 6f 72 64  ned? $10 !!>=ord
4670: 65 72 3f 20 24 3e 20 6b 65 2d 73 69 67 73 20 24  er? $> ke-sigs $
4680: 2b 5b 5d 21 20 3b 0a 20 20 20 20 5c 67 20 61 64  +[]! ;.    \g ad
4690: 64 20 61 20 6b 65 79 20 73 69 67 6e 61 74 75 72  d a key signatur
46a0: 65 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 69 6d 70  e.+net2o: keyimp
46b0: 6f 72 74 20 28 20 6e 20 2d 2d 20 29 20 20 20 20  ort ( n -- )    
46c0: 20 20 20 21 21 75 6e 73 69 67 6e 65 64 3f 20 24     !!unsigned? $
46d0: 31 30 20 21 21 3e 3d 6f 72 64 65 72 3f 0a 20 20  10 !!>=order?.  
46e0: 20 20 63 6f 6e 66 69 67 3a 70 77 2d 6c 65 76 65    config:pw-leve
46f0: 6c 23 20 40 20 30 3c 20 49 46 20 20 36 34 3e 6e  l# @ 0< IF  64>n
4700: 0a 09 64 75 70 20 5b 20 31 20 69 6d 70 6f 72 74  ..dup [ 1 import
4710: 23 6e 65 77 20 6c 73 68 69 66 74 20 5d 4c 20 61  #new lshift ]L a
4720: 6e 64 20 30 3d 20 49 46 0a 09 20 20 20 20 69 6d  nd 0= IF..    im
4730: 70 6f 72 74 23 75 6e 74 72 75 73 74 65 64 20 75  port#untrusted u
4740: 6d 69 6e 20 31 20 73 77 61 70 20 6c 73 68 69 66  min 1 swap lshif
4750: 74 20 5b 20 31 20 69 6d 70 6f 72 74 23 6e 65 77  t [ 1 import#new
4760: 20 6c 73 68 69 66 74 20 5d 4c 20 6f 72 0a 09 45   lshift ]L or..E
4770: 4c 53 45 0a 09 20 20 20 20 5b 20 32 20 69 6d 70  LSE..    [ 2 imp
4780: 6f 72 74 23 75 6e 74 72 75 73 74 65 64 20 6c 73  ort#untrusted ls
4790: 68 69 66 74 20 31 2d 20 31 20 69 6d 70 6f 72 74  hift 1- 1 import
47a0: 23 6e 65 77 20 6c 73 68 69 66 74 20 6f 72 20 5d  #new lshift or ]
47b0: 4c 20 61 6e 64 0a 09 54 48 45 4e 0a 09 6b 65 2d  L and..THEN..ke-
47c0: 69 6d 70 6f 72 74 73 20 6f 72 21 0a 20 20 20 20  imports or!.    
47d0: 45 4c 53 45 20 20 36 34 64 72 6f 70 20 20 54 48  ELSE  64drop  TH
47e0: 45 4e 20 3b 0a 2b 6e 65 74 32 6f 3a 20 72 73 6b  EN ;.+net2o: rsk
47f0: 6b 65 79 20 28 20 24 3a 73 74 72 69 6e 67 20 2d  key ( $:string -
4800: 2d 2d 20 29 0a 20 20 20 20 5c 67 20 72 65 76 6f  -- ).    \g revo
4810: 6b 65 20 6b 65 79 2c 20 74 65 6d 70 6f 72 61 72  ke key, temporar
4820: 69 6c 79 20 73 74 6f 72 65 64 0a 20 20 20 20 5c  ily stored.    \
4830: 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74   does not need t
4840: 6f 20 62 65 20 73 69 67 6e 65 64 2c 20 74 68 65  o be signed, the
4850: 20 72 65 76 6f 6b 65 20 6b 65 79 20 76 65 72 69   revoke key veri
4860: 66 69 65 73 20 69 74 73 65 6c 66 0a 20 20 20 20  fies itself.    
4870: 21 21 75 6e 73 69 67 6e 65 64 3f 20 24 38 30 20  !!unsigned? $80 
4880: 21 21 3e 3d 6f 72 64 65 72 3f 0a 20 20 20 20 24  !!>=order?.    $
4890: 3e 20 32 64 75 70 20 73 6b 72 65 76 20 73 77 61  > 2dup skrev swa
48a0: 70 20 6b 65 79 7c 20 6d 6f 76 65 20 6b 65 2d 70  p key| move ke-p
48b0: 6b 20 24 40 20 64 72 6f 70 20 63 68 65 63 6b 2d  k $@ drop check-
48c0: 72 65 76 3f 20 30 3d 20 21 21 6e 6f 74 2d 6d 79  rev? 0= !!not-my
48d0: 2d 72 65 76 73 6b 21 21 0a 20 20 20 20 70 6b 72  -revsk!!.    pkr
48e0: 65 76 20 6b 65 79 73 69 7a 65 32 20 65 72 61 73  ev keysize2 eras
48f0: 65 20 20 6b 65 2d 72 73 6b 20 73 65 63 21 20 3b  e  ke-rsk sec! ;
4900: 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 70 65 74 20  .+net2o: keypet 
4910: 28 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20 29 20  ( $:string -- ) 
4920: 20 21 21 75 6e 73 69 67 6e 65 64 3f 20 20 24 3e   !!unsigned?  $>
4930: 0a 20 20 20 20 63 6f 6e 66 69 67 3a 70 77 2d 6c  .    config:pw-l
4940: 65 76 65 6c 23 20 40 20 30 3c 20 49 46 20 20 6b  evel# @ 0< IF  k
4950: 65 2d 70 65 74 73 20 24 2b 5b 5d 21 20 70 65 74  e-pets $+[]! pet
4960: 21 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20 20  !  ELSE  2drop  
4970: 54 48 45 4e 20 3b 0a 7d 73 63 6f 70 65 0a 0a 67  THEN ;.}scope..g
4980: 65 6e 2d 74 61 62 6c 65 20 24 66 72 65 65 7a 65  en-table $freeze
4990: 0a 27 20 63 6f 6e 74 65 78 74 2d 74 61 62 6c 65  .' context-table
49a0: 20 69 73 20 67 65 6e 2d 74 61 62 6c 65 0a 0a 3a   is gen-table..:
49b0: 20 6b 65 79 3a 6e 65 73 74 2d 73 69 67 20 28 20   key:nest-sig ( 
49c0: 61 64 64 72 20 75 20 2d 2d 20 61 64 64 72 20 75  addr u -- addr u
49d0: 27 20 66 6c 61 67 20 29 0a 20 20 20 20 70 6b 32  ' flag ).    pk2
49e0: 2d 73 69 67 3f 20 64 75 70 20 3f 45 58 49 54 20  -sig? dup ?EXIT 
49f0: 64 72 6f 70 0a 20 20 20 20 32 64 75 70 20 2b 20  drop.    2dup + 
4a00: 73 69 67 73 69 7a 65 23 20 2d 20 73 69 67 73 69  sigsize# - sigsi
4a10: 7a 65 23 20 3e 24 0a 20 20 20 20 73 69 67 70 6b  ze# >$.    sigpk
4a20: 32 73 69 7a 65 23 20 2d 20 32 64 75 70 20 2b 20  2size# - 2dup + 
4a30: 6b 65 79 73 69 7a 65 32 20 6b 65 79 3f 6e 65 77  keysize2 key?new
4a40: 20 6e 3a 3e 6f 20 24 3e 20 6b 65 2d 73 65 6c 66   n:>o $> ke-self
4a50: 73 69 67 20 24 21 0a 20 20 20 20 73 69 6d 2d 6e  sig $!.    sim-n
4a60: 69 63 6b 21 20 6f 66 66 20 63 2d 73 74 61 74 65  ick! off c-state
4a70: 20 6f 66 66 20 73 69 67 2d 6f 6b 20 3b 0a 27 20   off sig-ok ;.' 
4a80: 6b 65 79 3a 6e 65 73 74 2d 73 69 67 20 6b 65 79  key:nest-sig key
4a90: 2d 65 6e 74 72 79 20 74 6f 20 6e 65 73 74 2d 73  -entry to nest-s
4aa0: 69 67 0a 0a 73 61 6d 70 6c 65 2d 6b 65 79 20 3e  ig..sample-key >
4ab0: 6f 20 6b 65 79 2d 65 6e 74 72 79 2d 74 61 62 6c  o key-entry-tabl
4ac0: 65 20 40 20 74 6f 6b 65 6e 2d 74 61 62 6c 65 20  e @ token-table 
4ad0: 21 20 6f 3e 0a 0a 3a 20 6b 65 79 3a 63 6f 64 65  ! o>..: key:code
4ae0: 20 28 20 2d 2d 20 29 0a 20 20 20 20 63 6f 64 65   ( -- ).    code
4af0: 2d 6b 65 79 20 20 63 6d 64 6c 6f 63 6b 20 6c 6f  -key  cmdlock lo
4b00: 63 6b 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b  ck.    keypack k
4b10: 65 79 70 61 63 6b 2d 61 6c 6c 23 20 65 72 61 73  eypack-all# eras
4b20: 65 0a 20 20 20 20 63 6d 64 72 65 73 65 74 20 69  e.    cmdreset i
4b30: 6e 69 74 2d 72 65 70 6c 79 20 61 6c 73 6f 20 6e  nit-reply also n
4b40: 65 74 32 6f 2d 62 61 73 65 20 3b 0a 63 6f 6d 70  et2o-base ;.comp
4b50: 3a 20 3a 2c 20 61 6c 73 6f 20 6e 65 74 32 6f 2d  : :, also net2o-
4b60: 62 61 73 65 20 3b 0a 0a 73 63 6f 70 65 7b 20 6e  base ;..scope{ n
4b70: 65 74 32 6f 2d 62 61 73 65 0a 0a 3a 20 65 6e 64  et2o-base..: end
4b80: 3a 6b 65 79 20 28 20 2d 2d 20 29 0a 20 20 20 20  :key ( -- ).    
4b90: 65 6e 64 2d 77 69 74 68 20 70 72 65 76 69 6f 75  end-with previou
4ba0: 73 20 63 6d 64 6c 6f 63 6b 20 75 6e 6c 6f 63 6b  s cmdlock unlock
4bb0: 20 3b 0a 63 6f 6d 70 3a 20 3a 2c 20 70 72 65 76   ;.comp: :, prev
4bc0: 69 6f 75 73 20 3b 0a 0a 7d 73 63 6f 70 65 0a 0a  ious ;..}scope..
4bd0: 3a 20 6b 65 79 2d 63 72 79 70 74 20 28 20 2d 2d  : key-crypt ( --
4be0: 20 29 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b   ).    keypack k
4bf0: 65 79 70 61 63 6b 2d 61 6c 6c 23 0a 20 20 20 20  eypack-all#.    
4c00: 3e 73 74 6f 72 65 6b 65 79 20 73 65 63 40 20 64  >storekey sec@ d
4c10: 75 70 20 24 32 30 20 75 3c 3d 20 5c 20 69 73 20  up $20 u<= \ is 
4c20: 61 20 73 65 63 72 65 74 2c 20 6e 6f 20 6e 65 65  a secret, no nee
4c30: 64 20 74 6f 20 62 65 20 73 6c 6f 77 0a 20 20 20  d to be slow.   
4c40: 20 49 46 20 20 65 6e 63 72 79 70 74 24 20 20 45   IF  encrypt$  E
4c50: 4c 53 45 20 20 63 6f 6e 66 69 67 3a 70 77 2d 6c  LSE  config:pw-l
4c60: 65 76 65 6c 23 20 40 20 65 6e 63 72 79 70 74 2d  evel# @ encrypt-
4c70: 70 77 24 20 20 54 48 45 4e 20 3b 0a 0a 30 20 56  pw$  THEN ;..0 V
4c80: 61 6c 75 65 20 6b 65 79 2d 73 66 64 20 5c 20 73  alue key-sfd \ s
4c90: 65 63 72 65 74 20 6b 65 79 73 0a 30 20 56 61 6c  ecret keys.0 Val
4ca0: 75 65 20 6b 65 79 2d 70 66 64 20 5c 20 70 75 62  ue key-pfd \ pub
4cb0: 6b 65 79 73 0a 0a 5c 20 6c 65 67 61 63 79 20 66  keys..\ legacy f
4cc0: 6f 72 20 65 61 72 6c 79 20 76 65 72 73 69 6f 6e  or early version
4cd0: 73 20 6f 66 20 6e 65 74 32 6f 20 70 72 69 6f 72  s of net2o prior
4ce0: 20 32 30 31 36 30 36 30 36 0a 0a 3a 20 6e 65 74   20160606..: net
4cf0: 32 6f 3e 6b 65 79 73 20 7b 20 61 64 64 72 20 75  2o>keys { addr u
4d00: 20 2d 2d 20 7d 0a 20 20 20 20 61 64 64 72 20 75   -- }.    addr u
4d10: 20 2e 6e 65 74 32 6f 2f 20 20 61 64 64 72 20 75   .net2o/  addr u
4d20: 20 2e 6b 65 79 73 2f 20 72 65 6e 61 6d 65 2d 66   .keys/ rename-f
4d30: 69 6c 65 20 64 72 6f 70 20 3b 0a 3a 20 3f 6c 65  ile drop ;.: ?le
4d40: 67 61 63 79 2d 6b 65 79 73 20 28 20 66 6c 61 67  gacy-keys ( flag
4d50: 20 2d 2d 20 29 0a 20 20 20 20 5c 20 21 21 46 49   -- ).    \ !!FI
4d60: 58 4d 45 21 21 20 6e 65 65 64 73 20 74 6f 20 62  XME!! needs to b
4d70: 65 20 72 65 6d 6f 76 65 64 20 77 68 65 6e 20 61  e removed when a
4d80: 6c 6c 20 63 75 72 72 65 6e 74 20 75 73 65 72 73  ll current users
4d90: 0a 20 20 20 20 5c 20 68 61 76 65 20 6d 69 67 72  .    \ have migr
4da0: 61 74 65 64 0a 20 20 20 20 49 46 0a 09 22 70 75  ated.    IF.."pu
4db0: 62 6b 65 79 73 2e 6b 32 6f 22 20 6e 65 74 32 6f  bkeys.k2o" net2o
4dc0: 3e 6b 65 79 73 0a 09 22 73 65 63 6b 65 79 73 2e  >keys.."seckeys.
4dd0: 6b 32 6f 22 20 6e 65 74 32 6f 3e 6b 65 79 73 0a  k2o" net2o>keys.
4de0: 20 20 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 67 65      THEN ;..: ge
4df0: 6e 2d 6b 65 79 73 2d 64 69 72 20 28 20 2d 2d 20  n-keys-dir ( -- 
4e00: 29 0a 20 20 20 20 69 6e 69 74 2d 64 69 72 73 20  ).    init-dirs 
4e10: 3f 2e 6e 65 74 32 6f 2f 6b 65 79 73 20 3f 6c 65  ?.net2o/keys ?le
4e20: 67 61 63 79 2d 6b 65 79 73 20 3b 0a 0a 3a 20 3f  gacy-keys ;..: ?
4e30: 66 64 2d 6b 65 79 73 20 28 20 66 64 20 61 64 64  fd-keys ( fd add
4e40: 72 20 75 20 2d 2d 20 66 64 27 20 29 20 7b 20 61  r u -- fd' ) { a
4e50: 64 64 72 20 75 20 7d 20 64 75 70 20 3f 45 58 49  ddr u } dup ?EXI
4e60: 54 20 64 72 6f 70 0a 20 20 20 20 67 65 6e 2d 6b  T drop.    gen-k
4e70: 65 79 73 2d 64 69 72 0a 20 20 20 20 61 64 64 72  eys-dir.    addr
4e80: 20 75 20 72 2f 77 20 6f 70 65 6e 2d 66 69 6c 65   u r/w open-file
4e90: 20 64 75 70 20 6e 6f 2d 66 69 6c 65 23 20 3d 20   dup no-file# = 
4ea0: 49 46 0a 09 32 64 72 6f 70 20 61 64 64 72 20 75  IF..2drop addr u
4eb0: 20 72 2f 77 20 63 72 65 61 74 65 2d 66 69 6c 65   r/w create-file
4ec0: 0a 20 20 20 20 54 48 45 4e 20 20 74 68 72 6f 77  .    THEN  throw
4ed0: 20 3b 0a 0a 3a 20 3f 6b 65 79 2d 73 66 64 20 28   ;..: ?key-sfd (
4ee0: 20 2d 2d 20 66 64 20 29 0a 20 20 20 20 6b 65 79   -- fd ).    key
4ef0: 2d 73 66 64 20 22 73 65 63 6b 65 79 73 2e 6b 32  -sfd "seckeys.k2
4f00: 6f 22 20 2e 6b 65 79 73 2f 20 3f 66 64 2d 6b 65  o" .keys/ ?fd-ke
4f10: 79 73 20 64 75 70 20 74 6f 20 6b 65 79 2d 73 66  ys dup to key-sf
4f20: 64 20 3b 0a 3a 20 3f 6b 65 79 2d 70 66 64 20 28  d ;.: ?key-pfd (
4f30: 20 2d 2d 20 66 64 20 29 0a 20 20 20 20 6b 65 79   -- fd ).    key
4f40: 2d 70 66 64 20 22 70 75 62 6b 65 79 73 2e 6b 32  -pfd "pubkeys.k2
4f50: 6f 22 20 2e 6b 65 79 73 2f 20 3f 66 64 2d 6b 65  o" .keys/ ?fd-ke
4f60: 79 73 20 64 75 70 20 74 6f 20 6b 65 79 2d 70 66  ys dup to key-pf
4f70: 64 20 3b 0a 0a 3a 20 6b 65 79 3e 73 66 69 6c 65  d ;..: key>sfile
4f80: 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 70   ( -- ).    keyp
4f90: 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23  ack keypack-all#
4fa0: 20 3f 6b 65 79 2d 73 66 64 20 61 70 70 65 6e 64   ?key-sfd append
4fb0: 2d 66 69 6c 65 20 6b 65 2d 6f 66 66 73 65 74 20  -file ke-offset 
4fc0: 36 34 21 20 3b 0a 3a 20 6b 65 79 3e 70 66 69 6c  64! ;.: key>pfil
4fd0: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79  e ( -- ).    key
4fe0: 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c  pack keypack-all
4ff0: 23 20 3f 6b 65 79 2d 70 66 64 20 61 70 70 65 6e  # ?key-pfd appen
5000: 64 2d 66 69 6c 65 20 6b 65 2d 6f 66 66 73 65 74  d-file ke-offset
5010: 20 36 34 21 20 3b 0a 0a 3a 20 6b 65 79 3e 73 66   64! ;..: key>sf
5020: 69 6c 65 40 70 6f 73 20 28 20 36 34 70 6f 73 20  ile@pos ( 64pos 
5030: 2d 2d 20 29 20 36 34 64 75 70 20 36 34 23 2d 31  -- ) 64dup 64#-1
5040: 20 36 34 3d 20 49 46 20 20 36 34 64 72 6f 70 20   64= IF  64drop 
5050: 6b 65 79 3e 73 66 69 6c 65 0a 20 20 20 20 45 4c  key>sfile.    EL
5060: 53 45 20 20 36 34 3e 72 20 6b 65 79 70 61 63 6b  SE  64>r keypack
5070: 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 36 34   keypack-all# 64
5080: 72 3e 20 3f 6b 65 79 2d 73 66 64 20 77 72 69 74  r> ?key-sfd writ
5090: 65 40 70 6f 73 2d 66 69 6c 65 20 20 54 48 45 4e  e@pos-file  THEN
50a0: 20 3b 0a 3a 20 6b 65 79 3e 70 66 69 6c 65 40 70   ;.: key>pfile@p
50b0: 6f 73 20 28 20 36 34 70 6f 73 20 2d 2d 20 29 20  os ( 64pos -- ) 
50c0: 36 34 64 75 70 20 36 34 23 2d 31 20 36 34 3d 20  64dup 64#-1 64= 
50d0: 49 46 20 20 36 34 64 72 6f 70 20 6b 65 79 3e 70  IF  64drop key>p
50e0: 66 69 6c 65 0a 20 20 20 20 45 4c 53 45 20 20 36  file.    ELSE  6
50f0: 34 3e 72 20 6b 65 79 70 61 63 6b 20 6b 65 79 70  4>r keypack keyp
5100: 61 63 6b 2d 61 6c 6c 23 20 36 34 72 3e 20 3f 6b  ack-all# 64r> ?k
5110: 65 79 2d 70 66 64 20 77 72 69 74 65 40 70 6f 73  ey-pfd write@pos
5120: 2d 66 69 6c 65 20 20 54 48 45 4e 20 3b 0a 0a 3a  -file  THEN ;..:
5130: 20 72 6e 64 3e 73 66 69 6c 65 20 28 20 2d 2d 20   rnd>sfile ( -- 
5140: 29 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b 65  ).    keypack ke
5150: 79 70 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e 67 24  ypack-all# >rng$
5160: 20 6b 65 79 3e 73 66 69 6c 65 20 3b 0a 3a 20 72   key>sfile ;.: r
5170: 6e 64 3e 70 66 69 6c 65 20 28 20 2d 2d 20 29 0a  nd>pfile ( -- ).
5180: 20 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79 70      keypack keyp
5190: 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e 67 24 20 6b  ack-all# >rng$ k
51a0: 65 79 3e 70 66 69 6c 65 20 3b 0a 0a 3a 20 3e 6b  ey>pfile ;..: >k
51b0: 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 5c  eys ( -- ).    \
51c0: 47 20 61 64 64 20 73 68 61 72 65 64 20 73 65 63  G add shared sec
51d0: 72 65 74 20 74 6f 20 6c 69 73 74 20 6f 66 20 70  ret to list of p
51e0: 6f 73 73 69 62 6c 65 20 6b 65 79 73 0a 20 20 20  ossible keys.   
51f0: 20 73 6b 63 20 70 6b 63 20 6b 65 79 70 61 64 20   skc pkc keypad 
5200: 65 64 2d 64 68 20 2b 6b 65 79 20 3b 0a 0a 5c 20  ed-dh +key ;..\ 
5210: 6b 65 79 20 67 65 6e 65 72 61 74 69 6f 6e 0a 5c  key generation.\
5220: 20 66 6f 72 20 72 65 70 72 6f 64 75 63 69 62 69   for reproducibi
5230: 6c 69 74 79 20 6f 66 20 74 68 65 20 73 65 6c 66  lity of the self
5240: 73 69 67 2c 20 61 6c 77 61 79 73 20 75 73 65 20  sig, always use 
5250: 74 68 65 20 73 61 6d 65 20 6f 72 64 65 72 3a 0a  the same order:.
5260: 5c 20 22 70 75 62 6b 65 79 22 20 6e 65 77 6b 65  \ "pubkey" newke
5270: 79 20 3c 6e 3e 20 6b 65 79 74 79 70 65 20 22 6e  y <n> keytype "n
5280: 69 63 6b 22 20 6b 65 79 6e 69 63 6b 20 22 73 69  ick" keynick "si
5290: 67 22 20 6b 65 79 73 65 6c 66 73 69 67 0a 0a 55  g" keyselfsig..U
52a0: 73 65 72 20 70 6b 2b 73 69 67 24 0a 0a 6b 65 79  ser pk+sig$..key
52b0: 73 69 7a 65 32 20 43 6f 6e 73 74 61 6e 74 20 70  size2 Constant p
52c0: 6b 72 6b 23 0a 0a 3a 20 5d 70 6b 2b 73 69 67 6e  krk#..: ]pk+sign
52d0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 2b   ( addr u -- ) +
52e0: 63 6d 64 62 75 66 20 5d 73 69 67 6e 20 3b 0a 0a  cmdbuf ]sign ;..
52f0: 3a 20 70 61 63 6b 2d 6b 65 79 20 28 20 74 79 70  : pack-key ( typ
5300: 65 20 6e 69 63 6b 20 75 20 2d 2d 20 29 0a 20 20  e nick u -- ).  
5310: 20 20 6e 6f 77 3e 6e 65 76 65 72 0a 20 20 20 20    now>never.    
5320: 6b 65 79 3a 63 6f 64 65 0a 20 20 20 20 20 20 73  key:code.      s
5330: 69 67 6e 5b 0a 20 20 20 20 20 20 72 6f 74 20 75  ign[.      rot u
5340: 6c 69 74 2c 20 6b 65 79 74 79 70 65 20 24 2c 20  lit, keytype $, 
5350: 6b 65 79 6e 69 63 6b 0a 20 20 20 20 20 20 70 6b  keynick.      pk
5360: 63 20 70 6b 72 6b 23 20 5d 70 6b 2b 73 69 67 6e  c pkrk# ]pk+sign
5370: 0a 20 20 20 20 20 20 73 6b 63 20 6b 65 79 73 69  .      skc keysi
5380: 7a 65 20 73 65 63 24 2c 20 70 72 69 76 6b 65 79  ze sec$, privkey
5390: 0a 20 20 20 20 65 6e 64 3a 6b 65 79 20 3b 0a 0a  .    end:key ;..
53a0: 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a  also net2o-base.
53b0: 3a 20 70 61 63 6b 2d 63 6f 72 65 20 28 20 6f 3a  : pack-core ( o:
53c0: 6b 65 79 20 2d 2d 20 29 20 5c 20 63 6f 72 65 20  key -- ) \ core 
53d0: 77 69 74 68 6f 75 74 20 6b 65 79 0a 20 20 20 20  without key.    
53e0: 6b 65 2d 74 79 70 65 20 40 20 75 6c 69 74 2c 20  ke-type @ ulit, 
53f0: 6b 65 79 74 79 70 65 0a 20 20 20 20 6b 65 2d 6e  keytype.    ke-n
5400: 69 63 6b 20 24 40 20 24 2c 20 6b 65 79 6e 69 63  ick $@ $, keynic
5410: 6b 0a 20 20 20 20 6b 65 2d 70 72 6f 66 20 24 40  k.    ke-prof $@
5420: 20 64 75 70 20 49 46 20 20 24 2c 20 6b 65 79 70   dup IF  $, keyp
5430: 72 6f 66 69 6c 65 20 20 45 4c 53 45 20 20 32 64  rofile  ELSE  2d
5440: 72 6f 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 70  rop  THEN ;..: p
5450: 61 63 6b 2d 73 69 67 6e 6b 65 79 20 28 20 6f 3a  ack-signkey ( o:
5460: 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 73 69 67  key -- ).    sig
5470: 6e 5b 0a 20 20 20 20 70 61 63 6b 2d 63 6f 72 65  n[.    pack-core
5480: 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 2b 63  .    ke-pk $@ +c
5490: 6d 64 62 75 66 0a 20 20 20 20 6b 65 2d 73 65 6c  mdbuf.    ke-sel
54a0: 66 73 69 67 20 24 40 20 2b 63 6d 64 62 75 66 20  fsig $@ +cmdbuf 
54b0: 63 6d 64 2d 72 65 73 6f 6c 76 65 3e 20 32 64 72  cmd-resolve> 2dr
54c0: 6f 70 20 6e 65 73 74 73 69 67 20 3b 0a 0a 3a 20  op nestsig ;..: 
54d0: 70 61 63 6b 2d 63 6f 72 65 6b 65 79 20 28 20 6f  pack-corekey ( o
54e0: 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20 70 61  :key -- ).    pa
54f0: 63 6b 2d 73 69 67 6e 6b 65 79 0a 20 20 20 20 6b  ck-signkey.    k
5500: 65 2d 69 6d 70 6f 72 74 73 20 40 20 75 6c 69 74  e-imports @ ulit
5510: 2c 20 6b 65 79 69 6d 70 6f 72 74 0a 20 20 20 20  , keyimport.    
5520: 6b 65 2d 6d 61 73 6b 20 40 20 20 6b 65 2d 67 72  ke-mask @  ke-gr
5530: 6f 75 70 73 20 24 40 6c 65 6e 20 49 46 0a 09 6b  oups $@len IF..k
5540: 65 2d 67 72 6f 75 70 73 20 24 40 20 32 64 75 70  e-groups $@ 2dup
5550: 20 24 2c 20 6b 65 79 67 72 6f 75 70 73 0a 09 67   $, keygroups..g
5560: 72 6f 75 70 73 3e 6d 61 73 6b 20 69 6e 76 65 72  roups>mask inver
5570: 74 20 61 6e 64 20 20 54 48 45 4e 0a 20 20 20 20  t and  THEN.    
5580: 3f 64 75 70 2d 49 46 20 20 6e 6c 69 74 2c 20 6b  ?dup-IF  nlit, k
5590: 65 79 6d 61 73 6b 20 20 54 48 45 4e 0a 20 20 20  eymask  THEN.   
55a0: 20 6b 65 2d 70 65 74 73 20 5b 3a 20 24 2c 20 6b   ke-pets [: $, k
55b0: 65 79 70 65 74 20 3b 5d 20 24 5b 5d 6d 61 70 0a  eypet ;] $[]map.
55c0: 20 20 20 20 6b 65 2d 73 74 6f 72 65 6b 65 79 20      ke-storekey 
55d0: 40 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 3b 0a  @ >storekey ! ;.
55e0: 70 72 65 76 69 6f 75 73 0a 0a 3a 20 70 61 63 6b  previous..: pack
55f0: 2d 70 75 62 6b 65 79 20 28 20 6f 3a 6b 65 79 20  -pubkey ( o:key 
5600: 2d 2d 20 29 0a 20 20 20 20 6b 65 79 3a 63 6f 64  -- ).    key:cod
5610: 65 0a 20 20 20 20 20 20 70 61 63 6b 2d 63 6f 72  e.      pack-cor
5620: 65 6b 65 79 0a 20 20 20 20 65 6e 64 3a 6b 65 79  ekey.    end:key
5630: 20 3b 0a 3a 20 70 61 63 6b 2d 6f 75 74 6b 65 79   ;.: pack-outkey
5640: 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20   ( o:key -- ).  
5650: 20 20 6b 65 79 3a 63 6f 64 65 0a 20 20 20 20 20    key:code.     
5660: 20 22 6e 32 6f 22 20 6e 65 74 32 6f 2d 62 61 73   "n2o" net2o-bas
5670: 65 3a 34 63 63 2c 0a 20 20 20 20 20 20 70 61 63  e:4cc,.      pac
5680: 6b 2d 73 69 67 6e 6b 65 79 0a 20 20 20 20 65 6e  k-signkey.    en
5690: 64 3a 6b 65 79 20 3b 0a 3a 20 70 61 63 6b 2d 73  d:key ;.: pack-s
56a0: 65 63 6b 65 79 20 28 20 6f 3a 6b 65 79 20 2d 2d  eckey ( o:key --
56b0: 20 29 0a 20 20 20 20 6b 65 79 3a 63 6f 64 65 0a   ).    key:code.
56c0: 20 20 20 20 20 20 70 61 63 6b 2d 63 6f 72 65 6b        pack-corek
56d0: 65 79 0a 20 20 20 20 20 20 6b 65 2d 73 6b 20 73  ey.      ke-sk s
56e0: 65 63 40 20 73 65 63 24 2c 20 70 72 69 76 6b 65  ec@ sec$, privke
56f0: 79 0a 20 20 20 20 20 20 6b 65 2d 72 73 6b 20 73  y.      ke-rsk s
5700: 65 63 40 20 64 75 70 20 49 46 20 20 73 65 63 24  ec@ dup IF  sec$
5710: 2c 20 72 73 6b 6b 65 79 20 20 45 4c 53 45 20 20  , rskkey  ELSE  
5720: 32 64 72 6f 70 20 20 54 48 45 4e 0a 20 20 20 20  2drop  THEN.    
5730: 65 6e 64 3a 6b 65 79 20 3b 0a 3a 20 6b 65 79 6e  end:key ;.: keyn
5740: 69 63 6b 24 20 28 20 6f 3a 6b 65 79 20 2d 2d 20  ick$ ( o:key -- 
5750: 61 64 64 72 20 75 20 29 0a 20 20 20 20 5c 47 20  addr u ).    \G 
5760: 67 65 74 20 74 68 65 20 61 6e 6e 6f 74 61 74 69  get the annotati
5770: 6f 6e 73 20 77 69 74 68 20 73 69 67 6e 61 74 75  ons with signatu
5780: 72 65 0a 20 20 20 20 5b 27 5d 20 70 61 63 6b 2d  re.    ['] pack-
5790: 63 6f 72 65 20 67 65 6e 2d 63 6d 64 24 20 32 64  core gen-cmd$ 2d
57a0: 72 6f 70 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73  rop.    ke-selfs
57b0: 69 67 20 24 40 20 74 6d 70 24 20 24 2b 21 20 74  ig $@ tmp$ $+! t
57c0: 6d 70 24 20 24 40 20 3b 0a 3a 20 6b 65 79 70 6b  mp$ $@ ;.: keypk
57d0: 32 6e 69 63 6b 24 20 28 20 6f 3a 6b 65 79 20 2d  2nick$ ( o:key -
57e0: 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20 5c  - addr u ).    \
57f0: 47 20 67 65 74 20 74 68 65 20 61 6e 6e 6f 74 61  G get the annota
5800: 74 69 6f 6e 73 20 77 69 74 68 20 73 69 67 6e 61  tions with signa
5810: 74 75 72 65 0a 20 20 20 20 5b 27 5d 20 70 61 63  ture.    ['] pac
5820: 6b 2d 63 6f 72 65 20 67 65 6e 2d 63 6d 64 24 20  k-core gen-cmd$ 
5830: 32 64 72 6f 70 0a 20 20 20 20 6b 65 2d 70 6b 20  2drop.    ke-pk 
5840: 24 40 20 74 6d 70 24 20 24 2b 21 20 6b 65 2d 73  $@ tmp$ $+! ke-s
5850: 65 6c 66 73 69 67 20 24 40 20 74 6d 70 24 20 24  elfsig $@ tmp$ $
5860: 2b 21 20 74 6d 70 24 20 24 40 20 3b 0a 3a 20 6d  +! tmp$ $@ ;.: m
5870: 79 6e 69 63 6b 2d 6b 65 79 20 28 20 2d 2d 20 6f  ynick-key ( -- o
5880: 20 29 0a 20 20 20 20 70 6b 63 20 6b 65 79 73 69   ).    pkc keysi
5890: 7a 65 20 6b 65 79 23 20 23 40 20 64 72 6f 70 20  ze key# #@ drop 
58a0: 63 65 6c 6c 2b 20 3b 0a 3a 20 6d 79 6e 69 63 6b  cell+ ;.: mynick
58b0: 24 20 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a  $ ( -- addr u ).
58c0: 20 20 20 20 5c 47 20 67 65 74 20 6d 79 20 6e 69      \G get my ni
58d0: 63 6b 20 77 69 74 68 20 73 69 67 6e 61 74 75 72  ck with signatur
58e0: 65 0a 20 20 20 20 6d 79 6e 69 63 6b 2d 6b 65 79  e.    mynick-key
58f0: 20 2e 6b 65 79 6e 69 63 6b 24 20 3b 0a 3a 20 6d   .keynick$ ;.: m
5900: 79 70 6b 32 6e 69 63 6b 24 20 28 20 6f 3a 6b 65  ypk2nick$ ( o:ke
5910: 79 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20  y -- addr u ).  
5920: 20 20 5c 47 20 67 65 74 20 6d 79 20 6e 69 63 6b    \G get my nick
5930: 20 77 69 74 68 20 73 69 67 6e 61 74 75 72 65 0a   with signature.
5940: 20 20 20 20 6d 79 6e 69 63 6b 2d 6b 65 79 20 2e      mynick-key .
5950: 6b 65 79 70 6b 32 6e 69 63 6b 24 20 3b 0a 3a 20  keypk2nick$ ;.: 
5960: 6b 65 79 2d 73 69 67 6e 20 28 20 6f 3a 6b 65 79  key-sign ( o:key
5970: 20 2d 2d 20 6f 3a 6b 65 79 20 29 0a 20 20 20 20   -- o:key ).    
5980: 5b 27 5d 20 70 61 63 6b 2d 63 6f 72 65 20 67 65  ['] pack-core ge
5990: 6e 2d 63 6d 64 24 0a 20 20 20 20 5b 3a 20 74 79  n-cmd$.    [: ty
59a0: 70 65 20 6b 65 2d 70 6b 20 24 40 20 74 79 70 65  pe ke-pk $@ type
59b0: 20 3b 5d 20 24 74 6d 70 0a 20 20 20 20 6e 6f 77   ;] $tmp.    now
59c0: 3e 6e 65 76 65 72 20 63 3a 30 6b 65 79 20 63 3a  >never c:0key c:
59d0: 68 61 73 68 20 5b 27 5d 20 2e 73 69 67 20 24 74  hash ['] .sig $t
59e0: 6d 70 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 21  mp ke-selfsig $!
59f0: 20 3b 0a 0a 56 61 72 69 61 62 6c 65 20 63 70 2d   ;..Variable cp-
5a00: 74 6d 70 0a 0a 3a 20 73 61 76 65 2d 70 75 62 6b  tmp..: save-pubk
5a10: 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b  eys ( -- ).    k
5a20: 65 79 2d 70 66 64 20 3f 64 75 70 2d 49 46 20 20  ey-pfd ?dup-IF  
5a30: 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f 77  close-file throw
5a40: 20 20 54 48 45 4e 0a 20 20 20 20 22 70 75 62 6b    THEN.    "pubk
5a50: 65 79 73 2e 6b 32 6f 22 20 2e 6b 65 79 73 2f 20  eys.k2o" .keys/ 
5a60: 5b 3a 20 74 6f 20 6b 65 79 2d 70 66 64 0a 20 20  [: to key-pfd.  
5a70: 20 20 20 20 6b 65 79 23 20 5b 3a 20 63 65 6c 6c      key# [: cell
5a80: 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20  + $@ drop cell+ 
5a90: 3e 6f 0a 09 6b 65 2d 73 6b 20 73 65 63 40 20 64  >o..ke-sk sec@ d
5aa0: 30 3d 20 49 46 20 20 70 61 63 6b 2d 70 75 62 6b  0= IF  pack-pubk
5ab0: 65 79 0a 09 20 20 20 20 66 6c 75 73 68 28 20 2e  ey..    flush( .
5ac0: 22 20 73 61 76 69 6e 67 20 22 20 2e 6e 69 63 6b  " saving " .nick
5ad0: 20 66 6f 72 74 68 3a 63 72 20 29 0a 09 20 20 20   forth:cr )..   
5ae0: 20 6b 65 79 2d 63 72 79 70 74 20 6b 65 2d 6f 66   key-crypt ke-of
5af0: 66 73 65 74 20 36 34 40 20 6b 65 79 3e 70 66 69  fset 64@ key>pfi
5b00: 6c 65 40 70 6f 73 0a 09 54 48 45 4e 20 6f 3e 20  le@pos..THEN o> 
5b10: 3b 5d 20 23 6d 61 70 0a 20 20 20 20 30 20 74 6f  ;] #map.    0 to
5b20: 20 6b 65 79 2d 70 66 64 20 3b 5d 20 73 61 76 65   key-pfd ;] save
5b30: 2d 66 69 6c 65 20 20 3f 6b 65 79 2d 70 66 64 20  -file  ?key-pfd 
5b40: 64 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65 2d 73  drop ;..: save-s
5b50: 65 63 6b 65 79 73 20 28 20 2d 2d 20 29 0a 20 20  eckeys ( -- ).  
5b60: 20 20 6b 65 79 2d 73 66 64 20 3f 64 75 70 2d 49    key-sfd ?dup-I
5b70: 46 20 20 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68  F  close-file th
5b80: 72 6f 77 20 20 54 48 45 4e 0a 20 20 20 20 22 73  row  THEN.    "s
5b90: 65 63 6b 65 79 73 2e 6b 32 6f 22 20 2e 6b 65 79  eckeys.k2o" .key
5ba0: 73 2f 20 5b 3a 20 74 6f 20 6b 65 79 2d 73 66 64  s/ [: to key-sfd
5bb0: 0a 20 20 20 20 20 20 6b 65 79 23 20 5b 3a 20 63  .      key# [: c
5bc0: 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65 6c  ell+ $@ drop cel
5bd0: 6c 2b 20 3e 6f 0a 09 6b 65 2d 73 6b 20 73 65 63  l+ >o..ke-sk sec
5be0: 40 20 64 30 3c 3e 20 49 46 20 20 70 61 63 6b 2d  @ d0<> IF  pack-
5bf0: 73 65 63 6b 65 79 0a 09 20 20 20 20 63 6f 6e 66  seckey..    conf
5c00: 69 67 3a 70 77 2d 6c 65 76 65 6c 23 20 40 20 3e  ig:pw-level# @ >
5c10: 72 20 20 6b 65 2d 70 77 6c 65 76 65 6c 20 40 20  r  ke-pwlevel @ 
5c20: 63 6f 6e 66 69 67 3a 70 77 2d 6c 65 76 65 6c 23  config:pw-level#
5c30: 20 21 0a 09 20 20 20 20 6b 65 79 2d 63 72 79 70   !..    key-cryp
5c40: 74 20 6b 65 2d 6f 66 66 73 65 74 20 36 34 40 20  t ke-offset 64@ 
5c50: 6b 65 79 3e 73 66 69 6c 65 40 70 6f 73 0a 09 20  key>sfile@pos.. 
5c60: 20 20 20 72 3e 20 63 6f 6e 66 69 67 3a 70 77 2d     r> config:pw-
5c70: 6c 65 76 65 6c 23 20 21 0a 09 54 48 45 4e 20 6f  level# !..THEN o
5c80: 3e 20 3b 5d 20 23 6d 61 70 0a 20 20 20 20 30 20  > ;] #map.    0 
5c90: 74 6f 20 6b 65 79 2d 73 66 64 20 3b 5d 20 73 61  to key-sfd ;] sa
5ca0: 76 65 2d 66 69 6c 65 20 20 3f 6b 65 79 2d 73 66  ve-file  ?key-sf
5cb0: 64 20 64 72 6f 70 20 3b 0a 0a 3a 20 73 61 76 65  d drop ;..: save
5cc0: 2d 6b 65 79 73 20 28 20 2d 2d 20 29 20 20 3f 2e  -keys ( -- )  ?.
5cd0: 6e 65 74 32 6f 2f 6b 65 79 73 0a 20 20 20 20 73  net2o/keys.    s
5ce0: 61 76 65 2d 70 75 62 6b 65 79 73 20 73 61 76 65  ave-pubkeys save
5cf0: 2d 73 65 63 6b 65 79 73 20 3b 0a 0a 3a 20 2b 67  -seckeys ;..: +g
5d00: 65 6e 2d 6b 65 79 73 20 28 20 6e 69 63 6b 20 75  en-keys ( nick u
5d10: 20 74 79 70 65 20 2d 2d 20 29 0a 20 20 20 20 67   type -- ).    g
5d20: 65 6e 2d 6b 65 79 73 20 20 36 34 23 2d 31 20 6b  en-keys  64#-1 k
5d30: 65 79 2d 72 65 61 64 2d 6f 66 66 73 65 74 20 36  ey-read-offset 6
5d40: 34 21 20 20 70 6b 63 20 6b 65 79 73 69 7a 65 32  4!  pkc keysize2
5d50: 20 6b 65 79 3a 6e 65 77 20 3e 6f 0a 20 20 20 20   key:new >o.    
5d60: 5b 20 31 20 69 6d 70 6f 72 74 23 73 65 6c 66 20  [ 1 import#self 
5d70: 6c 73 68 69 66 74 20 31 20 69 6d 70 6f 72 74 23  lshift 1 import#
5d80: 6e 65 77 20 6c 73 68 69 66 74 20 6f 72 20 5d 4c  new lshift or ]L
5d90: 20 6b 65 2d 69 6d 70 6f 72 74 73 20 21 0a 20 20   ke-imports !.  
5da0: 20 20 6b 65 2d 74 79 70 65 20 21 20 20 6b 65 2d    ke-type !  ke-
5db0: 6e 69 63 6b 20 24 21 20 20 6e 69 63 6b 21 0a 20  nick $!  nick!. 
5dc0: 20 20 20 63 6f 6e 66 69 67 3a 70 77 2d 6c 65 76     config:pw-lev
5dd0: 65 6c 23 20 40 20 6b 65 2d 70 77 6c 65 76 65 6c  el# @ ke-pwlevel
5de0: 20 21 20 20 70 65 72 6d 25 6d 79 73 65 6c 66 20   !  perm%myself 
5df0: 6b 65 2d 6d 61 73 6b 20 21 0a 20 20 20 20 73 6b  ke-mask !.    sk
5e00: 63 20 6b 65 79 73 69 7a 65 20 6b 65 2d 73 6b 20  c keysize ke-sk 
5e10: 73 65 63 21 20 20 2b 73 65 63 6b 65 79 0a 20 20  sec!  +seckey.  
5e20: 20 20 73 6b 72 65 76 20 6b 65 79 73 69 7a 65 20    skrev keysize 
5e30: 6b 65 2d 72 73 6b 20 73 65 63 21 0a 20 20 20 20  ke-rsk sec!.    
5e40: 6b 65 79 2d 73 69 67 6e 20 6f 3e 20 3b 0a 0a 24  key-sign o> ;..$
5e50: 34 30 20 62 75 66 66 65 72 3a 20 6e 69 63 6b 2d  40 buffer: nick-
5e60: 62 75 66 0a 0a 3a 20 67 65 74 2d 6e 69 63 6b 20  buf..: get-nick 
5e70: 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20  ( -- addr u ).  
5e80: 20 20 2e 22 20 6e 69 63 6b 3a 20 22 20 6e 69 63    ." nick: " nic
5e90: 6b 2d 62 75 66 20 24 34 30 20 61 63 63 65 70 74  k-buf $40 accept
5ea0: 20 6e 69 63 6b 2d 62 75 66 20 73 77 61 70 20 2d   nick-buf swap -
5eb0: 74 72 61 69 6c 69 6e 67 20 63 72 20 3b 0a 0a 66  trailing cr ;..f
5ec0: 61 6c 73 65 20 76 61 6c 75 65 20 3f 79 65 73 0a  alse value ?yes.
5ed0: 3a 20 79 65 73 3f 20 28 20 61 64 64 72 20 75 20  : yes? ( addr u 
5ee0: 2d 2d 20 66 6c 61 67 20 29 0a 20 20 20 20 3f 79  -- flag ).    ?y
5ef0: 65 73 20 49 46 20 20 32 64 72 6f 70 20 74 72 75  es IF  2drop tru
5f00: 65 20 20 45 4c 53 45 20 20 74 79 70 65 20 2e 22  e  ELSE  type ."
5f10: 20 20 28 79 2f 4e 29 22 20 6b 65 79 20 63 72 20    (y/N)" key cr 
5f20: 27 79 27 20 3d 20 20 54 48 45 4e 20 3b 0a 0a 3a  'y' =  THEN ;..:
5f30: 20 3f 72 73 6b 20 28 20 2d 2d 20 29 0a 20 20 20   ?rsk ( -- ).   
5f40: 20 70 6b 63 20 6b 65 79 73 69 7a 65 20 6b 65 79   pkc keysize key
5f50: 2d 65 78 69 73 74 3f 20 64 75 70 20 30 3d 20 49  -exist? dup 0= I
5f60: 46 20 20 64 72 6f 70 20 20 45 58 49 54 20 20 54  F  drop  EXIT  T
5f70: 48 45 4e 0a 20 20 20 20 3e 6f 20 6b 65 2d 72 73  HEN.    >o ke-rs
5f80: 6b 20 73 65 63 40 20 64 75 70 20 30 3d 20 49 46  k sec@ dup 0= IF
5f90: 20 20 32 64 72 6f 70 20 6f 3e 20 20 45 58 49 54    2drop o>  EXIT
5fa0: 20 20 54 48 45 4e 0a 20 20 20 20 2e 22 20 59 6f    THEN.    ." Yo
5fb0: 75 20 73 74 69 6c 6c 20 68 61 76 65 6e 27 74 20  u still haven't 
5fc0: 73 74 6f 72 65 64 20 79 6f 75 72 20 72 65 76 6f  stored your revo
5fd0: 6b 65 20 6b 65 79 20 73 65 63 75 72 65 6c 79 20  ke key securely 
5fe0: 6f 66 66 2d 6c 69 6e 65 2e 22 20 63 72 0a 20 20  off-line." cr.  
5ff0: 20 20 73 22 20 50 61 70 65 72 20 61 6e 64 20 70    s" Paper and p
6000: 65 6e 63 69 6c 20 72 65 61 64 79 3f 22 20 79 65  encil ready?" ye
6010: 73 3f 20 49 46 0a 09 2e 73 74 72 69 70 65 38 35  s? IF...stripe85
6020: 0a 09 73 22 20 57 72 69 74 74 65 6e 20 64 6f 77  ..s" Written dow
6030: 6e 3f 22 20 79 65 73 3f 20 49 46 0a 09 20 20 20  n?" yes? IF..   
6040: 20 73 22 20 59 6f 75 20 77 6f 6e 27 74 20 73 65   s" You won't se
6050: 65 20 74 68 69 73 20 61 67 61 69 6e 21 20 44 65  e this again! De
6060: 6c 65 74 65 3f 22 20 79 65 73 3f 0a 09 20 20 20  lete?" yes?..   
6070: 20 49 46 20 6b 65 2d 72 73 6b 20 73 65 63 2d 6f   IF ke-rsk sec-o
6080: 66 66 20 20 73 61 76 65 2d 6b 65 79 73 0a 09 09  ff  save-keys...
6090: 2e 22 20 72 65 76 6f 6b 65 20 6b 65 79 20 64 65  ." revoke key de
60a0: 6c 65 74 65 64 2e 22 20 63 72 20 6f 3e 20 20 45  leted." cr o>  E
60b0: 58 49 54 20 20 54 48 45 4e 20 20 54 48 45 4e 0a  XIT  THEN  THEN.
60c0: 20 20 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20      ELSE  2drop 
60d0: 20 54 48 45 4e 0a 20 20 20 20 2e 22 20 49 27 6d   THEN.    ." I'm
60e0: 20 6b 65 65 70 69 6e 67 20 79 6f 75 72 20 72 65   keeping your re
60f0: 76 6f 6b 65 20 6b 65 79 2e 20 20 54 68 69 73 20  voke key.  This 
6100: 77 69 6c 6c 20 73 68 6f 77 20 75 70 20 61 67 61  will show up aga
6110: 69 6e 2e 22 20 63 72 20 6f 3e 20 3b 0a 0a 5c 20  in." cr o> ;..\ 
6120: 72 65 61 64 20 6b 65 79 20 66 69 6c 65 0a 0a 3a  read key file..:
6130: 20 74 72 79 2d 64 65 63 72 79 70 74 2d 6b 65 79   try-decrypt-key
6140: 20 28 20 6b 65 79 20 75 31 20 2d 2d 20 61 64 64   ( key u1 -- add
6150: 72 20 75 32 20 66 6c 61 67 20 29 0a 20 20 20 20  r u2 flag ).    
6160: 6b 65 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d  keypack keypack-
6170: 64 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 6d  d keypack-all# m
6180: 6f 76 65 0a 20 20 20 20 6b 65 79 70 61 63 6b 2d  ove.    keypack-
6190: 64 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 32  d keypack-all# 2
61a0: 73 77 61 70 0a 20 20 20 20 64 75 70 20 24 32 30  swap.    dup $20
61b0: 20 3d 20 49 46 20 20 64 65 63 72 79 70 74 24 20   = IF  decrypt$ 
61c0: 20 45 4c 53 45 0a 09 6b 65 79 70 61 63 6b 20 63   ELSE..keypack c
61d0: 40 20 24 46 20 61 6e 64 20 63 6f 6e 66 69 67 3a  @ $F and config:
61e0: 70 77 2d 6d 61 78 6c 65 76 65 6c 23 20 40 20 3c  pw-maxlevel# @ <
61f0: 3d 0a 09 49 46 20 20 64 65 63 72 79 70 74 2d 70  =..IF  decrypt-p
6200: 77 24 20 20 45 4c 53 45 20 20 32 64 72 6f 70 20  w$  ELSE  2drop 
6210: 66 61 6c 73 65 20 20 54 48 45 4e 0a 20 20 20 20  false  THEN.    
6220: 54 48 45 4e 20 3b 0a 0a 3a 20 74 72 79 2d 64 65  THEN ;..: try-de
6230: 63 72 79 70 74 20 28 20 66 6c 61 67 20 2d 2d 20  crypt ( flag -- 
6240: 61 64 64 72 20 75 20 2f 20 30 20 30 20 29 20 7b  addr u / 0 0 ) {
6250: 20 66 6c 61 67 20 7d 0a 20 20 20 20 6b 65 79 73   flag }.    keys
6260: 20 24 5b 5d 23 20 30 20 3f 44 4f 0a 09 49 20 6b   $[]# 0 ?DO..I k
6270: 65 79 73 20 73 65 63 5b 5d 40 20 64 75 70 20 6b  eys sec[]@ dup k
6280: 65 79 73 69 7a 65 20 3d 20 66 6c 61 67 20 78 6f  eysize = flag xo
6290: 72 20 49 46 0a 09 20 20 20 20 74 72 79 2d 64 65  r IF..    try-de
62a0: 63 72 79 70 74 2d 6b 65 79 20 49 46 0a 09 09 49  crypt-key IF...I
62b0: 20 6b 65 79 73 20 24 5b 5d 20 40 20 64 75 70 20   keys $[] @ dup 
62c0: 3e 73 74 6f 72 65 6b 65 79 20 21 20 64 65 66 61  >storekey ! defa
62d0: 75 6c 74 6b 65 79 20 21 0a 09 09 75 6e 6c 6f 6f  ultkey !...unloo
62e0: 70 20 20 45 58 49 54 20 20 54 48 45 4e 20 20 54  p  EXIT  THEN  T
62f0: 48 45 4e 0a 09 32 64 72 6f 70 0a 20 20 20 20 4c  HEN..2drop.    L
6300: 4f 4f 50 20 20 30 20 30 20 3b 0a 0a 3a 20 3f 70  OOP  0 0 ;..: ?p
6310: 65 72 6d 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29  erm ( o:key -- )
6320: 0a 20 20 20 20 6b 65 2d 73 6b 20 73 65 63 40 20  .    ke-sk sec@ 
6330: 6e 69 70 20 49 46 20 20 70 65 72 6d 25 6d 79 73  nip IF  perm%mys
6340: 65 6c 66 20 20 45 4c 53 45 20 20 70 65 72 6d 25  elf  ELSE  perm%
6350: 64 65 66 61 75 6c 74 20 20 54 48 45 4e 20 20 6b  default  THEN  k
6360: 65 2d 6d 61 73 6b 20 21 20 3b 0a 0a 3a 20 64 6f  e-mask ! ;..: do
6370: 2d 6b 65 79 20 28 20 61 64 64 72 20 75 20 2f 20  -key ( addr u / 
6380: 30 20 30 20 20 2d 2d 20 29 0a 20 20 20 20 64 75  0 0  -- ).    du
6390: 70 20 30 3d 20 49 46 20 20 32 64 72 6f 70 20 20  p 0= IF  2drop  
63a0: 45 58 49 54 20 20 54 48 45 4e 0a 20 20 20 20 73  EXIT  THEN.    s
63b0: 61 6d 70 6c 65 2d 6b 65 79 20 3e 6f 20 6b 65 2d  ample-key >o ke-
63c0: 73 6b 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d  sk ke-end over -
63d0: 20 65 72 61 73 65 20 20 64 6f 2d 63 6d 64 2d 6c   erase  do-cmd-l
63e0: 6f 6f 70 20 6f 3e 20 3b 0a 0a 3a 20 2e 6b 65 79  oop o> ;..: .key
63f0: 24 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a  $ ( addr u -- ).
6400: 20 20 20 20 73 61 6d 70 6c 65 2d 6b 65 79 20 3e      sample-key >
6410: 6f 20 20 6b 65 2d 73 6b 20 6b 65 2d 65 6e 64 20  o  ke-sk ke-end 
6420: 6f 76 65 72 20 2d 20 65 72 61 73 65 0a 20 20 20  over - erase.   
6430: 20 73 69 67 6e 65 64 2d 76 61 6c 20 76 61 6c 69   signed-val vali
6440: 64 61 74 65 64 20 6f 72 21 20 20 63 2d 73 74 61  dated or!  c-sta
6450: 74 65 20 6f 66 66 20 20 6e 65 73 74 2d 63 6d 64  te off  nest-cmd
6460: 2d 6c 6f 6f 70 0a 20 20 20 20 73 69 67 6e 65 64  -loop.    signed
6470: 2d 76 61 6c 20 69 6e 76 65 72 74 20 76 61 6c 69  -val invert vali
6480: 64 61 74 65 64 20 61 6e 64 21 0a 20 20 20 20 2e  dated and!.    .
6490: 6b 65 79 2d 73 68 6f 72 74 20 66 72 65 65 2d 6b  key-short free-k
64a0: 65 79 20 6f 3e 20 3b 0a 0a 3a 20 72 65 61 64 2d  ey o> ;..: read-
64b0: 6b 65 79 73 2d 6c 6f 6f 70 20 28 20 66 64 20 2d  keys-loop ( fd -
64c0: 2d 20 29 20 20 63 6f 64 65 2d 6b 65 79 0a 20 20  - )  code-key.  
64d0: 20 20 3e 72 20 23 30 2e 20 72 40 20 72 65 70 6f    >r #0. r@ repo
64e0: 73 69 74 69 6f 6e 2d 66 69 6c 65 20 74 68 72 6f  sition-file thro
64f0: 77 0a 20 20 20 20 42 45 47 49 4e 0a 09 72 40 20  w.    BEGIN..r@ 
6500: 66 69 6c 65 2d 70 6f 73 69 74 69 6f 6e 20 74 68  file-position th
6510: 72 6f 77 20 64 3e 36 34 20 6b 65 79 2d 72 65 61  row d>64 key-rea
6520: 64 2d 6f 66 66 73 65 74 20 36 34 21 0a 09 6b 65  d-offset 64!..ke
6530: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
6540: 6c 23 20 72 40 20 72 65 61 64 2d 66 69 6c 65 20  l# r@ read-file 
6550: 74 68 72 6f 77 0a 09 6b 65 79 70 61 63 6b 2d 61  throw..keypack-a
6560: 6c 6c 23 20 3d 20 57 48 49 4c 45 0a 09 20 20 20  ll# = WHILE..   
6570: 20 69 6d 70 6f 72 74 2d 74 79 70 65 20 40 20 69   import-type @ i
6580: 6d 70 6f 72 74 23 73 65 6c 66 20 3d 20 74 72 79  mport#self = try
6590: 2d 64 65 63 72 79 70 74 20 64 6f 2d 6b 65 79 0a  -decrypt do-key.
65a0: 20 20 20 20 52 45 50 45 41 54 20 20 72 64 72 6f      REPEAT  rdro
65b0: 70 20 20 63 6f 64 65 30 2d 62 75 66 20 3b 0a 3a  p  code0-buf ;.:
65c0: 20 72 65 61 64 2d 6b 65 79 2d 6c 6f 6f 70 20 28   read-key-loop (
65d0: 20 2d 2d 20 29 0a 20 20 20 20 69 6d 70 6f 72 74   -- ).    import
65e0: 23 73 65 6c 66 20 69 6d 70 6f 72 74 2d 74 79 70  #self import-typ
65f0: 65 20 21 0a 20 20 20 20 3f 6b 65 79 2d 73 66 64  e !.    ?key-sfd
6600: 20 72 65 61 64 2d 6b 65 79 73 2d 6c 6f 6f 70 20   read-keys-loop 
6610: 3b 0a 3a 20 72 65 61 64 2d 70 6b 65 79 2d 6c 6f  ;.: read-pkey-lo
6620: 6f 70 20 28 20 2d 2d 20 29 0a 20 20 20 20 6c 61  op ( -- ).    la
6630: 73 74 6b 65 79 40 20 64 72 6f 70 20 64 65 66 61  stkey@ drop defa
6640: 75 6c 74 6b 65 79 20 21 20 5c 20 61 74 20 6c 65  ultkey ! \ at le
6650: 61 73 74 20 6f 6e 65 20 64 65 66 61 75 6c 74 20  ast one default 
6660: 6b 65 79 20 61 76 61 69 6c 61 62 6c 65 0a 20 20  key available.  
6670: 20 20 2d 31 20 63 6f 6e 66 69 67 3a 70 77 2d 6c    -1 config:pw-l
6680: 65 76 65 6c 23 0a 20 20 20 20 5b 3a 20 69 6d 70  evel#.    [: imp
6690: 6f 72 74 23 6e 65 77 20 69 6d 70 6f 72 74 2d 74  ort#new import-t
66a0: 79 70 65 20 21 20 3f 6b 65 79 2d 70 66 64 20 72  ype ! ?key-pfd r
66b0: 65 61 64 2d 6b 65 79 73 2d 6c 6f 6f 70 20 3b 5d  ead-keys-loop ;]
66c0: 20 21 77 72 61 70 70 65 72 20 3b 0a 0a 3a 20 72   !wrapper ;..: r
66d0: 65 61 64 2d 6b 65 79 73 20 28 20 2d 2d 20 29 0a  ead-keys ( -- ).
66e0: 20 20 20 20 72 65 61 64 2d 6b 65 79 2d 6c 6f 6f      read-key-loo
66f0: 70 20 72 65 61 64 2d 70 6b 65 79 2d 6c 6f 6f 70  p read-pkey-loop
6700: 20 69 6d 70 6f 72 74 23 6e 65 77 20 69 6d 70 6f   import#new impo
6710: 72 74 2d 74 79 70 65 20 21 20 3b 0a 0a 3a 20 72  rt-type ! ;..: r
6720: 65 61 64 2d 70 6b 32 6b 65 79 24 20 28 20 61 64  ead-pk2key$ ( ad
6730: 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 5c 67  dr u -- ).    \g
6740: 20 72 65 61 64 20 61 20 6e 65 73 74 65 64 20 6b   read a nested k
6750: 65 79 20 69 6e 74 6f 20 73 61 6d 70 6c 65 2d 6b  ey into sample-k
6760: 65 79 0a 20 20 20 20 73 61 6d 70 6c 65 2d 6b 65  ey.    sample-ke
6770: 79 20 3e 6f 20 63 2d 73 74 61 74 65 20 6f 66 66  y >o c-state off
6780: 20 20 73 69 6d 2d 6e 69 63 6b 21 20 6f 6e 0a 20    sim-nick! on. 
6790: 20 20 20 70 6b 32 2d 73 69 67 3f 20 21 21 73 69     pk2-sig? !!si
67a0: 67 21 21 20 73 69 67 70 6b 32 73 69 7a 65 23 20  g!! sigpk2size# 
67b0: 2d 20 32 64 75 70 20 2b 20 3e 72 20 64 6f 2d 6e  - 2dup + >r do-n
67c0: 65 73 74 73 69 67 0a 20 20 20 20 72 40 20 6b 65  estsig.    r@ ke
67d0: 79 73 69 7a 65 32 20 6b 65 2d 70 6b 20 24 21 0a  ysize2 ke-pk $!.
67e0: 20 20 20 20 72 3e 20 6b 65 79 73 69 7a 65 32 20      r> keysize2 
67f0: 2b 20 73 69 67 73 69 7a 65 23 20 6b 65 2d 73 65  + sigsize# ke-se
6800: 6c 66 73 69 67 20 24 21 0a 20 20 20 20 6f 3e 20  lfsig $!.    o> 
6810: 20 73 69 6d 2d 6e 69 63 6b 21 20 6f 66 66 20 3b   sim-nick! off ;
6820: 0a 0a 3a 20 2e 70 6b 32 6b 65 79 24 20 28 20 61  ..: .pk2key$ ( a
6830: 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20 72  ddr u -- ).    r
6840: 65 61 64 2d 70 6b 32 6b 65 79 24 20 73 61 6d 70  ead-pk2key$ samp
6850: 6c 65 2d 6b 65 79 20 3e 6f 0a 20 20 20 20 5b 20  le-key >o.    [ 
6860: 31 20 69 6d 70 6f 72 74 23 69 6e 76 69 74 65 64  1 import#invited
6870: 20 6c 73 68 69 66 74 20 31 20 69 6d 70 6f 72 74   lshift 1 import
6880: 23 6e 65 77 20 6c 73 68 69 66 74 20 6f 72 20 5d  #new lshift or ]
6890: 4c 20 6b 65 2d 69 6d 70 6f 72 74 73 20 21 0a 20  L ke-imports !. 
68a0: 20 20 20 2e 6b 65 79 2d 69 6e 76 69 74 65 20 66     .key-invite f
68b0: 72 65 65 2d 6b 65 79 20 6f 3e 20 3b 0a 0a 5c 20  ree-key o> ;..\ 
68c0: 73 65 6c 65 63 74 20 6b 65 79 20 62 79 20 6e 69  select key by ni
68d0: 63 6b 0a 0a 3a 20 3e 72 61 77 2d 6b 65 79 20 28  ck..: >raw-key (
68e0: 20 6f 20 2d 2d 20 29 0a 20 20 20 20 64 75 70 20   o -- ).    dup 
68f0: 30 3d 20 21 21 6e 6f 2d 6e 69 63 6b 21 21 20 3e  0= !!no-nick!! >
6900: 6f 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 70  o.    ke-pk $@ p
6910: 6b 63 20 70 6b 72 6b 23 20 73 6d 6f 76 65 0a 20  kc pkrk# smove. 
6920: 20 20 20 6b 65 2d 73 6b 20 73 65 63 40 20 73 6b     ke-sk sec@ sk
6930: 63 20 73 77 61 70 20 6b 65 79 7c 20 6d 6f 76 65  c swap key| move
6940: 0a 20 20 20 20 3e 73 6b 73 69 67 20 6f 3e 20 3b  .    >sksig o> ;
6950: 0a 0a 3a 20 3e 6b 65 79 20 28 20 61 64 64 72 20  ..: >key ( addr 
6960: 75 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 23 20  u -- ).    key# 
6970: 40 20 30 3d 20 49 46 20 20 72 65 61 64 2d 6b 65  @ 0= IF  read-ke
6980: 79 73 20 20 54 48 45 4e 0a 20 20 20 20 6e 69 63  ys  THEN.    nic
6990: 6b 2d 6b 65 79 20 3e 72 61 77 2d 6b 65 79 20 3b  k-key >raw-key ;
69a0: 0a 0a 3a 20 69 27 6d 20 28 20 22 6e 61 6d 65 22  ..: i'm ( "name"
69b0: 20 2d 2d 20 29 20 70 61 72 73 65 2d 6e 61 6d 65   -- ) parse-name
69c0: 20 3e 6b 65 79 20 3b 0a 3a 20 70 6b 27 20 28 20   >key ;.: pk' ( 
69d0: 22 6e 61 6d 65 22 20 2d 2d 20 61 64 64 72 20 75  "name" -- addr u
69e0: 20 29 0a 20 20 20 20 70 61 72 73 65 2d 6e 61 6d   ).    parse-nam
69f0: 65 20 6e 69 63 6b 3e 70 6b 20 3b 0a 0a 3a 20 64  e nick>pk ;..: d
6a00: 65 73 74 2d 6b 65 79 20 28 20 61 64 64 72 20 75  est-key ( addr u
6a10: 20 2d 2d 20 29 20 64 75 70 20 30 3d 20 49 46 20   -- ) dup 0= IF 
6a20: 20 32 64 72 6f 70 20 20 45 58 49 54 20 20 54 48   2drop  EXIT  TH
6a30: 45 4e 0a 20 20 20 20 6e 69 63 6b 2d 6b 65 79 20  EN.    nick-key 
6a40: 3e 6f 20 6f 20 30 3d 20 21 21 75 6e 6b 6e 6f 77  >o o 0= !!unknow
6a50: 6e 2d 6b 65 79 21 21 0a 20 20 20 20 6b 65 2d 70  n-key!!.    ke-p
6a60: 6b 20 24 40 20 6f 3e 0a 20 20 20 20 70 75 62 6b  k $@ o>.    pubk
6a70: 65 79 20 24 21 20 3b 0a 0a 3a 20 64 65 73 74 2d  ey $! ;..: dest-
6a80: 70 6b 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29  pk ( addr u -- )
6a90: 20 6b 65 79 32 7c 20 32 64 75 70 20 6b 65 79 7c   key2| 2dup key|
6aa0: 20 6b 65 79 23 20 23 40 20 30 3d 20 49 46 0a 09   key# #@ 0= IF..
6ab0: 64 72 6f 70 20 70 75 62 6b 65 79 20 24 21 20 20  drop pubkey $!  
6ac0: 70 65 72 6d 25 75 6e 6b 6e 6f 77 6e 20 70 65 72  perm%unknown per
6ad0: 6d 2d 6d 61 73 6b 20 21 0a 20 20 20 20 45 4c 53  m-mask !.    ELS
6ae0: 45 20 20 63 65 6c 6c 2b 20 3e 6f 0a 09 6b 65 2d  E  cell+ >o..ke-
6af0: 6d 61 73 6b 20 40 0a 09 6b 65 2d 70 6b 20 24 40  mask @..ke-pk $@
6b00: 20 6f 3e 0a 09 70 75 62 6b 65 79 20 24 21 20 20   o>..pubkey $!  
6b10: 70 65 72 6d 2d 6d 61 73 6b 20 21 20 20 32 64 72  perm-mask !  2dr
6b20: 6f 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 72 65  op  THEN ;..: re
6b30: 70 6c 61 63 65 2d 6b 65 79 20 31 20 2f 73 74 72  place-key 1 /str
6b40: 69 6e 67 20 7b 20 72 65 76 2d 61 64 64 72 20 75  ing { rev-addr u
6b50: 20 2d 2d 20 6f 20 7d 20 5c 20 72 65 76 6f 63 61   -- o } \ revoca
6b60: 74 69 6f 6e 20 74 69 63 6b 65 74 0a 20 20 20 20  tion ticket.    
6b70: 6b 65 79 28 20 2e 22 20 52 65 70 6c 61 63 65 3a  key( ." Replace:
6b80: 22 20 63 72 20 6f 20 63 65 6c 6c 2d 20 30 20 2e  " cr o cell- 0 .
6b90: 6b 65 79 20 29 0a 20 20 20 20 69 6d 70 6f 72 74  key ).    import
6ba0: 23 73 65 6c 66 20 69 6d 70 6f 72 74 2d 74 79 70  #self import-typ
6bb0: 65 20 21 0a 20 20 20 20 73 22 20 23 72 65 76 6f  e !.    s" #revo
6bc0: 6b 65 64 22 20 64 75 70 20 3e 72 20 6b 65 2d 6e  ked" dup >r ke-n
6bd0: 69 63 6b 20 24 2b 21 0a 20 20 20 20 6b 65 2d 6e  ick $+!.    ke-n
6be0: 69 63 6b 20 24 40 20 72 3e 20 2d 20 6b 65 2d 70  ick $@ r> - ke-p
6bf0: 72 6f 66 20 24 40 20 6b 65 2d 73 69 67 73 20 6b  rof $@ ke-sigs k
6c00: 65 2d 74 79 70 65 20 40 0a 20 20 20 20 72 65 76  e-type @.    rev
6c10: 2d 61 64 64 72 20 70 6b 72 6b 23 20 6b 65 79 3f  -addr pkrk# key?
6c20: 6e 65 77 20 3e 6f 0a 20 20 20 20 6b 65 2d 74 79  new >o.    ke-ty
6c30: 70 65 20 21 20 5b 3a 20 6b 65 2d 73 69 67 73 20  pe ! [: ke-sigs 
6c40: 24 2b 5b 5d 21 20 3b 5d 20 24 5b 5d 6d 61 70 20  $+[]! ;] $[]map 
6c50: 6b 65 2d 70 72 6f 66 20 24 21 20 6b 65 2d 6e 69  ke-prof $! ke-ni
6c60: 63 6b 20 24 21 0a 20 20 20 20 72 65 76 2d 61 64  ck $!.    rev-ad
6c70: 64 72 20 70 6b 72 6b 23 20 6b 65 2d 70 6b 20 24  dr pkrk# ke-pk $
6c80: 21 0a 20 20 20 20 72 65 76 2d 61 64 64 72 20 75  !.    rev-addr u
6c90: 20 2b 20 31 2d 20 64 75 70 20 63 40 20 32 2a 20   + 1- dup c@ 2* 
6ca0: 2d 20 24 31 30 20 2d 20 24 31 30 20 6b 65 2d 73  - $10 - $10 ke-s
6cb0: 65 6c 66 73 69 67 20 24 21 0a 20 20 20 20 6b 65  elfsig $!.    ke
6cc0: 79 28 20 2e 22 20 77 69 74 68 3a 22 20 63 72 20  y( ." with:" cr 
6cd0: 6f 20 63 65 6c 6c 2d 20 30 20 2e 6b 65 79 20 29  o cell- 0 .key )
6ce0: 20 6f 20 6f 3e 0a 20 20 20 20 69 6d 70 6f 72 74   o o>.    import
6cf0: 23 6e 65 77 20 69 6d 70 6f 72 74 2d 74 79 70 65  #new import-type
6d00: 20 21 20 3b 0a 0a 3a 20 72 65 6e 65 77 2d 6b 65   ! ;..: renew-ke
6d10: 79 20 28 20 72 65 76 61 64 64 72 20 75 31 20 6b  y ( revaddr u1 k
6d20: 65 79 61 64 64 72 20 75 32 20 2d 2d 20 6f 20 29  eyaddr u2 -- o )
6d30: 0a 20 20 20 20 63 75 72 72 65 6e 74 2d 6b 65 79  .    current-key
6d40: 20 3e 6f 20 72 65 70 6c 61 63 65 2d 6b 65 79 20   >o replace-key 
6d50: 6f 3e 0a 20 20 20 20 3e 6f 20 73 6b 63 20 6b 65  o>.    >o skc ke
6d60: 79 73 69 7a 65 20 6b 65 2d 73 6b 20 73 65 63 21  ysize ke-sk sec!
6d70: 20 6f 20 6f 3e 20 3b 0a 0a 5c 20 67 65 6e 65 72   o o> ;..\ gener
6d80: 61 74 65 20 6e 65 77 20 6b 65 79 0a 0a 3a 20 6f  ate new key..: o
6d90: 75 74 2d 6b 65 79 20 28 20 6f 20 2d 2d 20 29 0a  ut-key ( o -- ).
6da0: 20 20 20 20 3e 6f 20 70 61 63 6b 2d 6f 75 74 6b      >o pack-outk
6db0: 65 79 20 5b 27 5d 20 2e 6e 69 63 6b 2d 62 61 73  ey ['] .nick-bas
6dc0: 65 20 24 74 6d 70 20 66 6e 2d 73 61 6e 69 74 69  e $tmp fn-saniti
6dd0: 7a 65 20 6f 3e 0a 20 20 20 20 5b 3a 20 2e 22 20  ze o>.    [: ." 
6de0: 7e 2f 22 20 74 79 70 65 20 2e 22 20 2e 6e 32 6f  ~/" type ." .n2o
6df0: 22 20 3b 5d 20 24 74 6d 70 20 77 2f 6f 20 63 72  " ;] $tmp w/o cr
6e00: 65 61 74 65 2d 66 69 6c 65 20 74 68 72 6f 77 0a  eate-file throw.
6e10: 20 20 20 20 3e 72 20 63 6d 64 62 75 66 24 20 72      >r cmdbuf$ r
6e20: 40 20 77 72 69 74 65 2d 66 69 6c 65 20 74 68 72  @ write-file thr
6e30: 6f 77 20 72 3e 20 63 6c 6f 73 65 2d 66 69 6c 65  ow r> close-file
6e40: 20 74 68 72 6f 77 20 3b 0a 3a 20 6f 75 74 2d 6d   throw ;.: out-m
6e50: 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 70 6b 63  e ( -- ).    pkc
6e60: 20 6b 65 79 73 69 7a 65 20 6b 65 79 23 20 23 40   keysize key# #@
6e70: 20 30 3d 20 21 21 75 6e 6b 6e 6f 77 6e 2d 6b 65   0= !!unknown-ke
6e80: 79 21 21 0a 20 20 20 20 63 65 6c 6c 2b 20 6f 75  y!!.    cell+ ou
6e90: 74 2d 6b 65 79 20 3b 0a 0a 56 61 72 69 61 62 6c  t-key ;..Variabl
6ea0: 65 20 64 68 74 72 6f 6f 74 2e 6e 32 6f 0a 0a 3a  e dhtroot.n2o..:
6eb0: 20 2b 64 68 74 72 6f 6f 74 20 28 20 2d 2d 20 29   +dhtroot ( -- )
6ec0: 0a 20 20 20 20 64 65 66 61 75 6c 74 6b 65 79 20  .    defaultkey 
6ed0: 40 20 3e 73 74 6f 72 65 6b 65 79 20 21 0a 20 20  @ >storekey !.  
6ee0: 20 20 69 6d 70 6f 72 74 23 6d 61 6e 75 61 6c 20    import#manual 
6ef0: 69 6d 70 6f 72 74 2d 74 79 70 65 20 21 20 20 36  import-type !  6
6f00: 34 23 2d 31 20 6b 65 79 2d 72 65 61 64 2d 6f 66  4#-1 key-read-of
6f10: 66 73 65 74 20 36 34 21 0a 20 20 20 20 64 68 74  fset 64!.    dht
6f20: 72 6f 6f 74 2e 6e 32 6f 20 24 40 20 64 6f 2d 6b  root.n2o $@ do-k
6f30: 65 79 20 20 69 6d 70 6f 72 74 23 6e 65 77 20 69  ey  import#new i
6f40: 6d 70 6f 72 74 2d 74 79 70 65 20 21 20 3b 0a 0a  mport-type ! ;..
6f50: 3a 20 6e 65 77 2d 6b 65 79 20 28 20 6e 69 63 6b  : new-key ( nick
6f60: 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20 20 20  addr u -- ).    
6f70: 3f 63 68 65 63 6b 2d 72 6e 67 20 5c 20 62 65 66  ?check-rng \ bef
6f80: 6f 72 65 20 67 65 6e 65 72 61 74 69 6e 67 20 61  ore generating a
6f90: 20 6b 65 79 2c 20 63 68 65 63 6b 20 74 68 65 20   key, check the 
6fa0: 72 6e 67 20 66 6f 72 20 68 65 61 6c 74 68 0a 20  rng for health. 
6fb0: 20 20 20 2b 6e 65 77 70 68 72 61 73 65 20 6b 65     +newphrase ke
6fc0: 79 3e 64 65 66 61 75 6c 74 0a 20 20 20 20 6b 65  y>default.    ke
6fd0: 79 23 75 73 65 72 20 2b 67 65 6e 2d 6b 65 79 73  y#user +gen-keys
6fe0: 0a 20 20 20 20 73 65 63 72 65 74 2d 6b 65 79 73  .    secret-keys
6ff0: 23 20 31 2d 20 73 65 63 72 65 74 2d 6b 65 79 20  # 1- secret-key 
7000: 3e 72 61 77 2d 6b 65 79 20 20 6c 61 73 74 6b 65  >raw-key  lastke
7010: 79 40 20 64 72 6f 70 20 64 65 66 61 75 6c 74 6b  y@ drop defaultk
7020: 65 79 20 21 0a 20 20 20 20 6f 75 74 2d 6d 65 20  ey !.    out-me 
7030: 2b 64 68 74 72 6f 6f 74 20 73 61 76 65 2d 6b 65  +dhtroot save-ke
7040: 79 73 20 3b 0a 0a 5c 20 72 65 76 6f 6b 61 74 69  ys ;..\ revokati
7050: 6f 6e 0a 0a 34 20 64 61 74 65 73 69 7a 65 23 20  on..4 datesize# 
7060: 2b 20 6b 65 79 73 69 7a 65 20 39 20 2a 20 2b 20  + keysize 9 * + 
7070: 43 6f 6e 73 74 61 6e 74 20 72 65 76 73 69 7a 65  Constant revsize
7080: 23 0a 0a 56 61 72 69 61 62 6c 65 20 72 65 76 74  #..Variable revt
7090: 6f 6b 65 6e 0a 0a 3a 20 30 6f 6c 64 6b 65 79 20  oken..: 0oldkey 
70a0: 28 20 2d 2d 20 29 20 5c 20 70 75 62 6b 65 79 73  ( -- ) \ pubkeys
70b0: 20 63 61 6e 20 73 74 61 79 0a 20 20 20 20 6f 6c   can stay.    ol
70c0: 64 73 6b 63 20 6b 65 79 73 69 7a 65 20 65 72 61  dskc keysize era
70d0: 73 65 20 20 6f 6c 64 73 6b 72 65 76 20 6b 65 79  se  oldskrev key
70e0: 73 69 7a 65 20 65 72 61 73 65 20 3b 0a 0a 3a 20  size erase ;..: 
70f0: 6b 65 79 6d 6f 76 65 20 28 20 61 64 64 72 31 20  keymove ( addr1 
7100: 61 64 64 72 32 20 2d 2d 20 29 20 20 6b 65 79 73  addr2 -- )  keys
7110: 69 7a 65 20 6d 6f 76 65 20 3b 0a 0a 3a 20 72 65  ize move ;..: re
7120: 76 6f 6b 65 2d 76 65 72 69 66 79 20 28 20 61 64  voke-verify ( ad
7130: 64 72 20 75 31 20 70 6b 20 73 74 72 69 6e 67 20  dr u1 pk string 
7140: 75 32 20 2d 2d 20 61 64 64 72 20 75 20 66 6c 61  u2 -- addr u fla
7150: 67 20 29 20 72 6f 74 20 3e 72 20 32 3e 72 20 63  g ) rot >r 2>r c
7160: 3a 30 6b 65 79 0a 20 20 20 20 73 69 67 6f 6e 6c  :0key.    sigonl
7170: 79 73 69 7a 65 23 20 2d 20 32 64 75 70 20 32 72  ysize# - 2dup 2r
7180: 3e 20 3e 6b 65 79 65 64 2d 68 61 73 68 0a 20 20  > >keyed-hash.  
7190: 20 20 73 69 67 64 61 74 65 20 2b 64 61 74 65 0a    sigdate +date.
71a0: 20 20 20 20 32 64 75 70 20 2b 20 72 3e 20 65 64      2dup + r> ed
71b0: 2d 76 65 72 69 66 79 20 3b 0a 0a 3a 20 3e 72 65  -verify ;..: >re
71c0: 76 6f 6b 65 20 28 20 73 6b 72 65 76 20 2d 2d 20  voke ( skrev -- 
71d0: 29 20 20 73 6b 72 65 76 20 6b 65 79 6d 6f 76 65  )  skrev keymove
71e0: 20 20 70 6b 63 20 63 68 65 63 6b 2d 72 65 76 3f    pkc check-rev?
71f0: 20 30 3d 20 21 21 6e 6f 74 2d 6d 79 2d 72 65 76   0= !!not-my-rev
7200: 73 6b 21 21 20 3b 0a 0a 3a 20 2b 72 65 76 73 69  sk!! ;..: +revsi
7210: 67 6e 20 28 20 73 6b 20 70 6b 20 2d 2d 20 29 20  gn ( sk pk -- ) 
7220: 20 73 6b 73 69 67 20 2d 72 6f 74 20 65 64 2d 73   sksig -rot ed-s
7230: 69 67 6e 20 72 65 76 74 6f 6b 65 6e 20 24 2b 21  ign revtoken $+!
7240: 20 62 6c 20 72 65 76 74 6f 6b 65 6e 20 63 24 2b   bl revtoken c$+
7250: 21 20 3b 0a 0a 3a 20 73 69 67 6e 2d 74 6f 6b 65  ! ;..: sign-toke
7260: 6e 2c 20 28 20 73 6b 20 70 6b 20 73 74 72 69 6e  n, ( sk pk strin
7270: 67 20 75 32 20 2d 2d 20 29 0a 20 20 20 20 63 3a  g u2 -- ).    c:
7280: 30 6b 65 79 20 72 65 76 74 6f 6b 65 6e 20 24 40  0key revtoken $@
7290: 20 32 73 77 61 70 20 3e 6b 65 79 65 64 2d 68 61   2swap >keyed-ha
72a0: 73 68 0a 20 20 20 20 73 69 67 64 61 74 65 20 2b  sh.    sigdate +
72b0: 64 61 74 65 20 2b 72 65 76 73 69 67 6e 20 3b 0a  date +revsign ;.
72c0: 0a 3a 20 72 65 76 6f 6b 65 2d 6b 65 79 20 28 20  .: revoke-key ( 
72d0: 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20 20 20  -- addr u ).    
72e0: 73 6b 63 20 6f 6c 64 73 6b 63 20 6b 65 79 6d 6f  skc oldskc keymo
72f0: 76 65 20 20 70 6b 63 20 6f 6c 64 70 6b 63 20 6b  ve  pkc oldpkc k
7300: 65 79 6d 6f 76 65 20 20 73 6b 72 65 76 20 6f 6c  eymove  skrev ol
7310: 64 73 6b 72 65 76 20 6b 65 79 6d 6f 76 65 0a 20  dskrev keymove. 
7320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7330: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7340: 20 20 20 20 20 20 20 20 20 20 5c 20 62 61 63 6b            \ back
7350: 75 70 20 6b 65 79 73 0a 20 20 20 20 6f 6c 64 73  up keys.    olds
7360: 6b 72 65 76 20 6f 6c 64 70 6b 72 65 76 20 73 6b  krev oldpkrev sk
7370: 3e 70 6b 20 20 20 20 20 20 20 20 20 20 20 20 20  >pk             
7380: 20 20 20 5c 20 67 65 6e 65 72 61 74 65 20 72 65     \ generate re
7390: 76 6f 6b 61 74 69 6f 6e 20 70 75 62 6b 65 79 0a  vokation pubkey.
73a0: 20 20 20 20 67 65 6e 2d 6b 65 79 73 20 20 20 20      gen-keys    
73b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
73c0: 20 20 20 20 20 20 20 20 20 20 20 5c 20 67 65 6e             \ gen
73d0: 65 72 61 74 65 20 6e 65 77 20 6b 65 79 73 0a 20  erate new keys. 
73e0: 20 20 20 70 6b 63 20 6b 65 79 73 69 7a 65 32 20     pkc keysize2 
73f0: 72 65 76 74 6f 6b 65 6e 20 24 21 20 20 20 20 20  revtoken $!     
7400: 20 20 20 20 20 20 20 20 20 20 5c 20 6d 79 20 6e            \ my n
7410: 65 77 20 6b 65 79 0a 20 20 20 20 6f 6c 64 70 6b  ew key.    oldpk
7420: 72 65 76 20 6b 65 79 73 69 7a 65 20 72 65 76 74  rev keysize revt
7430: 6f 6b 65 6e 20 24 2b 21 20 20 20 20 20 20 20 20  oken $+!        
7440: 20 20 5c 20 72 65 76 6f 6b 65 20 74 6f 6b 65 6e    \ revoke token
7450: 0a 20 20 20 20 6f 6c 64 73 6b 72 65 76 20 6f 6c  .    oldskrev ol
7460: 64 70 6b 72 65 76 20 22 72 65 76 6f 6b 65 22 20  dpkrev "revoke" 
7470: 73 69 67 6e 2d 74 6f 6b 65 6e 2c 20 5c 20 72 65  sign-token, \ re
7480: 76 6f 6b 65 20 73 69 67 6e 61 74 75 72 65 0a 20  voke signature. 
7490: 20 20 20 73 6b 63 20 70 6b 63 20 22 73 65 6c 66     skc pkc "self
74a0: 73 69 67 6e 22 20 73 69 67 6e 2d 74 6f 6b 65 6e  sign" sign-token
74b0: 2c 20 20 20 20 20 20 20 20 20 5c 20 73 65 6c 66  ,         \ self
74c0: 20 73 69 67 6e 65 64 20 77 69 74 68 20 6e 65 77   signed with new
74d0: 20 6b 65 79 0a 20 20 20 20 22 21 22 20 72 65 76   key.    "!" rev
74e0: 74 6f 6b 65 6e 20 30 20 24 69 6e 73 20 20 20 20  token 0 $ins    
74f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7500: 5c 20 22 21 22 20 2b 20 6f 6c 64 6b 65 79 6c 65  \ "!" + oldkeyle
7510: 6e 2b 6e 65 77 6b 65 79 6c 65 6e 20 74 6f 20 66  n+newkeylen to f
7520: 6c 61 67 20 72 65 76 6f 6b 61 74 69 6f 6e 0a 20  lag revokation. 
7530: 20 20 20 72 65 76 74 6f 6b 65 6e 20 24 40 20 67     revtoken $@ g
7540: 65 6e 3e 68 6f 73 74 20 32 64 72 6f 70 20 20 20  en>host 2drop   
7550: 20 20 20 20 20 20 20 20 20 20 5c 20 73 69 67 6e            \ sign
7560: 20 68 6f 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f   host informatio
7570: 6e 20 77 69 74 68 20 6f 6c 64 20 6b 65 79 0a 20  n with old key. 
7580: 20 20 20 73 69 67 64 61 74 65 20 2b 64 61 74 65     sigdate +date
7590: 20 73 69 67 64 61 74 65 20 64 61 74 65 73 69 7a   sigdate datesiz
75a0: 65 23 20 72 65 76 74 6f 6b 65 6e 20 24 2b 21 0a  e# revtoken $+!.
75b0: 20 20 20 20 6f 6c 64 73 6b 63 20 6f 6c 64 70 6b      oldskc oldpk
75c0: 63 20 2b 72 65 76 73 69 67 6e 0a 20 20 20 20 30  c +revsign.    0
75d0: 6f 6c 64 6b 65 79 20 72 65 76 74 6f 6b 65 6e 20  oldkey revtoken 
75e0: 24 40 20 3b 0a 0a 5c 20 69 6e 76 69 74 61 74 69  $@ ;..\ invitati
75f0: 6f 6e 0a 0a 56 61 72 69 61 62 6c 65 20 69 6e 76  on..Variable inv
7600: 69 74 61 74 69 6f 6e 73 0a 0a 65 76 65 6e 74 3a  itations..event:
7610: 20 2d 3e 69 6e 76 69 74 65 20 28 20 61 64 64 72   ->invite ( addr
7620: 20 75 20 2d 2d 20 29 0a 20 20 20 20 2e 22 20 69   u -- ).    ." i
7630: 6e 76 69 74 65 20 6d 65 3a 20 22 20 6f 76 65 72  nvite me: " over
7640: 20 3e 72 20 2e 70 6b 32 6b 65 79 24 20 63 72 20   >r .pk2key$ cr 
7650: 72 3e 20 66 72 65 65 20 74 68 72 6f 77 20 63 74  r> free throw ct
7660: 72 6c 20 4c 20 69 6e 73 6b 65 79 20 3b 0a 65 76  rl L inskey ;.ev
7670: 65 6e 74 3a 20 2d 3e 77 61 6b 65 6d 65 20 28 20  ent: ->wakeme ( 
7680: 6f 20 2d 2d 20 29 20 3c 65 76 65 6e 74 20 2d 3e  o -- ) <event ->
7690: 77 61 6b 65 20 65 76 65 6e 74 3e 20 3b 0a 0a 3a  wake event> ;..:
76a0: 20 70 6b 32 6b 65 79 24 2d 61 64 64 20 28 20 61   pk2key$-add ( a
76b0: 64 64 72 20 75 20 70 65 72 6d 20 2d 2d 20 29 20  ddr u perm -- ) 
76c0: 7b 20 70 65 72 6d 20 7d 0a 20 20 20 20 73 61 6d  { perm }.    sam
76d0: 70 6c 65 2d 6b 65 79 20 3e 6f 20 69 6d 70 6f 72  ple-key >o impor
76e0: 74 23 69 6e 76 69 74 65 64 20 69 6d 70 6f 72 74  t#invited import
76f0: 2d 74 79 70 65 20 21 20 63 6d 64 3a 6e 65 73 74  -type ! cmd:nest
7700: 73 69 67 0a 20 20 20 20 70 65 72 6d 20 6b 65 2d  sig.    perm ke-
7710: 6d 61 73 6b 20 21 0a 20 20 20 20 69 6d 70 6f 72  mask !.    impor
7720: 74 23 6e 65 77 20 69 6d 70 6f 72 74 2d 74 79 70  t#new import-typ
7730: 65 20 21 20 20 73 61 76 65 2d 70 75 62 6b 65 79  e !  save-pubkey
7740: 73 20 6f 3e 20 3b 0a 0a 3a 20 78 2d 65 72 61 73  s o> ;..: x-eras
7750: 65 20 28 20 6c 65 6e 20 2d 2d 20 29 0a 20 20 20  e ( len -- ).   
7760: 20 64 75 70 20 78 62 61 63 6b 2d 72 65 73 74 6f   dup xback-resto
7770: 72 65 20 20 64 75 70 20 73 70 61 63 65 73 20 20  re  dup spaces  
7780: 78 62 61 63 6b 2d 72 65 73 74 6f 72 65 20 3b 0a  xback-restore ;.
7790: 0a 3a 20 69 6e 76 69 74 65 2d 6b 65 79 20 28 20  .: invite-key ( 
77a0: 61 64 64 72 20 75 20 2d 2d 20 6b 65 79 20 29 0a  addr u -- key ).
77b0: 20 20 20 20 32 64 75 70 20 78 2d 77 69 64 74 68      2dup x-width
77c0: 20 7b 20 61 64 64 72 20 75 20 6c 65 6e 20 7d 0a   { addr u len }.
77d0: 20 20 20 20 42 45 47 49 4e 20 20 61 64 64 72 20      BEGIN  addr 
77e0: 75 20 74 79 70 65 20 6b 65 79 20 20 6c 65 6e 20  u type key  len 
77f0: 78 2d 65 72 61 73 65 0a 09 64 75 70 20 63 74 72  x-erase..dup ctr
7800: 6c 20 5a 20 3d 0a 20 20 20 20 57 48 49 4c 45 20  l Z =.    WHILE 
7810: 20 64 72 6f 70 20 20 42 45 47 49 4e 20 20 6b 65   drop  BEGIN  ke
7820: 79 20 63 74 72 6c 20 4c 20 3d 20 20 55 4e 54 49  y ctrl L =  UNTI
7830: 4c 20 20 52 45 50 45 41 54 20 3b 0a 0a 3a 20 70  L  REPEAT ;..: p
7840: 72 6f 63 65 73 73 2d 69 6e 76 69 74 61 74 69 6f  rocess-invitatio
7850: 6e 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a  n ( addr u -- ).
7860: 20 20 20 20 73 22 20 69 6e 76 69 74 65 20 28 79      s" invite (y
7870: 2f 6e 2f 62 29 3f 22 20 69 6e 76 69 74 65 2d 6b  /n/b)?" invite-k
7880: 65 79 0a 20 20 20 20 63 61 73 65 0a 09 27 79 27  ey.    case..'y'
7890: 20 6f 66 20 20 70 65 72 6d 25 64 65 66 61 75 6c   of  perm%defaul
78a0: 74 20 70 6b 32 6b 65 79 24 2d 61 64 64 20 20 2e  t pk2key$-add  .
78b0: 22 20 61 64 64 65 64 22 20 63 72 20 20 20 65 6e  " added" cr   en
78c0: 64 6f 66 0a 09 27 62 27 20 6f 66 20 20 70 65 72  dof..'b' of  per
78d0: 6d 25 62 6c 6f 63 6b 65 64 20 70 6b 32 6b 65 79  m%blocked pk2key
78e0: 24 2d 61 64 64 20 20 2e 22 20 62 6c 6f 63 6b 65  $-add  ." blocke
78f0: 64 22 20 63 72 20 65 6e 64 6f 66 0a 09 32 64 72  d" cr endof..2dr
7900: 6f 70 20 2e 22 20 69 67 6e 6f 72 65 64 22 20 63  op ." ignored" c
7910: 72 0a 20 20 20 20 65 6e 64 63 61 73 65 20 3b 0a  r.    endcase ;.
7920: 0a 3a 20 66 69 6c 74 65 72 2d 69 6e 76 69 74 61  .: filter-invita
7930: 74 69 6f 6e 3f 20 28 20 61 64 64 72 20 75 20 2d  tion? ( addr u -
7940: 2d 20 66 6c 61 67 20 29 0a 20 20 20 20 73 69 67  - flag ).    sig
7950: 70 6b 32 73 69 7a 65 23 20 2d 20 2b 20 6b 65 79  pk2size# - + key
7960: 73 69 7a 65 20 6b 65 79 23 20 23 40 20 64 30 3c  size key# #@ d0<
7970: 3e 20 3b 20 5c 20 61 6c 72 65 61 64 79 20 74 68  > ; \ already th
7980: 65 72 65 0a 0a 3a 20 2e 69 6e 76 69 74 61 74 69  ere..: .invitati
7990: 6f 6e 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 69  ons ( -- ).    i
79a0: 6e 76 69 74 61 74 69 6f 6e 73 20 5b 3a 20 32 64  nvitations [: 2d
79b0: 75 70 20 2e 70 6b 32 6b 65 79 24 20 63 72 20 70  up .pk2key$ cr p
79c0: 72 6f 63 65 73 73 2d 69 6e 76 69 74 61 74 69 6f  rocess-invitatio
79d0: 6e 20 3b 5d 20 24 5b 5d 6d 61 70 0a 20 20 20 20  n ;] $[]map.    
79e0: 69 6e 76 69 74 61 74 69 6f 6e 73 20 24 5b 5d 6f  invitations $[]o
79f0: 66 66 20 3b 0a 0a 3a 20 3e 69 6e 76 69 74 61 74  ff ;..: >invitat
7a00: 69 6f 6e 73 20 28 20 61 64 64 72 20 75 20 2d 2d  ions ( addr u --
7a10: 20 29 0a 20 20 20 20 32 64 75 70 20 66 69 6c 74   ).    2dup filt
7a20: 65 72 2d 69 6e 76 69 74 61 74 69 6f 6e 3f 20 49  er-invitation? I
7a30: 46 20 20 32 64 72 6f 70 20 45 58 49 54 20 20 54  F  2drop EXIT  T
7a40: 48 45 4e 0a 20 20 20 20 69 6e 76 69 74 61 74 69  HEN.    invitati
7a50: 6f 6e 73 20 24 5b 5d 23 20 3e 72 0a 20 20 20 20  ons $[]# >r.    
7a60: 32 64 75 70 20 69 6e 76 69 74 61 74 69 6f 6e 73  2dup invitations
7a70: 20 24 69 6e 73 5b 5d 73 69 67 20 64 72 6f 70 0a   $ins[]sig drop.
7a80: 20 20 20 20 69 6e 76 69 74 61 74 69 6f 6e 73 20      invitations 
7a90: 24 5b 5d 23 20 72 3e 20 3c 3e 20 49 46 0a 09 73  $[]# r> <> IF..s
7aa0: 61 76 65 2d 6d 65 6d 20 6d 61 69 6e 2d 75 70 40  ave-mem main-up@
7ab0: 20 3c 68 69 64 65 3e 0a 09 3c 65 76 65 6e 74 20   <hide>..<event 
7ac0: 65 24 2c 20 2d 3e 69 6e 76 69 74 65 20 75 70 40  e$, ->invite up@
7ad0: 20 65 6c 69 74 2c 20 2d 3e 77 61 6b 65 6d 65 20   elit, ->wakeme 
7ae0: 6d 61 69 6e 2d 75 70 40 20 65 76 65 6e 74 3e 20  main-up@ event> 
7af0: 73 74 6f 70 0a 20 20 20 20 45 4c 53 45 20 20 32  stop.    ELSE  2
7b00: 64 72 6f 70 20 20 54 48 45 4e 20 3b 0a 0a 3a 20  drop  THEN ;..: 
7b10: 73 65 6e 64 2d 69 6e 76 69 74 61 74 69 6f 6e 20  send-invitation 
7b20: 28 20 70 6b 20 75 20 2d 2d 20 29 0a 20 20 20 20  ( pk u -- ).    
7b30: 73 65 74 75 70 21 20 6d 79 70 6b 32 6e 69 63 6b  setup! mypk2nick
7b40: 24 20 32 3e 72 0a 20 20 20 20 67 65 6e 2d 74 6d  $ 2>r.    gen-tm
7b50: 70 6b 65 79 73 20 64 72 6f 70 20 74 73 6b 63 20  pkeys drop tskc 
7b60: 73 77 61 70 20 6b 65 79 70 61 64 20 65 64 2d 64  swap keypad ed-d
7b70: 68 20 64 6f 2d 6b 65 79 70 61 64 20 73 65 63 21  h do-keypad sec!
7b80: 0a 20 20 20 20 6e 65 74 32 6f 2d 63 6f 64 65 30  .    net2o-code0
7b90: 0a 20 20 20 20 74 70 6b 63 20 6b 65 79 73 69 7a  .    tpkc keysiz
7ba0: 65 20 24 2c 20 6f 6e 65 73 68 6f 74 2d 74 6d 70  e $, oneshot-tmp
7bb0: 6b 65 79 0a 20 20 20 20 6e 65 73 74 5b 20 32 72  key.    nest[ 2r
7bc0: 3e 20 24 2c 20 69 6e 76 69 74 65 20 5d 74 6d 70  > $, invite ]tmp
7bd0: 6e 65 73 74 0a 20 20 20 20 63 6f 6f 6b 69 65 2b  nest.    cookie+
7be0: 72 65 71 75 65 73 74 0a 20 20 20 20 65 6e 64 2d  request.    end-
7bf0: 63 6f 64 65 7c 20 3b 0a 0a 5c 20 6b 65 79 20 61  code| ;..\ key a
7c00: 70 69 20 68 65 6c 70 65 72 73 0a 0a 3a 20 64 65  pi helpers..: de
7c10: 6c 2d 6c 61 73 74 2d 6b 65 79 20 28 20 2d 2d 20  l-last-key ( -- 
7c20: 29 0a 20 20 20 20 6b 65 79 73 20 24 5b 5d 23 20  ).    keys $[]# 
7c30: 31 2d 20 6b 65 79 73 20 24 5b 5d 20 73 65 63 2d  1- keys $[] sec-
7c40: 6f 66 66 0a 20 20 20 20 6b 65 79 73 20 24 40 6c  off.    keys $@l
7c50: 65 6e 20 63 65 6c 6c 2d 20 6b 65 79 73 20 24 21  en cell- keys $!
7c60: 6c 65 6e 20 3b 0a 0a 3a 20 73 74 6f 72 65 6b 65  len ;..: storeke
7c70: 79 21 20 28 20 2d 2d 20 29 0a 20 20 20 20 3e 73  y! ( -- ).    >s
7c80: 65 63 6b 65 79 20 6b 65 79 73 20 24 5b 5d 23 20  eckey keys $[]# 
7c90: 30 20 3f 44 4f 20 20 32 64 75 70 20 49 20 6b 65  0 ?DO  2dup I ke
7ca0: 79 73 20 73 65 63 5b 5d 40 20 73 74 72 3d 20 49  ys sec[]@ str= I
7cb0: 46 0a 09 20 20 20 20 49 20 6b 65 79 73 20 73 65  F..    I keys se
7cc0: 63 5b 5d 40 20 64 72 6f 70 20 3e 73 74 6f 72 65  c[]@ drop >store
7cd0: 6b 65 79 20 21 20 20 4c 45 41 56 45 20 20 54 48  key !  LEAVE  TH
7ce0: 45 4e 20 20 4c 4f 4f 50 20 20 32 64 72 6f 70 20  EN  LOOP  2drop 
7cf0: 3b 0a 0a 3a 20 63 68 6f 6f 73 65 2d 6b 65 79 20  ;..: choose-key 
7d00: 28 20 2d 2d 20 6f 20 29 0a 20 20 20 20 30 20 42  ( -- o ).    0 B
7d10: 45 47 49 4e 20 20 64 72 6f 70 0a 09 2e 22 20 43  EGIN  drop..." C
7d20: 68 6f 6f 73 65 20 6b 65 79 20 62 79 20 6e 75 6d  hoose key by num
7d30: 62 65 72 3a 22 20 63 72 20 2e 73 65 63 72 65 74  ber:" cr .secret
7d40: 2d 6e 69 63 6b 73 0a 09 42 45 47 49 4e 20 20 6b  -nicks..BEGIN  k
7d50: 65 79 20 64 75 70 20 62 6c 20 3c 20 57 48 49 4c  ey dup bl < WHIL
7d60: 45 20 20 64 72 6f 70 20 20 52 45 50 45 41 54 20  E  drop  REPEAT 
7d70: 5c 20 73 77 61 6c 6c 6f 77 20 63 6f 6e 74 72 6f  \ swallow contro
7d80: 6c 20 6b 65 79 73 0a 09 5b 27 5d 20 64 69 67 69  l keys..['] digi
7d90: 74 3f 20 23 33 36 20 62 61 73 65 2d 65 78 65 63  t? #36 base-exec
7da0: 75 74 65 20 30 3d 20 49 46 20 2d 31 20 54 48 45  ute 0= IF -1 THE
7db0: 4e 0a 09 73 65 63 72 65 74 2d 6b 65 79 20 64 75  N..secret-key du
7dc0: 70 20 30 3d 20 57 48 49 4c 45 0a 09 20 20 20 20  p 0= WHILE..    
7dd0: 2e 22 20 50 6c 65 61 73 65 20 65 6e 74 65 72 20  ." Please enter 
7de0: 61 20 62 61 73 65 2d 33 36 20 6e 75 6d 62 65 72  a base-36 number
7df0: 20 62 65 74 77 65 65 6e 20 30 20 61 6e 64 20 22   between 0 and "
7e00: 0a 09 20 20 20 20 73 65 63 72 65 74 2d 6b 65 79  ..    secret-key
7e10: 73 23 20 31 2d 20 5b 27 5d 20 2e 20 23 33 36 20  s# 1- ['] . #36 
7e20: 62 61 73 65 2d 65 78 65 63 75 74 65 20 63 72 20  base-execute cr 
7e30: 20 72 64 72 6f 70 0a 20 20 20 20 52 45 50 45 41   rdrop.    REPEA
7e40: 54 0a 20 20 20 20 64 75 70 20 2e 73 74 6f 72 65  T.    dup .store
7e50: 6b 65 79 21 20 20 3e 73 74 6f 72 65 6b 65 79 20  key!  >storekey 
7e60: 40 20 64 65 66 61 75 6c 74 6b 65 79 20 21 0a 20  @ defaultkey !. 
7e70: 20 20 20 2e 22 20 3d 3d 3d 3d 20 6b 65 79 20 22     ." ==== key "
7e80: 20 64 75 70 20 2e 2e 6e 69 63 6b 20 2e 22 20 20   dup ..nick ."  
7e90: 63 68 6f 73 65 6e 20 3d 3d 3d 3d 22 20 63 72 20  chosen ====" cr 
7ea0: 3b 0a 0a 5c 20 77 69 6c 6c 20 61 73 6b 20 66 6f  ;..\ will ask fo
7eb0: 72 20 79 6f 75 72 20 70 61 73 73 77 6f 72 64 20  r your password 
7ec0: 61 6e 64 20 69 66 20 70 6f 73 73 69 62 6c 65 20  and if possible 
7ed0: 61 75 74 6f 2d 73 65 6c 65 63 74 20 79 6f 75 72  auto-select your
7ee0: 20 69 64 0a 0a 56 61 72 69 61 62 6c 65 20 74 72   id..Variable tr
7ef0: 69 65 73 23 0a 23 31 30 20 56 61 6c 75 65 20 6d  ies#.#10 Value m
7f00: 61 78 74 72 69 65 73 23 0a 0a 3a 20 67 65 74 2d  axtries#..: get-
7f10: 73 6b 63 20 28 20 2d 2d 20 29 0a 20 20 20 20 73  skc ( -- ).    s
7f20: 65 63 72 65 74 2d 6b 65 79 73 23 20 3f 45 58 49  ecret-keys# ?EXI
7f30: 54 20 20 74 72 69 65 73 23 20 6f 66 66 0a 20 20  T  tries# off.  
7f40: 20 20 64 65 62 75 67 2d 76 65 63 74 6f 72 20 40    debug-vector @
7f50: 20 6f 70 2d 76 65 63 74 6f 72 20 21 40 20 3e 72   op-vector !@ >r
7f60: 20 3c 64 65 66 61 75 6c 74 3e 0a 20 20 20 20 73   <default>.    s
7f70: 65 63 72 65 74 2d 6b 65 79 73 23 0a 20 20 20 20  ecret-keys#.    
7f80: 42 45 47 49 4e 20 20 64 75 70 20 30 3d 20 74 72  BEGIN  dup 0= tr
7f90: 69 65 73 23 20 40 20 6d 61 78 74 72 69 65 73 23  ies# @ maxtries#
7fa0: 20 75 3c 20 61 6e 64 20 20 57 48 49 4c 45 20 64   u< and  WHILE d
7fb0: 72 6f 70 0a 09 20 20 20 20 73 22 20 50 61 73 73  rop..    s" Pass
7fc0: 70 68 72 61 73 65 3a 20 22 20 2b 70 61 73 73 70  phrase: " +passp
7fd0: 68 72 61 73 65 20 20 20 21 74 69 6d 65 0a 09 20  hrase   !time.. 
7fe0: 20 20 20 72 65 61 64 2d 6b 65 79 73 20 73 65 63     read-keys sec
7ff0: 72 65 74 2d 6b 65 79 73 23 20 64 75 70 20 30 3d  ret-keys# dup 0=
8000: 20 49 46 0a 09 09 5c 20 66 61 69 6c 20 72 69 67   IF...\ fail rig
8010: 68 74 20 61 66 74 65 72 20 74 68 65 20 66 69 72  ht after the fir
8020: 73 74 20 74 72 79 20 69 66 20 50 41 53 53 50 48  st try if PASSPH
8030: 52 41 53 45 20 69 73 20 75 73 65 64 0a 09 09 5c  RASE is used...\
8040: 20 61 6e 64 20 67 69 76 65 20 74 68 65 20 6d 61   and give the ma
8050: 78 69 6d 75 6d 20 77 61 69 74 69 6e 67 20 70 65  ximum waiting pe
8060: 6e 61 6c 74 79 20 69 6e 20 74 68 61 74 20 63 61  nalty in that ca
8070: 73 65 0a 09 09 31 20 6d 61 78 74 72 69 65 73 23  se...1 maxtries#
8080: 20 73 22 20 50 41 53 53 50 48 52 41 53 45 22 20   s" PASSPHRASE" 
8090: 67 65 74 65 6e 76 20 64 30 3d 20 73 65 6c 65 63  getenv d0= selec
80a0: 74 20 74 72 69 65 73 23 20 2b 21 0a 09 09 3c 65  t tries# +!...<e
80b0: 72 72 3e 20 2e 22 20 54 72 79 23 20 22 20 74 72  rr> ." Try# " tr
80c0: 69 65 73 23 20 40 20 30 20 2e 72 20 27 2f 27 20  ies# @ 0 .r '/' 
80d0: 65 6d 69 74 20 6d 61 78 74 72 69 65 73 23 20 2e  emit maxtries# .
80e0: 0a 09 09 2e 22 20 66 61 69 6c 65 64 2c 20 6e 6f  ...." failed, no
80f0: 20 6b 65 79 20 66 6f 75 6e 64 2c 20 77 61 69 74   key found, wait
8100: 69 6e 67 20 22 0a 09 09 23 31 20 74 72 69 65 73  ing "...#1 tries
8110: 23 20 40 20 32 2a 20 6c 73 68 69 66 74 20 64 75  # @ 2* lshift du
8120: 70 20 2e 20 2e 22 20 6d 73 2e 2e 2e 22 20 6d 73  p . ." ms..." ms
8130: 20 20 3c 64 65 66 61 75 6c 74 3e 20 63 72 0a 09    <default> cr..
8140: 09 64 65 6c 2d 6c 61 73 74 2d 6b 65 79 0a 09 20  .del-last-key.. 
8150: 20 20 20 54 48 45 4e 0a 20 20 20 20 52 45 50 45     THEN.    REPE
8160: 41 54 0a 20 20 20 20 64 75 70 20 30 3d 20 49 46  AT.    dup 0= IF
8170: 20 20 23 2d 35 36 20 74 68 72 6f 77 20 20 54 48    #-56 throw  TH
8180: 45 4e 0a 20 20 20 20 31 20 3d 20 49 46 20 20 30  EN.    1 = IF  0
8190: 20 73 65 63 72 65 74 2d 6b 65 79 0a 09 2e 22 20   secret-key..." 
81a0: 3d 3d 3d 3d 20 6f 70 65 6e 65 64 3a 20 22 20 64  ==== opened: " d
81b0: 75 70 20 2e 2e 6e 69 63 6b 20 2e 22 20 20 69 6e  up ..nick ."  in
81c0: 20 22 20 2e 74 69 6d 65 20 2e 22 20 3d 3d 3d 3d   " .time ." ====
81d0: 22 20 63 72 0a 20 20 20 20 45 4c 53 45 20 20 2e  " cr.    ELSE  .
81e0: 22 20 3d 3d 3d 3d 20 6f 70 65 6e 65 64 20 69 6e  " ==== opened in
81f0: 20 22 20 2e 74 69 6d 65 20 2e 22 20 3d 3d 3d 3d   " .time ." ====
8200: 22 20 63 72 20 63 68 6f 6f 73 65 2d 6b 65 79 20  " cr choose-key 
8210: 20 54 48 45 4e 0a 20 20 20 20 3e 72 61 77 2d 6b   THEN.    >raw-k
8220: 65 79 20 3f 72 73 6b 20 20 20 72 3e 20 6f 70 2d  ey ?rsk   r> op-
8230: 76 65 63 74 6f 72 20 21 20 3b 0a 0a 73 63 6f 70  vector ! ;..scop
8240: 65 3a 20 6e 32 6f 0a 46 6f 72 77 61 72 64 20 68  e: n2o.Forward h
8250: 65 6c 70 0a 7d 73 63 6f 70 65 0a 0a 3a 20 67 65  elp.}scope..: ge
8260: 74 2d 6d 79 2d 6b 65 79 20 28 20 2d 2d 20 78 74  t-my-key ( -- xt
8270: 20 29 0a 20 20 20 20 67 65 6e 2d 6b 65 79 73 2d   ).    gen-keys-
8280: 64 69 72 20 20 22 73 65 63 6b 65 79 73 2e 6b 32  dir  "seckeys.k2
8290: 6f 22 20 2e 6b 65 79 73 2f 20 32 64 75 70 20 66  o" .keys/ 2dup f
82a0: 69 6c 65 2d 73 74 61 74 75 73 20 6e 69 70 0a 20  ile-status nip. 
82b0: 20 20 20 30 3d 20 49 46 20 20 72 2f 6f 20 6f 70     0= IF  r/o op
82c0: 65 6e 2d 66 69 6c 65 20 74 68 72 6f 77 20 3e 72  en-file throw >r
82d0: 20 72 40 20 66 69 6c 65 2d 73 69 7a 65 20 74 68   r@ file-size th
82e0: 72 6f 77 20 64 30 3d 0a 09 72 3e 20 63 6c 6f 73  row d0=..r> clos
82f0: 65 2d 66 69 6c 65 20 74 68 72 6f 77 20 20 45 4c  e-file throw  EL
8300: 53 45 20 20 74 72 75 65 20 20 54 48 45 4e 0a 20  SE  true  THEN. 
8310: 20 20 20 49 46 20 20 5b 3a 20 2e 22 20 47 65 6e     IF  [: ." Gen
8320: 65 72 61 74 65 20 61 20 6e 65 77 20 6b 65 79 70  erate a new keyp
8330: 61 69 72 3a 22 20 63 72 0a 09 20 20 67 65 74 2d  air:" cr..  get-
8340: 6e 69 63 6b 20 64 75 70 20 30 3d 20 23 2d 35 36  nick dup 0= #-56
8350: 20 61 6e 64 20 74 68 72 6f 77 20 5c 20 65 6d 70   and throw \ emp
8360: 74 79 20 6e 69 63 6b 3a 20 70 72 65 74 65 6e 64  ty nick: pretend
8370: 20 74 6f 20 71 75 69 74 0a 09 20 20 6e 65 77 2d   to quit..  new-
8380: 6b 65 79 20 2e 6b 65 79 73 20 3f 72 73 6b 20 3b  key .keys ?rsk ;
8390: 5d 0a 20 20 20 20 45 4c 53 45 20 20 5b 27 5d 20  ].    ELSE  ['] 
83a0: 67 65 74 2d 73 6b 63 20 20 54 48 45 4e 20 3b 0a  get-skc  THEN ;.
83b0: 0a 3a 20 2e 6b 65 79 69 6e 66 6f 20 28 20 2d 2d  .: .keyinfo ( --
83c0: 20 29 0a 20 20 20 20 3c 77 61 72 6e 3e 20 2e 22   ).    <warn> ."
83d0: 20 3d 3d 3d 3d 20 4e 6f 20 6b 65 79 20 6f 70 65   ==== No key ope
83e0: 6e 65 64 20 3d 3d 3d 3d 22 20 63 72 0a 20 20 20  ned ====" cr.   
83f0: 20 3c 69 6e 66 6f 3e 20 2e 22 20 67 65 6e 65 72   <info> ." gener
8400: 61 74 65 20 61 20 6e 65 77 20 6f 6e 65 20 77 69  ate a new one wi
8410: 74 68 20 27 6b 65 79 67 65 6e 27 22 20 63 72 20  th 'keygen'" cr 
8420: 3c 64 65 66 61 75 6c 74 3e 20 3b 0a 0a 3a 20 67  <default> ;..: g
8430: 65 74 2d 6d 65 20 28 20 2d 2d 20 29 0a 20 20 20  et-me ( -- ).   
8440: 20 67 65 74 2d 6d 79 2d 6b 65 79 20 63 61 74 63   get-my-key catc
8450: 68 20 64 75 70 20 23 2d 35 36 20 3d 20 49 46 20  h dup #-56 = IF 
8460: 64 72 6f 70 20 2e 6b 65 79 69 6e 66 6f 20 45 4c  drop .keyinfo EL
8470: 53 45 20 74 68 72 6f 77 20 54 48 45 4e 20 3b 0a  SE throw THEN ;.
8480: 0a 3a 20 3f 67 65 74 2d 6d 65 20 28 20 2d 2d 20  .: ?get-me ( -- 
8490: 29 0a 20 20 20 20 5c 47 20 74 68 69 73 20 76 65  ).    \G this ve
84a0: 72 73 69 6f 6e 20 6f 66 20 67 65 74 2d 6d 65 20  rsion of get-me 
84b0: 66 61 69 6c 73 20 68 61 72 64 20 69 66 20 6e 6f  fails hard if no
84c0: 20 6b 65 79 20 69 73 20 6f 70 65 6e 65 64 0a 20   key is opened. 
84d0: 20 20 20 67 65 74 2d 6d 79 2d 6b 65 79 20 63 61     get-my-key ca
84e0: 74 63 68 20 23 2d 35 36 20 3d 20 49 46 0a 09 2e  tch #-56 = IF...
84f0: 6b 65 79 69 6e 66 6f 20 74 72 75 65 20 21 21 6e  keyinfo true !!n
8500: 6f 2d 6b 65 79 2d 6f 70 65 6e 21 21 0a 20 20 20  o-key-open!!.   
8510: 20 54 48 45 4e 20 3b 0a 0a 30 20 5b 49 46 5d 0a   THEN ;..0 [IF].
8520: 4c 6f 63 61 6c 20 56 61 72 69 61 62 6c 65 73 3a  Local Variables:
8530: 0a 66 6f 72 74 68 2d 6c 6f 63 61 6c 2d 77 6f 72  .forth-local-wor
8540: 64 73 3a 0a 20 20 20 20 28 0a 20 20 20 20 20 28  ds:.    (.     (
8550: 28 22 6e 65 74 32 6f 3a 22 20 22 2b 6e 65 74 32  ("net2o:" "+net2
8560: 6f 3a 22 29 20 64 65 66 69 6e 69 74 69 6f 6e 2d  o:") definition-
8570: 73 74 61 72 74 65 72 20 28 66 6f 6e 74 2d 6c 6f  starter (font-lo
8580: 63 6b 2d 6b 65 79 77 6f 72 64 2d 66 61 63 65 20  ck-keyword-face 
8590: 2e 20 31 29 0a 20 20 20 20 20 20 22 5b 20 5c 74  . 1).      "[ \t
85a0: 5c 6e 5d 22 20 74 20 6e 61 6d 65 20 28 66 6f 6e  \n]" t name (fon
85b0: 74 2d 6c 6f 63 6b 2d 66 75 6e 63 74 69 6f 6e 2d  t-lock-function-
85c0: 6e 61 6d 65 2d 66 61 63 65 20 2e 20 33 29 29 0a  name-face . 3)).
85d0: 20 20 20 20 20 28 28 22 64 65 62 75 67 3a 22 20       (("debug:" 
85e0: 22 66 69 65 6c 64 3a 22 20 22 32 66 69 65 6c 64  "field:" "2field
85f0: 3a 22 20 22 73 66 66 69 65 6c 64 3a 22 20 22 64  :" "sffield:" "d
8600: 66 66 69 65 6c 64 3a 22 20 22 36 34 66 69 65 6c  ffield:" "64fiel
8610: 64 3a 22 20 22 75 76 61 72 22 20 22 75 76 61 6c  d:" "uvar" "uval
8620: 75 65 22 29 20 6e 6f 6e 2d 69 6d 6d 65 64 69 61  ue") non-immedia
8630: 74 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 74 79  te (font-lock-ty
8640: 70 65 2d 66 61 63 65 20 2e 20 32 29 0a 20 20 20  pe-face . 2).   
8650: 20 20 20 22 5b 20 5c 74 5c 6e 5d 22 20 74 20 6e     "[ \t\n]" t n
8660: 61 6d 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 76  ame (font-lock-v
8670: 61 72 69 61 62 6c 65 2d 6e 61 6d 65 2d 66 61 63  ariable-name-fac
8680: 65 20 2e 20 33 29 29 0a 20 20 20 20 20 28 22 5b  e . 3)).     ("[
8690: 61 2d 7a 30 2d 39 5d 2b 28 22 20 69 6d 6d 65 64  a-z0-9]+(" immed
86a0: 69 61 74 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d  iate (font-lock-
86b0: 63 6f 6d 6d 65 6e 74 2d 66 61 63 65 20 2e 20 31  comment-face . 1
86c0: 29 0a 20 20 20 20 20 20 22 29 22 20 6e 69 6c 20  ).      ")" nil 
86d0: 63 6f 6d 6d 65 6e 74 20 28 66 6f 6e 74 2d 6c 6f  comment (font-lo
86e0: 63 6b 2d 63 6f 6d 6d 65 6e 74 2d 66 61 63 65 20  ck-comment-face 
86f0: 2e 20 31 29 29 0a 20 20 20 20 29 0a 66 6f 72 74  . 1)).    ).fort
8700: 68 2d 6c 6f 63 61 6c 2d 69 6e 64 65 6e 74 2d 77  h-local-indent-w
8710: 6f 72 64 73 3a 0a 20 20 20 20 28 0a 20 20 20 20  ords:.    (.    
8720: 20 28 28 22 6e 65 74 32 6f 3a 22 20 22 2b 6e 65   (("net2o:" "+ne
8730: 74 32 6f 3a 22 29 20 28 30 20 2e 20 32 29 20 28  t2o:") (0 . 2) (
8740: 30 20 2e 20 32 29 20 6e 6f 6e 2d 69 6d 6d 65 64  0 . 2) non-immed
8750: 69 61 74 65 29 0a 20 20 20 20 20 28 28 22 5b 3a  iate).     (("[:
8760: 22 20 22 6b 65 79 3a 63 6f 64 65 22 29 20 28 30  " "key:code") (0
8770: 20 2e 20 31 29 20 28 30 20 2e 20 31 29 20 69 6d   . 1) (0 . 1) im
8780: 6d 65 64 69 61 74 65 29 0a 20 20 20 20 20 28 28  mediate).     ((
8790: 22 3b 5d 22 20 22 65 6e 64 3a 6b 65 79 22 29 20  ";]" "end:key") 
87a0: 28 2d 31 20 2e 20 30 29 20 28 30 20 2e 20 2d 31  (-1 . 0) (0 . -1
87b0: 29 20 69 6d 6d 65 64 69 61 74 65 29 0a 20 20 20  ) immediate).   
87c0: 20 29 0a 45 6e 64 3a 0a 5b 54 48 45 4e 5d         ).End:.[THEN]