Hex Artifact Content

Artifact a8b3b2afbe8e774fff6e8f6d8d98fb61ffc3734c:


0000: 23 20 73 68 61 31 2e 74 63 6c 20 2d 20 0a 0a 23  # sha1.tcl - ..#
0010: 20 40 40 20 4d 65 74 61 20 42 65 67 69 6e 0a 23   @@ Meta Begin.#
0020: 20 50 61 63 6b 61 67 65 20 73 68 61 31 20 32 2e   Package sha1 2.
0030: 30 2e 33 0a 23 20 4d 65 74 61 20 70 6c 61 74 66  0.3.# Meta platf
0040: 6f 72 6d 20 20 20 20 20 20 20 20 20 20 20 74 63  orm           tc
0050: 6c 0a 23 20 4d 65 74 61 20 72 73 6b 3a 3a 62 75  l.# Meta rsk::bu
0060: 69 6c 64 3a 3a 64 61 74 65 20 20 20 32 30 31 31  ild::date   2011
0070: 2d 30 33 2d 33 30 0a 23 20 4d 65 74 61 20 64 65  -03-30.# Meta de
0080: 73 63 72 69 70 74 69 6f 6e 20 20 20 20 20 20 20  scription       
0090: 20 50 61 72 74 20 6f 66 20 74 68 65 20 54 63 6c   Part of the Tcl
00a0: 69 62 20 73 68 61 31 20 6d 6f 64 75 6c 65 0a 23  ib sha1 module.#
00b0: 20 4d 65 74 61 20 72 65 71 75 69 72 65 20 20 20   Meta require   
00c0: 20 20 20 20 20 20 20 20 20 7b 54 63 6c 20 38 2e           {Tcl 8.
00d0: 32 7d 0a 23 20 40 40 20 4d 65 74 61 20 45 6e 64  2}.# @@ Meta End
00e0: 0a 0a 23 0a 23 20 43 6f 70 79 72 69 67 68 74 20  ..#.# Copyright 
00f0: 28 43 29 20 32 30 30 31 20 44 6f 6e 20 4c 69 62  (C) 2001 Don Lib
0100: 65 73 20 3c 6c 69 62 65 73 40 6e 69 73 74 2e 67  es <libes@nist.g
0110: 6f 76 3e 0a 23 20 43 6f 70 79 72 69 67 68 74 20  ov>.# Copyright 
0120: 28 43 29 20 32 30 30 33 20 50 61 74 20 54 68 6f  (C) 2003 Pat Tho
0130: 79 74 73 20 3c 70 61 74 74 68 6f 79 74 73 40 75  yts <patthoyts@u
0140: 73 65 72 73 2e 73 6f 75 72 63 65 66 6f 72 67 65  sers.sourceforge
0150: 2e 6e 65 74 3e 0a 23 0a 23 20 53 48 41 31 20 64  .net>.#.# SHA1 d
0160: 65 66 69 6e 65 64 20 62 79 20 46 49 50 53 20 31  efined by FIPS 1
0170: 38 30 2d 31 2c 20 22 54 68 65 20 53 48 41 31 20  80-1, "The SHA1 
0180: 4d 65 73 73 61 67 65 2d 44 69 67 65 73 74 20 41  Message-Digest A
0190: 6c 67 6f 72 69 74 68 6d 22 0a 23 20 48 4d 41 43  lgorithm".# HMAC
01a0: 20 64 65 66 69 6e 65 64 20 62 79 20 52 46 43 20   defined by RFC 
01b0: 32 31 30 34 2c 20 22 4b 65 79 65 64 2d 48 61 73  2104, "Keyed-Has
01c0: 68 69 6e 67 20 66 6f 72 20 4d 65 73 73 61 67 65  hing for Message
01d0: 20 41 75 74 68 65 6e 74 69 63 61 74 69 6f 6e 22   Authentication"
01e0: 0a 23 0a 23 20 54 68 69 73 20 69 73 20 61 6e 20  .#.# This is an 
01f0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  implementation o
0200: 66 20 53 48 41 31 20 62 61 73 65 64 20 75 70 6f  f SHA1 based upo
0210: 6e 20 74 68 65 20 65 78 61 6d 70 6c 65 20 63 6f  n the example co
0220: 64 65 20 67 69 76 65 6e 20 69 6e 0a 23 20 46 49  de given in.# FI
0230: 50 53 20 31 38 30 2d 31 20 61 6e 64 20 75 70 6f  PS 180-1 and upo
0240: 6e 20 74 68 65 20 74 63 6c 6c 69 62 20 4d 44 34  n the tcllib MD4
0250: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
0260: 61 6e 64 20 74 61 6b 69 6e 67 20 73 6f 6d 65 20  and taking some 
0270: 69 64 65 61 73 0a 23 20 61 6e 64 20 6d 65 74 68  ideas.# and meth
0280: 6f 64 73 20 66 72 6f 6d 20 74 68 65 20 65 61 72  ods from the ear
0290: 6c 69 65 72 20 74 63 6c 6c 69 62 20 73 68 61 31  lier tcllib sha1
02a0: 20 76 65 72 73 69 6f 6e 20 62 79 20 44 6f 6e 20   version by Don 
02b0: 4c 69 62 65 73 2e 0a 23 0a 23 20 54 68 69 73 20  Libes..#.# This 
02c0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 70  implementation p
02d0: 65 72 6d 69 74 73 20 69 6e 63 72 65 6d 65 6e 74  ermits increment
02e0: 61 6c 20 75 70 64 61 74 69 6e 67 20 6f 66 20 74  al updating of t
02f0: 68 65 20 68 61 73 68 20 61 6e 64 20 0a 23 20 70  he hash and .# p
0300: 72 6f 76 69 64 65 73 20 73 75 70 70 6f 72 74 20  rovides support 
0310: 66 6f 72 20 65 78 74 65 72 6e 61 6c 20 63 6f 6d  for external com
0320: 70 69 6c 65 64 20 69 6d 70 6c 65 6d 65 6e 74 61  piled implementa
0330: 74 69 6f 6e 73 20 65 69 74 68 65 72 20 75 73 69  tions either usi
0340: 6e 67 0a 23 20 63 72 69 74 63 6c 20 28 73 68 61  ng.# critcl (sha
0350: 31 63 29 20 6f 72 20 54 72 66 2e 0a 23 0a 23 20  1c) or Trf..#.# 
0360: 72 65 66 3a 20 68 74 74 70 3a 2f 2f 77 77 77 2e  ref: http://www.
0370: 69 74 6c 2e 6e 69 73 74 2e 67 6f 76 2f 66 69 70  itl.nist.gov/fip
0380: 73 70 75 62 73 2f 66 69 70 31 38 30 2d 31 2e 68  spubs/fip180-1.h
0390: 74 6d 0a 23 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d  tm.#.# ---------
03a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
03e0: 0a 23 20 53 65 65 20 74 68 65 20 66 69 6c 65 20  .# See the file 
03f0: 22 6c 69 63 65 6e 73 65 2e 74 65 72 6d 73 22 20  "license.terms" 
0400: 66 6f 72 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  for information 
0410: 6f 6e 20 75 73 61 67 65 20 61 6e 64 20 72 65 64  on usage and red
0420: 69 73 74 72 69 62 75 74 69 6f 6e 0a 23 20 6f 66  istribution.# of
0430: 20 74 68 69 73 20 66 69 6c 65 2c 20 61 6e 64 20   this file, and 
0440: 66 6f 72 20 61 20 44 49 53 43 4c 41 49 4d 45 52  for a DISCLAIMER
0450: 20 4f 46 20 41 4c 4c 20 57 41 52 52 41 4e 54 49   OF ALL WARRANTI
0460: 45 53 2e 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ES..# ----------
0470: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0480: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0490: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
04a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
04b0: 23 0a 23 20 24 49 64 3a 20 73 68 61 31 2e 74 63  #.# $Id: sha1.tc
04c0: 6c 2c 76 20 31 2e 32 32 20 32 30 30 39 2f 30 35  l,v 1.22 2009/05
04d0: 2f 30 37 20 30 30 3a 33 35 3a 31 30 20 70 61 74  /07 00:35:10 pat
04e0: 74 68 6f 79 74 73 20 45 78 70 20 24 0a 0a 23 20  thoyts Exp $..# 
04f0: 40 6d 64 67 65 6e 20 45 58 43 4c 55 44 45 3a 20  @mdgen EXCLUDE: 
0500: 73 68 61 31 63 2e 74 63 6c 0a 0a 70 61 63 6b 61  sha1c.tcl..packa
0510: 67 65 20 72 65 71 75 69 72 65 20 54 63 6c 20 38  ge require Tcl 8
0520: 2e 32 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  .2;             
0530: 20 20 20 23 20 74 63 6c 20 6d 69 6e 69 6d 75 6d     # tcl minimum
0540: 20 76 65 72 73 69 6f 6e 0a 0a 6e 61 6d 65 73 70   version..namesp
0550: 61 63 65 20 65 76 61 6c 20 3a 3a 73 68 61 31 20  ace eval ::sha1 
0560: 7b 0a 20 20 20 20 76 61 72 69 61 62 6c 65 20 20  {.    variable  
0570: 76 65 72 73 69 6f 6e 20 32 2e 30 2e 33 0a 20 20  version 2.0.3.  
0580: 20 20 6e 61 6d 65 73 70 61 63 65 20 65 78 70 6f    namespace expo
0590: 72 74 20 73 68 61 31 20 68 6d 61 63 20 53 48 41  rt sha1 hmac SHA
05a0: 31 49 6e 69 74 20 53 48 41 31 55 70 64 61 74 65  1Init SHA1Update
05b0: 20 53 48 41 31 46 69 6e 61 6c 0a 20 20 20 20 76   SHA1Final.    v
05c0: 61 72 69 61 62 6c 65 20 75 69 64 0a 20 20 20 20  ariable uid.    
05d0: 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69 73 74  if {![info exist
05e0: 73 20 75 69 64 5d 7d 20 7b 0a 20 20 20 20 20 20  s uid]} {.      
05f0: 20 20 73 65 74 20 75 69 64 20 30 0a 20 20 20 20    set uid 0.    
0600: 7d 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 73 68 61 31  }.}..proc ::sha1
0610: 3a 3a 53 48 41 31 49 6e 69 74 20 7b 7d 20 7b 0a  ::SHA1Init {} {.
0620: 20 20 20 20 76 61 72 69 61 62 6c 65 20 75 69 64      variable uid
0630: 0a 20 20 20 20 73 65 74 20 74 6f 6b 65 6e 20 5b  .    set token [
0640: 6e 61 6d 65 73 70 61 63 65 20 63 75 72 72 65 6e  namespace curren
0650: 74 5d 3a 3a 5b 69 6e 63 72 20 75 69 64 5d 0a 20  t]::[incr uid]. 
0660: 20 20 20 75 70 76 61 72 20 23 30 20 24 74 6f 6b     upvar #0 $tok
0670: 65 6e 20 73 74 61 74 65 0a 0a 20 20 20 20 23 20  en state..    # 
0680: 46 49 50 53 20 31 38 30 2d 31 3a 20 37 20 2d 20  FIPS 180-1: 7 - 
0690: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 68  Initialize the h
06a0: 61 73 68 20 73 74 61 74 65 0a 20 20 20 20 61 72  ash state.    ar
06b0: 72 61 79 20 73 65 74 20 73 74 61 74 65 20 5c 0a  ray set state \.
06c0: 20 20 20 20 20 20 20 20 5b 6c 69 73 74 20 5c 0a          [list \.
06d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 41 20 5b               A [
06e0: 65 78 70 72 20 7b 69 6e 74 28 30 78 36 37 34 35  expr {int(0x6745
06f0: 32 33 30 31 29 7d 5d 20 5c 0a 20 20 20 20 20 20  2301)}] \.      
0700: 20 20 20 20 20 20 20 42 20 5b 65 78 70 72 20 7b         B [expr {
0710: 69 6e 74 28 30 78 45 46 43 44 41 42 38 39 29 7d  int(0xEFCDAB89)}
0720: 5d 20 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ] \.            
0730: 20 43 20 5b 65 78 70 72 20 7b 69 6e 74 28 30 78   C [expr {int(0x
0740: 39 38 42 41 44 43 46 45 29 7d 5d 20 5c 0a 20 20  98BADCFE)}] \.  
0750: 20 20 20 20 20 20 20 20 20 20 20 44 20 5b 65 78             D [ex
0760: 70 72 20 7b 69 6e 74 28 30 78 31 30 33 32 35 34  pr {int(0x103254
0770: 37 36 29 7d 5d 20 5c 0a 20 20 20 20 20 20 20 20  76)}] \.        
0780: 20 20 20 20 20 45 20 5b 65 78 70 72 20 7b 69 6e       E [expr {in
0790: 74 28 30 78 43 33 44 32 45 31 46 30 29 7d 5d 20  t(0xC3D2E1F0)}] 
07a0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 6e  \.             n
07b0: 20 30 20 69 20 22 22 20 5d 0a 20 20 20 20 72 65   0 i "" ].    re
07c0: 74 75 72 6e 20 24 74 6f 6b 65 6e 0a 7d 0a 0a 23  turn $token.}..#
07d0: 20 53 48 41 31 55 70 64 61 74 65 20 2d 2d 0a 23   SHA1Update --.#
07e0: 0a 23 20 20 20 54 68 69 73 20 69 73 20 63 61 6c  .#   This is cal
07f0: 6c 65 64 20 74 6f 20 61 64 64 20 6d 6f 72 65 20  led to add more 
0800: 64 61 74 61 20 69 6e 74 6f 20 74 68 65 20 68 61  data into the ha
0810: 73 68 2e 20 59 6f 75 20 6d 61 79 20 63 61 6c 6c  sh. You may call
0820: 20 74 68 69 73 0a 23 20 20 20 61 73 20 6d 61 6e   this.#   as man
0830: 79 20 74 69 6d 65 73 20 61 73 20 79 6f 75 20 72  y times as you r
0840: 65 71 75 69 72 65 2e 20 4e 6f 74 65 20 74 68 61  equire. Note tha
0850: 74 20 70 61 73 73 69 6e 67 20 69 6e 20 22 41 42  t passing in "AB
0860: 43 22 20 69 73 20 65 71 75 69 76 61 6c 65 6e 74  C" is equivalent
0870: 0a 23 20 20 20 74 6f 20 70 61 73 73 69 6e 67 20  .#   to passing 
0880: 74 68 65 73 65 20 6c 65 74 74 65 72 73 20 69 6e  these letters in
0890: 20 61 73 20 73 65 70 61 72 61 74 65 20 63 61 6c   as separate cal
08a0: 6c 73 20 2d 2d 20 68 65 6e 63 65 20 74 68 69 73  ls -- hence this
08b0: 20 70 72 6f 63 20 0a 23 20 20 20 70 65 72 6d 69   proc .#   permi
08c0: 74 73 20 68 61 73 68 69 6e 67 20 6f 66 20 63 68  ts hashing of ch
08d0: 75 6e 6b 65 64 20 64 61 74 61 0a 23 0a 23 20 20  unked data.#.#  
08e0: 20 49 66 20 77 65 20 68 61 76 65 20 61 20 43 2d   If we have a C-
08f0: 62 61 73 65 64 20 69 6d 70 6c 65 6d 65 6e 74 61  based implementa
0900: 74 69 6f 6e 20 61 76 61 69 6c 61 62 6c 65 2c 20  tion available, 
0910: 74 68 65 6e 20 77 65 20 77 69 6c 6c 20 75 73 65  then we will use
0920: 0a 23 20 20 20 69 74 20 68 65 72 65 20 69 6e 20  .#   it here in 
0930: 70 72 65 66 65 72 65 6e 63 65 20 74 6f 20 74 68  preference to th
0940: 65 20 70 75 72 65 2d 54 63 6c 20 69 6d 70 6c 65  e pure-Tcl imple
0950: 6d 65 6e 74 61 74 69 6f 6e 2e 0a 23 0a 70 72 6f  mentation..#.pro
0960: 63 20 3a 3a 73 68 61 31 3a 3a 53 48 41 31 55 70  c ::sha1::SHA1Up
0970: 64 61 74 65 20 7b 74 6f 6b 65 6e 20 64 61 74 61  date {token data
0980: 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20 23 30  } {.    upvar #0
0990: 20 24 74 6f 6b 65 6e 20 73 74 61 74 65 0a 0a 20   $token state.. 
09a0: 20 20 20 23 20 55 70 64 61 74 65 20 74 68 65 20     # Update the 
09b0: 73 74 61 74 65 20 76 61 6c 75 65 73 0a 20 20 20  state values.   
09c0: 20 69 6e 63 72 20 73 74 61 74 65 28 6e 29 20 5b   incr state(n) [
09d0: 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 64  string length $d
09e0: 61 74 61 5d 0a 20 20 20 20 61 70 70 65 6e 64 20  ata].    append 
09f0: 73 74 61 74 65 28 69 29 20 24 64 61 74 61 0a 0a  state(i) $data..
0a00: 20 20 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20      # Calculate 
0a10: 74 68 65 20 68 61 73 68 20 66 6f 72 20 61 6e 79  the hash for any
0a20: 20 63 6f 6d 70 6c 65 74 65 20 62 6c 6f 63 6b 73   complete blocks
0a30: 0a 20 20 20 20 73 65 74 20 6c 65 6e 20 5b 73 74  .    set len [st
0a40: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 74 61  ring length $sta
0a50: 74 65 28 69 29 5d 0a 20 20 20 20 66 6f 72 20 7b  te(i)].    for {
0a60: 73 65 74 20 6e 20 30 7d 20 7b 28 24 6e 20 2b 20  set n 0} {($n + 
0a70: 36 34 29 20 3c 3d 20 24 6c 65 6e 7d 20 7b 7d 20  64) <= $len} {} 
0a80: 7b 0a 20 20 20 20 20 20 20 20 53 48 41 31 54 72  {.        SHA1Tr
0a90: 61 6e 73 66 6f 72 6d 20 24 74 6f 6b 65 6e 20 5b  ansform $token [
0aa0: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 73 74  string range $st
0ab0: 61 74 65 28 69 29 20 24 6e 20 5b 69 6e 63 72 20  ate(i) $n [incr 
0ac0: 6e 20 36 34 5d 5d 0a 20 20 20 20 7d 0a 0a 20 20  n 64]].    }..  
0ad0: 20 20 23 20 41 64 6a 75 73 74 20 74 68 65 20 73    # Adjust the s
0ae0: 74 61 74 65 20 66 6f 72 20 74 68 65 20 62 6c 6f  tate for the blo
0af0: 63 6b 73 20 63 6f 6d 70 6c 65 74 65 64 2e 0a 20  cks completed.. 
0b00: 20 20 20 73 65 74 20 73 74 61 74 65 28 69 29 20     set state(i) 
0b10: 5b 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 73  [string range $s
0b20: 74 61 74 65 28 69 29 20 24 6e 20 65 6e 64 5d 0a  tate(i) $n end].
0b30: 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a 23 20      return.}..# 
0b40: 53 48 41 31 46 69 6e 61 6c 20 2d 2d 0a 23 0a 23  SHA1Final --.#.#
0b50: 20 20 20 20 54 68 69 73 20 70 72 6f 63 65 64 75      This procedu
0b60: 72 65 20 69 73 20 75 73 65 64 20 74 6f 20 63 6c  re is used to cl
0b70: 6f 73 65 20 74 68 65 20 63 75 72 72 65 6e 74 20  ose the current 
0b80: 68 61 73 68 20 61 6e 64 20 72 65 74 75 72 6e 73  hash and returns
0b90: 20 74 68 65 0a 23 20 20 20 20 68 61 73 68 20 64   the.#    hash d
0ba0: 61 74 61 2e 20 4f 6e 63 65 20 74 68 69 73 20 70  ata. Once this p
0bb0: 72 6f 63 65 64 75 72 65 20 68 61 73 20 62 65 65  rocedure has bee
0bc0: 6e 20 63 61 6c 6c 65 64 20 74 68 65 20 68 61 73  n called the has
0bd0: 68 20 63 6f 6e 74 65 78 74 0a 23 20 20 20 20 69  h context.#    i
0be0: 73 20 66 72 65 65 64 20 61 6e 64 20 63 61 6e 6e  s freed and cann
0bf0: 6f 74 20 62 65 20 75 73 65 64 20 61 67 61 69 6e  ot be used again
0c00: 2e 0a 23 0a 23 20 20 20 20 4e 6f 74 65 20 74 68  ..#.#    Note th
0c10: 61 74 20 74 68 65 20 6f 75 74 70 75 74 20 69 73  at the output is
0c20: 20 31 36 30 20 62 69 74 73 20 72 65 70 72 65 73   160 bits repres
0c30: 65 6e 74 65 64 20 61 73 20 62 69 6e 61 72 79 20  ented as binary 
0c40: 64 61 74 61 2e 0a 23 0a 70 72 6f 63 20 3a 3a 73  data..#.proc ::s
0c50: 68 61 31 3a 3a 53 48 41 31 46 69 6e 61 6c 20 7b  ha1::SHA1Final {
0c60: 74 6f 6b 65 6e 7d 20 7b 0a 20 20 20 20 75 70 76  token} {.    upv
0c70: 61 72 20 23 30 20 24 74 6f 6b 65 6e 20 73 74 61  ar #0 $token sta
0c80: 74 65 0a 0a 20 20 20 20 23 20 50 61 64 64 69 6e  te..    # Paddin
0c90: 67 0a 20 20 20 20 23 0a 20 20 20 20 73 65 74 20  g.    #.    set 
0ca0: 6c 65 6e 20 5b 73 74 72 69 6e 67 20 6c 65 6e 67  len [string leng
0cb0: 74 68 20 24 73 74 61 74 65 28 69 29 5d 0a 20 20  th $state(i)].  
0cc0: 20 20 73 65 74 20 70 61 64 20 5b 65 78 70 72 20    set pad [expr 
0cd0: 7b 35 36 20 2d 20 28 24 6c 65 6e 20 25 20 36 34  {56 - ($len % 64
0ce0: 29 7d 5d 0a 20 20 20 20 69 66 20 7b 24 6c 65 6e  )}].    if {$len
0cf0: 20 25 20 36 34 20 3e 20 35 36 7d 20 7b 0a 20 20   % 64 > 56} {.  
0d00: 20 20 20 20 20 20 69 6e 63 72 20 70 61 64 20 36        incr pad 6
0d10: 34 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 20 7b  4.    }.    if {
0d20: 24 70 61 64 20 3d 3d 20 30 7d 20 7b 0a 20 20 20  $pad == 0} {.   
0d30: 20 20 20 20 20 69 6e 63 72 20 70 61 64 20 36 34       incr pad 64
0d40: 0a 20 20 20 20 7d 0a 20 20 20 20 61 70 70 65 6e  .    }.    appen
0d50: 64 20 73 74 61 74 65 28 69 29 20 5b 62 69 6e 61  d state(i) [bina
0d60: 72 79 20 66 6f 72 6d 61 74 20 61 24 70 61 64 20  ry format a$pad 
0d70: 5c 78 38 30 5d 0a 0a 20 20 20 20 23 20 41 70 70  \x80]..    # App
0d80: 65 6e 64 20 6c 65 6e 67 74 68 20 69 6e 20 62 69  end length in bi
0d90: 74 73 20 61 73 20 62 69 67 2d 65 6e 64 69 61 6e  ts as big-endian
0da0: 20 77 69 64 65 20 69 6e 74 2e 0a 20 20 20 20 73   wide int..    s
0db0: 65 74 20 64 6c 65 6e 20 5b 65 78 70 72 20 7b 38  et dlen [expr {8
0dc0: 20 2a 20 24 73 74 61 74 65 28 6e 29 7d 5d 0a 20   * $state(n)}]. 
0dd0: 20 20 20 61 70 70 65 6e 64 20 73 74 61 74 65 28     append state(
0de0: 69 29 20 5b 62 69 6e 61 72 79 20 66 6f 72 6d 61  i) [binary forma
0df0: 74 20 49 49 20 30 20 24 64 6c 65 6e 5d 0a 0a 20  t II 0 $dlen].. 
0e00: 20 20 20 23 20 43 61 6c 63 75 6c 61 74 65 20 74     # Calculate t
0e10: 68 65 20 68 61 73 68 20 66 6f 72 20 74 68 65 20  he hash for the 
0e20: 72 65 6d 61 69 6e 69 6e 67 20 62 6c 6f 63 6b 2e  remaining block.
0e30: 0a 20 20 20 20 73 65 74 20 6c 65 6e 20 5b 73 74  .    set len [st
0e40: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 73 74 61  ring length $sta
0e50: 74 65 28 69 29 5d 0a 20 20 20 20 66 6f 72 20 7b  te(i)].    for {
0e60: 73 65 74 20 6e 20 30 7d 20 7b 28 24 6e 20 2b 20  set n 0} {($n + 
0e70: 36 34 29 20 3c 3d 20 24 6c 65 6e 7d 20 7b 7d 20  64) <= $len} {} 
0e80: 7b 0a 20 20 20 20 20 20 20 20 53 48 41 31 54 72  {.        SHA1Tr
0e90: 61 6e 73 66 6f 72 6d 20 24 74 6f 6b 65 6e 20 5b  ansform $token [
0ea0: 73 74 72 69 6e 67 20 72 61 6e 67 65 20 24 73 74  string range $st
0eb0: 61 74 65 28 69 29 20 24 6e 20 5b 69 6e 63 72 20  ate(i) $n [incr 
0ec0: 6e 20 36 34 5d 5d 0a 20 20 20 20 7d 0a 0a 20 20  n 64]].    }..  
0ed0: 20 20 23 20 4f 75 74 70 75 74 0a 20 20 20 20 73    # Output.    s
0ee0: 65 74 20 72 20 5b 62 79 74 65 73 20 24 73 74 61  et r [bytes $sta
0ef0: 74 65 28 41 29 5d 5b 62 79 74 65 73 20 24 73 74  te(A)][bytes $st
0f00: 61 74 65 28 42 29 5d 5b 62 79 74 65 73 20 24 73  ate(B)][bytes $s
0f10: 74 61 74 65 28 43 29 5d 5b 62 79 74 65 73 20 24  tate(C)][bytes $
0f20: 73 74 61 74 65 28 44 29 5d 5b 62 79 74 65 73 20  state(D)][bytes 
0f30: 24 73 74 61 74 65 28 45 29 5d 0a 20 20 20 20 75  $state(E)].    u
0f40: 6e 73 65 74 20 73 74 61 74 65 0a 20 20 20 20 72  nset state.    r
0f50: 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20 2d 2d  eturn $r.}..# --
0f60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0f70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0f80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0f90: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
0fa0: 2d 2d 2d 2d 2d 2d 2d 0a 23 20 48 4d 41 43 20 48  -------.# HMAC H
0fb0: 61 73 68 65 64 20 4d 65 73 73 61 67 65 20 41 75  ashed Message Au
0fc0: 74 68 65 6e 74 69 63 61 74 69 6f 6e 20 28 52 46  thentication (RF
0fd0: 43 20 32 31 30 34 29 0a 23 0a 23 20 68 6d 61 63  C 2104).#.# hmac
0fe0: 20 3d 20 48 28 4b 20 78 6f 72 20 6f 70 61 64 2c   = H(K xor opad,
0ff0: 20 48 28 4b 20 78 6f 72 20 69 70 61 64 2c 20 74   H(K xor ipad, t
1000: 65 78 74 29 29 0a 23 0a 0a 23 20 48 4d 41 43 49  ext)).#..# HMACI
1010: 6e 69 74 20 2d 2d 0a 23 0a 23 20 20 20 20 54 68  nit --.#.#    Th
1020: 69 73 20 69 73 20 65 71 75 69 76 61 6c 65 6e 74  is is equivalent
1030: 20 74 6f 20 74 68 65 20 53 48 41 31 49 6e 69 74   to the SHA1Init
1040: 20 70 72 6f 63 65 64 75 72 65 20 65 78 63 65 70   procedure excep
1050: 74 20 74 68 61 74 20 61 20 6b 65 79 20 69 73 0a  t that a key is.
1060: 23 20 20 20 20 61 64 64 65 64 20 69 6e 74 6f 20  #    added into 
1070: 74 68 65 20 61 6c 67 6f 72 69 74 68 6d 0a 23 0a  the algorithm.#.
1080: 70 72 6f 63 20 3a 3a 73 68 61 31 3a 3a 48 4d 41  proc ::sha1::HMA
1090: 43 49 6e 69 74 20 7b 4b 7d 20 7b 0a 0a 20 20 20  CInit {K} {..   
10a0: 20 23 20 4b 65 79 20 4b 20 69 73 20 61 64 6a 75   # Key K is adju
10b0: 73 74 65 64 20 74 6f 20 62 65 20 36 34 20 62 79  sted to be 64 by
10c0: 74 65 73 20 6c 6f 6e 67 2e 20 49 66 20 4b 20 69  tes long. If K i
10d0: 73 20 6c 61 72 67 65 72 2c 20 74 68 65 6e 20 75  s larger, then u
10e0: 73 65 0a 20 20 20 20 23 20 74 68 65 20 53 48 41  se.    # the SHA
10f0: 31 20 64 69 67 65 73 74 20 6f 66 20 4b 20 61 6e  1 digest of K an
1100: 64 20 70 61 64 20 74 68 69 73 20 69 6e 73 74 65  d pad this inste
1110: 61 64 2e 0a 20 20 20 20 73 65 74 20 6c 65 6e 20  ad..    set len 
1120: 5b 73 74 72 69 6e 67 20 6c 65 6e 67 74 68 20 24  [string length $
1130: 4b 5d 0a 20 20 20 20 69 66 20 7b 24 6c 65 6e 20  K].    if {$len 
1140: 3e 20 36 34 7d 20 7b 0a 20 20 20 20 20 20 20 20  > 64} {.        
1150: 73 65 74 20 74 6f 6b 20 5b 53 48 41 31 49 6e 69  set tok [SHA1Ini
1160: 74 5d 0a 20 20 20 20 20 20 20 20 53 48 41 31 55  t].        SHA1U
1170: 70 64 61 74 65 20 24 74 6f 6b 20 24 4b 0a 20 20  pdate $tok $K.  
1180: 20 20 20 20 20 20 73 65 74 20 4b 20 5b 53 48 41        set K [SHA
1190: 31 46 69 6e 61 6c 20 24 74 6f 6b 5d 0a 20 20 20  1Final $tok].   
11a0: 20 20 20 20 20 73 65 74 20 6c 65 6e 20 5b 73 74       set len [st
11b0: 72 69 6e 67 20 6c 65 6e 67 74 68 20 24 4b 5d 0a  ring length $K].
11c0: 20 20 20 20 7d 0a 20 20 20 20 73 65 74 20 70 61      }.    set pa
11d0: 64 20 5b 65 78 70 72 20 7b 36 34 20 2d 20 24 6c  d [expr {64 - $l
11e0: 65 6e 7d 5d 0a 20 20 20 20 61 70 70 65 6e 64 20  en}].    append 
11f0: 4b 20 5b 73 74 72 69 6e 67 20 72 65 70 65 61 74  K [string repeat
1200: 20 5c 30 20 24 70 61 64 5d 0a 0a 20 20 20 20 23   \0 $pad]..    #
1210: 20 43 61 63 6c 75 61 74 65 20 74 68 65 20 70 61   Cacluate the pa
1220: 64 64 69 6e 67 20 62 75 66 66 65 72 73 2e 0a 20  dding buffers.. 
1230: 20 20 20 73 65 74 20 4b 69 20 7b 7d 0a 20 20 20     set Ki {}.   
1240: 20 73 65 74 20 4b 6f 20 7b 7d 0a 20 20 20 20 62   set Ko {}.    b
1250: 69 6e 61 72 79 20 73 63 61 6e 20 24 4b 20 69 31  inary scan $K i1
1260: 36 20 4b 73 0a 20 20 20 20 66 6f 72 65 61 63 68  6 Ks.    foreach
1270: 20 6b 20 24 4b 73 20 7b 0a 20 20 20 20 20 20 20   k $Ks {.       
1280: 20 61 70 70 65 6e 64 20 4b 69 20 5b 62 69 6e 61   append Ki [bina
1290: 72 79 20 66 6f 72 6d 61 74 20 69 20 5b 65 78 70  ry format i [exp
12a0: 72 20 7b 24 6b 20 5e 20 30 78 33 36 33 36 33 36  r {$k ^ 0x363636
12b0: 33 36 7d 5d 5d 0a 20 20 20 20 20 20 20 20 61 70  36}]].        ap
12c0: 70 65 6e 64 20 4b 6f 20 5b 62 69 6e 61 72 79 20  pend Ko [binary 
12d0: 66 6f 72 6d 61 74 20 69 20 5b 65 78 70 72 20 7b  format i [expr {
12e0: 24 6b 20 5e 20 30 78 35 63 35 63 35 63 35 63 7d  $k ^ 0x5c5c5c5c}
12f0: 5d 5d 0a 20 20 20 20 7d 0a 0a 20 20 20 20 73 65  ]].    }..    se
1300: 74 20 74 6f 6b 20 5b 53 48 41 31 49 6e 69 74 5d  t tok [SHA1Init]
1310: 0a 20 20 20 20 53 48 41 31 55 70 64 61 74 65 20  .    SHA1Update 
1320: 24 74 6f 6b 20 24 4b 69 3b 20 20 20 20 20 20 20  $tok $Ki;       
1330: 20 20 20 20 20 20 20 20 20 20 23 20 69 6e 69 74            # init
1340: 69 61 6c 69 7a 65 20 77 69 74 68 20 74 68 65 20  ialize with the 
1350: 69 6e 6e 65 72 20 70 61 64 0a 20 20 20 20 0a 20  inner pad.    . 
1360: 20 20 20 23 20 70 72 65 73 65 72 76 65 20 74 68     # preserve th
1370: 65 20 4b 6f 20 76 61 6c 75 65 20 66 6f 72 20 74  e Ko value for t
1380: 68 65 20 66 69 6e 61 6c 20 73 74 61 67 65 2e 0a  he final stage..
1390: 20 20 20 20 23 20 46 52 49 4e 4b 3a 20 6e 6f 63      # FRINK: noc
13a0: 68 65 63 6b 0a 20 20 20 20 73 65 74 20 5b 73 75  heck.    set [su
13b0: 62 73 74 20 24 74 6f 6b 5d 28 4b 6f 29 20 24 4b  bst $tok](Ko) $K
13c0: 6f 0a 0a 20 20 20 20 72 65 74 75 72 6e 20 24 74  o..    return $t
13d0: 6f 6b 0a 7d 0a 0a 23 20 48 4d 41 43 55 70 64 61  ok.}..# HMACUpda
13e0: 74 65 20 2d 2d 0a 23 0a 23 20 20 20 20 49 64 65  te --.#.#    Ide
13f0: 6e 74 69 63 61 6c 20 74 6f 20 63 61 6c 6c 69 6e  ntical to callin
1400: 67 20 53 48 41 31 55 70 64 61 74 65 0a 23 0a 70  g SHA1Update.#.p
1410: 72 6f 63 20 3a 3a 73 68 61 31 3a 3a 48 4d 41 43  roc ::sha1::HMAC
1420: 55 70 64 61 74 65 20 7b 74 6f 6b 65 6e 20 64 61  Update {token da
1430: 74 61 7d 20 7b 0a 20 20 20 20 53 48 41 31 55 70  ta} {.    SHA1Up
1440: 64 61 74 65 20 24 74 6f 6b 65 6e 20 24 64 61 74  date $token $dat
1450: 61 0a 20 20 20 20 72 65 74 75 72 6e 0a 7d 0a 0a  a.    return.}..
1460: 23 20 48 4d 41 43 46 69 6e 61 6c 20 2d 2d 0a 23  # HMACFinal --.#
1470: 0a 23 20 20 20 20 54 68 69 73 20 69 73 20 65 71  .#    This is eq
1480: 75 69 76 61 6c 65 6e 74 20 74 6f 20 74 68 65 20  uivalent to the 
1490: 53 48 41 31 46 69 6e 61 6c 20 70 72 6f 63 65 64  SHA1Final proced
14a0: 75 72 65 2e 20 54 68 65 20 68 61 73 68 20 63 6f  ure. The hash co
14b0: 6e 74 65 78 74 20 69 73 0a 23 20 20 20 20 63 6c  ntext is.#    cl
14c0: 6f 73 65 64 20 61 6e 64 20 74 68 65 20 62 69 6e  osed and the bin
14d0: 61 72 79 20 72 65 70 72 65 73 65 6e 74 61 74 69  ary representati
14e0: 6f 6e 20 6f 66 20 74 68 65 20 68 61 73 68 20 72  on of the hash r
14f0: 65 73 75 6c 74 20 69 73 20 72 65 74 75 72 6e 65  esult is returne
1500: 64 2e 0a 23 0a 70 72 6f 63 20 3a 3a 73 68 61 31  d..#.proc ::sha1
1510: 3a 3a 48 4d 41 43 46 69 6e 61 6c 20 7b 74 6f 6b  ::HMACFinal {tok
1520: 65 6e 7d 20 7b 0a 20 20 20 20 75 70 76 61 72 20  en} {.    upvar 
1530: 23 30 20 24 74 6f 6b 65 6e 20 73 74 61 74 65 0a  #0 $token state.
1540: 0a 20 20 20 20 73 65 74 20 74 6f 6b 20 5b 53 48  .    set tok [SH
1550: 41 31 49 6e 69 74 5d 3b 20 20 20 20 20 20 20 20  A1Init];        
1560: 20 20 20 20 20 20 20 20 20 23 20 69 6e 69 74 20           # init 
1570: 74 68 65 20 6f 75 74 65 72 20 68 61 73 68 69 6e  the outer hashin
1580: 67 20 66 75 6e 63 74 69 6f 6e 0a 20 20 20 20 53  g function.    S
1590: 48 41 31 55 70 64 61 74 65 20 24 74 6f 6b 20 24  HA1Update $tok $
15a0: 73 74 61 74 65 28 4b 6f 29 3b 20 20 20 20 20 20  state(Ko);      
15b0: 20 20 20 23 20 70 72 65 70 61 72 65 20 77 69 74     # prepare wit
15c0: 68 20 74 68 65 20 6f 75 74 65 72 20 70 61 64 2e  h the outer pad.
15d0: 0a 20 20 20 20 53 48 41 31 55 70 64 61 74 65 20  .    SHA1Update 
15e0: 24 74 6f 6b 20 5b 53 48 41 31 46 69 6e 61 6c 20  $tok [SHA1Final 
15f0: 24 74 6f 6b 65 6e 5d 3b 20 23 20 68 61 73 68 20  $token]; # hash 
1600: 74 68 65 20 69 6e 6e 65 72 20 72 65 73 75 6c 74  the inner result
1610: 0a 20 20 20 20 72 65 74 75 72 6e 20 5b 53 48 41  .    return [SHA
1620: 31 46 69 6e 61 6c 20 24 74 6f 6b 5d 0a 7d 0a 0a  1Final $tok].}..
1630: 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  # --------------
1640: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1650: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1660: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
1670: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 44 65  -----------.# De
1680: 73 63 72 69 70 74 69 6f 6e 3a 0a 23 20 20 54 68  scription:.#  Th
1690: 69 73 20 69 73 20 74 68 65 20 63 6f 72 65 20 53  is is the core S
16a0: 48 41 31 20 61 6c 67 6f 72 69 74 68 6d 2e 20 49  HA1 algorithm. I
16b0: 74 20 69 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20  t is a lot like 
16c0: 74 68 65 20 4d 44 34 20 61 6c 67 6f 72 69 74 68  the MD4 algorith
16d0: 6d 20 62 75 74 0a 23 20 20 69 6e 63 6c 75 64 65  m but.#  include
16e0: 73 20 61 6e 20 65 78 74 72 61 20 72 6f 75 6e 64  s an extra round
16f0: 20 61 6e 64 20 61 20 73 65 74 20 6f 66 20 63 6f   and a set of co
1700: 6e 73 74 61 6e 74 20 6d 6f 64 69 66 69 65 72 73  nstant modifiers
1710: 20 74 68 72 6f 75 67 68 6f 75 74 2e 0a 23 0a 73   throughout..#.s
1720: 65 74 20 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54  et ::sha1::SHA1T
1730: 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 20 7b 0a  ransform_body {.
1740: 20 20 20 20 75 70 76 61 72 20 23 30 20 24 74 6f      upvar #0 $to
1750: 6b 65 6e 20 73 74 61 74 65 0a 0a 20 20 20 20 23  ken state..    #
1760: 20 46 49 50 53 20 31 38 30 2d 31 3a 20 37 61 3a   FIPS 180-1: 7a:
1770: 20 50 72 6f 63 65 73 73 20 4d 65 73 73 61 67 65   Process Message
1780: 20 69 6e 20 31 36 2d 57 6f 72 64 20 42 6c 6f 63   in 16-Word Bloc
1790: 6b 73 0a 20 20 20 20 62 69 6e 61 72 79 20 73 63  ks.    binary sc
17a0: 61 6e 20 24 6d 73 67 20 49 2a 20 62 6c 6f 63 6b  an $msg I* block
17b0: 73 0a 20 20 20 20 73 65 74 20 62 6c 6f 63 6b 4c  s.    set blockL
17c0: 65 6e 20 5b 6c 6c 65 6e 67 74 68 20 24 62 6c 6f  en [llength $blo
17d0: 63 6b 73 5d 0a 20 20 20 20 66 6f 72 20 7b 73 65  cks].    for {se
17e0: 74 20 69 20 30 7d 20 7b 24 69 20 3c 20 24 62 6c  t i 0} {$i < $bl
17f0: 6f 63 6b 4c 65 6e 7d 20 7b 69 6e 63 72 20 69 20  ockLen} {incr i 
1800: 31 36 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  16} {.        se
1810: 74 20 57 20 5b 6c 72 61 6e 67 65 20 24 62 6c 6f  t W [lrange $blo
1820: 63 6b 73 20 24 69 20 5b 65 78 70 72 20 7b 24 69  cks $i [expr {$i
1830: 2b 31 35 7d 5d 5d 0a 20 20 20 20 20 20 20 20 0a  +15}]].        .
1840: 20 20 20 20 20 20 20 20 23 20 46 49 50 53 20 31          # FIPS 1
1850: 38 30 2d 31 3a 20 37 62 3a 20 45 78 70 61 6e 64  80-1: 7b: Expand
1860: 20 74 68 65 20 69 6e 70 75 74 20 69 6e 74 6f 20   the input into 
1870: 38 30 20 77 6f 72 64 73 0a 20 20 20 20 20 20 20  80 words.       
1880: 20 23 20 46 6f 72 20 74 20 3d 20 31 36 20 74 6f   # For t = 16 to
1890: 20 37 39 20 0a 20 20 20 20 20 20 20 20 23 20 20   79 .        #  
18a0: 20 6c 65 74 20 57 74 20 3d 20 28 57 74 2d 33 20   let Wt = (Wt-3 
18b0: 5e 20 57 74 2d 38 20 5e 20 57 74 2d 31 34 20 5e  ^ Wt-8 ^ Wt-14 ^
18c0: 20 57 74 2d 31 36 29 20 3c 3c 3c 20 31 0a 20 20   Wt-16) <<< 1.  
18d0: 20 20 20 20 20 20 73 65 74 20 74 33 20 20 31 32        set t3  12
18e0: 0a 20 20 20 20 20 20 20 20 73 65 74 20 74 38 20  .        set t8 
18f0: 20 20 37 0a 20 20 20 20 20 20 20 20 73 65 74 20    7.        set 
1900: 74 31 34 20 20 31 0a 20 20 20 20 20 20 20 20 73  t14  1.        s
1910: 65 74 20 74 31 36 20 2d 31 0a 20 20 20 20 20 20  et t16 -1.      
1920: 20 20 66 6f 72 20 7b 73 65 74 20 74 20 31 36 7d    for {set t 16}
1930: 20 7b 24 74 20 3c 20 38 30 7d 20 7b 69 6e 63 72   {$t < 80} {incr
1940: 20 74 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20   t} {.          
1950: 20 20 73 65 74 20 78 20 5b 65 78 70 72 20 7b 5b    set x [expr {[
1960: 6c 69 6e 64 65 78 20 24 57 20 5b 69 6e 63 72 20  lindex $W [incr 
1970: 74 33 5d 5d 20 5e 20 5b 6c 69 6e 64 65 78 20 24  t3]] ^ [lindex $
1980: 57 20 5b 69 6e 63 72 20 74 38 5d 5d 20 5e 20 5c  W [incr t8]] ^ \
1990: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
19a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c                [l
19b0: 69 6e 64 65 78 20 24 57 20 5b 69 6e 63 72 20 74  index $W [incr t
19c0: 31 34 5d 5d 20 5e 20 5b 6c 69 6e 64 65 78 20 24  14]] ^ [lindex $
19d0: 57 20 5b 69 6e 63 72 20 74 31 36 5d 5d 7d 5d 0a  W [incr t16]]}].
19e0: 20 20 20 20 20 20 20 20 20 20 20 20 6c 61 70 70              lapp
19f0: 65 6e 64 20 57 20 5b 65 78 70 72 20 7b 69 6e 74  end W [expr {int
1a00: 28 28 24 78 20 3c 3c 20 31 29 20 7c 20 28 28 24  (($x << 1) | (($
1a10: 78 20 3e 3e 20 33 31 29 20 26 20 31 29 29 7d 5d  x >> 31) & 1))}]
1a20: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
1a30: 20 20 20 0a 20 20 20 20 20 20 20 20 23 20 46 49     .        # FI
1a40: 50 53 20 31 38 30 2d 31 3a 20 37 63 3a 20 43 6f  PS 180-1: 7c: Co
1a50: 70 79 20 68 61 73 68 20 73 74 61 74 65 2e 0a 20  py hash state.. 
1a60: 20 20 20 20 20 20 20 73 65 74 20 41 20 24 73 74         set A $st
1a70: 61 74 65 28 41 29 0a 20 20 20 20 20 20 20 20 73  ate(A).        s
1a80: 65 74 20 42 20 24 73 74 61 74 65 28 42 29 0a 20  et B $state(B). 
1a90: 20 20 20 20 20 20 20 73 65 74 20 43 20 24 73 74         set C $st
1aa0: 61 74 65 28 43 29 0a 20 20 20 20 20 20 20 20 73  ate(C).        s
1ab0: 65 74 20 44 20 24 73 74 61 74 65 28 44 29 0a 20  et D $state(D). 
1ac0: 20 20 20 20 20 20 20 73 65 74 20 45 20 24 73 74         set E $st
1ad0: 61 74 65 28 45 29 0a 0a 20 20 20 20 20 20 20 20  ate(E)..        
1ae0: 23 20 46 49 50 53 20 31 38 30 2d 31 3a 20 37 64  # FIPS 180-1: 7d
1af0: 3a 20 44 6f 20 70 65 72 6d 75 74 61 74 69 6f 6e  : Do permutation
1b00: 20 72 6f 75 6e 64 73 0a 20 20 20 20 20 20 20 20   rounds.        
1b10: 23 20 46 6f 72 20 74 20 3d 20 30 20 74 6f 20 37  # For t = 0 to 7
1b20: 39 20 64 6f 0a 20 20 20 20 20 20 20 20 23 20 20  9 do.        #  
1b30: 20 54 45 4d 50 20 3d 20 28 41 3c 3c 3c 35 29 20   TEMP = (A<<<5) 
1b40: 2b 20 66 74 28 42 2c 43 2c 44 29 20 2b 20 45 20  + ft(B,C,D) + E 
1b50: 2b 20 57 74 20 2b 20 4b 74 3b 0a 20 20 20 20 20  + Wt + Kt;.     
1b60: 20 20 20 23 20 20 20 45 20 3d 20 44 3b 20 44 20     #   E = D; D 
1b70: 3d 20 43 3b 20 43 20 3d 20 53 33 30 28 42 29 3b  = C; C = S30(B);
1b80: 20 42 20 3d 20 41 3b 20 41 20 3d 20 54 45 4d 50   B = A; A = TEMP
1b90: 3b 0a 0a 20 20 20 20 20 20 20 20 23 20 52 6f 75  ;..        # Rou
1ba0: 6e 64 20 31 3a 20 66 74 28 42 2c 43 2c 44 29 20  nd 1: ft(B,C,D) 
1bb0: 3d 20 28 42 20 26 20 43 29 20 7c 20 28 7e 42 20  = (B & C) | (~B 
1bc0: 26 20 44 29 20 28 20 30 20 3c 3d 20 74 20 3c 3d  & D) ( 0 <= t <=
1bd0: 20 31 39 29 0a 20 20 20 20 20 20 20 20 66 6f 72   19).        for
1be0: 20 7b 73 65 74 20 74 20 30 7d 20 7b 24 74 20 3c   {set t 0} {$t <
1bf0: 20 32 30 7d 20 7b 69 6e 63 72 20 74 7d 20 7b 0a   20} {incr t} {.
1c00: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
1c10: 54 45 4d 50 20 5b 46 31 20 24 41 20 24 42 20 24  TEMP [F1 $A $B $
1c20: 43 20 24 44 20 24 45 20 5b 6c 69 6e 64 65 78 20  C $D $E [lindex 
1c30: 24 57 20 24 74 5d 5d 0a 20 20 20 20 20 20 20 20  $W $t]].        
1c40: 20 20 20 20 73 65 74 20 45 20 24 44 0a 20 20 20      set E $D.   
1c50: 20 20 20 20 20 20 20 20 20 73 65 74 20 44 20 24           set D $
1c60: 43 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65  C.            se
1c70: 74 20 43 20 5b 72 6f 74 6c 33 32 20 24 42 20 33  t C [rotl32 $B 3
1c80: 30 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  0].            s
1c90: 65 74 20 42 20 24 41 0a 20 20 20 20 20 20 20 20  et B $A.        
1ca0: 20 20 20 20 73 65 74 20 41 20 24 54 45 4d 50 0a      set A $TEMP.
1cb0: 20 20 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20          }..     
1cc0: 20 20 20 23 20 52 6f 75 6e 64 20 32 3a 20 66 74     # Round 2: ft
1cd0: 28 42 2c 43 2c 44 29 20 3d 20 28 42 20 5e 20 43  (B,C,D) = (B ^ C
1ce0: 20 5e 20 44 29 20 28 20 32 30 20 3c 3d 20 74 20   ^ D) ( 20 <= t 
1cf0: 3c 3d 20 33 39 29 0a 20 20 20 20 20 20 20 20 66  <= 39).        f
1d00: 6f 72 20 7b 7d 20 7b 24 74 20 3c 20 34 30 7d 20  or {} {$t < 40} 
1d10: 7b 69 6e 63 72 20 74 7d 20 7b 0a 20 20 20 20 20  {incr t} {.     
1d20: 20 20 20 20 20 20 20 73 65 74 20 54 45 4d 50 20         set TEMP 
1d30: 5b 46 32 20 24 41 20 24 42 20 24 43 20 24 44 20  [F2 $A $B $C $D 
1d40: 24 45 20 5b 6c 69 6e 64 65 78 20 24 57 20 24 74  $E [lindex $W $t
1d50: 5d 5d 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  ]].            s
1d60: 65 74 20 45 20 24 44 0a 20 20 20 20 20 20 20 20  et E $D.        
1d70: 20 20 20 20 73 65 74 20 44 20 24 43 0a 20 20 20      set D $C.   
1d80: 20 20 20 20 20 20 20 20 20 73 65 74 20 43 20 5b           set C [
1d90: 72 6f 74 6c 33 32 20 24 42 20 33 30 5d 0a 20 20  rotl32 $B 30].  
1da0: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 42 20            set B 
1db0: 24 41 0a 20 20 20 20 20 20 20 20 20 20 20 20 73  $A.            s
1dc0: 65 74 20 41 20 24 54 45 4d 50 0a 20 20 20 20 20  et A $TEMP.     
1dd0: 20 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 23 20     }..        # 
1de0: 52 6f 75 6e 64 20 33 3a 20 66 74 28 42 2c 43 2c  Round 3: ft(B,C,
1df0: 44 29 20 3d 20 28 28 42 20 26 20 43 29 20 7c 20  D) = ((B & C) | 
1e00: 28 42 20 26 20 44 29 20 7c 20 28 43 20 26 20 44  (B & D) | (C & D
1e10: 29 29 20 28 20 34 30 20 3c 3d 20 74 20 3c 3d 20  )) ( 40 <= t <= 
1e20: 35 39 29 0a 20 20 20 20 20 20 20 20 66 6f 72 20  59).        for 
1e30: 7b 7d 20 7b 24 74 20 3c 20 36 30 7d 20 7b 69 6e  {} {$t < 60} {in
1e40: 63 72 20 74 7d 20 7b 0a 20 20 20 20 20 20 20 20  cr t} {.        
1e50: 20 20 20 20 73 65 74 20 54 45 4d 50 20 5b 46 33      set TEMP [F3
1e60: 20 24 41 20 24 42 20 24 43 20 24 44 20 24 45 20   $A $B $C $D $E 
1e70: 5b 6c 69 6e 64 65 78 20 24 57 20 24 74 5d 5d 0a  [lindex $W $t]].
1e80: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
1e90: 45 20 24 44 0a 20 20 20 20 20 20 20 20 20 20 20  E $D.           
1ea0: 20 73 65 74 20 44 20 24 43 0a 20 20 20 20 20 20   set D $C.      
1eb0: 20 20 20 20 20 20 73 65 74 20 43 20 5b 72 6f 74        set C [rot
1ec0: 6c 33 32 20 24 42 20 33 30 5d 0a 20 20 20 20 20  l32 $B 30].     
1ed0: 20 20 20 20 20 20 20 73 65 74 20 42 20 24 41 0a         set B $A.
1ee0: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20              set 
1ef0: 41 20 24 54 45 4d 50 0a 20 20 20 20 20 20 20 20  A $TEMP.        
1f00: 20 7d 0a 0a 20 20 20 20 20 20 20 20 23 20 52 6f   }..        # Ro
1f10: 75 6e 64 20 34 3a 20 66 74 28 42 2c 43 2c 44 29  und 4: ft(B,C,D)
1f20: 20 3d 20 28 42 20 5e 20 43 20 5e 20 44 29 20 28   = (B ^ C ^ D) (
1f30: 20 36 30 20 3c 3d 20 74 20 3c 3d 20 37 39 29 0a   60 <= t <= 79).
1f40: 20 20 20 20 20 20 20 20 66 6f 72 20 7b 7d 20 7b          for {} {
1f50: 24 74 20 3c 20 38 30 7d 20 7b 69 6e 63 72 20 74  $t < 80} {incr t
1f60: 7d 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  } {.            
1f70: 73 65 74 20 54 45 4d 50 20 5b 46 34 20 24 41 20  set TEMP [F4 $A 
1f80: 24 42 20 24 43 20 24 44 20 24 45 20 5b 6c 69 6e  $B $C $D $E [lin
1f90: 64 65 78 20 24 57 20 24 74 5d 5d 0a 20 20 20 20  dex $W $t]].    
1fa0: 20 20 20 20 20 20 20 20 73 65 74 20 45 20 24 44          set E $D
1fb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 74  .            set
1fc0: 20 44 20 24 43 0a 20 20 20 20 20 20 20 20 20 20   D $C.          
1fd0: 20 20 73 65 74 20 43 20 5b 72 6f 74 6c 33 32 20    set C [rotl32 
1fe0: 24 42 20 33 30 5d 0a 20 20 20 20 20 20 20 20 20  $B 30].         
1ff0: 20 20 20 73 65 74 20 42 20 24 41 0a 20 20 20 20     set B $A.    
2000: 20 20 20 20 20 20 20 20 73 65 74 20 41 20 24 54          set A $T
2010: 45 4d 50 0a 20 20 20 20 20 20 20 20 7d 0a 0a 20  EMP.        }.. 
2020: 20 20 20 20 20 20 20 23 20 54 68 65 6e 20 70 65         # Then pe
2030: 72 66 6f 72 6d 20 74 68 65 20 66 6f 6c 6c 6f 77  rform the follow
2040: 69 6e 67 20 61 64 64 69 74 69 6f 6e 73 2e 20 28  ing additions. (
2050: 54 68 61 74 20 69 73 2c 20 69 6e 63 72 65 6d 65  That is, increme
2060: 6e 74 20 65 61 63 68 0a 20 20 20 20 20 20 20 20  nt each.        
2070: 23 20 6f 66 20 74 68 65 20 66 6f 75 72 20 72 65  # of the four re
2080: 67 69 73 74 65 72 73 20 62 79 20 74 68 65 20 76  gisters by the v
2090: 61 6c 75 65 20 69 74 20 68 61 64 20 62 65 66 6f  alue it had befo
20a0: 72 65 20 74 68 69 73 20 62 6c 6f 63 6b 0a 20 20  re this block.  
20b0: 20 20 20 20 20 20 23 20 77 61 73 20 73 74 61 72        # was star
20c0: 74 65 64 2e 29 0a 20 20 20 20 20 20 20 20 69 6e  ted.).        in
20d0: 63 72 20 73 74 61 74 65 28 41 29 20 24 41 0a 20  cr state(A) $A. 
20e0: 20 20 20 20 20 20 20 69 6e 63 72 20 73 74 61 74         incr stat
20f0: 65 28 42 29 20 24 42 0a 20 20 20 20 20 20 20 20  e(B) $B.        
2100: 69 6e 63 72 20 73 74 61 74 65 28 43 29 20 24 43  incr state(C) $C
2110: 0a 20 20 20 20 20 20 20 20 69 6e 63 72 20 73 74  .        incr st
2120: 61 74 65 28 44 29 20 24 44 0a 20 20 20 20 20 20  ate(D) $D.      
2130: 20 20 69 6e 63 72 20 73 74 61 74 65 28 45 29 20    incr state(E) 
2140: 24 45 0a 20 20 20 20 7d 0a 0a 20 20 20 20 72 65  $E.    }..    re
2150: 74 75 72 6e 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 73  turn.}..proc ::s
2160: 68 61 31 3a 3a 46 31 20 7b 41 20 42 20 43 20 44  ha1::F1 {A B C D
2170: 20 45 20 57 7d 20 7b 0a 20 20 20 20 65 78 70 72   E W} {.    expr
2180: 20 7b 28 28 28 28 24 41 20 3c 3c 20 35 29 20 26   {(((($A << 5) &
2190: 20 30 78 66 66 66 66 66 66 66 66 29 20 7c 20 28   0xffffffff) | (
21a0: 28 24 41 20 3e 3e 20 32 37 29 20 26 20 30 78 31  ($A >> 27) & 0x1
21b0: 66 29 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20  f)) \.          
21c0: 20 20 20 20 20 2b 20 28 24 44 20 5e 20 28 24 42       + ($D ^ ($B
21d0: 20 26 20 28 24 43 20 5e 20 24 44 29 29 29 20 2b   & ($C ^ $D))) +
21e0: 20 24 45 20 2b 20 24 57 20 2b 20 30 78 35 61 38   $E + $W + 0x5a8
21f0: 32 37 39 39 39 29 20 26 20 30 78 66 66 66 66 66  27999) & 0xfffff
2200: 66 66 66 7d 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 73  fff}.}..proc ::s
2210: 68 61 31 3a 3a 46 32 20 7b 41 20 42 20 43 20 44  ha1::F2 {A B C D
2220: 20 45 20 57 7d 20 7b 0a 20 20 20 20 65 78 70 72   E W} {.    expr
2230: 20 7b 28 28 28 28 24 41 20 3c 3c 20 35 29 20 26   {(((($A << 5) &
2240: 20 30 78 66 66 66 66 66 66 66 66 29 20 7c 20 28   0xffffffff) | (
2250: 28 24 41 20 3e 3e 20 32 37 29 20 26 20 30 78 31  ($A >> 27) & 0x1
2260: 66 29 29 20 5c 0a 20 20 20 20 20 20 20 20 20 20  f)) \.          
2270: 20 20 20 20 20 2b 20 28 24 42 20 5e 20 24 43 20       + ($B ^ $C 
2280: 5e 20 24 44 29 20 2b 20 24 45 20 2b 20 24 57 20  ^ $D) + $E + $W 
2290: 2b 20 30 78 36 65 64 39 65 62 61 31 29 20 26 20  + 0x6ed9eba1) & 
22a0: 30 78 66 66 66 66 66 66 66 66 7d 0a 7d 0a 0a 70  0xffffffff}.}..p
22b0: 72 6f 63 20 3a 3a 73 68 61 31 3a 3a 46 33 20 7b  roc ::sha1::F3 {
22c0: 41 20 42 20 43 20 44 20 45 20 57 7d 20 7b 0a 20  A B C D E W} {. 
22d0: 20 20 20 65 78 70 72 20 7b 28 28 28 28 24 41 20     expr {(((($A 
22e0: 3c 3c 20 35 29 20 26 20 30 78 66 66 66 66 66 66  << 5) & 0xffffff
22f0: 66 66 29 7c 20 28 28 24 41 20 3e 3e 20 32 37 29  ff)| (($A >> 27)
2300: 20 26 20 30 78 31 66 29 29 20 5c 0a 20 20 20 20   & 0x1f)) \.    
2310: 20 20 20 20 20 20 20 20 20 20 20 2b 20 28 28 24             + (($
2320: 42 20 26 20 24 43 29 20 7c 20 28 24 44 20 26 20  B & $C) | ($D & 
2330: 28 24 42 20 7c 20 24 43 29 29 29 20 2b 20 24 45  ($B | $C))) + $E
2340: 20 2b 20 24 57 20 2b 20 30 78 38 66 31 62 62 63   + $W + 0x8f1bbc
2350: 64 63 29 20 26 20 30 78 66 66 66 66 66 66 66 66  dc) & 0xffffffff
2360: 7d 0a 7d 0a 0a 70 72 6f 63 20 3a 3a 73 68 61 31  }.}..proc ::sha1
2370: 3a 3a 46 34 20 7b 41 20 42 20 43 20 44 20 45 20  ::F4 {A B C D E 
2380: 57 7d 20 7b 0a 20 20 20 20 65 78 70 72 20 7b 28  W} {.    expr {(
2390: 28 28 28 24 41 20 3c 3c 20 35 29 20 26 20 30 78  ((($A << 5) & 0x
23a0: 66 66 66 66 66 66 66 66 29 7c 20 28 28 24 41 20  ffffffff)| (($A 
23b0: 3e 3e 20 32 37 29 20 26 20 30 78 31 66 29 29 20  >> 27) & 0x1f)) 
23c0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  \.              
23d0: 20 2b 20 28 24 42 20 5e 20 24 43 20 5e 20 24 44   + ($B ^ $C ^ $D
23e0: 29 20 2b 20 24 45 20 2b 20 24 57 20 2b 20 30 78  ) + $E + $W + 0x
23f0: 63 61 36 32 63 31 64 36 29 20 26 20 30 78 66 66  ca62c1d6) & 0xff
2400: 66 66 66 66 66 66 7d 0a 7d 0a 0a 70 72 6f 63 20  ffffff}.}..proc 
2410: 3a 3a 73 68 61 31 3a 3a 72 6f 74 6c 33 32 20 7b  ::sha1::rotl32 {
2420: 76 20 6e 7d 20 7b 0a 20 20 20 20 72 65 74 75 72  v n} {.    retur
2430: 6e 20 5b 65 78 70 72 20 7b 28 28 28 24 76 20 3c  n [expr {((($v <
2440: 3c 20 24 6e 29 20 5c 0a 20 20 20 20 20 20 20 20  < $n) \.        
2450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2460: 7c 20 28 28 24 76 20 3e 3e 20 28 33 32 20 2d 20  | (($v >> (32 - 
2470: 24 6e 29 29 20 5c 0a 20 20 20 20 20 20 20 20 20  $n)) \.         
2480: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2490: 20 20 20 20 20 20 26 20 28 30 78 37 46 46 46 46        & (0x7FFFF
24a0: 46 46 46 20 3e 3e 20 28 33 31 20 2d 20 24 6e 29  FFF >> (31 - $n)
24b0: 29 29 29 29 20 5c 0a 20 20 20 20 20 20 20 20 20  )))) \.         
24c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 26 20 30               & 0
24d0: 78 46 46 46 46 46 46 46 46 7d 5d 0a 7d 0a 0a 0a  xFFFFFFFF}].}...
24e0: 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  # --------------
24f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2500: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2510: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
2520: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20 0a 23  -----------.# .#
2530: 20 49 6e 20 6f 72 64 65 72 20 74 6f 20 67 65 74   In order to get
2540: 20 74 68 69 73 20 63 6f 64 65 20 74 6f 20 67 6f   this code to go
2550: 20 61 73 20 66 61 73 74 20 61 73 20 70 6f 73 73   as fast as poss
2560: 69 62 6c 65 20 77 68 69 6c 65 20 6c 65 61 76 69  ible while leavi
2570: 6e 67 0a 23 20 74 68 65 20 6d 61 69 6e 20 63 6f  ng.# the main co
2580: 64 65 20 72 65 61 64 61 62 6c 65 20 77 65 20 63  de readable we c
2590: 61 6e 20 73 75 62 73 74 69 74 75 74 65 20 74 68  an substitute th
25a0: 65 20 61 62 6f 76 65 20 66 75 6e 63 74 69 6f 6e  e above function
25b0: 20 62 6f 64 69 65 73 0a 23 20 69 6e 74 6f 20 74   bodies.# into t
25c0: 68 65 20 74 72 61 6e 73 66 6f 72 6d 20 70 72 6f  he transform pro
25d0: 63 65 64 75 72 65 2e 20 54 68 69 73 20 69 6e 6c  cedure. This inl
25e0: 69 6e 65 73 20 74 68 65 20 63 6f 64 65 20 66 6f  ines the code fo
25f0: 72 20 75 73 20 61 6e 20 61 76 6f 69 64 73 0a 23  r us an avoids.#
2600: 20 61 20 70 72 6f 63 65 64 75 72 65 20 63 61 6c   a procedure cal
2610: 6c 20 6f 76 65 72 68 65 61 64 20 77 69 74 68 69  l overhead withi
2620: 6e 20 74 68 65 20 6c 6f 6f 70 73 2e 0a 23 0a 23  n the loops..#.#
2630: 20 57 65 20 63 61 6e 20 64 6f 20 73 6f 6d 65 20   We can do some 
2640: 6d 69 6e 6f 72 20 74 77 65 61 6b 69 6e 67 20 74  minor tweaking t
2650: 6f 20 69 6d 70 72 6f 76 65 20 73 70 65 65 64 20  o improve speed 
2660: 6f 6e 20 54 63 6c 20 3c 20 38 2e 35 20 77 68 65  on Tcl < 8.5 whe
2670: 72 65 20 77 65 0a 23 20 6b 6e 6f 77 20 6f 75 72  re we.# know our
2680: 20 61 72 69 74 68 6d 65 74 69 63 20 69 73 20 6c   arithmetic is l
2690: 69 6d 69 74 65 64 20 74 6f 20 36 34 20 62 69 74  imited to 64 bit
26a0: 73 2e 20 4f 6e 20 3e 20 38 2e 35 20 77 65 20 6d  s. On > 8.5 we m
26b0: 61 79 20 68 61 76 65 20 0a 23 20 75 6e 63 6f 6e  ay have .# uncon
26c0: 73 74 72 61 69 6e 65 64 20 69 6e 74 65 67 65 72  strained integer
26d0: 20 61 72 69 74 68 6d 65 74 69 63 20 61 6e 64 20   arithmetic and 
26e0: 6d 75 73 74 20 61 76 6f 69 64 20 6c 65 74 74 69  must avoid letti
26f0: 6e 67 20 69 74 20 72 75 6e 20 61 77 61 79 2e 0a  ng it run away..
2700: 23 0a 0a 72 65 67 73 75 62 20 2d 61 6c 6c 20 2d  #..regsub -all -
2710: 6c 69 6e 65 20 5c 0a 20 20 20 20 7b 5c 5b 46 31  line \.    {\[F1
2720: 20 5c 24 41 20 5c 24 42 20 5c 24 43 20 5c 24 44   \$A \$B \$C \$D
2730: 20 5c 24 45 20 28 5c 5b 2e 2a 3f 5c 5d 29 5c 5d   \$E (\[.*?\])\]
2740: 7d 20 5c 0a 20 20 20 20 24 3a 3a 73 68 61 31 3a  } \.    $::sha1:
2750: 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62  :SHA1Transform_b
2760: 6f 64 79 20 5c 0a 20 20 20 20 7b 5b 65 78 70 72  ody \.    {[expr
2770: 20 7b 28 72 6f 74 6c 33 32 28 24 41 2c 35 29 20   {(rotl32($A,5) 
2780: 2b 20 28 24 44 20 5e 20 28 24 42 20 5c 26 20 28  + ($D ^ ($B \& (
2790: 24 43 20 5e 20 24 44 29 29 29 20 2b 20 24 45 20  $C ^ $D))) + $E 
27a0: 2b 20 5c 31 20 2b 20 30 78 35 61 38 32 37 39 39  + \1 + 0x5a82799
27b0: 39 29 20 5c 26 20 30 78 66 66 66 66 66 66 66 66  9) \& 0xffffffff
27c0: 7d 5d 7d 20 5c 0a 20 20 20 20 3a 3a 73 68 61 31  }]} \.    ::sha1
27d0: 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f  ::SHA1Transform_
27e0: 62 6f 64 79 5f 74 6d 70 0a 0a 72 65 67 73 75 62  body_tmp..regsub
27f0: 20 2d 61 6c 6c 20 2d 6c 69 6e 65 20 5c 0a 20 20   -all -line \.  
2800: 20 20 7b 5c 5b 46 32 20 5c 24 41 20 5c 24 42 20    {\[F2 \$A \$B 
2810: 5c 24 43 20 5c 24 44 20 5c 24 45 20 28 5c 5b 2e  \$C \$D \$E (\[.
2820: 2a 3f 5c 5d 29 5c 5d 7d 20 5c 0a 20 20 20 20 24  *?\])\]} \.    $
2830: 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e  ::sha1::SHA1Tran
2840: 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 20 5c  sform_body_tmp \
2850: 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b 28 72 6f  .    {[expr {(ro
2860: 74 6c 33 32 28 24 41 2c 35 29 20 2b 20 28 24 42  tl32($A,5) + ($B
2870: 20 5e 20 24 43 20 5e 20 24 44 29 20 2b 20 24 45   ^ $C ^ $D) + $E
2880: 20 2b 20 5c 31 20 2b 20 30 78 36 65 64 39 65 62   + \1 + 0x6ed9eb
2890: 61 31 29 20 5c 26 20 30 78 66 66 66 66 66 66 66  a1) \& 0xfffffff
28a0: 66 7d 5d 7d 20 5c 0a 20 20 20 20 3a 3a 73 68 61  f}]} \.    ::sha
28b0: 31 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d  1::SHA1Transform
28c0: 5f 62 6f 64 79 5f 74 6d 70 0a 0a 72 65 67 73 75  _body_tmp..regsu
28d0: 62 20 2d 61 6c 6c 20 2d 6c 69 6e 65 20 5c 0a 20  b -all -line \. 
28e0: 20 20 20 7b 5c 5b 46 33 20 5c 24 41 20 5c 24 42     {\[F3 \$A \$B
28f0: 20 5c 24 43 20 5c 24 44 20 5c 24 45 20 28 5c 5b   \$C \$D \$E (\[
2900: 2e 2a 3f 5c 5d 29 5c 5d 7d 20 5c 0a 20 20 20 20  .*?\])\]} \.    
2910: 24 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61  $::sha1::SHA1Tra
2920: 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 20  nsform_body_tmp 
2930: 5c 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b 28 72  \.    {[expr {(r
2940: 6f 74 6c 33 32 28 24 41 2c 35 29 20 2b 20 28 28  otl32($A,5) + ((
2950: 24 42 20 5c 26 20 24 43 29 20 7c 20 28 24 44 20  $B \& $C) | ($D 
2960: 5c 26 20 28 24 42 20 7c 20 24 43 29 29 29 20 2b  \& ($B | $C))) +
2970: 20 24 45 20 2b 20 5c 31 20 2b 20 30 78 38 66 31   $E + \1 + 0x8f1
2980: 62 62 63 64 63 29 20 5c 26 20 30 78 66 66 66 66  bbcdc) \& 0xffff
2990: 66 66 66 66 7d 5d 7d 20 5c 0a 20 20 20 20 3a 3a  ffff}]} \.    ::
29a0: 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e 73 66  sha1::SHA1Transf
29b0: 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 0a 0a 72 65  orm_body_tmp..re
29c0: 67 73 75 62 20 2d 61 6c 6c 20 2d 6c 69 6e 65 20  gsub -all -line 
29d0: 5c 0a 20 20 20 20 7b 5c 5b 46 34 20 5c 24 41 20  \.    {\[F4 \$A 
29e0: 5c 24 42 20 5c 24 43 20 5c 24 44 20 5c 24 45 20  \$B \$C \$D \$E 
29f0: 28 5c 5b 2e 2a 3f 5c 5d 29 5c 5d 7d 20 5c 0a 20  (\[.*?\])\]} \. 
2a00: 20 20 20 24 3a 3a 73 68 61 31 3a 3a 53 48 41 31     $::sha1::SHA1
2a10: 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f 74  Transform_body_t
2a20: 6d 70 20 5c 0a 20 20 20 20 7b 5b 65 78 70 72 20  mp \.    {[expr 
2a30: 7b 28 72 6f 74 6c 33 32 28 24 41 2c 35 29 20 2b  {(rotl32($A,5) +
2a40: 20 28 24 42 20 5e 20 24 43 20 5e 20 24 44 29 20   ($B ^ $C ^ $D) 
2a50: 2b 20 24 45 20 2b 20 5c 31 20 2b 20 30 78 63 61  + $E + \1 + 0xca
2a60: 36 32 63 31 64 36 29 20 5c 26 20 30 78 66 66 66  62c1d6) \& 0xfff
2a70: 66 66 66 66 66 7d 5d 7d 20 5c 0a 20 20 20 20 3a  fffff}]} \.    :
2a80: 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e 73  :sha1::SHA1Trans
2a90: 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 0a 0a 72  form_body_tmp..r
2aa0: 65 67 73 75 62 20 2d 61 6c 6c 20 2d 6c 69 6e 65  egsub -all -line
2ab0: 20 5c 0a 20 20 20 20 7b 72 6f 74 6c 33 32 5c 28   \.    {rotl32\(
2ac0: 5c 24 41 2c 35 5c 29 7d 20 5c 0a 20 20 20 20 24  \$A,5\)} \.    $
2ad0: 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e  ::sha1::SHA1Tran
2ae0: 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 20 5c  sform_body_tmp \
2af0: 0a 20 20 20 20 7b 28 28 28 24 41 20 3c 3c 20 35  .    {((($A << 5
2b00: 29 20 5c 26 20 30 78 66 66 66 66 66 66 66 66 29  ) \& 0xffffffff)
2b10: 20 7c 20 28 28 24 41 20 3e 3e 20 32 37 29 20 5c   | (($A >> 27) \
2b20: 26 20 30 78 31 66 29 29 7d 20 5c 0a 20 20 20 20  & 0x1f))} \.    
2b30: 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e  ::sha1::SHA1Tran
2b40: 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 0a 0a  sform_body_tmp..
2b50: 72 65 67 73 75 62 20 2d 61 6c 6c 20 2d 6c 69 6e  regsub -all -lin
2b60: 65 20 5c 0a 20 20 20 20 7b 5c 5b 72 6f 74 6c 33  e \.    {\[rotl3
2b70: 32 20 5c 24 42 20 33 30 5c 5d 7d 20 5c 0a 20 20  2 \$B 30\]} \.  
2b80: 20 20 24 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54    $::sha1::SHA1T
2b90: 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d  ransform_body_tm
2ba0: 70 20 5c 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b  p \.    {[expr {
2bb0: 69 6e 74 28 28 24 42 20 3c 3c 20 33 30 29 20 7c  int(($B << 30) |
2bc0: 20 28 28 24 42 20 3e 3e 20 32 29 20 5c 26 20 30   (($B >> 2) \& 0
2bd0: 78 33 66 66 66 66 66 66 66 29 29 7d 5d 7d 20 5c  x3fffffff))}]} \
2be0: 0a 20 20 20 20 3a 3a 73 68 61 31 3a 3a 53 48 41  .    ::sha1::SHA
2bf0: 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f  1Transform_body_
2c00: 74 6d 70 0a 23 0a 23 20 56 65 72 73 69 6f 6e 20  tmp.#.# Version 
2c10: 32 20 61 76 6f 69 64 73 20 61 20 66 65 77 20 74  2 avoids a few t
2c20: 72 75 6e 63 61 74 69 6f 6e 73 20 74 6f 20 33 32  runcations to 32
2c30: 20 62 69 74 73 20 69 6e 20 6e 6f 6e 2d 65 73 73   bits in non-ess
2c40: 65 6e 74 69 61 6c 20 70 6c 61 63 65 73 2e 0a 23  ential places..#
2c50: 0a 72 65 67 73 75 62 20 2d 61 6c 6c 20 2d 6c 69  .regsub -all -li
2c60: 6e 65 20 5c 0a 20 20 20 20 7b 5c 5b 46 31 20 5c  ne \.    {\[F1 \
2c70: 24 41 20 5c 24 42 20 5c 24 43 20 5c 24 44 20 5c  $A \$B \$C \$D \
2c80: 24 45 20 28 5c 5b 2e 2a 3f 5c 5d 29 5c 5d 7d 20  $E (\[.*?\])\]} 
2c90: 5c 0a 20 20 20 20 24 3a 3a 73 68 61 31 3a 3a 53  \.    $::sha1::S
2ca0: 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64  HA1Transform_bod
2cb0: 79 20 5c 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b  y \.    {[expr {
2cc0: 72 6f 74 6c 33 32 28 24 41 2c 35 29 20 2b 20 28  rotl32($A,5) + (
2cd0: 24 44 20 5e 20 28 24 42 20 5c 26 20 28 24 43 20  $D ^ ($B \& ($C 
2ce0: 5e 20 24 44 29 29 29 20 2b 20 24 45 20 2b 20 5c  ^ $D))) + $E + \
2cf0: 31 20 2b 20 30 78 35 61 38 32 37 39 39 39 7d 5d  1 + 0x5a827999}]
2d00: 7d 20 5c 0a 20 20 20 20 3a 3a 73 68 61 31 3a 3a  } \.    ::sha1::
2d10: 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f  SHA1Transform_bo
2d20: 64 79 5f 74 6d 70 32 0a 0a 72 65 67 73 75 62 20  dy_tmp2..regsub 
2d30: 2d 61 6c 6c 20 2d 6c 69 6e 65 20 5c 0a 20 20 20  -all -line \.   
2d40: 20 7b 5c 5b 46 32 20 5c 24 41 20 5c 24 42 20 5c   {\[F2 \$A \$B \
2d50: 24 43 20 5c 24 44 20 5c 24 45 20 28 5c 5b 2e 2a  $C \$D \$E (\[.*
2d60: 3f 5c 5d 29 5c 5d 7d 20 5c 0a 20 20 20 20 24 3a  ?\])\]} \.    $:
2d70: 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e 73  :sha1::SHA1Trans
2d80: 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 32 20 5c  form_body_tmp2 \
2d90: 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b 72 6f 74  .    {[expr {rot
2da0: 6c 33 32 28 24 41 2c 35 29 20 2b 20 28 24 42 20  l32($A,5) + ($B 
2db0: 5e 20 24 43 20 5e 20 24 44 29 20 2b 20 24 45 20  ^ $C ^ $D) + $E 
2dc0: 2b 20 5c 31 20 2b 20 30 78 36 65 64 39 65 62 61  + \1 + 0x6ed9eba
2dd0: 31 7d 5d 7d 20 5c 0a 20 20 20 20 3a 3a 73 68 61  1}]} \.    ::sha
2de0: 31 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d  1::SHA1Transform
2df0: 5f 62 6f 64 79 5f 74 6d 70 32 0a 0a 72 65 67 73  _body_tmp2..regs
2e00: 75 62 20 2d 61 6c 6c 20 2d 6c 69 6e 65 20 5c 0a  ub -all -line \.
2e10: 20 20 20 20 7b 5c 5b 46 33 20 5c 24 41 20 5c 24      {\[F3 \$A \$
2e20: 42 20 5c 24 43 20 5c 24 44 20 5c 24 45 20 28 5c  B \$C \$D \$E (\
2e30: 5b 2e 2a 3f 5c 5d 29 5c 5d 7d 20 5c 0a 20 20 20  [.*?\])\]} \.   
2e40: 20 24 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72   $::sha1::SHA1Tr
2e50: 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70  ansform_body_tmp
2e60: 32 20 5c 0a 20 20 20 20 7b 5b 65 78 70 72 20 7b  2 \.    {[expr {
2e70: 72 6f 74 6c 33 32 28 24 41 2c 35 29 20 2b 20 28  rotl32($A,5) + (
2e80: 28 24 42 20 5c 26 20 24 43 29 20 7c 20 28 24 44  ($B \& $C) | ($D
2e90: 20 5c 26 20 28 24 42 20 7c 20 24 43 29 29 29 20   \& ($B | $C))) 
2ea0: 2b 20 24 45 20 2b 20 5c 31 20 2b 20 30 78 38 66  + $E + \1 + 0x8f
2eb0: 31 62 62 63 64 63 7d 5d 7d 20 5c 0a 20 20 20 20  1bbcdc}]} \.    
2ec0: 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e  ::sha1::SHA1Tran
2ed0: 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 32 0a  sform_body_tmp2.
2ee0: 0a 72 65 67 73 75 62 20 2d 61 6c 6c 20 2d 6c 69  .regsub -all -li
2ef0: 6e 65 20 5c 0a 20 20 20 20 7b 5c 5b 46 34 20 5c  ne \.    {\[F4 \
2f00: 24 41 20 5c 24 42 20 5c 24 43 20 5c 24 44 20 5c  $A \$B \$C \$D \
2f10: 24 45 20 28 5c 5b 2e 2a 3f 5c 5d 29 5c 5d 7d 20  $E (\[.*?\])\]} 
2f20: 5c 0a 20 20 20 20 24 3a 3a 73 68 61 31 3a 3a 53  \.    $::sha1::S
2f30: 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64  HA1Transform_bod
2f40: 79 5f 74 6d 70 32 20 5c 0a 20 20 20 20 7b 5b 65  y_tmp2 \.    {[e
2f50: 78 70 72 20 7b 72 6f 74 6c 33 32 28 24 41 2c 35  xpr {rotl32($A,5
2f60: 29 20 2b 20 28 24 42 20 5e 20 24 43 20 5e 20 24  ) + ($B ^ $C ^ $
2f70: 44 29 20 2b 20 24 45 20 2b 20 5c 31 20 2b 20 30  D) + $E + \1 + 0
2f80: 78 63 61 36 32 63 31 64 36 7d 5d 7d 20 5c 0a 20  xca62c1d6}]} \. 
2f90: 20 20 20 3a 3a 73 68 61 31 3a 3a 53 48 41 31 54     ::sha1::SHA1T
2fa0: 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d  ransform_body_tm
2fb0: 70 32 0a 0a 72 65 67 73 75 62 20 2d 61 6c 6c 20  p2..regsub -all 
2fc0: 2d 6c 69 6e 65 20 5c 0a 20 20 20 20 7b 72 6f 74  -line \.    {rot
2fd0: 6c 33 32 5c 28 5c 24 41 2c 35 5c 29 7d 20 5c 0a  l32\(\$A,5\)} \.
2fe0: 20 20 20 20 24 3a 3a 73 68 61 31 3a 3a 53 48 41      $::sha1::SHA
2ff0: 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79 5f  1Transform_body_
3000: 74 6d 70 32 20 5c 0a 20 20 20 20 7b 28 28 24 41  tmp2 \.    {(($A
3010: 20 3c 3c 20 35 29 20 7c 20 28 28 24 41 20 3e 3e   << 5) | (($A >>
3020: 20 32 37 29 20 5c 26 20 30 78 31 66 29 29 7d 20   27) \& 0x1f))} 
3030: 5c 0a 20 20 20 20 3a 3a 73 68 61 31 3a 3a 53 48  \.    ::sha1::SH
3040: 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f 64 79  A1Transform_body
3050: 5f 74 6d 70 32 0a 0a 72 65 67 73 75 62 20 2d 61  _tmp2..regsub -a
3060: 6c 6c 20 2d 6c 69 6e 65 20 5c 0a 20 20 20 20 7b  ll -line \.    {
3070: 5c 5b 72 6f 74 6c 33 32 20 5c 24 42 20 33 30 5c  \[rotl32 \$B 30\
3080: 5d 7d 20 5c 0a 20 20 20 20 24 3a 3a 73 68 61 31  ]} \.    $::sha1
3090: 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f  ::SHA1Transform_
30a0: 62 6f 64 79 5f 74 6d 70 32 20 5c 0a 20 20 20 20  body_tmp2 \.    
30b0: 7b 5b 65 78 70 72 20 7b 28 24 42 20 3c 3c 20 33  {[expr {($B << 3
30c0: 30 29 20 7c 20 28 28 24 42 20 3e 3e 20 32 29 20  0) | (($B >> 2) 
30d0: 5c 26 20 30 78 33 66 66 66 66 66 66 66 29 7d 5d  \& 0x3fffffff)}]
30e0: 7d 20 5c 0a 20 20 20 20 3a 3a 73 68 61 31 3a 3a  } \.    ::sha1::
30f0: 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f  SHA1Transform_bo
3100: 64 79 5f 74 6d 70 32 0a 0a 69 66 20 7b 5b 70 61  dy_tmp2..if {[pa
3110: 63 6b 61 67 65 20 76 73 61 74 69 73 66 69 65 73  ckage vsatisfies
3120: 20 5b 70 61 63 6b 61 67 65 20 70 72 6f 76 69 64   [package provid
3130: 65 20 54 63 6c 5d 20 38 2e 35 5d 7d 20 7b 0a 20  e Tcl] 8.5]} {. 
3140: 20 20 20 70 72 6f 63 20 3a 3a 73 68 61 31 3a 3a     proc ::sha1::
3150: 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 20 7b 74  SHA1Transform {t
3160: 6f 6b 65 6e 20 6d 73 67 7d 20 24 3a 3a 73 68 61  oken msg} $::sha
3170: 31 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d  1::SHA1Transform
3180: 5f 62 6f 64 79 5f 74 6d 70 0a 7d 20 65 6c 73 65  _body_tmp.} else
3190: 20 7b 0a 20 20 20 20 70 72 6f 63 20 3a 3a 73 68   {.    proc ::sh
31a0: 61 31 3a 3a 53 48 41 31 54 72 61 6e 73 66 6f 72  a1::SHA1Transfor
31b0: 6d 20 7b 74 6f 6b 65 6e 20 6d 73 67 7d 20 24 3a  m {token msg} $:
31c0: 3a 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e 73  :sha1::SHA1Trans
31d0: 66 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 32 0a 7d  form_body_tmp2.}
31e0: 0a 0a 75 6e 73 65 74 20 3a 3a 73 68 61 31 3a 3a  ..unset ::sha1::
31f0: 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62 6f  SHA1Transform_bo
3200: 64 79 0a 75 6e 73 65 74 20 3a 3a 73 68 61 31 3a  dy.unset ::sha1:
3210: 3a 53 48 41 31 54 72 61 6e 73 66 6f 72 6d 5f 62  :SHA1Transform_b
3220: 6f 64 79 5f 74 6d 70 0a 75 6e 73 65 74 20 3a 3a  ody_tmp.unset ::
3230: 73 68 61 31 3a 3a 53 48 41 31 54 72 61 6e 73 66  sha1::SHA1Transf
3240: 6f 72 6d 5f 62 6f 64 79 5f 74 6d 70 32 0a 0a 23  orm_body_tmp2..#
3250: 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d   ---------------
3260: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3270: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3280: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3290: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63  ----------..proc
32a0: 20 3a 3a 73 68 61 31 3a 3a 62 79 74 65 20 7b 6e   ::sha1::byte {n
32b0: 20 76 7d 20 7b 65 78 70 72 20 7b 28 28 30 78 46   v} {expr {((0xF
32c0: 46 20 3c 3c 20 28 38 20 2a 20 24 6e 29 29 20 26  F << (8 * $n)) &
32d0: 20 24 76 29 20 3e 3e 20 28 38 20 2a 20 24 6e 29   $v) >> (8 * $n)
32e0: 7d 7d 0a 70 72 6f 63 20 3a 3a 73 68 61 31 3a 3a  }}.proc ::sha1::
32f0: 62 79 74 65 73 20 7b 76 7d 20 7b 20 0a 20 20 20  bytes {v} { .   
3300: 20 23 66 6f 72 6d 61 74 20 25 63 25 63 25 63 25   #format %c%c%c%
3310: 63 20 5b 62 79 74 65 20 30 20 24 76 5d 20 5b 62  c [byte 0 $v] [b
3320: 79 74 65 20 31 20 24 76 5d 20 5b 62 79 74 65 20  yte 1 $v] [byte 
3330: 32 20 24 76 5d 20 5b 62 79 74 65 20 33 20 24 76  2 $v] [byte 3 $v
3340: 5d 0a 20 20 20 20 66 6f 72 6d 61 74 20 25 63 25  ].    format %c%
3350: 63 25 63 25 63 20 5c 0a 20 20 20 20 20 20 20 20  c%c%c \.        
3360: 5b 65 78 70 72 20 7b 28 28 30 78 46 46 30 30 30  [expr {((0xFF000
3370: 30 30 30 20 26 20 24 76 29 20 3e 3e 20 32 34 29  000 & $v) >> 24)
3380: 20 26 20 30 78 46 46 7d 5d 20 5c 0a 20 20 20 20   & 0xFF}] \.    
3390: 20 20 20 20 5b 65 78 70 72 20 7b 28 30 78 46 46      [expr {(0xFF
33a0: 30 30 30 30 20 26 20 24 76 29 20 3e 3e 20 31 36  0000 & $v) >> 16
33b0: 7d 5d 20 5c 0a 20 20 20 20 20 20 20 20 5b 65 78  }] \.        [ex
33c0: 70 72 20 7b 28 30 78 46 46 30 30 20 26 20 24 76  pr {(0xFF00 & $v
33d0: 29 20 3e 3e 20 38 7d 5d 20 5c 0a 20 20 20 20 20  ) >> 8}] \.     
33e0: 20 20 20 5b 65 78 70 72 20 7b 30 78 46 46 20 26     [expr {0xFF &
33f0: 20 24 76 7d 5d 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d   $v}].}..# -----
3400: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3410: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3420: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3430: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3440: 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 3a 3a 73 68 61  ----..proc ::sha
3450: 31 3a 3a 48 65 78 20 7b 64 61 74 61 7d 20 7b 0a  1::Hex {data} {.
3460: 20 20 20 20 62 69 6e 61 72 79 20 73 63 61 6e 20      binary scan 
3470: 24 64 61 74 61 20 48 2a 20 72 65 73 75 6c 74 0a  $data H* result.
3480: 20 20 20 20 72 65 74 75 72 6e 20 24 72 65 73 75      return $resu
3490: 6c 74 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d  lt.}..# --------
34a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
34b0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
34c0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
34d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
34e0: 2d 0a 0a 23 20 44 65 73 63 72 69 70 74 69 6f 6e  -..# Description
34f0: 3a 0a 23 20 20 50 6f 70 20 74 68 65 20 6e 74 68  :.#  Pop the nth
3500: 20 65 6c 65 6d 65 6e 74 20 6f 66 66 20 61 20 6c   element off a l
3510: 69 73 74 2e 20 55 73 65 64 20 69 6e 20 6f 70 74  ist. Used in opt
3520: 69 6f 6e 73 20 70 72 6f 63 65 73 73 69 6e 67 2e  ions processing.
3530: 0a 23 0a 70 72 6f 63 20 3a 3a 73 68 61 31 3a 3a  .#.proc ::sha1::
3540: 50 6f 70 20 7b 76 61 72 6e 61 6d 65 20 7b 6e 74  Pop {varname {nt
3550: 68 20 30 7d 7d 20 7b 0a 20 20 20 20 75 70 76 61  h 0}} {.    upva
3560: 72 20 24 76 61 72 6e 61 6d 65 20 61 72 67 73 0a  r $varname args.
3570: 20 20 20 20 73 65 74 20 72 20 5b 6c 69 6e 64 65      set r [linde
3580: 78 20 24 61 72 67 73 20 24 6e 74 68 5d 0a 20 20  x $args $nth].  
3590: 20 20 73 65 74 20 61 72 67 73 20 5b 6c 72 65 70    set args [lrep
35a0: 6c 61 63 65 20 24 61 72 67 73 20 24 6e 74 68 20  lace $args $nth 
35b0: 24 6e 74 68 5d 0a 20 20 20 20 72 65 74 75 72 6e  $nth].    return
35c0: 20 24 72 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d   $r.}..# -------
35d0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
35e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
35f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3600: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3610: 2d 2d 0a 0a 23 20 66 69 6c 65 65 76 65 6e 74 20  --..# fileevent 
3620: 68 61 6e 64 6c 65 72 20 66 6f 72 20 63 68 75 6e  handler for chun
3630: 6b 65 64 20 66 69 6c 65 20 68 61 73 68 69 6e 67  ked file hashing
3640: 2e 0a 23 0a 70 72 6f 63 20 3a 3a 73 68 61 31 3a  ..#.proc ::sha1:
3650: 3a 43 68 75 6e 6b 20 7b 74 6f 6b 65 6e 20 63 68  :Chunk {token ch
3660: 61 6e 6e 65 6c 20 7b 63 68 75 6e 6b 73 69 7a 65  annel {chunksize
3670: 20 34 30 39 36 7d 7d 20 7b 0a 20 20 20 20 75 70   4096}} {.    up
3680: 76 61 72 20 23 30 20 24 74 6f 6b 65 6e 20 73 74  var #0 $token st
3690: 61 74 65 0a 20 20 20 20 0a 20 20 20 20 69 66 20  ate.    .    if 
36a0: 7b 5b 65 6f 66 20 24 63 68 61 6e 6e 65 6c 5d 7d  {[eof $channel]}
36b0: 20 7b 0a 20 20 20 20 20 20 20 20 66 69 6c 65 65   {.        filee
36c0: 76 65 6e 74 20 24 63 68 61 6e 6e 65 6c 20 72 65  vent $channel re
36d0: 61 64 61 62 6c 65 20 7b 7d 0a 20 20 20 20 20 20  adable {}.      
36e0: 20 20 73 65 74 20 73 74 61 74 65 28 72 65 61 64    set state(read
36f0: 69 6e 67 29 20 30 0a 20 20 20 20 7d 0a 20 20 20  ing) 0.    }.   
3700: 20 20 20 20 20 0a 20 20 20 20 53 48 41 31 55 70       .    SHA1Up
3710: 64 61 74 65 20 24 74 6f 6b 65 6e 20 5b 72 65 61  date $token [rea
3720: 64 20 24 63 68 61 6e 6e 65 6c 20 24 63 68 75 6e  d $channel $chun
3730: 6b 73 69 7a 65 5d 0a 7d 0a 0a 23 20 2d 2d 2d 2d  ksize].}..# ----
3740: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3750: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3760: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3770: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3780: 2d 2d 2d 2d 2d 0a 0a 70 72 6f 63 20 3a 3a 73 68  -----..proc ::sh
3790: 61 31 3a 3a 73 68 61 31 20 7b 61 72 67 73 7d 20  a1::sha1 {args} 
37a0: 7b 0a 20 20 20 20 61 72 72 61 79 20 73 65 74 20  {.    array set 
37b0: 6f 70 74 73 20 7b 2d 68 65 78 20 30 20 2d 66 69  opts {-hex 0 -fi
37c0: 6c 65 6e 61 6d 65 20 7b 7d 20 2d 63 68 61 6e 6e  lename {} -chann
37d0: 65 6c 20 7b 7d 20 2d 63 68 75 6e 6b 73 69 7a 65  el {} -chunksize
37e0: 20 34 30 39 36 7d 0a 20 20 20 20 69 66 20 7b 5b   4096}.    if {[
37f0: 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3d  llength $args] =
3800: 3d 20 31 7d 20 7b 0a 20 20 20 20 20 20 20 20 73  = 1} {.        s
3810: 65 74 20 6f 70 74 73 28 2d 68 65 78 29 20 31 0a  et opts(-hex) 1.
3820: 20 20 20 20 7d 20 65 6c 73 65 20 7b 0a 20 20 20      } else {.   
3830: 20 20 20 20 20 77 68 69 6c 65 20 7b 5b 73 74 72       while {[str
3840: 69 6e 67 20 6d 61 74 63 68 20 2d 2a 20 5b 73 65  ing match -* [se
3850: 74 20 6f 70 74 69 6f 6e 20 5b 6c 69 6e 64 65 78  t option [lindex
3860: 20 24 61 72 67 73 20 30 5d 5d 5d 7d 20 7b 0a 20   $args 0]]]} {. 
3870: 20 20 20 20 20 20 20 20 20 20 20 73 77 69 74 63             switc
3880: 68 20 2d 67 6c 6f 62 20 2d 2d 20 24 6f 70 74 69  h -glob -- $opti
3890: 6f 6e 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  on {.           
38a0: 20 20 20 20 20 2d 68 65 78 20 20 20 20 20 20 20       -hex       
38b0: 7b 20 73 65 74 20 6f 70 74 73 28 2d 68 65 78 29  { set opts(-hex)
38c0: 20 31 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20   1 }.           
38d0: 20 20 20 20 20 2d 62 69 6e 20 20 20 20 20 20 20       -bin       
38e0: 7b 20 73 65 74 20 6f 70 74 73 28 2d 68 65 78 29  { set opts(-hex)
38f0: 20 30 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20   0 }.           
3900: 20 20 20 20 20 2d 66 69 6c 65 2a 20 20 20 20 20       -file*     
3910: 7b 20 73 65 74 20 6f 70 74 73 28 2d 66 69 6c 65  { set opts(-file
3920: 6e 61 6d 65 29 20 5b 50 6f 70 20 61 72 67 73 20  name) [Pop args 
3930: 31 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20  1] }.           
3940: 20 20 20 20 20 2d 63 68 61 6e 6e 65 6c 20 20 20       -channel   
3950: 7b 20 73 65 74 20 6f 70 74 73 28 2d 63 68 61 6e  { set opts(-chan
3960: 6e 65 6c 29 20 5b 50 6f 70 20 61 72 67 73 20 31  nel) [Pop args 1
3970: 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ] }.            
3980: 20 20 20 20 2d 63 68 75 6e 6b 73 69 7a 65 20 7b      -chunksize {
3990: 20 73 65 74 20 6f 70 74 73 28 2d 63 68 75 6e 6b   set opts(-chunk
39a0: 73 69 7a 65 29 20 5b 50 6f 70 20 61 72 67 73 20  size) [Pop args 
39b0: 31 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20  1] }.           
39c0: 20 20 20 20 20 64 65 66 61 75 6c 74 20 7b 0a 20       default {. 
39d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
39e0: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
39f0: 24 61 72 67 73 5d 20 3d 3d 20 31 7d 20 7b 20 62  $args] == 1} { b
3a00: 72 65 61 6b 20 7d 0a 20 20 20 20 20 20 20 20 20  reak }.         
3a10: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b             if {[
3a20: 73 74 72 69 6e 67 20 63 6f 6d 70 61 72 65 20 24  string compare $
3a30: 6f 70 74 69 6f 6e 20 22 2d 2d 22 5d 20 3d 3d 20  option "--"] == 
3a40: 30 7d 20 7b 20 50 6f 70 20 61 72 67 73 3b 20 62  0} { Pop args; b
3a50: 72 65 61 6b 20 7d 0a 20 20 20 20 20 20 20 20 20  reak }.         
3a60: 20 20 20 20 20 20 20 20 20 20 20 73 65 74 20 65             set e
3a70: 72 72 20 5b 6a 6f 69 6e 20 5b 6c 73 6f 72 74 20  rr [join [lsort 
3a80: 5b 63 6f 6e 63 61 74 20 2d 62 69 6e 20 5b 61 72  [concat -bin [ar
3a90: 72 61 79 20 6e 61 6d 65 73 20 6f 70 74 73 5d 5d  ray names opts]]
3aa0: 5d 20 22 2c 20 22 5d 0a 20 20 20 20 20 20 20 20  ] ", "].        
3ab0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
3ac0: 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22  rn -code error "
3ad0: 62 61 64 20 6f 70 74 69 6f 6e 20 24 6f 70 74 69  bad option $opti
3ae0: 6f 6e 3a 5c 0a 20 20 20 20 20 20 20 20 20 20 20  on:\.           
3af0: 20 20 20 20 20 20 20 20 20 6d 75 73 74 20 62 65           must be
3b00: 20 6f 6e 65 20 6f 66 20 24 65 72 72 22 0a 20 20   one of $err".  
3b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a                }.
3b20: 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20              }.  
3b30: 20 20 20 20 20 20 20 20 20 20 50 6f 70 20 61 72            Pop ar
3b40: 67 73 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  gs.        }.   
3b50: 20 7d 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 74   }..    if {$opt
3b60: 73 28 2d 66 69 6c 65 6e 61 6d 65 29 20 21 3d 20  s(-filename) != 
3b70: 7b 7d 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  {}} {.        se
3b80: 74 20 6f 70 74 73 28 2d 63 68 61 6e 6e 65 6c 29  t opts(-channel)
3b90: 20 5b 6f 70 65 6e 20 24 6f 70 74 73 28 2d 66 69   [open $opts(-fi
3ba0: 6c 65 6e 61 6d 65 29 20 72 5d 0a 20 20 20 20 20  lename) r].     
3bb0: 20 20 20 66 63 6f 6e 66 69 67 75 72 65 20 24 6f     fconfigure $o
3bc0: 70 74 73 28 2d 63 68 61 6e 6e 65 6c 29 20 2d 74  pts(-channel) -t
3bd0: 72 61 6e 73 6c 61 74 69 6f 6e 20 62 69 6e 61 72  ranslation binar
3be0: 79 0a 20 20 20 20 7d 0a 0a 20 20 20 20 69 66 20  y.    }..    if 
3bf0: 7b 24 6f 70 74 73 28 2d 63 68 61 6e 6e 65 6c 29  {$opts(-channel)
3c00: 20 3d 3d 20 7b 7d 7d 20 7b 0a 0a 20 20 20 20 20   == {}} {..     
3c10: 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20     if {[llength 
3c20: 24 61 72 67 73 5d 20 21 3d 20 31 7d 20 7b 0a 20  $args] != 1} {. 
3c30: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
3c40: 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 77  n -code error "w
3c50: 72 6f 6e 67 20 23 20 61 72 67 73 3a 5c 0a 20 20  rong # args:\.  
3c60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 73 68                sh
3c70: 6f 75 6c 64 20 62 65 20 5c 22 73 68 61 31 20 3f  ould be \"sha1 ?
3c80: 2d 68 65 78 3f 20 2d 66 69 6c 65 6e 61 6d 65 20  -hex? -filename 
3c90: 66 69 6c 65 20 7c 20 73 74 72 69 6e 67 5c 22 22  file | string\""
3ca0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
3cb0: 20 20 20 73 65 74 20 74 6f 6b 20 5b 53 48 41 31     set tok [SHA1
3cc0: 49 6e 69 74 5d 0a 20 20 20 20 20 20 20 20 53 48  Init].        SH
3cd0: 41 31 55 70 64 61 74 65 20 24 74 6f 6b 20 5b 6c  A1Update $tok [l
3ce0: 69 6e 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20  index $args 0]. 
3cf0: 20 20 20 20 20 20 20 73 65 74 20 72 20 5b 53 48         set r [SH
3d00: 41 31 46 69 6e 61 6c 20 24 74 6f 6b 5d 0a 0a 20  A1Final $tok].. 
3d10: 20 20 20 7d 20 65 6c 73 65 20 7b 0a 0a 20 20 20     } else {..   
3d20: 20 20 20 20 20 73 65 74 20 74 6f 6b 20 5b 53 48       set tok [SH
3d30: 41 31 49 6e 69 74 5d 0a 20 20 20 20 20 20 20 20  A1Init].        
3d40: 23 20 46 52 49 4e 4b 3a 20 6e 6f 63 68 65 63 6b  # FRINK: nocheck
3d50: 0a 20 20 20 20 20 20 20 20 73 65 74 20 5b 73 75  .        set [su
3d60: 62 73 74 20 24 74 6f 6b 5d 28 72 65 61 64 69 6e  bst $tok](readin
3d70: 67 29 20 31 0a 20 20 20 20 20 20 20 20 66 69 6c  g) 1.        fil
3d80: 65 65 76 65 6e 74 20 24 6f 70 74 73 28 2d 63 68  eevent $opts(-ch
3d90: 61 6e 6e 65 6c 29 20 72 65 61 64 61 62 6c 65 20  annel) readable 
3da0: 5c 0a 20 20 20 20 20 20 20 20 20 20 20 20 5b 6c  \.            [l
3db0: 69 73 74 20 5b 6e 61 6d 65 73 70 61 63 65 20 6f  ist [namespace o
3dc0: 72 69 67 69 6e 20 43 68 75 6e 6b 5d 20 5c 0a 20  rigin Chunk] \. 
3dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3de0: 24 74 6f 6b 20 24 6f 70 74 73 28 2d 63 68 61 6e  $tok $opts(-chan
3df0: 6e 65 6c 29 20 24 6f 70 74 73 28 2d 63 68 75 6e  nel) $opts(-chun
3e00: 6b 73 69 7a 65 29 5d 0a 20 20 20 20 20 20 20 20  ksize)].        
3e10: 23 20 46 52 49 4e 4b 3a 20 6e 6f 63 68 65 63 6b  # FRINK: nocheck
3e20: 0a 20 20 20 20 20 20 20 20 76 77 61 69 74 20 5b  .        vwait [
3e30: 73 75 62 73 74 20 24 74 6f 6b 5d 28 72 65 61 64  subst $tok](read
3e40: 69 6e 67 29 0a 20 20 20 20 20 20 20 20 73 65 74  ing).        set
3e50: 20 72 20 5b 53 48 41 31 46 69 6e 61 6c 20 24 74   r [SHA1Final $t
3e60: 6f 6b 5d 0a 0a 20 20 20 20 20 20 20 20 23 20 49  ok]..        # I
3e70: 66 20 77 65 20 6f 70 65 6e 65 64 20 74 68 65 20  f we opened the 
3e80: 63 68 61 6e 6e 65 6c 20 2d 20 77 65 20 73 68 6f  channel - we sho
3e90: 75 6c 64 20 63 6c 6f 73 65 20 69 74 20 74 6f 6f  uld close it too
3ea0: 2e 0a 20 20 20 20 20 20 20 20 69 66 20 7b 24 6f  ..        if {$o
3eb0: 70 74 73 28 2d 66 69 6c 65 6e 61 6d 65 29 20 21  pts(-filename) !
3ec0: 3d 20 7b 7d 7d 20 7b 0a 20 20 20 20 20 20 20 20  = {}} {.        
3ed0: 20 20 20 20 63 6c 6f 73 65 20 24 6f 70 74 73 28      close $opts(
3ee0: 2d 63 68 61 6e 6e 65 6c 29 0a 20 20 20 20 20 20  -channel).      
3ef0: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 0a 20    }.    }.    . 
3f00: 20 20 20 69 66 20 7b 24 6f 70 74 73 28 2d 68 65     if {$opts(-he
3f10: 78 29 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65  x)} {.        se
3f20: 74 20 72 20 5b 48 65 78 20 24 72 5d 0a 20 20 20  t r [Hex $r].   
3f30: 20 7d 0a 20 20 20 20 72 65 74 75 72 6e 20 24 72   }.    return $r
3f40: 0a 7d 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  .}..# ----------
3f50: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f60: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f70: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
3f80: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a  ---------------.
3f90: 0a 70 72 6f 63 20 3a 3a 73 68 61 31 3a 3a 68 6d  .proc ::sha1::hm
3fa0: 61 63 20 7b 61 72 67 73 7d 20 7b 0a 20 20 20 20  ac {args} {.    
3fb0: 61 72 72 61 79 20 73 65 74 20 6f 70 74 73 20 7b  array set opts {
3fc0: 2d 68 65 78 20 31 20 2d 66 69 6c 65 6e 61 6d 65  -hex 1 -filename
3fd0: 20 7b 7d 20 2d 63 68 61 6e 6e 65 6c 20 7b 7d 20   {} -channel {} 
3fe0: 2d 63 68 75 6e 6b 73 69 7a 65 20 34 30 39 36 7d  -chunksize 4096}
3ff0: 0a 20 20 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74  .    if {[llengt
4000: 68 20 24 61 72 67 73 5d 20 21 3d 20 32 7d 20 7b  h $args] != 2} {
4010: 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 20 7b  .        while {
4020: 5b 73 74 72 69 6e 67 20 6d 61 74 63 68 20 2d 2a  [string match -*
4030: 20 5b 73 65 74 20 6f 70 74 69 6f 6e 20 5b 6c 69   [set option [li
4040: 6e 64 65 78 20 24 61 72 67 73 20 30 5d 5d 5d 7d  ndex $args 0]]]}
4050: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 73   {.            s
4060: 77 69 74 63 68 20 2d 67 6c 6f 62 20 2d 2d 20 24  witch -glob -- $
4070: 6f 70 74 69 6f 6e 20 7b 0a 20 20 20 20 20 20 20  option {.       
4080: 20 20 20 20 20 20 20 20 20 2d 6b 65 79 20 20 20           -key   
4090: 20 20 20 20 7b 20 73 65 74 20 6f 70 74 73 28 2d      { set opts(-
40a0: 6b 65 79 29 20 5b 50 6f 70 20 61 72 67 73 20 31  key) [Pop args 1
40b0: 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ] }.            
40c0: 20 20 20 20 2d 68 65 78 20 20 20 20 20 20 20 7b      -hex       {
40d0: 20 73 65 74 20 6f 70 74 73 28 2d 68 65 78 29 20   set opts(-hex) 
40e0: 31 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  1 }.            
40f0: 20 20 20 20 2d 62 69 6e 20 20 20 20 20 20 20 7b      -bin       {
4100: 20 73 65 74 20 6f 70 74 73 28 2d 68 65 78 29 20   set opts(-hex) 
4110: 30 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  0 }.            
4120: 20 20 20 20 2d 66 69 6c 65 2a 20 20 20 20 20 7b      -file*     {
4130: 20 73 65 74 20 6f 70 74 73 28 2d 66 69 6c 65 6e   set opts(-filen
4140: 61 6d 65 29 20 5b 50 6f 70 20 61 72 67 73 20 31  ame) [Pop args 1
4150: 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ] }.            
4160: 20 20 20 20 2d 63 68 61 6e 6e 65 6c 20 20 20 7b      -channel   {
4170: 20 73 65 74 20 6f 70 74 73 28 2d 63 68 61 6e 6e   set opts(-chann
4180: 65 6c 29 20 5b 50 6f 70 20 61 72 67 73 20 31 5d  el) [Pop args 1]
4190: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   }.             
41a0: 20 20 20 2d 63 68 75 6e 6b 73 69 7a 65 20 7b 20     -chunksize { 
41b0: 73 65 74 20 6f 70 74 73 28 2d 63 68 75 6e 6b 73  set opts(-chunks
41c0: 69 7a 65 29 20 5b 50 6f 70 20 61 72 67 73 20 31  ize) [Pop args 1
41d0: 5d 20 7d 0a 20 20 20 20 20 20 20 20 20 20 20 20  ] }.            
41e0: 20 20 20 20 64 65 66 61 75 6c 74 20 7b 0a 20 20      default {.  
41f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4200: 20 20 69 66 20 7b 5b 6c 6c 65 6e 67 74 68 20 24    if {[llength $
4210: 61 72 67 73 5d 20 3d 3d 20 31 7d 20 7b 20 62 72  args] == 1} { br
4220: 65 61 6b 20 7d 0a 20 20 20 20 20 20 20 20 20 20  eak }.          
4230: 20 20 20 20 20 20 20 20 20 20 69 66 20 7b 5b 73            if {[s
4240: 74 72 69 6e 67 20 63 6f 6d 70 61 72 65 20 24 6f  tring compare $o
4250: 70 74 69 6f 6e 20 22 2d 2d 22 5d 20 3d 3d 20 30  ption "--"] == 0
4260: 7d 20 7b 20 50 6f 70 20 61 72 67 73 3b 20 62 72  } { Pop args; br
4270: 65 61 6b 20 7d 0a 20 20 20 20 20 20 20 20 20 20  eak }.          
4280: 20 20 20 20 20 20 20 20 20 20 73 65 74 20 65 72            set er
4290: 72 20 5b 6a 6f 69 6e 20 5b 6c 73 6f 72 74 20 5b  r [join [lsort [
42a0: 61 72 72 61 79 20 6e 61 6d 65 73 20 6f 70 74 73  array names opts
42b0: 5d 5d 20 22 2c 20 22 5d 0a 20 20 20 20 20 20 20  ]] ", "].       
42c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74               ret
42d0: 75 72 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20  urn -code error 
42e0: 22 62 61 64 20 6f 70 74 69 6f 6e 20 24 6f 70 74  "bad option $opt
42f0: 69 6f 6e 3a 5c 0a 20 20 20 20 20 20 20 20 20 20  ion:\.          
4300: 20 20 20 20 20 20 20 20 20 20 6d 75 73 74 20 62            must b
4310: 65 20 6f 6e 65 20 6f 66 20 24 65 72 72 22 0a 20  e one of $err". 
4320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 7d                 }
4330: 0a 20 20 20 20 20 20 20 20 20 20 20 20 7d 0a 20  .            }. 
4340: 20 20 20 20 20 20 20 20 20 20 20 50 6f 70 20 61             Pop a
4350: 72 67 73 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  rgs.        }.  
4360: 20 20 7d 0a 0a 20 20 20 20 69 66 20 7b 5b 6c 6c    }..    if {[ll
4370: 65 6e 67 74 68 20 24 61 72 67 73 5d 20 3d 3d 20  ength $args] == 
4380: 32 7d 20 7b 0a 20 20 20 20 20 20 20 20 73 65 74  2} {.        set
4390: 20 6f 70 74 73 28 2d 6b 65 79 29 20 5b 50 6f 70   opts(-key) [Pop
43a0: 20 61 72 67 73 5d 0a 20 20 20 20 7d 0a 0a 20 20   args].    }..  
43b0: 20 20 69 66 20 7b 21 5b 69 6e 66 6f 20 65 78 69    if {![info exi
43c0: 73 74 73 20 6f 70 74 73 28 2d 6b 65 79 29 5d 7d  sts opts(-key)]}
43d0: 20 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72   {.        retur
43e0: 6e 20 2d 63 6f 64 65 20 65 72 72 6f 72 20 22 77  n -code error "w
43f0: 72 6f 6e 67 20 23 20 61 72 67 73 3a 5c 0a 20 20  rong # args:\.  
4400: 20 20 20 20 20 20 20 20 20 20 73 68 6f 75 6c 64            should
4410: 20 62 65 20 5c 22 68 6d 61 63 20 3f 2d 68 65 78   be \"hmac ?-hex
4420: 3f 20 2d 6b 65 79 20 6b 65 79 20 2d 66 69 6c 65  ? -key key -file
4430: 6e 61 6d 65 20 66 69 6c 65 20 7c 20 73 74 72 69  name file | stri
4440: 6e 67 5c 22 22 0a 20 20 20 20 7d 0a 0a 20 20 20  ng\"".    }..   
4450: 20 69 66 20 7b 24 6f 70 74 73 28 2d 66 69 6c 65   if {$opts(-file
4460: 6e 61 6d 65 29 20 21 3d 20 7b 7d 7d 20 7b 0a 20  name) != {}} {. 
4470: 20 20 20 20 20 20 20 73 65 74 20 6f 70 74 73 28         set opts(
4480: 2d 63 68 61 6e 6e 65 6c 29 20 5b 6f 70 65 6e 20  -channel) [open 
4490: 24 6f 70 74 73 28 2d 66 69 6c 65 6e 61 6d 65 29  $opts(-filename)
44a0: 20 72 5d 0a 20 20 20 20 20 20 20 20 66 63 6f 6e   r].        fcon
44b0: 66 69 67 75 72 65 20 24 6f 70 74 73 28 2d 63 68  figure $opts(-ch
44c0: 61 6e 6e 65 6c 29 20 2d 74 72 61 6e 73 6c 61 74  annel) -translat
44d0: 69 6f 6e 20 62 69 6e 61 72 79 0a 20 20 20 20 7d  ion binary.    }
44e0: 0a 0a 20 20 20 20 69 66 20 7b 24 6f 70 74 73 28  ..    if {$opts(
44f0: 2d 63 68 61 6e 6e 65 6c 29 20 3d 3d 20 7b 7d 7d  -channel) == {}}
4500: 20 7b 0a 0a 20 20 20 20 20 20 20 20 69 66 20 7b   {..        if {
4510: 5b 6c 6c 65 6e 67 74 68 20 24 61 72 67 73 5d 20  [llength $args] 
4520: 21 3d 20 31 7d 20 7b 0a 20 20 20 20 20 20 20 20  != 1} {.        
4530: 20 20 20 20 72 65 74 75 72 6e 20 2d 63 6f 64 65      return -code
4540: 20 65 72 72 6f 72 20 22 77 72 6f 6e 67 20 23 20   error "wrong # 
4550: 61 72 67 73 3a 5c 0a 20 20 20 20 20 20 20 20 20  args:\.         
4560: 20 20 20 20 20 20 20 73 68 6f 75 6c 64 20 62 65         should be
4570: 20 5c 22 68 6d 61 63 20 3f 2d 68 65 78 3f 20 2d   \"hmac ?-hex? -
4580: 6b 65 79 20 6b 65 79 20 2d 66 69 6c 65 6e 61 6d  key key -filenam
4590: 65 20 66 69 6c 65 20 7c 20 73 74 72 69 6e 67 5c  e file | string\
45a0: 22 22 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  "".        }.   
45b0: 20 20 20 20 20 73 65 74 20 74 6f 6b 20 5b 48 4d       set tok [HM
45c0: 41 43 49 6e 69 74 20 24 6f 70 74 73 28 2d 6b 65  ACInit $opts(-ke
45d0: 79 29 5d 0a 20 20 20 20 20 20 20 20 48 4d 41 43  y)].        HMAC
45e0: 55 70 64 61 74 65 20 24 74 6f 6b 20 5b 6c 69 6e  Update $tok [lin
45f0: 64 65 78 20 24 61 72 67 73 20 30 5d 0a 20 20 20  dex $args 0].   
4600: 20 20 20 20 20 73 65 74 20 72 20 5b 48 4d 41 43       set r [HMAC
4610: 46 69 6e 61 6c 20 24 74 6f 6b 5d 0a 0a 20 20 20  Final $tok]..   
4620: 20 7d 20 65 6c 73 65 20 7b 0a 0a 20 20 20 20 20   } else {..     
4630: 20 20 20 73 65 74 20 74 6f 6b 20 5b 48 4d 41 43     set tok [HMAC
4640: 49 6e 69 74 20 24 6f 70 74 73 28 2d 6b 65 79 29  Init $opts(-key)
4650: 5d 0a 20 20 20 20 20 20 20 20 23 20 46 52 49 4e  ].        # FRIN
4660: 4b 3a 20 6e 6f 63 68 65 63 6b 0a 20 20 20 20 20  K: nocheck.     
4670: 20 20 20 73 65 74 20 5b 73 75 62 73 74 20 24 74     set [subst $t
4680: 6f 6b 5d 28 72 65 61 64 69 6e 67 29 20 31 0a 20  ok](reading) 1. 
4690: 20 20 20 20 20 20 20 66 69 6c 65 65 76 65 6e 74         fileevent
46a0: 20 24 6f 70 74 73 28 2d 63 68 61 6e 6e 65 6c 29   $opts(-channel)
46b0: 20 72 65 61 64 61 62 6c 65 20 5c 0a 20 20 20 20   readable \.    
46c0: 20 20 20 20 20 20 20 20 5b 6c 69 73 74 20 5b 6e          [list [n
46d0: 61 6d 65 73 70 61 63 65 20 6f 72 69 67 69 6e 20  amespace origin 
46e0: 43 68 75 6e 6b 5d 20 5c 0a 20 20 20 20 20 20 20  Chunk] \.       
46f0: 20 20 20 20 20 20 20 20 20 20 24 74 6f 6b 20 24            $tok $
4700: 6f 70 74 73 28 2d 63 68 61 6e 6e 65 6c 29 20 24  opts(-channel) $
4710: 6f 70 74 73 28 2d 63 68 75 6e 6b 73 69 7a 65 29  opts(-chunksize)
4720: 5d 0a 20 20 20 20 20 20 20 20 23 20 46 52 49 4e  ].        # FRIN
4730: 4b 3a 20 6e 6f 63 68 65 63 6b 0a 20 20 20 20 20  K: nocheck.     
4740: 20 20 20 76 77 61 69 74 20 5b 73 75 62 73 74 20     vwait [subst 
4750: 24 74 6f 6b 5d 28 72 65 61 64 69 6e 67 29 0a 20  $tok](reading). 
4760: 20 20 20 20 20 20 20 73 65 74 20 72 20 5b 48 4d         set r [HM
4770: 41 43 46 69 6e 61 6c 20 24 74 6f 6b 5d 0a 0a 20  ACFinal $tok].. 
4780: 20 20 20 20 20 20 20 23 20 49 66 20 77 65 20 6f         # If we o
4790: 70 65 6e 65 64 20 74 68 65 20 63 68 61 6e 6e 65  pened the channe
47a0: 6c 20 2d 20 77 65 20 73 68 6f 75 6c 64 20 63 6c  l - we should cl
47b0: 6f 73 65 20 69 74 20 74 6f 6f 2e 0a 20 20 20 20  ose it too..    
47c0: 20 20 20 20 69 66 20 7b 24 6f 70 74 73 28 2d 66      if {$opts(-f
47d0: 69 6c 65 6e 61 6d 65 29 20 21 3d 20 7b 7d 7d 20  ilename) != {}} 
47e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6c  {.            cl
47f0: 6f 73 65 20 24 6f 70 74 73 28 2d 63 68 61 6e 6e  ose $opts(-chann
4800: 65 6c 29 0a 20 20 20 20 20 20 20 20 7d 0a 20 20  el).        }.  
4810: 20 20 7d 0a 20 20 20 20 0a 20 20 20 20 69 66 20    }.    .    if 
4820: 7b 24 6f 70 74 73 28 2d 68 65 78 29 7d 20 7b 0a  {$opts(-hex)} {.
4830: 20 20 20 20 20 20 20 20 73 65 74 20 72 20 5b 48          set r [H
4840: 65 78 20 24 72 5d 0a 20 20 20 20 7d 0a 20 20 20  ex $r].    }.   
4850: 20 72 65 74 75 72 6e 20 24 72 0a 7d 0a 0a 23 20   return $r.}..# 
4860: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4870: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4880: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4890: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
48a0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 0a 70 61 63 6b 61  ---------..packa
48b0: 67 65 20 70 72 6f 76 69 64 65 20 73 68 61 31 20  ge provide sha1 
48c0: 24 3a 3a 73 68 61 31 3a 3a 76 65 72 73 69 6f 6e  $::sha1::version
48d0: 0a 0a 23 20 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ..# ------------
48e0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
48f0: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4900: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d  ----------------
4910: 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 2d 0a 23 20  -------------.# 
4920: 4c 6f 63 61 6c 20 56 61 72 69 61 62 6c 65 73 3a  Local Variables:
4930: 0a 23 20 20 20 6d 6f 64 65 3a 20 74 63 6c 0a 23  .#   mode: tcl.#
4940: 20 20 20 69 6e 64 65 6e 74 2d 74 61 62 73 2d 6d     indent-tabs-m
4950: 6f 64 65 3a 20 6e 69 6c 0a 23 20 45 6e 64 3a 0a  ode: nil.# End:.