/**
 * Copyright (c) 1996-2003 Borland Software Corporation.  All Rights Reserved.
 * ......
 */
//------------------------------------------------------------------------------
// Copyright (c) 1996-2003 Borland Software Corporation.  All Rights Reserved.
//------------------------------------------------------------------------------

// package com.borland.samples.welcome;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.math.*;
import ua.kiev.author.cryptolib.*;


public class WelcomeFrame extends JFrame {
  JPanel contentPane;
  JMenuBar jMenuBar1 = new JMenuBar();
  JMenu jMenuFile = new JMenu();
  JMenuItem jMenuFileExit = new JMenuItem();
  JMenu jMenuHelp = new JMenu();
  JMenuItem jMenuHelpAbout = new JMenuItem();
  JButton jButton1 = new JButton();
  TextArea txt = new TextArea();

  /**
   * Construct the frame
   */
  public WelcomeFrame() {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try {
      jbInit();
    }
    catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * Component initialization
   *
   * @throws Exception exception
   */
  private void jbInit() throws Exception {
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(null);
    this.setTitle("Welcome to JBuilder");
    this.setContentPane(contentPane);
    this.setJMenuBar(jMenuBar1);
    this.setResizable(true);
    this.setSize(new Dimension(450, 421));
    jMenuFile.setText("File");
    jMenuFileExit.setText("Exit");
    jMenuFileExit.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jMenuFileExit_actionPerformed(e);
      }
    });
    jButton1.setBounds(new Rectangle(17, 17, 411, 27));
    jButton1.setText("jButton1");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
    txt.setBounds(new Rectangle(19, 68, 409, 299));
    jMenuFile.add(jMenuFileExit);
    jMenuHelp.setText("Help");
    jMenuHelpAbout.setText("About");
    jMenuHelpAbout.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jMenuHelpAbout_actionPerformed(e);
      }
    });
    jMenuHelp.add(jMenuHelpAbout);
    jMenuBar1.add(jMenuFile);
    jMenuBar1.add(jMenuHelp);
    contentPane.add(txt, null);
    contentPane.add(jButton1, null);
  }

  /**
   * Overridden so we can exit when window is closed
   *
   * @param e WindowEvent
   */
  protected void processWindowEvent(WindowEvent e) {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING) {
      System.exit(0);
    }
  }

  /**
   * File | Exit action performed
   *
   * @param e ActionEvent
   */
  public void jMenuFileExit_actionPerformed(ActionEvent e) {
    System.exit(0);
  }

  /**
   * Help | About action performed
   *
   * @param e ActionEvent
   */
  public void jMenuHelpAbout_actionPerformed(ActionEvent e) {
  }

  /**
   * Convert byte array to Hex-String LSB-first
   *
   * @param a byte[]
   * @return String
   */

  public String BsToHex(byte[] a) {
    String HexTab = "0123456789ABCDEF";
    String res = "";
    for (int i=0; i<=a.length*2-1; i++) {
      res += HexTab.charAt((a[i/2] >>> (i%2^1)*4) & 0x0f);
    };
    return res;
  }

  /**
   * Convert byte array to Hex-String MSB-first
   *
   * @param a byte[]
   * @return String
   */

  public String BsToHexMsb(byte[] a) {
    String HexTab = "0123456789ABCDEF";
    String res = "";
    for (int i = a.length*2-1; i>=0; i--) {
      res += HexTab.charAt((a[i/2] >>> (i%2)*4) & 0x0f);
    };
    return res;
  }


  void jButton1_actionPerformed(ActionEvent e) {
    Prng4145A  Rng;
    Ecc4145    Ecc;
    EcPoint    P,Q;
    BigInteger d;
    byte[]     SkPoint;
    byte[]     sign;
    byte[]     hash;
    byte[]     buffer;
    byte[]     mac;
    boolean    ok;

// ================== RNG

    // initialize RNG (Test example 1)
    txt.append("== rng ==\n");
    Rng = new Prng4145A(Prng4145A.getVector("7BA480436DF5012759DC1E98BACF32E698C63071021DEE47A48CDBBA2FF963559778B3122A6F8C56F0E14B0EA9C435DD5687697FE5D1249B32C843B0FE1A0DAC"),
                        Prng4145A.getVector("1BED2034A44D897E2C20BD0DF55B942A29C07BA142EDCFBE332356DAB900A744"),
                        Prng4145A.getVector("D0D40D37C95C9438"),
                        Prng4145A.getVector("0000000000123879"));

    // output 20 random bytes
    buffer = new byte[20];
    Rng.nextBytes(buffer);
    txt.append("rng(LSB)= "+BsToHex(buffer) +"\n");
    txt.append("rng(MSB)= "+BsToHexMsb(buffer) +"\n");

// ================== DSTU 4145

    // create Ecc with Rng
    txt.append("== base point ==\n");
    Ecc = new Ecc4145(Rng);

    // set field and curve
    Ecc.SetBaseField(163,7,6,3);
    Ecc.SetCurve(1, Ecc.getElement("5FF6108462A2DC8210AB403925E638A19C1455D21"),
                   new BigInteger("400000000000000000002BEC12BE2262D39BCF14D",16));

    // set D
    Rng.Reinit(Prng4145A.getVector("D0D40D37C95C9438"), new byte[]{1,2,3,4,5,6,7,8});

    // generate Base point
    P = Ecc.GenerateBasePoint();
    txt.append("Px= "+Ecc.toString(P.x) +"\n");
    txt.append("Py= "+Ecc.toString(P.y) +"\n");

    // set Base point
    Ecc.SetBasePoint(P);

    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    // generate private and public key
    d = Ecc.GeneratePrivateKey();
    Q = Ecc.CalcPublicKey(d);
    txt.append("Qx= "+Ecc.toString(Q.x) +"\n");
    txt.append("Qy= "+Ecc.toString(Q.y) +"\n");

    // shrink point
    txt.append("== shrink point ==\n");
    txt.append("Sk= "+Ecc.toString(Ecc.ShrinkPoint(Q)) +"\n");
    SkPoint = Ecc.toByteArray(Ecc.ShrinkPoint(Q));

    // expand point
    Q = Ecc.ExpandPoint(Ecc.fromByteArrayEl(SkPoint));
    txt.append("Qx= "+Ecc.toString(Q.x) +"\n");
    txt.append("Qy= "+Ecc.toString(Q.y) +"\n");

    // expand point (alternative)
    Q = Ecc.ExpandPoint(Ecc.getElement("434A634A6E0F9F636C035F21BF429C2A8A5798664"));
    txt.append("Qx= "+Ecc.toString(Q.x) +"\n");
    txt.append("Qy= "+Ecc.toString(Q.y) +"\n");

    // sign 191
    txt.append("== sign ==\n");
    Ecc.SetBaseField(191,9,0,0);
    Ecc.SetCurve(1, Ecc.getElement("7BC86E2102902EC4D5890E8B6B4981FF27E0482750FEFC03"),
                   new BigInteger("40000000000000000000000069A779CAC1DABC6788F7474F",16));
    P = new EcPoint("43BF0476DE642DDF9056B2DA34E1D1BEB53FFE2215E7AB9",
                    "46CC71EF75595F681BC91A758D8A9D24428B37D6FF6E251F");
    Ecc.SetBasePoint(P);

    d = new BigInteger("3A774C3EF9D011A7853F403CED3CF724727C40312A969E0D",16);
    hash = Prng4145A.getVector("23423402938402938023984203948847356384758437651D2362342342342342");
    Rng.Reinit(Prng4145A.getVector("D0D40D37C95C9438"), new byte[]{7,0,0,0,0,0,0,0});
    //!!!!!!!!!!!
    sign = Ecc.Sign(d,hash);
    txt.append("sign= "+BsToHexMsb(sign) +"\n");

    hash = Prng4145A.getVector("23423402938402938023984203948847356384758437651D23623423423423420");
    Rng.Reinit(Prng4145A.getVector("D0D40D37C95C9438"), new byte[]{7,0,0,0,0,0,0,0});

    // check 191
    Q = new EcPoint("673E73758C0EA7B489309AFAD1344C7BF7AF07ED07C8A59F",
                    "0C3562C97A49670695F6FFDBF8C18F4F5D1DEA3BFA3C0B39");
    ok = Ecc.Check(Q,hash,sign);
    if (ok) txt.append("check= TRUE\n");
      else txt.append("sign= FALSE\n");

// ================== GOST 34.311

    Gost34311  HS;

    txt.append("== hash ==\n");
    HS = new Gost34311(Gost34311.getVector("CC82B866E73E2A9049A57F5301D4FB1DE2FBC3905E896A34D81D2F7501A7BC463B5920B6C76C4FEEF294830A1DA1D87593557F071C813B26AEF0D86DC249BAE4"),null);
    buffer = new byte[] {
      0x53,0x75,0x70,0x70,0x6F,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x6F,0x72,0x69,0x67,
      0x69,0x6E,0x61,0x6C,0x20,0x6D,0x65,0x73,0x73,0x61,0x67,0x65,0x20,0x68,0x61,0x73,
      0x20,0x6C,0x65,0x6E,0x67,0x74,0x68,0x20,0x3D,0x20,0x35,0x30,0x20,0x62,0x79,0x74,
      0x65,0x73};
    HS.Hash(buffer,50);
    hash = HS.HashEnd();
    txt.append("hash= "+BsToHexMsb(hash) +"\n");

    HS = new Gost34311(Gost34311.getVector("7BA480436DF5012759DC1E98BACF32E698C63071021DEE47A48CDBBA2FF963559778B3122A6F8C56F0E14B0EA9C435DD5687697FE5D1249B32C843B0FE1A0DAC"),
                       Gost34311.getVector("0000000000000000000000000000000000000000000000000000000000000000"));
    buffer = new byte[] {(byte)0xB0,(byte)0xE6,(byte)0xF5,0x00,(byte)0xE7,0x12,0x68};
    HS.Hash(buffer,7);
    hash = HS.HashEnd();
    txt.append("hash= "+BsToHexMsb(hash) +"\n");


// ================== GOST 28147

    Gost28147  MG;

    // set SBox and Key
    txt.append("== gost ==\n");
    MG = new Gost28147();
    MG.SetSBox(Gost28147.getVector("CC82B866E73E2A9049A57F5301D4FB1DE2FBC3905E896A34D81D2F7501A7BC463B5920B6C76C4FEEF294830A1DA1D87593557F071C813B26AEF0D86DC249BAE4"));
    MG.SetKey(Gost28147.getVector("144773730C0C61651F01686D4F0020204C50656C04156761061D616E1D277369"));

    //Encrypt/Decrypt ECB (method 1)
    buffer = new byte[] {0x53,0x75,0x70,0x70,0x6F,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x6F,0x72,0x69,0x67};
    MG.M1Enc(buffer,16);
    txt.append("E1= "+BsToHex(buffer) +"\n");
    MG.M1Dec(buffer,16);
    txt.append("D1= "+BsToHex(buffer) +"\n");

    //Encrypt/Decrypt ECB (method 2)
    buffer = new byte[] {0x53,0x75,0x70,0x70,0x6F,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x6F,0x72};
    MG.SetSync(Gost28147.getVector("0807060504030201"));
    MG.M2Enc(buffer,14);
    txt.append("E2= "+BsToHex(buffer) +"\n");
    MG.SetSync(new byte[]{1,2,3,4,5,6,7,8});
    MG.M2Dec(buffer,14);
    txt.append("D2= "+BsToHex(buffer) +"\n");

    //Encrypt/Decrypt ECB (method 3)
    buffer = new byte[] {0x53,0x75,0x70,0x70,0x6F,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x6F,0x72};
    MG.SetSync(Gost28147.getVector("0807060504030201"));
    MG.M3Enc(buffer,14);
    txt.append("E3= "+BsToHex(buffer) +"\n");
    MG.SetSync(Gost28147.getVector("0807060504030201"));
    MG.M3Dec(buffer,14);
    txt.append("D3= "+BsToHex(buffer) +"\n");

    //MAC (method 4)
    buffer = new byte[] {0x53,0x75,0x70,0x70,0x6F,0x73,0x65,0x20,0x74,0x68,0x65,0x20,0x6F,0x72};
    MG.ClearSync();
    MG.MAC(buffer,14);
    mac = new byte[4];
    MG.GetMAC4(mac);
    txt.append("MAC(32 bit)= "+BsToHex(mac) +"\n");

    MG.ClearSync();
    MG.MAC(buffer,14);
    mac = new byte[8];
    MG.GetMAC8(mac);
    txt.append("MAC(64 bit)= "+BsToHex(mac) +"\n");

  }


}
