Hex Artifact Content
Not logged in

Artifact a9d808d91c456bcab7949a5de64257728789f7be:


0000: 5c 20 6e 65 74 32 6f 20 6b 65 79 20 73 74 6f 72  \ net2o key stor
0010: 61 67 65 0a 0a 5c 20 43 6f 70 79 72 69 67 68 74  age..\ Copyright
0020: 20 28 43 29 20 32 30 31 30 2d 32 30 31 35 20 20   (C) 2010-2015  
0030: 20 42 65 72 6e 64 20 50 61 79 73 61 6e 0a 0a 5c   Bernd Paysan..\
0040: 20 54 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73   This program is
0050: 20 66 72 65 65 20 73 6f 66 74 77 61 72 65 3a 20   free software: 
0060: 79 6f 75 20 63 61 6e 20 72 65 64 69 73 74 72 69  you can redistri
0070: 62 75 74 65 20 69 74 20 61 6e 64 2f 6f 72 20 6d  bute it and/or m
0080: 6f 64 69 66 79 0a 5c 20 69 74 20 75 6e 64 65 72  odify.\ it under
0090: 20 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68   the terms of th
00a0: 65 20 47 4e 55 20 41 66 66 65 72 6f 20 47 65 6e  e GNU Affero Gen
00b0: 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69 63 65  eral Public Lice
00c0: 6e 73 65 20 61 73 20 70 75 62 6c 69 73 68 65 64  nse as published
00d0: 20 62 79 0a 5c 20 74 68 65 20 46 72 65 65 20 53   by.\ the Free S
00e0: 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 61 74 69  oftware Foundati
00f0: 6f 6e 2c 20 65 69 74 68 65 72 20 76 65 72 73 69  on, either versi
0100: 6f 6e 20 33 20 6f 66 20 74 68 65 20 4c 69 63 65  on 3 of the Lice
0110: 6e 73 65 2c 20 6f 72 0a 5c 20 28 61 74 20 79 6f  nse, or.\ (at yo
0120: 75 72 20 6f 70 74 69 6f 6e 29 20 61 6e 79 20 6c  ur option) any l
0130: 61 74 65 72 20 76 65 72 73 69 6f 6e 2e 0a 0a 5c  ater version...\
0140: 20 54 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73   This program is
0150: 20 64 69 73 74 72 69 62 75 74 65 64 20 69 6e 20   distributed in 
0160: 74 68 65 20 68 6f 70 65 20 74 68 61 74 20 69 74  the hope that it
0170: 20 77 69 6c 6c 20 62 65 20 75 73 65 66 75 6c 2c   will be useful,
0180: 0a 5c 20 62 75 74 20 57 49 54 48 4f 55 54 20 41  .\ but WITHOUT A
0190: 4e 59 20 57 41 52 52 41 4e 54 59 3b 20 77 69 74  NY WARRANTY; wit
01a0: 68 6f 75 74 20 65 76 65 6e 20 74 68 65 20 69 6d  hout even the im
01b0: 70 6c 69 65 64 20 77 61 72 72 61 6e 74 79 20 6f  plied warranty o
01c0: 66 0a 5c 20 4d 45 52 43 48 41 4e 54 41 42 49 4c  f.\ MERCHANTABIL
01d0: 49 54 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46  ITY or FITNESS F
01e0: 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52 20  OR A PARTICULAR 
01f0: 50 55 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68  PURPOSE.  See th
0200: 65 0a 5c 20 47 4e 55 20 41 66 66 65 72 6f 20 47  e.\ GNU Affero G
0210: 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69  eneral Public Li
0220: 63 65 6e 73 65 20 66 6f 72 20 6d 6f 72 65 20 64  cense for more d
0230: 65 74 61 69 6c 73 2e 0a 0a 5c 20 59 6f 75 20 73  etails...\ You s
0240: 68 6f 75 6c 64 20 68 61 76 65 20 72 65 63 65 69  hould have recei
0250: 76 65 64 20 61 20 63 6f 70 79 20 6f 66 20 74 68  ved a copy of th
0260: 65 20 47 4e 55 20 41 66 66 65 72 6f 20 47 65 6e  e GNU Affero Gen
0270: 65 72 61 6c 20 50 75 62 6c 69 63 20 4c 69 63 65  eral Public Lice
0280: 6e 73 65 0a 5c 20 61 6c 6f 6e 67 20 77 69 74 68  nse.\ along with
0290: 20 74 68 69 73 20 70 72 6f 67 72 61 6d 2e 20 20   this program.  
02a0: 49 66 20 6e 6f 74 2c 20 73 65 65 20 3c 68 74 74  If not, see <htt
02b0: 70 3a 2f 2f 77 77 77 2e 67 6e 75 2e 6f 72 67 2f  p://www.gnu.org/
02c0: 6c 69 63 65 6e 73 65 73 2f 3e 2e 0a 0a 72 65 71  licenses/>...req
02d0: 75 69 72 65 20 6d 6b 64 69 72 2e 66 73 0a 0a 5c  uire mkdir.fs..\
02e0: 20 61 63 63 65 70 74 20 66 6f 72 20 70 61 73 73   accept for pass
02f0: 77 6f 72 64 20 65 6e 74 72 79 0a 0a 3a 20 61 63  word entry..: ac
0300: 63 65 70 74 2a 20 28 20 61 64 64 72 20 75 20 2d  cept* ( addr u -
0310: 2d 20 75 27 20 29 0a 20 20 20 20 5c 67 20 61 63  - u' ).    \g ac
0320: 63 65 70 74 2d 6c 69 6b 65 20 69 6e 70 75 74 2c  cept-like input,
0330: 20 62 75 74 20 74 79 70 65 73 20 2a 20 69 6e 73   but types * ins
0340: 74 65 61 64 20 6f 66 20 74 68 65 20 63 68 61 72  tead of the char
0350: 61 63 74 65 72 0a 20 20 20 20 5c 67 20 64 6f 6e  acter.    \g don
0360: 27 74 20 73 61 76 65 20 69 6e 74 6f 20 68 69 73  't save into his
0370: 74 6f 72 79 0a 20 20 20 20 64 75 70 20 3e 72 0a  tory.    dup >r.
0380: 20 20 20 20 42 45 47 49 4e 20 20 78 6b 65 79 20      BEGIN  xkey 
0390: 64 75 70 20 23 63 72 20 3c 3e 20 6f 76 65 72 20  dup #cr <> over 
03a0: 23 6c 66 20 3c 3e 20 61 6e 64 20 57 48 49 4c 45  #lf <> and WHILE
03b0: 0a 09 20 20 20 20 64 75 70 20 23 62 73 20 3d 20  ..    dup #bs = 
03c0: 6f 76 65 72 20 23 64 65 6c 20 3d 20 6f 72 20 49  over #del = or I
03d0: 46 0a 09 09 64 72 6f 70 20 64 75 70 20 72 40 20  F...drop dup r@ 
03e0: 75 3c 20 49 46 0a 09 09 20 20 20 20 6f 76 65 72  u< IF...    over
03f0: 20 2b 20 3e 72 20 78 63 68 61 72 2d 20 72 3e 20   + >r xchar- r> 
0400: 6f 76 65 72 20 2d 0a 09 09 20 20 20 20 31 20 62  over -...    1 b
0410: 61 63 6b 73 70 61 63 65 73 20 73 70 61 63 65 20  ackspaces space 
0420: 31 20 62 61 63 6b 73 70 61 63 65 73 0a 09 09 45  1 backspaces...E
0430: 4c 53 45 0a 09 09 20 20 20 20 62 65 6c 6c 0a 09  LSE...    bell..
0440: 09 54 48 45 4e 0a 09 20 20 20 20 45 4c 53 45 0a  .THEN..    ELSE.
0450: 09 09 2d 72 6f 74 20 78 63 21 2b 3f 20 30 3d 20  ..-rot xc!+? 0= 
0460: 49 46 20 20 62 65 6c 6c 20 20 45 4c 53 45 0a 09  IF  bell  ELSE..
0470: 09 20 20 20 20 5b 49 46 44 45 46 5d 20 61 6e 64  .    [IFDEF] and
0480: 72 6f 69 64 20 27 2a 27 20 5b 45 4c 53 45 5d 20  roid '*' [ELSE] 
0490: 27 e2 ac a4 27 20 5b 54 48 45 4e 5d 20 78 65 6d  '⬤' [THEN] xem
04a0: 69 74 20 20 54 48 45 4e 0a 09 20 20 20 20 54 48  it  THEN..    TH
04b0: 45 4e 0a 20 20 20 20 52 45 50 45 41 54 20 20 64  EN.    REPEAT  d
04c0: 72 6f 70 20 20 6e 69 70 20 72 3e 20 73 77 61 70  rop  nip r> swap
04d0: 20 2d 20 3b 0a 0a 5c 20 4b 65 79 73 20 61 72 65   - ;..\ Keys are
04e0: 20 70 61 73 73 77 6f 72 64 73 20 61 6e 64 20 70   passwords and p
04f0: 72 69 76 61 74 65 20 6b 65 79 73 20 28 73 65 6c  rivate keys (sel
0500: 66 2d 6b 65 79 65 64 2c 20 69 2e 65 2e 20 70 72  f-keyed, i.e. pr
0510: 69 76 61 74 65 2a 70 75 62 6c 69 63 20 6b 65 79  ivate*public key
0520: 29 0a 0a 0a 32 20 56 61 6c 75 65 20 70 77 2d 6c  )...2 Value pw-l
0530: 65 76 65 6c 23 20 5c 20 70 77 2d 6c 65 76 65 6c  evel# \ pw-level
0540: 23 20 30 20 69 73 20 6c 6f 77 65 73 74 0a 5c 20  # 0 is lowest.\ 
0550: 21 21 54 4f 44 4f 21 21 20 77 65 20 6e 65 65 64  !!TODO!! we need
0560: 20 61 20 77 61 79 20 74 6f 20 74 65 6c 6c 20 68   a way to tell h
0570: 6f 77 20 6d 75 63 68 20 77 65 20 63 61 6e 20 74  ow much we can t
0580: 72 75 73 74 20 6b 65 79 73 0a 5c 20 70 61 73 73  rust keys.\ pass
0590: 77 6f 72 64 73 20 6e 65 65 64 20 61 20 70 77 2d  words need a pw-
05a0: 6c 65 76 65 6c 20 28 62 65 63 61 75 73 65 20 74  level (because t
05b0: 68 65 79 20 61 72 65 20 67 75 65 73 73 61 62 6c  hey are guessabl
05c0: 65 29 0a 5c 20 73 65 63 72 65 74 73 20 64 6f 6e  e).\ secrets don
05d0: 27 74 2c 20 74 68 65 79 20 61 72 65 6e 27 74 2e  't, they aren't.
05e0: 20 57 65 20 63 61 6e 20 71 75 69 63 6b 6c 79 20   We can quickly 
05f0: 64 65 63 72 79 70 74 20 61 6c 6c 0a 5c 20 73 65  decrypt all.\ se
0600: 63 72 65 74 2d 62 61 73 65 64 20 73 74 75 66 66  cret-based stuff
0610: 2c 20 77 69 74 68 6f 75 74 20 62 6f 74 68 65 72  , without bother
0620: 69 6e 67 20 77 69 74 68 20 73 6c 6f 77 64 6f 77  ing with slowdow
0630: 6e 73 2e 0a 5c 20 53 6f 20 73 65 63 72 65 74 73  ns..\ So secrets
0640: 20 73 68 6f 75 6c 64 20 75 73 65 20 6e 6f 72 6d   should use norm
0650: 61 6c 20 73 74 72 69 6e 67 20 64 65 63 72 79 70  al string decryp
0660: 74 0a 0a 63 6d 64 2d 62 75 66 30 20 63 6c 61 73  t..cmd-buf0 clas
0670: 73 0a 20 20 20 20 6d 61 78 64 61 74 61 20 2d 0a  s.    maxdata -.
0680: 20 20 20 20 6b 65 79 2d 73 61 6c 74 23 20 75 76      key-salt# uv
0690: 61 72 20 6b 65 79 70 61 63 6b 0a 20 20 20 20 6b  ar keypack.    k
06a0: 65 79 70 61 63 6b 23 20 20 75 76 61 72 20 6b 65  eypack#  uvar ke
06b0: 79 70 61 63 6b 2d 62 75 66 0a 20 20 20 20 6b 65  ypack-buf.    ke
06c0: 79 2d 63 6b 73 75 6d 23 20 75 76 61 72 20 6b 65  y-cksum# uvar ke
06d0: 79 70 61 63 6b 2d 63 68 6b 73 75 6d 0a 65 6e 64  ypack-chksum.end
06e0: 2d 63 6c 61 73 73 20 63 6d 64 2d 6b 65 79 62 75  -class cmd-keybu
06f0: 66 2d 63 0a 0a 63 6d 64 2d 6b 65 79 62 75 66 2d  f-c..cmd-keybuf-
0700: 63 20 6e 65 77 20 63 6d 64 62 75 66 3a 20 63 6f  c new cmdbuf: co
0710: 64 65 2d 6b 65 79 0a 0a 63 6f 64 65 2d 6b 65 79  de-key..code-key
0720: 0a 63 6d 64 30 6c 6f 63 6b 20 30 20 70 74 68 72  .cmd0lock 0 pthr
0730: 65 61 64 5f 6d 75 74 65 78 5f 69 6e 69 74 20 64  ead_mutex_init d
0740: 72 6f 70 0a 0a 3a 6e 6f 6e 61 6d 65 20 28 20 2d  rop..:noname ( -
0750: 2d 20 61 64 64 72 20 75 20 29 20 6b 65 79 70 61  - addr u ) keypa
0760: 63 6b 2d 62 75 66 20 63 6d 64 62 75 66 23 20 40  ck-buf cmdbuf# @
0770: 20 3b 20 74 6f 20 63 6d 64 62 75 66 24 0a 3a 6e   ; to cmdbuf$.:n
0780: 6f 6e 61 6d 65 20 28 20 2d 2d 20 6e 20 29 20 20  oname ( -- n )  
0790: 6b 65 79 70 61 63 6b 23 20 63 6d 64 62 75 66 23  keypack# cmdbuf#
07a0: 20 40 20 2d 20 3b 20 74 6f 20 6d 61 78 73 74 72   @ - ; to maxstr
07b0: 69 6e 67 0a 0a 63 6f 64 65 30 2d 62 75 66 0a 0a  ing..code0-buf..
07c0: 5c 20 68 61 73 68 65 64 20 6b 65 79 20 64 61 74  \ hashed key dat
07d0: 61 20 62 61 73 65 0a 0a 55 73 65 72 20 3e 73 74  a base..User >st
07e0: 6f 72 65 6b 65 79 0a 0a 63 6d 64 2d 63 6c 61 73  orekey..cmd-clas
07f0: 73 20 63 6c 61 73 73 0a 20 20 20 20 66 69 65 6c  s class.    fiel
0800: 64 3a 20 6b 65 2d 73 6b 20 20 20 5c 20 73 65 63  d: ke-sk   \ sec
0810: 72 65 74 20 6b 65 79 0a 20 20 20 20 66 69 65 6c  ret key.    fiel
0820: 64 3a 20 6b 65 2d 70 6b 20 20 20 5c 20 70 75 62  d: ke-pk   \ pub
0830: 6c 69 63 20 6b 65 79 0a 20 20 20 20 66 69 65 6c  lic key.    fiel
0840: 64 3a 20 6b 65 2d 74 79 70 65 20 5c 20 6b 65 79  d: ke-type \ key
0850: 20 74 79 70 65 0a 20 20 20 20 66 69 65 6c 64 3a   type.    field:
0860: 20 6b 65 2d 6e 69 63 6b 20 5c 20 6b 65 79 20 6e   ke-nick \ key n
0870: 69 63 6b 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b  ick.    field: k
0880: 65 2d 70 73 6b 20 20 5c 20 70 72 65 73 68 61 72  e-psk  \ preshar
0890: 65 64 20 6b 65 79 20 66 6f 72 20 73 74 61 74 65  ed key for state
08a0: 6c 65 73 73 20 63 6f 6d 6d 75 6e 69 63 61 74 69  less communicati
08b0: 6f 6e 0a 20 20 20 20 66 69 65 6c 64 3a 20 6b 65  on.    field: ke
08c0: 2d 70 72 6f 66 20 5c 20 70 72 6f 66 69 6c 65 20  -prof \ profile 
08d0: 6f 62 6a 65 63 74 0a 20 20 20 20 66 69 65 6c 64  object.    field
08e0: 3a 20 6b 65 2d 73 65 6c 66 73 69 67 0a 20 20 20  : ke-selfsig.   
08f0: 20 66 69 65 6c 64 3a 20 6b 65 2d 73 69 67 73 0a   field: ke-sigs.
0900: 20 20 20 20 66 69 65 6c 64 3a 20 6b 65 2d 73 74      field: ke-st
0910: 6f 72 65 6b 65 79 20 5c 20 75 73 65 64 20 74 6f  orekey \ used to
0920: 20 65 6e 63 72 79 70 74 20 6f 6e 20 73 74 6f 72   encrypt on stor
0930: 61 67 65 0a 20 20 20 20 36 34 66 69 65 6c 64 3a  age.    64field:
0940: 20 6b 65 2d 6f 66 66 73 65 74 20 5c 20 6f 66 66   ke-offset \ off
0950: 73 65 74 20 69 6e 20 6b 65 79 20 66 69 6c 65 0a  set in key file.
0960: 20 20 20 20 30 20 2b 66 69 65 6c 64 20 6b 65 2d      0 +field ke-
0970: 65 6e 64 0a 65 6e 64 2d 63 6c 61 73 73 20 6b 65  end.end-class ke
0980: 79 2d 65 6e 74 72 79 0a 0a 56 61 72 69 61 62 6c  y-entry..Variabl
0990: 65 20 6b 65 79 2d 65 6e 74 72 79 2d 74 61 62 6c  e key-entry-tabl
09a0: 65 0a 0a 30 20 43 6f 6e 73 74 61 6e 74 20 6b 65  e..0 Constant ke
09b0: 79 23 61 6e 6f 6e 0a 31 20 43 6f 6e 73 74 61 6e  y#anon.1 Constan
09c0: 74 20 6b 65 79 23 75 73 65 72 0a 32 20 43 6f 6e  t key#user.2 Con
09d0: 73 74 61 6e 74 20 6b 65 79 23 67 72 6f 75 70 0a  stant key#group.
09e0: 0a 30 20 56 61 6c 75 65 20 73 61 6d 70 6c 65 2d  .0 Value sample-
09f0: 6b 65 79 0a 0a 56 61 72 69 61 62 6c 65 20 6b 65  key..Variable ke
0a00: 79 2d 74 61 62 6c 65 0a 0a 36 34 56 61 72 69 61  y-table..64Varia
0a10: 62 6c 65 20 6b 65 79 2d 72 65 61 64 2d 6f 66 66  ble key-read-off
0a20: 73 65 74 0a 0a 3a 20 63 75 72 72 65 6e 74 2d 6b  set..: current-k
0a30: 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6f  ey ( addr u -- o
0a40: 20 29 0a 20 20 20 20 32 64 75 70 20 6b 65 79 73   ).    2dup keys
0a50: 69 7a 65 20 75 6d 69 6e 20 6b 65 79 2d 74 61 62  ize umin key-tab
0a60: 6c 65 20 23 40 20 64 72 6f 70 0a 20 20 20 20 64  le #@ drop.    d
0a70: 75 70 20 30 3d 20 49 46 20 20 64 72 6f 70 20 2e  up 0= IF  drop .
0a80: 22 20 75 6e 6b 6e 6f 77 6e 20 6b 65 79 3a 20 22  " unknown key: "
0a90: 20 38 35 74 79 70 65 20 63 72 20 20 30 20 45 58   85type cr  0 EX
0aa0: 49 54 20 20 54 48 45 4e 0a 20 20 20 20 63 65 6c  IT  THEN.    cel
0ab0: 6c 2b 20 3e 6f 20 6b 65 2d 70 6b 20 24 21 20 6f  l+ >o ke-pk $! o
0ac0: 20 6f 3e 20 3b 0a 0a 3a 20 6b 65 79 3a 6e 65 77   o> ;..: key:new
0ad0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 6f 20 29   ( addr u -- o )
0ae0: 0a 20 20 20 20 5c 47 20 63 72 65 61 74 65 20 6e  .    \G create n
0af0: 65 77 20 6b 65 79 2c 20 61 64 64 72 20 75 20 69  ew key, addr u i
0b00: 73 20 74 68 65 20 70 75 62 6c 69 63 20 6b 65 79  s the public key
0b10: 0a 20 20 20 20 73 61 6d 70 6c 65 2d 6b 65 79 20  .    sample-key 
0b20: 3e 6f 0a 20 20 20 20 6b 65 79 2d 65 6e 74 72 79  >o.    key-entry
0b30: 2d 74 61 62 6c 65 20 40 20 74 6f 6b 65 6e 2d 74  -table @ token-t
0b40: 61 62 6c 65 20 21 0a 20 20 20 20 6b 65 2d 73 6b  able !.    ke-sk
0b50: 20 6b 65 2d 65 6e 64 20 6f 76 65 72 20 2d 20 65   ke-end over - e
0b60: 72 61 73 65 20 20 3e 73 74 6f 72 65 6b 65 79 20  rase  >storekey 
0b70: 40 20 6b 65 2d 73 74 6f 72 65 6b 65 79 20 21 0a  @ ke-storekey !.
0b80: 20 20 20 20 6b 65 79 2d 72 65 61 64 2d 6f 66 66      key-read-off
0b90: 73 65 74 20 36 34 40 20 6b 65 2d 6f 66 66 73 65  set 64@ ke-offse
0ba0: 74 20 36 34 21 0a 20 20 20 20 6b 65 79 70 61 63  t 64!.    keypac
0bb0: 6b 2d 61 6c 6c 23 20 6e 3e 36 34 20 6b 65 79 2d  k-all# n>64 key-
0bc0: 72 65 61 64 2d 6f 66 66 73 65 74 20 36 34 2b 21  read-offset 64+!
0bd0: 20 6f 20 63 65 6c 6c 2d 20 6b 65 2d 65 6e 64 20   o cell- ke-end 
0be0: 6f 76 65 72 20 2d 0a 20 20 20 20 32 6f 76 65 72  over -.    2over
0bf0: 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e 20 6b 65   keysize umin ke
0c00: 79 2d 74 61 62 6c 65 20 23 21 20 6f 3e 0a 20 20  y-table #! o>.  
0c10: 20 20 63 75 72 72 65 6e 74 2d 6b 65 79 20 3b 0a    current-key ;.
0c20: 0a 3a 20 6b 65 79 3f 6e 65 77 20 28 20 61 64 64  .: key?new ( add
0c30: 72 20 75 20 2d 2d 20 6f 20 29 0a 20 20 20 20 5c  r u -- o ).    \
0c40: 47 20 43 72 65 61 74 65 20 6f 72 20 6c 6f 6f 6b  G Create or look
0c50: 75 70 20 6e 65 77 20 6b 65 79 0a 20 20 20 20 32  up new key.    2
0c60: 64 75 70 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e  dup keysize umin
0c70: 20 6b 65 79 2d 74 61 62 6c 65 20 23 40 20 64 72   key-table #@ dr
0c80: 6f 70 0a 20 20 20 20 64 75 70 20 30 3d 20 49 46  op.    dup 0= IF
0c90: 20 20 64 72 6f 70 20 6b 65 79 3a 6e 65 77 20 20    drop key:new  
0ca0: 45 4c 53 45 20 20 6e 69 70 20 6e 69 70 20 63 65  ELSE  nip nip ce
0cb0: 6c 6c 2b 20 20 54 48 45 4e 20 3b 0a 0a 5c 20 73  ll+  THEN ;..\ s
0cc0: 65 61 72 63 68 20 66 6f 72 20 6b 65 79 73 20 2d  earch for keys -
0cd0: 20 6e 6f 74 20 6f 70 74 69 6d 69 7a 65 64 0a 0a   not optimized..
0ce0: 3a 20 6e 69 63 6b 2d 6b 65 79 20 28 20 61 64 64  : nick-key ( add
0cf0: 72 20 75 20 2d 2d 20 6f 20 29 20 5c 20 73 65 61  r u -- o ) \ sea
0d00: 72 63 68 20 66 6f 72 20 6b 65 79 20 6e 69 63 6b  rch for key nick
0d10: 6e 61 6d 65 0a 20 20 20 20 30 20 2d 72 6f 74 20  name.    0 -rot 
0d20: 6b 65 79 2d 74 61 62 6c 65 20 0a 20 20 20 20 5b  key-table .    [
0d30: 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20  : cell+ $@ drop 
0d40: 63 65 6c 6c 2b 20 3e 6f 20 6b 65 2d 6e 69 63 6b  cell+ >o ke-nick
0d50: 20 24 40 20 32 6f 76 65 72 20 73 74 72 3d 20 49   $@ 2over str= I
0d60: 46 0a 09 72 6f 74 20 64 72 6f 70 20 6f 20 2d 72  F..rot drop o -r
0d70: 6f 74 0a 20 20 20 20 54 48 45 4e 20 20 6f 3e 20  ot.    THEN  o> 
0d80: 3b 5d 20 23 6d 61 70 20 32 64 72 6f 70 20 3b 0a  ;] #map 2drop ;.
0d90: 0a 3a 20 73 65 63 72 65 74 2d 6b 65 79 73 23 20  .: secret-keys# 
0da0: 28 20 2d 2d 20 6e 20 29 0a 20 20 20 20 30 20 6b  ( -- n ).    0 k
0db0: 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63 65 6c 6c  ey-table [: cell
0dc0: 2b 20 24 40 20 64 72 6f 70 20 63 65 6c 6c 2b 20  + $@ drop cell+ 
0dd0: 3e 6f 20 6b 65 2d 73 6b 20 40 20 30 3c 3e 20 2d  >o ke-sk @ 0<> -
0de0: 20 6f 3e 20 3b 5d 20 23 6d 61 70 20 3b 0a 3a 20   o> ;] #map ;.: 
0df0: 73 65 63 72 65 74 2d 6b 65 79 20 28 20 6e 20 2d  secret-key ( n -
0e00: 2d 20 6f 2f 30 20 29 0a 20 20 20 20 30 20 74 75  - o/0 ).    0 tu
0e10: 63 6b 20 6b 65 79 2d 74 61 62 6c 65 20 5b 3a 20  ck key-table [: 
0e20: 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20 63 65  cell+ $@ drop ce
0e30: 6c 6c 2b 20 3e 6f 20 6b 65 2d 73 6b 20 40 20 49  ll+ >o ke-sk @ I
0e40: 46 0a 09 20 20 32 64 75 70 20 3d 20 49 46 20 20  F..  2dup = IF  
0e50: 72 6f 74 20 64 72 6f 70 20 6f 20 2d 72 6f 74 20  rot drop o -rot 
0e60: 20 54 48 45 4e 20 20 31 2b 0a 20 20 20 20 20 20   THEN  1+.      
0e70: 54 48 45 4e 20 20 6f 3e 20 3b 5d 20 23 6d 61 70  THEN  o> ;] #map
0e80: 20 32 64 72 6f 70 20 3b 0a 3a 20 2e 73 65 63 72   2drop ;.: .secr
0e90: 65 74 2d 6e 69 63 6b 73 20 28 20 2d 2d 20 29 0a  et-nicks ( -- ).
0ea0: 20 20 20 20 30 20 6b 65 79 2d 74 61 62 6c 65 20      0 key-table 
0eb0: 5b 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70  [: cell+ $@ drop
0ec0: 20 63 65 6c 6c 2b 20 3e 6f 20 6b 65 2d 73 6b 20   cell+ >o ke-sk 
0ed0: 40 20 49 46 0a 09 20 20 64 75 70 20 2e 20 6b 65  @ IF..  dup . ke
0ee0: 2d 6e 69 63 6b 20 24 40 20 74 79 70 65 20 63 72  -nick $@ type cr
0ef0: 20 31 2b 0a 20 20 20 20 20 20 54 48 45 4e 20 6f   1+.      THEN o
0f00: 3e 20 3b 5d 20 23 6d 61 70 20 64 72 6f 70 20 3b  > ;] #map drop ;
0f10: 0a 0a 3a 20 6e 69 63 6b 3e 70 6b 20 28 20 6e 69  ..: nick>pk ( ni
0f20: 63 6b 20 75 20 2d 2d 20 70 6b 20 75 20 29 0a 20  ck u -- pk u ). 
0f30: 20 20 20 6e 69 63 6b 2d 6b 65 79 20 3f 64 75 70     nick-key ?dup
0f40: 2d 49 46 20 2e 6b 65 2d 70 6b 20 24 40 20 45 4c  -IF .ke-pk $@ EL
0f50: 53 45 20 30 20 30 20 54 48 45 4e 20 3b 0a 0a 3a  SE 0 0 THEN ;..:
0f60: 20 6b 65 79 2d 65 78 69 73 74 3f 20 28 20 61 64   key-exist? ( ad
0f70: 64 72 20 75 20 2d 2d 20 66 6c 61 67 20 29 0a 20  dr u -- flag ). 
0f80: 20 20 20 6b 65 79 2d 74 61 62 6c 65 20 23 40 20     key-table #@ 
0f90: 64 30 3c 3e 20 3b 20 0a 0a 56 61 72 69 61 62 6c  d0<> ; ..Variabl
0fa0: 65 20 73 74 72 69 63 74 2d 6b 65 79 73 20 20 73  e strict-keys  s
0fb0: 74 72 69 63 74 2d 6b 65 79 73 20 6f 6e 0a 0a 5b  trict-keys on..[
0fc0: 49 46 55 4e 44 45 46 5d 20 6d 61 67 65 6e 74 61  IFUNDEF] magenta
0fd0: 20 20 62 72 6f 77 6e 20 63 6f 6e 73 74 61 6e 74    brown constant
0fe0: 20 6d 61 67 65 6e 74 61 20 5b 54 48 45 4e 5d 0a   magenta [THEN].
0ff0: 0a 43 72 65 61 74 65 20 38 35 63 6f 6c 6f 72 73  .Create 85colors
1000: 0a 72 65 64 20 20 20 20 20 3e 62 67 20 77 68 69  .red     >bg whi
1010: 74 65 20 3e 66 67 20 6f 72 20 62 6f 6c 64 20 6f  te >fg or bold o
1020: 72 20 2c 0a 79 65 6c 6c 6f 77 20 20 3e 62 67 20  r ,.yellow  >bg 
1030: 77 68 69 74 65 20 3e 66 67 20 6f 72 20 62 6f 6c  white >fg or bol
1040: 64 20 6f 72 20 2c 0a 62 6c 75 65 20 20 20 20 3e  d or ,.blue    >
1050: 62 67 20 77 68 69 74 65 20 3e 66 67 20 6f 72 20  bg white >fg or 
1060: 62 6f 6c 64 20 6f 72 20 2c 0a 6d 61 67 65 6e 74  bold or ,.magent
1070: 61 20 3e 62 67 20 77 68 69 74 65 20 3e 66 67 20  a >bg white >fg 
1080: 6f 72 20 62 6f 6c 64 20 6f 72 20 2c 0a 0a 3a 20  or bold or ,..: 
1090: 72 65 73 65 74 2d 63 6f 6c 6f 72 20 28 20 2d 2d  reset-color ( --
10a0: 20 29 0a 20 20 20 20 64 65 66 61 75 6c 74 2d 63   ).    default-c
10b0: 6f 6c 6f 72 20 61 74 74 72 21 20 3b 0a 3a 20 2e  olor attr! ;.: .
10c0: 62 6c 61 63 6b 38 35 20 28 20 61 64 64 72 20 75  black85 ( addr u
10d0: 20 2d 2d 20 29 0a 20 20 20 20 5b 20 62 6c 61 63   -- ).    [ blac
10e0: 6b 20 3e 62 67 20 62 6c 61 63 6b 20 3e 66 67 20  k >bg black >fg 
10f0: 6f 72 20 5d 4c 20 61 74 74 72 21 20 20 20 38 35  or ]L attr!   85
1100: 74 79 70 65 20 72 65 73 65 74 2d 63 6f 6c 6f 72  type reset-color
1110: 20 3b 0a 3a 20 2e 72 65 64 38 35 20 28 20 61 64   ;.: .red85 ( ad
1120: 64 72 20 75 20 2d 2d 20 29 20 20 30 20 2d 72 6f  dr u -- )  0 -ro
1130: 74 20 62 6f 75 6e 64 73 20 3f 44 4f 0a 09 63 72  t bounds ?DO..cr
1140: 20 2e 22 20 5c 20 72 65 76 6f 6b 65 3a 20 22 20   ." \ revoke: " 
1150: 64 75 70 20 63 65 6c 6c 73 20 38 35 63 6f 6c 6f  dup cells 85colo
1160: 72 73 20 2b 20 40 20 61 74 74 72 21 20 31 2b 20  rs + @ attr! 1+ 
1170: 33 20 61 6e 64 0a 09 49 20 34 20 38 35 74 79 70  3 and..I 4 85typ
1180: 65 20 20 64 75 70 20 63 65 6c 6c 73 20 38 35 63  e  dup cells 85c
1190: 6f 6c 6f 72 73 20 2b 20 40 20 61 74 74 72 21 20  olors + @ attr! 
11a0: 31 2b 20 33 20 61 6e 64 0a 09 49 20 34 20 2b 20  1+ 3 and..I 4 + 
11b0: 34 20 38 35 74 79 70 65 20 72 65 73 65 74 2d 63  4 85type reset-c
11c0: 6f 6c 6f 72 20 38 20 2b 4c 4f 4f 50 20 20 64 72  olor 8 +LOOP  dr
11d0: 6f 70 20 3b 0a 3a 20 2e 72 73 6b 20 28 20 6e 69  op ;.: .rsk ( ni
11e0: 63 6b 20 75 20 2d 2d 20 29 0a 20 20 20 20 73 6b  ck u -- ).    sk
11f0: 72 65 76 20 24 32 30 20 2e 72 65 64 38 35 20 73  rev $20 .red85 s
1200: 70 61 63 65 20 74 79 70 65 20 2e 22 20 20 28 6b  pace type ."  (k
1210: 65 65 70 20 6f 66 66 6c 69 6e 65 20 63 6f 70 79  eep offline copy
1220: 21 29 22 20 63 72 20 3b 0a 3a 20 2e 6b 65 79 20  !)" cr ;.: .key 
1230: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 64 72  ( addr u -- ) dr
1240: 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a 20 20 20 20  op cell+ >o.    
1250: 2e 22 20 6e 69 63 6b 3a 20 22 20 6b 65 2d 6e 69  ." nick: " ke-ni
1260: 63 6b 20 24 40 20 74 79 70 65 20 63 72 0a 20 20  ck $@ type cr.  
1270: 20 20 2e 22 20 70 75 62 6b 65 79 3a 20 22 20 6b    ." pubkey: " k
1280: 65 2d 70 6b 20 24 40 20 38 35 74 79 70 65 20 63  e-pk $@ 85type c
1290: 72 0a 20 20 20 20 6b 65 2d 73 6b 20 40 20 49 46  r.    ke-sk @ IF
12a0: 20 20 2e 22 20 73 65 63 6b 65 79 3a 20 22 20 6b    ." seckey: " k
12b0: 65 2d 73 6b 20 40 20 6b 65 79 73 69 7a 65 0a 09  e-sk @ keysize..
12c0: 2e 62 6c 61 63 6b 38 35 20 2e 22 20 20 28 6b 65  .black85 ."  (ke
12d0: 65 70 20 73 65 63 72 65 74 21 29 22 20 63 72 20  ep secret!)" cr 
12e0: 20 54 48 45 4e 0a 20 20 20 20 2e 22 20 66 69 72   THEN.    ." fir
12f0: 73 74 3a 20 22 20 6b 65 2d 73 65 6c 66 73 69 67  st: " ke-selfsig
1300: 20 24 40 20 64 72 6f 70 20 36 34 40 20 2e 73 69   $@ drop 64@ .si
1310: 67 64 61 74 65 20 63 72 0a 20 20 20 20 2e 22 20  gdate cr.    ." 
1320: 6c 61 73 74 3a 20 22 20 6b 65 2d 73 65 6c 66 73  last: " ke-selfs
1330: 69 67 20 24 40 20 64 72 6f 70 20 36 34 27 2b 20  ig $@ drop 64'+ 
1340: 36 34 40 20 2e 73 69 67 64 61 74 65 20 63 72 0a  64@ .sigdate cr.
1350: 20 20 20 20 6f 3e 20 3b 0a 0a 3a 20 64 75 6d 70      o> ;..: dump
1360: 6b 65 79 20 28 20 61 64 64 72 20 75 20 2d 2d 20  key ( addr u -- 
1370: 29 20 64 72 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a  ) drop cell+ >o.
1380: 20 20 20 20 2e 5c 22 20 78 5c 22 20 22 20 6b 65      .\" x\" " ke
1390: 2d 70 6b 20 24 40 20 38 35 74 79 70 65 20 2e 5c  -pk $@ 85type .\
13a0: 22 20 5c 22 20 6b 65 79 3f 6e 65 77 22 20 63 72  " \" key?new" cr
13b0: 0a 20 20 20 20 6b 65 2d 73 6b 20 40 20 49 46 20  .    ke-sk @ IF 
13c0: 20 2e 5c 22 20 78 5c 22 20 22 20 6b 65 2d 73 6b   .\" x\" " ke-sk
13d0: 20 40 20 6b 65 79 73 69 7a 65 20 38 35 74 79 70   @ keysize 85typ
13e0: 65 20 2e 5c 22 20 5c 22 20 6b 65 2d 73 6b 20 73  e .\" \" ke-sk s
13f0: 65 63 21 20 2b 73 65 63 6b 65 79 22 20 63 72 20  ec! +seckey" cr 
1400: 20 54 48 45 4e 0a 20 20 20 20 27 22 27 20 65 6d   THEN.    '"' em
1410: 69 74 20 6b 65 2d 6e 69 63 6b 20 24 40 20 74 79  it ke-nick $@ ty
1420: 70 65 20 2e 5c 22 20 5c 22 20 6b 65 2d 6e 69 63  pe .\" \" ke-nic
1430: 6b 20 24 21 20 22 0a 20 20 20 20 6b 65 2d 73 65  k $! ".    ke-se
1440: 6c 66 73 69 67 20 24 40 20 64 72 6f 70 20 36 34  lfsig $@ drop 64
1450: 40 20 36 34 3e 64 20 5b 3a 20 27 24 27 20 65 6d  @ 64>d [: '$' em
1460: 69 74 20 30 20 75 64 2e 72 20 3b 5d 20 24 31 30  it 0 ud.r ;] $10
1470: 20 62 61 73 65 2d 65 78 65 63 75 74 65 0a 20 20   base-execute.  
1480: 20 20 2e 22 20 2e 20 64 3e 36 34 20 6b 65 2d 66    ." . d>64 ke-f
1490: 69 72 73 74 21 20 22 20 6b 65 2d 74 79 70 65 20  irst! " ke-type 
14a0: 40 20 2e 20 2e 22 20 6b 65 2d 74 79 70 65 20 21  @ . ." ke-type !
14b0: 22 20 20 63 72 20 6f 3e 20 3b 0a 0a 3a 20 2e 6b  "  cr o> ;..: .k
14c0: 65 79 73 20 28 20 2d 2d 20 29 20 6b 65 79 2d 74  eys ( -- ) key-t
14d0: 61 62 6c 65 20 5b 3a 20 63 65 6c 6c 2b 20 24 40  able [: cell+ $@
14e0: 20 2e 6b 65 79 20 3b 5d 20 23 6d 61 70 20 3b 0a   .key ;] #map ;.
14f0: 3a 20 64 75 6d 70 6b 65 79 73 20 28 20 2d 2d 20  : dumpkeys ( -- 
1500: 29 20 6b 65 79 2d 74 61 62 6c 65 20 5b 3a 20 63  ) key-table [: c
1510: 65 6c 6c 2b 20 24 40 20 64 75 6d 70 6b 65 79 20  ell+ $@ dumpkey 
1520: 3b 5d 20 23 6d 61 70 20 3b 0a 0a 3a 20 2e 6b 65  ;] #map ;..: .ke
1530: 79 23 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29  y# ( addr u -- )
1540: 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e 0a 20 20   keysize umin.  
1550: 20 20 2e 22 20 4b 65 79 20 27 22 20 6b 65 79 2d    ." Key '" key-
1560: 74 61 62 6c 65 20 23 40 20 30 3d 20 49 46 20 64  table #@ 0= IF d
1570: 72 6f 70 20 45 58 49 54 20 54 48 45 4e 0a 20 20  rop EXIT THEN.  
1580: 20 20 63 65 6c 6c 2b 20 2e 6b 65 2d 6e 69 63 6b    cell+ .ke-nick
1590: 20 24 40 20 74 79 70 65 20 2e 22 20 27 20 6f 6b   $@ type ." ' ok
15a0: 22 20 63 72 20 3b 0a 3a 20 2e 6b 65 79 2d 69 64  " cr ;.: .key-id
15b0: 20 28 20 61 64 64 72 20 75 20 2d 2d 20 29 20 6b   ( addr u -- ) k
15c0: 65 79 73 69 7a 65 20 75 6d 69 6e 20 32 64 75 70  eysize umin 2dup
15d0: 20 6b 65 79 2d 74 61 62 6c 65 20 23 40 20 30 3d   key-table #@ 0=
15e0: 0a 20 20 20 20 49 46 20 20 32 64 72 6f 70 20 38  .    IF  2drop 8
15f0: 20 38 35 74 79 70 65 0a 20 20 20 20 45 4c 53 45   85type.    ELSE
1600: 20 20 63 65 6c 6c 2b 20 2e 6b 65 2d 6e 69 63 6b    cell+ .ke-nick
1610: 20 24 40 20 74 79 70 65 20 32 64 72 6f 70 20 20   $@ type 2drop  
1620: 54 48 45 4e 20 3b 0a 0a 3a 6e 6f 6e 61 6d 65 20  THEN ;..:noname 
1630: 28 20 61 64 64 72 20 75 20 2d 2d 20 29 0a 20 20  ( addr u -- ).  
1640: 20 20 6f 20 49 46 20 20 64 65 73 74 2d 70 75 62    o IF  dest-pub
1650: 6b 65 79 20 40 20 49 46 0a 09 20 20 20 20 32 64  key @ IF..    2d
1660: 75 70 20 64 65 73 74 2d 70 75 62 6b 65 79 20 24  up dest-pubkey $
1670: 40 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e 20 73  @ keysize umin s
1680: 74 72 3d 20 30 3d 20 49 46 0a 09 09 5b 3a 20 2e  tr= 0= IF...[: .
1690: 22 20 77 61 6e 74 3a 20 22 20 64 65 73 74 2d 70  " want: " dest-p
16a0: 75 62 6b 65 79 20 24 40 20 6b 65 79 73 69 7a 65  ubkey $@ keysize
16b0: 20 75 6d 69 6e 20 38 35 74 79 70 65 20 63 72 0a   umin 85type cr.
16c0: 09 09 20 20 2e 22 20 67 6f 74 20 3a 20 22 20 32  ..  ." got : " 2
16d0: 64 75 70 20 38 35 74 79 70 65 20 63 72 20 3b 5d  dup 85type cr ;]
16e0: 20 24 65 72 72 0a 09 09 74 72 75 65 20 21 21 77   $err...true !!w
16f0: 72 6f 6e 67 2d 6b 65 79 21 21 0a 09 20 20 20 20  rong-key!!..    
1700: 54 48 45 4e 0a 09 20 20 20 20 2e 6b 65 79 23 20  THEN..    .key# 
1710: 20 45 58 49 54 0a 09 54 48 45 4e 20 20 54 48 45   EXIT..THEN  THE
1720: 4e 0a 20 20 20 20 32 64 75 70 20 6b 65 79 2d 65  N.    2dup key-e
1730: 78 69 73 74 3f 20 30 3d 20 49 46 0a 09 73 74 72  xist? 0= IF..str
1740: 69 63 74 2d 6b 65 79 73 20 40 20 21 21 75 6e 6b  ict-keys @ !!unk
1750: 6e 6f 77 6e 2d 6b 65 79 21 21 0a 09 2e 22 20 55  nown-key!!..." U
1760: 6e 6b 6e 6f 77 6e 20 6b 65 79 20 22 20 38 35 74  nknown key " 85t
1770: 79 70 65 20 63 72 0a 20 20 20 20 45 4c 53 45 0a  ype cr.    ELSE.
1780: 09 2e 6b 65 79 23 0a 20 20 20 20 54 48 45 4e 20  ..key#.    THEN 
1790: 3b 20 49 53 20 63 68 65 63 6b 2d 6b 65 79 0a 0a  ; IS check-key..
17a0: 3a 6e 6f 6e 61 6d 65 20 28 20 70 6b 63 20 2d 2d  :noname ( pkc --
17b0: 20 73 6b 63 20 29 0a 20 20 20 20 6b 65 79 73 69   skc ).    keysi
17c0: 7a 65 20 6b 65 79 2d 74 61 62 6c 65 20 23 40 20  ze key-table #@ 
17d0: 30 3d 20 21 21 75 6e 6b 6e 6f 77 6e 2d 6b 65 79  0= !!unknown-key
17e0: 21 21 0a 20 20 20 20 63 65 6c 6c 2b 20 2e 6b 65  !!.    cell+ .ke
17f0: 2d 73 6b 20 73 65 63 40 20 30 3d 20 21 21 75 6e  -sk sec@ 0= !!un
1800: 6b 6e 6f 77 6e 2d 6b 65 79 21 21 20 3b 20 69 73  known-key!! ; is
1810: 20 73 65 61 72 63 68 2d 6b 65 79 0a 0a 5c 20 67   search-key..\ g
1820: 65 74 20 70 61 73 73 70 68 72 61 73 65 0a 0a 33  et passphrase..3
1830: 20 56 61 6c 75 65 20 70 61 73 73 70 68 72 61 73   Value passphras
1840: 65 2d 72 65 74 72 79 23 0a 24 31 30 30 20 43 6f  e-retry#.$100 Co
1850: 6e 73 74 61 6e 74 20 6d 61 78 2d 70 61 73 73 70  nstant max-passp
1860: 68 72 61 73 65 23 20 5c 20 32 35 36 20 63 68 61  hrase# \ 256 cha
1870: 72 61 63 74 65 72 73 20 73 68 6f 75 6c 64 20 62  racters should b
1880: 65 20 65 6e 6f 75 67 68 2e 2e 2e 0a 6d 61 78 2d  e enough....max-
1890: 70 61 73 73 70 68 72 61 73 65 23 20 62 75 66 66  passphrase# buff
18a0: 65 72 3a 20 70 61 73 73 70 68 72 61 73 65 0a 0a  er: passphrase..
18b0: 3a 20 70 61 73 73 70 68 72 61 73 65 2d 69 6e 20  : passphrase-in 
18c0: 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20  ( -- addr u ).  
18d0: 20 20 70 61 73 73 70 68 72 61 73 65 20 64 75 70    passphrase dup
18e0: 20 6d 61 78 2d 70 61 73 73 70 68 72 61 73 65 23   max-passphrase#
18f0: 20 61 63 63 65 70 74 2a 20 3b 0a 0a 3a 20 3e 70   accept* ;..: >p
1900: 61 73 73 70 68 72 61 73 65 20 28 20 61 64 64 72  assphrase ( addr
1910: 20 75 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20   u -- addr u ). 
1920: 20 20 20 5c 47 20 63 72 65 61 74 65 20 61 20 35     \G create a 5
1930: 31 32 20 62 69 74 20 68 61 73 68 20 6f 66 20 74  12 bit hash of t
1940: 68 65 20 70 61 73 73 70 68 72 61 73 65 0a 20 20  he passphrase.  
1950: 20 20 6e 6f 2d 6b 65 79 20 3e 63 3a 6b 65 79 20    no-key >c:key 
1960: 63 3a 68 61 73 68 0a 20 20 20 20 6b 65 63 63 61  c:hash.    kecca
1970: 6b 2d 70 61 64 64 65 64 20 63 3a 6b 65 79 3e 20  k-padded c:key> 
1980: 6b 65 63 63 61 6b 2d 70 61 64 64 65 64 20 6b 65  keccak-padded ke
1990: 63 63 61 6b 23 6d 61 78 20 32 2f 20 3b 0a 0a 3a  ccak#max 2/ ;..:
19a0: 20 67 65 74 2d 70 61 73 73 70 68 72 61 73 65 20   get-passphrase 
19b0: 28 20 2d 2d 20 61 64 64 72 20 75 20 29 0a 20 20  ( -- addr u ).  
19c0: 20 20 70 61 73 73 70 68 72 61 73 65 2d 69 6e 20    passphrase-in 
19d0: 3e 70 61 73 73 70 68 72 61 73 65 20 3b 0a 0a 56  >passphrase ;..V
19e0: 61 72 69 61 62 6c 65 20 6b 65 79 73 0a 0a 3a 20  ariable keys..: 
19f0: 6b 65 79 3e 64 65 66 61 75 6c 74 20 28 20 2d 2d  key>default ( --
1a00: 20 29 20 6b 65 79 73 20 24 5b 5d 23 20 31 2d 20   ) keys $[]# 1- 
1a10: 6b 65 79 73 20 73 65 63 5b 5d 40 20 32 64 75 70  keys sec[]@ 2dup
1a20: 20 38 35 74 79 70 65 20 46 20 63 72 20 64 72 6f   85type F cr dro
1a30: 70 20 3e 73 74 6f 72 65 6b 65 79 20 21 20 3b 0a  p >storekey ! ;.
1a40: 3a 20 2b 6b 65 79 20 28 20 61 64 64 72 20 75 20  : +key ( addr u 
1a50: 2d 2d 20 29 20 6b 65 79 73 20 73 65 63 2b 5b 5d  -- ) keys sec+[]
1a60: 21 20 3b 0a 3a 20 2b 70 61 73 73 70 68 72 61 73  ! ;.: +passphras
1a70: 65 20 28 20 2d 2d 20 29 20 20 67 65 74 2d 70 61  e ( -- )  get-pa
1a80: 73 73 70 68 72 61 73 65 20 2b 6b 65 79 20 3b 0a  ssphrase +key ;.
1a90: 3a 20 2b 63 68 65 63 6b 70 68 72 61 73 65 20 28  : +checkphrase (
1aa0: 20 2d 2d 20 66 6c 61 67 20 29 20 67 65 74 2d 70   -- flag ) get-p
1ab0: 61 73 73 70 68 72 61 73 65 20 6b 65 79 73 20 24  assphrase keys $
1ac0: 5b 5d 23 20 31 2d 20 6b 65 79 73 20 73 65 63 5b  []# 1- keys sec[
1ad0: 5d 40 20 73 74 72 3d 20 3b 0a 3a 20 2b 6e 65 77  ]@ str= ;.: +new
1ae0: 70 68 72 61 73 65 20 28 20 2d 2d 20 29 0a 20 20  phrase ( -- ).  
1af0: 20 20 42 45 47 49 4e 0a 09 2e 22 20 50 61 73 73    BEGIN..." Pass
1b00: 70 68 72 61 73 65 3a 20 22 20 2b 70 61 73 73 70  phrase: " +passp
1b10: 68 72 61 73 65 20 63 72 0a 09 2e 22 20 52 65 74  hrase cr..." Ret
1b20: 79 70 65 20 70 6c 73 3a 20 22 20 2b 63 68 65 63  ype pls: " +chec
1b30: 6b 70 68 72 61 73 65 20 30 3d 20 57 48 49 4c 45  kphrase 0= WHILE
1b40: 0a 09 20 20 20 20 2e 22 20 20 64 69 64 6e 27 74  ..    ."  didn't
1b50: 20 6d 61 74 63 68 2c 20 74 72 79 20 61 67 61 69   match, try agai
1b60: 6e 20 70 6c 65 61 73 65 22 20 63 72 0a 20 20 20  n please" cr.   
1b70: 20 52 45 50 45 41 54 20 63 72 20 3b 0a 0a 3a 20   REPEAT cr ;..: 
1b80: 22 3e 70 61 73 73 70 68 72 61 73 65 20 28 20 61  ">passphrase ( a
1b90: 64 64 72 20 75 20 2d 2d 20 29 20 3e 70 61 73 73  ddr u -- ) >pass
1ba0: 70 68 72 61 73 65 20 2b 6b 65 79 20 3b 0a 3a 20  phrase +key ;.: 
1bb0: 2b 73 65 63 6b 65 79 20 28 20 2d 2d 20 29 0a 20  +seckey ( -- ). 
1bc0: 20 20 20 6b 65 2d 73 6b 20 40 20 6b 65 2d 70 6b     ke-sk @ ke-pk
1bd0: 20 24 40 20 64 72 6f 70 20 6b 65 79 70 61 64 20   $@ drop keypad 
1be0: 65 64 2d 64 68 20 2b 6b 65 79 20 3b 0a 0a 22 22  ed-dh +key ;..""
1bf0: 20 22 3e 70 61 73 73 70 68 72 61 73 65 20 5c 20   ">passphrase \ 
1c00: 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 65 6e  following the en
1c10: 63 72 79 70 74 2d 65 76 65 72 79 74 68 69 6e 67  crypt-everything
1c20: 20 70 61 72 61 64 69 67 6d 2c 0a 5c 20 6e 6f 20   paradigm,.\ no 
1c30: 70 61 73 73 77 6f 72 64 20 69 73 20 74 68 65 20  password is the 
1c40: 65 6d 70 74 79 20 73 74 72 69 6e 67 21 20 20 49  empty string!  I
1c50: 74 27 73 20 73 74 69 6c 6c 20 65 6e 63 72 79 70  t's still encryp
1c60: 74 65 64 20 3b 2d 29 21 0a 0a 5c 20 61 20 73 65  ted ;-)!..\ a se
1c70: 63 72 65 74 20 6b 65 79 20 6a 75 73 74 20 6e 65  cret key just ne
1c80: 65 64 73 20 61 20 6e 69 63 6b 20 61 6e 64 20 61  eds a nick and a
1c90: 20 74 79 70 65 2e 0a 5c 20 53 65 63 72 65 74 20   type..\ Secret 
1ca0: 6b 65 79 73 20 63 61 6e 20 62 65 20 70 65 72 73  keys can be pers
1cb0: 6f 6e 73 20 61 6e 64 20 67 72 6f 75 70 73 2e 0a  ons and groups..
1cc0: 0a 5c 20 61 20 70 75 62 6c 69 63 20 6b 65 79 20  .\ a public key 
1cd0: 6e 65 65 64 73 20 6d 6f 72 65 3a 20 6e 69 63 6b  needs more: nick
1ce0: 2c 20 74 79 70 65 2c 20 70 72 6f 66 69 6c 65 2e  , type, profile.
1cf0: 0a 5c 20 54 68 65 20 70 72 6f 66 69 6c 65 20 69  .\ The profile i
1d00: 73 20 61 20 73 74 72 75 63 74 75 72 65 64 20 64  s a structured d
1d10: 6f 63 75 6d 65 6e 74 2c 20 69 2e 65 2e 20 70 6f  ocument, i.e. po
1d20: 69 6e 74 65 64 20 74 6f 20 62 79 20 61 20 68 61  inted to by a ha
1d30: 73 68 2e 0a 0a 5c 20 61 20 73 69 67 6e 61 74 75  sh...\ a signatu
1d40: 72 65 20 63 6f 6e 74 61 69 6e 73 20 61 20 70 75  re contains a pu
1d50: 62 6b 65 79 2c 20 61 20 63 68 65 63 6b 62 6f 78  bkey, a checkbox
1d60: 20 62 69 74 6d 61 73 6b 2c 0a 5c 20 61 20 64 61   bitmask,.\ a da
1d70: 74 65 2c 20 61 6e 20 65 78 70 69 72 61 74 69 6f  te, an expiratio
1d80: 6e 20 64 61 74 65 2c 20 74 68 65 20 73 69 67 6e  n date, the sign
1d90: 65 72 27 73 20 70 75 62 6b 65 79 20 61 6e 64 20  er's pubkey and 
1da0: 74 68 65 20 73 69 67 6e 61 74 75 72 65 20 69 74  the signature it
1db0: 73 65 6c 66 0a 5c 20 28 72 2b 73 29 2e 20 20 54  self.\ (r+s).  T
1dc0: 68 65 72 65 20 69 73 20 61 6e 20 6f 70 74 69 6f  here is an optio
1dd0: 6e 61 6c 20 73 69 67 6e 69 6e 67 20 70 72 6f 74  nal signing prot
1de0: 6f 63 6f 6c 20 64 6f 63 75 6d 65 6e 74 20 28 68  ocol document (h
1df0: 61 73 68 29 2e 0a 0a 5c 20 77 65 20 73 74 6f 72  ash)...\ we stor
1e00: 65 20 65 61 63 68 20 69 74 65 6d 20 69 6e 20 61  e each item in a
1e10: 20 32 35 36 20 62 79 74 65 73 20 65 6e 63 72 79   256 bytes encry
1e20: 70 74 65 64 20 73 74 72 69 6e 67 2c 20 69 2e 65  pted string, i.e
1e30: 2e 20 77 69 74 68 20 61 20 31 36 0a 5c 20 62 79  . with a 16.\ by
1e40: 74 65 20 73 61 6c 74 20 61 6e 64 20 61 20 31 36  te salt and a 16
1e50: 20 62 79 74 65 20 63 68 65 63 6b 73 75 6d 2e 0a   byte checksum..
1e60: 0a 3a 20 6b 65 2d 6c 61 73 74 21 20 28 20 36 34  .: ke-last! ( 64
1e70: 64 61 74 65 20 2d 2d 20 29 0a 20 20 20 20 6b 65  date -- ).    ke
1e80: 2d 73 65 6c 66 73 69 67 20 24 40 6c 65 6e 20 24  -selfsig $@len $
1e90: 31 30 20 75 6d 61 78 20 6b 65 2d 73 65 6c 66 73  10 umax ke-selfs
1ea0: 69 67 20 24 21 6c 65 6e 0a 20 20 20 20 6b 65 2d  ig $!len.    ke-
1eb0: 73 65 6c 66 73 69 67 20 24 40 20 64 72 6f 70 20  selfsig $@ drop 
1ec0: 36 34 27 2b 20 36 34 21 20 3b 0a 3a 20 6b 65 2d  64'+ 64! ;.: ke-
1ed0: 66 69 72 73 74 21 20 28 20 36 34 64 61 74 65 20  first! ( 64date 
1ee0: 2d 2d 20 29 20 36 34 23 2d 31 20 6b 65 2d 6c 61  -- ) 64#-1 ke-la
1ef0: 73 74 21 0a 20 20 20 20 6b 65 2d 73 65 6c 66 73  st!.    ke-selfs
1f00: 69 67 20 24 40 20 64 72 6f 70 20 36 34 21 20 3b  ig $@ drop 64! ;
1f10: 0a 0a 67 65 74 2d 63 75 72 72 65 6e 74 20 61 6c  ..get-current al
1f20: 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 20 64 65  so net2o-base de
1f30: 66 69 6e 69 74 69 6f 6e 73 0a 0a 63 6d 64 2d 74  finitions..cmd-t
1f40: 61 62 6c 65 20 24 40 20 69 6e 68 65 72 69 74 2d  able $@ inherit-
1f50: 74 61 62 6c 65 20 6b 65 79 2d 65 6e 74 72 79 2d  table key-entry-
1f60: 74 61 62 6c 65 0a 0a 5c 20 24 31 30 20 6e 65 74  table..\ $10 net
1f70: 32 6f 3a 20 6e 65 77 6b 65 79 20 28 20 24 3a 73  2o: newkey ( $:s
1f80: 74 72 69 6e 67 20 2d 2d 20 6f 3a 6b 65 79 20 29  tring -- o:key )
1f90: 20 21 21 73 69 67 6e 65 64 3f 0a 5c 20 20 20 20   !!signed?.\    
1fa0: 20 24 3e 20 6b 65 79 3a 6e 65 77 20 6e 3a 3e 6f   $> key:new n:>o
1fb0: 20 20 31 20 21 21 3e 6f 72 64 65 72 3f 20 3b 0a    1 !!>order? ;.
1fc0: 5c 20 6b 65 79 2d 65 6e 74 72 79 2d 74 61 62 6c  \ key-entry-tabl
1fd0: 65 20 3e 74 61 62 6c 65 0a 24 31 31 20 6e 65 74  e >table.$11 net
1fe0: 32 6f 3a 20 70 72 69 76 6b 65 79 20 28 20 24 3a  2o: privkey ( $:
1ff0: 73 74 72 69 6e 67 20 2d 2d 20 29 0a 20 20 20 20  string -- ).    
2000: 5c 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20  \ does not need 
2010: 74 6f 20 62 65 20 73 69 67 6e 65 64 2c 20 74 68  to be signed, th
2020: 65 20 73 65 63 72 65 74 20 6b 65 79 20 76 65 72  e secret key ver
2030: 69 66 69 65 73 20 69 74 73 65 6c 66 0a 20 20 20  ifies itself.   
2040: 20 24 3e 20 6f 76 65 72 20 6b 65 79 70 61 64 20   $> over keypad 
2050: 73 6b 3e 70 6b 20 5c 20 67 65 6e 65 72 61 74 65  sk>pk \ generate
2060: 20 70 75 62 6b 65 79 0a 20 20 20 20 6b 65 79 70   pubkey.    keyp
2070: 61 64 20 6b 65 2d 70 6b 20 24 40 20 64 72 6f 70  ad ke-pk $@ drop
2080: 20 6b 65 79 73 69 7a 65 20 74 75 63 6b 20 73 74   keysize tuck st
2090: 72 3d 20 30 3d 20 21 21 77 72 6f 6e 67 2d 6b 65  r= 0= !!wrong-ke
20a0: 79 21 21 0a 20 20 20 20 6b 65 2d 73 6b 20 73 65  y!!.    ke-sk se
20b0: 63 21 20 2b 73 65 63 6b 65 79 20 3b 0a 2b 6e 65  c! +seckey ;.+ne
20c0: 74 32 6f 3a 20 6b 65 79 74 79 70 65 20 28 20 6e  t2o: keytype ( n
20d0: 20 2d 2d 20 29 20 20 20 20 20 20 20 20 20 20 20   -- )           
20e0: 21 21 73 69 67 6e 65 64 3f 20 20 20 31 20 21 21  !!signed?   1 !!
20f0: 3e 6f 72 64 65 72 3f 20 36 34 3e 6e 20 6b 65 2d  >order? 64>n ke-
2100: 74 79 70 65 20 21 20 3b 0a 2b 6e 65 74 32 6f 3a  type ! ;.+net2o:
2110: 20 6b 65 79 6e 69 63 6b 20 28 20 24 3a 73 74 72   keynick ( $:str
2120: 69 6e 67 20 2d 2d 20 29 20 20 20 20 21 21 73 69  ing -- )    !!si
2130: 67 6e 65 64 3f 20 20 20 32 20 21 21 3e 6f 72 64  gned?   2 !!>ord
2140: 65 72 3f 20 24 3e 20 6b 65 2d 6e 69 63 6b 20 24  er? $> ke-nick $
2150: 21 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 70  ! ;.+net2o: keyp
2160: 72 6f 66 69 6c 65 20 28 20 24 3a 73 74 72 69 6e  rofile ( $:strin
2170: 67 20 2d 2d 20 29 20 21 21 73 69 67 6e 65 64 3f  g -- ) !!signed?
2180: 20 20 20 34 20 21 21 3e 6f 72 64 65 72 3f 20 24     4 !!>order? $
2190: 3e 20 6b 65 2d 70 72 6f 66 20 24 21 20 3b 0a 2b  > ke-prof $! ;.+
21a0: 6e 65 74 32 6f 3a 20 6b 65 79 6d 61 73 6b 20 28  net2o: keymask (
21b0: 20 78 20 2d 2d 20 29 20 20 20 20 20 20 20 20 20   x -- )         
21c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 38 20                8 
21d0: 21 21 3e 6f 72 64 65 72 3f 20 36 34 64 72 6f 70  !!>order? 64drop
21e0: 20 3b 0a 2b 6e 65 74 32 6f 3a 20 6b 65 79 70 73   ;.+net2o: keyps
21f0: 6b 20 28 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20  k ( $:string -- 
2200: 29 20 20 20 20 20 21 21 73 69 67 6e 65 64 3f 20  )     !!signed? 
2210: 24 31 30 20 21 21 3e 6f 72 64 65 72 3f 20 24 3e  $10 !!>order? $>
2220: 20 6b 65 2d 70 73 6b 20 73 65 63 21 20 3b 0a 2b   ke-psk sec! ;.+
2230: 6e 65 74 32 6f 3a 20 2b 6b 65 79 73 69 67 20 28  net2o: +keysig (
2240: 20 24 3a 73 74 72 69 6e 67 20 2d 2d 20 29 20 20   $:string -- )  
2250: 24 32 30 20 21 21 3e 3d 6f 72 64 65 72 3f 20 24  $20 !!>=order? $
2260: 3e 20 6b 65 2d 73 69 67 73 20 24 2b 5b 5d 21 20  > ke-sigs $+[]! 
2270: 3b 0a 64 75 70 20 73 65 74 2d 63 75 72 72 65 6e  ;.dup set-curren
2280: 74 20 70 72 65 76 69 6f 75 73 0a 0a 67 65 6e 2d  t previous..gen-
2290: 74 61 62 6c 65 20 24 66 72 65 65 7a 65 0a 27 20  table $freeze.' 
22a0: 63 6f 6e 74 65 78 74 2d 74 61 62 6c 65 20 69 73  context-table is
22b0: 20 67 65 6e 2d 74 61 62 6c 65 0a 0a 3a 6e 6f 6e   gen-table..:non
22c0: 61 6d 65 20 28 20 61 64 64 72 20 75 20 2d 2d 20  ame ( addr u -- 
22d0: 61 64 64 72 20 75 27 20 66 6c 61 67 20 29 0a 20  addr u' flag ). 
22e0: 20 20 20 70 6b 32 2d 73 69 67 3f 20 64 75 70 20     pk2-sig? dup 
22f0: 30 3d 20 3f 45 58 49 54 20 64 72 6f 70 0a 20 20  0= ?EXIT drop.  
2300: 20 20 32 64 75 70 20 2b 20 73 69 67 73 69 7a 65    2dup + sigsize
2310: 23 20 2d 20 73 69 67 73 69 7a 65 23 20 3e 24 0a  # - sigsize# >$.
2320: 20 20 20 20 73 69 67 70 6b 32 73 69 7a 65 23 20      sigpk2size# 
2330: 2d 20 32 64 75 70 20 2b 20 6b 65 79 73 69 7a 65  - 2dup + keysize
2340: 20 32 2a 20 6b 65 79 3f 6e 65 77 20 6e 3a 3e 6f   2* key?new n:>o
2350: 20 24 3e 20 6b 65 2d 73 65 6c 66 73 69 67 20 24   $> ke-selfsig $
2360: 21 0a 20 20 20 20 63 2d 73 74 61 74 65 20 6f 66  !.    c-state of
2370: 66 20 74 72 75 65 20 3b 20 6b 65 79 2d 65 6e 74  f true ; key-ent
2380: 72 79 20 74 6f 20 6e 65 73 74 2d 73 69 67 0a 0a  ry to nest-sig..
2390: 6b 65 79 2d 65 6e 74 72 79 20 27 20 6e 65 77 20  key-entry ' new 
23a0: 73 74 61 74 69 63 2d 61 20 77 69 74 68 2d 61 6c  static-a with-al
23b0: 6c 6f 63 61 74 65 72 20 74 6f 20 73 61 6d 70 6c  locater to sampl
23c0: 65 2d 6b 65 79 0a 73 61 6d 70 6c 65 2d 6b 65 79  e-key.sample-key
23d0: 20 3e 6f 20 6b 65 79 2d 65 6e 74 72 79 2d 74 61   >o key-entry-ta
23e0: 62 6c 65 20 40 20 74 6f 6b 65 6e 2d 74 61 62 6c  ble @ token-tabl
23f0: 65 20 21 20 6f 3e 0a 0a 3a 20 6b 65 79 3a 63 6f  e ! o>..: key:co
2400: 64 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 63 6f  de ( -- ).    co
2410: 64 65 2d 6b 65 79 20 20 63 6d 64 6c 6f 63 6b 20  de-key  cmdlock 
2420: 6c 6f 63 6b 0a 20 20 20 20 6b 65 79 70 61 63 6b  lock.    keypack
2430: 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20 65 72   keypack-all# er
2440: 61 73 65 0a 20 20 20 20 63 6d 64 72 65 73 65 74  ase.    cmdreset
2450: 20 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65   also net2o-base
2460: 20 3b 0a 63 6f 6d 70 3a 20 3a 2c 20 61 6c 73 6f   ;.comp: :, also
2470: 20 6e 65 74 32 6f 2d 62 61 73 65 20 3b 0a 0a 61   net2o-base ;..a
2480: 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 20 64  lso net2o-base d
2490: 65 66 69 6e 69 74 69 6f 6e 73 0a 0a 3a 20 65 6e  efinitions..: en
24a0: 64 3a 6b 65 79 20 28 20 2d 2d 20 29 0a 20 20 20  d:key ( -- ).   
24b0: 20 65 6e 64 77 69 74 68 20 70 72 65 76 69 6f 75   endwith previou
24c0: 73 20 63 6d 64 6c 6f 63 6b 20 75 6e 6c 6f 63 6b  s cmdlock unlock
24d0: 20 3b 0a 63 6f 6d 70 3a 20 3a 2c 20 70 72 65 76   ;.comp: :, prev
24e0: 69 6f 75 73 20 3b 0a 0a 73 65 74 2d 63 75 72 72  ious ;..set-curr
24f0: 65 6e 74 20 70 72 65 76 69 6f 75 73 20 70 72 65  ent previous pre
2500: 76 69 6f 75 73 0a 0a 3a 20 6b 65 79 2d 63 72 79  vious..: key-cry
2510: 70 74 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65  pt ( -- ).    ke
2520: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
2530: 6c 23 0a 20 20 20 20 3e 73 74 6f 72 65 6b 65 79  l#.    >storekey
2540: 20 73 65 63 40 20 64 75 70 20 24 32 30 20 75 3c   sec@ dup $20 u<
2550: 3d 20 5c 20 69 73 20 61 20 73 65 63 72 65 74 2c  = \ is a secret,
2560: 20 6e 6f 20 6e 65 65 64 20 74 6f 20 62 65 20 73   no need to be s
2570: 6c 6f 77 0a 20 20 20 20 49 46 20 20 65 6e 63 72  low.    IF  encr
2580: 79 70 74 24 20 20 45 4c 53 45 20 20 70 77 2d 6c  ypt$  ELSE  pw-l
2590: 65 76 65 6c 23 20 65 6e 63 72 79 70 74 2d 70 77  evel# encrypt-pw
25a0: 24 20 20 54 48 45 4e 20 3b 0a 0a 30 20 56 61 6c  $  THEN ;..0 Val
25b0: 75 65 20 6b 65 79 2d 73 66 64 20 5c 20 73 65 63  ue key-sfd \ sec
25c0: 72 65 74 20 6b 65 79 73 0a 30 20 56 61 6c 75 65  ret keys.0 Value
25d0: 20 6b 65 79 2d 70 66 64 20 5c 20 70 75 62 6b 65   key-pfd \ pubke
25e0: 79 73 0a 0a 3a 20 3f 2e 6e 65 74 32 6f 20 28 20  ys..: ?.net2o ( 
25f0: 2d 2d 20 29 0a 20 20 20 20 73 22 20 7e 2f 2e 6e  -- ).    s" ~/.n
2600: 65 74 32 6f 22 20 72 2f 6f 20 6f 70 65 6e 2d 66  et2o" r/o open-f
2610: 69 6c 65 20 49 46 0a 09 64 72 6f 70 20 73 22 20  ile IF..drop s" 
2620: 7e 2f 2e 6e 65 74 32 6f 22 20 24 31 43 30 20 6d  ~/.net2o" $1C0 m
2630: 6b 64 69 72 2d 70 61 72 65 6e 74 73 20 74 68 72  kdir-parents thr
2640: 6f 77 0a 20 20 20 20 45 4c 53 45 0a 09 63 6c 6f  ow.    ELSE..clo
2650: 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 0a 20 20  se-file throw.  
2660: 20 20 54 48 45 4e 20 3b 0a 0a 3a 20 3f 66 64 20    THEN ;..: ?fd 
2670: 28 20 66 64 20 61 64 64 72 20 75 20 2d 2d 20 66  ( fd addr u -- f
2680: 64 27 20 29 20 7b 20 61 64 64 72 20 75 20 7d 20  d' ) { addr u } 
2690: 64 75 70 20 3f 45 58 49 54 20 64 72 6f 70 0a 20  dup ?EXIT drop. 
26a0: 20 20 20 3f 2e 6e 65 74 32 6f 0a 20 20 20 20 61     ?.net2o.    a
26b0: 64 64 72 20 75 20 72 2f 77 20 6f 70 65 6e 2d 66  ddr u r/w open-f
26c0: 69 6c 65 20 64 75 70 20 2d 35 31 34 20 3d 20 49  ile dup -514 = I
26d0: 46 0a 09 32 64 72 6f 70 20 61 64 64 72 20 75 20  F..2drop addr u 
26e0: 72 2f 77 20 63 72 65 61 74 65 2d 66 69 6c 65 0a  r/w create-file.
26f0: 20 20 20 20 54 48 45 4e 20 20 74 68 72 6f 77 20      THEN  throw 
2700: 3b 0a 3a 20 3f 6b 65 79 2d 73 66 64 20 28 20 2d  ;.: ?key-sfd ( -
2710: 2d 20 66 64 20 29 20 6b 65 79 2d 73 66 64 20 22  - fd ) key-sfd "
2720: 7e 2f 2e 6e 65 74 32 6f 2f 73 65 63 6b 65 79 73  ~/.net2o/seckeys
2730: 2e 6b 32 6f 22 20 3f 66 64 20 64 75 70 20 74 6f  .k2o" ?fd dup to
2740: 20 6b 65 79 2d 73 66 64 20 3b 0a 3a 20 3f 6b 65   key-sfd ;.: ?ke
2750: 79 2d 70 66 64 20 28 20 2d 2d 20 66 64 20 29 20  y-pfd ( -- fd ) 
2760: 6b 65 79 2d 70 66 64 20 22 7e 2f 2e 6e 65 74 32  key-pfd "~/.net2
2770: 6f 2f 70 75 62 6b 65 79 73 2e 6b 32 6f 22 20 3f  o/pubkeys.k2o" ?
2780: 66 64 20 64 75 70 20 74 6f 20 6b 65 79 2d 70 66  fd dup to key-pf
2790: 64 20 3b 0a 0a 3a 20 77 72 69 74 65 40 70 6f 73  d ;..: write@pos
27a0: 2d 66 69 6c 65 20 28 20 61 64 64 72 20 75 20 36  -file ( addr u 6
27b0: 34 70 6f 73 20 66 64 20 2d 2d 20 29 20 3e 72 0a  4pos fd -- ) >r.
27c0: 20 20 20 20 36 34 3e 64 20 72 40 20 72 65 70 6f      64>d r@ repo
27d0: 73 69 74 69 6f 6e 2d 66 69 6c 65 20 74 68 72 6f  sition-file thro
27e0: 77 0a 20 20 20 20 72 40 20 77 72 69 74 65 2d 66  w.    r@ write-f
27f0: 69 6c 65 20 74 68 72 6f 77 20 72 3e 20 66 6c 75  ile throw r> flu
2800: 73 68 2d 66 69 6c 65 20 74 68 72 6f 77 20 3b 0a  sh-file throw ;.
2810: 0a 3a 20 61 70 70 65 6e 64 2d 66 69 6c 65 20 28  .: append-file (
2820: 20 61 64 64 72 20 75 20 66 64 20 2d 2d 20 29 20   addr u fd -- ) 
2830: 3e 72 0a 20 20 20 20 72 40 20 66 69 6c 65 2d 73  >r.    r@ file-s
2840: 69 7a 65 20 74 68 72 6f 77 20 64 3e 36 34 20 72  ize throw d>64 r
2850: 3e 20 77 72 69 74 65 40 70 6f 73 2d 66 69 6c 65  > write@pos-file
2860: 20 3b 0a 0a 3a 20 6b 65 79 3e 73 66 69 6c 65 20   ;..: key>sfile 
2870: 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 70 61  ( -- ).    keypa
2880: 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20  ck keypack-all# 
2890: 3f 6b 65 79 2d 73 66 64 20 61 70 70 65 6e 64 2d  ?key-sfd append-
28a0: 66 69 6c 65 20 3b 0a 3a 20 6b 65 79 3e 70 66 69  file ;.: key>pfi
28b0: 6c 65 20 28 20 2d 2d 20 29 0a 20 20 20 20 6b 65  le ( -- ).    ke
28c0: 79 70 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c  ypack keypack-al
28d0: 6c 23 20 3f 6b 65 79 2d 70 66 64 20 61 70 70 65  l# ?key-pfd appe
28e0: 6e 64 2d 66 69 6c 65 20 3b 0a 0a 3a 20 6b 65 79  nd-file ;..: key
28f0: 3e 73 66 69 6c 65 40 70 6f 73 20 28 20 36 34 70  >sfile@pos ( 64p
2900: 6f 73 20 2d 2d 20 29 20 36 34 3e 72 0a 20 20 20  os -- ) 64>r.   
2910: 20 6b 65 79 70 61 63 6b 20 6b 65 79 70 61 63 6b   keypack keypack
2920: 2d 61 6c 6c 23 20 36 34 72 3e 20 3f 6b 65 79 2d  -all# 64r> ?key-
2930: 73 66 64 20 77 72 69 74 65 40 70 6f 73 2d 66 69  sfd write@pos-fi
2940: 6c 65 20 3b 0a 3a 20 6b 65 79 3e 70 66 69 6c 65  le ;.: key>pfile
2950: 40 70 6f 73 20 28 20 36 34 70 6f 73 20 2d 2d 20  @pos ( 64pos -- 
2960: 29 20 36 34 3e 72 0a 20 20 20 20 6b 65 79 70 61  ) 64>r.    keypa
2970: 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23 20  ck keypack-all# 
2980: 36 34 72 3e 20 3f 6b 65 79 2d 70 66 64 20 77 72  64r> ?key-pfd wr
2990: 69 74 65 40 70 6f 73 2d 66 69 6c 65 20 3b 0a 0a  ite@pos-file ;..
29a0: 3a 20 72 6e 64 3e 73 66 69 6c 65 20 28 20 2d 2d  : rnd>sfile ( --
29b0: 20 29 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b   ).    keypack k
29c0: 65 79 70 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e 67  eypack-all# >rng
29d0: 24 20 6b 65 79 3e 73 66 69 6c 65 20 3b 0a 3a 20  $ key>sfile ;.: 
29e0: 72 6e 64 3e 70 66 69 6c 65 20 28 20 2d 2d 20 29  rnd>pfile ( -- )
29f0: 0a 20 20 20 20 6b 65 79 70 61 63 6b 20 6b 65 79  .    keypack key
2a00: 70 61 63 6b 2d 61 6c 6c 23 20 3e 72 6e 67 24 20  pack-all# >rng$ 
2a10: 6b 65 79 3e 70 66 69 6c 65 20 3b 0a 0a 3a 20 3e  key>pfile ;..: >
2a20: 6b 65 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20  keys ( -- ).    
2a30: 5c 47 20 61 64 64 20 73 68 61 72 65 64 20 73 65  \G add shared se
2a40: 63 72 65 74 20 74 6f 20 6c 69 73 74 20 6f 66 20  cret to list of 
2a50: 70 6f 73 73 69 62 6c 65 20 6b 65 79 73 0a 20 20  possible keys.  
2a60: 20 20 73 6b 63 20 70 6b 63 20 6b 65 79 70 61 64    skc pkc keypad
2a70: 20 65 64 2d 64 68 20 2b 6b 65 79 20 3b 0a 0a 5c   ed-dh +key ;..\
2a80: 20 6b 65 79 20 67 65 6e 65 72 61 74 69 6f 6e 0a   key generation.
2a90: 5c 20 66 6f 72 20 72 65 70 72 6f 64 75 63 69 62  \ for reproducib
2aa0: 69 6c 69 74 79 20 6f 66 20 74 68 65 20 73 65 6c  ility of the sel
2ab0: 66 73 69 67 2c 20 61 6c 77 61 79 73 20 75 73 65  fsig, always use
2ac0: 20 74 68 65 20 73 61 6d 65 20 6f 72 64 65 72 3a   the same order:
2ad0: 0a 5c 20 22 70 75 62 6b 65 79 22 20 6e 65 77 6b  .\ "pubkey" newk
2ae0: 65 79 20 3c 6e 3e 20 6b 65 79 74 79 70 65 20 22  ey <n> keytype "
2af0: 6e 69 63 6b 22 20 6b 65 79 6e 69 63 6b 20 22 73  nick" keynick "s
2b00: 69 67 22 20 6b 65 79 73 65 6c 66 73 69 67 0a 0a  ig" keyselfsig..
2b10: 55 73 65 72 20 70 6b 2b 73 69 67 24 0a 0a 6b 65  User pk+sig$..ke
2b20: 79 73 69 7a 65 20 32 2a 20 43 6f 6e 73 74 61 6e  ysize 2* Constan
2b30: 74 20 70 6b 72 6b 23 0a 0a 3a 20 5d 70 6b 2b 73  t pkrk#..: ]pk+s
2b40: 69 67 6e 20 28 20 61 64 64 72 20 75 20 2d 2d 20  ign ( addr u -- 
2b50: 29 20 2b 63 6d 64 62 75 66 20 5d 73 69 67 6e 20  ) +cmdbuf ]sign 
2b60: 3b 0a 0a 3a 20 70 61 63 6b 2d 6b 65 79 20 28 20  ;..: pack-key ( 
2b70: 74 79 70 65 20 6e 69 63 6b 20 75 20 2d 2d 20 29  type nick u -- )
2b80: 0a 20 20 20 20 6e 6f 77 3e 6e 65 76 65 72 0a 20  .    now>never. 
2b90: 20 20 20 6b 65 79 3a 63 6f 64 65 0a 20 20 20 20     key:code.    
2ba0: 20 20 73 69 67 6e 5b 0a 20 20 20 20 20 20 72 6f    sign[.      ro
2bb0: 74 20 75 6c 69 74 2c 20 6b 65 79 74 79 70 65 20  t ulit, keytype 
2bc0: 24 2c 20 6b 65 79 6e 69 63 6b 0a 20 20 20 20 20  $, keynick.     
2bd0: 20 70 6b 63 20 70 6b 72 6b 23 20 5d 70 6b 2b 73   pkc pkrk# ]pk+s
2be0: 69 67 6e 0a 20 20 20 20 20 20 73 6b 63 20 6b 65  ign.      skc ke
2bf0: 79 73 69 7a 65 20 24 2c 20 70 72 69 76 6b 65 79  ysize $, privkey
2c00: 0a 20 20 20 20 65 6e 64 3a 6b 65 79 20 3b 0a 0a  .    end:key ;..
2c10: 61 6c 73 6f 20 6e 65 74 32 6f 2d 62 61 73 65 0a  also net2o-base.
2c20: 3a 20 70 61 63 6b 2d 63 6f 72 65 6b 65 79 20 28  : pack-corekey (
2c30: 20 6f 3a 6b 65 79 20 2d 2d 20 29 0a 20 20 20 20   o:key -- ).    
2c40: 73 69 67 6e 5b 0a 20 20 20 20 6b 65 2d 74 79 70  sign[.    ke-typ
2c50: 65 20 40 20 75 6c 69 74 2c 20 6b 65 79 74 79 70  e @ ulit, keytyp
2c60: 65 0a 20 20 20 20 6b 65 2d 6e 69 63 6b 20 24 40  e.    ke-nick $@
2c70: 20 24 2c 20 6b 65 79 6e 69 63 6b 0a 20 20 20 20   $, keynick.    
2c80: 6b 65 2d 70 73 6b 20 73 65 63 40 20 64 75 70 20  ke-psk sec@ dup 
2c90: 49 46 20 20 24 2c 20 6b 65 79 70 73 6b 20 20 45  IF  $, keypsk  E
2ca0: 4c 53 45 20 20 32 64 72 6f 70 20 20 54 48 45 4e  LSE  2drop  THEN
2cb0: 0a 20 20 20 20 6b 65 2d 70 72 6f 66 20 24 40 20  .    ke-prof $@ 
2cc0: 64 75 70 20 49 46 20 20 24 2c 20 6b 65 79 70 72  dup IF  $, keypr
2cd0: 6f 66 69 6c 65 20 20 45 4c 53 45 20 20 32 64 72  ofile  ELSE  2dr
2ce0: 6f 70 20 20 54 48 45 4e 0a 20 20 20 20 6b 65 2d  op  THEN.    ke-
2cf0: 70 6b 20 24 40 20 2b 63 6d 64 62 75 66 0a 20 20  pk $@ +cmdbuf.  
2d00: 20 20 6b 65 2d 73 65 6c 66 73 69 67 20 24 40 20    ke-selfsig $@ 
2d10: 2b 63 6d 64 62 75 66 20 63 6d 64 2d 72 65 73 6f  +cmdbuf cmd-reso
2d20: 6c 76 65 3e 20 32 64 72 6f 70 20 6e 65 73 74 73  lve> 2drop nests
2d30: 69 67 0a 20 20 20 20 6b 65 2d 73 74 6f 72 65 6b  ig.    ke-storek
2d40: 65 79 20 40 20 3e 73 74 6f 72 65 6b 65 79 20 21  ey @ >storekey !
2d50: 20 3b 0a 70 72 65 76 69 6f 75 73 0a 0a 3a 20 70   ;.previous..: p
2d60: 61 63 6b 2d 70 75 62 6b 65 79 20 28 20 6f 3a 6b  ack-pubkey ( o:k
2d70: 65 79 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 3a  ey -- ).    key:
2d80: 63 6f 64 65 0a 20 20 20 20 20 20 70 61 63 6b 2d  code.      pack-
2d90: 63 6f 72 65 6b 65 79 0a 20 20 20 20 65 6e 64 3a  corekey.    end:
2da0: 6b 65 79 20 3b 0a 3a 20 70 61 63 6b 2d 73 65 63  key ;.: pack-sec
2db0: 6b 65 79 20 28 20 6f 3a 6b 65 79 20 2d 2d 20 29  key ( o:key -- )
2dc0: 0a 20 20 20 20 6b 65 79 3a 63 6f 64 65 0a 20 20  .    key:code.  
2dd0: 20 20 20 20 70 61 63 6b 2d 63 6f 72 65 6b 65 79      pack-corekey
2de0: 0a 20 20 20 20 20 20 6b 65 2d 73 6b 20 73 65 63  .      ke-sk sec
2df0: 40 20 24 2c 20 70 72 69 76 6b 65 79 0a 20 20 20  @ $, privkey.   
2e00: 20 65 6e 64 3a 6b 65 79 20 3b 0a 0a 3a 20 3e 62   end:key ;..: >b
2e10: 61 63 6b 75 70 20 28 20 61 64 64 72 20 75 20 2d  ackup ( addr u -
2e20: 2d 20 29 0a 20 20 20 20 32 64 75 70 20 32 64 75  - ).    2dup 2du
2e30: 70 20 5b 3a 20 74 79 70 65 20 27 7e 27 20 65 6d  p [: type '~' em
2e40: 69 74 20 3b 5d 20 24 74 6d 70 20 72 65 6e 61 6d  it ;] $tmp renam
2e50: 65 2d 66 69 6c 65 20 74 68 72 6f 77 0a 20 20 20  e-file throw.   
2e60: 20 32 64 75 70 20 5b 3a 20 74 79 70 65 20 27 2b   2dup [: type '+
2e70: 27 20 65 6d 69 74 20 3b 5d 20 24 74 6d 70 20 32  ' emit ;] $tmp 2
2e80: 73 77 61 70 20 72 65 6e 61 6d 65 2d 66 69 6c 65  swap rename-file
2e90: 20 74 68 72 6f 77 20 3b 0a 0a 56 61 72 69 61 62   throw ;..Variab
2ea0: 6c 65 20 63 70 2d 74 6d 70 0a 0a 3a 20 73 61 76  le cp-tmp..: sav
2eb0: 65 2d 70 75 62 6b 65 79 73 20 28 20 2d 2d 20 29  e-pubkeys ( -- )
2ec0: 0a 20 20 20 20 6b 65 79 2d 70 66 64 20 3f 64 75  .    key-pfd ?du
2ed0: 70 2d 49 46 0a 09 64 75 70 20 30 2e 20 72 6f 74  p-IF..dup 0. rot
2ee0: 20 72 65 70 6f 73 69 74 69 6f 6e 2d 66 69 6c 65   reposition-file
2ef0: 20 74 68 72 6f 77 0a 09 64 75 70 20 63 70 2d 74   throw..dup cp-t
2f00: 6d 70 20 24 73 6c 75 72 70 20 63 6c 6f 73 65 2d  mp $slurp close-
2f10: 66 69 6c 65 20 74 68 72 6f 77 20 20 54 48 45 4e  file throw  THEN
2f20: 0a 20 20 20 20 30 20 22 7e 2f 2e 6e 65 74 32 6f  .    0 "~/.net2o
2f30: 2f 70 75 62 6b 65 79 73 2e 6b 32 6f 2b 22 20 3f  /pubkeys.k2o+" ?
2f40: 66 64 20 74 6f 20 6b 65 79 2d 70 66 64 0a 20 20  fd to key-pfd.  
2f50: 20 20 63 70 2d 74 6d 70 20 24 40 20 6b 65 79 2d    cp-tmp $@ key-
2f60: 70 66 64 20 77 72 69 74 65 2d 66 69 6c 65 20 74  pfd write-file t
2f70: 68 72 6f 77 20 63 70 2d 74 6d 70 20 24 6f 66 66  hrow cp-tmp $off
2f80: 0a 20 20 20 20 6b 65 79 2d 74 61 62 6c 65 20 5b  .    key-table [
2f90: 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72 6f 70 20  : cell+ $@ drop 
2fa0: 63 65 6c 6c 2b 20 3e 6f 0a 20 20 20 20 20 20 6b  cell+ >o.      k
2fb0: 65 2d 73 6b 20 73 65 63 40 20 64 30 3d 20 49 46  e-sk sec@ d0= IF
2fc0: 20 20 70 61 63 6b 2d 70 75 62 6b 65 79 0a 09 20    pack-pubkey.. 
2fd0: 20 66 6c 75 73 68 28 20 2e 22 20 73 61 76 69 6e   flush( ." savin
2fe0: 67 20 22 20 6b 65 2d 6e 69 63 6b 20 24 40 20 74  g " ke-nick $@ t
2ff0: 79 70 65 20 46 20 63 72 20 29 0a 09 20 20 6b 65  ype F cr )..  ke
3000: 79 2d 63 72 79 70 74 20 6b 65 2d 6f 66 66 73 65  y-crypt ke-offse
3010: 74 20 36 34 40 20 6b 65 79 3e 70 66 69 6c 65 40  t 64@ key>pfile@
3020: 70 6f 73 0a 20 20 20 20 20 20 54 48 45 4e 20 6f  pos.      THEN o
3030: 3e 20 3b 5d 20 23 6d 61 70 0a 20 20 20 20 6b 65  > ;] #map.    ke
3040: 79 2d 70 66 64 20 63 6c 6f 73 65 2d 66 69 6c 65  y-pfd close-file
3050: 20 74 68 72 6f 77 0a 20 20 20 20 22 7e 2f 2e 6e   throw.    "~/.n
3060: 65 74 32 6f 2f 70 75 62 6b 65 79 73 2e 6b 32 6f  et2o/pubkeys.k2o
3070: 22 20 3e 62 61 63 6b 75 70 0a 20 20 20 20 30 20  " >backup.    0 
3080: 74 6f 20 6b 65 79 2d 70 66 64 20 3b 0a 0a 3a 20  to key-pfd ;..: 
3090: 73 61 76 65 2d 73 65 63 6b 65 79 73 20 28 20 2d  save-seckeys ( -
30a0: 2d 20 29 0a 20 20 20 20 6b 65 79 2d 73 66 64 20  - ).    key-sfd 
30b0: 3f 64 75 70 2d 49 46 0a 09 64 75 70 20 30 2e 20  ?dup-IF..dup 0. 
30c0: 72 6f 74 20 72 65 70 6f 73 69 74 69 6f 6e 2d 66  rot reposition-f
30d0: 69 6c 65 20 74 68 72 6f 77 0a 09 64 75 70 20 63  ile throw..dup c
30e0: 70 2d 74 6d 70 20 24 73 6c 75 72 70 20 63 6c 6f  p-tmp $slurp clo
30f0: 73 65 2d 66 69 6c 65 20 74 68 72 6f 77 20 20 54  se-file throw  T
3100: 48 45 4e 0a 20 20 20 20 30 20 22 7e 2f 2e 6e 65  HEN.    0 "~/.ne
3110: 74 32 6f 2f 73 65 63 6b 65 79 73 2e 6b 32 6f 2b  t2o/seckeys.k2o+
3120: 22 20 3f 66 64 20 74 6f 20 6b 65 79 2d 73 66 64  " ?fd to key-sfd
3130: 0a 20 20 20 20 63 70 2d 74 6d 70 20 24 40 20 6b  .    cp-tmp $@ k
3140: 65 79 2d 73 66 64 20 77 72 69 74 65 2d 66 69 6c  ey-sfd write-fil
3150: 65 20 74 68 72 6f 77 20 63 70 2d 74 6d 70 20 24  e throw cp-tmp $
3160: 6f 66 66 0a 20 20 20 20 6b 65 79 2d 74 61 62 6c  off.    key-tabl
3170: 65 20 5b 3a 20 63 65 6c 6c 2b 20 24 40 20 64 72  e [: cell+ $@ dr
3180: 6f 70 20 63 65 6c 6c 2b 20 3e 6f 0a 20 20 20 20  op cell+ >o.    
3190: 20 20 6b 65 2d 73 6b 20 73 65 63 40 20 64 30 3c    ke-sk sec@ d0<
31a0: 3e 20 49 46 20 20 70 61 63 6b 2d 73 65 63 6b 65  > IF  pack-secke
31b0: 79 0a 09 20 20 6b 65 79 2d 63 72 79 70 74 20 6b  y..  key-crypt k
31c0: 65 2d 6f 66 66 73 65 74 20 36 34 40 20 6b 65 79  e-offset 64@ key
31d0: 3e 73 66 69 6c 65 40 70 6f 73 0a 20 20 20 20 20  >sfile@pos.     
31e0: 20 54 48 45 4e 20 6f 3e 20 3b 5d 20 23 6d 61 70   THEN o> ;] #map
31f0: 0a 20 20 20 20 22 7e 2f 2e 6e 65 74 32 6f 2f 73  .    "~/.net2o/s
3200: 65 63 6b 65 79 73 2e 6b 32 6f 22 20 3e 62 61 63  eckeys.k2o" >bac
3210: 6b 75 70 0a 20 20 20 20 6b 65 79 2d 73 66 64 20  kup.    key-sfd 
3220: 63 6c 6f 73 65 2d 66 69 6c 65 20 74 68 72 6f 77  close-file throw
3230: 20 30 20 74 6f 20 6b 65 79 2d 73 66 64 20 3b 0a   0 to key-sfd ;.
3240: 0a 3a 20 73 61 76 65 2d 6b 65 79 73 20 28 20 2d  .: save-keys ( -
3250: 2d 20 29 0a 20 20 20 20 73 61 76 65 2d 70 75 62  - ).    save-pub
3260: 6b 65 79 73 20 73 61 76 65 2d 73 65 63 6b 65 79  keys save-seckey
3270: 73 20 3b 0a 0a 3a 20 2b 67 65 6e 2d 6b 65 79 73  s ;..: +gen-keys
3280: 20 28 20 6e 69 63 6b 20 75 20 74 79 70 65 20 2d   ( nick u type -
3290: 2d 20 29 20 2d 72 6f 74 0a 20 20 20 20 67 65 6e  - ) -rot.    gen
32a0: 2d 6b 65 79 73 20 3e 6b 65 79 73 20 70 61 63 6b  -keys >keys pack
32b0: 2d 6b 65 79 20 6b 65 79 2d 63 72 79 70 74 20 6b  -key key-crypt k
32c0: 65 79 3e 73 66 69 6c 65 20 3b 0a 0a 3a 20 2b 6b  ey>sfile ;..: +k
32d0: 65 79 70 61 69 72 20 28 20 74 79 70 65 20 6e 69  eypair ( type ni
32e0: 63 6b 20 75 20 2d 2d 20 29 20 2b 70 61 73 73 70  ck u -- ) +passp
32f0: 68 72 61 73 65 20 2b 67 65 6e 2d 6b 65 79 73 20  hrase +gen-keys 
3300: 3b 0a 0a 3a 20 2e 72 76 6b 20 2e 22 20 50 6c 65  ;..: .rvk ." Ple
3310: 61 73 65 20 77 72 69 74 65 20 64 6f 77 6e 20 72  ase write down r
3320: 65 76 6f 6b 65 20 6b 65 79 3a 20 22 20 63 72 0a  evoke key: " cr.
3330: 20 20 20 20 73 6b 72 65 76 20 24 32 30 20 62 6f      skrev $20 bo
3340: 75 6e 64 73 20 44 4f 20 20 2e 22 20 5c 20 22 20  unds DO  ." \ " 
3350: 49 20 34 20 38 35 74 79 70 65 20 73 70 61 63 65  I 4 85type space
3360: 20 49 20 34 20 2b 20 34 20 38 35 74 79 70 65 20   I 4 + 4 85type 
3370: 63 72 20 38 20 2b 4c 4f 4f 50 20 3b 0a 0a 24 34  cr 8 +LOOP ;..$4
3380: 30 20 62 75 66 66 65 72 3a 20 6e 69 63 6b 2d 62  0 buffer: nick-b
3390: 75 66 0a 0a 3a 20 6d 61 6b 65 2d 6b 65 79 20 28  uf..: make-key (
33a0: 20 2d 2d 20 29 0a 20 20 20 20 6b 65 79 23 75 73   -- ).    key#us
33b0: 65 72 20 2e 22 20 6e 69 63 6b 3a 20 22 20 6e 69  er ." nick: " ni
33c0: 63 6b 2d 62 75 66 20 24 34 30 20 61 63 63 65 70  ck-buf $40 accep
33d0: 74 20 6e 69 63 6b 2d 62 75 66 20 73 77 61 70 20  t nick-buf swap 
33e0: 63 72 0a 20 20 20 20 2e 22 20 70 61 73 73 70 68  cr.    ." passph
33f0: 72 61 73 65 3a 20 22 20 2b 70 61 73 73 70 68 72  rase: " +passphr
3400: 61 73 65 20 6b 65 79 3e 64 65 66 61 75 6c 74 0a  ase key>default.
3410: 20 20 20 20 63 72 20 2b 67 65 6e 2d 6b 65 79 73      cr +gen-keys
3420: 20 2e 72 76 6b 20 3b 0a 0a 5c 20 72 65 61 64 20   .rvk ;..\ read 
3430: 6b 65 79 20 66 69 6c 65 0a 0a 3a 20 74 72 79 2d  key file..: try-
3440: 64 65 63 72 79 70 74 2d 6b 65 79 20 28 20 6b 65  decrypt-key ( ke
3450: 79 20 75 31 20 2d 2d 20 61 64 64 72 20 75 32 20  y u1 -- addr u2 
3460: 66 6c 61 67 20 29 0a 20 20 20 20 6b 65 79 70 61  flag ).    keypa
3470: 63 6b 20 6b 65 79 70 61 63 6b 2d 64 20 6b 65 79  ck keypack-d key
3480: 70 61 63 6b 2d 61 6c 6c 23 20 6d 6f 76 65 0a 20  pack-all# move. 
3490: 20 20 20 6b 65 79 70 61 63 6b 2d 64 20 6b 65 79     keypack-d key
34a0: 70 61 63 6b 2d 61 6c 6c 23 20 32 73 77 61 70 0a  pack-all# 2swap.
34b0: 20 20 20 20 64 75 70 20 24 32 30 20 3d 20 49 46      dup $20 = IF
34c0: 20 20 64 65 63 72 79 70 74 24 20 20 45 4c 53 45    decrypt$  ELSE
34d0: 0a 09 6b 65 79 70 61 63 6b 20 63 40 20 24 46 20  ..keypack c@ $F 
34e0: 61 6e 64 20 70 77 2d 6c 65 76 65 6c 23 20 3c 3d  and pw-level# <=
34f0: 20 49 46 20 20 64 65 63 72 79 70 74 2d 70 77 24   IF  decrypt-pw$
3500: 0a 09 45 4c 53 45 20 20 32 64 72 6f 70 20 66 61  ..ELSE  2drop fa
3510: 6c 73 65 20 20 54 48 45 4e 0a 20 20 20 20 54 48  lse  THEN.    TH
3520: 45 4e 20 3b 0a 0a 3a 20 74 72 79 2d 64 65 63 72  EN ;..: try-decr
3530: 79 70 74 20 28 20 2d 2d 20 61 64 64 72 20 75 20  ypt ( -- addr u 
3540: 2f 20 30 20 30 20 29 0a 20 20 20 20 6b 65 79 73  / 0 0 ).    keys
3550: 20 24 5b 5d 23 20 30 20 3f 44 4f 0a 09 49 20 6b   $[]# 0 ?DO..I k
3560: 65 79 73 20 73 65 63 5b 5d 40 20 74 72 79 2d 64  eys sec[]@ try-d
3570: 65 63 72 79 70 74 2d 6b 65 79 20 49 46 0a 09 20  ecrypt-key IF.. 
3580: 20 20 20 49 20 6b 65 79 73 20 24 5b 5d 20 40 20     I keys $[] @ 
3590: 3e 73 74 6f 72 65 6b 65 79 20 21 20 75 6e 6c 6f  >storekey ! unlo
35a0: 6f 70 20 20 45 58 49 54 20 20 54 48 45 4e 0a 09  op  EXIT  THEN..
35b0: 32 64 72 6f 70 0a 20 20 20 20 4c 4f 4f 50 20 20  2drop.    LOOP  
35c0: 30 20 30 20 3b 0a 0a 3a 20 64 6f 2d 6b 65 79 20  0 0 ;..: do-key 
35d0: 28 20 61 64 64 72 20 75 20 2f 20 30 20 30 20 20  ( addr u / 0 0  
35e0: 2d 2d 20 29 0a 20 20 20 20 64 75 70 20 30 3d 20  -- ).    dup 0= 
35f0: 49 46 20 20 32 64 72 6f 70 20 20 45 58 49 54 20  IF  2drop  EXIT 
3600: 20 54 48 45 4e 0a 20 20 20 20 73 61 6d 70 6c 65   THEN.    sample
3610: 2d 6b 65 79 20 2e 64 6f 2d 63 6d 64 2d 6c 6f 6f  -key .do-cmd-loo
3620: 70 20 3b 0a 0a 3a 20 72 65 61 64 2d 6b 65 79 73  p ;..: read-keys
3630: 2d 6c 6f 6f 70 20 28 20 66 64 20 2d 2d 20 29 20  -loop ( fd -- ) 
3640: 20 3e 72 20 30 2e 20 72 40 20 72 65 70 6f 73 69   >r 0. r@ reposi
3650: 74 69 6f 6e 2d 66 69 6c 65 20 74 68 72 6f 77 0a  tion-file throw.
3660: 20 20 20 20 42 45 47 49 4e 0a 09 72 40 20 66 69      BEGIN..r@ fi
3670: 6c 65 2d 70 6f 73 69 74 69 6f 6e 20 74 68 72 6f  le-position thro
3680: 77 20 64 3e 36 34 20 6b 65 79 2d 72 65 61 64 2d  w d>64 key-read-
3690: 6f 66 66 73 65 74 20 36 34 21 0a 09 6b 65 79 70  offset 64!..keyp
36a0: 61 63 6b 20 6b 65 79 70 61 63 6b 2d 61 6c 6c 23  ack keypack-all#
36b0: 20 72 40 20 72 65 61 64 2d 66 69 6c 65 20 74 68   r@ read-file th
36c0: 72 6f 77 0a 09 6b 65 79 70 61 63 6b 2d 61 6c 6c  row..keypack-all
36d0: 23 20 3d 20 57 48 49 4c 45 20 20 74 72 79 2d 64  # = WHILE  try-d
36e0: 65 63 72 79 70 74 20 64 6f 2d 6b 65 79 0a 20 20  ecrypt do-key.  
36f0: 20 20 52 45 50 45 41 54 20 20 72 64 72 6f 70 20    REPEAT  rdrop 
3700: 3b 0a 3a 20 72 65 61 64 2d 6b 65 79 2d 6c 6f 6f  ;.: read-key-loo
3710: 70 20 28 20 2d 2d 20 29 20 3f 6b 65 79 2d 73 66  p ( -- ) ?key-sf
3720: 64 20 72 65 61 64 2d 6b 65 79 73 2d 6c 6f 6f 70  d read-keys-loop
3730: 20 3b 0a 3a 20 72 65 61 64 2d 70 6b 65 79 2d 6c   ;.: read-pkey-l
3740: 6f 6f 70 20 28 20 2d 2d 20 29 20 70 77 2d 6c 65  oop ( -- ) pw-le
3750: 76 65 6c 23 20 3e 72 20 2d 31 20 74 6f 20 70 77  vel# >r -1 to pw
3760: 2d 6c 65 76 65 6c 23 0a 20 20 20 20 3f 6b 65 79  -level#.    ?key
3770: 2d 70 66 64 20 72 65 61 64 2d 6b 65 79 73 2d 6c  -pfd read-keys-l
3780: 6f 6f 70 20 72 3e 20 74 6f 20 70 77 2d 6c 65 76  oop r> to pw-lev
3790: 65 6c 23 20 3b 0a 0a 3a 20 72 65 61 64 2d 6b 65  el# ;..: read-ke
37a0: 79 73 20 28 20 2d 2d 20 29 0a 20 20 20 20 72 65  ys ( -- ).    re
37b0: 61 64 2d 6b 65 79 2d 6c 6f 6f 70 20 72 65 61 64  ad-key-loop read
37c0: 2d 70 6b 65 79 2d 6c 6f 6f 70 20 3b 0a 0a 5c 20  -pkey-loop ;..\ 
37d0: 73 65 6c 65 63 74 20 6b 65 79 20 62 79 20 6e 69  select key by ni
37e0: 63 6b 0a 0a 3a 20 3e 72 61 77 2d 6b 65 79 20 28  ck..: >raw-key (
37f0: 20 6f 20 2d 2d 20 29 0a 20 20 20 20 64 75 70 20   o -- ).    dup 
3800: 30 3d 20 21 21 6e 6f 2d 6e 69 63 6b 21 21 20 3e  0= !!no-nick!! >
3810: 6f 0a 20 20 20 20 6b 65 2d 70 6b 20 24 40 20 70  o.    ke-pk $@ p
3820: 6b 63 20 73 77 61 70 20 70 6b 72 6b 23 20 75 6d  kc swap pkrk# um
3830: 69 6e 20 6d 6f 76 65 0a 20 20 20 20 6b 65 2d 70  in move.    ke-p
3840: 73 6b 20 73 65 63 40 20 6d 79 2d 30 6b 65 79 20  sk sec@ my-0key 
3850: 73 65 63 21 0a 20 20 20 20 6b 65 2d 73 6b 20 73  sec!.    ke-sk s
3860: 65 63 40 20 73 6b 63 20 73 77 61 70 20 6b 65 79  ec@ skc swap key
3870: 73 69 7a 65 20 75 6d 69 6e 20 6d 6f 76 65 0a 20  size umin move. 
3880: 20 20 20 3e 73 6b 73 69 67 20 6f 3e 20 3b 0a 0a     >sksig o> ;..
3890: 3a 20 3e 6b 65 79 20 28 20 61 64 64 72 20 75 20  : >key ( addr u 
38a0: 2d 2d 20 29 0a 20 20 20 20 6b 65 79 2d 74 61 62  -- ).    key-tab
38b0: 6c 65 20 40 20 30 3d 20 49 46 20 20 72 65 61 64  le @ 0= IF  read
38c0: 2d 6b 65 79 73 20 20 54 48 45 4e 0a 20 20 20 20  -keys  THEN.    
38d0: 6e 69 63 6b 2d 6b 65 79 20 3e 72 61 77 2d 6b 65  nick-key >raw-ke
38e0: 79 20 3b 0a 0a 3a 20 69 27 6d 20 28 20 22 6e 61  y ;..: i'm ( "na
38f0: 6d 65 22 20 2d 2d 20 29 20 70 61 72 73 65 2d 6e  me" -- ) parse-n
3900: 61 6d 65 20 3e 6b 65 79 20 3b 0a 3a 20 70 6b 27  ame >key ;.: pk'
3910: 20 28 20 22 6e 61 6d 65 22 20 2d 2d 20 61 64 64   ( "name" -- add
3920: 72 20 75 20 29 0a 20 20 20 20 70 61 72 73 65 2d  r u ).    parse-
3930: 6e 61 6d 65 20 6e 69 63 6b 3e 70 6b 20 3b 0a 0a  name nick>pk ;..
3940: 3a 20 64 65 73 74 2d 6b 65 79 20 28 20 61 64 64  : dest-key ( add
3950: 72 20 75 20 2d 2d 20 29 20 64 75 70 20 30 3d 20  r u -- ) dup 0= 
3960: 49 46 20 20 32 64 72 6f 70 20 20 45 58 49 54 20  IF  2drop  EXIT 
3970: 20 54 48 45 4e 0a 20 20 20 20 6e 69 63 6b 2d 6b   THEN.    nick-k
3980: 65 79 20 3e 6f 20 6f 20 30 3d 20 21 21 75 6e 6b  ey >o o 0= !!unk
3990: 6e 6f 77 6e 2d 6b 65 79 21 21 0a 20 20 20 20 6b  nown-key!!.    k
39a0: 65 2d 70 73 6b 20 73 65 63 40 20 73 74 61 74 65  e-psk sec@ state
39b0: 23 20 75 6d 69 6e 0a 20 20 20 20 6b 65 2d 70 6b  # umin.    ke-pk
39c0: 20 24 40 20 6b 65 79 73 69 7a 65 20 75 6d 69 6e   $@ keysize umin
39d0: 20 6f 3e 0a 20 20 20 20 64 65 73 74 2d 70 75 62   o>.    dest-pub
39e0: 6b 65 79 20 24 21 20 20 64 65 73 74 2d 30 6b 65  key $!  dest-0ke
39f0: 79 20 73 65 63 21 20 3b 0a 0a 3a 20 72 65 70 6c  y sec! ;..: repl
3a00: 61 63 65 2d 6b 65 79 20 31 20 2f 73 74 72 69 6e  ace-key 1 /strin
3a10: 67 20 7b 20 72 65 76 2d 61 64 64 72 20 75 20 2d  g { rev-addr u -
3a20: 2d 20 6f 20 7d 20 5c 20 72 65 76 6f 63 61 74 69  - o } \ revocati
3a30: 6f 6e 20 74 69 63 6b 65 74 0a 20 20 20 20 6b 65  on ticket.    ke
3a40: 79 28 20 2e 22 20 52 65 70 6c 61 63 65 3a 22 20  y( ." Replace:" 
3a50: 63 72 20 6f 20 63 65 6c 6c 2d 20 30 20 2e 6b 65  cr o cell- 0 .ke
3a60: 79 20 29 0a 20 20 20 20 73 22 20 23 72 65 76 6f  y ).    s" #revo
3a70: 6b 65 64 22 20 64 75 70 20 3e 72 20 6b 65 2d 6e  ked" dup >r ke-n
3a80: 69 63 6b 20 24 2b 21 0a 20 20 20 20 6b 65 2d 6e  ick $+!.    ke-n
3a90: 69 63 6b 20 24 40 20 72 3e 20 2d 20 6b 65 2d 70  ick $@ r> - ke-p
3aa0: 72 6f 66 20 24 40 20 6b 65 2d 70 73 6b 20 73 65  rof $@ ke-psk se
3ab0: 63 40 20 6b 65 2d 73 69 67 73 20 6b 65 2d 74 79  c@ ke-sigs ke-ty
3ac0: 70 65 20 40 0a 20 20 20 20 72 65 76 2d 61 64 64  pe @.    rev-add
3ad0: 72 20 70 6b 72 6b 23 20 6b 65 79 3f 6e 65 77 20  r pkrk# key?new 
3ae0: 3e 6f 0a 20 20 20 20 6b 65 2d 74 79 70 65 20 21  >o.    ke-type !
3af0: 20 5b 3a 20 6b 65 2d 73 69 67 73 20 24 2b 5b 5d   [: ke-sigs $+[]
3b00: 21 20 3b 5d 20 24 5b 5d 6d 61 70 20 6b 65 2d 70  ! ;] $[]map ke-p
3b10: 73 6b 20 73 65 63 21 20 6b 65 2d 70 72 6f 66 20  sk sec! ke-prof 
3b20: 24 21 20 6b 65 2d 6e 69 63 6b 20 24 21 0a 20 20  $! ke-nick $!.  
3b30: 20 20 72 65 76 2d 61 64 64 72 20 70 6b 72 6b 23    rev-addr pkrk#
3b40: 20 6b 65 2d 70 6b 20 24 21 0a 20 20 20 20 72 65   ke-pk $!.    re
3b50: 76 2d 61 64 64 72 20 75 20 2b 20 31 2d 20 64 75  v-addr u + 1- du
3b60: 70 20 63 40 20 32 2a 20 2d 20 24 31 30 20 2d 20  p c@ 2* - $10 - 
3b70: 24 31 30 20 6b 65 2d 73 65 6c 66 73 69 67 20 24  $10 ke-selfsig $
3b80: 21 0a 20 20 20 20 6b 65 79 28 20 2e 22 20 77 69  !.    key( ." wi
3b90: 74 68 3a 22 20 63 72 20 6f 20 63 65 6c 6c 2d 20  th:" cr o cell- 
3ba0: 30 20 2e 6b 65 79 20 29 20 6f 20 6f 3e 20 3b 0a  0 .key ) o o> ;.
3bb0: 0a 3a 20 72 65 6e 65 77 2d 6b 65 79 20 28 20 72  .: renew-key ( r
3bc0: 65 76 61 64 64 72 20 75 31 20 6b 65 79 61 64 64  evaddr u1 keyadd
3bd0: 72 20 75 32 20 2d 2d 20 6f 20 29 0a 20 20 20 20  r u2 -- o ).    
3be0: 63 75 72 72 65 6e 74 2d 6b 65 79 20 3e 6f 20 72  current-key >o r
3bf0: 65 70 6c 61 63 65 2d 6b 65 79 20 6f 3e 0a 20 20  eplace-key o>.  
3c00: 20 20 3e 6f 20 73 6b 63 20 6b 65 79 73 69 7a 65    >o skc keysize
3c10: 20 6b 65 2d 73 6b 20 73 65 63 21 20 6f 20 6f 3e   ke-sk sec! o o>
3c20: 20 3b 0a 0a 5c 20 72 65 76 6f 6b 61 74 69 6f 6e   ;..\ revokation
3c30: 0a 0a 34 20 64 61 74 65 73 69 7a 65 23 20 2b 20  ..4 datesize# + 
3c40: 6b 65 79 73 69 7a 65 20 39 20 2a 20 2b 20 43 6f  keysize 9 * + Co
3c50: 6e 73 74 61 6e 74 20 72 65 76 73 69 7a 65 23 0a  nstant revsize#.
3c60: 0a 56 61 72 69 61 62 6c 65 20 72 65 76 74 6f 6b  .Variable revtok
3c70: 65 6e 0a 0a 3a 20 30 6f 6c 64 6b 65 79 20 28 20  en..: 0oldkey ( 
3c80: 2d 2d 20 29 20 5c 20 70 75 62 6b 65 79 73 20 63  -- ) \ pubkeys c
3c90: 61 6e 20 73 74 61 79 0a 20 20 20 20 6f 6c 64 73  an stay.    olds
3ca0: 6b 63 20 6b 65 79 73 69 7a 65 20 65 72 61 73 65  kc keysize erase
3cb0: 20 20 6f 6c 64 73 6b 72 65 76 20 6b 65 79 73 69    oldskrev keysi
3cc0: 7a 65 20 65 72 61 73 65 20 3b 0a 0a 3a 20 6b 65  ze erase ;..: ke
3cd0: 79 6d 6f 76 65 20 28 20 61 64 64 72 31 20 61 64  ymove ( addr1 ad
3ce0: 64 72 32 20 2d 2d 20 29 20 20 6b 65 79 73 69 7a  dr2 -- )  keysiz
3cf0: 65 20 6d 6f 76 65 20 3b 0a 0a 3a 20 72 65 76 6f  e move ;..: revo
3d00: 6b 65 2d 76 65 72 69 66 79 20 28 20 61 64 64 72  ke-verify ( addr
3d10: 20 75 31 20 70 6b 20 73 74 72 69 6e 67 20 75 32   u1 pk string u2
3d20: 20 2d 2d 20 61 64 64 72 20 75 20 66 6c 61 67 20   -- addr u flag 
3d30: 29 20 72 6f 74 20 3e 72 20 32 3e 72 20 63 3a 30  ) rot >r 2>r c:0
3d40: 6b 65 79 0a 20 20 20 20 73 69 67 6f 6e 6c 79 73  key.    sigonlys
3d50: 69 7a 65 23 20 2d 20 32 64 75 70 20 32 72 3e 20  ize# - 2dup 2r> 
3d60: 3e 6b 65 79 65 64 2d 68 61 73 68 0a 20 20 20 20  >keyed-hash.    
3d70: 73 69 67 64 61 74 65 20 2b 64 61 74 65 0a 20 20  sigdate +date.  
3d80: 20 20 32 64 75 70 20 2b 20 72 3e 20 65 64 2d 76    2dup + r> ed-v
3d90: 65 72 69 66 79 20 3b 0a 0a 3a 20 3e 72 65 76 6f  erify ;..: >revo
3da0: 6b 65 20 28 20 73 6b 72 65 76 20 2d 2d 20 29 20  ke ( skrev -- ) 
3db0: 20 73 6b 72 65 76 20 6b 65 79 6d 6f 76 65 20 20   skrev keymove  
3dc0: 63 68 65 63 6b 2d 72 65 76 3f 20 30 3d 20 21 21  check-rev? 0= !!
3dd0: 6e 6f 74 2d 6d 79 2d 72 65 76 73 6b 21 21 20 3b  not-my-revsk!! ;
3de0: 0a 0a 3a 20 2b 72 65 76 73 69 67 6e 20 28 20 73  ..: +revsign ( s
3df0: 6b 20 70 6b 20 2d 2d 20 29 20 20 73 6b 73 69 67  k pk -- )  sksig
3e00: 20 2d 72 6f 74 20 65 64 2d 73 69 67 6e 20 72 65   -rot ed-sign re
3e10: 76 74 6f 6b 65 6e 20 24 2b 21 20 62 6c 20 72 65  vtoken $+! bl re
3e20: 76 74 6f 6b 65 6e 20 63 24 2b 21 20 3b 0a 0a 3a  vtoken c$+! ;..:
3e30: 20 73 69 67 6e 2d 74 6f 6b 65 6e 2c 20 28 20 73   sign-token, ( s
3e40: 6b 20 70 6b 20 73 74 72 69 6e 67 20 75 32 20 2d  k pk string u2 -
3e50: 2d 20 29 0a 20 20 20 20 63 3a 30 6b 65 79 20 72  - ).    c:0key r
3e60: 65 76 74 6f 6b 65 6e 20 24 40 20 32 73 77 61 70  evtoken $@ 2swap
3e70: 20 3e 6b 65 79 65 64 2d 68 61 73 68 0a 20 20 20   >keyed-hash.   
3e80: 20 73 69 67 64 61 74 65 20 2b 64 61 74 65 20 2b   sigdate +date +
3e90: 72 65 76 73 69 67 6e 20 3b 0a 0a 3a 20 72 65 76  revsign ;..: rev
3ea0: 6f 6b 65 2d 6b 65 79 20 28 20 2d 2d 20 61 64 64  oke-key ( -- add
3eb0: 72 20 75 20 29 0a 20 20 20 20 73 6b 63 20 6f 6c  r u ).    skc ol
3ec0: 64 73 6b 63 20 6b 65 79 6d 6f 76 65 20 20 70 6b  dskc keymove  pk
3ed0: 63 20 6f 6c 64 70 6b 63 20 6b 65 79 6d 6f 76 65  c oldpkc keymove
3ee0: 20 20 73 6b 72 65 76 20 6f 6c 64 73 6b 72 65 76    skrev oldskrev
3ef0: 20 6b 65 79 6d 6f 76 65 0a 20 20 20 20 20 20 20   keymove.       
3f00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3f20: 20 20 20 20 5c 20 62 61 63 6b 75 70 20 6b 65 79      \ backup key
3f30: 73 0a 20 20 20 20 6f 6c 64 73 6b 72 65 76 20 6f  s.    oldskrev o
3f40: 6c 64 70 6b 72 65 76 20 73 6b 3e 70 6b 20 20 20  ldpkrev sk>pk   
3f50: 20 20 20 20 20 20 20 20 20 20 20 20 20 5c 20 67               \ g
3f60: 65 6e 65 72 61 74 65 20 72 65 76 6f 6b 61 74 69  enerate revokati
3f70: 6f 6e 20 70 75 62 6b 65 79 0a 20 20 20 20 67 65  on pubkey.    ge
3f80: 6e 2d 6b 65 79 73 20 20 20 20 20 20 20 20 20 20  n-keys          
3f90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3fa0: 20 20 20 20 20 5c 20 67 65 6e 65 72 61 74 65 20       \ generate 
3fb0: 6e 65 77 20 6b 65 79 73 0a 20 20 20 20 70 6b 63  new keys.    pkc
3fc0: 20 6b 65 79 73 69 7a 65 20 32 2a 20 72 65 76 74   keysize 2* revt
3fd0: 6f 6b 65 6e 20 24 21 20 20 20 20 20 20 20 20 20  oken $!         
3fe0: 20 20 20 20 5c 20 6d 79 20 6e 65 77 20 6b 65 79      \ my new key
3ff0: 0a 20 20 20 20 6f 6c 64 70 6b 72 65 76 20 6b 65  .    oldpkrev ke
4000: 79 73 69 7a 65 20 72 65 76 74 6f 6b 65 6e 20 24  ysize revtoken $
4010: 2b 21 20 20 20 20 20 20 20 20 20 20 5c 20 72 65  +!          \ re
4020: 76 6f 6b 65 20 74 6f 6b 65 6e 0a 20 20 20 20 6f  voke token.    o
4030: 6c 64 73 6b 72 65 76 20 6f 6c 64 70 6b 72 65 76  ldskrev oldpkrev
4040: 20 22 72 65 76 6f 6b 65 22 20 73 69 67 6e 2d 74   "revoke" sign-t
4050: 6f 6b 65 6e 2c 20 5c 20 72 65 76 6f 6b 65 20 73  oken, \ revoke s
4060: 69 67 6e 61 74 75 72 65 0a 20 20 20 20 73 6b 63  ignature.    skc
4070: 20 70 6b 63 20 22 73 65 6c 66 73 69 67 6e 22 20   pkc "selfsign" 
4080: 73 69 67 6e 2d 74 6f 6b 65 6e 2c 20 20 20 20 20  sign-token,     
4090: 20 20 20 20 5c 20 73 65 6c 66 20 73 69 67 6e 65      \ self signe
40a0: 64 20 77 69 74 68 20 6e 65 77 20 6b 65 79 0a 20  d with new key. 
40b0: 20 20 20 22 21 22 20 72 65 76 74 6f 6b 65 6e 20     "!" revtoken 
40c0: 30 20 24 69 6e 73 20 20 20 20 20 20 20 20 20 20  0 $ins          
40d0: 20 20 20 20 20 20 20 20 20 20 5c 20 22 21 22 20            \ "!" 
40e0: 2b 20 6f 6c 64 6b 65 79 6c 65 6e 2b 6e 65 77 6b  + oldkeylen+newk
40f0: 65 79 6c 65 6e 20 74 6f 20 66 6c 61 67 20 72 65  eylen to flag re
4100: 76 6f 6b 61 74 69 6f 6e 0a 20 20 20 20 72 65 76  vokation.    rev
4110: 74 6f 6b 65 6e 20 24 40 20 67 65 6e 3e 68 6f 73  token $@ gen>hos
4120: 74 20 32 64 72 6f 70 20 20 20 20 20 20 20 20 20  t 2drop         
4130: 20 20 20 20 5c 20 73 69 67 6e 20 68 6f 73 74 20      \ sign host 
4140: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 77 69 74 68  information with
4150: 20 6f 6c 64 20 6b 65 79 0a 20 20 20 20 73 69 67   old key.    sig
4160: 64 61 74 65 20 2b 64 61 74 65 20 73 69 67 64 61  date +date sigda
4170: 74 65 20 64 61 74 65 73 69 7a 65 23 20 72 65 76  te datesize# rev
4180: 74 6f 6b 65 6e 20 24 2b 21 0a 20 20 20 20 6f 6c  token $+!.    ol
4190: 64 73 6b 63 20 6f 6c 64 70 6b 63 20 2b 72 65 76  dskc oldpkc +rev
41a0: 73 69 67 6e 0a 20 20 20 20 30 6f 6c 64 6b 65 79  sign.    0oldkey
41b0: 20 72 65 76 74 6f 6b 65 6e 20 24 40 20 3b 0a 0a   revtoken $@ ;..
41c0: 30 20 5b 49 46 5d 0a 4c 6f 63 61 6c 20 56 61 72  0 [IF].Local Var
41d0: 69 61 62 6c 65 73 3a 0a 66 6f 72 74 68 2d 6c 6f  iables:.forth-lo
41e0: 63 61 6c 2d 77 6f 72 64 73 3a 0a 20 20 20 20 28  cal-words:.    (
41f0: 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f 3a 22  .     (("net2o:"
4200: 20 22 2b 6e 65 74 32 6f 3a 22 29 20 64 65 66 69   "+net2o:") defi
4210: 6e 69 74 69 6f 6e 2d 73 74 61 72 74 65 72 20 28  nition-starter (
4220: 66 6f 6e 74 2d 6c 6f 63 6b 2d 6b 65 79 77 6f 72  font-lock-keywor
4230: 64 2d 66 61 63 65 20 2e 20 31 29 0a 20 20 20 20  d-face . 1).    
4240: 20 20 22 5b 20 5c 74 5c 6e 5d 22 20 74 20 6e 61    "[ \t\n]" t na
4250: 6d 65 20 28 66 6f 6e 74 2d 6c 6f 63 6b 2d 66 75  me (font-lock-fu
4260: 6e 63 74 69 6f 6e 2d 6e 61 6d 65 2d 66 61 63 65  nction-name-face
4270: 20 2e 20 33 29 29 0a 20 20 20 20 20 28 28 22 64   . 3)).     (("d
4280: 65 62 75 67 3a 22 20 22 66 69 65 6c 64 3a 22 20  ebug:" "field:" 
4290: 22 32 66 69 65 6c 64 3a 22 20 22 73 66 66 69 65  "2field:" "sffie
42a0: 6c 64 3a 22 20 22 64 66 66 69 65 6c 64 3a 22 20  ld:" "dffield:" 
42b0: 22 36 34 66 69 65 6c 64 3a 22 20 22 75 76 61 72  "64field:" "uvar
42c0: 22 20 22 75 76 61 6c 75 65 22 29 20 6e 6f 6e 2d  " "uvalue") non-
42d0: 69 6d 6d 65 64 69 61 74 65 20 28 66 6f 6e 74 2d  immediate (font-
42e0: 6c 6f 63 6b 2d 74 79 70 65 2d 66 61 63 65 20 2e  lock-type-face .
42f0: 20 32 29 0a 20 20 20 20 20 20 22 5b 20 5c 74 5c   2).      "[ \t\
4300: 6e 5d 22 20 74 20 6e 61 6d 65 20 28 66 6f 6e 74  n]" t name (font
4310: 2d 6c 6f 63 6b 2d 76 61 72 69 61 62 6c 65 2d 6e  -lock-variable-n
4320: 61 6d 65 2d 66 61 63 65 20 2e 20 33 29 29 0a 20  ame-face . 3)). 
4330: 20 20 20 20 28 22 5b 61 2d 7a 30 2d 39 5d 2b 28      ("[a-z0-9]+(
4340: 22 20 69 6d 6d 65 64 69 61 74 65 20 28 66 6f 6e  " immediate (fon
4350: 74 2d 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e 74 2d 66  t-lock-comment-f
4360: 61 63 65 20 2e 20 31 29 0a 20 20 20 20 20 20 22  ace . 1).      "
4370: 29 22 20 6e 69 6c 20 63 6f 6d 6d 65 6e 74 20 28  )" nil comment (
4380: 66 6f 6e 74 2d 6c 6f 63 6b 2d 63 6f 6d 6d 65 6e  font-lock-commen
4390: 74 2d 66 61 63 65 20 2e 20 31 29 29 0a 20 20 20  t-face . 1)).   
43a0: 20 29 0a 66 6f 72 74 68 2d 6c 6f 63 61 6c 2d 69   ).forth-local-i
43b0: 6e 64 65 6e 74 2d 77 6f 72 64 73 3a 0a 20 20 20  ndent-words:.   
43c0: 20 28 0a 20 20 20 20 20 28 28 22 6e 65 74 32 6f   (.     (("net2o
43d0: 3a 22 20 22 2b 6e 65 74 32 6f 3a 22 29 20 28 30  :" "+net2o:") (0
43e0: 20 2e 20 32 29 20 28 30 20 2e 20 32 29 20 6e 6f   . 2) (0 . 2) no
43f0: 6e 2d 69 6d 6d 65 64 69 61 74 65 29 0a 20 20 20  n-immediate).   
4400: 20 20 28 28 22 5b 3a 22 20 22 6b 65 79 3a 63 6f    (("[:" "key:co
4410: 64 65 22 29 20 28 30 20 2e 20 31 29 20 28 30 20  de") (0 . 1) (0 
4420: 2e 20 31 29 20 69 6d 6d 65 64 69 61 74 65 29 0a  . 1) immediate).
4430: 20 20 20 20 20 28 28 22 3b 5d 22 20 22 65 6e 64       ((";]" "end
4440: 3a 6b 65 79 22 29 20 28 2d 31 20 2e 20 30 29 20  :key") (-1 . 0) 
4450: 28 30 20 2e 20 2d 31 29 20 69 6d 6d 65 64 69 61  (0 . -1) immedia
4460: 74 65 29 0a 20 20 20 20 29 0a 45 6e 64 3a 0a 5b  te).    ).End:.[
4470: 54 48 45 4e 5d                                   THEN]