Skip to main content
Log in

Application of Grover’s Quantum Algorithm for SDES Key Searching

  • ATOMS, MOLECULES, OPTICS
  • Published:
Journal of Experimental and Theoretical Physics Aims and scope Submit manuscript

Abstract

The problem of finding the key of Simplified-DES (SDES)—a model of a block cipher DES—by Grover’s quantum algorithm is considered. Examples of application of Grover’s algorithm are presented. A quantum system with the minimum number of qubits is constructed that implements SDES key searching by a single pair of plaintext and ciphertext and requires only 19 qubits. This quantum circuit is simulated by using a Quipper quantum simulator.

This is a preview of subscription content, log in via an institution to check access.

Access this article

Price excludes VAT (USA)
Tax calculation will be finalised during checkout.

Instant access to the full article PDF.

Fig. 1.
Fig. 2.
Fig. 3.
Fig. 4.
Fig. 5.
Fig. 6.
Fig. 7.

Similar content being viewed by others

REFERENCES

  1. H. Bernien, S. Schwartz, A. Keesling, H. Levine, and A. Omran, Nature (London, U.K.) 551, 579 (2017); arXiv:1707.04344. doi https://doi.org/10.1038/nature24622 https://doi.org/10.1038/nature24622

  2. J. Zhang, G. Pagano, P. W. Hess, A. Kyprianidis, and P. Becker, Nature (London, U.K.) 551, 601 (2017); arXiv:1708.01044. doi https://doi.org/10.1038/nature24654 https://doi.org/10.1038/nature24654

  3. https://www.ibm.com/blogs/research/2017/11/thefuture-is-quantum/.

  4. M. Veldhorst, H. G. J. Eenink, C. H. Yang, and A. S. Dzurak, Nat. Commun. 8, 1766 (2017); https://doi.org/10.1038/s41467-017-01905-6

    Article  ADS  Google Scholar 

  5. C. S. Calude and E. Calude, arXiv:1712.01356v1.

  6. J. Kelly, A Preview of Bristlecone, Google’s New Quantum Processor, Quantum AI Lab. https://ai.googleblog.com/2018/03/a-preview-of-bristlecone-googles-new.html. Accessed March 05, 2018.

  7. P. W. Shor, J. Comput. 26, 1484 (1997).

    MathSciNet  Google Scholar 

  8. D. R. Simon, SIAM J. Comput. 26, 1474 (1997).

    Article  MathSciNet  Google Scholar 

  9. M. Kaplan, G. Leurent, A. Leverrier, et al., Lect. Notes Comp. Sci. 9815, (2016).

  10. L. K. Grover, in Proceedings of the 28th ACM Symposium on Theory of Computing STOC 1996, Ed. by G. L. Miller (ACM, 1996), p. 212.

  11. G. Brassard, P. Hoyer, M. Mosca, et al., arXiv:quant-ph/0005055.

  12. M. A. Nielsen and I. L. Chuang, Quantum Computation and Quantum Information (Cambridge Univ. Press, Cambridge, 2000).

    MATH  Google Scholar 

  13. M. Almazrooie, A. Samsudin, R. Abdullah, and K. N. Mutter, Springer Plus 5, 1494 (2016). doi https://doi.org/10.1186/s40064-016-3159-4

    Article  Google Scholar 

  14. Quantum Simulator Libquantum. http://www.libquantum.de.

  15. A. S. Green, P. L. Lumsdaine, N. J. Ross, P. Selinger, and B. Valiron, arXiv:1304.5485v1.

  16. S. Siddiqui, M. J. Islam, and O. Shehab, arXiv:1406.4481v2 [quant-ph].

  17. Quantum Simulator Quipper. http://www.mathstat.dal.ca/~selinger/quipper/.

  18. C. Shannon, Bell Syst. Tech. J. 28, 656 (1949).

    Article  Google Scholar 

Download references

Author information

Authors and Affiliations

Authors

Corresponding author

Correspondence to D. V. Denisenko.

Additional information

Translated by I. Nikitin

Appendices

APPENDICES

APPENDIX A: A Test Example of SDES

Take a block of a plaintext P = 00101000 and K = 1100011110. Formation of a round key k1:

Bit numbers

1

2

3

4

5

6

7

8

9

10

K

1

1

0

0

0

1

1

1

1

0

P10(K)

0

0

1

1

0

0

1

1

1

1

LS-1(P10(K))

0

1

1

0

0

1

1

1

1

1

k1 = P8(LS-1(P10(K)))

1

1

1

0

1

0

0

1

  

Formation of a round key k2:

Bit numbers

1

2

3

4

5

6

7

8

9

10

K

1

1

0

0

0

1

1

1

1

0

P10(K)

0

0

1

1

0

0

1

1

1

1

LS-3(P10(K))

1

0

0

0

1

1

1

0

1

1

k2 = P8(LS-3(P10(K)))

1

0

1

0

0

1

1

1

  

In this example, P = 00101000 and IP(P) = 00100010.

1. Take P = 00101000 and K = 1100011110.

2. IP(P) = 00100010.

3. \({{f}_{{{{k}_{1}}}}}\)(L, R) = f11101001(00100010) = (0010 ⊕ F(0010, 11101001), 0010).

4. F(0010, 11101001) = P4 \(\circ \) Sboxes \(\circ \) (11101001 ⊕ E/P(0010)):

Bit numbers

1

2

3

4

5

6

7

8

R

0

0

1

0

    

E/P(R)

0

0

0

1

0

1

0

0

k 1

1

1

1

0

1

0

0

1

E/P(R) ⊕ k1

1

1

1

1

1

1

0

1

Sboxes(E/P(R) ⊕ k1)

1

0

0

0

    

P4(Sboxes(E/P)⊕ k1))

0

0

0

1

    

5. We have calculated F(0010, 11101001) = 0001 and obtained \({{f}_{{{{k}_{1}}}}}\)(L, R) = (0011, 0010).

6. SW(0011, 0010) = (0010, 0011).

7. \({{f}_{{{{k}_{2}}}}}\)(L, R) = f10100111(00100011) = (0010 ⊕ F(0011, 10100111), 0011):

Bit numbers

1

2

3

4

5

6

7

8

R

0

0

1

1

    

E/P(R)

1

0

0

1

0

1

1

0

k 2

1

0

1

0

0

1

1

1

E/P(R) ⊕ k2

0

0

1

1

0

0

0

1

Sboxes(E/P(R) ⊕ k2)

1

0

1

0

    

P4(Sboxes(E/P)⊕ k2))

0

0

1

1

    

8. We have calculated F(0011, 10100111) = 0011 and obtained \({{f}_{{{{k}_{2}}}}}\)(L, R) = (0001, 0011).

9. Apply IP–1:

Bit numbers

1

2

3

4

5

6

7

8

L, R

0

0

0

1

0

0

1

1

IP–1(L, R)

1

0

0

0

1

0

1

0

Examples of SDES encryption with the key K = 1100011110:

$${{E}_{{SDES}}}(K,00101000) = 10001010,$$
$${{E}_{{SDES}}}(K,10001101) = 11010000,$$
$${{E}_{{SDES}}}(K,11110010) = 11011010,$$
$${{E}_{{SDES}}}(K,01010111) = 01100000.$$

APPENDIX B: Search for a Single Target Value by Grover’s Algorithm

Let N = 23, M = 1, and the target value be TargetValue=7. Determine the probability of success in the search for a target value depending on the number of iterations in Grover’s algorithm.

Listing 1. Program implementation in Wolfram Mathematica

1 TargetValue=7; (*Define the number of an element that we want to obtain by measuring qubits*)

2 NumberOfQubits=3; (*determined the number of qubits*)

3 H= HadamardMatrix[2^NumberOfQubits];

4 (*Initiated the Hadamard matrix*)

5 Numb=2^NumberOfQubits; (*introduced an additional variable for a shorter expression*)

6 matrixD=ConstantArray[ConstantArray[2/Numb,Numb],Numb]-IdentityMatrix[Numb];

7 (*Initiated the D matrix (the Grover diffusion)*)

8 Print[" Hadamard matrix: \n “,MatrixForm[H]];

$$H = \left( {\begin{array}{*{20}{c}} {\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}} \\ {\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}}&{\frac{1}{{2\sqrt 2 }}}&{ - \frac{1}{{2\sqrt 2 }}} \end{array}} \right)$$

9 Print[“Matrix D (Grover diffusion): \n ",MatrixForm[matrixD]];

$$D = \left( {\begin{array}{*{20}{c}} { - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}}&{\frac{1}{4}} \\ {\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{\frac{1}{4}}&{ - \frac{3}{4}} \end{array}} \right)$$

10 FirstState=ConstantArray[0,2^NumberOfQubits];

11 FirstState[[1]]=1;

12 (*Initiated the initial state*)

13 Print[“Initiated the initial state:”,FirstState];

$${\text{FirstState}} = \{ 1,0,0,0,0,0,0,0\} $$

14 State=FirstState.H; (*Applied Hadamard gates to each qubit,

   i.e., multiplied the vector FirstState by matrix H*)

$$State = \left\{ {\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }}} \right\}$$

15 i=0;

16 Print[“Iteration no., i , probability of success= ", N[(State[[TargetValue]]*

State[[TargetValue]])],"probability of failure= “,

N[(1-State[[TargetValue]]*State[[TargetValue]])] ];

Iteration no. 0, probability of success = 0.125, probability of failure = 0.875;

17 (*Change of sign of the amplitude of the target value*)

18 State[[TargetValue]]=(-1)*State[[TargetValue]];

19 Print[“changed the sign of the target value: \n”,State];

$$State = \left\{ {\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }}, - \frac{1}{{2\sqrt 2 }},\frac{1}{{2\sqrt 2 }}} \right\}$$

20 State=State.matrixD; (*Applied the Grover diffusion, multiplied State by matrix D*)

21 Print[“Applied the Grover diffusion, multiplied State by matrix D: \n”,State];

$$State = \left\{ {\frac{1}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }},\frac{5}{{4\sqrt 2 }},\frac{1}{{4\sqrt 2 }}} \right\}$$

22 i=1;

23 Print[“Iteration no., i , probability of success= ", N[(State[[TargetValue]]*

State[[TargetValue]])],"probability of failure= “, N[(1-State[[TargetValue]]*

State[[TargetValue]])] ];

Iteration no. 1, probability of success = 0.78125, probability of failure = 0.21875;

24 NumberOfGroverIterations=30;

25 (*defined the number of iterations, for example, 30*)

26 For[i=2,i<=NumberOfGroverIterations,i++,

27 State[[TargetValue]]=(-1)*State[[TargetValue]];

(*changed the sign of the target value*)

28 State=State.matrixD; (*Applied the Grover diffusion, multiplied State by matrix D*)

29 p=State[[TargetValue]]*State[[TargetValue]]

30 Print[“Iteration no., i , Probability of success = “, N[p],” Probability of failure= “, N[1–p]];

31 ]

Let us calculate the probability of successful search for the target value (TargetValue = 7) depending on the number of iterations of Grover’s algorithm on three qubits (see Table 6). The optimal number of Grover iterations in this example is estimated as \(\left[ {\frac{\pi }{4}\sqrt {\frac{{{{2}^{3}}}}{1}} } \right]\) = [2.221441469079183] = 2.

Table 6

Number of Grover iteration

Probability of success of Grover iteration, i.e., probability to obtain TargetValue=7 as a result of measurement of qubits

Probability of failure of Grover iteration, i.e., probability to obtain TargetValue≠7 as a result of measurement of qubits.

1

0.78125

0.21875

2

0.945313

0.0546875

3

0.330078

0.669922

4

0.012207

0.987793

5

0.547974

0.452026

6

0.999786

0.000213623

7

0.576973

0.423027

8

0.0194569

0.980543

9

0.302891

0.697109

10

0.931266

0.068734

11

0.804925

0.195075

12

0.144965

0.855035

13

0.106316

0.893684

14

0.756614

0.243386

15

0.957837

0.0421627

16

0.357846

0.642154

17

0.0066241

0.993376

18

0.51881

0.48119

19

0.998078

0.00192151

20

0.605709

0.394291

21

0.0283488

0.971651

22

0.276378

0.723622

23

0.915746

0.0842543

24

0.827558

0.172442

25

0.166144

0.833856

26

0.0889775

0.911022

27

0.7311

0.2689

28

0.968798

0.0312024

Table 7

Number of Grover iteration

Probability of success of Grover iteration, i.e., probability to obtain one of the values TargetValue = {151, 223} as a result of measurement of qubits

Probability of failure of Grover iteration, i.e., probability to obtain a value other than from TargetValues as a result of measurement of qubits

1

0.0174867

0.982513

2

0.0480693

0.951931

3

0.0927473

0.907253

4

0.150127

0.849873

5

0.218419

0.781581

6

0.295493

0.704507

7

0.378945

0.621055

8

0.466173

0.533827

9

0.554456

0.445544

10

0.641041

0.358959

11

0.723227

0.276773

12

0.79845

0.20155

13

0.864365

0.135635

14

0.918916

0.0810837

15

0.960402

0.0395983

16

0.987528

0.0124724

17

0.999448

0.000551974

18

0.995791

0.0042088

19

0.976671

0.0233288

20

0.942684

0.0573158

21

0.89489

0.10511

22

0.83478

0.16522

23

0.764229

0.235771

24

0.685436

0.314564

25

0.60086

0.39914

26

0.513139

0.486861

27

0.425007

0.574993

28

0.339214

0.660786

APPENIX C: Search for One of the two Target Values of Grover’s Algorithm

Let N = 210, M = 2, and the target value is TargetValue ∈ {151, 223}. Determine the probability of success in the search for a target value depending on the number of iterations in Grover’s algorithm (see Table 7). The optimal number of Grover iterations in this example is estimated as \(\left[ {\frac{\pi }{4}\sqrt {\frac{{{{2}^{{10}}}}}{2}} } \right]\) = [17.771531752633464] = 18.

Listing 2. Program implementation in Wolfram Mathematica

1 (*A case when there are several sought numbers*)

2 TargetValues={151,223}; (*sought numbers*)

3 NumberOfQubits=10; (*determined the number of qubits*)

4 H= HadamardMatrix[2^NumberOfQubits]; (*Initiated the Hadamard matrix*)

5 Numb=2^NumberOfQubits; (*introduced an additional variable for a shorter expression*)

6 matrixD=ConstantArray[ConstantArray[2/Numb,Numb],Numb]-IdentityMatrix[Numb];

7 (*Initiated the matrix D (the Grover diffusion)*)

8 FirstState=ConstantArray[0,2^NumberOfQubits];

9 FirstState[[1]]=1; (* Initiated the initial state*)

10 State=FirstState.H;

11 (* Applied Hadamard gates to each qubit, i.e., multiplied the vector FirstState by matrix H*)

$${\text{p}} = \sum\nolimits_{k = 1}^{{\text{Length[TargetValues]}}} {{\text{State}}[[{\text{TargetValues}}[[k]]]]} *{\text{State}}[[{\text{TargetValues}}[[k]]]];$$

12 i=0;Print[“Iteration no., i , probability of success = “, N[p],”,

probability of failure= “, N[1–p]];

13 (*Change of sign of the amplitude of the target value*)

14 For[i=1,i<=Length[TargetValues],i++,

15 State[[ TargetValues[[i]] ]]=(-1)*State[[ TargetValues[[i]] ]]; ];

16 State=State.matrixD;

17 (*Applied the Grover diffusion, multiplied the vector State by matrix D*)

$${\text{p}} = \sum\nolimits_{k = 1}^{{\text{Length[TargetValues]}}} {{\text{State}}[[{\text{TargetValues}}[[k]]]]} *{\text{State}}[[{\text{TargetValues}}[[k]]]];$$

18 Print[“Iteration no., i , probability of success = “, N[p],”, probability of failure= “, N[1–p]];

19 NumberOfGroverIterations=30;

20 (*defined the number of Grover iterations*)

21 For[i=2,i<=NumberOfGroverIterations,i++,

22 For[j=1,j<=Length[TargetValues],j++,

23 State[[TargetValues[[j]]]]=(-1)*State[[TargetValues[[j]] ]];];

24 State=State.matrixD;

$${\text{p}} = \sum\nolimits_{k = 1}^{{\text{Length[TargetValues]}}} {{\text{State}}[[{\text{TargetValues}}[[k]]]]} *{\text{State}}[[{\text{TargetValues}}[[k]]]];$$

25 Print[“Iteration no., i , probability of success = “, N[p],”, probability of failure=", N[1–p]];]

The probability of success after 17 Grover iterations turns out to be slightly greater than the probability of success after 18 Grover iterations. This does not contradict anything because \(\left[ {\frac{\pi }{4}\sqrt {\frac{N}{M}} } \right]\) is the upper bound for the number of iterations (see [12, p. 318]).

APPENDIX D: Program Implementation of Grover’s Algorithm for the SDES Key Search by a Plaintext–Ciphertext Pair on a Quipper Quantum Simulator

The program implementation represents three files:

(1) QSDES.hs—implementation of an SDES algorithm,

(2) Grover.hs—implementation of Grover’s algorithm on the basis of QSDES,

(3) Main.hs—start of simulation of the quantum circuit.

Here is the content of these files.

QSDES.HS

1 module QSDES where

2 - Block of quantum implementation of the SDES encryption circuit

3

4 import Quipper

5 import QuipperLib.Simulation

6 import System.Random

7 import Quipper.Printing

8 import Quipper.QData

9

10 - Summation with a key

11 sum_qubit :: ([Qubit], [Qubit]) -> Circ [Qubit]

12 sum_qubit ([k0, k1, k2, k3], [x0, x1, x2, x3]) = do

13 qnot_at x0 ‘controlled‘ [k0]

14 qnot_at x1 ‘controlled‘ [k1]

15 qnot_at x2 ‘controlled‘ [k2]

16 qnot_at x3 ‘controlled‘ [k3]

17 return [x0, x1, x2, x3]

19 - S0

20 s0_box :: ([Qubit], [Qubit]) -> Circ [Qubit]

21 s0_box ([x0, x1, x2, x3], [s0, s1]) = do

22 comment “S0_box”

23 qnot_at s0 ‘controlled‘ [x3]

24 qnot_at s0 ‘controlled‘ [x0, x1, x2, x3]

25 qnot_at s0 ‘controlled‘ [x0, x2]

26 x0 <- gate_X x0

27 qnot_at s0 ‘controlled‘ [x0, x1]

28 x2 <- gate_X x2

29 qnot_at s1 ‘controlled‘ [x0, x2]

30 x0 <- gate_X x0

31 qnot_at s1 ‘controlled‘ [x0, x1, x2, x3]

32 x1 <- gate_X x1

33 qnot_at s1 ‘controlled‘ [x0, x1]

34 x3 <- gate_X x3

35 qnot_at s1 ‘controlled‘ [x0, x3]

36 x1 <- gate_X x1

37 x2 <- gate_X x2

38 x3 <- gate_X x3

39 return [s0, s1]

40

41 - S1

42 s1_box :: ([Qubit], [Qubit]) -> Circ [Qubit]

43 s1_box ([x0, x1, x2, x3], [s2, s3]) = do

44 comment “S1_box”

45 qnot_at s2 ‘controlled‘ [x1]

46 qnot_at s3 ‘controlled‘ [x0, x2, x3]

47 x3 <- gate_X x3

48 qnot_at s3 ‘controlled‘ [x0, x3]

49 qnot_at s2 ‘controlled‘ [x0, x3]

50 x1 <- gate_X x1

51 qnot_at s2 ‘controlled‘ [x0, x1, x2, x3]

52 qnot_at s3 ‘controlled‘ [x2, x3]

53 x2 <- gate_X x2

54 x3 <- gate_X x3

55 qnot_at s2 ‘controlled‘ [x2, x3]

56 x0 <- gate_X x0

57 x1 <- gate_X x1

58 qnot_at s3 ‘controlled‘ [x0, x1, x3]

59 x0 <- gate_X x0

60 x2 <- gate_X x2

61 return [s2, s3]

62

63 —– round 1 —–

64

65 round1 :: ([Qubit], [Qubit]) -> Circ [Qubit]

66 round1 ([k0, k1, k2, k3, k4, k5, k6, k7, k8, k9], [x0, x1, x2, x3, x4, x5, x6, x7]) = do

67 comment “ROUND_1"

68

69 [x6, x3, x7, x4] <- sum_qubit ([k0, k6, k8, k3], [x6, x3, x7, x4])

70 [x0, x1] <- s0_box ([x6, x3, x7, x4], [x0, x1])

71 [x6, x3, x7, x4] <- sum_qubit ([k0, k6, k8, k3], [x6, x3, x7, x4])

72

73 [x7, x4, x6, x3] <- sum_qubit ([k7, k2, k9, k5], [x7, x4, x6, x3])

74 [x2, x5] <- s1_box ([x7, x4, x6, x3], [x2, x5])

75 [x7, x4, x6, x3] <- sum_qubit ([k7, k2, k9, k5], [x7, x4, x6, x3])

76

77 return [x0, x1, x2, x3, x4, x5, x6, x7]

78

79 —– round 2 —–

80

81 round2 :: ([Qubit], [Qubit]) -> Circ [Qubit]

82 round2 ([k0, k1, k2, k3, k4, k5, k6, k7, k8, k9], [x0, x1, x2, x3, x4, x5, x6, x7]) = do

83 comment “ROUND_2"

84

85 [x0, x1, x5, x2] <- sum_qubit ([k7, k2, k5, k4], [x0, x1, x5, x2])

86 [x6, x3] <- s0_box ([x0, x1, x5, x2], [x6, x3])

87 [x0, x1, x5, x2] <- sum_qubit ([k7, k2, k5, k4], [x0, x1, x5, x2])

88

89 [x5, x2, x0, x1] <- sum_qubit ([k9, k1, k8, k0], [x5, x2, x0, x1])

90 [x4, x7] <- s1_box ([x5, x2, x0, x1], [x4, x7])

91 [x5, x2, x0, x1] <- sum_qubit ([k9, k1, k8, k0], [x5, x2, x0, x1])

92

93 return [x0, x1, x2, x3, x4, x5, x6, x7]

94

95 - QSDES circuit (“direct”).

96 sdes :: ([Qubit], [Qubit]) -> Circ ([Qubit], [Qubit])

97 sdes (key, plaintext) = do

98 let [k0, k1, k2, k3, k4, k5, k6, k7, k8, k9] = key

99 let [x0, x1, x2, x3, x4, x5, x6, x7] = plaintext

100

101 comment_with_label “Key”

102 (k0, k1, k2, k3, k4, k5, k6, k7, k8, k9)

103 (“k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7", "k8", "k9")

104

105 comment_with_label “Plaintext”

106 (x0, x1, x2, x3, x4, x5, x6, x7)

107 (“x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7")

108

109 [x0, x1, x2, x3, x4, x5, x6, x7] <- round1 ([k0, k1, k2, k3, k4, k5, k6, k7, k8, k9],

[x0, x1, x2, x3, x4, x5, x6, x7])

110 [x0, x1, x2, x3, x4, x5, x6, x7] <- round2 ([k0, k1, k2, k3, k4, k5, k6, k7, k8, k9],

[x0, x1, x2, x3, x4, x5, x6, x7])

111

112 swap x6 x0

113 swap x3 x1

114 swap x4 x2

115 swap x5 x7

116

117 return ([k0, k1, k2, k3, k4, k5, k6, k7, k8, k9], [x0, x1, x2, x3, x4, x5, x6, x7])

118

119 - QSDES circuit (“direct”)

120 sdes_reverse :: ([Qubit], [Qubit]) -> Circ ([Qubit], [Qubit])

121 sdes_reverse = reverse_generic_endo sdes

122

123 - Test QSDES circuit with a key superposition;

124 - is used for test no. 2.

125 sdes_key_superposition :: [Bool] -> Circ ([Qubit], [Qubit])

126 sdes_key_superposition plaintext = do

127 key_in_superposition <- qinit (replicate 10 False)

128 mapUnary hadamard key_in_superposition

129 plaintext <- qinit plaintext

130 (key, cyphertext) <- sdes (key_in_superposition, plaintext)

131 return (key, cyphertext)

GROVER.HS

1 module Grover where

2 - Grover’s algorithm for QSDES

3

4 import Quipper

5 import Quipper.QData

6 import QSDES

7 - Oracle for QSDES

8 sdes_oracle :: ([Qubit], [Qubit], [Bool], Qubit) -> Circ Qubit

9 sdes_oracle (key, plaintext, cyphertext_bool, oracle) = do

10 (key, cyphertext) <- sdes (key, plaintext)

11 qnot_at oracle ‘controlled‘ cyphertext .==. cyphertext_bool

12 (key, plaintext) <- sdes_reverse (key, cyphertext)

13 return oracle

14 - Circuit inversion about the mean or Conditional Phase Flip (CPF)

15 inversion_about_mean :: [Qubit] -> Circ [Qubit]

16 inversion_about_mean top_qubits = do

17 comment “start inversion about mean”

18 mapUnary hadamard top_qubits

19 mapUnary gate_X top_qubits

20 let pos = (length top_qubits) - 1

21 let target_qubit = top_qubits !! pos

22 let controlled_qubit = take pos top_qubits

23 hadamard_at target_qubit

24 qnot_at target_qubit ‘controlled‘ controlled_qubit

25 hadamard_at target_qubit

26 mapUnary gate_X top_qubits

27 mapUnary hadamard top_qubits

28 comment “end inversion about mean”

29 return top_qubits

30 - Grover’s algorithm for QSDES

31 grover_search_circuit_sdes :: (Int, [Bool], [Bool]) -> Circ ([Bit], Bit)

32 grover_search_circuit_sdes (iterations_num, plaintext, cyphertext) = do

33 key <- qinit (replicate 10 False)

34 plaintext <- qinit plaintext

35 oracle <- qinit True

36 mapUnary hadamard key

37 hadamard_at oracle

38 - Start of Grover iterations

39 let index = iterations_num

40 for 1 (index) 1 $ \i -> do

41 comment “start grover iteration”

42 oracle <- sdes_oracle (key, plaintext, cyphertext, oracle)

43 key <- inversion_about_mean key

44 comment “after grover iteration”

45 endfor

46 - Measurement of qubits, return of the result

47 hadamard_at oracle

48 (key, oracle) <- measure (key, oracle)

49 - cdiscard oracle

50 return (key, oracle)

MAIN.HS

1 module Main where

2 - Main block. Start of examples

3

4 import System.Random

5 import Data.Time

6 import Quipper

7 import Quipper.Printing

8 import QuipperLib.Simulation

9 import Quipper.QData

10 import QSDES

11 import Grover

12

13 - START OF THE PROGRAM

14 main :: IO ()

15 - main = test1_circuit

16 main = test3_exec –25 Grover iterations, finding the key distribution.

17

18 - Functionality test. Test of the correctness of composing the circuit

19 test1_circuit :: IO ()

20 test1_circuit = do

21 putStrLn “QSDES functionality test:”

22 print_generic GateCount sdes ((replicate 10 qubit),(replicate 8 qubit))

23 print_generic PDF sdes ((replicate 10 qubit),(replicate 8 qubit))

24

25 test1_exec :: IO ()

26 test1_exec = do

27 putStrLn “QSDES functionality test:”

28 print_generic GateCount sdes ((replicate 10 qubit),(replicate 8 qubit))

29 g <- newStdGen

30 print $ run_generic g (0.0 :: Double) sdes

([True,True,False,False,False,True,True,True,True,False], [False,False,True,False,True,

False,False,False])

31 print $ run_generic g (0.0 :: Double) sdes ([True,True,False,False,False,True,True,

True,True,False], [True,False,False,False,True,True,False,True])

32 print $ run_generic g (0.0 :: Double) sdes

([True,True,False,False,False,True,True,

True,True,False], [True,True,True,True,False,False,True,False])

33 print $ run_generic g (0.0 :: Double) sdes ([True,True,False,False,False,True,True,

True,True,False], [False,True,False,True,False,True,True,True])

34

35 - Testing the circuit with key qubits in superposition.

36 test2_circuit :: IO ()

37 test2_circuit = do

38 putStrLn “QSDES results when key is in superposition:”

39 print_generic PDF (sdes_key_superposition [True,False,False,True,True,False,True,False])

40

41 test2_exec :: IO ()

42 test2_exec = do

43 putStrLn “QSDES results when key is in superposition:”

44 - t1 <- getZonedTime

45 - putStrLn $ formatTime defaultTimeLocale “%FT%T%z” t1

46 g <- newStdGen

47 print $ sim_generic undefined (sdes_key_superposition

([True,False,False,True,True,False,True,False]))

48 - t2 <- getZonedTime

49 - putStrLn $ formatTime defaultTimeLocale “%FT%T%z” t2

50

51

52 - Search for the key pair of public and private texts.

53 - Example with one true keys.

54 test3_circuit :: IO()

55 test3_circuit = do

56 putStrLn “Quantum exhaustive key search (1 key):”

57 let parameters = (25,[False,False,False,True,False,False,False,False],

58 [False,False,True,True,False,False,True,True])

59 print_generic GateCount (grover_search_circuit_sdes parameters)

60 - print_generic PDF (grover_search_circuit_sdes parameters)

61

62 test3_exec :: IO()

63 test3_exec = do

64 putStrLn “Quantum exhaustive key search (1 key):”

65 startTime <- getCurrentTime

66 let parameters = (25,[False,False,False,True,False,False,False,False],

[False,False,True,True,False,False,True,True]) – O.T.,C.T.

67 g <- newStdGen

68 - print $ run_generic g (0.0 :: Double) (grover_search_circuit_sdes parameters)

69 print_generic GateCount (grover_search_circuit_sdes parameters)

70 print $ sim_generic undefined (grover_search_circuit_sdes parameters)

71 stopTime <- getCurrentTime

72 let deltaTime = show $ diffUTCTime stopTime startTime

73 putStrLn deltaTime

74

75 - Search for the key pair of the open and closed text.

76 - Example with two true keys.

77 test4_circuit :: IO()

78 test4_circuit = do

79 putStrLn “Quantum exhaustive key search (2 keys):”

80 let parameters = (18,[True,False,True,False,False,True,False,True],

[False,False,True,True,False,True,True,False])

81 print_generic GateCount (grover_search_circuit_sdes parameters)

82 - print_generic PDF (grover_search_circuit_sdes parameters)

83

84 test4_exec :: IO()

85 test4_exec = do

86 putStrLn “Quantum exhaustive key search (2 keys):”

87 startTime <- getCurrentTime

88 let parameters = (18,[True,False,True,False,False,True,False,True],

[False,False,True,True,False,True,True,False])

89 print_generic GateCount (grover_search_circuit_sdes parameters)

90 g <- newStdGen

91 - print $ run_generic g (0.0 :: Double) (grover_search_circuit_sdes parameters)

92 print $ sim_generic undefined (grover_search_circuit_sdes parameters)

93 stopTime <- getCurrentTime

94 let deltaTime = show $ diffUTCTime stopTime startTime

95 putStrLn deltaTime

Rights and permissions

Reprints and permissions

About this article

Check for updates. Verify currency and authenticity via CrossMark

Cite this article

Denisenko, D.V., Nikitenkova, M.V. Application of Grover’s Quantum Algorithm for SDES Key Searching. J. Exp. Theor. Phys. 128, 25–44 (2019). https://doi.org/10.1134/S1063776118120142

Download citation

  • Received:

  • Revised:

  • Accepted:

  • Published:

  • Issue Date:

  • DOI: https://doi.org/10.1134/S1063776118120142

Navigation