unit ucrypt; interface type TEAKey = array[0..3] of cardinal; //Use 64-bit aligned data size (8,16...) or else some data will be left unencrypted! procedure TEA_Encode(Input, Output: pointer; size: integer; key: TEAKey); procedure TEA_Decode(Input, Output: pointer; size: integer; key: TEAKey); implementation type TEAData = array[0..1] of cardinal; PTEAKey = ^TEAKey; PTEAData = ^TEAData; procedure TEA_Cipher(v: PTEAData; var w: PTEAData; k: PTEAKey); var y, z, sum, delta, n: Cardinal; begin y := (v)[0]; z := (v)[1]; sum := 0; delta := $9E3779B9; n := 32; while (n > 0) do begin inc(y, (z shl 4 xor z shr 5) + z xor sum + (k)[sum and 3]); inc(sum, delta); inc(z, (y shl 4 xor y shr 5) + y xor sum + (k)[sum shr 11 and 3]); dec(n); end; (w)[0] := y; (w)[1] := z; end; procedure TEA_DeCipher(v: PTEAData; var w: PTEAData; k: PTEAKey); var y, z, sum, delta, n: Cardinal; begin y := v[0]; z := v[1]; sum := $0C6EF3720; delta := $9E3779B9; n := 32; while (n > 0) do begin dec(z, (y shl 4 xor y shr 5) + y xor sum + k[sum shr 11 and 3]); dec(sum, delta); dec(y, (z shl 4 xor z shr 5) + z xor sum + k[sum and 3]); dec(n); end; w[0] := y; w[1] := z; end; procedure TEA_EnDec(encode: boolean; Input, Output: pointer; size: integer; key: TEAKey); var DataIn, DataOut: TEAData; DOut: PTEAData; i, sz: integer; begin DOut := @DataOut; sz := (size shr 3) shl 3; i := 0; repeat DataIn[0] := Cardinal((pointer(Cardinal(Input) + Cardinal(i)))^); DataIn[1] := Cardinal((pointer(Cardinal(Input) + Cardinal(i + 4)))^); if encode then TEA_Cipher(@DataIn, DOut, @key) else TEA_DECipher(@DataIn, DOut, @key); Cardinal(pointer(Cardinal(Output) + Cardinal(i))^) := DataOut[0]; Cardinal(pointer(Cardinal(Output) + Cardinal(i + 4))^) := DataOut[1]; inc(i, 8); until i >= sz; end; procedure TEA_Encode(Input, Output: pointer; size: integer; key: TEAKey); begin TEA_EnDec(true, Input, Output, size, key); end; procedure TEA_Decode(Input, Output: pointer; size: integer; key: TEAKey); begin TEA_EnDec(false, Input, Output, size, key); end; end.
|