/usr/share/amsn/utils/sha1/sha1.tcl is in amsn-data 0.98.9-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 | ##################################################
#
# sha1.tcl - SHA1 in Tcl
# Author: Don Libes <libes@nist.gov>, May 2001
# Version 1.0.3
#
# SHA1 defined by FIPS 180-1, "The SHA1 Message-Digest Algorithm",
# http://www.itl.nist.gov/fipspubs/fip180-1.htm
# HMAC defined by RFC 2104, "Keyed-Hashing for Message Authentication"
#
# Some of the comments below come right out of FIPS 180-1; That's why
# they have such peculiar numbers. In addition, I have retained
# original syntax, etc. from the FIPS. All remaining bugs are mine.
#
# HMAC implementation by D. J. Hagberg <dhagberg@millibits.com> and
# is based on C code in FIPS 2104.
#
# For more info, see: http://expect.nist.gov/sha1pure
#
# - Don
##################################################
### Code speedups by Donal Fellows <fellowsd@cs.man.ac.uk> who may well
### have added some extra bugs of his own... :^)
### Changed the code to use Trf if this package is present on the
### system requiring the sha1 package. Analogous to md5.
package require Tcl 8.2
namespace eval ::sha1 {
}
if {![catch {package require Trf 2.0}] && ![catch {::sha1 -- test}]} {
# Trf is available, so implement the functionality provided here
# in terms of calls to Trf for speed.
proc ::sha1::sha1 {msg} {
string tolower [::hex -mode encode -- [::sha1 -- $msg]]
}
# hmac: hash for message authentication
# SHA1 of Trf and SHA1 as defined by this package have slightly
# different results. Trf returns the digest in binary, here we get
# it as hex-string. In the computation of the HMAC the latter
# requires back conversion into binary in some places. With Trf we
# can use omit these. (Not all, the first place must not the changed,
# see [x]
proc ::sha1::hmac {key text} {
# if key is longer than 64 bytes, reset it to SHA1(key). If shorter,
# pad it out with null (\x00) chars.
set keyLen [string length $key]
if {$keyLen > 64} {
set key [binary format H32 [sha1 $key]]
# [x] set key [::sha1 -- $key]
set keyLen [string length $key]
}
# ensure the key is padded out to 64 chars with nulls.
set padLen [expr {64 - $keyLen}]
append key [binary format "a$padLen" {}]
# Split apart the key into a list of 16 little-endian words
binary scan $key i16 blocks
# XOR key with ipad and opad values
set k_ipad {}
set k_opad {}
foreach i $blocks {
append k_ipad [binary format i [expr {$i ^ 0x36363636}]]
append k_opad [binary format i [expr {$i ^ 0x5c5c5c5c}]]
}
# Perform inner sha1, appending its results to the outer key
append k_ipad $text
#append k_opad [binary format H* [sha1 $k_ipad]]
append k_opad [::sha1 -- $k_ipad]
# Perform outer sha1
#sha1 $k_opad
string tolower [::hex -mode encode -- [::sha1 -- $k_opad]]
}
} else {
# Without Trf use the all-tcl implementation by Don Libes.
namespace eval ::sha1 {
variable K
proc initK {} {
variable K {}
foreach t {
0x5A827999
0x6ED9EBA1
0x8F1BBCDC
0xCA62C1D6
} {
for {set i 0} {$i < 20} {incr i} {
lappend K [expr {int($t)}]
}
}
}
initK
}
# test sha1
#
# This proc is not necessary during runtime and may be omitted if you
# are simply inserting this file into a production program.
#
proc ::sha1::test {} {
foreach {msg expected} {
"abc"
"a9993e364706816aba3e25717850c26c9cd0d89d"
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
"84983e441c3bd26ebaae4aa1f95129e5e54670f1"
"[string repeat a 1000000]"
"34aa973cd4c4daa4f61eeb2bdbad27316534016f"
} {
puts "testing: sha1 \"$msg\""
set msg [subst $msg]
set msgLen [string length $msg]
if {$msgLen > 10000} {
puts "warning: msg length = $msgLen; this may take a while . . ."
}
set computed [sha1 $msg]
puts "expected: $expected"
puts "computed: $computed"
if {0 != [string compare $computed $expected]} {
puts "FAILED"
} else {
puts "SUCCEEDED"
}
}
}
# time sha1
#
# This proc is not necessary during runtime and may be omitted if you
# are simply inserting this file into a production program.
#
proc ::sha1::time {} {
foreach len {10 50 100 500 1000 5000 10000} {
set time [::time {sha1 [format %$len.0s ""]} 10]
set msec [lindex $time 0]
puts "input length $len: [expr {$msec/1000}] milliseconds per interation"
}
}
proc ::sha1::sha1 {msg} {
variable K
#
# 4. MESSAGE PADDING
#
# pad to 512 bits (512/8 = 64 bytes)
set msgLen [string length $msg]
# last 8 bytes are reserved for msgLen
# plus 1 for "1"
set padLen [expr {56 - $msgLen%64}]
if {$msgLen % 64 >= 56} {
incr padLen 64
}
# 4a. and b. append single 1b followed by 0b's
append msg [binary format "a$padLen" \200]
# 4c. append 64-bit length
# Our implementation obviously limits string length to 32bits.
append msg \0\0\0\0[binary format "I" [expr {8*$msgLen}]]
#
# 7. COMPUTING THE MESSAGE DIGEST
#
# initial H buffer
set H0 [expr {int(0x67452301)}]
set H1 [expr {int(0xEFCDAB89)}]
set H2 [expr {int(0x98BADCFE)}]
set H3 [expr {int(0x10325476)}]
set H4 [expr {int(0xC3D2E1F0)}]
#
# process message in 16-word blocks (64-byte blocks)
#
# convert message to array of 32-bit integers
# each block of 16-words is stored in M($i,0-16)
binary scan $msg I* words
set blockLen [llength $words]
for {set i 0} {$i < $blockLen} {incr i 16} {
# 7a. Divide M[i] into 16 words W[0], W[1], ...
set W [lrange $words $i [expr {$i+15}]]
# 7b. For t = 16 to 79 let W[t] = ....
set t 16
set t3 12
set t8 7
set t14 1
set t16 -1
for {} {$t < 80} {incr t} {
set x [expr {[lindex $W [incr t3]] ^ [lindex $W [incr t8]] ^ \
[lindex $W [incr t14]] ^ [lindex $W [incr t16]]}]
lappend W [expr {($x << 1) | (($x >> 31) & 1)}]
}
# 7c. Let A = H[0] ....
set A $H0
set B $H1
set C $H2
set D $H3
set E $H4
# 7d. For t = 0 to 79 do
for {set t 0} {$t < 20} {incr t} {
set TEMP [expr {(($A << 5) | (($A >> 27) & 0x1f)) + \
(($B & $C) | ((~$B) & $D)) \
+ $E + [lindex $W $t] + [lindex $K $t]}]
set E $D
set D $C
set C [expr {($B << 30) | (($B >> 2) & 0x3fffffff)}]
set B $A
set A $TEMP
}
for {} {$t<40} {incr t} {
set TEMP [expr {(($A << 5) | (($A >> 27) & 0x1f)) + \
($B ^ $C ^ $D) \
+ $E + [lindex $W $t] + [lindex $K $t]}]
set E $D
set D $C
set C [expr {($B << 30) | (($B >> 2) & 0x3fffffff)}]
set B $A
set A $TEMP
}
for {} {$t<60} {incr t} {
set TEMP [expr {(($A << 5) | (($A >> 27) & 0x1f)) + \
(($B & $C) | ($B & $D) | ($C & $D)) \
+ $E + [lindex $W $t] + [lindex $K $t]}]
set E $D
set D $C
set C [expr {($B << 30) | (($B >> 2) & 0x3fffffff)}]
set B $A
set A $TEMP
}
for {} {$t<80} {incr t} {
set TEMP [expr {(($A << 5) | (($A >> 27) & 0x1f)) + \
($B ^ $C ^ $D) \
+ $E + [lindex $W $t] + [lindex $K $t]}]
set E $D
set D $C
set C [expr {($B << 30) | (($B >> 2) & 0x3fffffff)}]
set B $A
set A $TEMP
}
set H0 [expr {int(($H0 + $A) & 0xffffffff)}]
set H1 [expr {int(($H1 + $B) & 0xffffffff)}]
set H2 [expr {int(($H2 + $C) & 0xffffffff)}]
set H3 [expr {int(($H3 + $D) & 0xffffffff)}]
set H4 [expr {int(($H4 + $E) & 0xffffffff)}]
}
return [format %0.8x%0.8x%0.8x%0.8x%0.8x $H0 $H1 $H2 $H3 $H4]
}
### These procedures are either inlined or replaced with a normal [format]!
#
#proc ::sha1::f {t B C D} {
# switch [expr {$t/20}] {
# 0 {
# expr {($B & $C) | ((~$B) & $D)}
# } 1 - 3 {
# expr {$B ^ $C ^ $D}
# } 2 {
# expr {($B & $C) | ($B & $D) | ($C & $D)}
# }
# }
#}
#
#proc ::sha1::byte0 {i} {expr {0xff & $i}}
#proc ::sha1::byte1 {i} {expr {(0xff00 & $i) >> 8}}
#proc ::sha1::byte2 {i} {expr {(0xff0000 & $i) >> 16}}
#proc ::sha1::byte3 {i} {expr {((0xff000000 & $i) >> 24) & 0xff}}
#
#proc ::sha1::bytes {i} {
# format %0.2x%0.2x%0.2x%0.2x [byte3 $i] [byte2 $i] [byte1 $i] [byte0 $i]
#}
# hmac: hash for message authentication
proc ::sha1::hmac {key text} {
# if key is longer than 64 bytes, reset it to SHA1(key). If shorter,
# pad it out with null (\x00) chars.
set keyLen [string length $key]
if {$keyLen > 64} {
set key [binary format H32 [sha1 $key]]
set keyLen [string length $key]
}
# ensure the key is padded out to 64 chars with nulls.
set padLen [expr {64 - $keyLen}]
append key [binary format "a$padLen" {}]
# Split apart the key into a list of 16 little-endian words
binary scan $key i16 blocks
# XOR key with ipad and opad values
set k_ipad {}
set k_opad {}
foreach i $blocks {
append k_ipad [binary format i [expr {$i ^ 0x36363636}]]
append k_opad [binary format i [expr {$i ^ 0x5c5c5c5c}]]
}
# Perform inner sha1, appending its results to the outer key
append k_ipad $text
append k_opad [binary format H* [sha1 $k_ipad]]
# Perform outer sha1
sha1 $k_opad
}
}
package provide sha1 1.0.3
|