00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 package require Tcl 8.2;
00029
00030
00031 namespace ::ripemd {
00032 namespace ripemd160 {
00033 variable version 1.0.3
00034 variable rcsid {$Id: ripemd160.tcl,v 1.7 2005/02/24 03:25:50 patthoyts Exp $}
00035 variable accel
00036 array accel = {cryptkit 0 trf 0}
00037
00038 variable uid
00039 if {![info exists uid]} {
00040 uid = 0
00041 }
00042
00043 namespace export ripemd160 hmac160 Hex \
00044 RIPEMD160Init RIPEMD160Update RIPEMD160Final \
00045 RIPEHMAC160Init RIPEHMAC160Update RIPEHMAC160Final
00046 }
00047 }
00048
00049
00050
00051
00052
00053
00054 ret ::ripemd::ripemd160::RIPEMD160Init () {
00055 variable accel
00056 variable uid
00057 set token [namespace current]::[incr uid]
00058 upvar #0 $token state
00059
00060 # Initialize RIPEMD-160 state structure (same as MD4).
00061 array set state \
00062 [list \
00063 A [expr {0x67452301}] \
00064 B [expr {0xefcdab89}] \
00065 C [expr {0x98badcfe}] \
00066 D [expr {0x10325476}] \
00067 E [expr {0xc3d2e1f0}] \
00068 n 0 i "" ]
00069 if {$accel(cryptkit)} {
00070 cryptkit::cryptCreateContext state(ckctx) \
00071 CRYPT_UNUSED CRYPT_ALGO_RIPEMD160
00072 } elseif {$accel(trf)} {
00073 set s {}
00074 switch -exact -- $::tcl_platform(platform) {
00075 windows { set s [open NUL w] }
00076 unix { set s [open /dev/null w] }
00077 }
00078 if {$s != {}} {
00079 fconfigure $s -translation binary -buffering none
00080 ::ripemd160 -attach $s -mode write \
00081 -read-type variable \
00082 -read-destination [subst $token](trfread) \
00083 -write-type variable \
00084 -write-destination [subst $token](trfwrite)
00085 array set state [list trfread 0 trfwrite 0 trf $s]
00086 }
00087 }
00088 return $token
00089 }
00090
00091 ret ::ripemd::ripemd160::RIPEMD160Update (type token , type data) {
00092 upvar #0 $token state
00093
00094 if {[info exists state(ckctx)]} {
00095 if {[string length $data] > 0} {
00096 cryptkit::cryptEncrypt $state(ckctx) $data
00097 }
00098 return
00099 } elseif {[info exists state(trf)]} {
00100 puts -nonewline $state(trf) $data
00101 return
00102 }
00103
00104 # Update the state values
00105 incr state(n) [string length $data]
00106 append state(i) $data
00107
00108 # Calculate the hash for any complete blocks
00109 set len [string length $state(i)]
00110 for {set n 0} {($n + 64) <= $len} {} {
00111 RIPEMD160Hash $token [string range $state(i) $n [incr n 64]]
00112 }
00113
00114 # Adjust the state for the blocks completed.
00115 set state(i) [string range $state(i) $n end]
00116 return
00117 }
00118
00119 ret ::ripemd::ripemd160::RIPEMD160Final (type token) {
00120 upvar #0 $token state
00121
00122 if {[info exists state(ckctx)]} {
00123 cryptkit::cryptEncrypt $state(ckctx) ""
00124 cryptkit::cryptGetAttributeString $state(ckctx) \
00125 CRYPT_CTXINFO_HASHVALUE r 20
00126 cryptkit::cryptDestroyContext $state(ckctx)
00127 # If nothing was hashed, we get no r variable set!
00128 if {[info exists r]} {
00129 unset state
00130 return $r
00131 }
00132 } elseif {[info exists state(trf)]} {
00133 close $state(trf)
00134 set r $state(trfwrite)
00135 unset state
00136 return $r
00137 }
00138
00139 # Padding
00140 #
00141 set len [string length $state(i)]
00142 set pad [expr {56 - ($len % 64)}]
00143 if {$len % 64 > 56} {
00144 incr pad 64
00145 }
00146 if {$pad == 0} {
00147 incr pad 64
00148 }
00149 append state(i) [binary format a$pad \x80]
00150
00151 # Append length in bits as little-endian wide int.
00152 append state(i) [binary format ii [expr {8 * $state(n)}] 0]
00153
00154 # Calculate the hash for the remaining block.
00155 set len [string length $state(i)]
00156 for {set n 0} {($n + 64) <= $len} {} {
00157 RIPEMD160Hash $token [string range $state(i) $n [incr n 64]]
00158 }
00159
00160 # Output
00161 set r [bytes $state(A)][bytes $state(B)][bytes $state(C)][bytes $state(D)][bytes $state(E)]
00162 unset state
00163 return $r
00164 }
00165
00166
00167
00168
00169
00170
00171 ret ::ripemd::ripemd160::RIPEHMAC160Init (type K) {
00172
00173 # Key K is adjusted to be 64 bytes long. If K is larger, then use
00174 # the RIPEMD-160 digest of K and pad this instead.
00175 set len [string length $K]
00176 if {$len > 64} {
00177 set tok [RIPEMD160Init]
00178 RIPEMD160Update $tok $K
00179 set K [RIPEMD160Final $tok]
00180 set len [string length $K]
00181 }
00182 set pad [expr {64 - $len}]
00183 append K [string repeat \0 $pad]
00184
00185 # Cacluate the padding buffers.
00186 set Ki {}
00187 set Ko {}
00188 binary scan $K i16 Ks
00189 foreach k $Ks {
00190 append Ki [binary format i [expr {$k ^ 0x36363636}]]
00191 append Ko [binary format i [expr {$k ^ 0x5c5c5c5c}]]
00192 }
00193
00194 set tok [RIPEMD160Init]
00195 RIPEMD160Update $tok $Ki; # initialize with the inner pad
00196
00197 # preserve the Ko value for the final stage.
00198 # FRINK: nocheck
00199 set [subst $tok](Ko) $Ko
00200
00201 return $tok
00202 }
00203
00204 ret ::ripemd::ripemd160::RIPEHMAC160Update (type token , type data) {
00205 RIPEMD160Update $token $data
00206 return
00207 }
00208
00209 ret ::ripemd::ripemd160::RIPEHMAC160Final (type token) {
00210 # FRINK: nocheck
00211 variable $token
00212 upvar 0 $token state
00213
00214 set tok [RIPEMD160Init]; # init the outer hashing function
00215 RIPEMD160Update $tok $state(Ko); # prepare with the outer pad.
00216 RIPEMD160Update $tok [RIPEMD160Final $token]; # hash the inner result
00217 return [RIPEMD160Final $tok]
00218 }
00219
00220
00221
00222 ::ripemd = ::ripemd160::RIPEMD160Hash_body {
00223 variable $token
00224 upvar 0 $token state
00225
00226 binary scan $msg i* blocks
00227 foreach {X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15} $blocks {
00228 A = $state(A) ; AA = $state(A)
00229 B = $state(B) ; BB = $state(B)
00230 C = $state(C) ; CC = $state(C)
00231 D = $state(D) ; DD = $state(D)
00232 E = $state(E) ; EE = $state(E)
00233
00234 FF A B C D E $X0 11
00235 FF E A B C D $X1 14
00236 FF D E A B C $X2 15
00237 FF C D E A B $X3 12
00238 FF B C D E A $X4 5
00239 FF A B C D E $X5 8
00240 FF E A B C D $X6 7
00241 FF D E A B C $X7 9
00242 FF C D E A B $X8 11
00243 FF B C D E A $X9 13
00244 FF A B C D E $X10 14
00245 FF E A B C D $X11 15
00246 FF D E A B C $X12 6
00247 FF C D E A B $X13 7
00248 FF B C D E A $X14 9
00249 FF A B C D E $X15 8
00250
00251 GG E A B C D $X7 7
00252 GG D E A B C $X4 6
00253 GG C D E A B $X13 8
00254 GG B C D E A $X1 13
00255 GG A B C D E $X10 11
00256 GG E A B C D $X6 9
00257 GG D E A B C $X15 7
00258 GG C D E A B $X3 15
00259 GG B C D E A $X12 7
00260 GG A B C D E $X0 12
00261 GG E A B C D $X9 15
00262 GG D E A B C $X5 9
00263 GG C D E A B $X2 11
00264 GG B C D E A $X14 7
00265 GG A B C D E $X11 13
00266 GG E A B C D $X8 12
00267
00268 HH D E A B C $X3 11
00269 HH C D E A B $X10 13
00270 HH B C D E A $X14 6
00271 HH A B C D E $X4 7
00272 HH E A B C D $X9 14
00273 HH D E A B C $X15 9
00274 HH C D E A B $X8 13
00275 HH B C D E A $X1 15
00276 HH A B C D E $X2 14
00277 HH E A B C D $X7 8
00278 HH D E A B C $X0 13
00279 HH C D E A B $X6 6
00280 HH B C D E A $X13 5
00281 HH A B C D E $X11 12
00282 HH E A B C D $X5 7
00283 HH D E A B C $X12 5
00284
00285 II C D E A B $X1 11
00286 II B C D E A $X9 12
00287 II A B C D E $X11 14
00288 II E A B C D $X10 15
00289 II D E A B C $X0 14
00290 II C D E A B $X8 15
00291 II B C D E A $X12 9
00292 II A B C D E $X4 8
00293 II E A B C D $X13 9
00294 II D E A B C $X3 14
00295 II C D E A B $X7 5
00296 II B C D E A $X15 6
00297 II A B C D E $X14 8
00298 II E A B C D $X5 6
00299 II D E A B C $X6 5
00300 II C D E A B $X2 12
00301
00302 JJ B C D E A $X4 9
00303 JJ A B C D E $X0 15
00304 JJ E A B C D $X5 5
00305 JJ D E A B C $X9 11
00306 JJ C D E A B $X7 6
00307 JJ B C D E A $X12 8
00308 JJ A B C D E $X2 13
00309 JJ E A B C D $X10 12
00310 JJ D E A B C $X14 5
00311 JJ C D E A B $X1 12
00312 JJ B C D E A $X3 13
00313 JJ A B C D E $X8 14
00314 JJ E A B C D $X11 11
00315 JJ D E A B C $X6 8
00316 JJ C D E A B $X15 5
00317 JJ B C D E A $X13 6
00318
00319 JJJ AA BB CC DD EE $X5 8
00320 JJJ EE AA BB CC DD $X14 9
00321 JJJ DD EE AA BB CC $X7 9
00322 JJJ CC DD EE AA BB $X0 11
00323 JJJ BB CC DD EE AA $X9 13
00324 JJJ AA BB CC DD EE $X2 15
00325 JJJ EE AA BB CC DD $X11 15
00326 JJJ DD EE AA BB CC $X4 5
00327 JJJ CC DD EE AA BB $X13 7
00328 JJJ BB CC DD EE AA $X6 7
00329 JJJ AA BB CC DD EE $X15 8
00330 JJJ EE AA BB CC DD $X8 11
00331 JJJ DD EE AA BB CC $X1 14
00332 JJJ CC DD EE AA BB $X10 14
00333 JJJ BB CC DD EE AA $X3 12
00334 JJJ AA BB CC DD EE $X12 6
00335
00336 III EE AA BB CC DD $X6 9
00337 III DD EE AA BB CC $X11 13
00338 III CC DD EE AA BB $X3 15
00339 III BB CC DD EE AA $X7 7
00340 III AA BB CC DD EE $X0 12
00341 III EE AA BB CC DD $X13 8
00342 III DD EE AA BB CC $X5 9
00343 III CC DD EE AA BB $X10 11
00344 III BB CC DD EE AA $X14 7
00345 III AA BB CC DD EE $X15 7
00346 III EE AA BB CC DD $X8 12
00347 III DD EE AA BB CC $X12 7
00348 III CC DD EE AA BB $X4 6
00349 III BB CC DD EE AA $X9 15
00350 III AA BB CC DD EE $X1 13
00351 III EE AA BB CC DD $X2 11
00352
00353 HHH DD EE AA BB CC $X15 9
00354 HHH CC DD EE AA BB $X5 7
00355 HHH BB CC DD EE AA $X1 15
00356 HHH AA BB CC DD EE $X3 11
00357 HHH EE AA BB CC DD $X7 8
00358 HHH DD EE AA BB CC $X14 6
00359 HHH CC DD EE AA BB $X6 6
00360 HHH BB CC DD EE AA $X9 14
00361 HHH AA BB CC DD EE $X11 12
00362 HHH EE AA BB CC DD $X8 13
00363 HHH DD EE AA BB CC $X12 5
00364 HHH CC DD EE AA BB $X2 14
00365 HHH BB CC DD EE AA $X10 13
00366 HHH AA BB CC DD EE $X0 13
00367 HHH EE AA BB CC DD $X4 7
00368 HHH DD EE AA BB CC $X13 5
00369
00370 GGG CC DD EE AA BB $X8 15
00371 GGG BB CC DD EE AA $X6 5
00372 GGG AA BB CC DD EE $X4 8
00373 GGG EE AA BB CC DD $X1 11
00374 GGG DD EE AA BB CC $X3 14
00375 GGG CC DD EE AA BB $X11 14
00376 GGG BB CC DD EE AA $X15 6
00377 GGG AA BB CC DD EE $X0 14
00378 GGG EE AA BB CC DD $X5 6
00379 GGG DD EE AA BB CC $X12 9
00380 GGG CC DD EE AA BB $X2 12
00381 GGG BB CC DD EE AA $X13 9
00382 GGG AA BB CC DD EE $X9 12
00383 GGG EE AA BB CC DD $X7 5
00384 GGG DD EE AA BB CC $X10 15
00385 GGG CC DD EE AA BB $X14 8
00386
00387 FFF BB CC DD EE AA $X12 8
00388 FFF AA BB CC DD EE $X15 5
00389 FFF EE AA BB CC DD $X10 12
00390 FFF DD EE AA BB CC $X4 9
00391 FFF CC DD EE AA BB $X1 12
00392 FFF BB CC DD EE AA $X5 5
00393 FFF AA BB CC DD EE $X8 14
00394 FFF EE AA BB CC DD $X7 6
00395 FFF DD EE AA BB CC $X6 8
00396 FFF CC DD EE AA BB $X2 13
00397 FFF BB CC DD EE AA $X13 6
00398 FFF AA BB CC DD EE $X14 5
00399 FFF EE AA BB CC DD $X0 15
00400 FFF DD EE AA BB CC $X3 13
00401 FFF CC DD EE AA BB $X9 11
00402 FFF BB CC DD EE AA $X11 11
00403
00404
00405 DD = [expr {$state(B) + $C + $DD}]
00406 state = (B) [expr {$state(C) + $D + $EE}]
00407 state = (C) [expr {$state(D) + $E + $AA}]
00408 state = (D) [expr {$state(E) + $A + $BB}]
00409 state = (E) [expr {$state(A) + $B + $CC}]
00410 state = (A) $DD
00411 }
00412
00413 return
00414 }
00415
00416 ret ::ripemd::ripemd160::byte (type n , type v) {expr {((0xFF << (8 * $n)) & $v) >> (8 * $n)}}
00417 ret ::ripemd::ripemd160::bytes (type v) {
00418 #format %c%c%c%c [byte 0 $v] [byte 1 $v] [byte 2 $v] [byte 3 $v]
00419 format %c%c%c%c \
00420 [expr {0xFF & $v}] \
00421 [expr {(0xFF00 & $v) >> 8}] \
00422 [expr {(0xFF0000 & $v) >> 16}] \
00423 [expr {((0xFF000000 & $v) >> 24) & 0xFF}]
00424 }
00425
00426
00427 ret ::ripemd::ripemd160::F (type X , type Y , type Z) {
00428 return [expr {$X ^ $Y ^ $Z}]
00429 }
00430
00431 ret ::ripemd::ripemd160::G (type X , type Y , type Z) {
00432 return [expr {($X & $Y) | (~$X & $Z)}]
00433 }
00434
00435 ret ::ripemd::ripemd160::H (type X , type Y , type Z) {
00436 return [expr {($X | ~$Y) ^ $Z}]
00437 }
00438
00439 ret ::ripemd::ripemd160::I (type X , type Y , type Z) {
00440 return [expr {($X & $Z) | ($Y & ~$Z)}]
00441 }
00442
00443 ret ::ripemd::ripemd160::J (type X , type Y , type Z) {
00444 return [expr {($X ^ ($Y | ~$Z))}]
00445 }
00446
00447 ret ::ripemd::ripemd160::FF (type a , type b , type c , type d , type e , type x , type s) {
00448 upvar $a A $b B $c C $d D $e E
00449 set A [<<< [expr {$A + ($B ^ $C ^ $D) + $x}] $s]
00450 incr A $E
00451 set C [<<< $C 10]
00452 }
00453
00454 ret ::ripemd::ripemd160::GG (type a , type b , type c , type d , type e , type x , type s) {
00455 upvar $a A $b B $c C $d D $e E
00456 set A [<<< [expr {$A + (($B & $C) | (~$B & $D)) + $x + 0x5a827999}] $s]
00457 incr A $E
00458 set C [<<< $C 10]
00459 }
00460
00461 ret ::ripemd::ripemd160::HH (type a , type b , type c , type d , type e , type x , type s) {
00462 upvar $a A $b B $c C $d D $e E
00463 set A [<<< [expr {$A + (($B | ~$C) ^ $D) + $x + 0x6ed9eba1}] $s]
00464 incr A $E
00465 set C [<<< $C 10]
00466 }
00467
00468 ret ::ripemd::ripemd160::II (type a , type b , type c , type d , type e , type x , type s) {
00469 upvar $a A $b B $c C $d D $e E
00470 set A [<<< [expr {$A + (($B & $D)|($C & ~$D)) + $x + 0x8f1bbcdc}] $s]
00471 incr A $E
00472 set C [<<< $C 10]
00473
00474 }
00475
00476 ret ::ripemd::ripemd160::JJ (type a , type b , type c , type d , type e , type x , type s) {
00477 upvar $a A $b B $c C $d D $e E
00478 set A [<<< [expr {$A + ($B ^ ($C | ~$D)) + $x + 0xa953fd4e}] $s]
00479 incr A $E
00480 set C [<<< $C 10]
00481 }
00482
00483
00484 ret ::ripemd::ripemd160::FFF (type a , type b , type c , type d , type e , type x , type s) {
00485 upvar $a A $b B $c C $d D $e E
00486 set A [<<< [expr {$A + ($B ^ $C ^ $D) + $x}] $s]
00487 incr A $E
00488 set C [<<< $C 10]
00489 }
00490
00491 ret ::ripemd::ripemd160::GGG (type a , type b , type c , type d , type e , type x , type s) {
00492 upvar $a A $b B $c C $d D $e E
00493 set A [<<< [expr {$A + (($B & $C) | (~$B & $D)) + $x + 0x7a6d76e9}] $s]
00494 incr A $E
00495 set C [<<< $C 10]
00496 }
00497
00498 ret ::ripemd::ripemd160::HHH (type a , type b , type c , type d , type e , type x , type s) {
00499 upvar $a A $b B $c C $d D $e E
00500 set A [<<< [expr {$A + (($B | ~$C) ^ $D) + $x + 0x6d703ef3}] $s]
00501 incr A $E
00502 set C [<<< $C 10]
00503 }
00504
00505 ret ::ripemd::ripemd160::III (type a , type b , type c , type d , type e , type x , type s) {
00506 upvar $a A $b B $c C $d D $e E
00507 set A [<<< [expr {$A + (($B & $D)|($C & ~$D)) + $x + 0x5c4dd124}] $s]
00508 incr A $E
00509 set C [<<< $C 10]
00510
00511 }
00512
00513 ret ::ripemd::ripemd160::JJJ (type a , type b , type c , type d , type e , type x , type s) {
00514 upvar $a A $b B $c C $d D $e E
00515 set A [<<< [expr {$A + ($B ^ ($C | ~$D)) + $x + 0x50a28be6}] $s]
00516 incr A $E
00517 set C [<<< $C 10]
00518 }
00519
00520
00521 ret ::ripemd::ripemd160::<<< (type v , type n) {
00522 return [expr {((($v << $n) \
00523 | (($v >> (32 - $n)) \
00524 & (0x7FFFFFFF >> (31 - $n))))) \
00525 & 0xFFFFFFFF}]
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539 namespace ::ripemd::ripemd160 {
00540
00541
00542 Split = {(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\d+)}
00543
00544 regsub -all -line \
00545 "^\\s+FFF?\\s+$Split$" \
00546 $RIPEMD160Hash_body \
00547 { \1 [<<< [expr = {$\1 + ($\2 ^ $\3 ^ $\4) + \6}] \7];\
00548 incr \1 $\5; \3 [<<< $\3 10]} \
00549 RIPEMD160Hash = _body
00550
00551
00552 regsub -all -line \
00553 "^\\s+GG\\s+$Split$" \
00554 $RIPEMD160Hash_body \
00555 { \1 [<<< [expr = {$\1 + (($\2 \& $\3) | (~$\2 \& $\4)) + \6 \
00556 + 0x5a827999}] \7];\
00557 incr \1 $\5; \3 [<<< $\3 10]} \
00558 RIPEMD160Hash = _body
00559
00560
00561 regsub -all -line \
00562 "^\\s+GGG\\s+$Split$" \
00563 $RIPEMD160Hash_body \
00564 { \1 [<<< [expr = {$\1 + (($\2 \& $\3) | (~$\2 \& $\4)) + \6 \
00565 + 0x7a6d76e9}] \7];\
00566 incr \1 $\5; \3 [<<< $\3 10]} \
00567 RIPEMD160Hash = _body
00568
00569
00570 regsub -all -line \
00571 "^\\s+HH\\s+$Split$" \
00572 $RIPEMD160Hash_body \
00573 { \1 [<<< [expr = {$\1 + (($\2 | ~$\3) ^ $\4) + \6 \
00574 + 0x6ed9eba1}] \7];\
00575 incr \1 $\5; \3 [<<< $\3 10]} \
00576 RIPEMD160Hash = _body
00577
00578
00579 regsub -all -line \
00580 "^\\s+HHH\\s+$Split$" \
00581 $RIPEMD160Hash_body \
00582 { \1 [<<< [expr = {$\1 + (($\2 | ~$\3) ^ $\4) + \6 \
00583 + 0x6d703ef3}] \7];\
00584 incr \1 $\5; \3 [<<< $\3 10]} \
00585 RIPEMD160Hash = _body
00586
00587
00588 regsub -all -line \
00589 "^\\s+II\\s+$Split$" \
00590 $RIPEMD160Hash_body \
00591 { \1 [<<< [expr = {$\1 + (($\2 \& $\4) | ($\3 \& ~$\4)) + \6 \
00592 + 0x8f1bbcdc}] \7];\
00593 incr \1 $\5; \3 [<<< $\3 10]} \
00594 RIPEMD160Hash = _body
00595
00596
00597 regsub -all -line \
00598 "^\\s+III\\s+$Split$" \
00599 $RIPEMD160Hash_body \
00600 { \1 [<<< [expr = {$\1 + (($\2 \& $\4) | ($\3 \& ~$\4)) + \6 \
00601 + 0x5c4dd124}] \7];\
00602 incr \1 $\5; \3 [<<< $\3 10]} \
00603 RIPEMD160Hash = _body
00604
00605
00606 regsub -all -line \
00607 "^\\s+JJ\\s+$Split$" \
00608 $RIPEMD160Hash_body \
00609 { \1 [<<< [expr = {$\1 + ($\2 ^ ($\3 | ~$\4)) + \6 \
00610 + 0xa953fd4e}] \7];\
00611 incr \1 $\5; \3 [<<< $\3 10]} \
00612 RIPEMD160Hash = _body
00613
00614
00615 regsub -all -line \
00616 "^\\s+JJJ\\s+$Split$" \
00617 $RIPEMD160Hash_body \
00618 { \1 [<<< [expr = {$\1 + ($\2 ^ ($\3 | ~$\4)) + \6 \
00619 + 0x50a28be6}] \7];\
00620 incr \1 $\5; \3 [<<< $\3 10]} \
00621 RIPEMD160Hash = _body
00622
00623
00624 regsub -all -line \
00625 {\[<<< (\$\S+)\s+(\d+)\]$} \
00626 $RIPEMD160Hash_body \
00627 {[expr {(((\1 << \2) \
00628 | ((\1 >> (32 - \2)) \
00629 \& (0x7FFFFFFF >> (31 - \2))))) \
00630 \& 0xFFFFFFFF}]} \
00631 RIPEMD160Hash_body
00632 }
00633
00634
00635
00636
00637 ret ::ripemd::ripemd160::RIPEMD160Hash (type token , type msg) \
00638 $::ripemd::ripemd160::RIPEMD160Hash_body
00639
00640 # -------------------------------------------------------------------------
00641
00642 proc ::ripemd::ripemd160::Hex {data} {
00643 binary scan $data H* result
00644 return $result
00645 }
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 ret ::ripemd::ripemd160::LoadAccelerator (type name) {
00658 variable accel
00659 set r 0
00660 switch -exact -- $name {
00661 #critcl {
00662 # if {![catch {package require tcllibc}]
00663 # || ![catch {package require sha1c}]} {
00664 # set r [expr {[info command ::sha1::sha1c] != {}}]
00665 # }
00666 #}
00667 cryptkit {
00668 if {![catch {package require cryptkit}]} {
00669 set r [expr {![catch {cryptkit::cryptInit}]}]
00670 }
00671 }
00672 trf {
00673 if {![catch {package require Trf}]} {
00674 set r [expr {![catch {::ripemd160 aa} msg]}]
00675 }
00676 }
00677 default {
00678 return -code error "invalid accelerator package:\
00679 must be one of [join [array names accel] {, }]"
00680 }
00681 }
00682 set accel($name) $r
00683 }
00684
00685
00686
00687
00688
00689
00690 ret ::ripemd::ripemd160::Pop (type varname , optional nth =0) {
00691 upvar $varname args
00692 set r [lindex $args $nth]
00693 set args [lreplace $args $nth $nth]
00694 return $r
00695 }
00696
00697
00698
00699
00700
00701 ret ::ripemd::ripemd160::Chunk (type token , type channel , optional chunksize =4096) {
00702 # FRINK: nocheck
00703 variable $token
00704 upvar 0 $token state
00705
00706 if {[eof $channel]} {
00707 fileevent $channel readable {}
00708 set state(reading) 0
00709 }
00710
00711 RIPEMD160Update $token [read $channel $chunksize]
00712 }
00713
00714
00715
00716 ret ::ripemd::ripemd160::ripemd160 (type args) {
00717 array set opts {-hex 0 -filename {} -channel {} -chunksize 4096}
00718 while {[string match -* [set option [lindex $args 0]]]} {
00719 switch -glob -- $option {
00720 -hex { set opts(-hex) 1 }
00721 -file* { set opts(-filename) [Pop args 1] }
00722 -channel { set opts(-channel) [Pop args 1] }
00723 -chunksize { set opts(-chunksize) [Pop args 1] }
00724 default {
00725 if {[llength $args] == 1} { break }
00726 if {[string compare $option "--"] == 0} { Pop args; break }
00727 set err [join [lsort [array names opts]] ", "]
00728 return -code error "bad option $option:\
00729 must be one of $err"
00730 }
00731 }
00732 Pop args
00733 }
00734
00735 if {$opts(-filename) != {}} {
00736 set opts(-channel) [open $opts(-filename) r]
00737 fconfigure $opts(-channel) -translation binary
00738 }
00739
00740 if {$opts(-channel) == {}} {
00741
00742 if {[llength $args] != 1} {
00743 return -code error "wrong # args:\
00744 should be \"ripemd160 ?-hex? -filename file | string\""
00745 }
00746 set tok [RIPEMD160Init]
00747 RIPEMD160Update $tok [lindex $args 0]
00748 set r [RIPEMD160Final $tok]
00749
00750 } else {
00751
00752 set tok [RIPEMD160Init]
00753 # FRINK: nocheck
00754 set [subst $tok](reading) 1
00755 fileevent $opts(-channel) readable \
00756 [list [namespace origin Chunk] \
00757 $tok $opts(-channel) $opts(-chunksize)]
00758 vwait [subst $tok](reading)
00759 set r [RIPEMD160Final $tok]
00760
00761 # If we opened the channel - we should close it too.
00762 if {$opts(-filename) != {}} {
00763 close $opts(-channel)
00764 }
00765 }
00766
00767 if {$opts(-hex)} {
00768 set r [Hex $r]
00769 }
00770 return $r
00771 }
00772
00773
00774
00775 ret ::ripemd::ripemd160::hmac160 (type args) {
00776 array set opts {-hex 0 -filename {} -channel {} -chunksize 4096}
00777 while {[string match -* [set option [lindex $args 0]]]} {
00778 switch -glob -- $option {
00779 -key { set opts(-key) [Pop args 1] }
00780 -hex { set opts(-hex) 1 }
00781 -file* { set opts(-filename) [Pop args 1] }
00782 -channel { set opts(-channel) [Pop args 1] }
00783 -chunksize { set opts(-chunksize) [Pop args 1] }
00784 default {
00785 if {[llength $args] == 1} { break }
00786 if {[string compare $option "--"] == 0} { Pop args; break }
00787 set err [join [lsort [array names opts]] ", "]
00788 return -code error "bad option $option:\
00789 must be one of $err"
00790 }
00791 }
00792 Pop args
00793 }
00794
00795 if {![info exists opts(-key)]} {
00796 return -code error "wrong # args:\
00797 should be \"hmac160 ?-hex? -key key -filename file | string\""
00798 }
00799
00800 if {$opts(-filename) != {}} {
00801 set opts(-channel) [open $opts(-filename) r]
00802 fconfigure $opts(-channel) -translation binary
00803 }
00804
00805 if {$opts(-channel) == {}} {
00806
00807 if {[llength $args] != 1} {
00808 return -code error "wrong # args:\
00809 should be \"hmac160 ?-hex? -key key -filename file | string\""
00810 }
00811 set tok [RIPEHMAC160Init $opts(-key)]
00812 RIPEHMAC160Update $tok [lindex $args 0]
00813 set r [RIPEHMAC160Final $tok]
00814
00815 } else {
00816
00817 set tok [RIPEHMAC160Init $opts(-key)]
00818 # FRINK: nocheck
00819 set [subst $tok](reading) 1
00820 fileevent $opts(-channel) readable \
00821 [list [namespace origin Chunk] \
00822 $tok $opts(-channel) $opts(-chunksize)]
00823 vwait [subst $tok](reading)
00824 set r [RIPEHMAC160Final $tok]
00825
00826 # If we opened the channel - we should close it too.
00827 if {$opts(-filename) != {}} {
00828 close $opts(-channel)
00829 }
00830 }
00831
00832 if {$opts(-hex)} {
00833 set r [Hex $r]
00834 }
00835 return $r
00836 }
00837
00838
00839
00840 namespace ::ripemd {
00841
00842 namespace import -force [namespace current]::ripemd160::*
00843
00844 namespace export ripemd160 hmac160 \
00845 RIPEMD160Init RIPEMD160Update RIPEMD160Final \
00846 RIPEHMAC160Init RIPEHMAC160Update RIPEHMAC160Final
00847 }
00848
00849
00850
00851
00852 namespace ::ripemd::ripemd160 {
00853 foreach e {cryptkit trf} { if {[LoadAccelerator $e]} { break } }
00854 }
00855
00856 package provide ripemd160 $::ripemd::ripemd160::version
00857
00858
00859
00860
00861
00862
00863
00864
00865