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].
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,RegisterOperationA 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_modeislookahead.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:
n – The size of the two inputs of Alzette.
adder_mode – See
RegisterCircuit.add.
- 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,RegisterOperationA 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,RegisterOperationA 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,RegisterOperationA 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).