_ ______________________ _ \ \\ _\ /_ // / ______ | __ | ______ \_ \_|_ / \ __ ___ __|_\_ \ / /_ \/ \/ \/ \ / _/ / /____/ / /__/\__\ _ /_/ _/____/___ \______________\__/_/__\___/_________/ wPx| /___/ | | TEAM-53.TUTORiALS.14 | !_ _! (____________________) "Крякер и криптография эллиптических кривых" или "Взлом TMG Official KeygenMe #4" автор: bLaCk-eYe/Lz0 перевод: lord_Phoenix :: Intro :: Это мой первый тутор после длительного периода "неписания". Предидущий тутор я написал 1 год назад. Почему я уделил этому внимание? Да просто мне надоело слышать от читателей, что мои туторы непонятные и сложные. Английский не мой родной язык, так что если вам что-либо не нравится - можете идти читать другой тутор. :: Цель :: В этом туторе я расскажу вам, как взломать TMG trial keygenme #4. Крякмис был релизнут 27 сентября 2001 года, и на данный момент, 9 сентября 2003 года, мы можем точно сказать, что защита далеко не из легких. Вот так вот.. :: Инструменты :: Я закейгенил даный триал используя классический набор инструментов: - IDA - MS VisualC (для напсиания кейгена) - библиотека Miracl - UnPECompact (by y0da) - PEiD (или любой другой анализатор) :: Взлом :: Теперь, когда вы ашли все нужные нам инструменты, давайте посмотрим, что нам может предложить даный крякмис :) Запускаем и смотрим.. Нам надо ввести Имя (user-ID), V-код (?) и ессесно рег. код. Крякмис запакован pecompact'ом, так что я использовал анпакер by y0da. Теперь, грузим распакованный файл в иду. Сразу же я заметил большие числа, так что tE! не разочаровал своих фанов/крякеров; похоже дух криптографии летает дома у tE! с его триалами =) Аха, вот оно (имена переменных и процедур даны мной, а не идой конечно :) ): TMG_:0040122A 8B+ mov edi, [esp+1A4h+hWnd] TMG_:00401231 6A+ push 0 ; bSigned TMG_:00401233 6A+ push 0 ; lpTranslated TMG_:00401235 68+ push 3F3h ; nIDDlgItem TMG_:0040123A 57 push edi ; hDlg TMG_:0040123B FF+ call ds:GetDlgItemInt TMG_:00401241 8B+ mov esi, ds:SendDlgItemMessageA TMG_:00401247 89+ mov [esp+1A4h+v_code], eax TMG_:0040124B 8D+ lea eax, [esp+1A4h+_id] TMG_:00401252 50 push eax ; lParam TMG_:00401253 6A+ push 41h ; wParam TMG_:00401255 6A+ push 0Dh ; Msg TMG_:00401257 68+ push 3F1h ; nIDDlgItem TMG_:0040125C 57 push edi ; hDlg TMG_:0040125D FF+ call esi ; SendDlgItemMessageA TMG_:0040125F 83+ cmp eax, 5 ; len (user_id) =>5 TMG_:00401262 89+ mov [esp+1A4h+epoint_2], eax TMG_:00401266 73+ jnb short loc_401286 TMG_:00401268 6A+ push 10h ; uType TMG_:0040126A 68+ push offset aRegistrationEr ; lpCaption TMG_:0040126F 68+ push offset aLengthOfUserId ; lpText TMG_:00401274 57 push edi ; hWnd TMG_:00401275 FF+ call ds:MessageBoxA TMG_:0040127B 5F pop edi TMG_:0040127C 5E pop esi TMG_:0040127D 5D pop ebp TMG_:0040127E 5B pop ebx TMG_:0040127F 81+ add esp, 194h TMG_:00401285 C3 retn TMG_:00401286 loc_401286: ; CODE XREF: sub_401220+46j TMG_:00401286 8D+ lea ecx, [esp+1A4h+reg_code] TMG_:0040128D 51 push ecx ; lParam TMG_:0040128E 6A+ push 41h ; wParam TMG_:00401290 6A+ push 0Dh ; Msg TMG_:00401292 68+ push 3F2h ; nIDDlgItem TMG_:00401297 57 push edi ; hDlg TMG_:00401298 FF+ call esi ; SendDlgItemMessageA TMG_:0040129A 85+ test eax, eax TMG_:0040129C 8B+ mov esi, eax TMG_:0040129E 0F+ jz loc_401725 Тоесть, крякмис получает v_code (сразу как число-int), имя и рег.код. Длинна имени должна быть >=5. А я продолжу: TMG_:004012AA 8A+ mov cl, [esp+edx+1A4h+reg_code] TMG_:004012B1 80+ cmp cl, 30h TMG_:004012B4 73+ jnb short loc_4012B7 TMG_:004012B6 4E dec esi TMG_:004012B7 TMG_:004012B7 loc_4012B7: ; CODE XREF: sub_401220+94j TMG_:004012B7 80+ cmp cl, 46h TMG_:004012BA 76+ jbe short loc_4012BD TMG_:004012BC 4E dec esi TMG_:004012BD TMG_:004012BD loc_4012BD: ; CODE XREF: sub_401220+9Aj TMG_:004012BD 80+ cmp cl, 39h TMG_:004012C0 76+ jbe short loc_4012C8 TMG_:004012C2 80+ cmp cl, 41h TMG_:004012C5 73+ jnb short loc_4012C8 TMG_:004012C7 4E dec esi TMG_:004012C8 TMG_:004012C8 loc_4012C8: ; CODE XREF: sub_401220+A0j TMG_:004012C8 ; sub_401220+A5j TMG_:004012C8 42 inc edx TMG_:004012C9 3B+ cmp edx, esi TMG_:004012CB 72+ jb short loc_4012AA TMG_:004012CD TMG_:004012CD loc_4012CD: ; CODE XREF: sub_401220+88j TMG_:004012CD 33+ xor eax, esi TMG_:004012CF 74+ jz short loc_4012EF TMG_:004012D1 6A+ push 10h ; uType TMG_:004012D3 68+ push offset aBadLuck ; lpCaption TMG_:004012D8 68+ push offset aUsingYourBrain ; lpText TMG_:004012DD 57 push edi ; hWnd TMG_:004012DE FF+ call ds:MessageBoxA Код, приведенный выше, проверяет формат рег. кода - он может состоять только из hex-символов - [0..9][A..F]. И вот - основная часть защиты (код очень долгий, но обьяснения не заставят себя ждать =) ): TMG_:004012EF 8B+ mov edx, ds:dword_410DF8 TMG_:004012F5 6A+ push 0 TMG_:004012F7 C7+ mov dword ptr [edx+238h], 10h TMG_:00401301 E8+ call _BigCreate TMG_:00401306 83+ add esp, 4 TMG_:00401309 89+ mov [esp+1A4h+ptBig_1], eax TMG_:0040130D 6A+ push 0 TMG_:0040130F E8+ call _BigCreate TMG_:00401314 83+ add esp, 4 TMG_:00401317 89+ mov [esp+1A4h+ptBig_2], eax TMG_:0040131B 6A+ push 0 TMG_:0040131D E8+ call _BigCreate TMG_:00401322 83+ add esp, 4 TMG_:00401325 89+ mov [esp+1A4h+ptBig_3], eax TMG_:00401329 6A+ push 0 TMG_:0040132B E8+ call _BigCreate TMG_:00401330 83+ add esp, 4 TMG_:00401333 89+ mov [esp+1A4h+ptBig_4], eax TMG_:00401337 6A+ push 0FFFFFFFDh TMG_:00401339 E8+ call _BigCreate TMG_:0040133E 83+ add esp, 4 TMG_:00401341 89+ mov [esp+1A4h+ptBig_5], eax TMG_:00401345 6A+ push 0 TMG_:00401347 E8+ call _BigCreate TMG_:0040134C 83+ add esp, 4 TMG_:0040134F 8B+ mov ebp, eax TMG_:00401351 89+ mov [esp+1A4h+ptBig_6], ebp TMG_:00401355 6A+ push 0 TMG_:00401357 E8+ call _BigCreate TMG_:0040135C 83+ add esp, 4 TMG_:0040135F 8B+ mov edi, eax TMG_:0040135F 8B+ mov edi, eax TMG_:00401361 68+ push offset aAdf85458a2bb4a ; "ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C84"... TMG_:00401366 55 push ebp ; ptBig_6 TMG_:00401367 E8+ call _BigIn TMG_:0040136C 83+ add esp, 8 TMG_:0040136F 6A+ push 0 TMG_:00401371 E8+ call _BigCreate TMG_:00401376 83+ add esp, 4 TMG_:00401379 8B+ mov ebx, eax TMG_:0040137B 6A+ push 0 TMG_:0040137D E8+ call _BigCreate TMG_:00401382 83+ add esp, 4 TMG_:00401385 8B+ mov esi, eax TMG_:00401387 68+ push offset aC90fdaa22168c2 ; "C90FDAA22168C234C4C6628B80DC1CD129024E2"... TMG_:0040138C 57 push edi ; ptBig_7 TMG_:0040138D E8+ call _BigIn TMG_:00401392 83+ add esp, 8 TMG_:00401395 6A+ push 0 TMG_:00401397 E8+ call _BigCreate TMG_:0040139C 83+ add esp, 4 TMG_:0040139F 89+ mov [esp+1A4h+ptBig_10], eax TMG_:004013A3 68+ push offset a1c341c34e32d5e ; "1C341C34E32D5EC8F3DC83E7DA1A9DAC84E2662"... TMG_:004013A8 50 push eax TMG_:004013A9 E8+ call _BigIn TMG_:004013AE 83+ add esp, 8 TMG_:004013B1 57 push edi TMG_:004013B2 6A+ push 1 TMG_:004013B4 57 push edi TMG_:004013B5 E8+ call _BigSub TMG_:004013BA 83+ add esp, 0Ch TMG_:004013BD 8D+ lea eax, [esp+1A4h+var_158] TMG_:004013C1 50 push eax TMG_:004013C2 E8+ call MD5Init TMG_:004013C7 8B+ mov ecx, [esp+1A8h+epoint_2] TMG_:004013CB 83+ add esp, 4 TMG_:004013CE 8D+ lea edx, [esp+1A4h+_id] TMG_:004013D5 8D+ lea eax, [esp+1A4h+var_158] TMG_:004013D9 51 push ecx TMG_:004013DA 52 push edx TMG_:004013DB 50 push eax TMG_:004013DC E8+ call MD5Hash ; perform md5 on id TMG_:004013E1 83+ add esp, 0Ch TMG_:004013E4 8D+ lea ecx, [esp+1A4h+var_158] TMG_:004013E8 8D+ lea edx, [esp+1A4h+var_168] TMG_:004013EC 51 push ecx TMG_:004013ED 52 push edx TMG_:004013EE E8+ call MD5Finish TMG_:004013F3 A1+ mov eax, ds:dword_410DF8 TMG_:004013F8 83+ add esp, 8 TMG_:004013FB C7+ mov dword ptr [eax+238h], 100h TMG_:00401405 8B+ mov ecx, ds:dword_410DF8 TMG_:0040140B 8D+ lea edx, [esp+1A4h+var_168] TMG_:0040140F C7+ mov dword ptr [ecx+248h], 10h TMG_:00401419 52 push edx ; ptr to MD5 hash TMG_:0040141A 53 push ebx ; ptBig_8 TMG_:0040141B E8+ call _BigIn ; ptBig_8=MD5(id) TMG_:00401420 A1+ mov eax, ds:dword_410DF8 TMG_:00401425 83+ add esp, 8 TMG_:00401428 68+ push offset aAb6853bdd1100f ; "AB6853BDD1100F57" TMG_:0040142D 56 push esi ; ptBig_9 TMG_:0040142E C7+ mov dword ptr [eax+238h], 10h TMG_:00401438 E8+ call _BigIn TMG_:0040143D 83+ add esp, 8 TMG_:00401440 53 push ebx ; ptBig_8 TMG_:00401441 56 push esi ; ptBig_9 TMG_:00401442 6A+ push 3 TMG_:00401444 53 push ebx ; ptBig_8 TMG_:00401445 E8+ call _BigPowMod ; ptBig_8 = ptBig_8 ^ 3 mod ptBig_9 TMG_:0040144A 83+ add esp, 10h TMG_:0040144D 8D+ lea ecx, [esp+1A4h+reg_code] TMG_:00401454 51 push ecx ; pt to reg_code TMG_:00401455 56 push esi ; ptBig_9 TMG_:00401456 E8+ call _BigIn ; ptBig_9=reg_code TMG_:0040145B 8B+ mov edx, [esp+1ACh+ptBig_4] TMG_:0040145F 83+ add esp, 8 TMG_:00401462 68+ push offset aC90fdaa22168_0 ; "C90FDAA22168C234C4C5D89F4F2DD72349EE61F"... TMG_:00401467 52 push edx ; ptBig_4 TMG_:00401468 E8+ call _BigIn TMG_:0040146D 8B+ mov eax, [esp+1ACh+ptBig_5] TMG_:00401471 83+ add esp, 8 TMG_:00401474 6A+ push 1 ; MR_AFFINE = 1 TMG_:00401476 57 push edi ; B = ptBig_7 TMG_:00401477 55 push ebp ; B = ptBig_6 TMG_:00401478 50 push eax ; A = ptBig_5 = -3 TMG_:00401479 E8+ call ecurve_init TMG_:0040147E 83+ add esp, 10h TMG_:00401481 E8+ call epoint_init TMG_:00401486 8B+ mov ecx, [esp+1A4h+ptBig_1] TMG_:0040148A 68+ push offset a902166ccf36630 ; "902166CCF366300FAF8B1CCA939C1280E5450F4"... TMG_:0040148F 51 push ecx TMG_:00401490 8B+ mov ebp, eax TMG_:00401492 E8+ call _BigIn TMG_:00401497 8B+ mov edx, [esp+1ACh+ptBig_2] TMG_:0040149B 83+ add esp, 8 TMG_:0040149E 68+ push offset a5a3884af3e676f ; "5A3884AF3E676F49470F441CBEEBE7C0B1D9DF6"... TMG_:004014A3 52 push edx TMG_:004014A4 E8+ call _BigIn TMG_:004014A9 8B+ mov eax, [esp+1ACh+ptBig_1] TMG_:004014AD 8B+ mov ecx, [esp+1ACh+ptBig_10] TMG_:004014B1 83+ add esp, 8 TMG_:004014B4 55 push ebp TMG_:004014B5 6A+ push 0 TMG_:004014B7 50 push eax ; ptBig_1 TMG_:004014B8 51 push ecx ; ptBig_10 TMG_:004014B9 E8+ call epoint_set TMG_:004014BE 8B+ mov edx, [esp+1B4h+ptBig_3] TMG_:004014C2 83+ add esp, 10h TMG_:004014C5 68+ push offset a12c34484f6c34b ; "12C34484F6C34BB886EEE052ACC6247098BEDC3"... TMG_:004014CA 52 push edx TMG_:004014CB E8+ call _BigIn TMG_:004014D0 83+ add esp, 8 TMG_:004014D3 E8+ call epoint_init TMG_:004014D8 8B+ mov ecx, [esp+1A4h+ptBig_2] TMG_:004014DC 89+ mov [esp+1A4h+epoint_2], eax TMG_:004014E0 50 push eax TMG_:004014E1 8B+ mov eax, [esp+1A8h+ptBig_3] TMG_:004014E5 6A+ push 0 TMG_:004014E7 50 push eax ; ptBig_3 TMG_:004014E8 51 push ecx ; ptBig_2 TMG_:004014E9 E8+ call epoint_set TMG_:004014EE 83+ add esp, 10h TMG_:004014F1 E8+ call epoint_init TMG_:004014F6 89+ mov [esp+1A4h+epoint_3], eax TMG_:004014FA E8+ call epoint_init TMG_:004014FF 8B+ mov edx, [esp+1A4h+epoint_3] TMG_:00401503 89+ mov [esp+1A4h+epoint_4], eax TMG_:00401507 8B+ mov eax, [esp+1A4h+v_code] TMG_:0040150B 52 push edx TMG_:0040150C 50 push eax TMG_:0040150D 56 push esi TMG_:0040150E 56 push esi TMG_:0040150F E8+ call epoint_set TMG_:00401514 83+ add esp, 10h TMG_:00401517 85+ test eax, eax TMG_:00401519 0F+ jnz loc_4015EA Вывод - программа создает 10 больших чисел и инитализирует некотоыре из них: pBig_5 = -3 pBig_6 = ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C841 pBig_7 = C90FDAA22168C234C4C6628B80DC1CD129024E20 pBig_10 = 1C341C34E32D5EC8F3DC83E7DA1A9DAC84E26624 Затем, уменшает седьмое число, так что теперь - оно простое: pBig_7 = Big7 - 1 pBig_7 = C90FDAA22168C234C4C6628B80DC1CD129024E1F = простое Затем, программа получает хеш от имени - модифицированный md5, и присваивает его восьмому большому числу: pBig_8 = MD5(user_id) Затем, заполняется девятое большое число, проводится операция по взятию остатка(powmod): pBig_9 = AB6853BDD1100F57 pBig_8 = pBig_8 ^ 3 mod pBig_9 Далее заполняется девятое и четвертое большие числа: pBig_9 = reg_code pBig_4 = C90FDAA22168C234C4C5D89F4F2DD72349EE61F7 И теперь главное - call по адресу 00401479 - он принес мне много головной боли, я просто не мог уловить, что там происходит. Но основная защита именно там и находится. И как только мы разберемся - все обрушится как ряд домино. ПОверьте мне. =) Собссно вот, как я определил, что это - я просто просмтотрел функции Miracl'а и нашел только одну функцию с такими 4 параметрами - pBig,pBig,pBig,int. Вот, что я нашел: +======================================================================+ 1.1.1 ecurve_init Function: void ecurve_init(A,B,p,type) big A,B,p; int type; Module: mrcurve.c Description: Initialises the internal parameters of the current active GF(p) elliptic curve. The curve is assumed to be of 2 3 the form y =x + Ax + B mod p, the so-called Weierstrass model. This routine can be called subsequently with the parameters of a different curve. Parameters: Three big numbers A, B and p. The type parameter must be either MR_PROJECTIVE or MR_AFFINE, and specifies whether projective or affine co-ordinates should be used internally. Normally the former is faster. Return value: None +======================================================================+ Так что, наша цель инитализирует Weierstrass эллиптическую кривую, с такими параметрами: A = -3 B = ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C841 p = C90FDAA22168C234C4C6628B80DC1CD129024E1F Тоесть ECC здесь: y^2=(x^3-3*x+ADF85458A2BB4A9AAFDC5620273D3CF1D8B9C841) mod C90FDAA22168C234C4C6628B80DC1CD129024E1F Исследуя сайт miracl'а, я узнал, что ecc реализованно в miracl'e под именем SSC-160. =) Тажке, следует заметить, что на данной кривой существует очень-очень большое количество точек: q == 1147860701762054730346200648614608152209809891831. Далее, вы увидите, почему это так важно и почему tE! выбрал именно эту кривую, а не любую другую. Крякмис заполняет pBig_1b pBig_2. И после этого "ставит" точку (назовем ее P1) на GF(p) кривой: x=pBig10 y=pBig1. Если у вас есть калькулятор, который может проводить расчеты с большими числами, вы можете проверить, что: pBig1^2 = pBig_10^3 – 3*pBig_10 + B mod p Другими словами, пара (pBig10, pBig1) - точка, которая существует на кривой. Далее инитализируется pBig_3: pBig_3 = 12C34484F6C34BB886EEE052ACC6247098BEDC3C "Создается" еще одна точка (P2): x=pBig_2 y=pBig_3 Все, что было сказано про P1, можно сказать и здесь =) Хм, а дальше просиходит очень интересная вещь. Еще одна точка - P3: TMG_:00401507 8B+ mov eax, [esp+1A4h+v_code] TMG_:0040150B 52 push edx ; point structure TMG_:0040150C 50 push eax ; reg_code (прим.пер. - тут надо было написать v_code, даже только судя по mov eax[..+v_code] ;) ) TMG_:0040150D 56 push esi ; pBig_9 TMG_:0040150E 56 push esi ; pBig_9 TMG_:0040150F E8+ call epoint_set Но как так вышло, что x=y=pBig_9, смотрим в доки Miracl'а: +======================================================================+ 1.1.2 epoint_set Function: BOOL epoint_set(x,y,lsb,p) big x,y; int lsb; epoint *p; Module: mrcurve.c Description: Sets a point on the current active GF(p) elliptic curve (if possible). Parameters: The integer co-ordinates x and y of the point p. If x and y are not distinct variables then x only is passed to the function, and lsb is taken as the least significant bit of y. In this case the full value of y is reconstructed internally. This is known as “point decompression” (and is a bit time-consuming, requiring the extraction of a modular square root). On exit p=(x,y). Return value: TRUE if the point exists on the current active point, otherwise FALSE. +======================================================================+ Тоесть, кейгенми "расжимает" текущую точку, но что это значит на самом деле? Ранее, я сказал, что данная кривая вида: y^2=x^3+A*x+B mod p Значит, если мы знаем x и несущий бит y, то мы может легко узнать y, решив от него уравнение нашей кривой: _____________________ / 3 y= + \/ (x + A*x + B) mod p - Но здесь мы имеем 2 решения - и здесь нам на помощь приходит несущий бит! Программа првоеряет, существует ли такая точка на кривой, если нет - рег.код неверный. Я уже говорил вам, что tE! не зря выбрал именно эту прямую с большим числом (q) точек на ней. Чтобы для каждого имени была соответствующая точка. Так что никто не идет лесом =)) Ну, а если уж точка существует, то крякмис переходит ко второй проверке: TMG_:004015EA 8B+ mov eax, [esp+1A4h+epoint_4] TMG_:004015EE 50 push eax TMG_:004015EF 55 push ebp ; epoint_1 TMG_:004015F0 53 push ebx ; ptBig_8 TMG_:004015F1 E8+ call ecurve_mult TMG_:004015F6 8B+ mov ecx, [esp+1B0h+epoint_4] TMG_:004015FA 8B+ mov edx, [esp+1B0h+epoint_2] TMG_:004015FE 83+ add esp, 0Ch TMG_:00401601 51 push ecx ; epoint_4 TMG_:00401602 52 push edx ; epoint_2 TMG_:00401603 E8+ call ecurve_sub TMG_:00401608 83+ add esp, 8 TMG_:0040160B 55 push ebp ; epoint_1 TMG_:0040160C 55 push ebp ; epoint_1 TMG_:0040160D E8+ call ecurve_add TMG_:00401612 8B+ mov eax, [esp+1ACh+epoint_3] TMG_:00401616 83+ add esp, 8 TMG_:00401619 50 push eax ; epoint_3 TMG_:0040161A 55 push ebp ; epoint_1 TMG_:0040161B E8+ call ecurve_add TMG_:00401620 8B+ mov ecx, [esp+1ACh+epoint_4] TMG_:00401624 8B+ mov edx, [esp+1ACh+epoint_3] TMG_:00401628 83+ add esp, 8 TMG_:0040162B 51 push ecx ; epoint_4 TMG_:0040162C 52 push edx ; epoint_3 TMG_:0040162D E8+ call epoint_comp TMG_:00401632 83+ add esp, 8 TMG_:00401635 83+ cmp eax, 1 TMG_:00401638 75+ jnz short loc_40165A TMG_:0040163A 8B+ mov eax, [esp+1A4h+hWnd] TMG_:00401641 8B+ mov ecx, ds:hInstance TMG_:00401647 6A+ push 0 ; dwInitParam TMG_:00401649 68+ push offset loc_401000 ; lpDialogFunc TMG_:0040164E 50 push eax ; hWndParent TMG_:0040164F 6A+ push 76h ; lpTemplateName TMG_:00401651 51 push ecx ; hInstance TMG_:00401652 FF+ call ds:DialogBoxParamA Здесь происходит следующее: P4= P1*pBig_8 P4= P4 - P2 P1= P1 + P1 = 2*P1 P3= P3 + P1 ДЛЯ ПРАВИЛЬНОГО РЕГ.КОДА: P3==P4 Как "сделать" так, чтобы это условие выполнялось? Легко: P4= P1*pBig_8 P4= P4 - P2 = P1*pBig_8 - P2 P1= P1 + P1 = P1*2 P3= P3 + P1*2 Тоесть: P3==P4 <=> P1*pBig_8 – P2 = P3 + 2*P1 <=> P3 = P1*(pBig_8 – 2) – P2 и это и есть решение! Кейген: - поулчаем имя - получаем хеш - модиф. мд5 - присваиваем хеш большому числу (pBig_Hash) - pBig_Hash = pBig_Hash ^3 mod AB6853BDD1100F57 - создаем эллиптическую кривую - ставим 2 точки на ней - P1 и P2 - P3 = P1*(pBig_Hash – 2) – P1 - вызываем epoint_get, с такими параметрами - P3, большое число (которому будет присвоен рег.код); возвращаемое значение - наш v_code (0 или 1) И это все про данный крякмис. :: Outro :: Этот крякмис был первым, который заставил меня окунуться в новое "море" криптографии - ECC. И, насколько я помню, это елинственный крякмис, который оперирует ECC. (c) bLaCk-eYe 2003 mycherynos@yahoo.com ps. Все файлы к статье - tmg4.zip