1
Chapter 1
INTRODUCTION
1.1 Overview
Today’s world is growing with the technology and power. The growth of the
world depends on communication. This means, communication is growing exponentially.
As the growth of the communication increases, the need for its security also increases in
the same manner. In the last century, communication over the telephone was very limited.
It was only for the short distance communication. Today, one can handle his entire
business in a different country or continent by sitting in the comforts of his office
elsewhere. Here comes the role of security of data. When we talk about the
confidentiality of the data, the best technique that one can point out to is Cryptography.
Cryptography is the best technique to shield the integrity and the confidentiality
of the message stream or data transmitted on communication channel or network [4]. In
simple words, we can say, cryptography is an algorithm that enables us to have a secure
communication between the transmitter and the receiver. Cryptography contains
mathematical operations designed to guard data communication [4]. Mainly,
cryptography is based on mathematical techniques to modify the data. If the original
message bits are converted in some random message bits and transmitted over a
communication channel then if some person intercepts the message or overhears the
message, he would not be able to figure out the exact message that was sent by the
transmitter due to its randomness. We can come up with this randomness of data by
applying some mathematical operation such as multiplication, addition, and
2
transformation. It involves encryption and decryption as back bones of the entire
algorithm.
Encryption: Encryption is the process where data gets encrypted which means the
message to be sent is converted into another message stream. The new message stream
contains the original data bits as well as some pseudo bits to hide the original message
from unwanted entities.
Decryption: Decryption is the process where the encrypted message stream is
converted back to the original message bits. The original message bits can be retrieved
back by discarding the pseudo bits those are being merged while encrypting the original
message.
A Conventional Cryptosystem has the following five major terminologies:
Plaintext – The plaintext is the original message bits that are to be transferred securely
between two parties.
Encryption Algorithm – The encryption algorithm execute different mathematical
application and transformation on the plain text.
Key(s) – Key can be described as some particular critical data utilized by the user at the
transmitter side to encrypt the data and also utilized by the user at receiver side to decrypt
the data.
Cipher – Cipher is an algorithm to convert the plaintext into the coded message stream by
performing some mathematical steps such as multiplication, addition, and substitution.
3
Ciphertext – Ciphertext is the processed plaintext by applying an algorithm known as
cipher using the Key. In short, ciphertext is the secured message that is to be transmitted
over the communication channel.
Decryption Algorithm – Decryption algorithm is the reverse engineering algorithm to
retrieve back the original message bits using the ciphertext, and the key.
There are two constraints for protected use of conventional encryption.
1. Strong Encryption Algorithm
2. Security of Key
Encryption Algorithm: We require a strong encryption algorithm that means we have
to have an encryption algorithm such as a person who knows the algorithm and have the
access of few or more cipher text cannot decipher other cipher texts that are unknown to
him. The strength of an encryption algorithm is defined on the basis of the level of access
of the algorithm and the cipher techniques.
Security of Key: We require a most excellent security for our Key that is being
used to encrypt the data. If someone got to know about the key and if he can access it and
also he does know the algorithm then he can read as well as modify the whole
communication. Thus, the communication is no longer private or confidential. Therefore,
the users must keep the key top secret [1].
It is very vital to keep the key secret because the confidentiality of the key
impacts more on the private communication than the privacy of the algorithm because if
someone knows the algorithm and does not know the key then he cannot access the
communication. Instead if he knows the key that is being used to encrypt the message
4
stream then he can easily read the message and also he might change the message and
send a counterfeit message to mislead the user at the other of the communication channel.
Thus, we can say that privacy of the key is more important than the secrecy of the
encryption algorithm [1].
Today, private key cryptosystem and public key cryptosystem are the most
commonly used cryptosystems.
1.2 Private Key Cryptosystem
Encryption
Decryption
Symmetric Key
Original Data
728492292
4389422
728492292
4389422
#4!&$*3
92p432
%$#123*
7&
Symmetric Key
Scrambled Data
Original Data
Figure 1: Private Key Cryptosystem
Private Key: This kind of key is also known as conventional key or single key or
symmetric key. In such algorithm symmetric ciphers are used to encrypt the message bits.
The message bits are encrypted using a key and the same key can be used to decrypt the
message. This means the knowledge of just one key does the encryption as well as
decryption. Therefore, in such system the key must be secret between the end users.
Private-key encryption methodology can provide a good level of substantiation.
The data encrypted using a key cannot be decrypted using another key. One needs to have
the exact same cipher to decrypt the transferred data. Thus, if the symmetric key is kept
5
clandestine between the end users, they can be sure that their communication is secured.
They can get confidential and correct data as long as the communication channel works
fine and the data travels unaffected.
Private-key encryption is efficient only when the symmetric key is kept top secret
by the end users involved in the communication. If the third person somehow identifies
the key, it affects not only the confidentiality but also the data. A third party, with the
knowledge of the symmetric key, can not only decrypt the message, but he can also send
the false data mimicking that he is the one of the end users.
The Data Encryption Standard (DES) and the Advanced Encryption Standard
(AES) are the examples of this encryption system.
1.3 Public Key Cryptosystem
Encryption
Decryption
Public Key
Original Data
7284922
9243894
22
7284922
9243894
22
#4!&$*
392p43
2%$#12
3*7&
Private Key
Scrambled Data
Original Data
Figure 2: Public Key Cryptosystem
Public-key cryptosystem is the system in which awareness of encryption key
gives no indication about the decryption key. The public-key cryptosystem uses
asymmetric ciphers. Since there are different keys to encrypt and decrypt the data, it
gives more secured communication. In public-key cryptosystem, each end user has his
6
own private key and a public key. Public key can be known by anyone. To encrypt and
decrypt the message bits, the private key as well as the public key, both are used.
The methodology depicted in the above figure, lets you liberally dispense a public
key, and you will be capable to read data encrypted using this key. To transfer the data to
another person, one encrypts the message stream using his public key, and the person
receives the encrypted message. He decrypts the received message bits with the
appropriate private key. This is how, the whole algorithm work: data encrypted with the
private key “A” can only be decrypted with the appropriate public key “B”. (Private-key
“A” corresponds to public key “B”).
Compared with private-key encryption, public-key encryption requires more
computation and is therefore not always appropriate for large amounts of data.
The NTRU, RSA, and ECC are the examples of this encryption system.
1.4 NTRU Public Key Cryptosystem
Public-Key Cryptosystem, named NTRU stands for Number Theorist Research
Unit. NTRU is ring-based cryptosystem. NTRU was set up in 1996 and turned in to an
absolutely efficient company in 2000. NTRU was recently taken over by
SecurityInnovation, an application security company. NTRU is comparatively a new
cryptography technique that is known to be more proficient than the existing and more
extensively used public-key cryptosystem like RSA. In contrast to RSA, NTRU
necessitates approximately 0(
needs 0(
) process steps and a key length of 0(N), whereas RSA
) process steps and a key length of 0(
). For this reason, NTRU has lesser
complexity and its key size scales at slower rate. NTRU has lesser number of
7
multiplications for encryption and decryption. Hence, it can be implemented more
resourcefully than RSA. As a result this cryptosystem is showing more potential choice to
the more established public-key cryptosystem.
The core of NTRU is designed over an integer ring. Key creation, encryption, and
decryption are the most time consuming processes which point out the multiplication of
two polynomials defined over an integer ring (described with more feature in the
following section). The time consuming operation is the multiplication of the
polynomials. If we are able to save some time for the multiplication or else we can say
that if we speed up the multiplication process then we can come up with the improved
performance of the NTRU system. For that, it is essential to develop software algorithm
or a hardware speed up mechanism such as pipelining. At this point, few software and
hardware implementations are published. It is a well growing field in the field of
communication security.
To understand the mechanism or the process steps of encryption and decryption in
NTRU, first we need to be aware of the algorithm that controls the flow of the process
and how the information gets processed in order to secure the communication between
two parties. Person, who reads, should know polynomial algebra and number theory that
is being used in this project to create a key, encrypt the data and to decrypt the data. The
polynomial courses are described in the next chapter in depth.
8
Chapter 2
POLYNOMIAL ALGEBRA AND NUMBER THEORY

Modular Arithmetic [3]
Modular arithmetic is simply division with remainder, where you keep the remainder and
throw everything else away. For example,
a = b (modulo m)
simply means that a when divided by m leaves the remainder b. This is the same as
saying that the difference a-b is a multiple of m. The integer m is called the modulus of
the congruence [3].

Truncated Polynomial Rings [3]
The principal objects used by the NTRU are polynomials of degree N-1 having integer
coefficients:
a = a0 + a1X + a2X2 + a3X3 + . . . + aN-2XN-2 + aN-1XN-1.
The coefficients a0,...,aN-1 are integers. Some of the coefficients are allowed to be 0.
The set of all such polynomials is denoted by R.
The polynomials in R are added together in the usual way by simply adding their
coefficients:
a + b = (a0+b0) + (a1+b1)X + . . . + (aN-1+bN-1)XN-1.
They are also multiplied in almost the usual manner, with one change. After doing the
multiplication, the power XN should be replaced by 1, the power XN+1 should be replaced
by X, the power XN+2 should be replaced by X2, and so on [3].
9
Example : Suppose N=3, and take the two polynomials a = 2–X+3X2and b =1+2X-X2.
Then
a + b = (2-X+3X2) + (1+2X-X2) = 3+X+2X2 and
a*b = (2-X+3X2)*(1+2X-X2) = 2+3X-X2+7X3-3X4 = 2+3X-X2+7-3X = 9-X2.
The following is the general formula for multiplying polynomials in R:
a*b = c0 + c1X + c2X2 + c3X3 + . . . + cN-2XN-2 + cN-1XN-1,
where the kth coefficient ck is given by the formula
ck = a0bk + a1bk-1 + . . . + akb0 + ak+1bN-1 + ak+1bN-2 + . . . aN-1bk+1.
In modern terminology, R is called the Ring of Truncated Polynomials Z[X]/(XN-1) [3].
The NTRU PKCS uses the ring of truncated polynomials R combined with the modular
arithmetic described earlier. These are combined by reducing the coefficients of a
polynomial a modulo an integer q. Thus the expression
a (modulo q)
means to reduce the coefficients of a modulo q. That is, divide each coefficient by q and
take the remainder [3].
To make storage and computation easier, it is convenient to just list the coefficients of a
polynomial without explicitly writing the powers of X. For example, the polynomial
a = a0+ a1X + a2X2 + a3X3 + . . . + aN-2XN-2 + aN-1XN-1
is conveniently written as the list of N numbers: a = (a0, a1, a2, . . . ,, aN-2, aN-1 ).
Note that zeros should be included in the list if some of the powers of X are missing. For
example, when N = 7 the polynomial a = 3+2X2-3X4+X6 is stored as the list (3,0,2,0,3,0,1). But if N = 9, then a would be stored as the list (3,0,2,0,-3,0,1,0,0) [3].
10

Inverses in Truncated Polynomial Rings
The inverse modulo q of a polynomial a is a polynomial A with the property that
a*A = 1 (modulo q)
Not every polynomial has an inverse modulo q, but it is easy to determine if a has an
inverse, and to compute the inverse if it exists [3].
Example: Take N=7, q=11, a = 3+2X2-3X4+X6.
The inverse of a modulo 11 is A= -2+4X+2X2+4X3-4X4+2X5-2X6, since
(3+2X2-3X4+X6)*(-2+4X+2X2+4X3-4X4+2X5-2X6) = -10+22X+22X3-22X6 = 1 (modulo
11).
The next chapter will explain the complete process involved in NTRU [3].
11
Chapter 3
DESIGN OF NTRU PKCS
This section explains the architecture of the NTRU system built in this project
starting from the smallest unit in the design and moving up higher to the bigger blocks.
The NTRU system basically consists of three blocks: Key Creator, Encryptor and
Decryptor. All the 3 blocks use polynomial multiplication and hence, it is important to
choose a fast multiplication algorithm that will quickly multiply the polynomials,
yielding an effective design.
3.1 NTRU Multiplier Design [2]
NTRU is based on polynomial additions and multiplications in the ring R
Z[X]/(XN-1), as explained earlier. Polynomial multiplication is the cyclic convolution of
two polynomials, denoted by ‘*’. The NTRU multiplier designed here has a scalable
architecture and to explain this architecture, we shall consider the following parameter
values: p=3, q =256, N = 5.
The partial product array shown below is parallel in nature, this is because since
the polynomials in the multiplication are all reduced modulo XN-1, all the partial product
terms are exceeding the degree XN-1 after being reduced modulo XN-1, will be added back
to the lower portion of the partial product array. Look at the illustration belowSince each partial product term is reduced modulo q, the carry propagation is
confined within each column but not across the columns. This eliminates the need to
propagate the carry across columns.
Consider,
12
a = a0 + a1X + a2X2 + a3X3 + a4X4 and
{each ai is a 8-bit coefficient-since
q=256 }
b = b0 + b1X + b2X2 + b3X3 + b4X4
{each bi is a 2-bit coefficient-since p=3
}
Now consider the multiplication a*b
Figure 3: Polynomial Multiplication [2]
Thus, the above partial product array gets simplified to the array shown below :
13
Figure 4: Partial Product Array
For the partial product column k, a single processing unit (PU), which will be
explained later, performs the following operation:
c[k] = c[k] + a[i] *b[j] (mod q)
where, j = 0,1,….N-1 and i = -j mod N
This PU consists of one coefficient multiplication, one coefficient addition, and a
reduction modulo q. Each of the partial product terms that have been “boxed” need one
PU for their computation and from the figure above, we see that for a given column we
need 5 PU’s to compute product coefficient.
The next section will explain the design of the Processing Unit (PU)
14
3.2 Processing Unit [2]
The Processing Unit (PU) is the heart of the NTRU multiplier which performs the
following coefficient operation : c[k] = c[k] + a[i] *b[j] (mod q)[2]
We know that b[j], the multiplicand, is a 2-bit coefficient and can either be {1,0,1} and a[i], the multiplier, is any 8-bit coefficient since it is reduced mod q(=256).
c[k], product coefficient is also 8-bit wide since it is reduced mod q(=256) as well [2].
Figure 5: Processing Unit [8]
The PU consists of a coefficient multiplier and an adder, both of which
incorporate the reduction modulo q. The components of the processing unit consist solely
of combinational logic and are not dependent upon a rising edge clock signal. The
coefficient multiplier computes M = a[i] * b[j] (mod q) portion of the operation [2]. The
main hardware consists of eight 2 by 1-bit multipliers, each of which was designed to
behave according to the truth table shown on the next page.
Note that:
a[i]0 = Bit 0 of the 8-bit a[i] coefficient
15
b[j]0 = Bit 0 of the 2-bit b[j] coefficient
b[j]1 = Bit 1 of the 2-bit b[j] coefficient
Ii
= Result of multiplication of a[i]0 and b[j]
Table 1: PU Truth Table [2]
X is nothing but don’t care case.
In the above truth table the values marked by * may seem odd which is explained
below:
This design infers the 2-bit demonstration for b[j] dissimilarly than its decimal equivalent
according to the table shown below [2]:
16
Table 2: PU Integer Value [2]
So for the case b[j] = (11)2 = -1, it is necessary that a[i]0 be converted into it’s 2-s
complement representation in order for the adder to subtract. However, to keep the design
simple, the multiplier only inverts the value of a[i]0 . The two's complement conversion is
completed by setting the carry-in of the adder to `1'. This is accomplished by the AND
gate shown in figure 3.
For the case b[j] = (10)2 = 2, it should be noted that this operation is not
performed by the main hardware of the multiplier as indicated by the don't care (X)
condition in the table. Hence, a multiplexer is needed to pass the left shifted value of a[i] 0
for when b[j] = 2, otherwise for the other 3 combinations of b[j], I is passed to M [2].
The reduction modulo q portion of the equation is handled by ignoring any carries
that exceed the 8-bit boundary, which would only occur for the case b[j] = 2 [2].
The Karnaugh-map for the truth table of I[i] is as follows:
17
Table 3: PU K-map [2]
This gives us the expression for all the I[i]s.
As shown in the figure 4 on the next page, if b[j] = (10)2, the output of the AND
gate is = 1 which makes the selector input of the multiplexer =1 and the left-shifted-by-2
value of a6..0[i] appears at the output of the multiplexer, otherwise the value of I appears
as the output of the multiplexer.
Finally, the output of the multiplexer, M, is passed on to the 8-bit adder for
accumulation which is responsible for computing c[k] = M + c[k]. Again, the reduction
modulo q portion of the equation is handled by ignoring any carries that exceed the 8-bit
boundary.
The 8-by-8 bit adder is a Full adder with the Final carry out ignored.
Figure 6: 8-bit Full Adder
18
Figure 7: Coefficient Multiplier [2]
19
3.3 NTRU Multiplier or PM (Polynomial Multiplier)
Now that the operation of the PU has been fully understood, the next block to be
studied is the NTRU Multiplier in detail (also referred to as Polynomial Multiplier or
PM).
This block consists of COEFF, SHIFTER AND COUNTER blocks
Figure 8: NTRU Multiplier Design
3.3.1 COEFF:
From the above figure, we see that each column can be processed independently.
In this case, each column of partial products consists of 5 PU’s i.e. number of PU’s
needed for a given column=N. Add the output of the previous PU as input carry to the
20
one below it and finally, we arrive at the coefficient of that corresponding column. In this
case, since the product is also reduced modq, this coefficient c[k] is 8-bits too.
3.3.2 SHIFTER AND COUNTER
From the above figure, we see that in each column, the order in which b0 b1 b2 b3
b4 are listed is the same, it is the values of a0 a1 a2 a3 a4 that change their sequence (look at
direction of arrows). This capability has been implemented using a Barrel Shifter, which
is used to shift the multiplier coefficients that are input to the PM, such that partial
products of the next column are computed in the correct order. The size of this shifter
will be 8*4=40 ie, q*N.
To determine how many times the shift needs to be performed, a counter has been
designed. These counter increments with each shift and goes to zero when the shift has to
stop. In this case, we have to shift the coefficients of the multiplier 5 times- which means,
the counter needs to be a 3-bit counter i.e Nlog2-counter. Since each coefficient of the
multiplier is 8bits long, each shift rotates the multiplier by 8 bits.
3.4 Key Creator:
This block creates the public key ‘h’ for each NTRU user. Public key is given as,
h = p.fq*g mod q
,where p=3
This computation is done with two blocks- Constant Multiplier and Polynomial
Multiplier(PM) Constant multiplier (CM)- Multiplies each coefficient of the polynomial
fq with the constant p Polynomial multiplier- Multiplies two polynomials as described
above- output of the CM with g- and reduces the output modulo q, generates public key
h.
21
Figure 9: Key Creator
3.5 NTRU Encryptor:
This block computes the encrypted message for secure data exchange. Encrypted
message is given as,
e = r*h + m (mod q)
Where, r is the random polynomial selected
h is the public key
m is the message to be encrypted.
PM - Multiplies the polynomials r and h
Coefficient adder- adds the output of PM to message m, generates encrypted message e.
Figure 10: NTRU Encryptor
22
3.6 NTRU Decryptor:
This block performs the final and most important operation of the system,
decrypting the received encrypted message. This process is explained as belowStep 1: a = f*e ( mod q )
Step 2: Shift the coefficients of a from (0,q-1) to (-q/2, q/2)
Step 3: b = a ( mod p )
Step 4: c = fp*b (mod p)
Decryption basically involves polynomial multiplication and reduction of the product
mod p. Polynomial multiplication only performs mod q on the product and hence, we
design another block that performs mod p on the output of the PM.
Figure 11: Mult_Mod
The mult_mod block is the basic block of the decryption process.
Step1-3 is performed by one mult_mod block i.e. polynomials f and e are multiplied and
reduced mod p.
For eg, if the result of the multiplication f*e mod q is:
23
a = 3 - 7X - 10X2 - 11X3 + 10X4 + 7X5 + 6X6 + 7X7 + 5X8 - 3X9 - 7X10 (mod
256)
The mult_mod block returns,
b = - X - X2 + X3 + X4 + X5 + X7 - X8 - X10 (mod 3)
[3mod3=0, -7mod3=-1, -10mod3=-1, -11mod3=1, 10mod=1, 7mod3=1, 6mod3=0 etc.]
Next, Step 4: c = fp*b (mod p) is performed by another mult_mod block. The output of
the previous mult_mod block and fp are given as inputs to this block, which agin
performs polynomial multiplication followed by mod p on the product. This result is the
final decrypted message! This message should be equal to the message initially sent.
Figure 12: NTRU Decryptor
24
3.7 NTRU PKCS
A block diagram of the entire cryptosystem with inputs and outputs from the three main
blocks discussed above can be drawn as:
Figure 13: NTRU PKCS
25
Chapter 4
VALIDATION OF NTRU PKCS
4.1 Design Verification
The previous section showed the different steps involved in the design of the NTRU
PKCS. This section will show the implementation and verification of the design with
some examples. Each block of the design has been written in HDL Verilog and compiled
and simulated using VCS Synopsys. A bottom up approach has been used in this design.
Each
block/module
has
been
individually
written
merged/instantiated into another block.
The NTRU PKCS takes the following inputs:
Maximum degree of polynomials, N
Small modulo, p
Big modulo, q
Polynomials f, g
Inverse of f mod p, fp
Inverse of f mod q, fq
Random polynomial, r chosen by message sender
Message polynomial, m sent by sender
To demonstrate the system designed, we use the below inputs
N=11 q= 25=32 p=3.
Let, f = -1 + X + X2 - X4 + X6 + X9 - X10
g = -1 + X2 + X3 + X5 - X8 - X10
and
verified
and
then
26
Let us represent the above polynomials as:
f = {-1,1,1,0,-1,0,1,0,0,1,-1}
g = {-1,0,1,1,0,1,0,0,-1,0,-1}
Each coefficient of a given degree has a fixed position in the array and hence if any
degree is missing, that corresponding coefficient should be represented by a 0.
Since N=11, f and g have 11 coefficients, each 2 bits wide. Hence, f, g are 11*2=22 bits
wide. The inverses of these polynomials are

fp = {1,2,0,2,2,1,0,2,1,2,0}

fq = {5,9,6,16,4,15,16,22,20,18,30 }

fp has 11 coefficients, each 2 bits long, hence fp = 22 bits

fq has 11 coefficients, each 5 bits long, hence fq=55 bits
Using h = pfq *g mod q, the public key is calculated.

The key created h is {8,25,22,20,12,24,15,19,12,19,16}.

h has 11 coefficients, each 5 bits long, hence h=55 bits
Now that the public key is generated, we are ready to encrypt and send a message. To
create this message, we use a LFSR. The LFSR is a Linear Shift Feedback Register that is
used to generate random numbers.

The message generated is, m = {3,0,3,1,0,1,0,0,3,0,3}.

m has 11 coefficients, each 2 bits long, hence m = 22 bits
Using e = pr*h + m, the encrypted message is calculated and transmitted to the receiver.

The encrypted message generated is, e = {14,11,25,24,15,17,30,7,25,5,17}

m has 11 coefficients, each 5 bits long, hence m=55 bits
27
Using b = f*e ( mod p) and c = fp*b (mod p), the received encrypted message is
decrypted

The first mult_mod block generates b = {0,1,3,3,0,3,0,1,3,3,1}

b has 11 coefficients, each 2 bits long, hence b = 22 bits

The decrypted message generated by the second mult_mod block is c =
{3,0,3,1,0,1,0,0,3,0,3}

c has 11 coefficients, each 2 bits long, hence c = 22 bits

This decrypted message, c is the same as the message, m sent by the sender and
hence the NTRU PKCS design is verified!

This system may not function properly only in the case where all the coefficients
of the message to be send are the same
4.2 NTRU PKCS- Testbench
After designing the Key Creator, Encryptor and Decryptor blocks, a unified
testbench module was written, which instantiates the above blocks in it. This way, we can
consider the 3 blocks as part of one system, versus separately providing inputs to each of
them. The values of the input polynomials- f, g, r, the inverses fp, fq are accepted in this
block and passed on to the appropriate sub-module. The testbench also has a clock
generator block that generates the clock signals of a given period.
The testbench contains 3 signals that signify the completion of each stage of the
cryptosystem- key_complete, encrypt_complete, decrypt_complete. These signals
become high after their corresponding stage is complete. Once all the 3 signals are high,
it means that the decryption process is complete. At this point, a comparator block in the
28
testbench checks the sent message and the decrypted message. If they are the same, it
gives out a message showing a successful output, while if they do not match, an
unsuccessful message is sent out.
The output for the case explained in section 5.1 is shown below.
########################################################################
######
####################
NTRU PKCS for N=11 q=5 p=3
#########################
Input polynomials, f= 3 1 1 0 3 0 1 0 0 1 3 g= 3 0 1 1 0 1 0 0 3 0 3
Inverse of f modp, Fp= 1 2 0 2 2 1 0 2 1 2 0 Inverse of f modq, Fq= 5 9 6 16 4
15 16 22 20 18 30
Random polynomials, r = 3 0 1 1 1 3 0 3 0 0 0 Message m= 3 0 0 1 3 0 0 0 3 1 1
########################################################################
######
time = 0: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 0 0 0 0 0 0
0 0 0 0 0
time = 0: key_complete=0 encrypt_complete=0 decrypt_complete= 0 e= 0 0 0 0 0 0
0 0 0 0 0
time = 0: key_complete=0 encrypt_complete=0 decrypt_complete= 0 c= 0 x x x x x x x
xx0
time = 0: key_complete=0 encrypt_complete=0 decrypt_complete= 0 c= 0 0 0 0 0 0 0 0
000
time = 15: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 0 0 0 0 0
0 0 0 0 0
time = 25: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 0 0 0
0 0 0 0 0 0
29
time = 35: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 0 0
0 0 0 0 0 0
time = 45: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 0
0 0 0 0 0 0
time = 55: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 12
0 0 0 0 0 0
time = 65: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 12
24 0 0 0 0 0
time = 75: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 12
24 15 0 0 0 0
time = 85: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 12
24 15 19 0 0 0
time = 95: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20 12
24 15 19 12 0 0
time = 105: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20
12 24 15 19 12 19 0
time = 115: key_complete=0 encrypt_complete=0 decrypt_complete= 0 h= 8 25 22 20
12 24 15 19 12 19 16
time = 120: key_complete=1 encrypt_complete=0 decrypt_complete= 0 h= 0 0 0 0 0
0 0 0 0 0 0
time = 230: key_complete=1 encrypt_complete=1 decrypt_complete= 0 e= 14 11 26 24
14 16 30 7 25 6 19
time = 345: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 0 0 0 0
0000
time = 375: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 1 0 0 0
0000
time = 385: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 1 3 0 0
0000
time = 425: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 1 3 0 0
0300
30
time = 435: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 1 3 0 0
0310
time = 445: key_complete=1 encrypt_complete=1 decrypt_complete= 0 c= 3 0 0 1 3 0 0
0311
time = 450: key_complete=1 encrypt_complete=1 decrypt_complete= 1 c= 0 0 0 1 3 0 0
0310
time = 450: key_complete=1 encrypt_complete=1 decrypt_complete= 1 c= 0 0 0 0 0 0 0
0000
########################################################################
######
###### Success!!! The decrypted message is the same as the original message sent
######
Public key h= 8 25 22 20 12 24 15 19 12 19 16
Message sent m= 3 0 0 1 3 0 0 0 3 1 1
Encrypted message e= 14 11 26 24 14 16 30 7 25 6 19
Decrypted message c = 3 0 0 1 3 0 0 0 3 1 1
###########################################################
##################
The NTRU system was also designed for a more realistic example- for low level of
security. The parameters for this are N=107, p=3, q=64. To make the hardware design
simple and reuse smaller blocks instead of building one big block for N=107, we used a
different approach to design the system for this set of inputs.
We first designed a system for N=7,q=64,p=3. The different polynomials required for this
set are explained below.
f, g, fp, m, r = 7*2 = 14 bits
fq = 7*6 = 42 bits
Key, h = pfq*g (mod 64) = 7*6 = 42 bits
31
Encrypted message, ei = ri*h + mi (mod 64) = 7*6 = 42 bits
Decrypted message, c = 7*2 = 14 bits
Once this was verified, we applied the same design above to calculate the results
for the NTRU low level security parameters. The upper 10 bits of the message were set to
zeros since the actual message to be sent was 107*2=214 bits wide. The message was
split into smaller chunks, each of which was encrypted and decrypted individually to give
the final result. The polynomials in this design are explained below.
N = 16*7=112
f, g, fp, m, r = 16*7*2 = 214 bits (Top 10 bits set to 0)
Key, h = pfq*g (mod 64) = 16*7*6 = 672 bits
Encrypted message, ei = ri*h + mi (mod 64) = 16*7*6 = 672 bits
Decrypted message, c = 16*7*2 = 214 bits (Top 10 bits set to 0)
Hence, the NTRU cryptosystem was verified for different sets of input values.
This system was synthesized using Xilinx ISE Design Suite. The Key creator,
Encryptor and Decryptor blocks were individually synthesized and all the blocks of the
system were found to be perfectly synthesizable, without any issues. The synthesis results
of each of these blocks are included in Appendix C.
32
Chapter 5
SIMULATION RESULTS AND WAVEFORMS
5.1 Low level of security, parameters N=107, q=64, p=3
Chronologic VCS simulator copyright 1991-2008
Contains Synopsys proprietary information.
Compiler version B-2008.12-9; Runtime version B-2008.12-9;
Apr 3 20:11 2010
VCD+ Writer B-2008.12-9 Copyright 2005 Synopsys Inc.
###########################################################
###########################################################
##############
############################################ NTRU PKCS for
N=11 q=5 p=3 ############################################
Input polynomials, f= 0
Inverse of f modp, Fp=
modq, Fq= 9 11 62 13 49
Random polynomials, r =
9177447591388863703
0 1 1 3 0 0 g= 3 1 0 1 3 0 0
1 1 0 1 63 0 63 Inverse of f
29 20
0 3 1 3 3 3 0 Message m=
###########################################################
###########################################################
##############
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 0 0 0 0 0 0 0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 e= 0 0 0 0 0 0 0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 c= 0 x x x x x 0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 c= 0 0 0 0 0 0 0
33
time = 15: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 0 0 0 0 0 0
time = 25: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 0 0 0 0 0
time = 35: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 12 0 0 0 0
time = 45: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 12 50 0 0 0
time = 55: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 12 50 26 0 0
time = 65: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 12 50 26 21 0
time = 75: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 13 62 12 50 26 21 8
time = 85: key_complete=1 encrypt_complete=0
decrypt_complete= 0 h= 0 0 0 0 0 0 0
time = 150: key_complete=1 encrypt_complete=1
decrypt_complete= 0 e= 52 27 25 7 7 0 10
time = 225: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 0 0 0 0
time = 235: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 0 0 0 0 0
time = 245: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 1 0 0 0 0
time = 255: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 1 3 0 0 0
time = 265: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 1 3 0 0 0
time = 275: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 1 3 0 3 0
34
time = 285: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 1 1 3 0 3 1
time = 295: key_complete=1 encrypt_complete=1
decrypt_complete= 1 c= 0 1 1 3 0 3 0
time = 295: key_complete=1 encrypt_complete=1
decrypt_complete= 1 c= 0 0 0 0 0 0 0
###########################################################
###########################################################
##############
###################### Success!!! The decrypted message is
the same as the original message sent
######################
Public key h= 13 62 12 50 26 21 8
Message sent m= 9177447591388863703
Encrypted message e= 52 27 25 7 7 0 10
Decrypted message c= 9177447591388863703
###########################################################
###########################################################
##############
$finish called from file "ntru_pkcs.v", line 131.
$finish at simulation time
320
V C S
S i m u l a t i o n
R e p o r t
Time: 320
CPU Time:
0.070 seconds;
Data structure size:
0.3Mb
Sat Apr 3 20:11:34 2010
35
Waveform: 1
36
Waveform: 2
37
Waveform: 3
5.2 Small example parameters N=11, q=32, p=3
Chronologic VCS simulator copyright 1991-2008
Contains Synopsys proprietary information.
Compiler version B-2008.12-9; Runtime version B-2008.12-9;
Apr 3 20:04 2010
VCD+ Writer B-2008.12-9 Copyright 2005 Synopsys Inc.
###########################################################
###########################################################
##############
############################################ NTRU PKCS for
N=11 q=5 p=3 ############################################
38
Input polynomials, f= 3 1 1 0 3 0 1 0 0 1 3 g= 3 0 1 1 0
1 0 0 3 0 3
Inverse of f modp, Fp= 1 2 0 2 2 1 0 2 1 2 0
Inverse of f modq, Fq= 5 9 6 16 4 15 16 22 20 18 30
Random polynomials, r = 3 0 1 1 1 3 0 3 0 0 0 Message m=
3 0 0 1 3 0 0 0 3 1 1
###########################################################
###########################################################
##############
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 0 0 0 0 0 0 0 0
0
0
0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 e= 0 0 0 0 0 0 0 0
0
0
0
time = 15: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 0 0 0 0 0 0 0
0
0
0
time = 25: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 0 0 0 0 0 0
0
0
0
time = 35: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 0 0 0 0 0
0
0
0
time = 45: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 0 0 0 0
0
0
0
time = 55: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 0 0 0
0
0
0
time = 65: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 0 0
0
0
0
time = 75: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 15 0
0
0
0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 c= 0 x x x x x x x x x 0
time =
0: key_complete=0 encrypt_complete=0
decrypt_complete= 0 c= 0 0 0 0 0 0 0 0 0 0 0
39
time = 85: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 15 19
0
0
0
time = 95: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 15 19 12
0
0
time = 105: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 15 19 12 19
0
time = 115: key_complete=0 encrypt_complete=0
decrypt_complete= 0 h= 8 25 22 20 12 24 15 19 12 19 16
time = 120: key_complete=1 encrypt_complete=0
decrypt_complete= 0 h= 0 0 0 0 0 0 0 0
0
time = 230: key_complete=1 encrypt_complete=1
decrypt_complete= 0 e= 14 11 26 24 14 16 30 7 25
0
0
6 19
time = 345: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 0 0 0 0 0 0 0 0
time = 375: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 1 0 0 0 0 0 0 0
time = 385: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 1 3 0 0 0 0 0 0
time = 425: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 1 3 0 0 0 3 0 0
time = 435: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 1 3 0 0 0 3 1 0
time = 445: key_complete=1 encrypt_complete=1
decrypt_complete= 0 c= 3 0 0 1 3 0 0 0 3 1 1
time = 450: key_complete=1 encrypt_complete=1
decrypt_complete= 1 c= 0 0 0 1 3 0 0 0 3 1 0
time = 450: key_complete=1 encrypt_complete=1
decrypt_complete= 1 c= 0 0 0 0 0 0 0 0 0 0 0
###########################################################
###########################################################
##############
40
###################### Success!!! The decrypted message is
the same as the original message sent
######################
Public key h= 8 25 22 20 12 24 15 19 12 19 16
Message sent m= 3 0 0 1 3 0 0 0 3 1 1
Encrypted message e= 14 11 26 24 14 16 30 7 25
Decrypted message c = 3 0 0 1 3 0 0 0 3 1 1
6 19
###########################################################
###########################################################
##############
$finish called from file "ntru_pkcs.v", line 142.
$finish at simulation time
480
V C S
S i m u l a t i o n
R e p o r t
Time: 480
CPU Time:
0.040 seconds;
Data structure size:
0.0Mb
Sat Apr 3 20:04:47 2010
41
Waveform: 4
42
Waveform: 5
43
Waveform: 6
44
Waveform: 7
45
Chapter 6
SYNTHESIS FIGURES
6.1 NTRU_Decryptor_Blk
Figure 14: NTRU_Decryptor_Blk Top Level
Figure 15: NTRU_Decryptor_Blk Logic Block
46
6.2 NTRU_Decryptor
Figure 16: NTRU_Decryptor Top Level
Figure 17: NTRU_Decryptor Logic Block
47
6.3 NTRU_Encryptor_Blk
Figure 18: NTRU_Encryptor_Blk Top Level
Figure 19: NTRU_Encryptor_Blk Logic Block
48
6.4 NTRU_Encryptor
Figure 20: NTRU_Encryptor Top Level
Figure 21: NTRU_Encryptor Logic Block
49
6.5 NTRU_Key
Figure 22: NTRU_Key Top Level
Figure 23: NTRU_Key Logic Block
50
6.6 Mult_Mod
Figure 24: Mult_Mod Logic Block
6.7 Polynomial_Mult
Figure 25: Polynomial_Mult Logic Block
51
6.8 Barrel_Shift
Figure 26: Barrel_Shift Logic Block
6.9 Coeff
Figure 27: Coeff Logic Block
52
6.10 Bit4_Cnt
Figure 28: Bit4_Cnt Logic Block
6.11 Proc_Unit
Figure 29: Proc_Unit Logic Block
53
6.12 Const_Mult
Figure 30: Const_Mult Logic Block
54
Chapter 7
CONCLUSIONS AND FUTURE WORK
The NTRU Public-key cryptosystem was studied and a hardware implementation
for this sytem was designed using Verilog HDL. This system has been verified for
different input values, N=7, N=11, N=107, q=32, q=64. This is a very flexible design,
since we have been able to test out different values of input polynomials with minor
changes made to the design for different sets of inputs. The size of polynomials in the
Processing Unit, need to be modified for different values of q. The size of the barrel
shifter needs to be modified for different values of N. Once these values are changed, the
system can easily encrypt and decrypt a given message.
The next step would be to implement this system for higher levels of security like
moderate (N=164) and high (N=503) levels. This can be done by starting with a smaller
set of inpouts and then building the bigger design by instantiating the smaller blocks in
them. In order to do this, we need to find the different input polynomial values to the
design. The NTRU Company has not made this data public for all values of security.
The testbench designed in this project is very user-friendly and is able to cater to
any different value of input provided. The output generated by the decryptor goes to a
comparaotor, which checks this output against the input message sent and depending on
the outcome gives out a success or failure message. This makes sure that the process is
totally automated and is not prone to any kind of calculation error.
55
An implementation based on Montgomery Multiplication was also studied as part
of the project research. A hardware implementation of NTRU using this multiplication
algorithm can be done to increase the multiplication speed [5].
The field of data security is a very important field and will always continue to be
one. Hence, accurate and reliable encryption-decryption algorithms are very essential. A
hardware implementation of this algorithm enables us to implement this algorithm on
FPGA’s, which help execute the algorithm much faster with more reliability. Thus the
NTRU Public Key Cryptosystem designed in this project is of significant importance in
the field of data security today.
56
APPENDICES
57
APPENDIX A
RTL Code
A.1 PARAMETERS N=107, q=64, p=3
// Code for 4-bit counter
`ifdef _bit4_cnt_
`else
`define _bit4_cnt_
module bit4_cnt(cnt4,rst,clk);
output [3:0] cnt4;
input
rst,clk;
reg [3:0]
cnt4=0;
always @ (posedge clk or posedge rst)
begin
if (rst)
cnt4 <= 0;
else
cnt4 <= cnt4+1;
end
endmodule // bit4_cnt
`endif
___________________________________________________________
// Code for Barrel Shifter
//Used to shift the coefficients of the inputs of the
polynomial multiplication process to the correct position
`ifdef _BARREL_SHIFT_
`else
`define _BARREL_SHIFT_
module barrel_shift(shift_out,poly_in,shift_num);
parameter N = 7;
parameter q = 6;
parameter big_size = N*q;
bits
//Size of poly_in in
58
input [3:0]
shift_num;
//Number of positions to
be shifted
input [big_size-1:0] poly_in;
//Unshifted value of
input polynomial
output reg[big_size-1:0] shift_out=0;
//Shifted value of
polynomial
always @ (poly_in or shift_num)
begin
case (shift_num)
4'd0 : shift_out <=
{poly_in[11:6],poly_in[17:12],poly_in[23:18],poly_in[29:24]
,poly_in[35:30],poly_in[41:36],poly_in[5:0]};
4'd1 : shift_out <=
{poly_in[17:12],poly_in[23:18],poly_in[29:24],poly_in[35:30
],poly_in[41:36],poly_in[5:0],poly_in[11:6]};
4'd2 : shift_out <=
{poly_in[23:18],poly_in[29:24],poly_in[35:30],poly_in[41:36
],poly_in[5:0],poly_in[11:6],poly_in[17:12]};
4'd3 : shift_out <=
{poly_in[29:24],poly_in[35:30],poly_in[41:36],poly_in[5:0],
poly_in[11:6],poly_in[17:12],poly_in[23:18]};
4'd4 : shift_out <=
{poly_in[35:30],poly_in[41:36],poly_in[5:0],poly_in[11:6],p
oly_in[17:12],poly_in[23:18],poly_in[29:24]};
4'd5 : shift_out <=
{poly_in[41:36],poly_in[5:0],poly_in[11:6],poly_in[17:12],p
oly_in[23:18],poly_in[29:24],poly_in[35:30]};
4'd6 : shift_out <=
{poly_in[5:0],poly_in[11:6],poly_in[17:12],poly_in[23:18],p
oly_in[29:24],poly_in[35:30],poly_in[41:36]};
4'd7 : shift_out <=0;
4'd8 : shift_out <=0;
4'd9 : shift_out <=0;
4'd10 : shift_out <=0;
4'd11 : shift_out <=0;
4'd12 : shift_out <=0;
59
4'd13 :
4'd14 :
4'd15 :
default
endcase
end
shift_out <=0;
shift_out <=0;
shift_out <=0;
:
;
endmodule // barrel_shift
`endif
___________________________________________________________
// Code for Procesing Unit- heart of the polynomial
multiplier
`ifdef _PROC_UNIT_
`else
`define _PROC_UNIT_
module proc_unit (out,in1,in2,carry_in);
parameter q = 6;
input
input
output
wire
wire
wire
wire
[q-1:0]
in1,carry_in;
[1:0]
in2;
[q-1:0]
out;
[q-1:0] in_10;
[q-1:0]
temp_out;
[q-1:0]
out;
[q-1:0]
shift_2;
assign temp_out[5]=(((~in1[5])
(in1[5]&(~in2[1])&in2[0]));
assign temp_out[4]=(((~in1[4])
(in1[4]&(~in2[1])&in2[0]));
assign temp_out[3]=(((~in1[3])
(in1[3]&(~in2[1])&in2[0]));
assign temp_out[2]=(((~in1[2])
(in1[2]&(~in2[1])&in2[0]));
assign temp_out[1]=(((~in1[1])
(in1[1]&(~in2[1])&in2[0]));
assign temp_out[0]=(((~in1[0])
(in1[0]&(~in2[1])&in2[0]));
assign shift_2= in1[q-1:0]<<1;
& in2[1]) |
& in2[1]) |
& in2[1]) |
& in2[1]) |
& in2[1]) |
& in2[1]) |
60
assign in_10 = (in2[1]&(~in2[0])) ? shift_2 : temp_out ;
assign out = in_10 + carry_in + (in2[1]&in2[0]);
endmodule // proc_unit
`endif
___________________________________________________________
// Code for coeff block
// Compute final polynomial coefficient by adding each
column element got by polynomial multiplication process
`ifdef _COEFF_
`else
`define _COEFF_
module coeff(C_final,A,B);
parameter
parameter
parameter
parameter
N = 7 ;
q = 6 ;
big_size= N*q;
small_size= N*2;
//Size of A in bits
//Size of B in bits
input [big_size-1:0]
A;
input [small_size-1:0]
B;
output wire[q-1:0] C_final;
wire
[big_size-1:0]
C;
assign
C_final = C[41:36];
polynomial coefficient
//Final value of the
proc_unit
proc0(.out(C[5:0]),.in1(A[5:0]),.in2(B[1:0]),.carry_in(6'b0
));
proc_unit
proc1(.out(C[11:6]),.in1(A[11:6]),.in2(B[3:2]),.carry_in(C[
5:0]));
proc_unit
proc2(.out(C[17:12]),.in1(A[17:12]),.in2(B[5:4]),.carry_in(
C[11:6]));
proc_unit
proc3(.out(C[23:18]),.in1(A[23:18]),.in2(B[7:6]),.carry_in(
C[17:12]));
61
proc_unit
proc4(.out(C[29:24]),.in1(A[29:24]),.in2(B[9:8]),.carry_in(
C[23:18]));
proc_unit
proc5(.out(C[35:30]),.in1(A[35:30]),.in2(B[11:10]),.carry_i
n(C[29:24]));
proc_unit
proc6(.out(C[41:36]),.in1(A[41:36]),.in2(B[13:12]),.carry_i
n(C[35:30]));
endmodule
`endif
___________________________________________________________
// Code for NTRU Multiplier or Polynomial Multiplication
Engine (PME)
// Performs polynomial multiplication on two input
polynomials, by shifting one of the inputs using the barrel
shifter, to compute product
`ifdef _POLYNOMIAL_MULT_
`else
`define _POLYNOMIAL_MULT_
module
polynomial_mult(poly_prod,poly1,poly2,poly_done,clk,rst);
parameter
parameter
parameter
parameter
N= 7;
q= 6;
big_size= N*q;
small_size= N*2;
//Size of poly1 in bits
//Size of poly2 in bits
input
clk,rst;
input [big_size-1:0]
poly1;
input [small_size-1:0]
poly2;
output reg[big_size-1:0]
poly_prod=0;
output wire
poly_done;
wire
wire
wire
wire
reg
[big_size-1:0]
[q-1:0]
[big_size-1:0]
[3:0]
poly1_shift;
coeff;
prod_temp;
shift_cnt;
poly_done_temp=0;
assign poly_done=poly_done_temp;
62
assign prod_temp = coeff<<(6*shift_cnt);
shifted product Coefficients
//Intermediate
bit4_cnt count(.cnt4(shift_cnt),.rst(rst),.clk(clk));
barrel_shift
shift(.shift_out(poly1_shift),.poly_in(poly1),.shift_num(sh
ift_cnt));
coeff cf(.C_final(coeff),.A(poly1_shift),.B(poly2));
always @ (posedge clk or posedge rst)//or posedge poly_done
begin
if (rst)
poly_prod <=0 ;
else if (poly_done)
poly_prod <=0 ;
else
poly_prod <= poly_prod + prod_temp;
end
always @ (negedge clk)
begin
if(shift_cnt == 4'b0111)
begin
poly_done_temp <=1;
end
end
endmodule
`endif
___________________________________________________________
// Code for the p.Fq multiplier block
// Multiplies the constant integer value of 'const' with
each and every coefficient of the 'poly' polynomial
`ifdef _const_mult_
`else
`define _const_mult_
module const_mult(prod,poly,const);
parameter N= 7;
parameter q= 6;
63
parameter big_size= N*q;
output [big_size-1:0]
prod;
input [big_size-1:0]
poly;
input [1:0]
const;
assign
assign
assign
assign
assign
assign
assign
prod[5:0]
prod[11:6]
prod[17:12]
prod[23:18]
prod[29:24]
prod[35:30]
prod[41:36]
=
=
=
=
=
=
=
poly[5:0]*const;
poly[11:6]*const;
poly[17:12]*const;
poly[23:18]*const;
poly[29:24]*const;
poly[35:30]*const;
poly[41:36]*const;
endmodule // const_mult
`endif
___________________________________________________________
// Code for Key Creator block
// Key 'h' is calculated using Polynomial multiplication :
(p*Fq*g)mod64
module ntru_key(key,f_invq,g_poly,key_done,clk,rst);
parameter
parameter
parameter
parameter
parameter
N= 7;
q= 6;
p= 2'd3;
big_size= N*q;
small_size= N*2;
// Size of Fq, h in bits
// Size of g in bits
input [big_size-1:0]
f_invq;
random polynomial F mod q
input [small_size-1:0] g_poly;
polynomial
input
clk,rst;
output [big_size-1:0]
key;
value of key generated
output
key_done;
creation process is complete
wire
[big_size-1:0]
// Inverse of
// Random input
// Output
// Set when key
pFq;
const_mult const(.prod(pFq),.poly(f_invq),.const(p));
64
polynomial_mult
poly1(.poly_prod(key),.poly1(pFq),.poly2(g_poly),.poly_done
(key_done),.clk(clk),.rst(rst));
endmodule
___________________________________________________________
// Code for Encryptor block
// Encrypted message is calculated as: e = r*h + m (modulo
64)
module
ntru_encryptor(enc_msg,key,r_poly,msg,encrypt_done,clk,rst)
;
parameter
parameter
parameter
parameter
N= 7;
q= 6;
big_size= N*q;
small_size= N*2;
// Size of h,e,rxh in bits
// Size of r,m in bits
input
[big_size-1:0]
key;
// Key created
input
[small_size-1:0]
r_poly;
//
Random polynomial
input
[small_size-1:0]
msg;
//
Message to be sent
input
clk,rst;
output reg [big_size-1:0]
enc_msg=0;
//
Encrypted message generated
output reg
encrypt_done=0; // Set when
encryption process is complete
wire
mult_done;
// Set when
polynomial multiplication: r*h is complete
wire
[big_size-1:0]
rxh;
// Product of
r*h
// Multiply key, h and random polynomial, r
polynomial_mult
poly2(.poly_prod(rxh),.poly1(key),.poly2(r_poly),.poly_done
(mult_done),.clk(clk),.rst(rst));
always @ (posedge mult_done)
65
begin
if ((msg[1]&msg[0]) ==1)
//check if msgsg
bit is -1: if yes, subtract 1 else add msgessage msg to the
r*h product
enc_msg[5:0] = rxh[5:0] - 1;
else
enc_msg[5:0] = rxh[5:0] + msg[1:0];
if ((msg[3]&msg[2]) ==1)
enc_msg[11:6] = rxh[11:6] - 1;
else
enc_msg[11:6] = rxh[11:6] + msg[3:2];
if ((msg[5]&msg[4]) ==1)
enc_msg[17:12] = rxh[17:12] - 1;
else
enc_msg[17:12] = rxh[17:12] + msg[5:4];
if ((msg[7]&msg[6]) ==1)
enc_msg[23:18] = rxh[23:18] - 1;
else
enc_msg[23:18] = rxh[23:18] + msg[7:6];
if ((msg[9]&msg[8]) ==1)
enc_msg[29:24] = rxh[29:24] - 1;
else
enc_msg[29:24] = rxh[29:24] + msg[9:8];
if ((msg[11]&msg[10]) ==1)
enc_msg[35:30] = rxh[35:30] - 1;
else
enc_msg[35:30] = rxh[35:30] + msg[11:10];
if ((msg[13]&msg[12]) ==1)
enc_msg[41:36] = rxh[41:36] - 1;
else
enc_msg[41:36] = rxh[41:36] + msg[13:12];
encrypt_done=1;
//done signal goes high
only only after encrypted msg is generated
end
endmodule // ntru_encryptor
___________________________________________________________
66
// Code for different TOP level modules for q=64, N=
107(Moderate Level of NTRU Security)
// Code for ntru_encryptor_blk
module
ntru_encryptor_blk(enc_msg,key,r_poly,msg,encrypt_top_done,
clk,rst);
parameter
parameter
parameter
parameter
N= 112;
q= 6;
big_size= N*q;
small_size= N*2;
input
input
input
input
output wire
output
[41:0]
key;
[small_size-1:0]
r_poly;
[small_size-1:0]
msg;
clk,rst;
[big_size-1:0]
enc_msg;
encrypt_top_done;
wire
d_1,d_2,d_3,d_4,d_5,d_6,d_7,d_8,d_9,d_10,d_11,d_12,d_13,d_1
4,d_15;
ntru_encryptor
enc1(.enc_msg(enc_msg[41:0]),.key(key),.r_poly(r_poly[13:0]
),.msg(msg[13:0]),.encrypt_done(d_1),.clk(clk),.rst(rst));
ntru_encryptor
enc2(.enc_msg(enc_msg[83:42]),.key(key),.r_poly(r_poly[27:1
4]),.msg(msg[27:14]),.encrypt_done(d_2),.clk(clk),.rst(rst)
);
ntru_encryptor
enc3(.enc_msg(enc_msg[125:84]),.key(key),.r_poly(r_poly[41:
28]),.msg(msg[41:28]),.encrypt_done(d_3),.clk(clk),.rst(rst
));
ntru_encryptor
enc4(.enc_msg(enc_msg[167:126]),.key(key),.r_poly(r_poly[55
:42]),.msg(msg[55:42]),.encrypt_done(d_4),.clk(clk),.rst(rs
t));
ntru_encryptor
enc5(.enc_msg(enc_msg[209:168]),.key(key),.r_poly(r_poly[69
:56]),.msg(msg[69:56]),.encrypt_done(d_5),.clk(clk),.rst(rs
t));
67
ntru_encryptor
enc6(.enc_msg(enc_msg[251:210]),.key(key),.r_poly(r_poly[83
:70]),.msg(msg[83:70]),.encrypt_done(d_6),.clk(clk),.rst(rs
t));
ntru_encryptor
enc7(.enc_msg(enc_msg[293:252]),.key(key),.r_poly(r_poly[97
:84]),.msg(msg[97:84]),.encrypt_done(d_7),.clk(clk),.rst(rs
t));
ntru_encryptor
enc8(.enc_msg(enc_msg[335:294]),.key(key),.r_poly(r_poly[11
1:98]),.msg(msg[111:98]),.encrypt_done(d_8),.clk(clk),.rst(
rst));
ntru_encryptor
enc9(.enc_msg(enc_msg[377:336]),.key(key),.r_poly(r_poly[12
5:112]),.msg(msg[125:112]),.encrypt_done(d_9),.clk(clk),.rs
t(rst));
ntru_encryptor
enc10(.enc_msg(enc_msg[419:378]),.key(key),.r_poly(r_poly[1
39:126]),.msg(msg[139:126]),.encrypt_done(d_10),.clk(clk),.
rst(rst));
ntru_encryptor
enc11(.enc_msg(enc_msg[461:420]),.key(key),.r_poly(r_poly[1
53:140]),.msg(msg[153:140]),.encrypt_done(d_11),.clk(clk),.
rst(rst));
ntru_encryptor
enc12(.enc_msg(enc_msg[503:462]),.key(key),.r_poly(r_poly[1
67:154]),.msg(msg[167:154]),.encrypt_done(d_12),.clk(clk),.
rst(rst));
ntru_encryptor
enc13(.enc_msg(enc_msg[545:504]),.key(key),.r_poly(r_poly[1
81:168]),.msg(msg[181:168]),.encrypt_done(d_13),.clk(clk),.
rst(rst));
ntru_encryptor
enc14(.enc_msg(enc_msg[587:546]),.key(key),.r_poly(r_poly[1
95:182]),.msg(msg[195:182]),.encrypt_done(d_14),.clk(clk),.
rst(rst));
ntru_encryptor
enc15(.enc_msg(enc_msg[629:588]),.key(key),.r_poly(r_poly[2
09:196]),.msg(msg[209:196]),.encrypt_done(d_15),.clk(clk),.
rst(rst));
ntru_encryptor
enc16(.enc_msg(enc_msg[671:630]),.key(key),.r_poly({10'b0,r
_poly[213:210]}),.msg({10'b0,msg[213:210]}),.encrypt_done(e
ncrypt_top_done),.clk(clk),.rst(rst));
68
endmodule // ntru_encryptor_blk
___________________________________________________________
// Code for single stage of Decryptor block
// This block computes polynomial multiplcation product and
then does a mod3 operation on each coefficient element
module mult_mod(poly_mod,mult1,mult2,mod_done,clk,rst);
parameter
parameter
parameter
parameter
N= 7;
q= 6;
big_size= N*q;
small_size= N*2;
input
[big_size-1:0]
mult1;
// input
polynomial
input
[small_size-1:0]
mult2;
// input
polynomial
input
clk,rst;
output wire [small_size-1:0]
poly_mod;
//
Product of polynomial multiplication, mod3
output wire
mod_done;
// mod_done
wire
[big_size-1:0]
polynomial multiplication
mult_out;
// Product of
//Function mod3 computes the different mod3 values for a 6bit input ranging from 1-63
function[q-1:0] mod3;
input [q-1:0] mod_in;
begin
case(mod_in)
6'd1,4,7,10,13,16,19,22,25,28,31,35,38,41,44,47,50,53,
56,59,62 :
mod3= 1;
6'd2,5,8,11,14,17,20,23,26,29,32,33,36,39,42,45,48,51,
54,57,60,63 : mod3= -1;
6'd3,6,9,12,15,18,21,24,27,30,34,37,40,43,46,49,52,55,
58,61 :
mod3= 0;
default : mod3 =0;
69
endcase
end
endfunction // mod3
// Multiply 2 polynomials mod64
polynomial_mult
poly3(.poly_prod(mult_out),.poly1(mult1),.poly2(mult2),.pol
y_done(mod_done),.clk(clk),.rst(rst));
// Compute the mod3 value of each coefficient for the
product of the polynomial multiplication
assign poly_mod[1:0] = mod3(mult_out[5:0]);
assign poly_mod[3:2] = mod3(mult_out[11:6]);
assign poly_mod[5:4] = mod3(mult_out[17:12]);
assign poly_mod[7:6] = mod3(mult_out[23:18]);
assign poly_mod[9:8] = mod3(mult_out[29:24]);
assign poly_mod[11:10] = mod3(mult_out[35:30]);
assign poly_mod[13:12] = mod3(mult_out[41:36]);
endmodule // mult_mod
___________________________________________________________
// Code for combined Decryptor block
module
ntru_decryptor(dec_msg,enc_msg,f_poly,f_invp,decrypt_done,c
lk,rst);
parameter
parameter
parameter
parameter
N= 7;
q= 6;
big_size= N*q;
small_size= N*2;
input [big_size-1:0]
enc_msg;
message
input [small_size-1:0] f_poly;
polynomial
input [big_size-1:0]
f_invp;
polynomial f mod p
input
clk,rst;
output [small_size-1:0] dec_msg;
message
output wire
decrypt_done;
done
// Encrypted
// Random
// Inverse
// Decrypted
// Decryption
70
reg [small_size-1:0]
dec_b_reg;
wire [small_size-1:0]
dec_b;
wire
done_fe,done_Fpb,rst_fe,rst_Fpb;
assign
assign
assign
rst_fe = rst;
rst_Fpb = ~done_fe | rst;
decrypt_done = done_Fpb;
// Compute b = (f*e (modulo q))modulo_3
mult_mod fe(dec_b,enc_msg,f_poly,done_fe,clk,rst_fe);
always @ (done_fe)
begin
dec_b_reg <= dec_b;
end
// Compute c = Fp*b_out (modulo_3)
mult_mod
Fpb(dec_msg,f_invp,dec_b_reg,done_Fpb,clk,rst_Fpb);
endmodule
___________________________________________________________
// Code for ntru_decryptor_blk
module
ntru_decryptor_blk(dec_msg,enc_msg,f_poly,f_invp,decrypt_to
p_done,clk,rst);
parameter
parameter
parameter
parameter
N= 112;
q= 6;
big_size= N*q;
small_size= N*2;
input [41:0]
f_invp;
polynomial f mod 3
input [13:0]
f_poly;
polynomial f
input [big_size-1:0]
enc_msg;
message
input
clk,rst;
output wire
decrypt_top_done;
Decryption complete
output [small_size-1:0] dec_msg;
decrypted message
// Inverse
// Random
// Encrypted
//
// Final
71
wire
d_1,d_2,d_3,d_4,d_5,d_6,d_7,d_8,d_9,d_10,d_11,d_12,d_1
3,d_14,d_15;
ntru_decryptor
dec1(.dec_msg(dec_msg[13:0]),.enc_msg(enc_msg[41:0]),.f_pol
y(f_poly),.f_invp(f_invp),.decrypt_done(d_1),.clk(clk),.rst
(rst));
ntru_decryptor
dec2(.dec_msg(dec_msg[27:14]),.enc_msg(enc_msg[83:42]),.f_p
oly(f_poly),.f_invp(f_invp),.decrypt_done(d_2),.clk(clk),.r
st(rst));
ntru_decryptor
dec3(.dec_msg(dec_msg[41:28]),.enc_msg(enc_msg[125:84]),.f_
poly(f_poly),.f_invp(f_invp),.decrypt_done(d_3),.clk(clk),.
rst(rst));
ntru_decryptor
dec4(.dec_msg(dec_msg[55:42]),.enc_msg(enc_msg[167:126]),.f
_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_4),.clk(clk),
.rst(rst));
ntru_decryptor
dec5(.dec_msg(dec_msg[69:56]),.enc_msg(enc_msg[209:168]),.f
_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_5),.clk(clk),
.rst(rst));
ntru_decryptor
dec6(.dec_msg(dec_msg[83:70]),.enc_msg(enc_msg[251:210]),.f
_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_6),.clk(clk),
.rst(rst));
ntru_decryptor
dec7(.dec_msg(dec_msg[97:84]),.enc_msg(enc_msg[293:252]),.f
_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_7),.clk(clk),
.rst(rst));
ntru_decryptor
dec8(.dec_msg(dec_msg[111:98]),.enc_msg(enc_msg[335:294]),.
f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_8),.clk(clk)
,.rst(rst));
ntru_decryptor
dec9(.dec_msg(dec_msg[125:112]),.enc_msg(enc_msg[377:336]),
.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_9),.clk(clk
),.rst(rst));
ntru_decryptor
dec10(.dec_msg(dec_msg[139:126]),.enc_msg(enc_msg[419:378])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_10),.clk(c
lk),.rst(rst));
72
ntru_decryptor
dec11(.dec_msg(dec_msg[153:140]),.enc_msg(enc_msg[461:420])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_11),.clk(c
lk),.rst(rst));
ntru_decryptor
dec12(.dec_msg(dec_msg[167:154]),.enc_msg(enc_msg[503:462])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_12),.clk(c
lk),.rst(rst));
ntru_decryptor
dec13(.dec_msg(dec_msg[181:168]),.enc_msg(enc_msg[545:504])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_13),.clk(c
lk),.rst(rst));
ntru_decryptor
dec14(.dec_msg(dec_msg[195:182]),.enc_msg(enc_msg[587:546])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_14),.clk(c
lk),.rst(rst));
ntru_decryptor
dec15(.dec_msg(dec_msg[209:196]),.enc_msg(enc_msg[629:588])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(d_15),.clk(c
lk),.rst(rst));
ntru_decryptor
dec16(.dec_msg(dec_msg[223:210]),.enc_msg(enc_msg[671:630])
,.f_poly(f_poly),.f_invp(f_invp),.decrypt_done(decrypt_top_
done),.clk(clk),.rst(rst));
endmodule // ntru_decryptor_blk
___________________________________________________________
// Code for Unified Test Bench for Low Level of NTRU
Security
`include "ntru_key.v"
`include "ntru_encryptor_blk.v"
`include "ntru_decryptor_blk.v"
module ntru_pkcs;
parameter
parameter
parameter
parameter
parameter
parameter
N= 112;
N_ind= 7;
q= 6;
p= 3;
big_size= N*q;
small_size= N*2;
73
parameter big_ind= N_ind*q;
parameter small_ind= N_ind*2;
// NTRU Key Creator
reg
clk,rst_key;
reg [big_ind-1:0] f_invq;
reg [big_ind-1:0] pFq;
reg [small_ind-1:0]
g_poly;
wire [big_ind-1:0] key;
wire
key_complete;
// NTRU Encryptor Block
reg [small_size-1:0]
r_poly=0;
reg [small_size-1:0]
msg=0;
reg [big_ind-1:0]
key_reg=0;
wire
rst_enc;
wire [big_size-1:0]
enc_msg;
wire
encrypt_complete;
// NTRU Decryptor Block
reg [small_ind-1:0]
f_poly;
wire
rst_dec;
wire
decrypt_complete;
reg [big_ind-1:0]
f_invp;
wire [small_size-1:0]
dec_msg;
reg [small_size-1:0]
dec_msg_reg;
assign rst_enc = ~key_complete;
assign rst_dec = ~encrypt_complete | rst_key;
//Instantiate all the three blocks for key creation,
encryption, decryption
ntru_key
key_create(key,f_invq,g_poly,key_complete,clk,rst_key);
ntru_encryptor_blk
encrypt(enc_msg,key_reg,r_poly,msg,encrypt_complete,clk,rst
_enc);
ntru_decryptor_blk
decrypt(dec_msg,enc_msg,f_poly,f_invp,decrypt_complete,clk,
rst_dec);
wire [1:0]
g6,g5,g4,g3,g2,g1,g0,f6,f5,f4,f3,f2,f1,f0,r6,r5,r4,r3,r2,r1
,r0,m6,m5,m4,m3,m2,m1,m0,c6,c5,c4,c3,c2,c1,c0,ct6,ct5,ct4,c
t3,ct2,ct1,ct0;
74
wire [q-1:0]
ht6,ht5,ht4,ht3,ht2,ht1,ht0,h6,h5,h4,h3,h2,h1,h0,fp6,fp5,fp
4,fp3,fp2,fp1,fp0,fq6,fq5,fq4,fq3,fq2,fq1,fq0,e6,e5,e4,e3,e
2,e1,e0;
assign
assign
assign
assign
assign
assign
{g6,g5,g4,g3,g2,g1,g0}=g_poly;
{r6,r5,r4,r3,r2,r1,r0}=r_poly;
{f6,f5,f4,f3,f2,f1,f0}=f_poly;
{m6,m5,m4,m3,m2,m1,m0}=msg;
{c6,c5,c4,c3,c2,c1,c0}=dec_msg;
{ct6,ct5,ct4,ct3,ct2,ct1,ct0}=dec_msg_reg;
assign
assign
assign
assign
assign
{fp6,fp5,fp4,fp3,fp2,fp1,fp0}=f_invp;
{fq6,fq5,fq4,fq3,fq2,fq1,fq0}=f_invq;
{h6,h5,h4,h3,h2,h1,h0}=key;
{ht6,ht5,ht4,ht3,ht2,ht1,ht0}=key_reg;
{e6,e5,e4,e3,e2,e1,e0}=enc_msg;
initial
$vcdpluson;
// Clock generator
initial
begin
clk = 0;
#10 forever #5 clk = ~clk;
end
// Input polynomials and display commands
initial
begin
rst_key =
1;
f_invq =
{6'd20,6'd29,-6'd15,6'd13,-6'd2,6'd11,6'd9};
g_poly =
{2'd0,2'd0,-2'd1,2'd1,2'd0,2'd1,-2'd1};
f_invp =
{-6'd1,6'd0,-6'd1,6'd1,6'd0,6'd1,6'd1};
f_poly =
{2'd0,2'd0,-2'd1,2'd1,2'd1,2'd0,2'd0};
r_poly =
{2'd0,-2'd1,-2'd1,-2'd1,2'd1,-2'd1,2'd0};
msg
=
224'h7F5Cd7F5Cd7F5Cd7;
//{4'hf,4'h5,4'hc,4'h1,4'h3,4'h7,4'hd,4'hf,4'h7};
//5192296858534827628530496329220097;
//224'h8F5C28F5C28F5C28
$display("#################################################
75
###########################################################
########################\n");
$display("############################################
NTRU PKCS for N=11 q=5 p=3
############################################\n")
;
$display(" Input polynomials, f= %d %d %d %d %d %d %d
g= %d %d %d %d %d %d %d\n Inverse of f modp, Fp= %d %d %d
%d %d %d %d Inverse of f modq, Fq= %d %d %d %d %d %d
%d",f0,f1,f2,f3,f4,f5,f6,g0,g1,g2,g3,g4,g5,g6,fp0,fp1,fp2,f
p3,fp4,fp5,fp6,fq0,fq1,fq2,fq3,fq4,fq5,fq6);
$display(" Random polynomials, r = %d %d %d %d %d %d %d
Message m= %d \n",r0,r1,r2,r3,r4,r5,r6,msg);
$display("#################################################
###########################################################
########################\n");
#10;
rst_key =0;
#600 $finish;
end
always @ (key)
begin
$display("time = %3d: key_complete=%d
encrypt_complete=%d decrypt_complete= %d h= %d %d %d %d %d
%d %d
\n",$time,key_complete,encrypt_complete,decrypt_complete,h0
,h1,h2,h3,h4,h5,h6);
end
always @ (posedge key_complete)
begin
key_reg <= key;
end
always @ (enc_msg)
begin
$display("time = %3d: key_complete=%d
encrypt_complete=%d decrypt_complete= %d e= %d %d %d %d %d
%d %d
\n",$time,key_complete,encrypt_complete,decrypt_complete,e0
,e1,e2,e3,e4,e5,e6);
76
end
always @ (dec_msg)
begin
$display("time = %3d: key_complete=%d encrypt_complete=%d
decrypt_complete= %d c= %d %d %d %d %d %d %d\n
",$time,key_complete,encrypt_complete,decrypt_complete,c0,c
1,c2,c3,c4,c5,c6);
end
always @ (posedge decrypt_complete)
begin
dec_msg_reg <= dec_msg;
if(msg==dec_msg)
begin
#30
$display("#################################################
###########################################################
########################\n");
$display("###################### Success!!! The
decrypted message is the same as the original message sent
###################### \n");
$display("Public key h= %d %d %d %d %d %d %d\nMessage
sent m= %20d \nEncrypted message e= %d %d %d %d %d %d
%d\nDecrypted message c= %20d
\n",ht0,ht1,ht2,ht3,ht4,ht5,ht6,msg,e0,e1,e2,e3,e4,e5,e6,de
c_msg_reg);
$display("############################################
###########################################################
#############################");
$finish;
end
else
begin
#30
$display("#################################################
###########################################################
########################\n");
$display("###################### Fail!!! The
decrypted message and the original message sent are
different ###################### \n");
$display("Public key h= %d %d %d %d %d %d %d\nMessage
sent m= %20d \nEncrypted message, e= %d %d %d %d %d %d
%d\nDecrypted message c= %20d
77
\n",ht0,ht1,ht2,ht3,ht4,ht5,ht6,msg,e0,e1,e2,e3,e4,e5,e6,de
c_msg_reg);
$display("############################################
###########################################################
#############################");
$finish;
end
end
endmodule
___________________________________________________________
___________________________________________________________
A.2 PARAMETERS N=11, q=32, p=3
// Code for 4-bit counter
`ifdef _bit4_cnt_
`else
`define _bit4_cnt_
module bit4_cnt(cnt4,rst,clk);
output reg [3:0] cnt4=0;
input
rst,clk;
always @ (posedge clk or posedge rst)
begin
if (rst)
cnt4 <= 0;
else
cnt4 <= cnt4+1;
end
endmodule // bit4_cnt
`endif
___________________________________________________________
// Code for Barrel Shifter
// Used to shift the coefficients of the inputs of the
polynomial multiplication process to the correct position
78
`ifdef _BARREL_SHIFT_
`else
`define _BARREL_SHIFT_
module barrel_shift(shift_out,poly_in,shift_num);
parameter
parameter
parameter
//Size of
N =11;
q =5;
big_size = N*q;
poly_in in bits
input
[3:0]
shift_num;
positions to be shifted
input
[big_size-1:0] poly_in;
value of input polynomial
output reg
[big_size-1:0] shift_out=0;
of polynomial
//Number of
//Unshifted
//Shifted value
always @ (poly_in or shift_num)
begin
case (shift_num)
4'd0 : shift_out <=
{poly_in[9:5],poly_in[14:10],poly_in[19:15],poly_in[24:20],
poly_in[29:25],poly_in[34:30],poly_in[39:35],poly_in[44:40]
,poly_in[49:45],poly_in[54:50],poly_in[4:0]};
4'd1 : shift_out <=
{poly_in[14:10],poly_in[19:15],poly_in[24:20],poly_in[29:25
],poly_in[34:30],poly_in[39:35],poly_in[44:40],poly_in[49:4
5],poly_in[54:50],poly_in[4:0],poly_in[9:5]};
4'd2 : shift_out <=
{poly_in[19:15],poly_in[24:20],poly_in[29:25],poly_in[34:30
],poly_in[39:35],poly_in[44:40],poly_in[49:45],poly_in[54:5
0],poly_in[4:0],poly_in[9:5],poly_in[14:10]};
4'd3 : shift_out <=
{poly_in[24:20],poly_in[29:25],poly_in[34:30],poly_in[39:35
],poly_in[44:40],poly_in[49:45],poly_in[54:50],poly_in[4:0]
,poly_in[9:5],poly_in[14:10],poly_in[19:15]};
4'd4 : shift_out <=
{poly_in[29:25],poly_in[34:30],poly_in[39:35],poly_in[44:40
],poly_in[49:45],poly_in[54:50],poly_in[4:0],poly_in[9:5],p
oly_in[14:10],poly_in[19:15],poly_in[24:20]};
79
4'd5 : shift_out <=
{poly_in[34:30],poly_in[39:35],poly_in[44:40],poly_in[49:45
],poly_in[54:50],poly_in[4:0],poly_in[9:5],poly_in[14:10],p
oly_in[19:15],poly_in[24:20],poly_in[29:25]};
4'd6 : shift_out <=
{poly_in[39:35],poly_in[44:40],poly_in[49:45],poly_in[54:50
],poly_in[4:0],poly_in[9:5],poly_in[14:10],poly_in[19:15],p
oly_in[24:20],poly_in[29:25],poly_in[34:30]};
4'd7 : shift_out <=
{poly_in[44:40],poly_in[49:45],poly_in[54:50],poly_in[4:0],
poly_in[9:5],poly_in[14:10],poly_in[19:15],poly_in[24:20],p
oly_in[29:25],poly_in[34:30],poly_in[39:35]};
4'd8 : shift_out <=
{poly_in[49:45],poly_in[54:50],poly_in[4:0],poly_in[9:5],po
ly_in[14:10],poly_in[19:15],poly_in[24:20],poly_in[29:25],p
oly_in[34:30],poly_in[39:35],poly_in[44:40]};
4'd9 : shift_out <=
{poly_in[54:50],poly_in[4:0],poly_in[9:5],poly_in[14:10],po
ly_in[19:15],poly_in[24:20],poly_in[29:25],poly_in[34:30],p
oly_in[39:35],poly_in[44:40],poly_in[49:45]};
4'd10 : shift_out
<={poly_in[4:0],poly_in[9:5],poly_in[14:10],poly_in[19:15],
poly_in[24:20],poly_in[29:25],poly_in[34:30],poly_in[39:35]
,poly_in[44:40],poly_in[49:45],poly_in[54:50]};
4'd11 :
4'd12 :
4'd13 :
4'd14 :
4'd15 :
default
endcase
shift_out
shift_out
shift_out
shift_out
shift_out
:
<=0;
<=0;
<=0;
<=0;
<=0;
;
end
endmodule // barrel_shift
`endif
___________________________________________________________
80
// Code for Procesing Unit- heart of the polynomial
multiplier
`ifdef _PROC_UNIT_
`else
`define _PROC_UNIT_
module proc_unit (out,in1,in2,carry_in);
parameter q = 5;
input
input
output
wire
wire
wire
[q-1:0]
[1:0]
[q-1:0]
[q-1:0]
[q-1:0]
[q-1:0]
in1,carry_in;
in2;
out;
in_10;
temp_out;
out;
assign temp_out[4]=(((~in1[4])
(in1[4]&(~in2[1])&in2[0]));
assign temp_out[3]=(((~in1[3])
(in1[3]&(~in2[1])&in2[0]));
assign temp_out[2]=(((~in1[2])
(in1[2]&(~in2[1])&in2[0]));
assign temp_out[1]=(((~in1[1])
(in1[1]&(~in2[1])&in2[0]));
assign temp_out[0]=(((~in1[0])
(in1[0]&(~in2[1])&in2[0]));
& in2[1]) |
& in2[1]) |
& in2[1]) |
& in2[1]) |
& in2[1]) |
assign in_10 = (in2[1]&(~in2[0])) ? {in1[q-1:0]<<1} :
temp_out ;
assign out = in_10 + carry_in + (in2[1]&in2[0]);
endmodule // pu
`endif
___________________________________________________________
// Code for coeff block
// Compute final polynomial coefficient by adding each
column element got by polynomial multiplication process
`ifdef _COEFF_
`else
`define _COEFF_
81
module coeff(C_final,A,B);
parameter
parameter
parameter
parameter
N = 11 ;
q = 5 ;
big_size= N*q;
small_size= N*2;
//Size of A in bits
//Size of B in bits
input
[big_size-1:0] A;
input
[small_size-1:0]
output wire [q-1:0]
C_final;
wire
B;
[big_size-1:0] C;
assign C_final = C[54:50];
polynomial coefficient
//Final value of the
proc_unit proc0
(.out(C[4:0]),.in1(A[4:0]),.in2(B[1:0]),.carry_in(5'b0));
proc_unit proc1
(.out(C[9:5]),.in1(A[9:5]),.in2(B[3:2]),.carry_in(C[4:0]));
proc_unit proc2
(.out(C[14:10]),.in1(A[14:10]),.in2(B[5:4]),.carry_in(C[9:5
]));
proc_unit proc3
(.out(C[19:15]),.in1(A[19:15]),.in2(B[7:6]),.carry_in(C[14:
10]));
proc_unit proc4
(.out(C[24:20]),.in1(A[24:20]),.in2(B[9:8]),.carry_in(C[19:
15]));
proc_unit proc5
(.out(C[29:25]),.in1(A[29:25]),.in2(B[11:10]),.carry_in(C[2
4:20]));
proc_unit proc6
(.out(C[34:30]),.in1(A[34:30]),.in2(B[13:12]),.carry_in(C[2
9:25]));
proc_unit proc7
(.out(C[39:35]),.in1(A[39:35]),.in2(B[15:14]),.carry_in(C[3
4:30]));
proc_unit proc8
(.out(C[44:40]),.in1(A[44:40]),.in2(B[17:16]),.carry_in(C[3
9:35]));
proc_unit proc9
(.out(C[49:45]),.in1(A[49:45]),.in2(B[19:18]),.carry_in(C[4
4:40]));
82
proc_unit
proc10(.out(C[54:50]),.in1(A[54:50]),.in2(B[21:20]),.carry_
in(C[49:45]));
endmodule
`endif
___________________________________________________________
// Code for the p.Fq multiplier block
// Multiplies the constant integer value of p with each and
every coefficient of the Fq polynomial
`ifdef _const_mult_
`else
`define _const_mult_
module const_mult(prod,poly,const);
parameter N= 11;
parameter q= 5;
parameter big_size= N*q;
output [big_size-1:0] prod;
input [big_size-1:0] poly;
input [1:0]
const;
assign
assign
assign
assign
assign
assign
assign
assign
assign
assign
assign
prod[4:0]
prod[9:5]
prod[14:10]
prod[19:15]
prod[24:20]
prod[29:25]
prod[34:30]
prod[39:35]
prod[44:40]
prod[49:45]
prod[54:50]
=
=
=
=
=
=
=
=
=
=
=
poly[4:0]*const;
poly[9:5]*const;
poly[14:10]*const;
poly[19:15]*const;
poly[24:20]*const;
poly[29:25]*const;
poly[34:30]*const;
poly[39:35]*const;
poly[44:40]*const;
poly[49:45]*const;
poly[54:50]*const;
endmodule // const_mult
`endif
___________________________________________________________
83
// Code for NTRU Multiplier or Polynomial Multiplication
Engine (PME)
// Performs polynomial multiplication on two input
polynomials, by shifting one of the inputs using the barrel
shifter, to compute product
`ifdef _POLYNOMIAL_MULT_
`else
`define _POLYNOMIAL_MULT_
module
polynomial_mult(poly_prod,poly1,poly2,poly_done,clk,rst);
parameter
parameter
parameter
parameter
N= 11;
q= 5;
big_size= N*q;
small_size= N*2;
//Size of poly1 in bits
//Size of poly2 in bits
input
clk,rst;
input [big_size-1:0]
poly1;
input [small_size-1:0]
poly2;
output reg[big_size-1:0] poly_prod=0;
output reg
poly_done=0;
wire
wire
wire
wire
[big_size-1:0] poly1_shift;
[q-1:0]
coeff;
[big_size-1:0] prod_temp;
[3:0]
shift_cnt;
assign prod_temp = coeff<<(5*shift_cnt);
//Intermediate shifted product Coefficients
bit4_cnt count(.cnt4(shift_cnt),.rst(rst),.clk(clk));
barrel_shift
shift(.shift_out(poly1_shift),.poly_in(poly1),.shift_num(sh
ift_cnt));
coeff cf(.C_final(coeff),.A(poly1_shift),.B(poly2));
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
poly_prod <=0 ;
end
84
else if (poly_done)
poly_prod <=0 ;
else
begin
poly_prod <= poly_prod + prod_temp;
end
end
always @ (negedge clk)
begin
if(shift_cnt == 4'b1011)
begin
poly_done <= 1;
end
end
endmodule
`endif
___________________________________________________________
// Code for Key Creator block
// Key 'h' is calculated using Polynomial multiplication :
(p*Fq*g)mod64
module ntru_key(key,f_invq,g_poly,key_done,clk,rst);
parameter
parameter
parameter
parameter
parameter
N= 11;
q= 5;
p= 2'd3;
big_size= N*q;
small_size= N*2;
// Size of Fq, h in bits
// Size of g in bits
input [big_size-1:0]
f_invq; // Inverse of random
polynomial F mod q
input [small_size-1:0]
g_poly; // Random input
polynomial
input
clk,rst;
output [big_size-1:0]
key;
// Output value
of key generated
output
key_done;
// Set when key
creation process is complete
wire [big_size-1:0] pFq;
85
const_mult const(.prod(pFq),.poly(f_invq),.const(p));
polynomial_mult
poly1(.poly_prod(key),.poly1(pFq),.poly2(g_poly),.poly_done
(key_done),.clk(clk),.rst(rst));
endmodule
___________________________________________________________
// Code for Encryptor block
// Encrypted message is calculated as: e = r*h + m (modulo
64)
module
ntru_encryptor(enc_msg,key,r_poly,msg,encrypt_done,clk,rst)
;
parameter
parameter
parameter
parameter
N= 11;
q= 5;
big_size= N*q;
small_size= N*2;
// Size of h,e,rxh in bits
// Size of r,m in bits
input
[big_size-1:0]
key;
// Key created
input
[small_size-1:0] r_poly;
// Random
polynomial
input
[small_size-1:0] msg;
// Message to
be sent
input
clk,rst;
output reg [big_size-1:0]
enc_msg=0; // Encrypted
message generated
output reg
encrypt_done=0; // Set when
encryption process is complete
wire
mult_done;
// Set when
polynomial multiplication: r*h is complete
wire
[big_size-1:0]
rxh;
// Product of r*h
polynomial_mult
poly2(.poly_prod(rxh),.poly1(key),.poly2(r_poly),.poly_done
(mult_done),.clk(clk),.rst(rst));
always @ (posedge mult_done)
begin
86
if ((msg[1]&msg[0]) ==1)
//check if msg bit is
-1: if yes, subtract 1 else add msgessage msg to the r*h
product
enc_msg[4:0] = rxh[4:0] - 1;
else
enc_msg[4:0] = rxh[4:0] + msg[1:0];
if ((msg[3]&msg[2]) ==1)
enc_msg[9:5] = rxh[9:5] - 1;
else
enc_msg[9:5] = rxh[9:5] + msg[3:2];
if ((msg[5]&msg[4]) ==1)
enc_msg[14:10] = rxh[14:10] - 1;
else
enc_msg[14:10] = rxh[14:10] + msg[5:4];
if ((msg[7]&msg[6]) ==1)
enc_msg[19:15] = rxh[19:15] - 1;
else
enc_msg[19:15] = rxh[19:15] + msg[7:6];
if ((msg[9]&msg[8]) ==1)
enc_msg[24:20] = rxh[24:20] - 1;
else
enc_msg[24:20] = rxh[24:20] + msg[9:8];
if ((msg[11]&msg[10]) ==1)
enc_msg[29:25] = rxh[29:25] - 1;
else
enc_msg[29:25] = rxh[29:25] + msg[11:10];
if ((msg[13]&msg[12]) ==1)
enc_msg[34:30] = rxh[34:30] - 1;
else
enc_msg[34:30] = rxh[34:30] + msg[13:12];
if ((msg[15]&msg[14]) ==1)
enc_msg[39:35] = rxh[39:35] - 1;
else
enc_msg[39:35] = rxh[39:35] + msg[15:14];
if ((msg[17]&msg[16]) ==1)
enc_msg[44:40] = rxh[44:40] - 1;
else
87
enc_msg[44:40] = rxh[44:40] + msg[17:16];
if ((msg[19]&msg[18]) ==1)
enc_msg[49:45] = rxh[49:45] - 1;
else
enc_msg[49:45] = rxh[49:45] + msg[19:18];
if ((msg[21]&msg[20]) ==1)
enc_msg[54:50] = rxh[54:50] - 1;
else
enc_msg[54:50] = rxh[54:50] + msg[21:20];
encrypt_done=1;
//done signal goes high only
only after encrypted msg is generated
end
endmodule // ntru_encryptor
___________________________________________________________
// Code for single stage of Decryptor block
// This block computes polynomial multiplcation product and
then does a mod3 operation on each coefficient element
module mult_mod(poly_mod,mult1,mult2,mod_done,clk,rst);
parameter
parameter
parameter
parameter
N= 11;
q= 5;
big_size= N*q;
small_size= N*2;
input
[big_size-1:0]
mult1;
// input
polynomial
input
[small_size-1:0] mult2;
// input
polynomial
input
clk,rst;
output wire [small_size-1:0] poly_mod; // Product of
polynomial multiplication, mod3
output wire
mod_done; // mod_done
wire
[big_size-1:0]
polynomial multiplication
mult_out;
// Product of
//Function mod3 computes the different mod3 values for a 5bit input ranging from 1-31
88
function[q-1:0] mod3;
input [q-1:0] mod_in;
begin
case(mod_in)
5'd2,5'd5,5'd8,5'd11,5'd14,5'd16,5'd19,5'd22,5'd25,5'd28,5'
d31 : mod3= -1;
5'd3,5'd6,5'd9,5'd12,5'd15,5'd17,5'd20,5'd23,5'd26,5'd29
: mod3= 0;
5'd1,5'd4,5'd7,5'd10,5'd13,5'd18,5'd21,5'd24,5'd27,5'd30
: mod3= 1;
default : mod3 =0;
endcase
end
endfunction // mod3
// Multiply 2 polynomials mod32
polynomial_mult
poly3(.poly_prod(mult_out),.poly1(mult1),.poly2(mult2),.pol
y_done(mod_done),.clk(clk),.rst(rst));
// Compute the mod3 value of each coefficient for the
product of the polynomial multiplication
assign poly_mod[1:0] = mod3(mult_out[4:0]);
assign poly_mod[3:2] = mod3(mult_out[9:5]);
assign poly_mod[5:4] = mod3(mult_out[14:10]);
assign poly_mod[7:6] = mod3(mult_out[19:15]);
assign poly_mod[9:8] = mod3(mult_out[24:20]);
assign poly_mod[11:10] = mod3(mult_out[29:25]);
assign poly_mod[13:12] = mod3(mult_out[34:30]);
assign poly_mod[15:14] = mod3(mult_out[39:35]);
assign poly_mod[17:16] = mod3(mult_out[44:40]);
assign poly_mod[19:18] = mod3(mult_out[49:45]);
assign poly_mod[21:20] = mod3(mult_out[54:50]);
endmodule // mult_mod
___________________________________________________________
// Code for combined Decryptor block
89
module
ntru_decryptor(dec_msg,enc_msg,f_poly,f_invp,decrypt_done,c
lk,rst);
parameter
parameter
parameter
parameter
N= 11;
q= 5;
big_size= N*q;
small_size= N*2;
input [big_size-1:0]
enc_msg;
message
input [small_size-1:0] f_poly;
polynomial
input [big_size-1:0]
f_invp;
polynomial f mod p
input
clk,rst;
output [small_size-1:0] dec_msg;
message
output wire
decrypt_done;
done
// Encrypted
// Random
// Inverse
// Decrypted
// Decryption
reg [small_size-1:0]
dec_b_reg;
wire [small_size-1:0]
dec_b;
wire
done_fe,done_Fpb,rst_fe,rst_Fpb;
assign
assign
assign
rst_fe = rst;
rst_Fpb = ~done_fe | rst;
decrypt_done = done_Fpb;
// Compute b = (f*e (modulo q))modulo_3
mult_mod fe(dec_b,enc_msg,f_poly,done_fe,clk,rst_fe);
always @ (done_fe)
begin
dec_b_reg <= dec_b;
end
// Compute c = Fp*dec_b_reg (modulo_3)
mult_mod
Fpb(dec_msg,f_invp,dec_b_reg,done_Fpb,clk,rst_Fpb);
endmodule
___________________________________________________________
90
// Code for the entire NTRU PKCS for input parameters:
N=11,q=5,p=3
module ntru_pkcs;
parameter N= 11;
parameter q= 5;
parameter p= 3;
parameter big_size= N*q;
parameter small_size= N*2;
// NTRU Key Creator
reg
clk,rst_key;
reg [big_size-1:0] f_invq;
reg [big_size-1:0]
pFq;
reg [small_size-1:0]
g_poly;
wire [big_size-1:0]
key;
wire
key_complete;
// NTRU Encryptor
reg [small_size-1:0]
r_poly=0;
reg [small_size-1:0]
msg=0;
reg [big_size-1:0]
key_reg=0;
wire
rst_encrypt;
wire [big_size-1:0]
enc_msg;
wire
encrypt_complete;
// NTRU Decryptor
reg [small_size-1:0]
f_poly;
wire
rst_decrypt;
wire
decrypt_complete;
reg [big_size-1:0]
f_invp;
wire [small_size-1:0]
dec_msg;
reg [small_size-1:0]
dec_msg_reg;
assign
assign
rst_encrypt = ~key_complete;
rst_decrypt = ~encrypt_complete | rst_key;
//Instantiate all the three blocks for key creation,
encryption, decryption
ntru_key
key_create(key,f_invq,g_poly,key_complete,clk,rst_key);
ntru_encryptor
encrypt(enc_msg,key_reg,r_poly,msg,encrypt_complete,clk,rst
_encrypt);
91
ntru_decryptor
decrypt(dec_msg,enc_msg,f_poly,f_invp,decrypt_complete,clk,
rst_decrypt);
wire [1:0]
g10,g9,g8,g7,g6,g5,g4,g3,g2,g1,g0,f10,f9,f8,f7,f6,f5,f
4,f3,f2,f1,f0,r10,r9,r8,r7,r6,r5,r4,r3,r2,r1,r0,m10,m9,m8,m
7,m6,m5,m4,m3,m2,m1,m0,c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0,ct
10,ct9,ct8,ct7,ct6,ct5,ct4,ct3,ct2,ct1,ct0;
wire [q-1:0]
ht10,ht9,ht8,ht7,ht6,ht5,ht4,ht3,ht2,ht1,ht0,h10,h9,h8
,h7,h6,h5,h4,h3,h2,h1,h0,fp10,fp9,fp8,fp7,fp6,fp5,fp4,fp3,f
p2,fp1,fp0,fq10,fq9,fq8,fq7,fq6,fq5,fq4,fq3,fq2,fq1,fq0,e10
,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0;
assign {g10,g9,g8,g7,g6,g5,g4,g3,g2,g1,g0}=g_poly;
assign {r10,r9,r8,r7,r6,r5,r4,r3,r2,r1,r0}=r_poly;
assign {f10,f9,f8,f7,f6,f5,f4,f3,f2,f1,f0}=f_poly;
assign {m10,m9,m8,m7,m6,m5,m4,m3,m2,m1,m0}=msg;
assign {c10,c9,c8,c7,c6,c5,c4,c3,c2,c1,c0}=dec_msg;
assign
{ct10,ct9,ct8,ct7,ct6,ct5,ct4,ct3,ct2,ct1,ct0}=dec_msg_reg;
assign
{fp10,fp9,fp8,fp7,fp6,fp5,fp4,fp3,fp2,fp1,fp0}=f_invp;
assign
{fq10,fq9,fq8,fq7,fq6,fq5,fq4,fq3,fq2,fq1,fq0}=f_invq;
assign {h10,h9,h8,h7,h6,h5,h4,h3,h2,h1,h0}=key;
assign
{ht10,ht9,ht8,ht7,ht6,ht5,ht4,ht3,ht2,ht1,ht0}=key_reg;
assign {e10,e9,e8,e7,e6,e5,e4,e3,e2,e1,e0}=enc_msg;
initial
$vcdpluson;
// Clock generator
initial
begin
clk = 0;
#10 forever #5 clk = ~clk;
end
// Input polynomials and display commands
92
initial
begin
//g = -1 + X2 + X3 + X5 - X8 - X10
g_poly = {-2'd1,2'd0,2'd1,2'd0,2'd0,2'd1,2'd0,2'd1,2'd1,2'd0,-2'd1};
//fq = 5 + 9X + 6X2 + 16X3 + 4X4 + 15X5 + 16X6 + 22X7 +
20X8 + 18X9 + 30X10
f_invq =
{5'd30,5'd18,5'd20,5'd22,5'd16,5'd15,5'd4,5'd16,5'd6,5'd9,5
'd5 } ;
//fp = 1 + 2X + 2X3 + 2X4 + X5 + 2X7 + X8 + 2X9
f_invp =
{5'd0,5'd2,5'd1,5'd2,5'd0,5'd1,5'd2,5'd2,5'd0,5'd2,5'd1};
//f = -1 + X + X2 - X4 + X6 + X9 - X10
f_poly = {-2'd1,2'd1,2'd0,2'd0,2'd1,2'd0,2'd1,2'd0,2'd1,2'd1,-2'd1};
//r = -1 + X2 + X3 + X4 - X5 - X7.
r_poly = {2'd0,2'd0,2'd0,-2'd1,2'd0,2'd1,2'd1,2'd1,2'd1,2'd0,-2'd1};
//m = -1 + X3 - X4 - X8 + X9 + X10
msg = {2'd1,2'd1,-2'd1,2'd0,2'd0,2'd0,2'd1,2'd1,2'd0,2'd0,-2'd1};
$display("#################################################
###########################################################
########################\n");
$display("############################################ NTRU
PKCS for N=11 q=5 p=3
############################################\n")
;
$display(" Input polynomials, f= %d %d %d %d %d %d %d %d %d
%d %d g= %d %d %d %d %d %d %d %d %d %d %d\n Inverse of f
modp, Fp= %d %d %d %d %d %d %d %d %d %d %d Inverse of f
modq, Fq= %d %d %d %d %d %d %d %d %d %d
%d",f0,f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,g0,g1,g2,g3,g4,g5,g6,
g7,g8,g9,g10,fp0,fp1,fp2,fp3,fp4,fp5,fp6,fp7,fp8,fp9,fp10,f
q0,fq1,fq2,fq3,fq4,fq5,fq6,fq7,fq8,fq9,fq10);
$display(" Random polynomials, r = %d %d %d %d %d %d %d %d
%d %d %d Message m= %d %d %d %d %d %d %d %d %d %d
93
%d\n",r0,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,m0,m1,m2,m3,m4,m5,m
6,m7,m8,m9,m10);
$display("#################################################
###########################################################
########################\n");
rst_key =1;
#10 rst_key =0;
#600 $finish;
end // initial begin
always @ (key)
begin
$display("time = %3d: key_complete=%d
encrypt_complete=%d decrypt_complete= %d h= %d %d %d %d %d
%d %d %d %d %d
%d\n",$time,key_complete,encrypt_complete,decrypt_complete,
h0,h1,h2,h3,h4,h5,h6,h7,h8,h9,h10);
end
always @ (posedge key_complete)
begin
key_reg <= key;
end
always @ (enc_msg)
begin
$display("time = %3d: key_complete=%d encrypt_complete=%d
decrypt_complete= %d e= %d %d %d %d %d %d %d %d %d %d
%d\n",$time,key_complete,encrypt_complete,decrypt_complete,
e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10);
end
always @ (dec_msg)
begin
$display("time = %3d: key_complete=%d encrypt_complete=%d
decrypt_complete= %d c= %d %d %d %d %d %d %d %d %d %d
%d\n",$time,key_complete,encrypt_complete,decrypt_complete,
c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10);
end
94
always @ (posedge decrypt_complete)
begin
dec_msg_reg <= dec_msg;
if(msg==dec_msg)
begin
#30
$display("#################################################
###########################################################
########################\n");
$display("###################### Success!!! The
decrypted message is the same as the original message sent
###################### \n");
$display("Public key h= %d %d %d %d %d %d %d %d %d %d
%d\nMessage sent m= %d %d %d %d %d %d %d %d %d %d
%d\nEncrypted message e= %d %d %d %d %d %d %d %d %d %d
%d\nDecrypted message c = %d %d %d %d %d %d %d %d %d %d
%d\n",ht0,ht1,ht2,ht3,ht4,ht5,ht6,ht7,ht8,ht9,ht10,m0,m1,m2
,m3,m4,m5,m6,m7,m8,m9,m10,e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10
,ct0,ct1,ct2,ct3,ct4,ct5,ct6,ct7,ct8,ct9,ct10);
$display("############################################
###########################################################
#############################");
$finish;
end
else
begin
#30
$display("#################################################
###########################################################
########################\n");
$display("###################### Fail!!! The
decrypted message and the original message sent are
different ###################### \n");
$display("Public key h= %d %d %d %d %d %d %d %d %d %d
%d\nMessage sent m= %d %d %d %d %d %d %d %d %d %d
%d\nEncrypted message, e=%d %d %d %d %d %d %d %d %d %d
%d\nDecrypted message, c=%d %d %d %d %d %d %d %d %d %d
%d\n",ht0,ht1,ht2,ht3,ht4,ht5,ht6,ht7,ht8,ht9,ht10,m0,m1,m2
,m3,m4,m5,m6,m7,m8,m9,m10,e0,e1,e2,e3,e4,e5,e6,e7,e8,e9,e10
,ct0,ct1,ct2,ct3,ct4,ct5,ct6,ct7,ct8,ct9,ct10);
$display("############################################
###########################################################
#############################");
$finish;
95
end
end
endmodule
___________________________________________________________
96
APPENDIX B
Synthesis Results
The model for N=107 was synthesized and below are the synthesis reports for the Key,
Encrypt, Decrypt blocks.
B.1 NTRU_Key
Release 10.1 - xst K.31 (nt)
Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved.
--> Parameter TMPDIR set to C:/Documents and
Settings/kamatp/N112_synth_key/xst/projnav.tmp
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.08 secs
--> Parameter xsthdpdir set to C:/Documents and
Settings/kamatp/N112_synth_key/xst
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.08 secs
--> Reading design: ntru_key.prj
TABLE OF CONTENTS
1) Synthesis Options Summary
2) HDL Compilation
3) Design Hierarchy Analysis
4) HDL Analysis
5) HDL Synthesis
5.1) HDL Synthesis Report
6) Advanced HDL Synthesis
6.1) Advanced HDL Synthesis Report
7) Low Level Synthesis
8) Partition Report
9) Final Report
97
===========================================================
==============
*
Synthesis Options Summary
*
===========================================================
==============
---- Source Parameters
Input File Name
: "ntru_key.prj"
Input Format
: mixed
Ignore Synthesis Constraint File
: NO
---- Target Parameters
Output File Name
Output Format
Target Device
: "ntru_key"
: NGC
: Automotive 9500XL
---- Source Options
Top Module Name
Automatic FSM Extraction
FSM Encoding Algorithm
Safe Implementation
Mux Extraction
Resource Sharing
:
:
:
:
:
:
ntru_key
YES
Auto
No
YES
YES
---- Target Options
Add IO Buffers
MACRO Preserve
XOR Preserve
Equivalent register Removal
:
:
:
:
YES
YES
YES
YES
---- General Options
Optimization Goal
Optimization Effort
Library Search Order
Keep Hierarchy
Netlist Hierarchy
RTL Output
Hierarchy Separator
Bus Delimiter
Case Specifier
Verilog 2001
:
:
:
:
:
:
:
:
:
:
Speed
1
ntru_key.lso
YES
as_optimized
Yes
/
<>
maintain
YES
---- Other Options
Clock Enable
wysiwyg
: YES
: NO
98
===========================================================
==============
===========================================================
==============
*
HDL Compilation
*
===========================================================
==============
Compiling verilog file "proc_unit.v" in library work
Compiling verilog file "coeff.v" in library work
Module <proc_unit> compiled
Compiling verilog file "bit4_cnt.v" in library work
Module <coeff> compiled
Compiling verilog file "barrel_shift.v" in library work
Module <bit4_cnt> compiled
Compiling verilog file "polynomial_mult.v" in library work
Module <barrel_shift> compiled
Compiling verilog file "const_mult.v" in library work
Module <polynomial_mult> compiled
Compiling verilog file "ntru_key.v" in library work
Module <const_mult> compiled
Module <ntru_key> compiled
No errors in compilation
Analysis of file <"ntru_key.prj"> succeeded.
===========================================================
==============
*
Design Hierarchy Analysis
*
===========================================================
==============
Analyzing hierarchy for module <ntru_key> in library <work>
with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
p = "11"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <const_mult> in library
<work> with parameters.
99
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
Analyzing hierarchy for module <polynomial_mult> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <bit4_cnt> in library
<work>.
Analyzing hierarchy for module <barrel_shift> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
Analyzing hierarchy for module <coeff> in library <work>
with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <proc_unit> in library
<work> with parameters.
q = "00000000000000000000000000000110"
===========================================================
==============
*
HDL Analysis
*
===========================================================
==============
Analyzing top module <ntru_key>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
p = 2'b11
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <ntru_key> is correct for synthesis.
100
Analyzing module <const_mult> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
Module <const_mult> is correct for synthesis.
Analyzing module <polynomial_mult> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <polynomial_mult> is correct for synthesis.
Analyzing module <bit4_cnt> in library <work>.
Module <bit4_cnt> is correct for synthesis.
Analyzing module <barrel_shift> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
Module <barrel_shift> is correct for synthesis.
Analyzing module <coeff> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <coeff> is correct for synthesis.
Analyzing module <proc_unit> in library <work>.
q = 32'sb00000000000000000000000000000110
Module <proc_unit> is correct for synthesis.
===========================================================
==============
*
HDL Synthesis
*
===========================================================
==============
Performing bidirectional port resolution...
Synthesizing Unit <const_mult>.
101
Related source file is "const_mult.v".
WARNING:Xst:643 - "const_mult.v" line 18: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 19: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 20: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 21: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 22: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 23: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
WARNING:Xst:643 - "const_mult.v" line 24: The result of a
6x2-bit multiplication is partially used. Only the 6 least
significant bits are used. If you are doing this on
purpose, you may safely ignore this warning. Otherwise,
make sure you are not losing information, leading to
unexpected circuit behavior.
Found 6x2-bit multiplier for signal
<prod_11_6$mult0002> created at line 19.
102
Found 6x2-bit multiplier for
<prod_17_12$mult0002> created at
Found 6x2-bit multiplier for
<prod_23_18$mult0002> created at
Found 6x2-bit multiplier for
<prod_29_24$mult0002> created at
Found 6x2-bit multiplier for
<prod_35_30$mult0002> created at
Found 6x2-bit multiplier for
<prod_41_36$mult0002> created at
Found 6x2-bit multiplier for
created at line 18.
Summary:
inferred
7 Multiplier(s).
Unit <const_mult> synthesized.
signal
line 20.
signal
line 21.
signal
line 22.
signal
line 23.
signal
line 24.
signal <prod_5_0$mult0002>
Synthesizing Unit <bit4_cnt>.
Related source file is "bit4_cnt.v".
Found 4-bit up counter for signal <cnt4>.
Summary:
inferred
1 Counter(s).
Unit <bit4_cnt> synthesized.
Synthesizing Unit <barrel_shift>.
Related source file is "barrel_shift.v".
Found 42-bit 16-to-1 multiplexer for signal
<shift_out>.
Unit <barrel_shift> synthesized.
Synthesizing Unit <proc_unit>.
Related source file is "proc_unit.v".
Found 6-bit adder for signal <out>.
Found 6-bit adder for signal <out$addsub0000> created
at line 28.
Summary:
inferred
2 Adder/Subtractor(s).
Unit <proc_unit> synthesized.
Synthesizing Unit <coeff>.
Related source file is "coeff.v".
Unit <coeff> synthesized.
103
Synthesizing Unit <polynomial_mult>.
Related source file is "polynomial_mult.v".
Found 42-bit register for signal <poly_prod>.
Found 1-bit register for signal <poly_done_temp>.
Found 42-bit adder for signal <poly_prod$addsub0000>
created at line 42.
Found 4x3-bit multiplier for signal
<prod_temp$mult0000> created at line 29.
Found 42-bit shifter logical left for signal
<prod_temp$shift0000>.
Summary:
inferred
1 D-type flip-flop(s).
inferred
1 Adder/Subtractor(s).
inferred
1 Multiplier(s).
inferred
1 Combinational logic shifter(s).
Unit <polynomial_mult> synthesized.
Synthesizing Unit <ntru_key>.
Related source file is "ntru_key.v".
Unit <ntru_key> synthesized.
===========================================================
==============
HDL Synthesis Report
Macro Statistics
# Multipliers
4x3-bit multiplier
6x2-bit multiplier
# Adders/Subtractors
42-bit adder
6-bit adder
# Counters
4-bit up counter
# Registers
1-bit register
42-bit register
# Multiplexers
42-bit 16-to-1 multiplexer
# Logic shifters
42-bit shifter logical left
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
8
1
7
15
1
14
1
1
2
1
1
1
1
1
1
104
===========================================================
==============
===========================================================
==============
*
Advanced HDL Synthesis
*
===========================================================
==============
WARNING:Xst:1426 - The value init of the FF/Latch
poly_done_temp hinder the constant cleaning in the block
polynomial_mult.
You should achieve better results by setting this init
to 1.
===========================================================
==============
Advanced HDL Synthesis Report
Macro Statistics
# Multipliers
4x3-bit multiplier
6x2-bit multiplier
# Adders/Subtractors
42-bit adder
6-bit adder
# Counters
4-bit up counter
# Registers
Flip-Flops
# Multiplexers
42-bit 16-to-1 multiplexer
:
:
:
:
:
:
:
:
:
:
:
:
8
1
7
15
1
14
1
1
43
43
1
1
===========================================================
==============
===========================================================
==============
*
Low Level Synthesis
*
===========================================================
==============
105
Optimizing unit <ntru_key> ...
Optimizing unit <barrel_shift> ...
Optimizing unit <const_mult> ...
Optimizing unit <bit4_cnt> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
:
:
:
:
cnt4_3
cnt4_2
cnt4_1
cnt4_0
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
poly_prod_41
poly_done_temp
poly_prod_0
poly_prod_1
poly_prod_2
poly_prod_3
poly_prod_4
poly_prod_5
poly_prod_6
poly_prod_7
poly_prod_8
poly_prod_9
poly_prod_10
poly_prod_11
poly_prod_12
poly_prod_13
poly_prod_14
poly_prod_15
poly_prod_16
poly_prod_17
poly_prod_18
poly_prod_19
poly_prod_20
poly_prod_21
poly_prod_22
poly_prod_23
poly_prod_24
poly_prod_25
Optimizing unit <proc_unit> ...
Optimizing unit <coeff> ...
Optimizing unit <polynomial_mult> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
106
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
poly_prod_26
poly_prod_27
poly_prod_28
poly_prod_29
poly_prod_30
poly_prod_31
poly_prod_32
poly_prod_33
poly_prod_34
poly_prod_35
poly_prod_36
poly_prod_37
poly_prod_38
poly_prod_39
poly_prod_40
===========================================================
==============
*
Partition Report
*
===========================================================
==============
Partition Implementation Status
------------------------------No Partitions were found in this design.
------------------------------===========================================================
==============
*
Final Report
*
===========================================================
==============
Final Results
RTL Top Level Output File Name
: ntru_key.ngr
Top Level Output File Name
: ntru_key
Output Format
: NGC
Optimization Goal
: Speed
Keep Hierarchy
: YES
Target Technology
: Automotive 9500XL
Macro Preserve
: YES
XOR Preserve
: YES
107
Clock Enable
wysiwyg
: YES
: NO
Design Statistics
# IOs
: 101
Cell Usage :
# BELS
: 1751
#
AND2
: 870
#
AND3
: 10
#
AND4
: 22
#
AND6
: 2
#
AND7
: 2
#
GND
: 1
#
INV
: 267
#
OR2
: 203
#
OR3
: 15
#
OR7
: 42
#
VCC
: 1
#
XOR2
: 316
# FlipFlops/Latches
: 47
#
FDC
: 46
#
FDCE
: 1
# IO Buffers
: 101
#
IBUF
: 58
#
OBUF
: 43
===========================================================
==============
Total REAL time to Xst completion: 6.00 secs
Total CPU time to Xst completion: 6.22 secs
-->
Total memory usage is 144528 kilobytes
Number of errors
:
Number of warnings :
Number of infos
:
0 (
8 (
0 (
0 filtered)
0 filtered)
0 filtered)
108
B.2 NTRU_ENCRYPTOR:
Release 10.1 - xst K.31 (nt)
Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved.
--> Parameter TMPDIR set to C:/Documents and
Settings/kamatp/N112_synth_enc/xst/projnav.tmp
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.08 secs
--> Parameter xsthdpdir set to C:/Documents and
Settings/kamatp/N112_synth_enc/xst
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.08 secs
--> Reading design: ntru_encryptor_blk.prj
TABLE OF CONTENTS
1) Synthesis Options Summary
2) HDL Compilation
3) Design Hierarchy Analysis
4) HDL Analysis
5) HDL Synthesis
5.1) HDL Synthesis Report
6) Advanced HDL Synthesis
6.1) Advanced HDL Synthesis Report
7) Low Level Synthesis
8) Partition Report
9) Final Report
===========================================================
==============
*
Synthesis Options Summary
*
===========================================================
==============
---- Source Parameters
Input File Name
:
"ntru_encryptor_blk.prj"
Input Format
: mixed
Ignore Synthesis Constraint File
: NO
109
---- Target Parameters
Output File Name
Output Format
Target Device
: "ntru_encryptor_blk"
: NGC
: Automotive 9500XL
---- Source Options
Top Module Name
Automatic FSM Extraction
FSM Encoding Algorithm
Safe Implementation
Mux Extraction
Resource Sharing
:
:
:
:
:
:
ntru_encryptor_blk
YES
Auto
No
YES
YES
---- Target Options
Add IO Buffers
MACRO Preserve
XOR Preserve
Equivalent register Removal
:
:
:
:
YES
YES
YES
YES
---- General Options
Optimization Goal
Optimization Effort
Library Search Order
Keep Hierarchy
Netlist Hierarchy
RTL Output
Hierarchy Separator
Bus Delimiter
Case Specifier
Verilog 2001
:
:
:
:
:
:
:
:
:
:
Speed
1
ntru_encryptor_blk.lso
YES
as_optimized
Yes
/
<>
maintain
YES
---- Other Options
Clock Enable
wysiwyg
: YES
: NO
===========================================================
==============
===========================================================
==============
*
HDL Compilation
*
===========================================================
==============
110
Compiling verilog file "proc_unit.v" in library work
Compiling verilog file "coeff.v" in library work
Module <proc_unit> compiled
Compiling verilog file "bit4_cnt.v" in library work
Module <coeff> compiled
Compiling verilog file "barrel_shift.v" in library work
Module <bit4_cnt> compiled
Compiling verilog file "polynomial_mult.v" in library work
Module <barrel_shift> compiled
Compiling verilog file "ntru_encryptor.v" in library work
Module <polynomial_mult> compiled
Compiling verilog file "ntru_encryptor_blk.v" in library
work
Module <ntru_encryptor> compiled
Module <ntru_encryptor_blk> compiled
No errors in compilation
Analysis of file <"ntru_encryptor_blk.prj"> succeeded.
===========================================================
==============
*
Design Hierarchy Analysis
*
===========================================================
==============
Analyzing hierarchy for module <ntru_encryptor_blk> in
library <work> with parameters.
N = "00000000000000000000000001110000"
big_size = "00000000000000000000001010100000"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000011100000"
Analyzing hierarchy for module <ntru_encryptor> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <polynomial_mult> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
111
Analyzing hierarchy for module <bit4_cnt> in library
<work>.
Analyzing hierarchy for module <barrel_shift> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
Analyzing hierarchy for module <coeff> in library <work>
with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <proc_unit> in library
<work> with parameters.
q = "00000000000000000000000000000110"
===========================================================
==============
*
HDL Analysis
*
===========================================================
==============
Analyzing top module <ntru_encryptor_blk>.
N = 32'sb00000000000000000000000001110000
big_size = 32'sb00000000000000000000001010100000
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000011100000
Module <ntru_encryptor_blk> is correct for synthesis.
Analyzing module <ntru_encryptor> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <ntru_encryptor> is correct for synthesis.
Analyzing module <polynomial_mult> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
112
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <polynomial_mult> is correct for synthesis.
Analyzing module <bit4_cnt> in library <work>.
Module <bit4_cnt> is correct for synthesis.
Analyzing module <barrel_shift> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
Module <barrel_shift> is correct for synthesis.
Analyzing module <coeff> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <coeff> is correct for synthesis.
Analyzing module <proc_unit> in library <work>.
q = 32'sb00000000000000000000000000000110
Module <proc_unit> is correct for synthesis.
===========================================================
==============
*
HDL Synthesis
*
===========================================================
==============
Performing bidirectional port resolution...
Synthesizing Unit <bit4_cnt>.
Related source file is "bit4_cnt.v".
Found 4-bit up counter for signal <cnt4>.
Summary:
inferred
1 Counter(s).
Unit <bit4_cnt> synthesized.
Synthesizing Unit <barrel_shift>.
Related source file is "barrel_shift.v".
113
Found 42-bit 16-to-1 multiplexer for signal
<shift_out>.
Unit <barrel_shift> synthesized.
Synthesizing Unit <proc_unit>.
Related source file is "proc_unit.v".
Found 6-bit adder for signal <out>.
Found 6-bit adder for signal <out$addsub0000> created
at line 28.
Summary:
inferred
2 Adder/Subtractor(s).
Unit <proc_unit> synthesized.
Synthesizing Unit <coeff>.
Related source file is "coeff.v".
Unit <coeff> synthesized.
Synthesizing Unit <polynomial_mult>.
Related source file is "polynomial_mult.v".
Found 42-bit register for signal <poly_prod>.
Found 1-bit register for signal <poly_done_temp>.
Found 42-bit adder for signal <poly_prod$addsub0000>
created at line 42.
Found 4x3-bit multiplier for signal
<prod_temp$mult0000> created at line 29.
Found 42-bit shifter logical left for signal
<prod_temp$shift0000>.
Summary:
inferred
1 D-type flip-flop(s).
inferred
1 Adder/Subtractor(s).
inferred
1 Multiplier(s).
inferred
1 Combinational logic shifter(s).
Unit <polynomial_mult> synthesized.
Synthesizing Unit <ntru_encryptor>.
Related source file is "ntru_encryptor.v".
Found 42-bit register for signal <enc_msg>.
Found 1-bit register for signal <encrypt_done>.
Found 6-bit adder for signal <$add0000> created at line
31.
114
Found 6-bit adder for signal <$add0001> created at line
36.
Found 6-bit adder for signal <$add0002> created at line
41.
Found 6-bit adder for signal <$add0003> created at line
46.
Found 6-bit adder for signal <$add0004> created at line
51.
Found 6-bit adder for signal <$add0005> created at line
56.
Found 6-bit adder for signal <$add0006> created at line
61.
Found 6-bit subtractor for signal <$sub0000>
line 29.
Found 6-bit subtractor for signal <$sub0001>
line 34.
Found 6-bit subtractor for signal <$sub0002>
line 39.
Found 6-bit subtractor for signal <$sub0003>
line 44.
Found 6-bit subtractor for signal <$sub0004>
line 49.
Found 6-bit subtractor for signal <$sub0005>
line 54.
Found 6-bit subtractor for signal <$sub0006>
line 59.
Summary:
inferred 43 D-type flip-flop(s).
inferred 14 Adder/Subtractor(s).
Unit <ntru_encryptor> synthesized.
created at
created at
created at
created at
created at
created at
created at
Synthesizing Unit <ntru_encryptor_blk>.
Related source file is "ntru_encryptor_blk.v".
WARNING:Xst:647 - Input <msg<223:214>> is never used. This
port will be preserved and left unconnected if it belongs
to a top-level block or it belongs to a sub-block and the
hierarchy of this sub-block is preserved.
WARNING:Xst:647 - Input <r_poly<223:214>> is never used.
This port will be preserved and left unconnected if it
belongs to a top-level block or it belongs to a sub-block
and the hierarchy of this sub-block is preserved.
WARNING:Xst:646 - Signal <d_9> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
115
WARNING:Xst:646 - Signal <d_8> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_7> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_6> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_5> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_4> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_3> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_2> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_15> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_14> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_13> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_12> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_11> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_10> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_1> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
Unit <ntru_encryptor_blk> synthesized.
116
===========================================================
==============
HDL Synthesis Report
Macro Statistics
# Multipliers
4x3-bit multiplier
# Adders/Subtractors
464
42-bit adder
6-bit adder
336
6-bit subtractor
112
# Counters
4-bit up counter
# Registers
720
1-bit register
704
42-bit register
# Multiplexers
42-bit 16-to-1 multiplexer
# Logic shifters
42-bit shifter logical left
: 16
: 16
:
: 16
:
:
: 16
: 16
:
:
:
:
:
:
:
16
16
16
16
16
===========================================================
==============
===========================================================
==============
*
Advanced HDL Synthesis
*
===========================================================
==============
WARNING:Xst:1426 - The value init of the FF/Latch
poly_done_temp hinder the constant cleaning in the block
polynomial_mult.
You should achieve better results by setting this init
to 1.
WARNING:Xst:1426 - The value init of the FF/Latch
encrypt_done hinder the constant cleaning in the block
ntru_encryptor.
117
You should achieve better results by setting this
to 1.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc1>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc2>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc3>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc4>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc5>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc6>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc7>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc8>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc9>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc10>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc11>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc12>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc13>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc14>.
WARNING:Xst:2677 - Node <encrypt_done> of sequential
is unconnected in block <enc15>.
init
type
type
type
type
type
type
type
type
type
type
type
type
type
type
type
===========================================================
==============
Advanced HDL Synthesis Report
Macro Statistics
# Multipliers
4x3-bit multiplier
# Adders/Subtractors
464
42-bit adder
6-bit adder
336
: 16
: 16
:
: 16
:
118
6-bit subtractor
112
# Counters
4-bit up counter
# Registers
1376
Flip-Flops
1376
# Multiplexers
42-bit 16-to-1 multiplexer
:
: 16
: 16
:
:
: 16
: 16
===========================================================
==============
===========================================================
==============
*
Low Level Synthesis
*
===========================================================
==============
Optimizing unit <ntru_encryptor_blk> ...
Optimizing unit <barrel_shift> ...
Optimizing unit <bit4_cnt> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
:
:
:
:
cnt4_3
cnt4_2
cnt4_1
cnt4_0
:
:
:
:
:
:
:
:
:
poly_prod_41
poly_done_temp
poly_prod_0
poly_prod_1
poly_prod_2
poly_prod_3
poly_prod_4
poly_prod_5
poly_prod_6
Optimizing unit <proc_unit> ...
Optimizing unit <coeff> ...
Optimizing unit <polynomial_mult> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
119
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
Optimizing unit <ntru_encryptor> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
poly_prod_7
poly_prod_8
poly_prod_9
poly_prod_10
poly_prod_11
poly_prod_12
poly_prod_13
poly_prod_14
poly_prod_15
poly_prod_16
poly_prod_17
poly_prod_18
poly_prod_19
poly_prod_20
poly_prod_21
poly_prod_22
poly_prod_23
poly_prod_24
poly_prod_25
poly_prod_26
poly_prod_27
poly_prod_28
poly_prod_29
poly_prod_30
poly_prod_31
poly_prod_32
poly_prod_33
poly_prod_34
poly_prod_35
poly_prod_36
poly_prod_37
poly_prod_38
poly_prod_39
poly_prod_40
:
:
:
:
:
:
:
:
:
enc_msg_5
enc_msg_4
enc_msg_3
enc_msg_2
enc_msg_1
enc_msg_0
enc_msg_11
enc_msg_10
enc_msg_9
120
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
WARNING:Xst:2677 - Node <encrypt_done>
is unconnected in block <enc15>.
WARNING:Xst:2677 - Node <encrypt_done>
is unconnected in block <enc14>.
WARNING:Xst:2677 - Node <encrypt_done>
is unconnected in block <enc13>.
WARNING:Xst:2677 - Node <encrypt_done>
is unconnected in block <enc12>.
WARNING:Xst:2677 - Node <encrypt_done>
is unconnected in block <enc11>.
: enc_msg_8
: enc_msg_7
: enc_msg_6
: enc_msg_17
: enc_msg_16
: enc_msg_15
: enc_msg_14
: enc_msg_13
: enc_msg_12
: enc_msg_23
: enc_msg_22
: enc_msg_21
: enc_msg_20
: enc_msg_19
: enc_msg_18
: enc_msg_29
: enc_msg_28
: enc_msg_27
: enc_msg_26
: enc_msg_25
: enc_msg_24
: enc_msg_35
: enc_msg_34
: enc_msg_33
: enc_msg_32
: enc_msg_31
: enc_msg_30
: enc_msg_41
: enc_msg_40
: enc_msg_39
: enc_msg_38
: enc_msg_37
: enc_msg_36
: encrypt_done
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
121
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
WARNING:Xst:2677 - Node
is unconnected in block
<encrypt_done>
<enc10>.
<encrypt_done>
<enc9>.
<encrypt_done>
<enc8>.
<encrypt_done>
<enc7>.
<encrypt_done>
<enc6>.
<encrypt_done>
<enc5>.
<encrypt_done>
<enc4>.
<encrypt_done>
<enc3>.
<encrypt_done>
<enc2>.
<encrypt_done>
<enc1>.
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
of sequential type
===========================================================
==============
*
Partition Report
*
===========================================================
==============
Partition Implementation Status
------------------------------No Partitions were found in this design.
------------------------------===========================================================
==============
*
Final Report
*
===========================================================
==============
Final Results
RTL Top Level Output File Name
: ntru_encryptor_blk.ngr
Top Level Output File Name
: ntru_encryptor_blk
Output Format
: NGC
122
Optimization Goal
Keep Hierarchy
Target Technology
Macro Preserve
XOR Preserve
Clock Enable
wysiwyg
:
:
:
:
:
:
:
Speed
YES
Automotive 9500XL
YES
YES
YES
NO
Design Statistics
# IOs
: 1165
Cell Usage :
# BELS
: 18000
#
AND2
: 6688
#
AND3
: 160
#
AND4
: 352
#
AND6
: 32
#
AND7
: 32
#
GND
: 16
#
INV
: 4096
#
OR2
: 2064
#
OR3
: 16
#
OR7
: 192
#
VCC
: 32
#
XOR2
: 4320
# FlipFlops/Latches
: 1440
#
FD
: 688
#
FDC
: 736
#
FDCE
: 16
# IO Buffers
: 1145
#
IBUF
: 472
#
OBUF
: 673
===========================================================
==============
Total REAL time to Xst completion: 39.00 secs
Total CPU time to Xst completion: 38.78 secs
-->
Total memory usage is 245584 kilobytes
Number of errors
:
Number of warnings :
0 (
49 (
0 filtered)
0 filtered)
123
Number of infos
:
0 (
0 filtered)
B.3 NTRU_DECRYPTOR:
Release 10.1 - xst K.31 (nt)
Copyright (c) 1995-2008 Xilinx, Inc. All rights reserved.
--> Parameter TMPDIR set to C:/Documents and
Settings/kamatp/N112_synth_dec/xst/projnav.tmp
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.06 secs
--> Parameter xsthdpdir set to C:/Documents and
Settings/kamatp/N112_synth_dec/xst
Total REAL time to Xst completion: 0.00 secs
Total CPU time to Xst completion: 0.06 secs
--> Reading design: ntru_decryptor_blk.prj
TABLE OF CONTENTS
1) Synthesis Options Summary
2) HDL Compilation
3) Design Hierarchy Analysis
4) HDL Analysis
5) HDL Synthesis
5.1) HDL Synthesis Report
6) Advanced HDL Synthesis
6.1) Advanced HDL Synthesis Report
7) Low Level Synthesis
8) Partition Report
9) Final Report
===========================================================
==============
*
Synthesis Options Summary
*
===========================================================
==============
---- Source Parameters
Input File Name
:
"ntru_decryptor_blk.prj"
124
Input Format
Ignore Synthesis Constraint File
: mixed
: NO
---- Target Parameters
Output File Name
Output Format
Target Device
: "ntru_decryptor_blk"
: NGC
: Automotive 9500XL
---- Source Options
Top Module Name
Automatic FSM Extraction
FSM Encoding Algorithm
Safe Implementation
Mux Extraction
Resource Sharing
:
:
:
:
:
:
ntru_decryptor_blk
YES
Auto
No
YES
YES
---- Target Options
Add IO Buffers
MACRO Preserve
XOR Preserve
Equivalent register Removal
:
:
:
:
YES
YES
YES
YES
---- General Options
Optimization Goal
Optimization Effort
Library Search Order
Keep Hierarchy
Netlist Hierarchy
RTL Output
Hierarchy Separator
Bus Delimiter
Case Specifier
Verilog 2001
:
:
:
:
:
:
:
:
:
:
Speed
1
ntru_decryptor_blk.lso
YES
as_optimized
Yes
/
<>
maintain
YES
---- Other Options
Clock Enable
wysiwyg
: YES
: NO
===========================================================
==============
===========================================================
==============
125
*
HDL Compilation
*
===========================================================
==============
Compiling verilog file "proc_unit.v" in library work
Compiling verilog file "coeff.v" in library work
Compiling verilog include file "proc_unit.v"
Module <proc_unit> compiled
Compiling verilog file "bit4_cnt.v" in library work
Module <coeff> compiled
Compiling verilog file "barrel_shift.v" in library work
Module <bit4_cnt> compiled
Compiling verilog file "polynomial_mult.v" in library work
Module <barrel_shift> compiled
Compiling verilog file "mult_mod.v" in library work
Module <polynomial_mult> compiled
Compiling verilog file "ntru_decryptor.v" in library work
Module <mult_mod> compiled
Compiling verilog file "ntru_decryptor_blk.v" in library
work
Module <ntru_decryptor> compiled
Module <ntru_decryptor_blk> compiled
No errors in compilation
Analysis of file <"ntru_decryptor_blk.prj"> succeeded.
===========================================================
==============
*
Design Hierarchy Analysis
*
===========================================================
==============
Analyzing hierarchy for module <ntru_decryptor_blk> in
library <work> with parameters.
N = "00000000000000000000000001110000"
big_size = "00000000000000000000001010100000"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000011100000"
Analyzing hierarchy for module <ntru_decryptor> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
126
Analyzing hierarchy for module <mult_mod> in library <work>
with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <polynomial_mult> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <bit4_cnt> in library
<work>.
Analyzing hierarchy for module <barrel_shift> in library
<work> with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
Analyzing hierarchy for module <coeff> in library <work>
with parameters.
N = "00000000000000000000000000000111"
big_size = "00000000000000000000000000101010"
q = "00000000000000000000000000000110"
small_size = "00000000000000000000000000001110"
Analyzing hierarchy for module <proc_unit> in library
<work> with parameters.
q = "00000000000000000000000000000110"
===========================================================
==============
*
HDL Analysis
*
===========================================================
==============
Analyzing top module <ntru_decryptor_blk>.
N = 32'sb00000000000000000000000001110000
big_size = 32'sb00000000000000000000001010100000
127
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000011100000
Module <ntru_decryptor_blk> is correct for synthesis.
Analyzing module <ntru_decryptor> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
WARNING:Xst:905 - "ntru_decryptor.v" line 28: One or more
signals are missing in the sensitivity list of always
block. To enable synthesis of FPGA/CPLD hardware, XST will
assume that all necessary signals are present in the
sensitivity list. Please note that the result of the
synthesis may differ from the initial design specification.
The missing signals are:
<dec_b>
Module <ntru_decryptor> is correct for synthesis.
Analyzing module <mult_mod> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Calling function <mod3>.
Calling function <mod3>.
Calling function <mod3>.
Calling function <mod3>.
Calling function <mod3>.
Calling function <mod3>.
Calling function <mod3>.
Module <mult_mod> is correct for synthesis.
Analyzing module <polynomial_mult> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <polynomial_mult> is correct for synthesis.
Analyzing module <bit4_cnt> in library <work>.
Module <bit4_cnt> is correct for synthesis.
Analyzing module <barrel_shift> in library <work>.
N = 32'sb00000000000000000000000000000111
128
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
Module <barrel_shift> is correct for synthesis.
Analyzing module <coeff> in library <work>.
N = 32'sb00000000000000000000000000000111
big_size = 32'sb00000000000000000000000000101010
q = 32'sb00000000000000000000000000000110
small_size = 32'sb00000000000000000000000000001110
Module <coeff> is correct for synthesis.
Analyzing module <proc_unit> in library <work>.
q = 32'sb00000000000000000000000000000110
Module <proc_unit> is correct for synthesis.
===========================================================
==============
*
HDL Synthesis
*
===========================================================
==============
Performing bidirectional port resolution...
Synthesizing Unit <bit4_cnt>.
Related source file is "bit4_cnt.v".
Found 4-bit up counter for signal <cnt4>.
Summary:
inferred
1 Counter(s).
Unit <bit4_cnt> synthesized.
Synthesizing Unit <barrel_shift>.
Related source file is "barrel_shift.v".
Found 42-bit 16-to-1 multiplexer for signal
<shift_out>.
Unit <barrel_shift> synthesized.
Synthesizing Unit <proc_unit>.
Related source file is "proc_unit.v".
Found 6-bit adder for signal <out>.
Found 6-bit adder for signal <out$addsub0000> created
at line 28.
129
Summary:
inferred
2 Adder/Subtractor(s).
Unit <proc_unit> synthesized.
Synthesizing Unit <coeff>.
Related source file is "coeff.v".
Unit <coeff> synthesized.
Synthesizing Unit <polynomial_mult>.
Related source file is "polynomial_mult.v".
Found 42-bit register for signal <poly_prod>.
Found 1-bit register for signal <poly_done_temp>.
Found 42-bit adder for signal <poly_prod$addsub0000>
created at line 42.
Found 4x3-bit multiplier for signal
<prod_temp$mult0000> created at line 29.
Found 42-bit shifter logical left for signal
<prod_temp$shift0000>.
Summary:
inferred
1 D-type flip-flop(s).
inferred
1 Adder/Subtractor(s).
inferred
1 Multiplier(s).
inferred
1 Combinational logic shifter(s).
Unit <polynomial_mult> synthesized.
Synthesizing Unit <mult_mod>.
Related source file is "mult_mod.v".
WARNING:Xst:646 - Signal <mod3/7/mod3<5:2>>
never used. This unconnected signal will be
the optimization process.
WARNING:Xst:646 - Signal <mod3/6/mod3<5:2>>
never used. This unconnected signal will be
the optimization process.
WARNING:Xst:646 - Signal <mod3/5/mod3<5:2>>
never used. This unconnected signal will be
the optimization process.
WARNING:Xst:646 - Signal <mod3/4/mod3<5:2>>
never used. This unconnected signal will be
the optimization process.
WARNING:Xst:646 - Signal <mod3/3/mod3<5:2>>
never used. This unconnected signal will be
the optimization process.
is assigned but
trimmed during
is assigned but
trimmed during
is assigned but
trimmed during
is assigned but
trimmed during
is assigned but
trimmed during
130
WARNING:Xst:646 - Signal <mod3/2/mod3<5:2>> is assigned but
never used. This unconnected signal will be trimmed during
the optimization process.
WARNING:Xst:646 - Signal <mod3/1/mod3<5:2>> is assigned but
never used. This unconnected signal will be trimmed during
the optimization process.
Found 64x6-bit ROM for signal <mod3/1/mod3>.
Found 64x6-bit ROM for signal <mod3/2/mod3>.
Found 64x6-bit ROM for signal <mod3/3/mod3>.
Found 64x6-bit ROM for signal <mod3/4/mod3>.
Found 64x6-bit ROM for signal <mod3/5/mod3>.
Found 64x6-bit ROM for signal <mod3/6/mod3>.
Found 64x6-bit ROM for signal <mod3/7/mod3>.
Summary:
inferred
7 ROM(s).
Unit <mult_mod> synthesized.
Synthesizing Unit <ntru_decryptor>.
Related source file is "ntru_decryptor.v".
Unit <ntru_decryptor> synthesized.
Synthesizing Unit <ntru_decryptor_blk>.
Related source file is "ntru_decryptor_blk.v".
WARNING:Xst:646 - Signal <d_9> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_8> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_7> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_6> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_5> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_4> is assigned but never
This unconnected signal will be trimmed during the
optimization process.
used.
used.
used.
used.
used.
used.
131
WARNING:Xst:646 - Signal <d_3> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_2> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_15> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_14> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_13> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_12> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_11> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_10> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
WARNING:Xst:646 - Signal <d_1> is assigned but never used.
This unconnected signal will be trimmed during the
optimization process.
Unit <ntru_decryptor_blk> synthesized.
===========================================================
==============
HDL Synthesis Report
Macro Statistics
# ROMs
224
64x6-bit ROM
224
# Multipliers
4x3-bit multiplier
# Adders/Subtractors
480
42-bit adder
:
:
: 32
: 32
:
: 32
132
6-bit adder
448
# Counters
4-bit up counter
# Registers
1-bit register
42-bit register
# Multiplexers
42-bit 16-to-1 multiplexer
# Logic shifters
42-bit shifter logical left
:
:
:
:
:
:
:
:
:
:
32
32
64
32
32
32
32
32
32
===========================================================
==============
===========================================================
==============
*
Advanced HDL Synthesis
*
===========================================================
==============
WARNING:Xst:1426 - The value init of the FF/Latch
poly_done_temp hinder the constant cleaning in the block
polynomial_mult.
You should achieve better results by setting this init
to 1.
===========================================================
==============
Advanced HDL Synthesis Report
Macro Statistics
# ROMs
224
64x6-bit ROM
224
# Multipliers
4x3-bit multiplier
# Adders/Subtractors
480
42-bit adder
6-bit adder
448
# Counters
:
:
: 32
: 32
:
: 32
:
: 32
133
4-bit up counter
# Registers
1376
Flip-Flops
1376
# Multiplexers
42-bit 16-to-1 multiplexer
: 32
:
:
: 32
: 32
===========================================================
==============
===========================================================
==============
*
Low Level Synthesis
*
===========================================================
==============
Optimizing unit <ntru_decryptor_blk> ...
Optimizing unit <barrel_shift> ...
Optimizing unit <bit4_cnt> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
:
:
:
:
cnt4_3
cnt4_2
cnt4_1
cnt4_0
:
:
:
:
:
:
:
:
:
:
:
:
poly_prod_41
poly_done_temp
poly_prod_0
poly_prod_1
poly_prod_2
poly_prod_3
poly_prod_4
poly_prod_5
poly_prod_6
poly_prod_7
poly_prod_8
poly_prod_9
Optimizing unit <proc_unit> ...
Optimizing unit <coeff> ...
Optimizing unit <polynomial_mult> ...
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
implementation constraint: INIT=r
134
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
implementation
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
constraint:
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
INIT=r
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
poly_prod_10
poly_prod_11
poly_prod_12
poly_prod_13
poly_prod_14
poly_prod_15
poly_prod_16
poly_prod_17
poly_prod_18
poly_prod_19
poly_prod_20
poly_prod_21
poly_prod_22
poly_prod_23
poly_prod_24
poly_prod_25
poly_prod_26
poly_prod_27
poly_prod_28
poly_prod_29
poly_prod_30
poly_prod_31
poly_prod_32
poly_prod_33
poly_prod_34
poly_prod_35
poly_prod_36
poly_prod_37
poly_prod_38
poly_prod_39
poly_prod_40
Optimizing unit <mult_mod> ...
Optimizing unit <ntru_decryptor> ...
===========================================================
==============
*
Partition Report
*
===========================================================
==============
Partition Implementation Status
-------------------------------
135
No Partitions were found in this design.
------------------------------===========================================================
==============
*
Final Report
*
===========================================================
==============
Final Results
RTL Top Level Output File Name
: ntru_decryptor_blk.ngr
Top Level Output File Name
: ntru_decryptor_blk
Output Format
: NGC
Optimization Goal
: Speed
Keep Hierarchy
: YES
Target Technology
: Automotive 9500XL
Macro Preserve
: YES
XOR Preserve
: YES
Clock Enable
: YES
wysiwyg
: NO
Design Statistics
# IOs
: 955
Cell Usage :
# BELS
#
AND2
#
AND3
#
AND4
#
AND6
#
AND7
#
GND
#
INV
#
OR2
#
OR3
#
OR7
#
VCC
#
XOR2
# FlipFlops/Latches
#
FDC
#
FDCE
# IO Buffers
#
IBUF
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
:
82560
36256
3264
736
64
64
32
19632
10352
1152
1344
32
9632
1504
1472
32
955
730
136
#
OBUF
: 225
===========================================================
==============
Total REAL time to Xst completion: 76.00 secs
Total CPU time to Xst completion: 76.10 secs
-->
Total memory usage is 381072 kilobytes
Number of errors
:
Number of warnings :
Number of infos
:
0 (
24 (
0 (
0 filtered)
0 filtered)
0 filtered)
137
APPENDIX C
The NTRU Public Key Cryptosystem (PKCS)
C.1 NTRU PKCS Parameters [3, 6]
The basic collection of objects used by the NTRU PKCS is the ring R that
consists of all truncated polynomials of degree N-1 having integer coefficients:
a = a0 + a1X + a2X2 + a3X3 + . . . + aN-2XN-2 + aN-1XN-1.
An implementation of the NTRU Public Key Cryptosystem is specified by the following
parameters [3].
N - The polynomials in the truncated polynomial ring have degree N-1.
q - Large modulus: usually, the coefficients of the truncated polynomials will be reduced
modq.
p - small modulus. As the final step in decryption, the coefficients of the message are
reduced mod p.
In order to ensure security, it is essential that p and q have no common factors. The
following table gives some possible values for NTRU parameters at various security
levels [3].
138
Table 4: NTRU Security Parameters [3,6]
Next the process on encryption and decryption in NTRU is explained using the
classical “Bob-Alice” example using some smaller parameter values: [3]
Table 5: Small Security Parameters [3]
C.2 Key Creation [3, 6]

Overview :
Bob wants to create a public/private key pair for the NTRU PKCS. He first randomly
chooses two “small” polynomials f and g in the ring of truncated polynomials R. Bob
139
must keep the values of the polynomials f and g private, since anyone who knows the
value of either one of them will be able to decrypt messages sent to Bob. [3]
Bob's next step is to compute the inverse of f modulo q and the inverse of f
modulo p. Thus he computes polynomials fq and fpwith the property that
f*fq = 1 (modulo q) and f*fp = 1 (modulo p).
(If by some chance these inverses do not exist, Bob will need to go back and choose
another f) Now Bob computes the product [3].
h = pfq*g (modulo q)
Bob's private key is the pair of polynomials f and fp. Bob's public key is the polynomial h
[3].

Example :
So now N=11 q=32 p=3
We also need to define a "small" polynomial more precisely. For the purposes of this
example, we do this using the quantities df and dg. [3]
The polynomial f has df coefficients equal to +1, (df - 1) coefficients equal to -1, and the
rest equal to 0. The polynomial g has dg coefficients equal to +1, dg coefficients equal to
-1, and the rest equal to 0 [3].
(The reason for the slight difference in form between f and g is that f has to be invertible,
while g doesn't).
For the purposes of this example, we take df = 4 dg = 3.
140
So Bob needs to choose a polynomial f of degree 10 with four 1's and three -1's,
and he needs to choose a polynomial g of degree 10 with three 1's and three -1's. Suppose
he chooses:
f = -1 + X + X2 - X4 + X6 + X9 - X10
g = -1 + X2 + X3 + X5 - X8 - X10
Next Bob computes the inverse fp of f modulo p and the inverse fq of f modulo q. He
finds that:
fp = 1 + 2X + 2X3 + 2X4 + X5 + 2X7 + X8 + 2X9
fq = 5 + 9X + 6X2 + 16X3 + 4X4 + 15X5 + 16X6 + 22X7 + 20X8 + 18X9 + 30X10
The final step in key creation is to compute the product
h = pfq*g = 8 + 25X + 22X2 + 20X3 + 12X4 + 24X5 + 15X6 + 19X7 + 12X8 + 19X9 +
16X10 (modulo 32) [3].
Bob's private key is the pair of polynomials f and fp, and his public key is the polynomial
h [3].
C.3 Encryption [3, 6]

Overview :
Alice wants to send a message to Bob using Bob's public key h. She first puts her
message in the form of a polynomial m whose coefficients are chosen modulo p, (in other
words, m is a “small” polynomial mod p). Next she randomly chooses another “small”
polynomial, r which is used to obscure the message [3].
Alice uses the message m, her randomly chosen polynomial r, and Bob's public key h to
compute the polynomial
141
e = r*h + m (modulo q)
The polynomial e is the encrypted message which Alice sends to Bob [3].

Example :
As before, we need to specify what we mean by saying that r is a "small" polynomial.
We do this using the quantity dr. r has dr of its coefficients equal to 1, it has dr of its
coefficients equal to -1, and it has all of the rest of its coefficients equal to 0 [3] .
Here, we take dr = 3.
Now, suppose Alice wants to send the message
m = -1 + X3 - X4 - X8 + X9 + X10
to Bob using Bob's public key
h = 8 + 25X + 22X2 + 20X3 + 12X4 + 24X5 + 15X6 + 19X7 + 12X8 + 19X9 + 16X10.
She first chooses a random polynomial r of degree 10 with three 1's and three -1's. Say
she chooses
r = -1 + X2 + X3 + X4 - X5 - X7.
Then her encrypted message e is
e = r*h + m = 14 + 11X + 26X2 + 24X3 + 14X4 + 16X5 + 30X6 + 7X7 + 25X8 + 6X9 +
19X10 (modulo 32) [3].
Alice sends this encrypted message e to Bob [3].
C.4 Decryption [3, 6]

Overview :
Now Bob has received Alice's encrypted message e and he wants to decrypt it. He begins
by using his private polynomial f to compute the polynomial [3].
142
a = f*e (modulo q)
Since Bob is computing a modulo q, he can choose the coefficients of a to lie between q/2 and q/2. It is very important that Bob does this before performing the next step. Bob
next computes the polynomial
b = a (modulo p)
That is, he reduces each of the coefficients of a modulo p. Finally Bob uses his other
private polynomial fp to compute
c = fp*b (modulo p)
The polynomial c will be Alice's original message m [3].

Example :
Bob has received the encrypted message
e = 14 + 11X + 26X2 + 24X3 + 14X4 + 16X5 + 30X6 + 7X7 + 25X8 + 6X9 + 19X10
from Alice [3]. He uses his private key f to compute
a = f*e = 3 - 7X - 10X2 - 11X3 + 10X4 + 7X5 + 6X6 + 7X7 + 5X8 - 3X9 - 7X10 (modulo
32).
Note that when Bob reduces the coefficients of f*e modulo 32, he chooses values lying
between -15 and 16, not between 0 and 31. It is very important that he choose the
coefficients in this way. Next Bob reduces the coefficients of a modulo 3 to get
b = a = - X - X2 + X3 + X4 + X5 + X7 - X8 - X10 (modulo 3).
Finally Bob uses fp, the other part of his private key, to compute
c = fp*b = - 1 + X3 - X4 – X8 + X9 + X10 (modulo 3).
143
The polynomial c is Alice's message m, so Bob has successfully decrypted Alice's
message [3].
144
REFERENCES
[1] William Stallings, Network Security Essentials: Application and Standards, 2000,
Prentice Hall, Inc., Upper Saddle River, New Jersey 07458
[2] Colleen Marie O’Rourke, Worcester Polytechnic Institute, Efficient NTRU
Implementations, 2002
[3] http://www.ntru.com/cryptolab/pdf/ntrututorials.pdf
[4] Mohan Atreya, Ben Hammond, Stephen Paine, Paul Starrett, Stephen Wu
Digital Signature, 2002,The McGraw-Hill Companies.
[5] Gunar Gaubatz, Worcester Polytechnic Institute, Versatile Montgomery Multiplier
Architectures, 2002
[6] Jeffrey Hoffstein, Jill Pipher, Joseph H. Silverman, NTRU- A Ring-based Public-Key
Cryptosystem, 1998 (United States Patent: 6,298,137).
[7] www.securityinnovation.com
[8] Katherine Compton, Scott Hauck, An Introduction to Reconfigurable Computing,
2000
[9] Rodney D’Souza, The NTRU Cryptosystem: Implementation and Comparative
Analysis, 2001