# <20180324.1823.27>

# This file provides encryption / decryption of passwords that appear in the
# config file.  We use a rather simple and easy to crack system as we
# are attempting to make it, at least, not obvious what the real password is.
# We do NOT attempt to use any sort of thing that would get us in trouble with
# the export/import authorities.
#
# Warning: Passwords with tabs will be miss handled.

proc encrypt {key value} {
  set keyln [string length $key]
  set value "$value "
  # Replace each " " with a variable length sequence of tabs
  while {[regsub { } $value "[string repeat \t [expr {1 + int(10 * rand())}]]" value]} {}
  set valueln [string length $value]
  while { [string length $key] < $valueln } {
    set key $key$key
  }
  frputs valueln value
  set result ">>"
  set value [string reverse $value]
  set key   [string reverse $key]
  for {incr c 0} {$c < $valueln} {incr c} {
    lappend result  [expr {[scan [string index $key $c] %c] ^ \
			     [scan [string index $value $c] %c]}]
  }
  return [lappend result "<<"]
}

proc decrypt {key value} {
  set value [lrange $value 1 end-1]
  set vln [llength $value]
  while { [string length $key] < $vln } {
    set key $key$key
  }
  set result {}
  set key [string reverse $key]
  for {incr c 0} {$c < $vln} {incr c} {
    append result [format %c [expr {[scan [string index $key $c] %c] ^ \
					[lindex $value $c]}]]
  }
  set fr [regsub -all  {***:\t+} [string reverse $result] { }]
  # Here we remove the trailing blank we put in above...
  # Prior versions did not add the blank so we make this conditional
  # for backward compatability
  if {[string index $fr end] == " "} {
    return [string range $fr 0 end-1]
  }
  return $fr
}
