Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"friendly_name": "Elliptic Curve Discrete Logarithm",
"description": "Solving Elliptic Curve Discrete Logarithm Problem using Shor's Algorithm",
"level": ["advanced"],
"problem_domain_tags": [],
"qmod_type": ["algorithms"],
"vertical_tags": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,302 @@
qstruct EllipticCurvePoint {
x: qnum<3>;
y: qnum<3>;
}

qfunc hadamard_transform_expanded___0(target: qbit[3]) {
repeat (index: 3) {
H(target[index]);
}
}

qperm modular_add_constant_inplace_expanded___0(modulus: int, a: int, x: qnum<3, False, 0>) {
carry: qbit;
allocate(1, carry);
temp: qnum<4, True, 0>;
within {
{x, carry} -> temp;
} apply {
temp += a;
temp += -modulus;
}
control (carry) {
x += modulus;
}
carry ^= x >= a;
free(carry);
}

qperm mock_modular_inverse_expanded___0(const x: qnum<3, False, 0>, result: qnum<3, False, 0>) {
result ^= [0, 1, 4, 5, 2, 3, 6, 0][x];
}

qperm modular_add_inplace_expanded___0(modulus: int, const x: qnum<3, False, 0>, y: qnum<3, False, 0>) {
carry: qbit;
allocate(1, carry);
temp: qnum<4, True, 0>;
within {
{y, carry} -> temp;
} apply {
temp += x;
temp += -modulus;
}
control (carry) {
y += modulus;
}
carry ^= y >= x;
free(carry);
}

qperm cyclic_shift_left_expanded___0(reg: qbit[4]) {
repeat (i: 3) {
SWAP(reg[(4 - i) - 1], reg[(4 - i) - 2]);
}
}

qperm modular_double_inplace_expanded___0(modulus: int, x: qnum<3, False, 0>) {
carry: qbit;
allocate(1, carry);
res_and_carry: qnum<4, True, 0>;
within {
{x, carry} -> res_and_carry;
} apply {
cyclic_shift_left_expanded___0(res_and_carry);
res_and_carry += -modulus;
}
control (carry) {
x += modulus;
}
carry ^= (x % 2) == 0;
free(carry);
}

qperm modular_multiply_expanded___0(modulus: int, const x: qbit[3], const y: qbit[3], z: qbit[3]) {
repeat (idx: 3) {
control (x[(3 - idx) - 1]) {
modular_add_inplace_expanded___0(modulus, y, z);
}
if (idx != 2) {
modular_double_inplace_expanded___0(modulus, z);
}
}
}

qperm modular_square_expanded___0(modulus: int, const x: qbit[3], z: qbit[3]) {
repeat (i: 2) {
control (x[(3 - i) - 1]) {
modular_add_inplace_expanded___0(modulus, x, z);
}
modular_double_inplace_expanded___0(modulus, z);
}
control (x[0]) {
modular_add_inplace_expanded___0(modulus, x, z);
}
}

qperm apply_to_all_expanded___0(target: qbit[3]) {
repeat (index: 3) {
X(target[index]);
}
}

qperm bitwise_negate_expanded___0(x: qbit[3]) {
apply_to_all_expanded___0(x);
}

qperm modular_negate_inplace_expanded___0(modulus: int, x: qnum<3, False, 0>) {
is_all_zeros: qbit;
allocate(1, is_all_zeros);
is_all_zeros ^= x == 0;
control (is_all_zeros) {
x += modulus;
}
x += 7 - modulus;
is_all_zeros ^= x == 7;
bitwise_negate_expanded___0(x);
free(is_all_zeros);
}

qperm modular_subtract_inplace_expanded___0(modulus: int, const x: qnum<3, False, 0>, y: qnum<3, False, 0>) {
modular_negate_inplace_expanded___0(modulus, y);
modular_add_inplace_expanded___0(modulus, x, y);
}

qperm mock_modular_inverse_expanded___1(const x: qnum<3, False, 0>, result: qnum<3, False, 0>) {
result ^= [0, 1, 4, 5, 2, 3, 6, 0][x];
}

qperm ec_point_add_expanded___0(ecp: EllipticCurvePoint) {
slope: qnum<3, False, 0>;
allocate(3, slope);
t0: qnum<3, False, 0>;
allocate(3, t0);
modular_add_constant_inplace_expanded___0(7, 2, ecp.y);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
within {
mock_modular_inverse_expanded___0(ecp.x, t0);
} apply {
modular_multiply_expanded___0(7, t0, ecp.y, slope);
}
within {
modular_multiply_expanded___0(7, slope, ecp.x, t0);
} apply {
ecp.y ^= t0;
}
within {
modular_square_expanded___0(7, slope, t0);
} apply {
modular_subtract_inplace_expanded___0(7, t0, ecp.x);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
}
modular_multiply_expanded___0(7, slope, ecp.x, ecp.y);
t1: qnum<3, False, 0>;
within {
mock_modular_inverse_expanded___1(ecp.x, t0);
} apply {
within {
allocate(3, t1);
modular_multiply_expanded___0(7, t0, ecp.y, t1);
} apply {
slope ^= t1;
}
}
free(slope);
modular_add_constant_inplace_expanded___0(7, 2, ecp.y);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
}

qperm ec_point_add_expanded___1(ecp: EllipticCurvePoint) {
slope: qnum<3, False, 0>;
allocate(3, slope);
t0: qnum<3, False, 0>;
allocate(3, t0);
modular_add_constant_inplace_expanded___0(7, 6, ecp.y);
modular_add_constant_inplace_expanded___0(7, 5, ecp.x);
within {
mock_modular_inverse_expanded___0(ecp.x, t0);
} apply {
modular_multiply_expanded___0(7, t0, ecp.y, slope);
}
within {
modular_multiply_expanded___0(7, slope, ecp.x, t0);
} apply {
ecp.y ^= t0;
}
within {
modular_square_expanded___0(7, slope, t0);
} apply {
modular_subtract_inplace_expanded___0(7, t0, ecp.x);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 6, ecp.x);
}
modular_multiply_expanded___0(7, slope, ecp.x, ecp.y);
t1: qnum<3, False, 0>;
within {
mock_modular_inverse_expanded___1(ecp.x, t0);
} apply {
within {
allocate(3, t1);
modular_multiply_expanded___0(7, t0, ecp.y, t1);
} apply {
slope ^= t1;
}
}
free(slope);
modular_add_constant_inplace_expanded___0(7, 6, ecp.y);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 2, ecp.x);
}

qperm ec_point_add_expanded___2(ecp: EllipticCurvePoint) {
slope: qnum<3, False, 0>;
allocate(3, slope);
t0: qnum<3, False, 0>;
allocate(3, t0);
modular_add_constant_inplace_expanded___0(7, 5, ecp.y);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
within {
mock_modular_inverse_expanded___0(ecp.x, t0);
} apply {
modular_multiply_expanded___0(7, t0, ecp.y, slope);
}
within {
modular_multiply_expanded___0(7, slope, ecp.x, t0);
} apply {
ecp.y ^= t0;
}
within {
modular_square_expanded___0(7, slope, t0);
} apply {
modular_subtract_inplace_expanded___0(7, t0, ecp.x);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
}
modular_multiply_expanded___0(7, slope, ecp.x, ecp.y);
t1: qnum<3, False, 0>;
within {
mock_modular_inverse_expanded___1(ecp.x, t0);
} apply {
within {
allocate(3, t1);
modular_multiply_expanded___0(7, t0, ecp.y, t1);
} apply {
slope ^= t1;
}
}
free(slope);
modular_add_constant_inplace_expanded___0(7, 5, ecp.y);
modular_negate_inplace_expanded___0(7, ecp.x);
modular_add_constant_inplace_expanded___0(7, 0, ecp.x);
}

qperm ec_scalar_mult_add_expanded___0(ecp: EllipticCurvePoint, k: qbit[3]) {
control (k[0]) {
ec_point_add_expanded___0(ecp);
}
control (k[1]) {
ec_point_add_expanded___1(ecp);
}
control (k[2]) {
ec_point_add_expanded___2(ecp);
}
}

qfunc qft_no_swap_expanded___0(qbv: qbit[3]) {
repeat (i: 3) {
H(qbv[i]);
repeat (j: (3 - i) - 1) {
CPHASE(pi / (2 ** (j + 1)), qbv[(i + j) + 1], qbv[i]);
}
}
}

qfunc qft_expanded___0(target: qbit[3]) {
repeat (index: 1.5) {
SWAP(target[index], target[2 - index]);
}
qft_no_swap_expanded___0(target);
}

qfunc shor_ecdlp_expanded___0(output x1: qnum<3, False, 3>, output x2: qnum<3, False, 3>, output ecp: EllipticCurvePoint) {
allocate(3, False, 3, x1);
allocate(3, False, 3, x2);
allocate(6, ecp);
ecp.x ^= 4;
ecp.y ^= 2;
hadamard_transform_expanded___0(x1);
hadamard_transform_expanded___0(x2);
ec_scalar_mult_add_expanded___0(ecp, x1);
ec_scalar_mult_add_expanded___0(ecp, x2);
invert {
qft_expanded___0(x1);
}
invert {
qft_expanded___0(x2);
}
}

qfunc main(output x1: qnum<3, False, 3>, output x2: qnum<3, False, 3>, output ecp: EllipticCurvePoint) {
shor_ecdlp_expanded___0(x1, x2, ecp);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"constraints": {
"max_gate_count": {},
"optimization_parameter": "width"
},
"preferences": {
"custom_hardware_settings": {
"basis_gates": [
"rx",
"h",
"r",
"tdg",
"cz",
"s",
"sdg",
"z",
"u",
"cx",
"y",
"sx",
"x",
"id",
"sxdg",
"ry",
"cy",
"t",
"p",
"rz",
"u2",
"u1"
],
"is_symmetric_connectivity": true
},
"debug_mode": true,
"machine_precision": 8,
"optimization_level": 1,
"output_format": ["qasm"],
"pretty_qasm": true,
"qasm3": true,
"random_seed": 3794060243,
"synthesize_all_separately": false,
"timeout_seconds": 3600,
"transpilation_option": "auto optimize"
}
}
21 changes: 21 additions & 0 deletions tests/notebooks/test_elliptic_curve_discrete_log.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from tests.utils_for_testbook import (
validate_quantum_program_size,
validate_quantum_model,
wrap_testbook,
)
from testbook.client import TestbookNotebookClient


@wrap_testbook("elliptic_curve_discrete_log", timeout_seconds=1800)
def test_notebook(tb: TestbookNotebookClient) -> None:
# test models
validate_quantum_model(tb.ref("qmod"))
# test quantum programs
validate_quantum_program_size(
tb.ref_pydantic("qprog_shor_ecdlp"),
expected_width=25,
expected_depth=100000,
)

# test notebook content
pass # Todo
2 changes: 2 additions & 0 deletions tests/resources/timeouts.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ dqi_max_xorsat.qmod: 200
dt_quantumwalk_complex_network.qmod: 1799
electric_grid_optimization.ipynb: 996
electric_grid_optimization.qmod: 1152
elliptic_curve_discrete_log.ipynb: 1800
elliptic_curve_discrete_log.qmod: 1800
encode_in_angle.qmod: 10
encode_on_bloch.qmod: 10
entanglement.ipynb: 20
Expand Down
Loading