nfTlWNl rn Ѻq$³*LJ0Y8i(??yD "'o\{4%%p~72%8M+N4f3b(۲#q`d|ԧ`gƠE"kY+d-GZyD%vXg,!XZk- mN:]ӫ ,֓)Y$^VH#N.R};fOi3$K^o\%d|8E_GqKi#^GpFd<5pn_ Eƨ`rs񪇘lRHƷE혬 Yķ oVr>|[ψ̩}kT#L؀ț+ !×4 Ǯ5K#5VT9*s Qfv fhLMy.WϕɺyPٛPlqo<2UJ3Iz2E;"\ih-VM|{\(:EfRO {m ;S9gAA(77A.@{q є2x/(ڔ1tSv^@7 vH+ ?Т]^nxFdB$U@|(1}w Q4"~0ٛPJ0dB$U@|(1}D(ӏ]^UEk V$E̋@B!uM Ps/ a%w,q5jx7f?_.sU1GTXz" /;F!T uh\p1GK`Bա!tWe^pmB}7|#rBEfA1?}j/CuLt 3XNX zo^%%Cm7 FGv k*NLؙ1ɀ|=^a֡o(;;M&)ZTs9 Ç/i?M 0Jz.q:S1> 4OahrJDwcx۷瓯e:%)ޥ}˯=?9RTʥ7d8a8/x9رVˌChZ|m"ooh],lr$cl&N x!((!/.1&k1Nig" RHUS`8^&uLQΪR.]d;߾Ÿ a8C2c8U|M=+B,.9|7wOucnmc$/^9Χ= q;LBӌ7nTIE,*Xv(+m7p'k;< OXp_! *v(B#Y̌PGxil)n>t KÀp=`w,;_/ȱ6w/+ Zp&ŎINMIޱ̕nj_W'‰2yQh;7\B+eh)P@1pD.{}ȼY4ͺ#IB!xPnlmDЇ}d$p[bRe()2(XɘAsaRo]Y v{-pWŒVяfT!$0eۙ>j+ˏ1+kI$9ܲݒAڧ~TI NUK8G<@]?u{B! <&.!:FQ⨳/ ^ B,,`9X.$5K<Qu|EM-&ju-U퍺=y02vk(I'V{Y,;|e&` eHlmoӳO~[4h^Ye"ԄʁLgdW'g<YW{˹z$0e{Sm=Е&F߉Z0=%yC%`& 0R(F (^˺-+$43)H>f6x+b46)hk!CKW4VX」;ܲݒAڧ~ˤN'Fՠ+k#_Bek2AUgpo)cW\{vP5˽O(Zsz#A%y, -M`[cVc`ʱKP|w2dCѫrF$_YGU\_-.+vcLQ/z eWEH;0=cQ ߉Z0=%y9qf .>,PJ#3N_u7Ht|EF+$43)H> Qiq@ƮDH@'X)xxhf=^R0QIX4ƍ/6wd}ef^B1߲ykg&DB )Ї#NډI#34f::%e|ݘғ V+3MV 3fNk'o @q#Vjڕ+$43)H> &uc՟CR]UTTW^z3Z PBmsV4?8s[w+$43)H> 8\uq@ ,g78.0sgnbU3tL/{i=4iI >!UDF1L$c4s"6'_#s]]w;7~$$H'rm#@vW c c;rsĔ$[:hJYGJhg< c6j,x(L{iѡʹVaddJS \_|PV*ndLL.\P4ͺ#IB!x~].S,$:C޿~KݾšIɖI جd_hv{-pWcTf !!dfsւo91^߼@ /E<ߺN#ܲݒAڧ~t̸ටO-w <&L4}xR-HퟂFD,VBb,6S:.>+!k^Eo8 \IUPߓSnQ 1?+*@nVGC@U+S:ÜڼB69(QVAai\Rhb;5s]tkWSP,COq\%P:\Ƀ5mpЌE?rIIBu(\$[)i:uӾyM6Л w3šĖT &S:8D$$gJKK< Q͟h|UM1l~Ŷp0 self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44); self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9); self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60); self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70); self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6); self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa); self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085); self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05); self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039); self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5); self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8); self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665); // ROUND 4 self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244); self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97); self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7); self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039); self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3); self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92); self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d); self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1); self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f); self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0); self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314); self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1); self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82); self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235); self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb); self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391); $this->a = ($this->a + $A) & self::$allOneBits; $this->b = ($this->b + $B) & self::$allOneBits; $this->c = ($this->c + $C) & self::$allOneBits; $this->d = ($this->d + $D) & self::$allOneBits; } private static function f(int $X, int $Y, int $Z): int { return ($X & $Y) | ((~$X) & $Z); // X AND Y OR NOT X AND Z } private static function g(int $X, int $Y, int $Z): int { return ($X & $Z) | ($Y & (~$Z)); // X AND Z OR Y AND NOT Z } private static function h(int $X, int $Y, int $Z): int { return $X ^ $Y ^ $Z; // X XOR Y XOR Z } private static function i(int $X, int $Y, int $Z): int { return $Y ^ ($X | (~$Z)); // Y XOR (X OR NOT Z) } /** @param float|int $t may be float on 32-bit system */ private static function step(callable $func, int &$A, int $B, int $C, int $D, int $M, int $s, $t): void { $t = self::signedInt($t); $A = (int) ($A + call_user_func($func, $B, $C, $D) + $M + $t) & self::$allOneBits; $A = self::rotate($A, $s); $A = (int) ($B + $A) & self::$allOneBits; } /** @param float|int $result may be float on 32-bit system */ private static function signedInt($result): int { return is_int($result) ? $result : (int) (PHP_INT_MIN + $result - 1 - PHP_INT_MAX); } private static function rotate(int $decimal, int $bits): int { $binary = str_pad(decbin($decimal), 32, '0', STR_PAD_LEFT); return self::signedInt(bindec(substr($binary, $bits) . substr($binary, 0, $bits))); } }