1  
     8  import com.sekati.crypt.IHash;
     9  
    10  
    14  class com.sekati.crypt.SHA256 implements IHash {
    15  
    16  	
    17  	
    18  	
    19  	
    20  	
    21  	
    26  	public static function calculate(str:String):String {
    27  		return hex_sha256( str );
    28  	}
    29  
    30  	private static function safe_add(x:Number, y:Number):Number {
    31  		var lsw:Number = (x & 0xFFFF) + (y & 0xFFFF);
    32  		var msw:Number = (x >> 16) + (y >> 16) + (lsw >> 16);
    33  		return (msw << 16) | (lsw & 0xFFFF);
    34  	}
    35  
    36  	private static function S(X:Number, n:Number):Number { 
    37  		return (X >>> n) | (X << (32 - n)); 
    38  	}
    39  
    40  	private static function R(X:Number, n:Number):Number { 
    41  		return (X >>> n); 
    42  	}
    43  
    44  	private static function Ch(x:Number, y:Number, z:Number):Number { 
    45  		return ((x & y) ^ ((~x) & z)); 
    46  	}
    47  
    48  	private static function Maj(x:Number, y:Number, z:Number):Number { 
    49  		return ((x & y) ^ (x & z) ^ (y & z)); 
    50  	}
    51  
    52  	private static function Sigma0256(x:Number):Number { 
    53  		return (S( x, 2 ) ^ S( x, 13 ) ^ S( x, 22 )); 
    54  	}
    55  
    56  	private static function Sigma1256(x:Number):Number { 
    57  		return (S( x, 6 ) ^ S( x, 11 ) ^ S( x, 25 )); 
    58  	}
    59  
    60  	private static function Gamma0256(x:Number):Number { 
    61  		return (S( x, 7 ) ^ S( x, 18 ) ^ R( x, 3 )); 
    62  	}
    63  
    64  	private static function Gamma1256(x:Number):Number { 
    65  		return (S( x, 17 ) ^ S( x, 19 ) ^ R( x, 10 )); 
    66  	}
    67  
    68  	private static function Sigma0512(x:Number):Number { 
    69  		return (S( x, 28 ) ^ S( x, 34 ) ^ S( x, 39 )); 
    70  	}
    71  
    72  	private static function Sigma1512(x:Number):Number { 
    73  		return (S( x, 14 ) ^ S( x, 18 ) ^ S( x, 41 )); 
    74  	}
    75  
    76  	private static function Gamma0512(x:Number):Number { 
    77  		return (S( x, 1 ) ^ S( x, 8 ) ^ R( x, 7 )); 
    78  	}
    79  
    80  	private static function Gamma1512(x:Number):Number { 
    81  		return (S( x, 19 ) ^ S( x, 61 ) ^ R( x, 6 )); 
    82  	}
    83  
    84  	private static function core_sha256(m:Array, l:Number):Array {
    85  		var K:Array = [ 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 0xE49B69C1, 0xEFBE4786, 0xFC19DC6, 0x240CA1CC, 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 0xC6E00BF3, 0xD5A79147, 0x6CA6351, 0x14292967, 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 ];
    86  		var HASH:Array = [ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ];
    87  		var W:Array = new Array( 64 );
    88  		var a:Number, b:Number, c:Number, d:Number, e:Number, f:Number, g:Number, h:Number, i:Number, j:Number;
    89  		var T1:Number, T2:Number;
    90  		
    91  		m[l >> 5] |= 0x80 << (24 - l % 32);
    92  		m[((l + 64 >> 9) << 4) + 15] = l;
    93  		for (i = 0; i < m.length ; i += 16) {
    94  			a = HASH[0];
    95  			b = HASH[1];
    96  			c = HASH[2];
    97  			d = HASH[3];
    98  			e = HASH[4];
    99  			f = HASH[5];
   100  			g = HASH[6];
   101  			h = HASH[7];
   102  			for (j = 0; j < 64 ; j++) {
   103  				if (j < 16) {
   104  					W[j] = m[j + i];
   105  				} else {
   106  					W[j] = safe_add( safe_add( safe_add( Gamma1256( W[j - 2] ), W[j - 7] ), Gamma0256( W[j - 15] ) ), W[j - 16] );
   107  				}
   108  				T1 = safe_add( safe_add( safe_add( safe_add( h, Sigma1256( e ) ), Ch( e, f, g ) ), K[j] ), W[j] );
   109  				T2 = safe_add( Sigma0256( a ), Maj( a, b, c ) );
   110  				h = g;
   111  				g = f;
   112  				f = e;
   113  				e = safe_add( d, T1 );
   114  				d = c;
   115  				c = b;
   116  				b = a;
   117  				a = safe_add( T1, T2 );
   118  			}
   119  			HASH[0] = safe_add( a, HASH[0] );
   120  			HASH[1] = safe_add( b, HASH[1] );
   121  			HASH[2] = safe_add( c, HASH[2] );
   122  			HASH[3] = safe_add( d, HASH[3] );
   123  			HASH[4] = safe_add( e, HASH[4] );
   124  			HASH[5] = safe_add( f, HASH[5] );
   125  			HASH[6] = safe_add( g, HASH[6] );
   126  			HASH[7] = safe_add( h, HASH[7] );
   127  		}
   128  		return HASH;
   129  	}
   130  
   131  	
   140  	private static function str2binb(str:String):Array {
   141  		var bin:Array = new Array( );
   142  		var mask:Number = (1 << 8) - 1;
   143  		for (var i:Number = 0; i < str.length * 8 ; i += 8) {
   144  			bin[i >> 5] |= (str.charCodeAt( i / 8 ) & mask) << (24 - i % 32);
   145  		}
   146  		return bin;
   147  	}
   148  
   149  	private static function binb2str(bin:Array):String {
   150  		var str:String = "";
   151  		var mask:Number = (1 << 8) - 1;
   152  		for (var i:Number = 0; i < bin.length * 32 ; i += 8) {
   153  			str += String.fromCharCode( (bin[i >> 5] >>> (24 - i % 32)) & mask );
   154  		}
   155  		return str;
   156  	}
   157  
   158  	private static function binb2hex(binarray:Array):String {
   159  		var hex_tab:String = 0 ? "0123456789ABCDEF" : "0123456789abcdef";
   160  		var str:String = "";
   161  		for (var i:Number = 0; i < binarray.length * 4 ; i++) {
   162  			str += hex_tab.charAt( (binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF ) + hex_tab.charAt( (binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF );
   163  		}
   164  		return str;
   165  	}
   166  
   167  	
   180  	private static function hex_sha256(s:String):String {
   181  		return binb2hex( core_sha256( str2binb( s ), s.length * 8 ) );
   182  	}
   183  
   184  	private static function str_sha256(s:String):String {
   185  		return binb2str( core_sha256( str2binb( s ), s.length * 8 ) );
   186  	}
   187  
   188  	private function SHA256() {
   189  	}
   190  }