Code archives/Algorithms/HC-256

This code has been declared by its author to be Public Domain code.

Download source code

HC-256 by Otus
(Posted 18 years ago)
HC-256 is a stream cipher designed for easy and efficient software implementation. It has a 256 bit key and uses two S-boxes of 1024 32-bit integers. It uses 32-bit integer operations to get best speed on current machines, and can be implemented in parallel, due to low dependence between operations. It is not covered by any patents.

This BlitzMax implementation is a naive unoptimized version that may not be 100% compatible. It's still fast enough, if you don't switch keys very often. Inlining functions and unrolling some loops could increase speed 10-fold.

Initialize, EncryptString and DecryptString are nonstandard examples to show how it can be used.
SuperStrict

Extern "C"

	Function Ror:Int(i:Int, n:Int) = "_rotr"
	
End Extern

Type THcContext
	
	'S-boxes
	Field _P:Int[]
	Field _Q:Int[]
	
	'Counter
	Field _i:Int
	
	Method Init(k:Int[] , iv:Int[])
		Assert (k.Length = 8) And (iv.Length = 8), "K and IV must be 8 Ints long!"
		Local W:Int[] = k + iv + New Int[2544]
		
		For Local i:Int = 16 To 2559
			W[i] = _f2(W[i-2]) + W[i-7] + _f1(W[i-15]) + W[i-16] + i
		Next
		
		_P = W[512..1536]
		_Q = W[1536..]
		
		Assert _P.Length = 1024 , "P size: " + _P.Length
		Assert _Q.Length = 1024 , "Q size: " + _Q.Length
		
		For Local i:Int = 0 Until 4096
			Local j:Int = i & 1023
			If (i & 2047) < 1024
				_P[j] :+ _P[(j - 10) & 1023] ..
					+ _g1( _P[(j-3) & 1023], _P[(j-1023) & 1023] )
			Else
				_Q[j] :+ _Q[(j - 10) & 1023] ..
					+ _g2( _Q[(j-3) & 1023], _Q[(j-1023) & 1023] )
			End If
		Next
		
		_i = 0
	End Method
	
	Method Initialize(key:String , salt:String) 
		If key.Length < 8 Then key = key[..8]
		If salt.Length < 8 Then salt = salt[..8]
		Local k:Int[8] , iv:Int[8]
		Local l:Int = key.Length
		For Local i:Int = 0 Until l
			k[i & 7] = key[i] + _f1( key[(i+3) Mod l] ) + _f2( key[(i+5) Mod l] )
		Next
		l = salt.Length
		For Local i:Int = 0 Until l
			iv[i & 7] = salt[i] + _f1( salt[(i+3) Mod l] ) + _f2( salt[(i+5) Mod l] )
		Next
		Init k, iv
	End Method
	
	Method Output:Int() 
		Local j:Int = _i & 1023
		If (_i & 2047) < 1024
			_i :+ 1
			_P[j] :+ _P[(j - 10) & 1023] ..
				+ _g1( _P[(j-3) & 1023], _P[(j-1023) & 1023] ) 
			Return _h1( _P[(j-12) & 1023] ) ~ _P[j]
		Else
			_i :+ 1
			_Q[j] :+ _Q[(j - 10) & 1023] ..
				+ _g2( _Q[(j-3) & 1023], _Q[(j-1023) & 1023] ) 
			Return _h2( _Q[(j-12) & 1023] ) ~ _Q[j]
		End If
	End Method
	
	Method DecryptString:String(s:String)
		Local s2:String , i:Int, k:Int
		Local j:Int, slen:Int
		
		For k = 0 To 3
			j :+ s[k] Shl (k Shl 3)
		Next
		slen = j ~ Output()
		s = s[4..]
		
		While i < slen
			j = s[i] + (s[i + 1] Shl 8) + (s[i + 2] Shl 16) + (s[i + 3] Shl 24) 
			j :~ Output() 
			For k = 0 To 3
				If s2.Length = slen Then Exit
				s2 :+ Chr( (j Shr (k Shl 3) ) & 255 )
			Next
			i :+ 4
		Wend
		
		Return s2
	End Method
	
	Method EncryptString:String(s:String)
		Local s2:String , i:Int, k:Int
		Local j:Int = s.Length ~ Output() 
		
		For k = 0 To 3
			s2 :+ Chr( (j Shr (k Shl 3)) & 255 ) 
		Next
		
		While i < s.Length
			j = s[i] + (s[i + 1] Shl 8) + (s[i + 2] Shl 16) + (s[i + 3] Shl 24) 
			j :~ Output() 
			For k = 0 To 3
				s2 :+ Chr( (j Shr (k Shl 3)) & 255 ) 
			Next
			i :+ 4
		Wend
		
		Return s2
	End Method
	
	Function _f1:Int(x:Int) 
		Return Ror(x , 7) ~ Ror(x , 18) ~ Ror(x , 3) 
	End Function
	
	Function _f2:Int(x:Int) 
		Return Ror(x , 17) ~ Ror(x , 19) ~ Ror(x , 10) 
	End Function
	
	Method _g1:Int(x:Int , y:Int) 
		Return ( Ror(x , 10) ~ Ror(y , 23) ) + _Q[ (x ~ y) & 1023 ]
	End Method
	
	Method _g2:Int(x:Int , y:Int) 
		Return ( Ror(x , 10) ~ Ror(y , 23) ) + _P[ (x ~ y) & 1023 ]
	End Method
	
	Method _h1:Int(x:Int) 
		Local b:Byte Ptr = Byte Ptr( Varptr x ) 
		Return _Q[ b[0] ] + _Q[ 256 + b[1] ] + _Q[ 512 + b[2] ] + _Q[ 768 + b[3] ]
	End Method
	
	Method _h2:Int(x:Int) 
		Local b:Byte Ptr = Byte Ptr( Varptr(x) ) 
		Return _P[ b[0] ] + _P[ 256 + b[1] ] + _P[ 512 + b[2] ] + _P[ 768 + b[3] ]
	End Method
	
End Type