Advertisement
Guest User

TI 4 ready 08.12 17:09

a guest
Dec 8th, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 12.67 KB | None | 0 0
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  7.    System.Classes, Vcl.Graphics,
  8.    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
  9.  
  10. type
  11.    ByteArray = array [1 .. 128] of Byte;
  12.    TBytesToPrint = array of Byte;
  13.  
  14.    TForm1 = class(TForm)
  15.       edtP: TEdit;
  16.       lbP: TLabel;
  17.       btConfirm: TButton;
  18.       edtQ: TEdit;
  19.       lbQ: TLabel;
  20.       edtR: TEdit;
  21.       lbR: TLabel;
  22.       edtEuler: TEdit;
  23.       lbEuler: TLabel;
  24.     edtD: TEdit;
  25.     lbD: TLabel;
  26.     edtE: TEdit;
  27.     lbE: TLabel;
  28.       edtPublicKey: TEdit;
  29.       lbPublicKey: TLabel;
  30.       edtPrivateKey: TEdit;
  31.       lbPrivateKey: TLabel;
  32.       btnSignature: TButton;
  33.       OpenDialog: TOpenDialog;
  34.       SaveDialog1: TSaveDialog;
  35.       lbM: TLabel;
  36.       edtM: TEdit;
  37.       lbS: TLabel;
  38.       edtS: TEdit;
  39.     btnCheck: TButton;
  40.     edtM2: TEdit;
  41.     mmRes: TMemo;
  42.     lbM2: TLabel;
  43.       procedure ProcessCode(FileName: string);
  44.       procedure CheckEnteredNumber(Sender: TObject; Ident: Char;
  45.         var Number: string; BottomLine: Integer; TopLine: Int64);
  46.       procedure btConfirmClick(Sender: TObject);
  47.       procedure CheckEnteredNumberExt(Sender: TObject; Ident: Char;
  48.         var Number: string; BottomLine: Integer; TopLine: Int64);
  49.       procedure edtPKeyPress(Sender: TObject; var Key: Char);
  50.       procedure edtQKeyPress(Sender: TObject; var Key: Char);
  51.       procedure edtDKeyPress(Sender: TObject; var Key: Char);
  52.       procedure FormCreate(Sender: TObject);
  53.       procedure btnSignatureClick(Sender: TObject);
  54.     procedure btnCheckClick(Sender: TObject);
  55.    private
  56.       { Private declarations }
  57.    public
  58.       { Public declarations }
  59.    end;
  60.  
  61. var
  62.    Form1: TForm1;
  63.    NumberP, NumberQ, NumberR, NumberD, NumberE: string;
  64.    EulerFunc: string;
  65.    fNameCipher, fNameDecipher: string;
  66.    BytesArr: TBytesToPrint;
  67.  
  68. const
  69.    cBytesMax = 128;
  70.  
  71. implementation
  72.  
  73. {$R *.dfm}
  74. { TForm1 }
  75.  
  76. function IsPrimeNumber(Number: Int64): Boolean;
  77. var
  78.    i: Integer;
  79. begin
  80.    result := false;
  81.    if not Odd(Number) and (Number <> 2) then
  82.       Exit;
  83.    i := 3;
  84.    while i <= Sqrt(Number) do
  85.    begin
  86.       if Number mod i = 0 then
  87.          Exit;
  88.       inc(i, 2);
  89.    end;
  90.    result := true;
  91. end;
  92.  
  93. function IsPrimeButton(Number: Int64): Boolean;
  94. begin
  95.    if IsPrimeNumber(Number) then
  96.       result := true
  97.    else
  98.       result := false;
  99. end;
  100.  
  101. function ExtendedGCD(a, b: Integer; var x, y, gcd: Integer): Integer;
  102. var
  103.    x1, y1: Integer;
  104. begin
  105.    If b = 0 Then
  106.    begin
  107.       gcd := a;
  108.       x := 1;
  109.       y := 0;
  110.       Exit
  111.    end;
  112.    ExtendedGCD(b, a mod b, x1, y1, gcd);
  113.    x := y1;
  114.    y := x1 - (a div b) * y1;
  115.    result := gcd;
  116. end;
  117.  
  118. function FastExp(Number, Degree, Module: Int64): Int64;
  119. var
  120.    Num, Deg, Res, TempNum: Int64;
  121. begin
  122.    Num := Number;
  123.    Deg := Degree;
  124.    Res := 1;
  125.    while Deg <> 0 do
  126.    begin
  127.       while (Deg mod 2) = 0 do
  128.       begin
  129.          Deg := Deg div 2;
  130.          TempNum := Num mod Module;
  131.          Num := (TempNum * TempNum) mod Module;
  132.       end;
  133.       Deg := Deg - 1;
  134.       Res := (Res * Num) mod Module;
  135.    end;
  136.    FastExp := Res;
  137. end;
  138.  
  139. function HashFunction(StartValue: Integer; TempByte: Byte): Int64;
  140. begin
  141.    HashFunction :=  FastExp((StartValue + TempByte), 2, StrToInt(NumberR));
  142. end;
  143.  
  144. function CalcHashFunction(StartValue: Integer; TempByte: Byte): Int64;
  145. begin
  146.    CalcHashFunction := HashFunction(StartValue, TempByte);
  147. end;
  148.  
  149. procedure TForm1.btConfirmClick(Sender: TObject);
  150. var
  151.    Temp: Integer;
  152.    x, y, gcd: Integer;
  153. begin
  154.    edtPublicKey.Clear;
  155.    edtPrivateKey.Clear;
  156.    EulerFunc := '';
  157.    CheckEnteredNumber(edtP, 'p', NumberP, 2, 2147483647);
  158.    CheckEnteredNumber(edtQ, 'q', NumberQ, 2, 2147483647);
  159.    if (NumberP <> '') and (NumberQ <> '') then
  160.    begin
  161.       NumberR := IntToStr(StrToInt64(NumberP) * StrToInt64(NumberQ));
  162.       edtR.Text := NumberR;
  163.       EulerFunc := IntToStr((StrToInt64(NumberP) - 1) * (StrToInt64(NumberQ) - 1));
  164.       edtEuler.Text := EulerFunc;
  165.    end;
  166.    if (NumberP = '') or (NumberQ = '') then
  167.       edtEuler.Clear;
  168.    if (EulerFunc <> '') then
  169.       CheckEnteredNumberExt(edtD, 'd', NumberD, 2, StrToInt64(EulerFunc));
  170.    if (NumberD <> '') and (EulerFunc <> '') then
  171.    begin
  172.       Temp := ExtendedGCD(StrToInt64(NumberD), StrToInt64(EulerFunc), x, y, gcd);
  173.       NumberE := IntToStr(x);
  174.       if (StrToInt(NumberE) < 0) then
  175.          NumberE := IntToStr(StrToInt64(NumberE) + StrToInt64(EulerFunc));
  176.       edtE.Text := NumberE;
  177.    end;
  178.    if (NumberE <> '') and (NumberR <> '') then
  179.       edtPublicKey.Text := NumberE + ', ' + NumberR;
  180.    if (NumberD <> '') and (NumberR <> '') then
  181.       edtPrivateKey.Text := NumberD + ', ' + NumberR;
  182. end;
  183.  
  184. procedure TForm1.CheckEnteredNumber(Sender: TObject; Ident: Char;
  185.   var Number: string; BottomLine: Integer; TopLine: Int64);
  186. begin
  187.    with Sender as TEdit do
  188.       if Number <> '' then
  189.       begin
  190.          if (StrToInt64(Number) >= BottomLine) and (StrToInt64(Number) < TopLine)
  191.          then
  192.          begin
  193.             if (Ident = 'p') or (Ident = 'q') then
  194.                if not IsPrimeButton(StrToInt64(Number)) then
  195.                begin
  196.                   ShowMessage('Число ' + Ident + ' должно быть простым');
  197.                   Number := '';
  198.                   Clear;
  199.                end;
  200.          end
  201.          else
  202.          begin
  203.             ShowMessage('Введите число ' + Ident + ' больше ' +
  204.               IntToStr(BottomLine - 1) + ' меньше ' + IntToStr(TopLine));
  205.             Number := '';
  206.             Clear;
  207.          end;
  208.       end
  209.       else
  210.       begin
  211.          //if (Ident <> 'p') then
  212.             ShowMessage('Введите простое число ' + Ident);
  213.          Number := '';
  214.          Clear;
  215.       end;
  216. end;
  217.  
  218. procedure TForm1.CheckEnteredNumberExt(Sender: TObject; Ident: Char;
  219.   var Number: string; BottomLine: Integer; TopLine: Int64);
  220. var
  221.    x, y, gcd: Integer;
  222. begin
  223.    with Sender as TEdit do
  224.    begin
  225.       if Number <> '' then
  226.       begin
  227.          if (StrToInt64(Number) >= BottomLine) and (StrToInt64(Number) < TopLine)
  228.          then
  229.          begin
  230.          end
  231.          else
  232.          begin
  233.             ShowMessage('Введите число ' + Ident + ' больше ' +
  234.               IntToStr(BottomLine - 1) + ' меньше ' + IntToStr(TopLine));
  235.             Number := '';
  236.             Clear;
  237.          end;
  238.       end
  239.       else
  240.       begin
  241.          ShowMessage('Введите простое число ' + Ident);
  242.          Number := '';
  243.          Clear;
  244.       end;
  245.       if NumberD <> '' then
  246.          if ExtendedGCD(StrToInt64(NumberD), StrToInt64(EulerFunc), x, y,
  247.            gcd) <> 1 then
  248.          begin
  249.             ShowMessage('Введите число d взаимно простое с φ(r)');
  250.             Number := '';
  251.             Clear;
  252.          end;
  253.    end;
  254. end;
  255.  
  256. procedure TForm1.edtDKeyPress(Sender: TObject; var Key: Char);
  257. const
  258.    Digit: set of Char = ['0' .. '9'];
  259. begin
  260.    if Key in Digit then
  261.       NumberD := NumberD + Key;
  262.    if Key = #8 then
  263.    begin
  264.       NumberD := '';
  265.       edtD.Text := '';
  266.    end;
  267. end;
  268.  
  269. procedure TForm1.edtPKeyPress(Sender: TObject; var Key: Char);
  270. const
  271.    Digit: set of Char = ['0' .. '9'];
  272. begin
  273.    if Key in Digit then
  274.       NumberP := NumberP + Key;
  275.    if Key = #8 then
  276.    begin
  277.       NumberP := '';
  278.       edtP.Text := '';
  279.    end;
  280. end;
  281.  
  282. procedure TForm1.edtQKeyPress(Sender: TObject; var Key: Char);
  283. const
  284.    Digit: set of Char = ['0' .. '9'];
  285. begin
  286.    if Key in Digit then
  287.       NumberQ := NumberQ + Key;
  288.    if Key = #8 then
  289.    begin
  290.       NumberQ := '';
  291.       edtQ.Text := '';
  292.    end;
  293. end;
  294.  
  295. procedure TForm1.FormCreate(Sender: TObject);
  296. begin
  297.    NumberP := '';
  298.    NumberQ := '';
  299.    NumberR := '';
  300.    NumberD := '';
  301.    NumberE := '';
  302. end;
  303.  
  304. procedure TForm1.ProcessCode(FileName: string);
  305. var
  306.    i: Integer;
  307. begin
  308.    fNameCipher := FileName;
  309.    i := Length(fNameCipher);
  310.    while fNameCipher[i] <> '.' do
  311.       Dec(i);
  312.    Insert('  CIPHER', fNameCipher, i);
  313.    fNameDecipher := fNameCipher;
  314.    Insert(' DE', fNameDecipher, pos('CIPHER', fNameDecipher));
  315. end;
  316.  
  317. procedure Encrypt(InputFileName, OutputFileName: string;
  318.   var Output: TBytesToPrint);
  319. var
  320.    InputBuffer: array [1 .. cBytesMax] of Byte;
  321.    OutputBuffer: array [1 .. cBytesMax + 4] of Byte;
  322.    InputStream, OutputStream: TFileStream;
  323.    cBytes, i: Integer;
  324.    IsOutputFilled: Boolean;
  325.    M: Integer;
  326.    S: Integer;
  327.    F: TextFile;
  328. begin
  329.    M := 100;
  330.    InputStream := TFileStream.Create(InputFileName, fmOpenRead);
  331.    OutputStream := TFileStream.Create(OutputFileName, fmCreate);
  332.    IsOutputFilled := false;
  333.    SetLength(Output, cBytesMax);
  334.    repeat
  335.       cBytes := InputStream.ReadData(InputBuffer);
  336.       i := 1;
  337.       while i <= cBytes do
  338.       begin
  339.          OutputBuffer[i] := InputBuffer[i];
  340.          if not IsOutputFilled then
  341.          begin
  342.             Output[i - 1] := OutputBuffer[i];
  343.             M := CalcHashFunction(M, Output[i - 1]);
  344.          end;
  345.          inc(i, 1);
  346.       end;
  347.       if not IsOutputFilled then
  348.       begin
  349.          SetLength(Output, cBytes);
  350.          IsOutputFilled := true;
  351.       end;
  352.       OutputStream.WriteData(Output, cBytes);
  353.    until (InputStream.Position = InputStream.Size);
  354.    OutputStream.Seek(0, soFromEnd);
  355.    Form1.edtM.Text := IntToStr(M);
  356.    S := FastExp(M, StrToInt64(NumberD), StrToInt64(NumberR));
  357.    Form1.edtS.Text := IntToStr(S);
  358.    InputStream.Free;
  359.    OutputStream.Free;
  360.    AssignFile(F, OutputFileName);
  361.    Append(F);
  362.    Write(F, '|');
  363.    Write(F, Int64(S));
  364.    CloseFile(F);
  365. end;
  366.  
  367. procedure Decrypt(InputFileName, OutputFileName: string;
  368.   var Output: TBytesToPrint);
  369. var
  370.    InputBuffer: array [1 .. cBytesMax] of Byte;
  371.    OutputBuffer: array [1 .. cBytesMax + 4] of Byte;
  372.    InputStream: TFileStream;
  373.    cBytes, i, j: Integer;
  374.    IsOutputFilled: Boolean;
  375.    M2, M1: Integer;
  376.    Valider: Integer;
  377.    CheckNumber: string;
  378. const
  379.    Digit: set of Char = ['0' .. '9'];
  380. begin
  381.    M2 := 100;
  382.    InputStream := TFileStream.Create(InputFileName, fmOpenRead);
  383.    IsOutputFilled := false;
  384.    SetLength(Output, cBytesMax);
  385.    repeat
  386.       cBytes := InputStream.ReadData(InputBuffer);
  387.       i := 1;
  388.       while (i <= cBytes) and (ord(InputBuffer[i]) <> 124) do
  389.       begin
  390.          OutputBuffer[i] := InputBuffer[i];
  391.          if not IsOutputFilled then
  392.          begin
  393.             Output[i - 1] := OutputBuffer[i];
  394.             M2 := CalcHashFunction(M2, Output[i - 1]);
  395.          end;
  396.          inc(i, 1);
  397.       end;
  398.       if (ord(InputBuffer[i]) = 124) then
  399.       begin
  400.          inc(i);
  401.          Valider := cBytes - i + 1;
  402.          for j := i to cBytes  do
  403.          begin
  404.             if chr(InputBuffer[i]) in Digit then
  405.             begin
  406.                CheckNumber := CheckNumber + chr(InputBuffer[i]);
  407.                dec(Valider);
  408.             end;
  409.             inc(i);
  410.          end;
  411.  
  412.       end;
  413.       if not IsOutputFilled then
  414.       begin
  415.          SetLength(Output, cBytes);
  416.          IsOutputFilled := true;
  417.       end;
  418.    until (InputStream.Position = InputStream.Size);
  419.    InputStream.Free;
  420.    Form1.edtM2.Text := IntToStr(M2);
  421.    M1 := FastExp(StrToInt64(CheckNumber), StrToInt64(NumberE), StrToInt64(NumberR));
  422.    Form1.edtM.Text := IntToStr(M1);
  423.    if (M1 = M2) then
  424.       Form1.mmRes.Text := 'Подпись действительна, т.к. m'' = m'
  425.    else
  426.       Form1.mmRes.Text := 'Подпись недействительна, т.к. m'' <> m';
  427.    if (Valider <> 0) then
  428.             Form1.mmRes.Text := 'Подпись содержит некорректные символы';
  429. end;
  430.  
  431. procedure TForm1.btnCheckClick(Sender: TObject);
  432. var
  433.    Output: TBytesToPrint;
  434. begin
  435.    edtM2.Clear;
  436.    mmRes.Clear;
  437.    if (NumberP <> '') and (NumberQ <> '') and (NumberR <> '') and
  438.      (NumberD <> '') and (NumberE <> '') then
  439.    begin
  440.       if OpenDialog.Execute then
  441.          Decrypt(OpenDialog.FileName, fNameDecipher, Output);
  442.    end;
  443.    lbM.Visible := True;
  444.    edtM.Visible := True;
  445.    lbM2.Visible := True;
  446.    edtM2.Visible := True;
  447.    mmRes.Visible := True;
  448. end;
  449.  
  450. procedure TForm1.btnSignatureClick(Sender: TObject);
  451. var
  452.    Output: TBytesToPrint;
  453. begin
  454.    edtM.Clear;
  455.    edtS.Clear;
  456.    edtM2.Clear;
  457.    mmRes.Clear;
  458.    if (NumberP <> '') and (NumberQ <> '') and (NumberR <> '') and
  459.      (NumberD <> '') and (NumberE <> '') then
  460.    begin
  461.       if OpenDialog.Execute then
  462.       begin
  463.          ProcessCode(OpenDialog.FileName);
  464.          Encrypt(OpenDialog.FileName, fNameCipher, Output);
  465.       end;
  466.    end;
  467.    lbM.Visible := True;
  468.    edtM.Visible := True;
  469.    lbS.Visible := True;
  470.    edtS.Visible := True;
  471. end;
  472.  
  473. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement