##########------------------------------------------------ ########## Arc4 if [llength [info commands p7proc]] { set Compiling true } else { set Compiling false source testing.tcl } if $Compiling { p7class Arc4 { (int)x (int)y (uni*)s } p7proc (tcl)to_hex (tcl)bytes { set (byt*)b $bytes set (tcl)z loop (int)i [len $b] { append z [to_hex $b($i)] } set z } p7proc (byt*)to_hex (int)n { set (int)hi ((n>>4)&15) set (int)lo ((n )&15) new (byt*)z 3 if (hi<10) { set z(0) ('0'+hi) } else { set z(0) ('A'+hi-10) } if (lo<10) { set z(1) ('0'+lo) } else { set z(1) ('A'+lo-10) } set z(2) (' ') set z } p7proc (tcl)dump { (Arc4)this } { set (tcl)z "x=$x y=$y " loop (int)i 256 { append z " [to_hex (s[i])]" } set z } p7proc (Arc4)arcfour_init { (uni*)key } { new (Arc4)p new (uni*)s 256 set p(s) $s loop (int)i 256 { set p(s)($i) $i } set (int)a 0 set (int)b 0 set (int)keylen [len $key] loop (int)j 256 { set b (( $key($a) + $p(s)($j) + $b ) % 256) set (int)temp $s($b) set s($b) $s($j) set s($j) $temp set a ( ($a+1) % $keylen ) } return $p } p7proc (uni*)arcfour_crypt_OLD { (Arc4)p (uni*)buf } { new (uni*)z [len $buf] loop (int)i [len $buf] { set p(x) ( ($p(x) + 1 ) % 256 ) set p(y) ( ($p(y) + $p(s)($p(x))) % 256 ) #set (int)temp $p(s)($p(s)($p(y))) #set p(s)($p(s)($p(y))) $p(s)($p(s)($p(x))) #set p(s)($p(s)($p(x))) $temp set (int)temp $p(s)($p(y)) set p(s)($p(y)) $p(s)($p(x)) set p(s)($p(x)) $temp set (int)j ( $p(s)( 255 & ($p(s)($p(x)) + $p(s)($p(y))) ) ) set z($i) ( $buf($i) ^ j ) # ::puts "i $i x $p(x) y $p(y) ... buf(i) $buf($i) j $j z(i) $z($i)" # ::puts "z(0) $z(0)" # ::puts "z(1) $z(1)" # ::puts "z(2) $z(2)" # ::puts "z(3) $z(3)" } set z } p7proc (uni*)arcfour_crypt { (Arc4)this (uni*)buf } { new (uni*)z [len $buf] loop (int)i [len $buf] { set x ( (x + 1) & 255 ) set y ( (y + s(x)) & 255 ) set (int)temp $s($y) set s($y) $s($x) set s($x) $temp set (int)xor ( s[ 255 & ( s[x] + s[y] ) ] ) set z($i) ( buf[i] ^ xor ) } set z } } else { # The output of ./c_arcfour must not be read as utf8. # encoding 'ascii' seems to be like binary. encoding system ascii set key "aerodynamic" set plain "home made pies" set c_cypher [exec echo -n $plain | ./c_arcfour $key] set state [arcfour_init $key] set cypher [arcfour_crypt $state $plain] AssertEq [to_hex $c_cypher] { to_hex $cypher } set state [arcfour_init $key] AssertEq $plain { arcfour_crypt $state $cypher } set state [arcfour_init $key] set cypher [arcfour_crypt_OLD $state $plain] AssertEq [to_hex $c_cypher] { to_hex $cypher } Okay }