/**
* Copyright (c) 2014 Matthias Jaenicke <matthias.jaenicke@student.kit.edu>,
* Matthias Plappert <undkc@student.kit.edu>,
* Julien Duman <uncyc@student.kit.edu>,
* Christian Dreher <uaeef@student.kit.edu>,
* Wasilij Beskorovajnov <uajkm@student.kit.edu> and
* Aydin Tekin <aydin.tekin@student.kit.edu>
*
* Released under the MIT license (refer to LICENSE.md)
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package edu.kit.iks.Cryptographics.DiffieHellman.Demonstration;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JLabel;
import org.xnap.commons.i18n.I18n;
import edu.kit.iks.CryptographicsLib.Configuration;
import edu.kit.iks.CryptographicsLib.VisualizationView;
public class DHDemoView extends VisualizationView {
/**
* Localization instance
*/
private static I18n i18n = Configuration.getInstance().getI18n(DHDemoView.class);
private String explanation1 = i18n.tr("Now to our Diffie-Hellman Key-Exchange Analogy. Here " +
"is how the protocol in principle works. " +
"Alice chooses a public color and sends it to Bob. " +
"As Eve listens to the channel she gets a copy.");
private String explanation2 = i18n.tr("Next, Alice chooses a private color, that she keeps " +
"for herself, she does not send it. Then she mixes her private color with " +
"the previously sent public color and sends the mixture to Bob. " +
"Note that because we use the mixing of colors as a one-way function, " +
"Eve cannot compute which private color Alice used to get the mixture. " +
"Keep this in mind, as this is critical to understand why this " +
"protocol works. " +
"As previously Bob and Eve have the sent color, that means the mixture of Alice.");
private String explanation3 = i18n.tr("Now Bob does the exact same thing like Alice did " +
"in the previous step. " +
"He chooses a private color. Mixes it with the public color, " +
"and sends the mixture to Alice. Eve gets a copy, but can't compute " +
"the private color of Bob, because of the one-way function property");
private String explanation4 = i18n.tr("Here we will " +
"produce the secret that Alice and Bob know, but Eve doesn't. " +
"Alice will mix her private color to the mixture of Bob " +
"and Bob will mix his private color to the mixture of Alice. " +
"The trick lies in the combination of the private Colors, that " +
"are kept private, through the use of the one-way function and " +
"that it doesn't matter in which order we mix the colors. So " +
"mixing first the public color with Alices private color and then Bobs private color " +
"yields the same color as mixing first the public color with Bobs private color " +
"and then Alices private color.");
private JLabel aliceExplain;
private JButton skip;
private ColorChannel cc;
private ColorMix cm;
private ActionListener remember;
private String help = i18n.tr("No help");
private Navigation n;
private static final long serialVersionUID = 87178534093974249L;
public DHDemoView() {
super();
GridBagConstraints gbc = new GridBagConstraints();
GridBagLayout layout = new GridBagLayout();
this.setLayout(layout);
gbc.weightx = 0.1;
gbc.weighty = 0.0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
n = new Navigation(i18n.tr("Back to Introduction"), i18n.tr("Skip the Demonstration"));
this.add(n, gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.gridwidth = 1;
//
skip = new JButton(i18n.tr("Skip Introduction"));
//
// gbc.gridx = 2;
// gbc.gridy = 0;
// gbc.weightx = 0.1;
// gbc.weighty = 0.1;
// this.add(skip, gbc);
gbc.gridx = 2;
gbc.gridy = 3;
gbc.weightx = 0.1;
gbc.weighty = 0.1;
layout.setConstraints(this.getNextButton(), gbc);
gbc.gridx = 0;
gbc.gridy = 3;
layout.setConstraints(this.getBackButton(), gbc);
this.aliceExplain = new JLabel();
this.aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation1 + "</div></html>");
gbc.weightx = 0.1;
gbc.weighty = 0.1;
gbc.gridx = 1;
gbc.gridy = 3;
this.add(aliceExplain, gbc);
this.cc = new ColorChannel(new Dimension(700, 200), 50);
gbc.weightx = 0.25;
gbc.weighty = 0.25;
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
this.add(this.cc, gbc);
this.cc.choosePublicColor(Color.BLUE);
this.cm = new ColorMix(50, new Dimension(200, 50));
gbc.weightx = 0.1;
gbc.weighty = 0.1;
gbc.gridx = 0;
gbc.gridy = 2;
// gbc.fill = GridBagConstraints.NONE;
this.add(this.cm, gbc);
this.cc.loadView();
this.cc.setRepeat(false);
this.cc.setKeepColor(true);
//TODO remove validate()?
gbc.weightx = 0.1;
gbc.weighty = 0.1;
gbc.gridx = 2;
gbc.gridy = 1;
gbc.insets = new Insets(100, 0, 0, 0);
this.add(new LabelExplanation(), gbc);
this.revalidate();
}
public ColorChannel getColorChannel() {
return this.cc;
}
public void startDemo() {
this.cc.sendPublicColor(new NextStepCallback() {
@Override
public void callback() {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
getNextButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
secondStep();
}
});
}
});
}
private void secondStep() {
aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation2 + "</div></html>");
cc.chooseAlicePrivateColor(Color.GREEN);
cc.mixAlicePrivatePublic();
cm.setEllipColor(0, cc.getPublicColor());
cm.setEllipColor(1, cc.getAlicePrivateColor());
cm.mixColors(true, false, new NextStepCallback() {
@Override
public void callback() {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
getNextButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
thirdStep();
}
});
}
});
}
private void thirdStep() {
aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation2 + "</div></html>");
cc.sendAliceMixedColorToBob(new NextStepCallback() {
@Override
public void callback() {
getNextButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
fourthStep();
}
});
}
});
}
private void fourthStep() {
aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation3 + "</div></html>");
cc.chooseBobPrivateColor(Color.RED);
cm.setEllipColor(1, cc.getBobPrivateColor());
cm.mixColors(true, false, new NextStepCallback() {
@Override
public void callback() {
getNextButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
fifthStep();
}
});
}
});
}
private void fifthStep() {
aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation3 + "</div></html>");
cc.setColorNextToSend(cm.getMixedColor());
cc.sendBobMixedColorToAlice(new NextStepCallback() {
@Override
public void callback() {
getNextButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
for(ActionListener al : getNextButton().getActionListeners()) {
getNextButton().removeActionListener(al);
}
sixthStep();
}
});
}
});
}
private void sixthStep() {
aliceExplain.setText("<html><div style=\"width:650px; height:150px\">" + explanation4 + "</div></html>");
getNextButton().addActionListener(remember);
cc.mixAliceFinalSecret(new NextStepCallback() {
@Override
public void callback() {
cc.mixBobFinalSecret(null);
}
});
}
public void setRemember(ActionListener remember) {
this.remember = remember;
}
public String getHelp() {
return help ;
}
public JButton getSkip() {
return skip;
}
public void stopTimers() {
if(cm != null) {
cm.stopTimer();
}
if(cc != null) {
cc.stopTimer();
}
}
public JButton getSkipButton() {
return n.getForward();
}
public JButton getReturnButton() {
return n.getBack();
}
}