• No results found

A Lab System for Secret Sharing

N/A
N/A
Protected

Academic year: 2021

Share "A Lab System for Secret Sharing"

Copied!
73
0
0

Loading.... (view fulltext now)

Full text

(1)

A Lab System for Secret Sharing

Final Thesis

performed in Information Theory by

Fredrik Olsson

Reg nr: LiTH-ISY-EX-ET-0252-2004 3rd June 2004

(2)
(3)

A Lab System for Secret Sharing

Final Thesis

performed in Information Theory, Dept. of Electrical Engineering

at Link¨opings universitet by Fredrik Olsson

Reg nr: LiTH-ISY-EX-ET-0252-2004

Supervisor: Magnus ¨Oberg Examiner: Viiveke F˚ak Link¨oping, 3rd June 2004

(4)
(5)

Avdelning, Institution Division, Department Datum Date Spr˚ak Language 2Svenska/Swedish 2Engelska/English 2 Rapporttyp Report category 2Licentiatavhandling 2Examensarbete 2C-uppsats 2D-uppsats 2 ¨ Ovrig rapport 2

URL f¨or elektronisk version

ISBN

ISRN

Serietitel och serienummer

Title of series, numbering

ISSN Titel Title F¨orfattare Author Sammanfattning Abstract Nyckelord Keywords

Finnegan Lab System is a graphical computer program for learning how secret sharing works. With its focus on the algorithms and the data streams, the user does not have to consider machine-specific low-level details. It is highly modularised and is not restricted to secret sharing, but can easily be extended with new functions, such as building blocks for Feistel networks or signal processing.

This thesis describes what secret sharing is, the development of a new lab system designed for secret sharing and how it can be used.

Information Theory,

Dept. of Electrical Engineering SE-581 83 Link¨oping, Sweden

3rd June 2004

LITH-ISY-EX-ET-0252-2004 —

http://www.ep.liu.se/exjobb/isy/2004/252/

A Lab System for Secret Sharing

Utveckling av laborationssystem f¨or secret sharing

Fredrik Olsson × ×

Cryptography, Graph-Based Application Framework, Java, Key Man-agement, Secret Sharing.

(6)
(7)

Abstract

Finnegan Lab System is a graphical computer program for learning how secret sharing works. With its focus on the algorithms and the data streams, the user does not have to consider machine-specific low-level details. It is highly modularised and is not restricted to secret sharing, but can easily be extended with new functions, such as building blocks for Feistel networks or signal processing.

This thesis describes what secret sharing is, the development of a new lab system designed for secret sharing and how it can be used.

Keywords: Cryptography, Graph-Based Application Framework, Java, Key Management, Secret Sharing.

(8)
(9)

Contents

Abstract vii

1 Preface 1

2 Requirements of the Lab System 3

3 Theory 7

3.1 Introduction . . . 7

3.2 Primary Secret Sharing . . . 8

3.2.1 Simple Shared Control Schemes . . . 8

3.2.2 Threshold Schemes . . . 9

3.3 Extended Secret Sharing . . . 10

4 Finnegan Lab System 11 4.1 Overview . . . 11 4.2 User’s Guide . . . 12 4.3 Developer’s Guide . . . 12 4.4 Teacher’s Guide . . . 16 5 Conclusions 17 A Source Code 19 A.1 Finnegan.java . . . 19 A.2 plugin/Module.java . . . 34 A.3 plugin/Congruence.java . . . 36 A.4 plugin/FlipSign.java . . . 37 A.5 plugin/Int2Text.java . . . 38 A.6 plugin/Interpolate.java . . . 40 A.7 plugin/ModifyX.java . . . 42 A.8 plugin/ModifyY.java . . . 43 A.9 plugin/Plus.java . . . 45 A.10 plugin/Polynomial.java . . . 46 ix

(10)

A.11 plugin/RandomPrime.java . . . 47 A.12 plugin/ReadFile.java . . . 49 A.13 plugin/SetXY.java . . . 51 A.14 plugin/Stdout.java . . . 53 A.15 plugin/Swap.java . . . 54 A.16 plugin/Text2Int.java . . . 55 A.17 plugin/WriteFile.java . . . 57 A.18 plugin/Xor.java . . . 59 Bibliography 61 x

(11)

Chapter 1

Preface

Although a well-known term within the cryptographic community, secret sharing might be a bit misleading for an outsider. It does not mean two or more people sharing one secret.1 It means two or more people are having shares of the secret. One secret is split into n different shares. Only when merging at least k, 0 < k ≤ n, number of shares the initial secret can be reconstructed. Ideally, it should be impossible to gain any information about the secret with less than n shares.

In their work Practical Cryptography [6], Ferguson and Schneier mention that the value of secret sharing techniques in reality is very limited. The arguments are that it is complex to operate, and that most companies do not have a group of responsible people who distrust each other. However, there is another side of it too. As pointed out in [1], the main purpose of dual combination locks on bank vaults is not to prevent the employers from taking cash, but to stop their families from being taken hostage. The employer’s inability to open the lock on her own removes the inducement for criminals to force her. Secret sharing schemes can be used in equivalent situations, or perhaps to safely increase data availability, just to name two examples. Secret sharing is not only an interesting information-theoretical concept, but it also has several practical applications.

The Department of Electrical Engineering and its Division of Informa-tion Theory at Link¨opings universitet, Sweden, gives a course in cryptology for undergraduate students. There has been a wish from the former to in-corporate secret sharing into the practical part of the course. The practical part consists of a few computer-aided exercises, labs. For this purpose, a lab system was needed.

1This is usually referred to as a shared secret.

(12)

2 Preface

This thesis describes what secret sharing is, the development of a lab system designed for secret sharing and how it can be used. Chapter two is a loose specification of this lab system. Chapter three will introduce the reader to the theory behind secret sharing, and is in essence a compilation of prior research in the field. We return to the lab system in chapter four, and end with a closing discussion on the results in chapter five.

(13)

Chapter 2

Requirements of the Lab

System

While there are several existing software packages available (such as Nightin-gale from RSA Security and a cryptographic file system called TCFS from Universit`a di Salerno, Italy) that utilise secret sharing techniques, none of them are suitable for educational purpose. They aim at hiding the algorith-mic details from the user. This is of course the ideal approach for standard end-user applications. Educational software, on the other hand, need to fo-cus on the details and not the result. This is exactly why calculators are not used when pupils in their first school years are learning to add, subtract, divide and multiply. This is also why a customised lab system is needed. It should have the following properties:

• Intuitive, low learning curve. Why? Because the challenge should not be to learn how to use the software.

• Not require prior knowledge in computer programming languages. • Neither too low nor to high level of details. An able student should

finish a “meaningful” task after more than one hour of work but in less than two hours.

After some discussions, the idea of a graphical user interface came up, where the student can connect algebraic objects like nodes are connected by edges in a directed acyclic graph. This adds two more requirements to the list:

• Graphical. • “Graph-based.”

(14)

4 Requirements of the Lab System

Figure 2.1: A sketch of the user interface. In this example, X, Y and Z are xored. The result is written to a file.

Obviously, the lab system must not crash in the middle of a delicate operation, losing all the student’s work. Thus, it must also be:

• Reliable and stable.

Learning from the history, it might be a good idea to make the lab system flexible enough to avoid a future situation where the complete lab system needs to be rewritten, either because the hardware has changed or because the lab itself has. The final requirements are:

• Platform independent. • Adaptable and extensible.

All in all, this adds up to the following goal: User-friendly software for building and testing algorithms for secret sharing in a graphical and interac-tive manner. The user should be able to draw the scheme on the computer screen, test it, and get immediate feedback. For example, to join shares ac-cording to the secret splitting scheme, and send the output to a file, the user would draw something similar to figure 2.1 on the screen.

Similar lab systems, like Stream Cipher Companion, are too limited to be used for this purpose and would require large parts to be rewritten. Devising something new from the start seems like the best option. There are also several existing frameworks or components for interactive graph editing, like

(15)

5 User Logical Representation Interpretation Visual Representation Modules File I/O

Figure 2.2: Components of the lab system.

GEF or JHotDraw, which could be used as a foundation. However, most of them are still under development, are not portable, are not stable enough, lack important features, or are just too large and complex. Instead of adapt-ing one of these frameworks, which might very likely be too time consumadapt-ing, it is probably better to write a small customised graphical interface from start. The following things need to be developed and assembled for the new lab system:

• Graphical interface for creating, moving and removing modules, i.e. operators and operands (represented as boxes on the screen). Arrows can be drawn to connect the boxes.

• Something “behind the scene” that keeps track on the semantic mean-ing of the visual view.

• Graph evaluation and feedback. • Dynamic module loader.

• Useful modules; integers, polynomials, addition, multiplication, inter-polation.

Applying a component centred view, this list is summarised in figure 2.2. So this is the foundation for the lab system, but obviously it is not enough for performing secret sharing. As plug-in modules provide the real functionality, we need some of those. But what operations and operands are necessary to provide fundamental secret sharing? What modules have to be implemented? To answer that, we first need to know what secret sharing really is.

(16)
(17)

Chapter 3

Theory

Siffrornas nyckel ¨ar rent av l¨ojligt enkel. Vilken som helst med litet — hm — f¨orl˚at — skarpsinne kan l¨osa g˚atan, och nu skall jag bevisa, att en stor och v¨arldsomfattande hemlighet d¨oljes under siffrornas godtyckliga lek. Se hit, b¨asta farbror!

— Otto Witt, Hur m˚anen er¨ovrades (1915)

3.1

Introduction

According to Times Magazine [4], there were three ignition devices control-ling the nuclear weapons in the former Soviet Union. The president had one of these devices, the defence minister had one, and the defence ministry one. To launch a missile, at least two of these had to be activated.

In Sergio Leone’s film Il buono, il brutto, il cattivo from 1966, a treasure is buried in a cemetery. One of the characters knows the name of the cemetery, and the other knows the name of the grave. Without trusting each other, they have to cooperate in order to find the treasure.

This is secret sharing.

The idea of secret sharing is to divide a secret (e.g. a cryptographic key) into pieces that are distributed amongst the users. Only specific subsets of users can then compute the secret by pooling their shares. This means that secret sharing can be used to distribute keys in a way that maintains a certain access control structure. It can also be used to send a key to a single party where the only means of communication are several separate insecure one-way (i.e. the Diffie-Hellman key agreement protocol [5] can not be used) communication channels. For instance, imagine a spy who wants to send information to her employer. She has five couriers, and assuming that

(18)

8 Theory

at most two of them will get caught, she can successfully use secret sharing with a threshold scheme.

In this thesis, the following notation is being used:

M The secret message.

n Total number of (different) shares.

k Minimum number of shares required to compute M , where k≤ n. A scheme for secret sharing is said to be perfect if absolutely no informa-tion about the contents of M can be retrieved without access to k shares, not even from an exhaustive search of the key space. For this to be true, each share has to be at least as long as M . A scheme where they are equally long is called ideal. Formal definitions of these terms can be found in [14].

In [8], the authors divide secret sharing schemes into three classes — sim-ple shared control schemes, threshold schemes, and generalised or extended secret sharing. The first one is a subclass of the second, and both the first and the second are subclasses of the third. Each one of these three classes will now be discussed. This is followed by a brief section about schemes with extended capabilities.

3.2

Primary Secret Sharing

3.2.1

Simple Shared Control Schemes

This is also known as secret splitting. A trusted party generates a set of large random numbers; {r1, . . . , rn−1}. These numbers are distributed, using a trusted communication medium, to all the participants but one. The re-maining participant receives rn ≡ M −Pni=1−1ri (mod t), where t is larger than any possible message. Now, since M Pni=1ri (mod t), M can only be computed if everyone get together and pool their shares. With less than n shares, no information about the contents of M can be retrieved. Thus, the scheme is perfect (assuming the random numbers really are random, and not predictable). Notice that the scheme is useless for backup purposes. M can never be restored if one of the shares is lost or destroyed. As a consequence, a single shareholder can prevent the recreation of M either by refusing to give out anything, or anonymously by inserting a false share. Secret split-ting relies on availability and integrity of the shares, and the scheme is very vulnerable to denial-of-service attacks.

Still, this scheme has many uses, especially in its most simple form where n = 2. It could be very useful, e.g. with sensitive data in a smartcard system.

(19)

3.2. Primary Secret Sharing 9

3.2.2

Threshold Schemes

A (k, n)-threshold scheme is a way for a trusted party to create n shares of M , in such a way that only k users are required to get together in order to compute M . Obviously, secret splitting is the special case where n = k. The first threshold schemes were devised independently by Blakley [3] and Shamir [12] in 1979. Many other schemes have been proposed since. For instance, Asmuth and Bloom made use of the Chinese remainder theorem in [2], as did Mignotte in [9]. Another interesting approach to the problem is the visual secret sharing scheme by Naor and Shamir, as described in [10].

Blakley’s approach was to let M define a point in k-dimensional space, while each share (or “shadow”, to use Blakley’s terminology) is the equation of a (k− 1)-dimensional hyperplane. The intersection of any k hyperplanes exactly determines the point. In its original form, this is not a perfect scheme since a person with a share of the secret knows that the secret is a point somewhere on the hyperplane. Nevertheless, according to [13], this scheme can be modified to achieve perfect security.

Shamir suggested a somewhat different approach that is based on poly-nomial interpolation in a finite field. To share M , generate a polypoly-nomial p(x)≡ axk+ bxk−1+ . . . + cx2+ dx + M (mod p), where p is a prime larger

than any of the coefficients. This number has to be public. The randomly chosen coefficients should be discarded once the generator polynomial is not needed anymore, and kept secret until then. Now, give out n pairs (x, p(x)), starting at x = 1 and increasing it for each share. Reconstructing M — i.e. computing p(0) — is simply a matter of solving a set of k linear equa-tions. The Lagrange interpolation polynomial can also be used to solve the equation, which is why this also is called the Lagrange interpolation scheme. This is a very efficient scheme. As pointed out in [8], it has several desirable properties. It is both perfect and ideal. It is possible to compute new shares without affecting the existing shares, and the security does not rely on any unproven assumptions. The scheme has to work in a finite field; Zp or Fqn. With Z — the ordinary set of integers — the scheme would not be perfect, since there has to be an inverse defined for each number. Rational or real numbers could be used instead, but that would also lead to some practical problems, especially related to performance, floating-point precision, and large numbers.

McEliece and Sarwate showed in [7] that Shamir’s scheme for secret shar-ing can be viewed as a special case of the error correctshar-ing Reed-Solomon codes. This is a useful discovery, because commercial hardware chips for Reed-Solomon encoding and decoding are common, fast and inexpensive. More importantly, it means that this scheme is less vulnerable to tampered

(20)

10 Theory

shares, and thus does not have the same problem with denial-of-service at-tacks as the previously described schemes. For a secret to be inaccessible, more thanb(n−k)/2c shares must be tampered with. Compared to the data availability provided by secret splitting, this is a significant improvement.

3.3

Extended Secret Sharing

Both the threshold schemes previously described can easily be extended to support any access control structure. Consider a military organisation where either one general, or two colonels, or one colonel and two majors, or four majors are required to authorise activation of the Doomsday Device. This is easily implemented with Shamir’s scheme. Let the general have the complete M and the colonels two shares each. Each major should then only have one share.

A second example: No less than four people have to get together in order for an electronic transaction to be signed. The catch is that there has to be two from each department, where each department has its own internal hierarchy. This can be solved by combining a scheme for secret splitting and for secret sharing with a threshold.

There are several — more advanced — extensions of the idea of se-cret sharing; schemes coping with cheaters, sese-cret sharing without a trusted dealer, secret sharing with voting, and several other extensions of the basic schemes. Schneier gives a brief overview of this along with relevant literature references in [11].

(21)

Chapter 4

Finnegan Lab System

Cainfully! The sinus the curse. That’s it. Hung Chung Egglyfella now speak he tell numptywumpty topsawys belongahim pidgin. Secret things other persons place there covered not.

— James Joyce, Finnegans Wake (1939)

4.1

Overview

In chapter two we discussed the requirements of a system for secret sharing labs and outlined a potential software model. In this chapter, we introduce Finnegan; a cryptographic lab system that has been constructed according to these ideas, and discuss how it can be used.2

As we saw in chapter three, the scheme devised by Shamir is based on polynomial evaluation and polynomial interpolation in a finite field. This is why the lab system is provided with the modules Polynomial (for evaluating polynomials of arbitrary degree), Interpolation (using Neville’s algorithm) and Congruence. Using these, Shamir’s secret sharing scheme can be put into practice with little effort. The RandomPrime module is also useful for finite field operations, as it generates a probable prime number with the size of any desired number of bits.3 The Xor module can be used with

Ran-domPrime for secret splitting, but combining RanRan-domPrime and addition or subtraction with the Congurence module is another possible way to realise secret splitting. The rest of the modules deal with integers, text-to-number converting, input and output.

2

Needless to say, it was named after Finnegans Wake by Irish author Joyce. Possibly one of the most “cryptic” works of all times.

3

If p N, then Zp is a field if and only if p is prime. The number generated by

RandomPrime is prime with a probability of at least 1− 2−100.

(22)

12 Finnegan Lab System

4.2

User’s Guide

The best way to understand how to use Finnegan is simply to play with the program for a short while. Its graphical user interface, as seen in figure 4.1, should be fairly intuitive to anyone accustomed to modern computer systems. It works by letting the user connect atomic modules, which perform different computational operations. New modules are created from the menu named Modules. A module can be moved around on the screen by holding down the left mouse button, and it can be connected to other modules by drawing arrows with the right mouse button. The same action will also disconnect modules, if they are already linked together. Double click with left mouse button on a module, or select Command→Properties, to set its behaviour or value. Finally, select Command→Run to execute the graph. Note that cyclic graphs should be avoided, as they might lead to internal stack overflow errors due to the recursive nature of the graph evaluation.

All modules in Finnegan work with pairs of integers — (x, y). This uni-fication simplifies many operations, but naturally there are also many cases where only one number, and not a pair, is needed. In this case, the second number can simply be ignored as it is set to zero by default and does not affect the result. The integers can be of arbitrary length. However, using extremely large integers can lead to a rather poor performance depending on the computer system.

4.3

Developer’s Guide

Finnegan builds on the language Java (version 1.4), and executes as an appli-cation in a JVM (Java Virtual Machine).4 All modules are loaded from the subdirectory named plugin. As they are loaded dynamically, Finnegan does not need to be recompiled if a module is added or removed. It is sufficient to restart the program. Neither does Finnegan itself need to be modified when developing a new module. All modules are implemented as extensions of a base class called Module, and the following methods in this class can be overloaded:

• public boolean acquireLinkIn()

Return true if new links from other modules are accepted.

4

Java was originally developed by Sun Microsystems in the early 1990s. Java applica-tions are completely platform independent, which of course is a big advantage. One could argue against this and say that Java is a platform itself. However, that misses the point.

(23)

4.3. Developer’s Guide 13

(24)

14 Finnegan Lab System

• public boolean acquireLinkOut()

Return true if new links from to modules are accepted. • public BigInteger[] eval()

This is where the calculations are done. • public String getDescription()

Return a description of the module. HTML can be used. • public String getName()

Return the name of the module. • public Hashtable getProperties()

Return a hashtable with any properties the user could modify, with the name of each property as the key. Both the key and the value should be presented as String objects. This method is called when the user wants to modify the properties. Return null if no properties can be set.

• public void setProperties(final Hashtable properties)

Set any internal variables in a way corresponding to the way getProp-erties works. This method is called when the user has accepted any changes in the properties.

• public String toString()

Should call eval(), format the result in some way and return it. HTML can be used.

As mentioned, all modules work with pairs of integers — or rather pairs of BigInteger objects. This behaviour is defined in two methods (eval and toString ) and can be changed by modifying the base class (Module). This is the only case where the base class needs to be modified. Note that all the modules will need to be recompiled if the base class is changed. Figure 4.2 shows an overview of the class hierachy. The main class Finnegan is the monolithic lab environment, but it has no functionality without any modules. Readers interested in programming their own modules are encouraged to look at the source code in the appendix. The Xor module (see A.18), for instance, is very simple and can be used as a starting point. In fact, modular inverse (using either the built-in function in Java’s BigInteger class, or by implementing the extended Euclidean algorithm) and exponentiation is enough to get started with public-key cryptography and the Diffie-Hellman key-exchange protocol.

(25)

4.3. Developer’s Guide 15 Module +size: Dimension +halfSize: Dimension +linkIn: LinkedList +linkOut: LinkedList +rect: Rectangle +acquireLinkIn(): boolean +acquireLinkOut(): boolean +eval(): BigInteger[] +getDescription(): String +getName(): String +getProperties(): Hashtable +setProperties(properties:Hashtable) +toString(): String Finnegan +Finnegan() +main(args:String[]) plugin Congruence FlipSign Int2Text Interpolate ModifyX ModifyY Plus Polynomial RandomPrime ReadFile SetXY Stdout Swap Text2Int WriteFile Xor

(26)

16 Finnegan Lab System

4.4

Teacher’s Guide

To achieve a deeper understanding of the concept of secret sharing per se and the inner workings of the algorithms, a few excercises are suggested here.

The student will start with M1, M2 and M3, where M1⊕ M2⊕ M3 = M .

With the aid of Finnegan, the student should examine the contents of each share, examine the result of xoring two of them and finally xor them all to-gether. The student should now understand how to work with Finnegan, and be able to answer some questions pertaining secret splitting. Once the stu-dent has come this far, a good second excercise may be to make a threshold scheme out of M with the help of a description of Shamir’s scheme, exam-ine how this scheme works by testing it in different ways, and answer a few questions pertaining threshold schemes. Finally, the answers could be dis-cussed with an assisting teacher, along with a presentation of how the tasks were solved, or a short paper could be written where basic aspects of secret sharing are considered.

Other approaches are obviously possible, but the goal should be that each student, when finished with the excercises, should have an understanding of what secret sharing is, what it can be used for, why it works, and when it is useful. It is important that the student has understood what problem secret sharing is supposed to solve — that it is a method for key management and not for data encryption.

(27)

Chapter 5

Conclusions

A common lesson learned in software engineering is the importance of code reusability. In practice, however, it often turns out that it can be very dif-ficult to reuse code. This was confirmed in the decision to write a custom user interface, despite the number of existing graph-editing frameworks. Of course, it is a trade-off. In this case, the cost of starting from a blank file was estimated to be less than the cost of studying and modifying external code. This is partly because Java proved to be a good choice of language for this task. Thanks to the built in support for arbitrarily large integers, the variety of data structures and a straightforward graphical programming interface, the number of effective lines of code in Finnegan is below two thousand.

Perhaps the largest obstacle while designing Finnegan was how to handle and present the information that is passed between the modules in a uniform manner, without having the user to enter information that the computer already has. It had to be good for the purpose of secret sharing without being too specialiced. Otherwise it would be practically impossible in the future to write new extensions to the lab system, which was one of the initial design goals. The solution, to always let the modules work with integer pairs represented as (x, y), has shown to work fairly well. If only one variable is needed, the second can simply be ignored. It is also easy for a programmer to modify the Module class to use something else, be it single binary streams or triples of real numbers.

Software testings has shown that Finnegan is stable and can be used as intended to study secret sharing. It has not been evaluated in any user test cases. Testing has focused on locating faults, not usability issues. For a larger project it would be sensible during the development to let a group of people use the lab software under supervision, to see what needs improvement. Un-fortunately there has been neither time nor resources for this. Furthermore, the suggested exercises in the previous chapter have not been evaluated and

(28)

18 Conclusions

should only be treated as suggestions. It should be obvious that a lab assign-ment using Finnegan needs to be thoroughly prepared, but preparing such an assignment is beyond the scope of this thesis.

Finnegan was designed to be a lab system. This is a limitation that should be kept in mind. In its current shape, it is not suitable for other uses. For someone who wants to do “real” secret sharing, there are already several other computer programs that are better to use for this purpose, as they — in contrast to the lab system — work fully automated. There is also another reason why Finnegan should not be used with genuine secrets: Finnegan was never designed to be secure. After having used Finnegan, the secret will most likely stay intact in the computer memory for an unknown time, or even be swapped out on disk by a virtual memory manager. It is a trivial process to recover the secret from there. It does not help that Shamir’s scheme in theory provides ideal and perfect security when the software is not designed for security.

Instead of using a lab system like Finnegan, a suggested assignment for students could be to implement secret sharing using something like Matlab code. But one of the requirements of this lab system was to not require prior knowledge in computer programming, and this is why Finnegan was designed and developed.

Future work on the lab system should first of all involve enhancing the user interface; to make it more suitable for working with large graphs, and to implement features like cut, copy, paste, undo, redo, multiple selections and multiple windows. Secondly, the graph is now evaluated or executed in a strictly sequential manner. It might be very interesting to implement iteration (“do . . . while”) and selection (“if . . . then”). This would turn the lab system into a fully Turing complete visual programming environment!

Personally, this has been an interesting and challenging project. Interest-ing to learn much more about both cryptography and programmInterest-ing. How-ever, the most challenging part — and most creatively satisfactory — was designing the lab system. Trying to make everything fit together logically, making the software as simple as possible but not simpler. Aiming for flexi-bility and avoiding complexity. Finnegan is based on a few very simple design principles, both externally and internally. Externally, one of the challanges were to make a seamless user interface. It started with long lists of options and commands; one of the challenges was to minimise the number, and it finally stopped at about five user commands. Internally, the challange was not only to get every detail, part, coupling and every algorithm to work — but also to make them work together with the least possible complexity.

(29)

Appendix A

Source Code

A.1

Finnegan.java

import plugin.Module; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; import javax.swing.*; /** 10 * Fredrik Olsson, 2003 * freol@lysator.liu.se */

public class Finnegan extends JFrame implements ActionListener {

(30)

20

Source

Co

de

private final static int MOVE COMMAND = 0, DELETE COMMAND = 1, PROPERTIES COMMAND = 2; private final JTextPane console = new JTextPane();

private final JPanel editor = myJPanel();

private final Rectangle editorArea = new Rectangle(0, 0, 1600, 1200); private LinkedList data = new LinkedList();

private Module selectedNode = null;

20 private Point offset = new Point(), lineStart = new Point(), lineEnd = new Point(); private String consoleBuffert = new String();

private boolean leftMouseButton = false, rightMouseButton = false; private int command = MOVE COMMAND;

public Finnegan() {

setTitle("Finnegan Lab System"); setSize(640, 480); setDefaultCloseOperation(JFrame.EXIT ON CLOSE); 30 console.setContentType("text/html"); console.setEditable(false); editor.setDoubleBuffered(true); editor.setPreferredSize(editorArea.getSize()); editor.addMouseListener(myMouseListener()); editor.addMouseMotionListener(myMouseMotionListener()); JScrollPane editorScroller = new JScrollPane(editor); JScrollPane consoleScroller = new JScrollPane(console);

JSplitPane split = new JSplitPane(JSplitPane.VERTICAL SPLIT, editorScroller, consoleScroller);

40 split.setOneTouchExpandable(true); split.setDividerLocation(350); getContentPane().add(split);

JMenuBar menubar = new JMenuBar(); JMenu menu = new JMenu("File");

(31)

A.1. Finnegan.ja v a 2 1

JMenuItem item = new JMenuItem("New", KeyEvent.VK N); item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) { consoleBuffert = "";

50 writeln("<b>Welcome!</b>"); data = new LinkedList(); editor.repaint();

} });

menu.add(item); menu.addSeparator();

item = new JMenuItem("Open", KeyEvent.VK O);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK O, KeyEvent.CTRL DOWN MASK)); item.addActionListener(new ActionListener() {

60 public void actionPerformed(final ActionEvent e) { JFileChooser fileChooser = new JFileChooser();

if (fileChooser.showOpenDialog(getContentPane()) == JFileChooser.APPROVE OPTION){ try {

FileInputStream fin = new FileInputStream(fileChooser.getSelectedFile()); ObjectInputStream is = new ObjectInputStream(fin);

data = (LinkedList) is.readObject(); is.close();

fin.close();

70 editor.repaint();

}

catch (FileNotFoundException ex) { catchException(ex); } catch (IOException ex) { catchException(ex); } catch (ClassNotFoundException ex) { catchException(ex); }

} } });

(32)

22

Source

Co

de

menu.add(item);

item = new JMenuItem("Save", KeyEvent.VK S);

80 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK S, KeyEvent.CTRL DOWN MASK)); item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) { JFileChooser fileChooser = new JFileChooser();

if (fileChooser.showSaveDialog(getContentPane()) == JFileChooser.APPROVE OPTION) { try {

FileOutputStream fout = new FileOutputStream(fileChooser.getSelectedFile()); ObjectOutputStream os = new ObjectOutputStream(fout);

os.writeObject(data); os.close();

90 fout.close();

}

catch (FileNotFoundException ex){ catchException(ex); } catch (IOException ex) { catchException(ex); }

} } });

menu.add(item); menu.addSeparator();

item = new JMenuItem("Exit", KeyEvent.VK X);

100 item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) { dispose(); System.exit(0); } }); menu.add(item); menubar.add(menu);

(33)

A.1. Finnegan.ja v a 2 3

110 item = new JMenuItem("Delete", KeyEvent.VK D);

item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK DELETE, 0)); item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getContentPane().setCursor(new Cursor(Cursor.CROSSHAIR CURSOR)); command = DELETE COMMAND;

} });

menu.add(item);

item = new JMenuItem("Properties", KeyEvent.VK P);

120 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK ENTER, 0)); item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

getContentPane().setCursor(new Cursor(Cursor.CROSSHAIR CURSOR)); command = PROPERTIES COMMAND;

} });

menu.add(item); menu.addSeparator();

item = new JMenuItem("Run", KeyEvent.VK R);

130 item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK F5, 0)); item.addActionListener(new ActionListener() {

public void actionPerformed(final ActionEvent e) {

writeln("<b>Executing [" + new GregorianCalendar().getTime().toString() + "] =&gt;</b>"); for (Iterator i = data.iterator(); i.hasNext();) {

Module node = (Module) i.next(); if (node.linkOut.isEmpty()) {

try {

writeln(node.toString());

}

140 catch (ArithmeticException ex) { catchException(ex); } catch (NumberFormatException ex) { catchException(ex); }

(34)

24

Source

Co

de

catch (StackOverflowError er) { catchError(er); }

} } writeln("<b>Ready.</b>"); } }); menu.add(item); menubar.add(menu); 150

menu = new JMenu("Modules");

String[ ] fileNames = new File("plugin").list(); if (fileNames != null) {

for (int i = 0; i < fileNames.length; ++i) { if (!fileNames[i].equals("Module.class") &&

fileNames[i].endsWith(".class")) {

int extIndex = fileNames[i].indexOf(".class");

String pluginName = fileNames[i].substring(0, extIndex); item = new JMenuItem(pluginName);

160 item.addActionListener(Finnegan.this); item.setActionCommand(pluginName); try {

Module node = (Module) Class.forName("plugin." + pluginName).newInstance(); item.setToolTipText(node.getName());

menu.add(item);

}

catch (ClassNotFoundException ex) { catchException(ex); } catch (IllegalAccessException ex) { catchException(ex); }

170 catch (InstantiationException ex) { catchException(ex); }

} } }

(35)

A.1. Finnegan.ja v a 2 5 menubar.add(menu); setJMenuBar(menubar); setVisible(true); writeln("<b>Welcome!</b>"); }

180 public void actionPerformed(final ActionEvent e) { try {

Module node = (Module) Class.forName("plugin." + e.getActionCommand()).newInstance(); writeln("<b>" + node.getName() + " =&gt;</b> " + node.getDescription());

Rectangle rect = editor.getVisibleRect(); node.rect.setLocation(rect.getLocation());

node.rect.translate((rect.width − Module.size.width) >> 1, (rect.height − Module.size.height) >> 1);

while (getAtCoordinate(node.rect.getLocation()) != null) node.rect.translate(1, 1);

190 data.add(node); editor.repaint();

}

catch (ClassNotFoundException ex) { catchException(ex); } catch (IllegalAccessException ex) { catchException(ex); } catch (InstantiationException ex) { catchException(ex); }

}

private void catchError(final Error er) {

writeln("<b>Error =&gt;</b> " + er.toString());

200 }

private void catchException(final Exception ex) { writeln("<b>Error =&gt;</b> " + ex.toString());

(36)

26

Source

Co

de

private void drawArrow(final Graphics g, final Point from, final Point to) { double delY = to.y − from.y;

double delX = from.x − to.x; double angle;

210 if (delX > 0 && delY >= 0)

angle = (180 * Math.atan(delY / delX)) / Math.PI; else if (delX < 0 && delY >= 0)

angle = (180 * (Math.PI − Math.atan(−1 * delY / delX))) / Math.PI; else if (delX < 0 && delY <= 0)

angle = (180 * (Math.PI + Math.atan(delY / delX))) / Math.PI; else if (delX > 0 && delY <= 0)

angle = (−180 * Math.atan(−1 * delY / delX)) / Math.PI; else

angle = delY > 0 ? 90 : −90;

220 g.setColor(Color.BLACK);

g.drawLine(from.x, from.y, to.x, to.y);

g.fillArc(to.x − 10, to.y − 10, 20, 20, (int) angle − 15, 30); g.setColor(Color.WHITE);

}

private Module getAtCoordinate(final Point point) { Module node;

for (Iterator i = data.iterator(); i.hasNext();) { node = (Module) i.next();

230 if (node.rect.contains(point)) return node;

}

return null;

}

private JPanel myJPanel() { return new JPanel() {

(37)

A.1. Finnegan.ja v a 2 7

public void paint(final Graphics g) { Iterator i, j;

240 Module node1, node2; super.paint(g);

for (i = data.iterator(); i.hasNext();) { node1 = (Module) i.next();

if (!editorArea.contains(node1.rect)) { Rectangle rect = editor.getVisibleRect(); node1.rect.setLocation(rect.getLocation()); node1.rect.translate((rect.width − Module.size.width) >> 1, (rect.height − Module.size.height) >> 1); 250 } } if (!lineStart.equals(lineEnd))

drawArrow(g, lineStart, lineEnd); if (selectedNode != null) {

g.setColor(Color.BLACK);

g.drawString(selectedNode.getName(), selectedNode.rect.x, selectedNode.rect.y − 5); g.setColor(Color.WHITE);

g.draw3DRect(selectedNode.rect.x, selectedNode.rect.y,

260 Module.size.width, Module.size.height, false); for (i = selectedNode.linkOut.iterator(); i.hasNext();) {

node1 = (Module) i.next();

selectedNode.rect.translate(Module.halfSize.width, Module.halfSize.height); node1.rect.translate(Module.halfSize.width, Module.halfSize.height); drawArrow(g, selectedNode.rect.getLocation(), node1.rect.getLocation()); selectedNode.rect.translate(−Module.halfSize.width, −Module.halfSize.height); node1.rect.translate(−Module.halfSize.width, −Module.halfSize.height);

} }

(38)

28

Source

Co

de

270

for (i = data.iterator(); i.hasNext();) { node1 = (Module) i.next();

g.setColor(Color.BLACK);

g.drawString(node1.getName(), node1.rect.x, node1.rect.y − 5); g.setColor(Color.WHITE);

g.draw3DRect(node1.rect.x, node1.rect.y,

Module.size.width, Module.size.height, true); for (j = node1.linkOut.iterator(); j.hasNext();) {

node2 = (Module) j.next();

280 node1.rect.translate(Module.halfSize.width, Module.halfSize.height); node2.rect.translate(Module.halfSize.width, Module.halfSize.height); drawArrow(g, node1.rect.getLocation(), node2.rect.getLocation()); node1.rect.translate(−Module.halfSize.width, −Module.halfSize.height); node2.rect.translate(−Module.halfSize.width, −Module.halfSize.height);

} } } }; } 290

private MouseListener myMouseListener() { return new MouseListener() {

public void mouseClicked(final MouseEvent e) { if (e.getClickCount() == 2) {

Module node = getAtCoordinate(e.getPoint()); if (node != null)

properties(node);

} }

300

(39)

A.1. Finnegan.ja v a 2 9 }

public void mouseExited(final MouseEvent e) {

}

public void mousePressed(final MouseEvent e) { int mouse = e.getButton();

if (mouse == MouseEvent.BUTTON1) {

310 leftMouseButton = true;

selectedNode = getAtCoordinate(e.getPoint()); if (selectedNode != null){

switch (command) {

case MOVE COMMAND :

offset = selectedNode.rect.getLocation(); offset.translate(−e.getX(), −e.getY()); data.remove(selectedNode);

editor.repaint(); break;

320 case DELETE COMMAND :

for (Iterator i = selectedNode.linkIn.iterator(); i.hasNext();) { Module node = (Module) i.next();

node.linkOut.remove(selectedNode);

}

for (Iterator i = selectedNode.linkOut.iterator(); i.hasNext();) { Module node = (Module) i.next();

node.linkIn.remove(selectedNode); } data.remove(selectedNode); 330 selectedNode = null; editor.repaint(); break;

(40)

30 Source Co de properties(selectedNode); selectedNode = null; break; } } }

340 else if (mouse == MouseEvent.BUTTON3) { rightMouseButton = true;

lineStart = lineEnd = e.getPoint();

}

if (command != MOVE COMMAND) {

getContentPane().setCursor(new Cursor(Cursor.DEFAULT CURSOR)); command = MOVE COMMAND;

} }

350 public void mouseReleased(final MouseEvent e) { int mouse = e.getButton();

if (mouse == MouseEvent.BUTTON1) { leftMouseButton = false; if (selectedNode != null){ offset.setLocation(0, 0); data.add(selectedNode); selectedNode = null; editor.repaint(); } 360 }

else if (mouse == MouseEvent.BUTTON3) { rightMouseButton = false;

Module node1 = getAtCoordinate(lineStart); Module node2 = getAtCoordinate(lineEnd); lineStart = lineEnd;

(41)

A.1. Finnegan.ja v a 3 1

if (node1 != null && node2 != null && node1 != node2) { for (Iterator i = node1.linkOut.iterator(); i.hasNext();) {

if (i.next() == node2) { node1.linkOut.remove(node2); 370 node2.linkIn.remove(node1); editor.repaint(); return; } }

if (node1.acquireLinkOut() && node2.acquireLinkIn()) { node1.linkOut.add(node2);

node2.linkIn.add(node1);

}

else

380 writeln("The nodes could not be linked.");

} editor.repaint(); } } }; }

private MouseMotionListener myMouseMotionListener() { return new MouseMotionListener() {

390 public void mouseDragged(final MouseEvent e) {

editor.scrollRectToVisible(new Rectangle(e.getPoint())); if (leftMouseButton) { if (selectedNode != null){ selectedNode.rect.setLocation(e.getPoint()); selectedNode.rect.translate(offset.x, offset.y); editor.repaint(); }

(42)

32 Source Co de } if (rightMouseButton) { 400 lineEnd = e.getPoint(); editor.repaint(); } }

public void mouseMoved(final MouseEvent e) {

} }; }

410 private void properties(final Module node) { final JDialog dialog = new JDialog(); Hashtable properties = node.getProperties(); if (properties == null) {

writeln("No properties can be defined for this node."); return;

}

dialog.setTitle(node.getName());

LayoutManager layout = new GridLayout(properties.size() + 1, 2);

420 dialog.getContentPane().setLayout(layout); Enumeration keys = properties.keys(); Enumeration values = properties.elements(); while (keys.hasMoreElements()) {

dialog.getContentPane().add(new JLabel((String) keys.nextElement())); dialog.getContentPane().add(new JTextField((String) values.nextElement()));

}

JButton ok = new JButton("OK");

(43)

A.1. Finnegan.ja v a 3 3

430 public void actionPerformed(ActionEvent e) {

Hashtable newProp = new Hashtable();

int n = dialog.getContentPane().getComponentCount() − 2; for (int i = 0; i < n; ++i) {

newProp.put(((JLabel) dialog.getContentPane().getComponent(i)).getText(), ((JTextField) dialog.getContentPane().getComponent(++i)).getText()); } try { node.setProperties(newProp); }

440 catch (NumberFormatException ex) { catchException(ex); } dialog.dispose();

} });

JButton close = new JButton("Cancel"); close.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) { dialog.dispose(); } }); 450 dialog.getContentPane().add(ok); dialog.getContentPane().add(close); dialog.getRootPane().setDefaultButton(ok); dialog.pack(); dialog.setVisible(true); }

private void writeln(final String msg) { consoleBuffert += msg + "<br>";

460 console.setText(consoleBuffert);

(44)

34

Source

Co

de

public static void main(final String[ ] args) { new Finnegan(); } }

A.2

plugin/Module.java

package plugin; import java.awt.*; import java.io.Serializable; import java.math.BigInteger; import java.util.*; /** * Fredrik Olsson, 2003 10 * freol@lysator.liu.se */

public class Module implements Serializable {

public static final Dimension size = new Dimension(50, 50); public static final Dimension halfSize = new Dimension(25, 25); public final LinkedList linkIn = new LinkedList();

public final LinkedList linkOut = new LinkedList(); public final Rectangle rect = new Rectangle(size); public boolean acquireLinkIn() {

20 return true;

(45)

A.2. plugin/Mo dule.ja v a 35

public boolean acquireLinkOut() { return true;

}

public BigInteger[ ] eval() {

return new BigInteger[ ] {new BigInteger("0"), new BigInteger("0")};

}

30

public String getDescription() { return "";

}

public String getName() { return "";

}

public Hashtable getProperties() {

40 return null;

}

public void setProperties(final Hashtable properties) {

}

public String toString() { BigInteger[ ] value = eval();

return "(" + value[0].toString() + ", " + value[1].toString() + ")";

}

(46)

36 Source Co de

A.3

plugin/Congruence.java

package plugin; import java.math.BigInteger; import java.util.Hashtable; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class Congruence extends Module {

private BigInteger modulus = new BigInteger("0"); public boolean acquireLinkIn() {

return linkIn.size() == 0;

}

public BigInteger[ ] eval() {

BigInteger[ ] value = new BigInteger[2]; if (linkIn.size() == 0) {

20 value[0] = new BigInteger("0"); value[1] = new BigInteger("0");

}

else

value = ((Module) linkIn.getFirst()).eval();

return new BigInteger[ ] {value[0].mod(modulus), value[1].mod(modulus)};

}

public String getDescription() {

(47)

A.4. plugin/FlipSign.ja v a 3 7

30 ,→ value defined in the <i>properties</i> dialogue box.";

}

public String getName() { return "Congruence";

}

public Hashtable getProperties() {

Hashtable properties = new Hashtable(); properties.put("Modulus", modulus.toString());

40 return properties;

}

public void setProperties(final Hashtable properties) {

modulus = new BigInteger((String) properties.get("Modulus"));

} }

A.4

plugin/FlipSign.java

package plugin; import java.math.BigInteger; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

public class FlipSign extends Module {

(48)

38 Source Co de return linkIn.size() == 0; }

public BigInteger[ ] eval() {

BigInteger[ ] value = new BigInteger[2]; if (linkIn.size() == 0) {

value[0] = new BigInteger("0"); value[1] = new BigInteger("0");

}

20 else

value = ((Module) linkIn.getFirst()).eval();

return new BigInteger[ ] {value[0].multiply(new BigInteger("-1")), value[1].multiply(new BigInteger("-1"))};

}

public String getDescription() {

return "Return the additive inverse of the connected node values.";

}

30 public String getName() { return "* -1"; } }

A.5

plugin/Int2Text.java

package plugin; import java.math.BigInteger; import java.util.Hashtable;

(49)

A.5. plugin/In t2T ex t.ja v a 39 /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class Int2Text extends Module { private String text = new String(); public boolean acquireLinkIn() {

return linkIn.size() == 0;

}

public BigInteger[ ] eval() { if (linkIn.size() == 0)

return new BigInteger[ ] {new BigInteger("0"), new BigInteger("0")};

20 return ((Module) linkIn.getFirst()).eval();

}

public String getDescription() {

return "Interpret (x, y) as two text strings and print the result.";

}

public String getName() { return "Int2Text";

}

30

public Hashtable getProperties() {

Hashtable properties = new Hashtable(); properties.put("Text", text);

return properties;

(50)

40

Source

Co

de

public void setProperties(final Hashtable properties) { text = (String) properties.get("Text");

}

40

public String toString() { BigInteger[ ] value = eval();

return "<b>x:</b> " + new String(value[0].toByteArray()) + "<br><b>y:</b> " + new String(value[1].toByteArray());

} }

A.6

plugin/Interpolate.java

package plugin; import java.math.BigInteger; import java.util.*; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class Interpolate extends Module { private BigInteger xx = new BigInteger("0"); public BigInteger[ ] eval() {

if (linkIn.size() == 0)

return new BigInteger[ ] {new BigInteger("0"), new BigInteger("0")}; int c = 0, n = linkIn.size();

BigInteger tmp1, tmp2;

(51)

A.6. plugin/In terp o late.ja v a 4 1

BigInteger[ ] y = new BigInteger[n];

20 BigInteger[ ] xy = new BigInteger[2];

for (Iterator i = linkIn.iterator(); i.hasNext();) { xy = ((Module) i.next()).eval();

x[c] = xy[0]; y[c] = xy[1]; ++c;

}

for (int i = 0; i < n; ++i) {

for (int j = n − 1; j > i; −−j) { tmp1 = xx.subtract(x[j]); 30 tmp2 = y[j].subtract(y[j − 1]); tmp1 = tmp1.multiply(tmp2); tmp2 = x[j].subtract(x[j − i − 1]); tmp1 = tmp1.divide(tmp2); y[j] = y[j].add(tmp1); } }

return new BigInteger[ ] {xx, y[n − 1]};

}

40 public String getDescription() {

return "Interpolate the incoming set of points, using Neville’s algorithm.";

}

public String getName() { return "Interpolate";

}

public Hashtable getProperties() {

Hashtable properties = new Hashtable();

(52)

42 Source Co de return properties; }

public void setProperties(final Hashtable properties) {

xx = new BigInteger((String) properties.get("Interpolate y where x ="));

} }

A.7

plugin/ModifyX.java

package plugin; import java.math.BigInteger; import java.util.Hashtable; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class ModifyX extends Module {

private BigInteger[ ] value = {new BigInteger("0"), new BigInteger("0")}; public boolean acquireLinkIn() {

return linkIn.size() == 0;

}

public BigInteger[ ] eval() { if (linkIn.size() != 0)

value[1] = ((Module) linkIn.getFirst()).eval()[1];

(53)

A.8. plugin/Mo d ifyY.ja v a 4 3 }

public String getDescription() {

return "Modify the x-value from the input (x, y), as specified in the <i>properties</i> dialogue box.";

}

public String getName() { return "ModifyX";

}

30

public Hashtable getProperties() {

Hashtable properties = new Hashtable();

properties.put("New value of x", value[0].toString()); return properties;

}

public void setProperties(final Hashtable properties) {

value[0] = new BigInteger((String) properties.get("New value of x"));

} 40 }

A.8

plugin/ModifyY.java

package plugin; import java.math.BigInteger; import java.util.Hashtable; /** * Fredrik Olsson, 2003

(54)

44 Source Co de * freol@lysator.liu.se */

10 public class ModifyY extends Module {

private BigInteger[ ] value = {new BigInteger("0"), new BigInteger("0")}; public boolean acquireLinkIn() {

return linkIn.size() == 0;

}

public BigInteger[ ] eval() { if (linkIn.size() != 0)

value[0] = ((Module) linkIn.getFirst()).eval()[0];

20 return value;

}

public String getDescription() {

return "Modify the y-value from the input (x, y), as specified in the <i>properties</i> dialogue box.";

}

public String getName() { return "ModifyY";

}

30

public Hashtable getProperties() {

Hashtable properties = new Hashtable();

properties.put("New value of y", value[1].toString()); return properties;

}

public void setProperties(final Hashtable properties) {

value[1] = new BigInteger((String) properties.get("New value of y"));

(55)

A.9. plugin/Plus.ja v a 45 40 }

A.9

plugin/Plus.java

package plugin; import java.math.BigInteger; import java.util.Iterator; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class Plus extends Module { public BigInteger[ ] eval() {

BigInteger[ ] value = {new BigInteger("0"), new BigInteger("0")}; for (Iterator i = linkIn.iterator(); i.hasNext();) {

Module node = (Module) i.next(); value[0] = value[0].add(node.eval()[0]); value[1] = value[1].add(node.eval()[1]); } return value; } 20

public String getDescription() {

return "This module adds two or several connected nodes.<br><i>E.g.: (5, 0) + (1, 2) = (6, 2)</i>";

}

public String getName() { return "+";

(56)

46 Source Co de } }

A.10

plugin/Polynomial.java

package plugin; import java.math.BigInteger; import java.util.*; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class Polynomial extends Module { private String expr = new String(); public boolean acquireLinkIn() {

return linkIn.size() == 0;

}

public BigInteger[ ] eval() { if (linkIn.size() == 0)

return new BigInteger[ ] {new BigInteger("0"), new BigInteger("0")};

20 BigInteger value = new BigInteger("0");

BigInteger[ ] node = ((Module) linkIn.getFirst()).eval();

StringTokenizer tokenizer = new StringTokenizer(expr, " ,.;");

for (int i = tokenizer.countTokens() − 1; tokenizer.hasMoreTokens(); −−i) { BigInteger tmp1 = new BigInteger(tokenizer.nextToken());

(57)

A.11. plugin/RandomPrime.ja v a 47 BigInteger tmp3 = tmp1.multiply(tmp2); value = value.add(tmp3); }

return new BigInteger[ ] {node[0], value.add(node[1])};

30 }

public String getDescription() {

return "A polynomial, p(x), is a sum of powers multiplied by coefficients.<br><i>E.g.: p(x) =

,→ 7x<sup>4</sup> + 5x<sup>3</sup> + 12x + 0</i> is written as <i>7; 5; 0; 12; 0</i>. Assuming input ,→ is (x, y), the output will be (x, p(x) + y).";

}

public String getName() { return "p(x) + y";

40 }

public Hashtable getProperties() {

Hashtable properties = new Hashtable(); properties.put("p(x) =", expr);

return properties;

}

public void setProperties(final Hashtable properties) { expr = (String) properties.get("p(x) =");

50 }

}

A.11

plugin/RandomPrime.java

(58)

48 Source Co de import java.math.BigInteger; import java.util.*; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class RandomPrime extends Module { private final Random rnd = new Random(); private int length = 0;

public boolean acquireLinkIn() { return false;

}

public String getDescription() {

return "The output is (p, 0), where p is a randomly generated positive prime number. Use the <i>properties</i>

20 ,→ dialogue box to specify its length. Three more things should be noted:<br>1. This pseudo random number ,→ generator is not <i>cryptographically strong</i>.<br>2. The number will be different every time, for every ,→ connected node.<br>3. The number is prime with a probability of at least 1 - 2<sup>-100</sup>.";

}

public BigInteger[ ] eval() {

return new BigInteger[ ] {BigInteger.probablePrime(length, rnd), new BigInteger("0")};

}

public String getName() {

30 return "RandomPrime";

}

(59)

A.12. plugin/ReadFile.ja v a 4 9

Hashtable properties = new Hashtable();

properties.put("Length of the number, in bytes", new Integer(length).toString()); return properties;

}

public void setProperties(final Hashtable properties) {

40 length = new Integer((String) properties.get("Length of the number, in bytes")).intValue() * 8;

} }

A.12

plugin/ReadFile.java

package plugin; import java.io.*; import java.math.BigInteger; import java.util.Hashtable; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se 10 */

public class ReadFile extends Module { private String fileNameX = new String(); private String fileNameY = new String(); public boolean acquireLinkIn() {

return false;

(60)

50

Source

Co

de

public BigInteger[ ] eval() {

20 BigInteger[ ] value = new BigInteger[2];

try { byte[ ] b;

FileInputStream fis; DataInputStream dis;

if (fileNameX.compareTo(new String()) != 0) {

b = new byte[(int) new File(fileNameX).length()]; fis = new FileInputStream(fileNameX);

dis = new DataInputStream(fis); dis.readFully(b);

30 dis.close(); fis.close();

value[0] = new BigInteger(b);

}

else

value[0] = new BigInteger("0");

if (fileNameY.compareTo(new String()) != 0) {

b = new byte[(int) new File(fileNameY).length()]; fis = new FileInputStream(fileNameY);

dis = new DataInputStream(fis);

40 dis.readFully(b); dis.close(); fis.close();

value[1] = new BigInteger(b);

}

else

value[1] = new BigInteger("0"); return value;

}

catch (FileNotFoundException ex) { ex.printStackTrace(); }

(61)

A.13.

plugin/SetXY.ja

v

a

51

return new BigInteger[ ] {new BigInteger("0"), new BigInteger("0")};

}

public String getDescription() {

return "Read (x, y) from two separate files. A filename can be left blank in the <i>properties</i>

,→ dialogue box, to leave out the corresponding variable."; }

public String getName() {

60 return "ReadFile";

}

public Hashtable getProperties() {

Hashtable properties = new Hashtable(); properties.put("Filename for x", fileNameX); properties.put("Filename for y", fileNameY); return properties;

}

70 public void setProperties(final Hashtable properties) {

fileNameX = ((String) properties.get("Filename for x")).trim(); fileNameY = ((String) properties.get("Filename for y")).trim();

} }

A.13

plugin/SetXY.java

package plugin;

(62)

52 Source Co de import java.util.Hashtable; /** * Fredrik Olsson, 2003 * freol@lysator.liu.se */

10 public class SetXY extends Module {

private BigInteger[ ] value = {new BigInteger("0"), new BigInteger("0")}; public boolean acquireLinkIn() {

return false;

}

public BigInteger[ ] eval() { return value;

}

20

public String getDescription() {

return "Define a pair of integers -- (x, y).";

}

public String getName() { return "SetXY";

}

public Hashtable getProperties() {

30 Hashtable properties = new Hashtable(); properties.put("x", value[0].toString()); properties.put("y", value[1].toString()); return properties;

References

Related documents

In the MY PAGES screen, see figure 4, there are three tabs along the top where the user can see items they have borrowed from another user, lent to another user, as well as items

It will be argued that the three different narrative voices in Diary of a Bad Year can be seen to represent the super-ego (the opinions), the ego (Mister C) and the id (Anya

In light of the organisation’s vision and goal to reach out to as many people as possible due to operating within a new niche market, their specific target group

Key words: Logistics, SCM, Lean, The logistical goal mix, Economy, Dominican Republic, 3PL, 4PL, DuPont, Organisation, Leadership, Delivery service, Logistical cost, Capital

Since public corporate scandals often come from the result of management not knowing about the misbehavior or unsuccessful internal whistleblowing, companies might be

Society today faces unprecedented social and environmental challenges that are both complex in nature and require immediate and severe action. The financial system is a complex

The provisions in the Directive that will be analysed are (1) the distinction made in Preamble 14 between trade secrets and employee’s skills and experiences; (2) the provision

The question raised here is what characteristics and properties IS-based support systems for knowledge sharing should uphold in order to more accurately reflect