© Marius Iulian Mihailescu and Stefania Loredana Nita 2021
M. I. Mihailescu, S. L. NitaPro Cryptography and Cryptanalysis https://doi.org/10.1007/978-1-4842-6367-9_1

1. Cryptography Fundamentals

Marius Iulian Mihailescu1   and Stefania Loredana Nita1
(1)
Bucharest, Romania
 

Introduction

The history of cryptography is very long and interesting. For a complete non-technical reference of cryptography, we recommend The Codebreakers [1]. The book presents cryptography from its initial use by the Egyptians around 4,000 years ago to recent history when it played a vital role in the outcome of both world wars. The book was written in 1963 and covers aspects of history that were significant in terms of the development of cryptography. Cryptography is seen as an art and it is associated with diplomatic services, military personnel, and governments. Cryptography has been used as a tool for protecting strategies and different secrets related to national security.

The most important development in the history of cryptography was in 1976 when Diffie and Hellman [2] published the work paper entitled “New Directions in Cryptography.” The paper introduced the concept that revolutionized how cryptography was seen: public-key cryptography. The authors also introduced a new and ingenious method for key exchange. The security of the method is based on the intractability of the discrete logarithm problem. At that time, the authors didn’t have a practical implementation of the public-key encryption scheme, an idea that was very clear and started to generate significant interest in the cryptographic community. Starting in 1978, the first implementation of a public-key encryption and signature scheme was proposed by Rivest, Shamir, and Adleman (nowadays known as RSA [3]). The RSA scheme is based on the intractability of factoring large integers. If we are doing a parallel between integer factorization from RSA and Shor’s Algorithm, we will observe that the last algorithm will run in polynomial time for quantum computers and it will represent an important challenge to any cryptography approach that is based on the hardness assumption of factoring large integers [62]. The application of factoring large integers and its purpose has increased the number of the methods for factoring. In 1980, there were important advancements in this area but none of them showed any improvements for the security of RSA. A very important class of practical public-key schemes was found and proposed in 1985 by ElGamal [4]. His schemes are also based on the problem of the discrete logarithm.

The most important and significant contribution provided by public-key cryptography is represented by the digital signature. In 1991, the ISO/IEC 9796 international standard for digital signatures was adopted [5]. The standard is based on the RSA public-key scheme. In 1994, the United States government adopted the Digital Signature Standard, a powerful scheme based on the problem of the discrete logarithm.

Nowadays, searching for new public-key scheme, improvements on the current cryptographic mechanisms, and designing new proofs for security are still happening and continue to bring significant improvements.

The goal and purpose of this book is to explain the latest updates of the principles, techniques, algorithms, and implementations of the most important aspects of cryptography in practice. The focus is on the aspects that are most practical and applied. You will learn about the aspects that represent issues and we will point to references in literature and best practices that provide solutions. Due to the large volume of material covered, most of the results will be accompanied by implementations. This also serves to not obscure the real nature of cryptography. The book offers strong material for both implementers and researchers. The book describes algorithms and software systems with their interactions.

Information Security and Cryptography

In this book, the term and concept of information can be understood as quantity. In order to make an introduction to cryptography and its applications through algorithms and implementation technologies (such as C#), you need to understand the issues that are related to information security. All parties who participate in a certain transaction must have the confidence that specific objectives that are associated with the information security have been followed. The objectives are listed in Table 1-1.
Table 1-1

Security Objectives

Security Objective

Description

Privacy/confidentiality

Keeping the secrecy of the information from those who are not authorized to see it

Signature

A way to bind the signature to an entity (e.g. document)

Authorization

Sending from one entity to another, representing an official authorization to do or be something

Message authentication

Known as the authentication origin of data; some texts use as a definition the corroboration of the information source

Data integrity

The process of making sure that the information has not been altered by an unauthorized person or through other unknown means

Entity authentication/identification

Comparing the identity of an entity (e.g. computer, person, credit card, etc.).

Validation

A way of providing timeliness for authorization in order to use or manipulate the information or resources

Certification

Represents the acknowledgement of information by a trusted entity

Access control

The process of restricting resources to privileged entities

Certification

Acknowledgement of information by a trusted certification

Timestamping

A record that represents the time of creation or the existence of information

Witnessing

A way of verifying the creation of existence of information represented by an entity who is different from the creator

Receipt

Represents an acknowledgment that the information has been received

Ownership

A way to provide an entity with the legal right to use or transfer a specific resource to other entity

Confirmation

Represents the acknowledgement that services have been provided with success or not

Revocation

The process of retraction of a certification or authorization

Non-repudiation

The process of preventing the denial of other previous commitments or actions

Anonymity

The stashing process of the identity of an entity involved in a specific process

A set of protocols and mechanisms has been created in order to deal with the issues raised by information security when the information is send by physical documents. The objectives of the information security can be achieved as well through mathematical algorithms and protocols, requiring at the same time procedural techniques and following the laws by achieving the result that is desired. As an example, let’s consider the privacy of letters, which is provided by sealed envelopes that are delivered by a legitimate mail service. The physical security of the envelope has its own limitations and laws are established in such way that if mail is open by someone who is not authorized to do so, they can be charged with a criminal offense. There are cases when that security is achieved not only through the information itself but also through the paper document that records the originality of the information. As an example, consider paper currency, which requires special ink and material in order to avoid and prevent the forgery of it.

Conceptually speaking, the way information is stored, registered, interpreted, and recorded hasn’t changed too much. The ability to copy and modify information represents one of the most important characteristics of manipulating information that has been changed significantly.

One of the most important tools used in information security is represented by the signature . It represents a building block for multiple services such as non-repudiation, data origin authentication, identification, and witnessing.

In a society based on electronic communication, achieving information security implies fulfilling requirements based on legal and technical skills. At the same time, there is no guarantee that the objectives of information security can be met accordingly. The technical part of information security is assured by cryptography .

Cryptography represents the discipline that studies mathematical techniques that are related to information security such as confidentiality, integrity (data), authentication (entity), and the origin of the authentication. Cryptography doesn’t consist only of providing information security, but also in a specific set of techniques.

Cryptography Goals

From the list of objectives related to information security listed in Table 1-1, the next four represent the basis of a framework that will help others to be derived:
  • Privacy/confidentiality (Definition 1.5 and 1.8)

  • Data integrity (Definition 1.9)

  • Authentication (Definition 1.7)

  • Non-repudiation (Definition 1.6)

Let’s consider each of the objectives separately and see their own goal and purpose:
  • Confidentiality represents a service that is used to protect the content of information from those who are not authorized to see it. There are different approaches to providing confidentiality, from mathematical algorithms to physical protection that will scramble the data in an incomprehensible mode.

  • Data integrity represents a service that deals with the unauthorized alteration of data. In order to assure the integrity of the data, one needs to have the ability to detect data manipulation by parties that are unauthorized.

  • Authentication represents a service that occupies an important role in the authentication of the data or application and that deals with identification . The function is applied on both sides of the entity that deals with the information. It is necessary that both parties that are participating in the communication present their identity to each other (the parties involved could be a person or a system). The information that is delivered and transferred over a communication channel should be certified as to origin, data content, time sent, etc. Based on these reasons, this aspect of cryptography is divided in two major subfields: authentication of the entity and data origin authentication . The data origin authentication offers data integrity.

  • Non-repudiation is represented by a service that helps prevent an entity from denying previous actions.

When a conflict exists because an entity denies certain actions were taken, there is a sinew that can resolve the situation that is necessary.

One of the fundamental goals of cryptography is to make sure that the four areas listed above are addressed properly on both sides, theory and practice.

The book will describe a number of fundamental cryptographic tools , also known as primitives , which are used in providing information security. Examples of primitives are described as encryption schemes (Definition 1.5 and 1.8), hash functions (Definition 1.9), and schemes for digital signatures (Definition 1.6). In Figure 1-1, we have provided a schematic depiction of the cryptographic primitives and how they intersect and relate. Many of the cryptographic primitives depicted in Figure 1-1 are covered in this book, followed by practical implementations. The primitives should pass through an evaluation process with respect for the following criteria:
  • Level of security. The level of security is quite difficult when we have to quantify it. It can be seen as the number of operations necessary to defeat the proposed objective. Usually the level of security is defined based on the volume of work that is necessary to defeat the objective.

  • Functionality. In order to meet different information security objectives, the primitives need to be combined.

  • Operation methods. The primitives, when they are applied in different ways and with different inputs, usually develop different characteristics. One primitive is capable of providing very different functionality that depends on the mode of operation.

  • Performance. The concept of performance refers to the efficiency that a primitive can offer in a specific and particular mode of operation.

  • Ease of implementation. This concept represents a process more than a criterion of achieving the primitive in practical usage.

../images/493660_1_En_1_Chapter/493660_1_En_1_Fig1_HTML.png
Figure 1-1

Cryptographic primitives taxonomy

The importance of various criterions depends very much on the application and resources that are available.

Cryptography has been seen as an art practiced by many practitioners and professionals who have conceive different ad-hoc techniques with the goal of meeting important information security requirements. In the last twenty years, we have seen a period of transition of the discipline from art to science. Currently, there are a couple of very important scientific and practical international conferences that are entirely dedicated to cryptography. The International Association for Cryptologic Research (IACR) aims to promote the best results of research in the area.

This book is about cryptography and cryptanalysis, implementing algorithms and mechanisms with respect for standards.

Background of Mathematical Functions

This book does not represent a monograph on abstract mathematics. Getting familiar with some basic and fundamental mathematical concepts is necessary and will prove to be very useful in practical implementations. A very important concept that is fundamental to cryptography is based on a function in the mathematical sense. A function is also known as a transformation or mapping .

Functions – 1-1, One-Way, Trapdoor One-Way

We will consider as concept, a set that is based on distinct objects which are known as elements of that specific set. Let’s consider as an example set A, which has the elements a, b, c, this being denoted as A = {a, b, c}.

Definition 1.1. Cryptography represents the study of mathematical techniques that are related to the aspects of information security such as confidentiality, integrity (data), authentication (entity), and authentication of the data origin.

Definition 1.2. Two sets, A and B, and a rule, f, define a function. The rule f will assign to each element in A an element in B. The set A is known as the domain that characterizes the function and B represents the codomain. If a represents an element from A, written as a ∈ A, the image of a is represented by the element in B with the help of rule f; the image b of a is noted by b = f(a). The standard notation for function f from set A to set B is represented as f : A → B. If b ∈ B, and then we have a preimage of b, which is an element a ∈ A for which f(a) = b. The entire set of elements in B, which has at least one preimage, is known as the image of f, noted as Im(f).

Example 1.3. (function) Consider the sets A = {a, b, c} and B = {1, 2, 3, 4}, and the rule f from A to B as being defined as f(a) = 2, f(b) = 4, f(c) = 1. Figure 1-2 shows a depiction of the sets A, B and the function f. The preimage of the element 2 is a. The image of f is {1, 2, 4}.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig2_HTML.jpg
Figure 1-2

Function f from a set A formed from three elements to a set B formed from five elements

Example 1.4. (function) Let’s consider the following set of A = {1, 2, 3, ……, 10} and consider f to be the rule that for each a ∈ A, f(a) = ra, where ra represents the remainder when a2 is being divided by 11.
$$ f(1)=1kern2.75em f(6)=3 $$
$$ f(2)=3kern2.75em f(7)=5 $$
$$ f(3)=9kern2.75em f(8)=9 $$
$$ f(4)=5kern2.75em f(9)=4 $$
$$ f(5)=3kern2.25em f(10)=1 $$

The image of f is represented by the set Y = {1, 3, 4, 5, 9}.

Think of the function in terms of the scheme (in the literature, it’s known as the functional diagram ) as depicted in Figure 1-2, where each element from domain A has precisely one arrow originating from it. For each element from codomain B we can have any number of arrows as being incidental to it (including also zero lines).

Example 1.5. (function) Let’s consider the following set defined as A = {1, 2, 3, …, 1050} and consider f to be the rule f(a) = ra, where ra represents the remainder in the case when a2 is divided by 1050 + 1 for all a ∈ A. In this situation, it is not feasible to write down f explicitly as we did in Example 1.4. This being said, the function is completely defined by the domain and the mathematical description that characterize the rule f.

1-1 (One-to-One) Functions

Definition 1.6. We can say that a function or transformation is 1 − 1 (one-to-one) if each of the elements found within the codomain B are represented as the image of at most one element in the domain A.

Definition 1.7. We can say that a function or transformation is onto if each of the elements found within the codomain B represents the image of at least one element that can be found in the domain. At the same time, a function f : A → B is known as being onto if Im(f) = B.

Definition 1.8. If function f : A → B is to be considered 1 − 1 and Im(f) = B, and then the function f is called bijection.

Conclusion 1.9. If f : A → B is considered 1 − 1, then f : A →  Im (f) represents the bijection. In special cases, if f : A → B is represented as 1 − 1, and A and B are represented as finite sets with the same size, then f represents a bijection.

Based on the scheme and its representation, if f represents a bijection, then each element from B has exactly one line that is incidental with it. The function shown and described in Examples 1.3 and 1.4 does not represent bijections. As you can see in Example 1.3, element 3 doesn’t have the image of any other element that can be found within the domain. In Example 1.4, each element from the codomain is identified with two preimages.

Definition 1.10. If f is a bijection from A to B, then it is a quite simple matter to define a bijection g from B to A as follows: for each b ∈ B we will define g(b) = a where a ∈ A and f(a) = b. The function g is obtained from f and it is called an inverse function of f and is denoted as g = f−1.

Example 1.11. (inverse function) Let’s consider the following sets of A = {a, b, c, d, e} and Y = {1, 2, 3, 4, 5}, and consider the rule f which is given and represented by the lines in Figure 1-3. f represents a bijection and its inverse, g, is formed by reversing the sense of the arrows. The domain of g is represented by B and the codomain is A.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig3_HTML.jpg
Figure 1-3

Representation of bijection f and its inverse, g = f−1

Keep in mind that if f represents a bijection, f−1 is also a bijection. The bijections in cryptography are used as tools for message encryption and inverse transformations are used for decryption. The fundamental condition for decryption is for transformation to be bijections.

One-Way Functions

In cryptography, there are a certain types of functions that play an important role. Due to the rigor, a definition for one-way function is given as follows.

Definition 1.12. Let’s consider function f from set A to set B that is called a one-way function if f(a) proves to be simple and easy to be computed for all a ∈ A but for “essentially all” elements b ∈  Im (f) it is computationally infeasible to manage to find any a ∈ A in such way that f(a) = b.

Note 1.13. This note represents some additional notes and clarifications of the terms used in Definition1.12.
  1. 1.

    For the terms easy and computationally infeasible a rigorous definition is necessary but it will distract the attention from the general idea that is being agreed. For the goal of this chapter, the simple and intuitive meaning is sufficient.

     
  2. 2.

    The phrase “essentially all” refers to the idea that there are a couple of values b ∈ B for which it is easy to find an a ∈ A in such way that b = f(a). As an example, one may compute b = f(a) for a small number of a values and then for these, the inverse is known by a table look-up. A different way to describe this property of a one-way function is as follows: for any random b ∈  Im (f), it is computationally feasible to have and find any a ∈ A in such way that f(a) = b.

     

The following examples show the concept behind a one-way function.

Example 1.14. (one-way function) Consider A = {1, 2, 3, …, 16} and let’s define f(a) = ra for all the elements a ∈ A where ra represents the remainder when 3x will be divided with 17.

a

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

f(a)

3

9

10

13

5

15

11

16

14

8

7

4

12

2

6

1

Having a number between 1 and 16, it is quite easy to look and find the image of it under f. Without having the table in front of you, for example, for 7 it is hard to find a given that f(a) = 7. If the number that you are given is 3, then is quite easy to see that a = 1 is what you actually need.

Keep in mind that this represents an example that is based on very small numbers. The important aspect here is that there is a difference in the volume of work to compute f(a) and the amount of work to find a given f(a). Also, for large numbers, f(a) can be efficiently computed using the square-and-multiply algorithm [20], where the process of finding a from f(a) is harder to find.

Example 1.15. (one-way function) A prime number represents a positive integer bigger than 1 whose positive integer divisors are 1 and itself. Choose the following primes of p = 50633, q = 58411, compute n = pq = 50633 · 58411 = 2957524163, and let’s consider A = {1, 2, 3, …, n − 1}. We define a function f on A by f(a) = ra for each a ∈ A, where ra represents the remainder when x3 is divided by n. For example, let’s consider f(2489991 = 1981394214 since 24899913 = 5881949859 · n + 1981394214. Computing f(a) represents a simple thing to be done, but reversing the procedure is quite difficult .

Trapdoor One-Way Functions

Definition 1.16. A trapdoor one-way function is defined as a one-way function f : A → B with the additional property that by having extra information (known as trapdoor information) it will become feasible to find and identify any given b ∈  Im (f), with an a ∈ A in such way that f(a) = b.

In Example 1.15, we show the concept of a trapdoor one-way function. With extra information about the factors of n = 2957524163 it will become much easier to invert the function. The factors of 2957524163 are large enough that finding them by hand computation would be difficult. With the help of any computer software we can find the factors quite quickly. If, for example, we have very large distinct prime numbers (each number having around 200 decimal digits), p and q, with today’s technologies, it’s quite difficult even with the most powerful computers to find p and q from n. This is the well-known problem entitled as integer factorization problem, which for quantum computers will not represent an issue.

One-way and trapdoor one-way functions represent the basic foundation for public-key cryptography. These concepts are very important and they will become much clearer later when their application to cryptographic techniques are implemented and discussed. It is quite important to keep these abstract concepts from this section in mind as the concrete methods and the main foundation for the cryptography algorithms that will be implemented later within this book.

Permutations

Permutations represent functions that are in cryptographic constructs.

Definition 1.17. Consider S to be a finite set formed of elements. A permutation p on S represents a bijection as defined in Definition 1.8. The bijection is represented from S to itself as p : S → S.

Example 1.18. This example represents a permutation example. Let’s consider the following permutation: S = {1, 2, 3, 4, 5}. The permutation p : S → S is defined as follows:
$$ p(1)=2,kern0.5em p(2)=5,kern0.5em p(3)=4,kern0.5em p(4)=2,kern0.5em p(5)=1 $$
A permutation can be described in different ways. It can be written as above or as an array as
$$ p=left(egin{array}{ccc}1& 2& 3kern1.25em 4kern1.5em 5\ {}3& 5& 4kern1.25em 2kern1.5em 1end{array}
ight), $$

in which the top row of the array is represented by the domain and the bottom row is represented by the image under p as mapping.

As the permutations are bijections, they have inverses. If the permutation is written as an away (second form), its inverse will be very easily to find by interchanging the rows in the array and reordering the elements from the new top row and the bottom row. In this case, the inverse of p is defined as follows:
$$ {p}^{-1}=left(egin{array}{ccc}1& 2& 3kern1.25em 4kern1.5em 5\ {}5& 4& 1kern1.25em 3kern1.5em 2end{array}
ight) $$

Example 1.19. This example represents a permutation example. Let’s consider A to be the set of integers {0, 1, 2, …, p · q − 1} where p and q represent two distinct large primes. We need to suppose also that neither p − 1 nor q − 1 can be divisible by 3. The function p(a) = ra, in which ra represents the remainder when a3 is divided by pq can be demonstrated and shown as being the inverse perumutation. The inverse permutation is computationally infeasible by computers nowadays, unless p and q are known.

Involutions

Involutions are known as functions having their own inverses.

Definition 1.20. Let’s consider a finite set of S and f defined as a bijection S to S, noted as f : S → S. In this case, function f will be noted as the involution if f = f−1. Another way of defining this is f(f(a)) = a for any a ∈ S.

Example 1.21. This example represents an involution case. In Figure 1-4, we depict an example of involution. In Figure 1-4, note that if j represents the image of i, then i represents the image of j.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig4_HTML.jpg
Figure 1-4

Representation of an involution with a set of S with five elements

Concepts and Basic Terminology

When we deal with the scientific study of the cryptography discipline, we see that it was built on hard and abstract definitions born from fundamental concepts. In this section, we will list the most important terms and key concepts that are used in this book.

Domains and Codomains Used for Encryption

  • $$ mathcal{A} $$ is represented as a finite set known as the alphabet of definition. Let’s consider as an example, $$ mathcal{A}=left{0,1
ight} $$, which is the binary alphabet, which is a frequently used as a definition.

  • $$ mathcal{M} $$ represents a set known as the message space. The message space contains the strings of symbols from an alphabet, $$ mathcal{A} $$. As an example, $$ mathcal{M} $$ may contain binary strings, English text, French text, etc.

  • $$ mathcal{C} $$ represents the set known as the ciphertext space. $$ mathcal{C} $$ contains strings of symbols from an alphabet, $$ mathcal{A} $$, which is different from the alphabet defined for $$ mathcal{M} $$. An element from $$ mathcal{C} $$ is called ciphertext .

Encryption and Decryption Transformations

  • $$ mathcal{K} $$ is a set known as the key space. An element within $$ mathcal{K} $$ is known as a key.

  • Each element from $$ mathcal{K} $$, $$ ein mathcal{K} $$, defines a unique bijection from $$ mathcal{M} $$ to $$ mathcal{C} $$ which is noted as Ee. Ee is known as the encryption function or encryption transformation. Keep in mind that Ee has to be a bijection if the process is reversed and a unique clear message is recovered for each distinct ciphertext.

  • For each $$ din mathcal{K} $$, we have Dd, which is a bijection from $$ mathcal{C} $$ to $$ mathcal{M} $$ (for example, $$ {D}_d:mathcal{C}	o mathcal{M} $$). Dd is called a decryption function or decryption transformation.

  • When we apply the transformation Ee to message $$ min mathcal{M} $$, it is usually known as encrypting m or the encryption of m.

  • When we apply the transformation Dd to a ciphertext c, it is known as decrypting c or the decryption of c.

  • The encryption scheme is based on a set, $$ left{{E}_e:ein mathcal{K}
ight} $$, that represents the encryption transformations and a corresponding set, $$ left{{D}_d:din mathcal{K}
ight} $$, which are the decryption transformations that have the property that for each $$ ein mathcal{K} $$ there is a unique key $$ din mathcal{K} $$ in such that $$ {D}_d={E}_e^{-1} $$; so Dd(Ee(m)) = m for all $$ min mathcal{M} $$. The encryption scheme is also referred to as a cipher.

  • The keys represented by e and d are in the above definitions known as a key pair and in some documentation are noted as (e, d). In some cases, e and d could be the same.

  • In order to construct an encryption scheme, we must select a message space $$ mathcal{M} $$, a ciphertext $$ mathcal{C} $$, a key space $$ mathcal{K} $$, a set of encryption transformations $$ left{{E}_e:ein mathcal{K}
ight} $$, and a corresponding set of decryption transformations $$ left{{D}_d:din mathcal{K}
ight} $$.

The Participants in the Communication Process

Starting with Figure 1-5 the following terminology is defined:
  • An entity or party represents someone or something who sends, receives, or manipulates the information. In Figure 1-5, Alice and Bob are represented as entities or parties, as computers, etc.

  • A sender represents an entity in a two-party communication. It represents the rightful transmitter of the information. In Figure 1-5, the sender is represented by Alice.

  • A receiver represents an entity in a two-party communication. It represents the intended recipient of information. In Figure 1-5, the receiver is represented by Bob.

  • An adversary (attacker, or sometimes for simplifying the examples it is referred as Oscar or Eve1) represents an entity in a two-party communication. It is neither the sender nor the receiver. The adversary tries to break the information security service that serves as a service provided between the sender and receiver. Other names for the adversary found in the literature are enemy, attacker, opponent, eavesdropper, intruder, and interloper. Often, the adversary will play the role of either the rightful sender or the rightful receiver.

../images/493660_1_En_1_Chapter/493660_1_En_1_Fig5_HTML.jpg
Figure 1-5

Two-party communication process using encryption

Digital Signatures

In this book, we will deal with digital signatures as well. A digital signature represents a cryptographic primitive that is fundamental in the process of authentication, authorization, and non-repudiation. The goal of a digital signature is to offer a way for an entity to map its identity with a piece of information. The process of signing implies the transforming of the message and a part known as secret information that is held by the entity into a tag known as the signature.

A general description is as follows:
  • $$ mathcal{M} $$ represents the set of messages that have the possibility to be signed.

  • $$ mathcal{S} $$ represents the set of elements known as signatures. The signatures can be binary strings with a fixed length.

  • $$ {mathcal{S}}_A $$ is defined as a transformation from the set of messages $$ mathcal{M} $$ to the set of signatures $$ mathcal{S} $$, known as a signing transformation for entity A (Alice). The $$ {mathcal{S}}_A $$ is stored as a secret by A and is used to create signatures for the messages from $$ mathcal{M} $$.

  • VA represents a transformation from the set $$ mathcal{M}	imes mathcal{S} $$ to the set {true, false}. $$ mathcal{M}	imes mathcal{S} $$ consists of all pairs (m, s) where $$ min mathcal{M} $$ and $$ sin mathcal{S} $$, known as the Cartesian product of $$ mathcal{M} $$ and $$ mathcal{S} $$. VA is a transformation that can be used as a verification process for the signatures of A, is known as public, and is used by different entities in order to verify the signatures created by A.

Signing Procedure

We will use an entity A, which we will name as the signer. We will create a signature for a specific message $$ min mathcal{M} $$ by applying the following messages:
  • Calculate s = SA(m).

  • Send the pair (m, s), where s represents the signature for the message m.

Verification Procedure

In order to verify that a signature s for a message m is created by A, another entity B (known as Bob), who plays the verifier role, performs the following steps :
  • Get the function of verification for VA of A.

  • Calculate u = VA(m, s).

  • Agree on the signature that has been created by A if u = true and deny the signature if u = false.

Public-Key Cryptography

Public-key cryptography plays an important role in .NET and when we need to implement related algorithms. There are several important commercial libraries that implement public-key cryptography solutions for developers, such as [21-30].

To understand better how public-key cryptography works, let’s consider a of encryption transformations defined as $$ left{{E}_e:ein mathcal{K}
ight} $$ and a set of matching decryption transformations defined as $$ left{{D}_d:din mathcal{K}
ight} $$, where $$ mathcal{K} $$ represents the key space. Take into consideration the following pair association of encryption/decryption transformations (Ee, Dd) and let’s suppose that each pair has the property of knowing Ee that is computationally unrealizable, having a random ciphertext $$ cin mathcal{C} $$ to manage to identify the message $$ min mathcal{M} $$ in such way that Ee(m) = c. The property defined involves that for any given e it is unrealizable to determine the corresponding decryption key d.

Having the assumptions made above, let’s consider a two-party communication between Alice and Bob as illustrated in Figure 1-6.
  • Bob will select a key pair (e, d).

  • Bob will send the encryption key e, known as the public key, to Alice over any channel and will keep the decryption key, d, known as the private key, secure and secret.

  • Alice, afterwards, will send a message m to Bob by applying the encryption transformation that is computed and determined by Bob’s public key in order to get c = Ee(m). Bob will decrypt the ciphertext c by using the inverse transformation Dd which is determined uniquely by d.

../images/493660_1_En_1_Chapter/493660_1_En_1_Fig6_HTML.jpg
Figure 1-6

The process of encryption using public-key mechanism

The encryption key e does not need to be kept secret. It may be made public. Any entity can send encrypted messages to Bob, and only Bob has the ability to decrypt them. Figure 1-7 illustrates the idea where A1, A2, and A3 represent different entities. Remember if A1 destroys message m1 after encrypting it to c1, then even A1 is found in the position of not being able to recover m1 from c1.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig7_HTML.jpg
Figure 1-7

How public-key encryption is used

To make it clear, let’s consider as an example a box with the cover secured by a lock with a specific combination. Bob is the only one who knows the combination. If the lock remains unlocked for any reason and is thus publicly available, anyone can get inside the box and leave a message inside and lock the lock.

Hash Functions

.NET offers the HashAlgorithm class , which is part of the namespace System.Security.Cryptography [19]. The class represents the base class that needs to be used when all implementations of cryptographic hash algorithms must derive.

As an example (see Figure 1-8 and Listing 1-1), the following C# code example will compute the SHA1CryptoServiceProvider hash for a specific array. This example is based on the assumption that we have already a predefined byte array dataArray[]. SHA1CryptoServiceProvider represents a class that is derived from HashAlgorithm:
HashAlgorithm sha = new SHA1CryptoServiceProvider();
byte[] result = sha.ComputeHash(dataArray);
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig8_HTML.jpg
Figure 1-8

SHA256 example of implementation

Hash functions represent one of the most important primitives in modern cryptography. A hash function is also known as a one-way hash function. A hash function represents a computationally efficient function mapping the binary string with an arbitrary length to binary strings with a fixed length known as a hash value.

using System;
using System.IO;
using System.Security.Cryptography;
public class Program
{
    public static void Main(String[] args)
    {
        ApplyingHashOverADirectory obj = new ApplyingHashOverADirectory();
        obj.Compute();
    }
}
public class ApplyingHashOverADirectory
{
    public void Compute()
    {
        //if (args.Length < 1)
        //{
        //    Console.WriteLine("There is no directory selected to hash.");
        //    return;
        //}
        Console.Write("Enter the directory path: ");
        //string directory = args[0]; //D:Apps C#Chapter 1 - Cryptography Fundamentals
        string directory = Console.ReadLine();
        if (Directory.Exists(directory))
        {
            //** creating an object as DirectoryInfo
            //** which will represent the
            //** directory selected for hash
            var directories = new DirectoryInfo(directory);
            //** Obtaing the informations of the files from
            //** the directory select as FileInfo objects
            FileInfo[] files_from_directory = directories.GetFiles();
            //** create and SHA256 object and initialize it
            using (SHA256 mySHA256Object = SHA256.Create())
            {
                //** find the hash value for each
                //** of the file from the directory
                foreach (FileInfo file_information in files_from_directory)
                {
                    try
                    {
                        //** for each of the file
                        //** create a file stram
                        FileStream file_stream = file_information.Open(FileMode.Open);
                        //** put the position at
                        //** the beginning of the stream
                        file_stream.Position = 0;
                        //** find the hash of the
                        //** fileStream object
                        byte[] hash_value = mySHA256Object.ComputeHash(file_stream);
                        //** show the name and hash
                        //** value of the file in the console
                        Console.Write($"{file_information.Name}: ");
                        PrintByteArray(hash_value);
                        //** make sure that you close the file
                        file_stream.Close();
                    }
                    catch (IOException e)
                    {
                        Console.WriteLine($$"I/O Exception: { e.Message}");
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        Console.WriteLine($"There is an error with accessing the file: { e.Message}");
                    }
                }
            }
        }
        else
        {
            Console.WriteLine("The directory selected couldn't be located or found. Please, select another one.");
        }
    }
    //** Show the byte array for the
    //** user under a readable structure
    public static void PrintByteArray(byte[] array)
    {
        for (int i = 0; i < array.Length; i++)
        {
            Console.Write($"{array[i]:X2}");
            if ((i % 4) == 3) Console.Write(" ");
        }
        Console.WriteLine();
    }
}
Listing 1-1

C# Implementation of SHA256 for Files

Hash functions are widely used with digital signatures and also within the data integrity. When we are dealing with digital signatures, a long message is usually hashed and only the hash value is signed. The party that will receive the message then will hash the received message, and they will verify that the received signature is correct for this hash value. This will save time and space by signing the message directly, which consists of splitting the message into appropriate-sized blocks and individually signing each block.

Table 1-2 provides a classification of keyed cryptographic hash functions, and Table 1-3 provides unkeyed cryptographic hash functions. Most of the functions are already implemented in .NET within the System.Security.Cryptography namespace and the HashAlgorithm class.
Table 1-2

Keyed Cryptographic Hash Functions

Name

Length of the tag

Type

Bibliography

BLAKE2

Arbitrary

Keyed hash function with prefix-MAC

[31][42]

BLAKE3

Arbitrary

Keyed hash function with supplied initializing vector (IV)

[32]

HMAC

-

-

[33]

KMAC

Arbitrary

Based on Keccak

[34][35]

MD6

512 bits

Merkle tree with NLFSR

[37]

PMAC

-

-

[38]

UMAC

-

-

[39]

Table 1-3

Unkeyed Cryptographic Hash Functions

Name

Length

Type

Bibliography

BLAKE-256

256 bits

HAIFA structure [41]

[40]

BLAKE-512

512 bits

HAIFA structure [41]

[40]

GOST

256 bits

Hash

[43]

MD2

128 bits

Hash

 

MD4

128 bits

Hash

[44]

MD5

128 bits

Merkle-Damgard construction [36]

[45]

MD6

Up to 512 bits

Merkle-tree NLFSR

[37]

RIPEMD

128 bits

Hash

[46]

RIPEMD-128

RIPEMD-256

RIPEMD-160

RIPEMD-320

128 bits

-

160 bits

320 bits

Hash

Hash

Hash

Hash

[46][47][48]

SHA-1

160 bits

Merkle-Damgard construction [36]

[61]

SHA-256

SHA-384

SHA-512

256 bits

384 bits

512 bits

Merkle-Damgard construction

[50][51][54]

[52][54]

[53][54]

SHA-224

224 bits

Merkle-Damgard construction

[55]

SHA-3 (Keccak)

Arbitrary

Sponge function [50]

[56][57]

Whirlpool

512 bits

Hash

[58][59][60]

Case Studies

Caesar Cipher Implementation in C#

In this section, we will give an implementation in C# of a Caesar cipher. The purpose of this section is to illustrate how the mathematical foundations listed above can be useful during the implementation process and the advantages of understanding the basic math mechanisms behind the algorithms. We will NOT focus on the mathematical background of the algorithms in this book. If you want to go deeply into the mathematical background, it is recommended to follow the following references [6-18].

The encryption process used by a Caesar cipher can be represented as modular arithmetic by first transforming the letters into numbers. For this, we will use the following alphabet $$ mathcal{A}=left{A,dots, Z
ight}=25 $$ in such way that A = 0, B = 1, …, Z = 25. The encryption of a letter x is done by a shift n and mathematically can be described as
$$ {E}_n(x)=left(x+n
ight) mathit{operatorname{mod}} 26 $$
The decryption is done in a similar way:
$$ {D}_n(x)=left(x-n
ight) mathit{operatorname{mod}} 26 $$
Let’s start the implementation of the algorithm. In Solution Explorer we have only one single file, StartCaesar.cs (see Figure 1-9).
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig9_HTML.jpg
Figure 1-9

The structure of the Caesar cipher project (main form, Program.cs)

The application (see Figure 1-10 and Listing 1-2) is very simple and easy to interact with.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig10_HTML.jpg
Figure 1-10

Caesar Cipher (encoding and decoding)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleCaesarCipher
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Enter the plaintext/ciphertext: ");
            string text = Convert.ToString(Console.ReadLine());
            Console.WriteLine(" Choose a cryptographic method:");
            Console.WriteLine(" 1 -> Encrypt");
            Console.WriteLine(" 2 -> Decrypt ");
            int option = Convert.ToInt32(Console.ReadLine());
            if (option == 1)
            {
                Console.WriteLine(" Enter the key: ");
                int key = Convert.ToInt32(Console.ReadLine());
                Console.WriteLine("The encryption of text is {0}. ", Encode(text, key));
            }
            if (option == 2)
            {
                Console.WriteLine(" Enter the key: ");
                int key = Convert.ToInt32(Console.ReadLine());
                Console.WriteLine("The decryption of the ciphertext is {0}. ", Decode(text, key));
            }
            Console.ReadKey();
        }
        private static string Encode(string plaintext, int key)
        {
            string alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string final = "";
            int indexOfChar = 0;
            char encryptedChar;
            //Convert/encrypt each and every character of the text
            foreach (char c in plaintext)
            {
                //Get the index of the character from alphabets variable
                indexOfChar = alphabets.IndexOf(c);
                //if encounters an white space
                if (c == ' ')
                {
                    final = final + c;
                }
                //if encounters a new line
                else if (c == ' ')
                {
                    final += c;
                }
                //if the character is at the end of the string "alphabets"
                else if ((indexOfChar + key) > 25)
                {
                    //encrypt the character
                    encryptedChar = alphabets[(indexOfChar + key) - 26];
                    //add the encrypted character to a string every time to get an encrypted string
                    final += encryptedChar;
                }
                else
                {
                    //encrypt the character
                    //add the encrypted character to a string every time to get an encrypted string
                    encryptedChar = alphabets[indexOfChar + key];
                    final += encryptedChar;
                }
            }
            return final;
        }
        private static string Decode(string ciphertext, int key)
        {
            string alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
            string final = "";
            int indexOfChar = 0;
            char decryptedChar;
            //Convert/decrypt each and every character of the text
            foreach (char c in ciphertext)
            {
                //Get the index of the character from alphabets variable
                indexOfChar = alphabets.IndexOf(c);
                //if encounters a white space
                if (c == ' ')
                {
                    final = final + c;
                }
                //if encounters a new line
                else if (c == ' ')
                {
                    final = final + c;
                }
                //if the character is at the start of the string "alphabets"
                else if ((indexOfChar - key) < 0)
                {
                    //decrypt the character
                    //add the decrypted character to a string every time to get a decrypted string
                    decryptedChar = alphabets[(indexOfChar - key) + 26];
                    final = final + decryptedChar;
                }
                else
                {
                    //decrypt the character
                    //add the decrypted character to a string every time to get a decrypted string
                    decryptedChar = alphabets[indexOfChar - key];
                    final = final + decryptedChar;
                }
            }
            //Display decrypted text
            return final;
        }
    }
}
Listing 1-2

Caesar Cipher Implementation

Vigenére Cipher Implementation in C#

The Vigenére cipher (see Figure 1-11 and Listing 1-3) represents one of the classic methods of encrypting the alphabetical text by using a series of different Caesar ciphers that are based on the letters of a keyword. Some documentation shows it as a form of polyalphabetic substitution.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig11_HTML.jpg
Figure 1-11

Vigenére Cipher, encryption and decryption operations

A short algebraic description of the cipher is as follows. The numbers will be taken as numbers (A = 0, B = 1, etc) and an addition operation is performed as modulo 26. The Vigenére encryption E using K as the key can be written as
$$ {C}_i={E}_Kleft({M}_i
ight)=left({M}_i+{K}_i
ight) mathit{operatorname{mod}} 26 $$
and decryption D using the key K as
$$ {M}_i={D}_Kleft({C}_i
ight)=left({C}_i-{K}_i
ight) mathit{operatorname{mod}} 26 $$

in which M = M1Mn is the message, C = C1Cn represents the ciphertext, and K = K1Kn represents the key obtained by repeating the keyword [n/m] times in which m represents the keyword length.

Our implementation has two important files. The file Program.cs contains the functions for encryption and decryption operations. See Figure 1-12.
../images/493660_1_En_1_Chapter/493660_1_En_1_Fig12_HTML.jpg
Figure 1-12

The structure of the Vigenére cipher project

The source code for Program.cs is shown in Listing 1-3.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleVigenereCipher
{
    class Program
    {
        static void Main(string[] args)
        {
            VigenereCipher vigenere_engine = new VigenereCipher();
            //the key used for encryption or decryption
            string key = "apress";
            //the text that will encrypted
            //encrypted value is "WTCGGEEIFEHJEHJ"
            string text_for_encryption = "WELCOMETOAPRESS";
            string ciphertext = "WTCGGEEIFEHJEHJ";
            //You can use also Decrypt
            Console.WriteLine("The text that will be encrypted is: {0}", text_for_encryption);
            Console.WriteLine("The key used is: {0}", key);
            Console.WriteLine("The encryption is {0}. ", vigenere_engine.Encrypt(key, text_for_encryption));
            Console.WriteLine("The decryption is {0}. ", vigenere_engine.Decrypt(key, ciphertext));
            Console.ReadKey();
        }
    }
    class VigenereCipher
    {
        Dictionary<sbyte, char> TheAlphabet = new Dictionary<sbyte, char>();
        public VigenereCipher()
        {
            //Me from the future: wtf lol
            TheAlphabet.Add(0, 'A');
            TheAlphabet.Add(1, 'B');
            TheAlphabet.Add(2, 'C');
            TheAlphabet.Add(3, 'D');
            TheAlphabet.Add(4, 'E');
            TheAlphabet.Add(5, 'F');
            TheAlphabet.Add(6, 'G');
            TheAlphabet.Add(7, 'H');
            TheAlphabet.Add(8, 'I');
            TheAlphabet.Add(9, 'J');
            TheAlphabet.Add(10, 'K');
            TheAlphabet.Add(11, 'L');
            TheAlphabet.Add(12, 'M');
            TheAlphabet.Add(13, 'N');
            TheAlphabet.Add(14, 'O');
            TheAlphabet.Add(15, 'P');
            TheAlphabet.Add(16, 'Q');
            TheAlphabet.Add(17, 'R');
            TheAlphabet.Add(18, 'S');
            TheAlphabet.Add(19, 'T');
            TheAlphabet.Add(20, 'U');
            TheAlphabet.Add(21, 'V');
            TheAlphabet.Add(22, 'W');
            TheAlphabet.Add(23, 'X');
            TheAlphabet.Add(24, 'Y');
            TheAlphabet.Add(25, 'Z');
        }
        private bool CheckIfEmptyString(string Key, string Text)
        {
            if (string.IsNullOrEmpty(Key)
                || string.IsNullOrWhiteSpace(Key))
            {
                return true;
            }
            if (string.IsNullOrEmpty(Text)
                || string.IsNullOrWhiteSpace(Text))
            {
                return true;
            }
            return false;
        }
        public string Encrypt(string Key, string Text)
        {
            try
            {
                Key = Key.ToUpper();
                Text = Text.ToUpper();
                if (CheckIfEmptyString(Key, Text))
                    { return "Enter a valid string"; }
                string ciphertext = "";
                int i = 0;
                foreach (char element in Text)
                {
                    //** if we are having a character
                    //** that is not in the alphabet
                    if (!Char.IsLetter(element))
                        { ciphertext += element; }
                    else
                    {
                        //Obtain from the dictionary TKey by the TValue
                        sbyte T_Order = TheAlphabet.FirstOrDefault
                            (x => x.Value == element).Key;
                        sbyte K_Order = TheAlphabet.FirstOrDefault
                            (x => x.Value == Key[i]).Key;
                        sbyte Final = (sbyte)(T_Order + K_Order);
                        if (Final > 25) { Final -= 26; }
                        ciphertext += TheAlphabet[Final];
                        i++;
                    }
                    if (i == Key.Length) { i = 0; }
                }
                return ciphertext;
            }
            catch (Exception E)
            {
                return "Error: " + E.Message;
            }
        }
        public string Decrypt(string Key, string Text)
        {
            try
            {
                Key = Key.ToUpper();
                Text = Text.ToUpper();
                if (CheckIfEmptyString(Key, Text)) { return "Enter a valid string value!"; }
                string plaintext = "";
                int i = 0;
                foreach (char element in Text)
                {
                    //if the character is not an alphabetical value
                    if (!Char.IsLetter(element)) { plaintext += element; }
                    else
                    {
                        sbyte TOrder = TheAlphabet.FirstOrDefault
                            (x => x.Value == element).Key;
                        sbyte KOrder = TheAlphabet.FirstOrDefault
                            (x => x.Value == Key[i]).Key;
                        sbyte Final = (sbyte)(TOrder - KOrder);
                        if (Final < 0) { Final += 26; }
                        plaintext += TheAlphabet[Final];
                        i++;
                    }
                    if (i == Key.Length) { i = 0; }
                }
                return plaintext;
            }
            catch (Exception E)
            {
                return "Error: " + E.Message;
            }
        }
    }
}
Listing 1-3

Vigenére Implementation

We will continue with the source code analysis as follows. Let’s examine the source code from Program.cs, more precisely the source code behind the two operations that represents the main operations, Encrypt and Decrypt.

The source code for the Encrypt method is show in Listing 1-4.
public string Encrypt(string Key, string Text)
    {
        try
        {
            Key = Key.ToUpper();
            Text = Text.ToUpper();
            if (CheckIfEmptyString(Key, Text))
                { return "Enter a valid string"; }
            string ciphertext = "";
            int i = 0;
            foreach (char element in Text)
            {
                //** if we are having a character
                //** that is not in the alphabet
                if (!Char.IsLetter(element))
                    { ciphertext += element; }
                else
                {
                    //Obtain from the dictionary TKey by the TValue
                    sbyte T_Order = TheAlphabet.FirstOrDefault
                        (x => x.Value == element).Key;
                    sbyte K_Order = TheAlphabet.FirstOrDefault
                        (x => x.Value == Key[i]).Key;
                    sbyte Final = (sbyte)(T_Order + K_Order);
                    if (Final > 25) { Final -= 26; }
                    ciphertext += TheAlphabet[Final];
                    i++;
                }
                if (i == Key.Length) { i = 0; }
            }
            return ciphertext;
        }
        catch (Exception E)
        {
            return "Error: " + E.Message;
        }
    }
Listing 1-4

Source Code for the Encryption Method

The source code for the Decrypt method is shown in Listing 1-5.
public string Decrypt(string Key, string Text)
        {
            try
            {
                Key = Key.ToUpper();
                Text = Text.ToUpper();
                if (CheckIfEmptyString(Key, Text)) { return "Enter a valid string value!"; }
                string plaintext = "";
                int i = 0;
                foreach (char element in Text)
                {
                    //if the character is not an alphabetical value
                    if (!Char.IsLetter(element)) { plaintext += element; }
                    else
                    {
                        sbyte TOrder = TheAlphabet.FirstOrDefault
                            (x => x.Value == element).Key;
                        sbyte KOrder = TheAlphabet.FirstOrDefault
                            (x => x.Value == Key[i]).Key;
                        sbyte Final = (sbyte)(TOrder - KOrder);
                        if (Final < 0) { Final += 26; }
                        plaintext += TheAlphabet[Final];
                        i++;
                    }
                    if (i == Key.Length) { i = 0; }
                }
                return plaintext;
            }
            catch (Exception E)
            {
                return "Error: " + E.Message;
            }
        }
Listing 1-5

Souce Code for the Decryption Method

Conclusion

In this chapter, we provided a short introduction to the fundamentals of the cryptographic primitives and mechanisms. The chapter covered the following:
  • Security and information security objectives

  • The importance of the 1-1, one-way and trapdoor one-way functions in designing and implementing cryptographic functions

  • Digital signatures and how they work

  • Public-key cryptography and how it impacts developing applications

  • Hash functions

  • Case studies for illustrating the basic notions that the reader needs to know before advancing to high-level cryptographic concepts

In the next chapter, we will go through the basics of probability theory, information theory, number theory, and finite fields. We will discuss their importance and how they are related during the implementation already existing in .NET and how they are useful for developers.

Bibliography

  1. [1]

    Kahn, David. The Codebreakers: The Story of Secret Writing, 1967.

     
  2. [2]

    W. Diffie and M. Hellman, “New directions in cryptography.” IEEE Trans. Information Theory. 22, 6 (September 2006), 644–654. DOI: https://doi.org/10.1109/TIT.1976.1055638.

     
  3. [3]

    R. L. Rivest, A. Shamir, and L. Adleman, “A method for obtaining digital signatures and public-key cryptosystems,” Communications ACM, vol. 21, no. 2, pp. 120–126, 1978.

     
  4. [4]

    T. ElGamal, “A Public Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms.” In: Blakley G.R., Chaum D. (eds) Advances in Cryptology. CRYPTO 1984. Lecture Notes in Computer Science, vol 196. Springer, Berlin, Heidelberg.

     
  5. [5]

    ISO/IEC 9796-2:2010 – Information Technology – Security Techniques – Digital Signature schemes giving message recovery. Available: www.iso.org/standard/54788.html.

     
  6. [6]

    Bruce Schneier and Phil Sutherland, Applied Cryptography: Protocols, Algorithms, and Source Code in C (Second Edition), ISBN: 978-0-471-12845-8. John Wiley & Sons, Inc., USA. 1995.

     
  7. [7]

    William Stallings, Cryptography and Network Security: Principles and Practice. Upper Saddle River, N.J: Prentice Hall, 1999.

     
  8. [8]

    Douglas R. Stinson, Cryptography: Theory and Practice (First Edition.), ISBN: 978-0-8493-8521-6, CRC Press, Inc., USA. 1995

     
  9. [9]

    Neal Koblitz, A Course in Number Theory and Cryptography. New York: Springer-Verlag, 1994.

     
  10. [10]

    Neal Koblitz and A J. Menezes, Algebraic Aspects of Cryptography, 1999.

     
  11. [11]

    Oded Goldreich, Foundations of Cryptography: Basic Tools. Cambridge: Cambridge University Press, 2001. Print.

     
  12. [12]

    Oded Goldreich, Modern Cryptography, Probabilistic Proofs and Pseudorandomness. Berlin: Springer, 1999. Print.

     
  13. [13]

    Michael G. Luby, Pseudorandomness and Cryptographic Applications. Princeton, NJ: Princeton University Press, 1996. Print.

     
  14. [14]

    Bruce Schneier, Secrets and Lies: Digital Security in a Networked World. New York: John Wiley, 2000.

     
  15. [15]

    Peter Thorsteinson and Arun Ganesh, .NET Security and Cryptography. Prentice Hall Professional Technical Reference, 2003.

     
  16. [16]

    Adrian Atanasiu, Criptografie (Cryptography) – Volume 1, InfoData, 2007, ISBN: 978-973-1803-29-6, 978-973-1803-16-6. Available in Romanian language.

     
  17. [17]

    Adrian Atanasiu, Protocoale de Securitate (Security Protocols) – Volume 2, InfoData, 2007, ISBN: 978-973-1803-29-6, 978-973-1803-16-6. Available in Romanian language.

     
  18. [18]

    Alfred J. Menezes, Scott A. Vanstone, and Paul C. Van Oorschot, Handbook of Applied Cryptography (First Edition). CRC Press, Inc., USA, ISBN: 978-0-8493-8523-0. 1996.

     
  19. [19]
     
  20. [20]

    Henri Cohen, Gerhard Frey, Roberto Avanzi, Christophe Doche, Tanja Lange, Kim Nguyen, and Frederik Vercauteren, Handbook of Elliptic and Hyperelliptic Curve Cryptography, Second Edition (Second Edition). Chapman & Hall/CRC. 2012.

     
  21. [21]

    OpenPGP Library for .NET. Available: www.didisoft.com/net-openpgp/.

     
  22. [22]

    Bouncy Castle .NET. Available: www.bouncycastle.org/csharp/.

     
  23. [23]

    Nethereum. Availble: https://github.com/Nethereum.

     
  24. [24]

    Botan. Available: https://botan.randombit.net/.

     
  25. [25]
     
  26. [26]

    Crypto++. Available: www.cryptopp.com/.

     
  27. [27]
     
  28. [28]

    Libsodium. Available: https://nacl.cr.yp.to/.

     
  29. [29]
     
  30. [30]

    OpenSSL. Available: www.openssl.org/.

     
  31. [31]

    J. Guo, P. Karpman, I. Nikolić, L. Wang, S. Wu, Analysis of BLAKE2. In: Benaloh J. (eds) “Topics in Cryptology – CT-RSA 2014.” CT-RSA 2014. Lecture Notes in Computer Science, vol 8366. Springer, Cham.

     
  32. [32]
     
  33. [33]

    H. Krawczyk, M. Bellare, R. Canetti, “HMAC: Keyed-Hashing for Message Authentication,” RFC 2104, 1997.

     
  34. [34]
     
  35. [35]

    John Kelsey, Shu-jen Chang, Ray Perlner, SHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash, NIST Special Publication 800-185, National Institute of Standards and Technology, December 2016.

     
  36. [36]

    I.B. Damgard, “A design principle for hash functions,” LNCS 435 (1990), pp. 516-527.

     
  37. [37]

    Ronal L. Rivest, “The MD6 hash function. A proposal to NIST for SHA-3.” Available: http://groups.csail.mit.edu/cis/md6/submitted-2008-10-27/Supporting_Documentation/md6_report.pdf.

     
  38. [38]
     
  39. [39]

    UMAC. Available: http://fastcrypto.org/umac/.

     
  40. [40]
     
  41. [41]

    Eli Biham and Orr Dunkelman, “A Framework for Iterative Hash Functions - HAIFA.” Second NIST Cryptographic Hash Workshop – via Cryptology ePrint Archive: Report 2007/278. 24. 2006.

     
  42. [42]

    BLAKE2 Official Implementation. Available: https://github.com/BLAKE2/BLAKE2.

     
  43. [43]
     
  44. [44]

    Roland L. Rivest, “The MD4 message digest algorithm,” LNCS, 537, 1991, pp. 303-311.

     
  45. [45]

    Roland L. Rivest, “The MD5 message digest algorithm,” RFC 1321, 1992.

     
  46. [46]
     
  47. [47]
     
  48. [48]
     
  49. [49]

    The Sponge and Duplex Construction. Available: https://keccak.team/sponge_duplex.html.

     
  50. [50]

    Henri Gilbert, Helena Handschuh. “Security Analysis of SHA-256 and Sisters.” Selected Areas in Cryptography 2003: pp175–193.

     
  51. [51]
     
  52. [52]
     
  53. [53]
     
  54. [54]

    Descriptions of SHA-256, SHA-384, and SHA-512. Available: www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf.

     
  55. [55]

    A 224-bit One-way Hash Function : SHA 224. Available: www.iwar.org.uk/comsec/resources/cipher/sha256-384-512.pdf.

     
  56. [56]

    Paul Hernandez, “NIST Releases SHA-3 Cryptographic Hash Standard,” 2015.

     
  57. [57]

    Morris J. Dworkin, “SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions”. Federal Inf. Process. STDS. (NIST FIPS) – 202. 2015.

     
  58. [58]

    Paulo S. L. M. Barreto “The WHIRLPOOL Hash Function”. 2008. Archived from the original on 2017-11-29. Retrieved 2018-08-09.

     
  59. [59]

    Paulo S. L. M. Barreto and Vincent Rijmen, “The WHIRLPOOL Hashing Function.” 2003. Archived from the original (ZIP) on 2017-10-26. Retrieved 2018-08-09.

     
  60. [60]
     
  61. [61]

    Xiaoyun Wang, Yiqun Lisa Yin, and Hongbo Yu, Finding Collisions in the Full SHA-1, Crypto 2005.

     
  62. [62]

    Shor’s Algorithm. Available online: https://en.wikipedia.org/wiki/Shor%27s_algorithm.

     
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.50.188