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