Posted: Sun Mar 02, 2008 12:38 pm Post subject: Encrypting abap programs or 'what does this program do?'
Encrypting abap programs or "what does this program do?"
Original: geocities.com/krapinskij/abapecrypt.htm
As a first thing I would like to point out that it is definitely not a good idea to put encrypted coding into a customer system.
It is harder to maintain, and definitely there are very few reasons (if any at all) for hiding your source code, except you are ashamed from having written such a terrible program. And you don’t want your boss or customer to see it.
Unfortunately in the area of ABAP programming there is a lot of horrible terrible unmaintainable and often useless coding floating around. No design, no real need for it… anyway.
So you might ask: “why the hell do you put an encrypted ABAP program on the web”?
And I answer:
1) because it is fun
2) because one day I stumbled across something like a tentatively obfuscated abap coding (obfuscated in the sense of the “obfuscated C code contest”). Just look at the sample below. In a header comment the word “encrypt” appears.
Code:
TABLES: UINFO, SM04DIC, USR41. DATA: BEGIN OF K1775231 OCCURS 10. "read
INCLUDE STRUCTURE UINFO. DATA RFC_DEST LIKE MSXXLIST-NAME. DATA: END OF
K1775231. DATA: BEGIN OF O45093488 OCCURS 10. INCLUDE STRUCTURE UINFO. "
DATA: END OF O45093488. DATA: OPCODE TYPE X. CONSTANTS: F87445 LIKE "rea
UINFO-BNAME VALUE'SAP*', Q2860 LIKE UINFO-BNAME VALUE'DDIC'. DATA: "read
BEGIN OF M284541636 OCCURS 10. INCLUDE STRUCTURE MSXXLIST. DATA: END OF
M284541636. CALL FUNCTION'Z_RTC_MKTIMESTAMP' IMPORTING TIMESTAMP = "read
TIMESTAMP. CALL FUNCTION'RFC_GET_LOCAL_SERVERS' TABLES HOSTS = "read tab
M284541636 EXCEPTIONS NOT_AVAILABLE = 1 OTHERS = 2. LOOP AT M284541636.
CALL FUNCTION'THUSRINFO'DESTINATION M284541636-NAME "read table data: li
TABLES USR_TABL = O45093488 EXCEPTIONS COMMUNICATION_FAILURE = 17. LOOP
AT O45093488 WHERE TERM <>'APPC-TM'. "read table data: like endform whil
MOVE-CORRESPONDING O45093488 TO K1775231. "read table data: like endform
MOVE M284541636-NAME TO K1775231-RFC_DEST. APPEND K1775231. ENDLOOP. "re
ENDLOOP. LOOP AT K1775231. IF K1775231-BNAME = Q2860 OR "read table da
K1775231-BNAME = F87445. "read table data: like endform while insert tab
CHECK K1775231-TERM <>'????'AND K1775231-TERM <>'APPC-TM'. "read table d
IF K1775231-TERM CS':'. K1775231-TERM = K1775231-TERM(SY-FDPOS). ENDIF.
P2880211 = G17812431317. CALL FUNCTION'Z_RTC_APPEND_ALERT' EXPORTING "re
TIMESTAMP = TIMESTAMP ALERTTEXT = TEXT-097 SEVERITY = P2880211 "read tab
REPLACE_TEXT1 = K1775231-BNAME REPLACE_TEXT2 = K1775231-MANDT "read tabl
REPLACE_TEXT3 = K1775231-TERM REPLACE_TEXT4 = K1775231-RFC_DEST TABLES "
ALERT_LIST = ALERT_LIST EXCEPTIONS OTHERS = 1. ENDIF. ENDLOOP. "read tab
ENDFUNCTION. "read table data: like endform while insert table:= if cont
I would feel ashamed to put something like this onto customer systems because:
1) it is hard to maintain (because it is hard to read)
2) it is absolutely not difficult to revert to a readable format.
So this is why i decided to write my own encryption routines in ABAP.
Ok, ok I’ll stop this intro but fours thing must be said:
1) the encryption is “tea” (actually xtea). Info on TEA you can find here.
2) the encryption routines are inefficient (because bit operations are done in ABAP) they should be done in the kernel in C.
3) Actually encryption routines seem to exist in the kernel, but I had no time to explore them (SSF*) it seems that they rely on something installed on the gui… I ain’t sure.
4) Routines are not Unicode safe. They are tested on 4.6.
So now I can finally formulate the question:
"What does the following program do?"
Code:
*
*Copyright (C) 2005 Krapinskij ([email protected])
*
*This program is free software; you can redistribute it and/or
*modify it under the terms of the GNU General Public License
*as published by the Free Software Foundation; either version 2
*of the License, or (at your option) any later version.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
*GNU General Public License for more details.
*
*You should have received a copy of the GNU General Public License
*along with this program; if not, write to the Free Software
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
REPORT z_decrypt.
TYPES t_code(72) TYPE c.
TYPES: t_acode(72) TYPE c.
TYPES: t_x34(72) TYPE x.
PARAMETERS: k(16) TYPE c.
FIELD-SYMBOLS: <kx> TYPE x.
DATA gt_xcode TYPE TABLE OF t_x34 .
DATA gt_code TYPE TABLE OF t_code .
ASSIGN k TO <kx> CASTING.
*Load test code/test data from compressed binary
PERFORM merger USING gt_xcode.
*uncompress/re-make readable
PERFORM load_code_u USING gt_xcode
<kx>
CHANGING gt_code.
DATA name TYPE syrepid.
DATA: msg(120), lin(3), wrd(10), off(3).
*Create test routine with test data.
GENERATE SUBROUTINE POOL gt_code NAME name
MESSAGE msg
LINE lin
WORD wrd
OFFSET off.
IF sy-subrc NE 0.
EXIT.
ENDIF.
*Run test code.
PERFORM system_test IN PROGRAM (name) IF FOUND.
WRITE:/.
*---------------------------------------------------------------------*
* FORM merger *
*---------------------------------------------------------------------*
FORM merger USING pt_xcode.
DATA lt_data TYPE TABLE OF string.
DATA l_xstr TYPE xstring.
DATA l_xtmp TYPE xstring.
DATA lt_xcode TYPE TABLE OF xstring.
DEFINE a.
l_xtmp = &1.
concatenate l_xstr l_xtmp into l_xstr." in byte mode.
END-OF-DEFINITION.
a:
'F5B23D561331BFF8F460B81185E4C5A5E69A1BF62F3192CD9C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'76A9407F1B2ED13FF3AB455E83CA257D079A67359CC78A2BAC17B32AAB3CFB4A3B80',
'24C8A61FC51872986DF97EE87C43B80E7CE06381E3EFC17C09715E6B87EE9C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'2E4965130AD218706AC8A2B80BA8A825B572D3CB6E68479C49917E846C7E85136DC9',
'CCFADF4287B2236FC24A76347BDF9C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'8B6D9FE689BC8AA58A66CAAADB68DC3BCE6937D92C7015C19C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'E127BFF2747CF65EEBBB1EDE54364A1945B6EF5F7C1790F2E0F0DE828CA581F79C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'1875542AA1CCD03543257A7C563833132DA0EEFB0590F3D1DCC4BF741F5BA58A8920',
'6CFAE26452B49C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'CD533D2DBD425E611DB7226DDB1B4E7BEBA1470C4B1069DC8CB142CA5BA8A6C79C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'18B08BB36EE460494ABBA333287745829C47CA452A9B03049C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B0304A3DC990D4D96167B1ADD3DA9D5C5DEB095FCA8E5937468757D00',
'3F94E5675C939C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B0304841421154CF731ACA65F6895393A09E19C47CA452A9B0304A8B5',
'A4EDB7F52CF69C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B0304175183B43B1725730E6B2AFD71917FC19C47CA452A9B03040C73',
'59F4EC0F41FF9C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'E381B06057564131DBFDD775683353859C47CA452A9B03049C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B030412C2274932C5385B4AC7D5F809A029B19C47CA452A9B0304AA26',
'C5AC8EB61E6E58B0675F26DCAE7F9C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'18B08BB36EE460491F68E1D4ADE9C27313E6B66050476CF99C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B03045133012B2EE657B6000D52F72E94B3069C47CA452A9B03040753',
'CE661F88F4E39C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'9C47CA452A9B030404D0673C9B4FE8AB749909FA04E5473A9C47CA452A9B0304FB6E',
'65ECEFEEDED29C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'598A78C6F165447588DA3014C4FDE813C3208A1AF4781F17897F6346E7C23626D198',
'B6FA44E4DD0B99B29F0372CCFEAB7E4472E2F2FC2A2842544F4A834215F0CE6937D9',
'2C7015C1',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'41F85B93CFCF84998DCF49668F9AFBDCC667EE6500B4E55F6955E68A2EF144C459A8',
'117DCE1E1F299C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'598A78C6F165447588DA3014C4FDE813C3208A1AF4781F17897F6346E7C23626D198',
'B6FA44E4DD0BE7FB1F3974A0AE874937F9B2B00975C3E1BABC8148A950B69C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
a:
'AEF15BC29492EF089C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47',
'CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA452A9B03049C47CA45',
'2A9B0304',
''.
APPEND l_xstr TO lt_xcode.
CLEAR l_xstr.
pt_xcode = lt_xcode.
ENDFORM.
*********************************************************************
TYPES: t_tab_string TYPE TABLE OF t_acode.
TYPES: t_tab_xstring TYPE TABLE OF t_x34.
TYPES t_tab_acode TYPE TABLE OF t_acode.
*&--------------------------------------------------------------------*
*& Form load_code_u
*&--------------------------------------------------------------------*
FORM load_code_u USING pt_xstrings TYPE t_tab_xstring
k TYPE x
CHANGING pt_strings TYPE t_tab_string.
DATA l_str TYPE t_code.
DATA l_ox TYPE t_code.
DATA l_ix TYPE t_x34.
LOOP AT pt_xstrings INTO l_ix.
CLEAR l_ox. CLEAR l_str.
* PERFORM tea_cipher_u USING l_ix k 'D' CHANGING l_ox.
PERFORM tea_cipher USING l_ix k 'D' CHANGING l_ox.
* IMPORT xdata = l_str FROM DATA BUFFER l_ox.
l_str = l_ox.
APPEND l_str TO pt_strings.
ENDLOOP.
ENDFORM. "load_code_u
TYPES: t_x2(2) TYPE x.
TYPES: t_x4(4) TYPE x.
TYPES: t_x8(8) TYPE x.
TYPES: t_x16(16) TYPE x.
*&--------------------------------------------------------------------*
*& Form tea_cipher_U
*&--------------------------------------------------------------------*
* unicode and platform independent.
* Release >4.7 only (maybe 4.6C...)
*
* Note: Relies on the fact that import from data buffer
* does not care of eventual extra x00 at the end of the xstring.
*---------------------------------------------------------------------*
FORM tea_cipher_u USING input TYPE xstring
k mode
CHANGING output TYPE xstring.
DATA offset TYPE i.
DATA len TYPE i.
DATA l_ix TYPE t_x8.
DATA l_ox TYPE t_x8.
DATA delta TYPE i.
len = strlen( input ).
WHILE offset < len.
delta = len - offset.
IF delta > 8.
delta = 8.
ENDIF.
IF mode = 'E'.
l_ix = input+offset(delta).
PERFORM tea_tea USING l_ix k CHANGING l_ox.
CONCATENATE output l_ox INTO output." IN BYTE MODE.
ELSEIF mode = 'D'.
l_ix = input+offset(delta).
PERFORM tea_untea USING l_ix k CHANGING l_ox.
CONCATENATE output l_ox INTO output. "IN BYTE MODE.
ENDIF.
offset = offset + 8.
ENDWHILE.
ENDFORM. "tea_cipher_U
**&--------------------------------------------------------------------*
**& Form tea_cipher
**&--------------------------------------------------------------------*
** not unicode/platform independent
** Restrictions: input must be long n*8 and output too.
** Guaranteed to work only on char types. No int no unicode.
**---------------------------------------------------------------------*
FORM tea_cipher USING input
k mode
CHANGING output.
FIELD-SYMBOLS: <input> TYPE x.
FIELD-SYMBOLS: <output> TYPE x.
DATA offset TYPE i.
DATA len TYPE i.
ASSIGN input TO <input> CASTING.
DESCRIBE FIELD <input> LENGTH len." IN BYTE MODE.
WHILE offset < len.
ASSIGN input+offset(8) TO <input> CASTING.
ASSIGN output+offset(8) TO <output> CASTING.
IF NOT <input> IS ASSIGNED OR
NOT <output> IS ASSIGNED.
EXIT.
ENDIF.
IF mode = 'E'.
PERFORM tea_tea USING <input> k CHANGING <output>.
ELSEIF mode = 'D'.
PERFORM tea_untea USING <input> k CHANGING <output>.
ENDIF.
offset = offset + 8.
ENDWHILE.
ENDFORM. "tea_cipher
*&--------------------------------------------------------------------*
*& Form tea_tea
*&--------------------------------------------------------------------*
FORM tea_tea USING input
k
CHANGING output.
FIELD-SYMBOLS: <input> TYPE t_x8.
FIELD-SYMBOLS: <output> TYPE t_x8.
FIELD-SYMBOLS: <k> TYPE t_x16.
ASSIGN input TO <input> CASTING.
ASSIGN output TO <output> CASTING.
ASSIGN k TO <k> CASTING.
************************************************************************
* C is a little bit more... compact. :-)
* register unsigned long y=v[0],z=v[1],sum=0,delta=0x9E3779B9,n=32;
*
* while(n-->0)
* {
* y += (z << 4 ^ z >> 5) + z ^ sum + k[sum&3];
* sum += delta;
* z += (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];
* }
*
* w[0]=y; w[1]=z;
***********************************************************************
CONSTANTS x00000003 TYPE t_x4 VALUE '00000003'.
CONSTANTS delta TYPE t_x4 VALUE '9E3779B9'.
DATA y TYPE t_x4.
DATA z TYPE t_x4.
DATA sum TYPE t_x4 VALUE '00000000'.
DATA n TYPE i VALUE 32.
DATA ysl4 TYPE t_x4.
DATA ysr5 TYPE t_x4.
DATA zsl4 TYPE t_x4.
DATA zsr5 TYPE t_x4.
DATA sumand3 TYPE t_x4.
DATA sumsr11 TYPE t_x4.
DATA sumt TYPE t_x4.
DATA sum3 TYPE t_x4.
DATA ztmp TYPE t_x4.
DATA ytmp TYPE t_x4.
DATA y1 TYPE t_x4.
DATA y2 TYPE t_x4.
DATA y3 TYPE t_x4.
DATA z1 TYPE t_x4.
DATA z2 TYPE t_x4.
DATA z3 TYPE t_x4.
DATA ksum TYPE t_x4.
y = <input>+0(4).
z = <input>+4(4).
WHILE n > 0.
n = n - 1.
********************************************************
*/*y += (((z << 4) ^ (z >> 5)) + z) ^ (sum + k[sum&3])*/
*(z << 4) -> zsl4
PERFORM tea_shift_left USING z 4 CHANGING zsl4.
*(z >> 5) -> zsr5
PERFORM tea_shift_right USING z 5 CHANGING zsr5.
*((z << 4) ^ (z >> 5)) -> ztmp
ztmp = ( zsl4 BIT-XOR zsr5 ).
*(((z << 4) ^ (z >> 5)) + z) -> y1
PERFORM tea_unsigned_sum USING ztmp z CHANGING y1.
*sum&3
sumt = sum BIT-AND x00000003.
*
sumt = sumt * 4.
* k[sum&3] -> ksum
ksum = <k>+sumt(4).
*sum + k[sum&3] -> y2
PERFORM tea_unsigned_sum USING ksum sum CHANGING y2.
*
y2 = y2 BIT-XOR y1.
*y = y + y2
PERFORM tea_unsigned_sum USING y2 y CHANGING y3.
y = y3.
*******************************************************
* sum += delta;
PERFORM tea_unsigned_sum USING sum delta CHANGING sum3.
sum = sum3.
*******************************************************
* z += (((y << 4) ^ (y >> 5)) + y) ^ (sum + k[sum>>11 & 3]);
*(y << 4) -> ysl4
PERFORM tea_shift_left USING y 4 CHANGING ysl4.
*(y >> 5) -> ysr5
PERFORM tea_shift_right USING y 5 CHANGING ysr5.
*((y << 4) ^ (y >> 5)) -> ytmp
ytmp = ( ysl4 BIT-XOR ysr5 ).
*(((y << 4) ^ (y >> 5)) + y) -> z1
PERFORM tea_unsigned_sum USING ytmp y CHANGING z1.
*sum>>11
PERFORM tea_shift_right USING sum 11 CHANGING sumt.
*sumt&3
sumt = sumt BIT-AND x00000003.
*
sumt = sumt * 4.
* k[sum&3] -> ksum
ksum = <k>+sumt(4).
*sum + k[sum&3] -> z2
PERFORM tea_unsigned_sum USING ksum sum CHANGING z2.
*
z2 = z2 BIT-XOR z1.
*z = z + z2
PERFORM tea_unsigned_sum USING z2 z CHANGING z3.
z = z3.
ENDWHILE.
<output>+0(4) = y.
<output>+4(4) = z.
ENDFORM. "tea_tea
*&--------------------------------------------------------------------*
*& Form tea_untea
*&--------------------------------------------------------------------*
FORM tea_untea USING input k CHANGING output.
FIELD-SYMBOLS: <input> TYPE t_x8.
FIELD-SYMBOLS: <output> TYPE t_x8.
FIELD-SYMBOLS: <k> TYPE t_x16.
ASSIGN input TO <input> CASTING.
ASSIGN output TO <output> CASTING.
ASSIGN k TO <k> CASTING.
************************************************************************
* register unsigned long y=v[0],z=v[1],sum=0xC6EF3720,
* delta=0x9E3779B9,n=32;
*
* /* sum = delta<<5, in general sum = delta * n */
*
* while(n-->0)
* {
* z -= (y << 4 ^ y >> 5) + y ^ sum + k[sum>>11 & 3];
* sum -= delta;
* y -= (z << 4 ^ z >> 5) + z ^ sum + k[sum&3];
* }
*
* w[0]=y; w[1]=z;
***********************************************************************
CONSTANTS x00000003 TYPE t_x4 VALUE '00000003'.
CONSTANTS delta TYPE t_x4 VALUE '9E3779B9'.
DATA y TYPE t_x4.
DATA z TYPE t_x4.
DATA sum TYPE t_x4 VALUE 'C6EF3720'.
DATA n TYPE i VALUE 32.
DATA ysl4 TYPE t_x4.
DATA ysr5 TYPE t_x4.
DATA zsl4 TYPE t_x4.
DATA zsr5 TYPE t_x4.
DATA sumand3 TYPE t_x4.
DATA sumsr11 TYPE t_x4.
DATA sumt TYPE t_x4.
DATA sum3 TYPE t_x4.
DATA ztmp TYPE t_x4.
DATA ytmp TYPE t_x4.
DATA y1 TYPE t_x4.
DATA y2 TYPE t_x4.
DATA y3 TYPE t_x4.
DATA z1 TYPE t_x4.
DATA z2 TYPE t_x4.
DATA z3 TYPE t_x4.
DATA ksum TYPE t_x4.
y = <input>+0(4).
z = <input>+4(4).
WHILE n > 0.
n = n - 1.
*******************************************************
* z -= (((y << 4) ^ (y >> 5)) + y) ^ (sum + k[sum>>11 & 3]);
*(y << 4) -> ysl4
PERFORM tea_shift_left USING y 4 CHANGING ysl4.
*(y >> 5) -> ysr5
PERFORM tea_shift_right USING y 5 CHANGING ysr5.
*((y << 4) ^ (y >> 5)) -> ytmp
ytmp = ( ysl4 BIT-XOR ysr5 ).
*(((y << 4) ^ (y >> 5)) + y) -> z1
PERFORM tea_unsigned_sum USING ytmp y CHANGING z1.
*sum>>11
PERFORM tea_shift_right USING sum 11 CHANGING sumt.
*sumt&3
sumt = sumt BIT-AND x00000003.
*
sumt = sumt * 4.
* k[sum&3] -> ksum
ksum = <k>+sumt(4).
*sum + k[sum&3] -> z2
PERFORM tea_unsigned_sum USING ksum sum CHANGING z2.
*
z2 = z2 BIT-XOR z1.
*z = z - z2
PERFORM tea_unsigned_sub USING z z2 CHANGING z3.
z = z3.
*******************************************************
* sum -= delta;
PERFORM tea_unsigned_sub USING sum delta CHANGING sum3.
sum = sum3.
********************************************************
*/*y -= (((z << 4) ^ (z >> 5)) + z) ^ (sum + k[sum&3])*/
*(z << 4) -> zsl4
PERFORM tea_shift_left USING z 4 CHANGING zsl4.
*(z >> 5) -> zsr5
PERFORM tea_shift_right USING z 5 CHANGING zsr5.
*((z << 4) ^ (z >> 5)) -> ztmp
ztmp = ( zsl4 BIT-XOR zsr5 ).
*(((z << 4) ^ (z >> 5)) + z) -> y1
PERFORM tea_unsigned_sum USING ztmp z CHANGING y1.
*sum&3
sumt = sum BIT-AND x00000003.
*
sumt = sumt * 4.
* k[sum&3] -> ksum
ksum = <k>+sumt(4).
*sum + k[sum&3] -> y2
PERFORM tea_unsigned_sum USING ksum sum CHANGING y2.
*
y2 = y2 BIT-XOR y1.
*y = y - y2
PERFORM tea_unsigned_sub USING y y2 CHANGING y3.
y = y3.
ENDWHILE.
<output>+0(4) = y.
<output>+4(4) = z.
ENDFORM. "untea
*&--------------------------------------------------------------------*
*& Form tea_shift_right
*&--------------------------------------------------------------------*
FORM tea_shift_right USING i TYPE t_x4
n TYPE i
CHANGING o TYPE t_x4.
DATA li TYPE i VALUE 1.
DATA lo TYPE i VALUE 1.
CONSTANTS n_bits TYPE i VALUE 32.
DATA b TYPE i.
*This is the ugliest thing i have ever written.
*unfortunately 7FFFFFFF * 4 equals 00000010 in abap...
*so i have to do my own.
o = i.
li = n_bits.
DO n_bits TIMES.
GET BIT li OF o INTO b.
lo = li + n.
IF lo <= n_bits.
SET BIT lo OF o TO b.
ENDIF.
li = li - 1.
ENDDO.
li = 1.
DO n TIMES.
SET BIT li OF o TO 0.
li = li + 1.
ENDDO.
ENDFORM. "tea_shift_right
*&--------------------------------------------------------------------*
*& Form tea_shift_left
*&--------------------------------------------------------------------*
FORM tea_shift_left USING i TYPE t_x4
n TYPE i
CHANGING o TYPE t_x4.
DATA li TYPE i VALUE 1.
DATA lo TYPE i VALUE 1.
CONSTANTS n_bits TYPE i VALUE 32.
DATA b TYPE i.
*This is the second ugliest thing i have ever written.
* after shift right :-)
o = i.
li = 1.
DO n_bits TIMES.
GET BIT li OF o INTO b.
lo = li - n.
IF lo > 0.
SET BIT lo OF o TO b.
ENDIF.
li = li + 1.
ENDDO.
li = n_bits.
DO n TIMES.
SET BIT li OF o TO 0.
li = li - 1.
ENDDO.
ENDFORM. "tea_shift_left
*&--------------------------------------------------------------------*
*& Form tea_unsigned_sum
*&--------------------------------------------------------------------*
FORM tea_unsigned_sum USING i TYPE t_x4
j TYPE t_x4
CHANGING o TYPE t_x4.
DATA i0 TYPE t_x2.
DATA i1 TYPE t_x2.
DATA i2 TYPE t_x2.
DATA i3 TYPE t_x2.
DATA j0 TYPE t_x2.
DATA j1 TYPE t_x2.
DATA j2 TYPE t_x2.
DATA j3 TYPE t_x2.
DATA o0 TYPE t_x2.
DATA o1 TYPE t_x2.
DATA o2 TYPE t_x2.
DATA o3 TYPE t_x2.
*Sum is on signed values only.
*It overflows and even when catching the exception...
*the results is blank. :-(
*&--------------------------------------------------------------------*
*& Form tea_unsigned_sub
*&--------------------------------------------------------------------*
FORM tea_unsigned_sub USING i TYPE t_x4
j TYPE t_x4
CHANGING o TYPE t_x4.
DATA i0 TYPE t_x2.
DATA i1 TYPE t_x2.
DATA i2 TYPE t_x2.
DATA i3 TYPE t_x2.
DATA j0 TYPE t_x2.
DATA j1 TYPE t_x2.
DATA j2 TYPE t_x2.
DATA j3 TYPE t_x2.
DATA o0 TYPE t_x2.
DATA o1 TYPE t_x2.
DATA o2 TYPE t_x2.
DATA o3 TYPE t_x2.
*Subtraction has the same problem as sum...
i0+1(1) = i+3(1).
i1+1(1) = i+2(1).
i2+1(1) = i+1(1).
i3+1(1) = i+0(1).
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG. SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG. Every effort is made to ensure content integrity. Use information on this site at your own risk.