/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cryptolearning;

import com.sun.rave.web.ui.appbase.AbstractPageBean;
import com.sun.webui.jsf.component.Button;
import com.sun.webui.jsf.component.ImageComponent;
import com.sun.webui.jsf.component.StaticText;
import javax.faces.FacesException;
import javax.faces.component.html.HtmlCommandButton;
import javax.faces.component.html.HtmlInputText;
import javax.swing.JSpinner;
import core.*;

import core.ExMath;
import core.ExtraException;
import javax.swing.JOptionPane;
import logarithm.PrimeGen;

/**
 * <p>Page bean that corresponds to a similarly named JSP page.  This
 * class contains component definitions (and initialization code) for
 * all components that you have defined on this page, as well as
 * lifecycle methods and event handlers where you may add behavior
 * to respond to incoming events.</p>
 *
 * @version template.java
 * @version Created on 16.2.2009, 10:32:31
 * @author jirka
 */

public class ElGalman_Podepisovani extends AbstractPageBean {
    // <editor-fold defaultstate="collapsed" desc="Managed Component Definition">

    /**
     * <p>Automatically managed component initialization.  <strong>WARNING:</strong>
     * This method is automatically generated, so any user-specified code inserted
     * here is subject to being replaced.</p>
     */
    private void _init() throws Exception {
    }
    private HtmlInputText txtN = new HtmlInputText();

    public HtmlInputText getTxtN() {
        return txtN;
    }

    public void setTxtN(HtmlInputText hit) {
        this.txtN = hit;
    }
    private HtmlInputText txtB = new HtmlInputText();

    public HtmlInputText getTxtB() {
        return txtB;
    }

    public void setTxtB(HtmlInputText hit) {
        this.txtB = hit;
    }
    private HtmlInputText txtK = new HtmlInputText();

    public HtmlInputText getTxtK() {
        return txtK;
    }

    public void setTxtK(HtmlInputText hit) {
        this.txtK = hit;
    }
    private StaticText labY = new StaticText();

    public StaticText getLabY() {
        return labY;
    }

    public void setLabY(StaticText st) {
        this.labY = st;
    }
    private StaticText labPublicKey = new StaticText();

    public StaticText getLabPublicKey() {
        return labPublicKey;
    }

    public void setLabPublicKey(StaticText st) {
        this.labPublicKey = st;
    }
    private StaticText labPrivateKey = new StaticText();

    public StaticText getLabPrivateKey() {
        return labPrivateKey;
    }

    public void setLabPrivateKey(StaticText st) {
        this.labPrivateKey = st;
    }
    private HtmlInputText txtP1 = new HtmlInputText();

    public HtmlInputText getTxtP1() {
        return txtP1;
    }

    public void setTxtP1(HtmlInputText hit) {
        this.txtP1 = hit;
    }
    private HtmlInputText txtQ1 = new HtmlInputText();

    public HtmlInputText getTxtQ1() {
        return txtQ1;
    }

    public void setTxtQ1(HtmlInputText hit) {
        this.txtQ1 = hit;
    }
    private StaticText labN1 = new StaticText();

    public StaticText getLabN1() {
        return labN1;
    }

    public void setLabN1(StaticText st) {
        this.labN1 = st;
    }
    private StaticText labB1 = new StaticText();

    public StaticText getLabB1() {
        return labB1;
    }

    public void setLabB1(StaticText st) {
        this.labB1 = st;
    }
    private HtmlInputText txtM1 = new HtmlInputText();

    public HtmlInputText getTxtM1() {
        return txtM1;
    }

    public void setTxtM1(HtmlInputText hit) {
        this.txtM1 = hit;
    }
    private StaticText labASCIIM1 = new StaticText();

    public StaticText getLabASCIIM1() {
        return labASCIIM1;
    }

    public void setLabASCIIM1(StaticText st) {
        this.labASCIIM1 = st;
    }
    private StaticText labHash1 = new StaticText();

    public StaticText getLabHash1() {
        return labHash1;
    }

    public void setLabHash1(StaticText st) {
        this.labHash1 = st;
    }
    private StaticText hiddenCislo = new StaticText();

    public StaticText getHiddenCislo() {
        return hiddenCislo;
    }

    public void setHiddenCislo(StaticText st) {
        this.hiddenCislo = st;
    }
    private StaticText labKrok = new StaticText();

    public StaticText getLabKrok() {
        return labKrok;
    }

    public void setLabKrok(StaticText st) {
        this.labKrok = st;
    }
    private StaticText labPopis = new StaticText();

    public StaticText getLabPopis() {
        return labPopis;
    }

    public void setLabPopis(StaticText st) {
        this.labPopis = st;
    }
    private Button btnSkip = new Button();

    public Button getBtnSkip() {
        return btnSkip;
    }

    public void setBtnSkip(Button b) {
        this.btnSkip = b;
    }
    private Button btnBack = new Button();

    public Button getBtnBack() {
        return btnBack;
    }

    public void setBtnBack(Button b) {
        this.btnBack = b;
    }
    private Button btnFwd = new Button();

    public Button getBtnFwd() {
        return btnFwd;
    }

    public void setBtnFwd(Button b) {
        this.btnFwd = b;
    }
    private HtmlInputText txtKlic1 = new HtmlInputText();

    public HtmlInputText getTxtKlic1() {
        return txtKlic1;
    }

    public void setTxtKlic1(HtmlInputText hit) {
        this.txtKlic1 = hit;
    }
    private HtmlInputText txtM2 = new HtmlInputText();

    public HtmlInputText getTxtM2() {
        return txtM2;
    }

    public void setTxtM2(HtmlInputText hit) {
        this.txtM2 = hit;
    }
    private HtmlInputText txtHash1 = new HtmlInputText();

    public HtmlInputText getTxtHash1() {
        return txtHash1;
    }

    public void setTxtHash1(HtmlInputText hit) {
        this.txtHash1 = hit;
    }
    private HtmlInputText txtCislo1 = new HtmlInputText();

    public HtmlInputText getTxtCislo1() {
        return txtCislo1;
    }

    public void setTxtCislo1(HtmlInputText hit) {
        this.txtCislo1 = hit;
    }
    private StaticText labR1 = new StaticText();

    public StaticText getLabR1() {
        return labR1;
    }

    public void setLabR1(StaticText st) {
        this.labR1 = st;
    }
    private StaticText labS1 = new StaticText();

    public StaticText getLabS1() {
        return labS1;
    }

    public void setLabS1(StaticText st) {
        this.labS1 = st;
    }
    private HtmlCommandButton button1 = new HtmlCommandButton();

    public HtmlCommandButton getButton1() {
        return button1;
    }

    public void setButton1(HtmlCommandButton hcb) {
        this.button1 = hcb;
    }
    private HtmlInputText txtPublicKey1 = new HtmlInputText();

    public HtmlInputText getTxtPublicKey1() {
        return txtPublicKey1;
    }

    public void setTxtPublicKey1(HtmlInputText hit) {
        this.txtPublicKey1 = hit;
    }
    private HtmlInputText txtMessage1 = new HtmlInputText();

    public HtmlInputText getTxtMessage1() {
        return txtMessage1;
    }

    public void setTxtMessage1(HtmlInputText hit) {
        this.txtMessage1 = hit;
    }
    private HtmlInputText txtR1 = new HtmlInputText();

    public HtmlInputText getTxtR1() {
        return txtR1;
    }

    public void setTxtR1(HtmlInputText hit) {
        this.txtR1 = hit;
    }
    private HtmlInputText txtS1 = new HtmlInputText();

    public HtmlInputText getTxtS1() {
        return txtS1;
    }

    public void setTxtS1(HtmlInputText hit) {
        this.txtS1 = hit;
    }
    private HtmlInputText txtHash2 = new HtmlInputText();

    public HtmlInputText getTxtHash2() {
        return txtHash2;
    }

    public void setTxtHash2(HtmlInputText hit) {
        this.txtHash2 = hit;
    }
    private StaticText labV1 = new StaticText();

    public StaticText getLabV1() {
        return labV1;
    }

    public void setLabV1(StaticText st) {
        this.labV1 = st;
    }
    private StaticText labV2 = new StaticText();

    public StaticText getLabV2() {
        return labV2;
    }

    public void setLabV2(StaticText st) {
        this.labV2 = st;
    }
    private HtmlCommandButton btnOver1 = new HtmlCommandButton();

    public HtmlCommandButton getBtnOver1() {
        return btnOver1;
    }

    public void setBtnOver1(HtmlCommandButton hcb) {
        this.btnOver1 = hcb;
    }
    private StaticText labResult1 = new StaticText();

    public StaticText getLabResult1() {
        return labResult1;
    }

    public void setLabResult1(StaticText st) {
        this.labResult1 = st;
    }
    private HtmlCommandButton button2 = new HtmlCommandButton();

    public HtmlCommandButton getButton2() {
        return button2;
    }

    public void setButton2(HtmlCommandButton hcb) {
        this.button2 = hcb;
    }
    private HtmlCommandButton btnRad1 = new HtmlCommandButton();

    public HtmlCommandButton getBtnRad1() {
        return btnRad1;
    }

    public void setBtnRad1(HtmlCommandButton hcb) {
        this.btnRad1 = hcb;
    }
    private HtmlCommandButton btnHash1 = new HtmlCommandButton();

    public HtmlCommandButton getBtnHash1() {
        return btnHash1;
    }

    public void setBtnHash1(HtmlCommandButton hcb) {
        this.btnHash1 = hcb;
    }
    private Button btnRestart = new Button();

    public Button getBtnRestart() {
        return btnRestart;
    }

    public void setBtnRestart(Button b) {
        this.btnRestart = b;
    }
    private ImageComponent imgCert = new ImageComponent();

    public ImageComponent getImgCert() {
        return imgCert;
    }

    public void setImgCert(ImageComponent ic) {
        this.imgCert = ic;
    }
    private ImageComponent imgSipKrDol = new ImageComponent();

    public ImageComponent getImgSipKrDol() {
        return imgSipKrDol;
    }

    public void setImgSipKrDol(ImageComponent ic) {
        this.imgSipKrDol = ic;
    }
    private ImageComponent imgCA = new ImageComponent();

    public ImageComponent getImgCA() {
        return imgCA;
    }

    public void setImgCA(ImageComponent ic) {
        this.imgCA = ic;
    }
    private ImageComponent imgSipKrPr = new ImageComponent();

    public ImageComponent getImgSipKrPr() {
        return imgSipKrPr;
    }

    public void setImgSipKrPr(ImageComponent ic) {
        this.imgSipKrPr = ic;
    }
    private ImageComponent imgSipKrLv = new ImageComponent();

    public ImageComponent getImgSipKrLv() {
        return imgSipKrLv;
    }

    public void setImgSipKrLv(ImageComponent ic) {
        this.imgSipKrLv = ic;
    }
    private StaticText labPrenos1 = new StaticText();

    public StaticText getLabPrenos1() {
        return labPrenos1;
    }

    public void setLabPrenos1(StaticText st) {
        this.labPrenos1 = st;
    }
    private ImageComponent imgCert2 = new ImageComponent();

    public ImageComponent getImgCert2() {
        return imgCert2;
    }

    public void setImgCert2(ImageComponent ic) {
        this.imgCert2 = ic;
    }
    private ImageComponent imgArrowBigRight1 = new ImageComponent();

    public ImageComponent getImgArrowBigRight1() {
        return imgArrowBigRight1;
    }

    public void setImgArrowBigRight1(ImageComponent ic) {
        this.imgArrowBigRight1 = ic;
    }
    private HtmlInputText txtKlic2 = new HtmlInputText();

    public HtmlInputText getTxtKlic2() {
        return txtKlic2;
    }

    public void setTxtKlic2(HtmlInputText hit) {
        this.txtKlic2 = hit;
    }
    private HtmlInputText txtOdp1 = new HtmlInputText();

    public HtmlInputText getTxtOdp1() {
        return txtOdp1;
    }

    public void setTxtOdp1(HtmlInputText hit) {
        this.txtOdp1 = hit;
    }
    private HtmlInputText txtOdp2 = new HtmlInputText();

    public HtmlInputText getTxtOdp2() {
        return txtOdp2;
    }

    public void setTxtOdp2(HtmlInputText hit) {
        this.txtOdp2 = hit;
    }
    private HtmlInputText txtOdp3 = new HtmlInputText();

    public HtmlInputText getTxtOdp3() {
        return txtOdp3;
    }

    public void setTxtOdp3(HtmlInputText hit) {
        this.txtOdp3 = hit;
    }
    private StaticText labO1 = new StaticText();

    public StaticText getLabO1() {
        return labO1;
    }

    public void setLabO1(StaticText st) {
        this.labO1 = st;
    }
    private StaticText labO2 = new StaticText();

    public StaticText getLabO2() {
        return labO2;
    }

    public void setLabO2(StaticText st) {
        this.labO2 = st;
    }
    private StaticText labO3 = new StaticText();

    public StaticText getLabO3() {
        return labO3;
    }

    public void setLabO3(StaticText st) {
        this.labO3 = st;
    }
    private HtmlInputText txtOdp4 = new HtmlInputText();

    public HtmlInputText getTxtOdp4() {
        return txtOdp4;
    }

    public void setTxtOdp4(HtmlInputText hit) {
        this.txtOdp4 = hit;
    }
    private HtmlInputText txtOdp5 = new HtmlInputText();

    public HtmlInputText getTxtOdp5() {
        return txtOdp5;
    }

    public void setTxtOdp5(HtmlInputText hit) {
        this.txtOdp5 = hit;
    }
    private HtmlInputText txtOdp6 = new HtmlInputText();

    public HtmlInputText getTxtOdp6() {
        return txtOdp6;
    }

    public void setTxtOdp6(HtmlInputText hit) {
        this.txtOdp6 = hit;
    }
    private StaticText labO4 = new StaticText();

    public StaticText getLabO4() {
        return labO4;
    }

    public void setLabO4(StaticText st) {
        this.labO4 = st;
    }
    private StaticText labO5 = new StaticText();

    public StaticText getLabO5() {
        return labO5;
    }

    public void setLabO5(StaticText st) {
        this.labO5 = st;
    }
    private StaticText labO6 = new StaticText();

    public StaticText getLabO6() {
        return labO6;
    }

    public void setLabO6(StaticText st) {
        this.labO6 = st;
    }
    private HtmlInputText txtOdp7 = new HtmlInputText();

    public HtmlInputText getTxtOdp7() {
        return txtOdp7;
    }

    public void setTxtOdp7(HtmlInputText hit) {
        this.txtOdp7 = hit;
    }
    private StaticText labO7 = new StaticText();

    public StaticText getLabO7() {
        return labO7;
    }

    public void setLabO7(StaticText st) {
        this.labO7 = st;
    }

    // </editor-fold>

    /**
     * <p>Construct a new Page bean instance.</p>
     */
    public ElGalman_Podepisovani() {
    }

    /**
     * <p>Callback method that is called whenever a page is navigated to,
     * either directly via a URL, or indirectly via page navigation.
     * Customize this method to acquire resources that will be needed
     * for event handlers and lifecycle methods, whether or not this
     * page is performing post back processing.</p>
     * 
     * <p>Note that, if the current request is a postback, the property
     * values of the components do <strong>not</strong> represent any
     * values submitted with this request.  Instead, they represent the
     * property values that were saved for this view when it was rendered.</p>
     */
    @Override
    public void init() {
        // Perform initializations inherited from our superclass
        super.init();
        // Perform application initialization that must complete
        // *before* managed components are initialized
        // TODO - add your own initialiation code here
        
        // <editor-fold defaultstate="collapsed" desc="Managed Component Initialization">
        // Initialize automatically managed components
        // *Note* - this logic should NOT be modified
        try {
            _init();
        } catch (Exception e) {
            log("template Initialization Failure", e);
            throw e instanceof FacesException ? (FacesException) e: new FacesException(e);
        }
        
        // </editor-fold>
        // Perform application initialization that must complete
        // *after* managed components are initialized
        // TODO - add your own initialization code here
    }

    /**
     * <p>Callback method that is called after the component tree has been
     * restored, but before any event processing takes place.  This method
     * will <strong>only</strong> be called on a postback request that
     * is processing a form submit.  Customize this method to allocate
     * resources that will be required in your event handlers.</p>
     */
    @Override
    public void preprocess() {
    }

    /**
     * <p>Callback method that is called just before rendering takes place.
     * This method will <strong>only</strong> be called for the page that
     * will actually be rendered (and not, for example, on a page that
     * handled a postback and then navigated to a different page).  Customize
     * this method to allocate resources that will be required for rendering
     * this page.</p>
     */
    @Override
    public void prerender() {
    }

    /**
     * <p>Callback method that is called after rendering is completed for
     * this request, if <code>init()</code> was called (regardless of whether
     * or not this was the page that was actually rendered).  Customize this
     * method to release resources acquired in the <code>init()</code>,
     * <code>preprocess()</code>, or <code>prerender()</code> methods (or
     * acquired during execution of an event handler).</p>
     */
    @Override
    public void destroy() {
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected SessionBean1 getSessionBean1() {
        return (SessionBean1) getBean("SessionBean1");
    }

    /**
     * <p>Return a reference to the scoped data bean.</p>
     *
     * @return reference to the scoped data bean
     */
    protected ApplicationBean1 getApplicationBean1() {
        return (ApplicationBean1) getBean("ApplicationBean1");
    }

    public String btnBack_action() {
        PerformStep(false);
        return null;
    }

    public String btnSkip_action() {
        ClearFields();
        btnSkip.setText("Restart okna");
        txtN.setDisabled(false);
        txtB.setDisabled(false);
        txtK.setDisabled(false);

        txtP1.setDisabled(false);
        txtQ1.setDisabled(false);
        txtM1.setDisabled(false);

        txtKlic1.setDisabled(false);
        txtKlic2.setDisabled(false);
        txtM2.setDisabled(false);
        txtHash1.setDisabled(false);
        txtCislo1.setDisabled(false);

        txtPublicKey1.setDisabled(false);
        txtMessage1.setDisabled(false);
        txtR1.setDisabled(false);
        txtS1.setDisabled(false);
        txtHash2.setDisabled(false);

        btnBack.setDisabled(true);
        btnFwd.setDisabled(true);
        //btnSkip.setDisabled(true);
        btnRad1.setDisabled(false);
        button2.setDisabled(false);
        btnHash1.setDisabled(false);
        button1.setDisabled(false);
        btnOver1.setDisabled(false);

        imgCA.setVisible(false);
        imgCert.setVisible(false);
        imgSipKrDol.setVisible(false);
        imgSipKrLv.setVisible(false);
        imgSipKrPr.setVisible(false);
        imgArrowBigRight1.setVisible(false);
        imgCert2.setVisible(false);
        labPrenos1.setVisible(false);

        return null;
    }

     private void ClearFields() {
        ///////////////////////////////////////////////
        // text prvni zpravy
        String zprava = "Jednou z variant ElGamalova kryptosystému je systém pro šifrování zpráv. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.";
        labPopis.setText(zprava);
        ///////////////////////////////////////////////

        txtN.setValue("??");
        txtB.setValue("??");
        txtK.setValue("??");
        labY.setText("??");
        labPublicKey.setText("??");
        labPrivateKey.setText("??");

        txtP1.setValue("??");
        txtQ1.setValue("??");
        labN1.setText("??");
        labB1.setText("??");
        txtM1.setValue("??");
        labASCIIM1.setText("??");
        labHash1.setText("??");

        txtKlic1.setValue("??");
        txtKlic2.setValue("??");
        txtM2.setValue("??");
        txtHash1.setValue("??");
        txtCislo1.setValue("??");
        labR1.setText("??");
        labS1.setText("??");
        txtPublicKey1.setValue("??");
        txtMessage1.setValue("??");
        txtR1.setValue("??");
        txtS1.setValue("??");
        txtHash2.setValue("??");
        labV1.setText("??");
        labV2.setText("??");

        hiddenCislo.setText(0);

   /*     btnBack.setDisabled(false);
        btnFwd.setDisabled(false);
        btnSkip.setDisabled(false);
        btnRad1.setDisabled(false);
        button2.setDisabled(false);
        btnHash1.setDisabled(false);
        button1.setDisabled(false);
        btnOver1.setDisabled(false);*/

    }
     public String btnRestart_action() {
        
        ClearFields();
        btnSkip.setText("Přeskočit průvodce");
        txtN.setDisabled(true);
        txtB.setDisabled(true);
        txtK.setDisabled(true);

        txtP1.setDisabled(true);
        txtQ1.setDisabled(true);
        txtM1.setDisabled(true);

        txtKlic1.setDisabled(true);
        txtM2.setDisabled(true);
        txtHash1.setDisabled(true);
        txtCislo1.setDisabled(true);

        txtPublicKey1.setDisabled(true);
        txtMessage1.setDisabled(true);
        txtR1.setDisabled(true);
        txtS1.setDisabled(true);
        txtHash2.setDisabled(true);

        btnBack.setDisabled(true);
        btnFwd.setDisabled(false);
        btnSkip.setDisabled(false);
        btnRad1.setDisabled(true);
        button2.setDisabled(true);
        btnHash1.setDisabled(true);
        button1.setDisabled(true);
        btnOver1.setDisabled(true);

        labKrok.setVisible(false);

        imgCA.setVisible(false);
        imgCert.setVisible(false);
        imgSipKrDol.setVisible(false);
        imgSipKrLv.setVisible(false);
        imgSipKrPr.setVisible(false);
        imgArrowBigRight1.setVisible(false);
        imgCert2.setVisible(false);
        labPrenos1.setVisible(false);

        return null;

    }

    private void PerformStep(boolean forward) {
        int krok = Integer.parseInt(hiddenCislo.getValue().toString());

        ////////////////////////////////////////////////
        // nastavit pocet kroku
        int pocetKroku = 12;
        ////////////////////////////////////////////////

        if (forward) {
            krok = Math.min(pocetKroku, krok + 1);
        } else {
            krok = Math.max(0, krok - 1);
        }

        ////////////////////////////////////////////////
        // zprava se zobrazi uzivateli po provedeni kazdeho kroku
        String zprava = "";
        // hodnota slouzi pro predani zvolene hodnoty do prislusneho pole
        String hodnota;
        ////////////////////////////////////////////////

        switch (krok - 1) {
            case -1:

                if (!forward) {
                    zprava = ("Jednou z variant ElGamalova kryptosystému je systém pro podepisování zpráv. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.");
                    btnBack.setDisabled(true);
                    labKrok.setVisible(false);
                    txtN.setValue("??");
                    txtB.setValue("??");
                    txtK.setValue("??");
                }
                break;
            case 0:
                btnBack.setDisabled(false);
                zprava = "Proto, aby mohl uživatel podepsat zprávu, potřebuje soukromý klíč z dvojice soukromý-veřejný klíč. K jejich vytvoření musí zvolit řád cyklické grupy, ve které bude podepisování probíhat, generátor a soukromý klíč ze zvolené grupy. Výpočet klíčů je stejný i pro šifrování ElGamalovým kryptosystémem.";
                labKrok.setVisible(true);
                txtN.setValue("257");
                txtB.setValue("31");
                txtK.setValue("16");
                if (!forward) {
                    labY.setText("??");
                }
                break;
            case 1:
                zprava = "Volba vhodných parametrů je velmi důležitá s odledem na bezpečnost systému. Řád grupy musí být velké prvočíslo, což zajistí velký okruh čísel pro volbu soukromého klíče. Generátor by měl být také prvočíslo, i když to není nutné. Klíč může být libovolný. Výpočtem se získá poslední parametr veřejného klíče.";
                labY.setText("64");

                if (!forward) {
                labPublicKey.setText("??");
                labPrivateKey.setText("??");
                }
                break;
            case 2:
                zprava = "Uživatel tedy zná všechny parametry klíče a může publikovat svůj veřejný klíč.";
                labPublicKey.setText("257, 31, 64");
                labPrivateKey.setText("16");

                if (!forward) {
                    imgCA.setVisible(false);
                    imgCert.setVisible(false);
                    imgSipKrDol.setVisible(false);
                    imgSipKrLv.setVisible(false);
                    imgSipKrPr.setVisible(false);
                }
                break;
            case 3:
                zprava = "Vzhledem k praktické bezpečnosti se klíče nedistribuují přímo, ale pomocí certifikátů vydaných skupinou certifikačních autorit pro konkrétní uživatele. Úkolem certifikátů je zabránit distribuci podvržených klíčů. Více v části \"Komunikace v asymetrické kryptografii\"";
                
                imgCA.setVisible(true);
                imgCert.setVisible(true);
                imgSipKrDol.setVisible(true);
                imgSipKrLv.setVisible(true);
                imgSipKrPr.setVisible(true);
                if (!forward) {

                }
                break;
            case 4:
                zprava = "Zprávy mohou mít libovoulnou délku a vzhledem k redukci přenášených dat je není třeba podepisovat celé. Podepisuje se pouze jejich tzv. jednosměrný otisk, hash. Existuje mnoho hashovacích funkcí, zde je uvedena Shamirova hashovací funkce, založená na problému diskrétního logaritmu. ";

                if (!forward) {
                    txtP1.setValue("??");
                    txtQ1.setValue("??");
                    labN1.setText("??");
                    labB1.setValue("??");
                    
                }
                break;
            case 5:
                zprava = "Pro výpočet hashe je potřeba mít cyklickou grupu jejíž řád je součinem dvou tajných prvočísel. Tato prvočísla není možné zpětně určit z řádu grupy kvůli problému faktorizace. Jako generátor pro výpočet hashe se vypočte nejmenší společný násobek tajných prvočísel zmenšených o jedna. ";
                txtP1.setValue("11");
                txtQ1.setValue("17");
                labN1.setText("187");
                labB1.setValue("80");
                

                if (!forward) {
                    txtM1.setValue("??");
                    labHash1.setText("??");
                }
                break;
            case 6:
                zprava = "Hash se vypočte jako zbytek po dělení řádem grupy čísla vzniklého umocněním generátoru na číselnou hodnotu zprávy. Hash se pro podepsání nemusí použít celý, stačí pouze jeho část." ;
                txtM1.setValue("19");
                labHash1.setText("147");

                if (!forward) {
                    txtKlic1.setValue("??");
                    txtM2.setValue("??");
                    txtHash1.setValue("??");
                    txtCislo1.setValue("??");
                }
                break;
            case 7:
                zprava = "Pro podepsání zprávy tedy uživatel potřebuje svůj soukromý klíč, zprávu, resp. její hash (stačí zvolená část) a náhodné číslo zvolené z cyklické grupy, ze které se generovala dvojice klíčů.";
                txtKlic1.setValue("257, 31, 64");
                txtKlic2.setValue("16");
                txtM2.setValue("19");
                txtHash1.setValue("14");
                txtCislo1.setValue("57");
                if (!forward) {
                    labR1.setText("??");
                    labS1.setText("??");
                    imgArrowBigRight1.setVisible(false);
                    labPrenos1.setVisible(false);
                    imgCert2.setVisible(false);
                }
                break;
            case 8:
                zprava = "Z hashe, soukromého klíče a zvoleného náhodného čísla se vypočte podpis, který má dvě části. Jednu zcela nezávislou na hodnotě hashe zprávy - závislou na náhodně zvoleném parametru, který je třeba bezpečně utajit a změnit pro každý vytvářený podpis. Druhou část podpisu hash přímo ovlivňuje.";
                labR1.setText("221");
                labS1.setText("3566");
                imgArrowBigRight1.setVisible(true);
                labPrenos1.setVisible(true);
                imgCert2.setVisible(true);
                if (!forward) {
                    txtPublicKey1.setValue("??");
                    txtMessage1.setValue("??");
                    txtR1.setValue("??");
                    txtS1.setValue("??");
                }
                break;
                case 9:
                zprava = "Příjemce podepsané zprávy obdrží zprávu, její podpis, v případě použití Shamirova Hashovacího algoritmu také hashovací klíč a certifikát uživatele. Ověří si pravost certifikátu podle veřejně známěho klíče certifikační autority a pokud je certifikát pravý, zkopíruje si z něho veřejný klíč uživatele.";
                txtPublicKey1.setValue("257, 31, 64");
                txtMessage1.setValue("19");
                txtR1.setValue("221");
                txtS1.setValue("3566");
                if (!forward) {
                    txtHash2.setValue("??");
                    labV1.setText("??");
                    labV2.setText("??");

                    btnFwd.setText("Další");

                    imgArrowBigRight1.setVisible(true);
                    labPrenos1.setVisible(true);
                    imgCert2.setVisible(true);

                }
                break;
                case 10:
                zprava = "Uživatel si z přijaté zprávy vypočte pomocí hashovacího klíče její hash a vypočte parametry V1 a V2. Pokud se jejich hodnota schoduje, podpis je přijat a zpráva je označena za autentickou.";
                txtHash2.setValue("14");
                labV1.setText("165");
                labV2.setText("165");

                btnFwd.setText("Konec");
                labResult1.setVisible(true);
                labResult1.setText("OK: Podpis je pravý" );

                imgArrowBigRight1.setVisible(false);
                labPrenos1.setVisible(false);
                imgCert2.setVisible(false);


                if (!forward) {


                }
                break;
            case 11:
                ClearFields();
                txtN.setDisabled(false);
                txtB.setDisabled(false);
                txtK.setDisabled(false);
                labResult1.setVisible(false);

                txtP1.setDisabled(false);
                txtQ1.setDisabled(false);
                txtM1.setDisabled(false);

                txtKlic1.setDisabled(false);
                txtKlic2.setDisabled(false);
                txtM2.setDisabled(false);
                txtHash1.setDisabled(false);
                txtCislo1.setDisabled(false);

                txtPublicKey1.setDisabled(false);
                txtMessage1.setDisabled(false);
                txtR1.setDisabled(false);
                txtS1.setDisabled(false);
                txtHash2.setDisabled(false);

                btnBack.setDisabled(true);
                btnFwd.setDisabled(true);
                //btnSkip.setDisabled(true);
                btnSkip.setText("Restart okna");
                btnRad1.setDisabled(false);
                button2.setDisabled(false);
                btnHash1.setDisabled(false);
                button1.setDisabled(false);
                btnOver1.setDisabled(false);

                labKrok.setVisible(false);
                labPopis.setVisible(true);
                zprava = ("Jednou z variant ElGamalova kryptosystému je systém pro podepisování zpráv. Tento průvodce by měl vysvětlit průběh a některé vlastnosti tohoto protokolu.");

                imgCA.setVisible(false);
                imgCert.setVisible(false);
                imgSipKrDol.setVisible(false);
                imgSipKrLv.setVisible(false);
                imgSipKrPr.setVisible(false);
                imgArrowBigRight1.setVisible(false);
                imgCert2.setVisible(false);
                labPrenos1.setVisible(false);

                break;

        }

        hiddenCislo.setValue(krok);
        labKrok.setText("Krok " + (krok - 1) + ":");
        labPopis.setText(zprava);
    }

    public String btnFwd_action() {
        PerformStep(true);
        return null;
    }

    public String button_action() {
         Integer n, b, k, Y;
       try
        {
            n = Integer.parseInt(txtN.getValue().toString());
            b = Integer.parseInt(txtB.getValue().toString());
            k = Integer.parseInt(txtK.getValue().toString());

            if (!PrimeGen.isPrime(n))
                throw new ExtraException("Číslo n není prvočíslo.");

            if(k<1 || k>n-2)
                throw new ExtraException("Číslo k musí být: 0 < k < n-1");

            // pocita Y = b^k mod n
            //Y =(int) (ExMath.myExp(b, k) % n);
            //Double bNaK = ExMath.myExp(b, k);
            Y = SuperModulo.Modulo(b, k, n);

            String PublicKey = n.toString() + ", " + b.toString() + ", " + Y.toString();

            labY.setText(Y.toString());
            labPublicKey.setText(PublicKey);
            labPrivateKey.setText(k.toString());

        }
        catch (ExtraException e)
        {
            JOptionPane.showMessageDialog(null, e.toString());
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybná vstupní data.");
        }
        return null;
    }

    public String btnRad_action() {
        // 1) nacte vstupni hodnoty
        Integer p, q, n, b, m, hash;
        try
        {
            p = Integer.parseInt(txtP1.getValue().toString());
            q = Integer.parseInt(txtQ1.getValue().toString());

            if (!PrimeGen.isPrime(p) || !PrimeGen.isPrime(q))
                throw new ExtraException("Zadaná čísla nejsou prvočísla");

            n = p*q;
            if (n>700){
                labN1.setText("OoR");
                b = 0;
            }
            else
                b = ExMath.LCM(p-1, q-1);
            //hash = b^x mod n; - pocita supermodulo
            //hash = ExMath.myExp(b, x) % n;


            labN1.setText(n.toString());
            labB1.setText(b.toString());

        }
        catch (ExtraException e)
        {
            JOptionPane.showMessageDialog(null, e.toString());
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybná vstupní data.");
        }
        return null;
    }

    public String btnHash_action() {
        Integer p, q, b, m, n1;
         int hash =0;
        try
        {
            p = Integer.parseInt(txtP1.getValue().toString());
            q = Integer.parseInt(txtQ1.getValue().toString());

            if (!PrimeGen.isPrime(p) || !PrimeGen.isPrime(q))
                throw new ExtraException("Zadaná čísla nejsou prvočísla");
            n1 = Integer.parseInt(labN1.getValue().toString());
            b = ExMath.LCM(p-1, q-1);

            m = Integer.parseInt(txtM1.getValue().toString());
            //hash = ExMath.myExp(b, m) % n1;
            if (m > 800){
                labHash1.setText("OoR");
            }
            else 
            hash = SuperModulo.Modulo(b, m, n1);

        }
         catch (ExtraException e)
        {
            JOptionPane.showMessageDialog(null, e.toString());
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybná vstupní data.");
        }

        labHash1.setText(hash);
        return null;
    }

    private int[] CheckPublicKey(String klic)
    {
        // kontrola klice
        String cislo = "";
        int iCount = 0;
        int[] arr = new int[3];

        for (int i=0; i<klic.length(); i++)
        {
            char c = klic.charAt(i);

            if (c<'0' || c>'9') {
               if (cislo.length()>0)
                arr[iCount++] = Integer.parseInt(cislo) ;
               cislo = "";
            }
            else
            {
                cislo+=c;
                if ( i==klic.length()-1)
                {
                     if (cislo.length()>0)
                    arr[iCount++] = Integer.parseInt(cislo) ;
                }
            }
        }

        if (iCount!=3) return null;
        else return arr;
    }

    public String button1_action() {
        try
        {
                String msg = txtM2.getValue().toString();
                Integer SK = Integer.parseInt(txtKlic2.getValue().toString());
                Integer hash =  Integer.parseInt(txtHash1.getValue().toString());
                Integer x = Integer.parseInt(txtCislo1.getValue().toString());
                int[] arr = CheckPublicKey(txtKlic1.getValue().toString());

                //Integer R = ExMath.Exp(arr[1], x) % arr[0];
                Integer R = SuperModulo.Modulo(arr[1], x, arr[0]);
                Integer S = SK*R+(x*hash)%(arr[0]-1);


                        //((hash-SK*R)/x) % (arr[0]-1);


                labR1.setText(R);
                labS1.setText(S);

                txtMessage1.setValue(msg);
                txtR1.setValue(R.toString());
                txtS1.setValue(S.toString());
                btnOver1.setDisabled(false);
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybně zadané hodnoty.");
        }
        return null;
    }

    public String btnOver_action() {
        try
        {
            String PublicKey = txtPublicKey1.getValue().toString();
            String message = txtMessage1.getValue().toString();
            Integer R = Integer.parseInt(txtR1.getValue().toString());
            Integer S = Integer.parseInt(txtS1.getValue().toString());
            Integer hash = Integer.parseInt(txtHash2.getValue().toString());
            int[] arr = CheckPublicKey(PublicKey);

            //Integer V1 = (ExMath.Exp(arr[2],R)*ExMath.Exp(R, S))%arr[0];
            Integer V1 = ((SuperModulo.Modulo(arr[2], R, arr[0]))*SuperModulo.Modulo(R, hash, arr[0]))%arr[0];
            labV1.setText(V1);
            //Integer V2 = ExMath.Exp(arr[1], hash)%arr[0];
            Integer V2 = SuperModulo.Modulo(arr[1], S, arr[0]);
            labV2.setText(V2);

            labResult1.setVisible(true);

            if (V1.toString().equals(V2.toString())){
                labResult1.setText("OK: Podpis je pravý");}
            else
                labResult1.setText("KO: Podpis není pravý");
        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybně zadané hodnoty.");
        }
        return null;
    }

    public String btnVyh_action() {
        try
        {
        String odp = txtOdp1.getValue().toString();
        if (odp.equals("A")||odp.equals("a"))
            labO3.setText("OK");
        else
            labO3.setText("KO");

        odp = txtOdp2.getValue().toString();
        if (odp.equals("B")||odp.equals("b"))
            labO2.setText("OK");
        else
            labO2.setText("KO");

        odp = txtOdp3.getValue().toString();
        if (odp.equals("28"))
            labO1.setText("OK");
        else
            labO1.setText("KO");

        odp = txtOdp4.getValue().toString();
        if (odp.equals("4"))
            labO4.setText("OK");
        else
            labO4.setText("KO");

        int pom = Integer.parseInt(txtOdp5.getValue().toString());
        pom = SuperModulo.Modulo(15, pom, 15);
        if (pom==4)
            labO5.setText("OK");
        else
            labO5.setText("KO");

        odp = txtOdp6.getValue().toString();
        if (odp.equals("12, 2112"))
            labO6.setText("OK");
        else
            labO6.setText("KO");

        odp = txtOdp7.getValue().toString();
        if (odp.equals("ne")||odp.equals("NE")||odp.equals("Ne"))
            labO7.setText("OK");
        else
            labO7.setText("KO");


        }
        catch (Exception e)
        {
            JOptionPane.showMessageDialog(null, "Chybná vstupní data, DL.");
        }
        return null;
    }

    public String btnVysl_action() {
        txtOdp1.setValue("A");
        txtOdp2.setValue("B");
        txtOdp3.setValue("28");
        txtOdp4.setValue("4");
        txtOdp5.setValue("3+k.14");
        txtOdp6.setValue("12, 2112");
        txtOdp7.setValue("c");
        return null;
    }

    public String hyperlink1_action() {
        // TODO: Process the action. Return value is a navigation
        // case name where null will return to the same page.
        return null;
    }
    
}

