Sparkle

A reversible quantum implementation of ciphers from the Sparkle-suite.

It implements the n-qubits Alzette ARX box and the TRAX ciphers defined in [Alzette2020].

[Alzette2020] (1,2)

Beierle, C., Biryukov, A., Cardoso dos Santos, L., Großschädl, J., Perrin, L., Udovenko, A., … & Wang, Q. (2020). Alzette: A 64-Bit ARX-box: (Feat. CRAX and TRAX). In Advances in Cryptology-CRYPTO 2020: 40th Annual International Cryptology Conference, CRYPTO 2020, Santa Barbara, CA, USA, August 17-21, 2020, Proceedings, Part III 40 (pp. 419-448). Springer International Publishing.

class pyqrypto.sparkle.Alzette(X: QuantumRegister, Y: QuantumRegister, c: int, ancillas: AncillaRegister | None = None, adder_mode: str = 'ripple', label: str | None = None)[source]

Bases: Gate, RegisterOperation

A quantum gate implementing the ARX-box Alzette of two vectors of qubits.

Parameters:
  • X – X vector.

  • Y – Y vector.

  • c – Alzette constant.

  • ancillas – The anquilla register needed if adder_mode is lookahead.

  • adder_mode – See RegisterCircuit.add.

  • label – An optional label for the gate.

Raises:

CiruitError – If X and Y have a different size.

Operation:

\((X, Y) \leftarrow \mathrm{Alzette}(X, Y)\)

\(\mathrm{Alzette(X, Y)}\) is defined in [Alzette2020] as the following operations:

\[\begin{split}\begin{align*} & \mathrm{X} \leftarrow \mathrm{X} + (\mathrm{Y} \ggg 31) \\ & \mathrm{Y} \leftarrow \mathrm{Y} \oplus (\mathrm{X} \ggg 24) \\ & \mathrm{X} \leftarrow \mathrm{X} \oplus c \\ & \mathrm{X} \leftarrow \mathrm{X} + (\mathrm{Y} \ggg 17) \\ & \mathrm{Y} \leftarrow \mathrm{Y} \oplus (\mathrm{X} \ggg 17) \\ & \mathrm{X} \leftarrow \mathrm{X} \oplus c \\ & \mathrm{X} \leftarrow \mathrm{X} + (\mathrm{Y} \ggg 0) \\ & \mathrm{Y} \leftarrow \mathrm{Y} \oplus (\mathrm{X} \ggg 31) \\ & \mathrm{X} \leftarrow \mathrm{X} \oplus c \\ & \mathrm{X} \leftarrow \mathrm{X} + (\mathrm{Y} \ggg 24) \\ & \mathrm{Y} \leftarrow \mathrm{Y} \oplus (\mathrm{X} \ggg 16) \\ & \mathrm{X} \leftarrow \mathrm{X} \oplus c \end{align*}\end{split}\]
static get_num_ancilla_qubits(n: int = 32, adder_mode: str = 'ripple') int[source]

Get the number of required ancilla qubits without instantiating the class.

Parameters:
Returns:

The number of ancilla qubits needed for the computation.

pyqrypto.sparkle.RCON: Final[list[int]] = [3084996962, 3211876480, 951376470, 844003128, 3138487787, 1333558103, 3485442504, 3266521405]

The round constants for TRAX.

class pyqrypto.sparkle.TraxlEnc(x: list[QuantumRegister], y: list[QuantumRegister], key: list[QuantumRegister], tweak: list[int], ancillas: AncillaRegister, alzette_mode: str = 'lookahead-parallel', schedule_mode: str = 'lookahead', nsteps: int = 17, label: str | None = None)[source]

Bases: Gate, RegisterOperation

A quantum implementation of the encryption step of the TRAX-L cipher.

The default block size for this cipher is 256 bits.

The Alzette rounds of TRAX can be implemented using different techniques:

  • lookahead-parallel: Run the 4 instances of Alzette in parallel using carry lookahead adders.

  • lookahead-half-parallel: Run 2 instances of Alzette in parallel using carry lookahead adders.

  • lookahead-sequential: Run the 4 instances of Alzette sequentially using carry lookahead adders.

  • ripple: Run the 4 instances of Alzette in parallel using ripple carry adders.

The key schedule can be implemented using different techniques:

  • ripple: Compute the key schedule using ripple carry adders for the non constant adders.

  • lookahead: Compute the key schedule using only carry lookahead adders.

Each combinaison of techniques involves a tradeoff between the circuit depth, the quantum cost and the number of needed ancilla qubits. Please read the Grover on TRAX paper for more information about this.

Parameters:
  • x – A list of 4 quantum registers of size n/8.

  • y – A list of 4 quantum registers of size n/8.

  • key – The encryption key, a list of 8 quantum registers of size n/8.

  • tweak – The tweak, a list of 4 integers on n/8 bits.

  • ancillas – The ancillas qubits needed for the computation.

  • alzette_mode – The method to use to compute the Alzette rounds.

  • schedule_mode – The method to use to compute the key schedule.

  • nsteps – The number of rounds of TRAX.

  • label – An optional label for the gate.

static get_num_ancilla_qubits(n: int = 256, alzette_mode: str = 'lookahead-parallel', schedule_mode: str = 'lookahead') int[source]

Get the number of required ancilla qubits without instantiating the class.

Parameters:
  • n – The block size of the cipher.

  • alzette_mode – The method to use to compute the Alzette rounds.

Returns:

The number of ancilla qubits needed for the computation.

class pyqrypto.sparkle.TraxmEncRound(x: list[QuantumRegister], y: list[QuantumRegister], round_key: list[QuantumRegister], tweak: list[int] | None, ancillas: AncillaRegister, alzette_mode: str = 'lookahead-parallel', round_constants: tuple[int, int] = (3084996962, 3211876480), label: str | None = None)[source]

Bases: Gate, RegisterOperation

A quantum implementation of a round of the encryption step of TRAX-M.

The default block size for this cipher is 128 bits. Only a single round is implemented because there is no standard key schedule for this cipher.

The Alzette rounds of TRAX can be implemented using different techniques:

  • lookahead-parallel: Run the 2 instances of Alzette in parallel using carry lookahead adders.

  • lookahead-sequential: Run the 2 instances of Alzette sequentially using carry lookahead adders.

  • ripple: Run the 2 instances of Alzette in parallel using ripple carry adders.

Parameters:
  • x – A list of 2 quantum registers of size n/4.

  • y – A list of 2 quantum registers of size n/4.

  • key – The round key, a list of 4 quantum registers of size n/4.

  • tweak – The tweak, a list of 2 integers on n/4 bits. None if the tweak souldn’t be added at that round.

  • ancillas – The ancillas qubits needed for the computation.

  • alzette_mode – The method to use to compute the Alzette rounds.

  • round_constants – A list of the two round constants to use for this round.

  • label – An optional label for the gate.

static get_num_ancilla_qubits(n: int = 128, alzette_mode: str = 'lookahead-parallel') int[source]

Get the number of required ancilla qubits without instantiating the class.

Parameters:
  • n – The block size of the cipher.

  • alzette_mode – The method to use to compute the Alzette rounds.

Returns:

The number of ancilla qubits needed for the computation.

class pyqrypto.sparkle.TraxsEncRound(x: QuantumRegister, y: QuantumRegister, round_key: list[QuantumRegister], tweak: list[int] | None, ancillas: AncillaRegister, alzette_mode: str = 'lookahead', round_constant: int = 3084996962, label: str | None = None)[source]

Bases: Gate, RegisterOperation

A quantum implementation of a round of the encryption step of TRAX-S.

The default block size for this cipher is 64 bits. Only a single round is implemented because there is no standard key schedule for this cipher.

The adder in the Alzette rounds of TRAX can be implemented with two methods:

  • lookahead: Use a carry-lookahead adder.

  • ripple: Use a ripple-carry adder.

Parameters:
  • x – A quantum register of size n/2.

  • y – A quantum register of size n/2.

  • key – The round key, a list of 2 quantum registers of size n/2.

  • tweak – The tweak, a list of 2 integers on n/4 bits. None if the tweak souldn’t be added at that round.

  • ancillas – The ancillas qubits needed for the computation.

  • alzette_mode – The method to use to compute the Alzette rounds.

  • round_constant – The round constant to use for this round.

  • label – An optional label for the gate.

static get_num_ancilla_qubits(n: int = 64, alzette_mode: str = 'lookahead') int[source]

Get the number of required ancilla qubits without instantiating the class.

Parameters:
  • n – The block size of the cipher.

  • alzette_mode – The method to use to compute the Alzette rounds.

Returns:

The number of ancilla qubits needed for the computation.

pyqrypto.sparkle.c_alzette(x: int, y: int, c: int, n: int) list[int][source]

Classical software implementation of Alzette.

Parameters:
  • x – The integer value of x.

  • y – The integer value of y.

  • c – The c constant in Alzette.

  • n – The number of bits on which x, y and n are encoded.

Returns:

\(\text{ALZETTE}(x, y)\).

pyqrypto.sparkle.c_ell(x: int, n: int) int[source]

Classical implementation of Sparkle’s ELL transformation.

Parameters:
  • x – The integer value of x.

  • n – The number of bits on which x is encoded.

Returns:

\(\text{ELL(x)}\).

pyqrypto.sparkle.c_rol(x: int, r: int, n: int) int[source]

Classical implementation of the left rotation.

Parameters:
  • x – The integer to rotate.

  • r – The rotation amount.

  • n – The number of bits on which x is encoded.

Returns:

The integer x rotated left by r bits.

pyqrypto.sparkle.c_ror(x: int, r: int, n: int) int[source]

Classical implementation of the right rotation.

Parameters:
  • x – The integer to rotate.

  • r – The rotation amount.

  • n – The number of bits on which x is encoded.

Returns:

The integer x rotated right by r bits.

pyqrypto.sparkle.c_traxl_enc(x: list[int], y: list[int], subkeys: list[int], tweak: list[int], n: int = 32, nsteps: int = 17) tuple[list[int], list[int]][source]

Classical implementation of TRAX-L.

Parameters:
  • x – [\(x_0\), \(x_1\), \(x_2\), \(x_3\)] where \(x_i\) is a n-bit integer.

  • y – [\(y_0\), \(y_1\), \(y_2\), \(y_3\)] where \(y_i\) is a n-bit integer.

  • subkeys – A list of 8*( nsteps +1) n-bit subkey parts.

  • tweak – A list of the 4 n-bit tweak parts.

  • n – Size of each key part.

  • nsteps – Number of rounds.

Returns:

Encrypted (x,y).

pyqrypto.sparkle.c_traxl_genkeys(key: list[int], n: int = 32, nsteps: int = 17) list[int][source]

Classical implementation of TRAX-L key generation.

Parameters:
  • key – A list of the 8 n-bit key parts.

  • n – Size of each key part.

Nsteps:

Number of rounds.

Returns:

A list of 8*( nsteps +1) n-bit subkey parts.

pyqrypto.sparkle.c_traxm_enc(x: list[int], y: list[int], subkeys: list[int], tweak: list[int], n: int = 32, nsteps: int = 12, final_addition=True) tuple[list[int], list[int]][source]

Classical implementation of TRAX-M.

Parameters:
  • x – [\(x_0\), \(x_1\)] where \(x_i\) is a n-bit integer.

  • y – [\(y_0\), \(y_1\)] where \(y_i\) is a n-bit integer.

  • subkeys – A list of 4*( nsteps +1) n-bit subkey parts.

  • tweak – A list of the 2 n-bit tweak parts.

  • n – Size of each key part.

  • nsteps – Number of rounds.

  • final_addition – Whether to do the final key addition

Returns:

Encrypted (x,y).

pyqrypto.sparkle.c_traxs_enc(x: int, y: int, subkeys: list[int], tweak: list[int], n: int = 32, nsteps: int = 10, final_addition=True) tuple[int, int][source]

Classical implementation of TRAX-S.

Parameters:
  • x – A n-bit integer.

  • y – A n-bit integer.

  • subkeys – A list of 2*( nsteps +1) n-bit subkey parts.

  • tweak – A list of the 2 n-bit tweak parts.

  • n – Size of each key part.

  • nsteps – Number of rounds.

  • final_addition – Whether to do the final key addition.

Returns:

Encrypted (x,y).