Skip to content

Commit

Permalink
Crypto example programs. (#518)
Browse files Browse the repository at this point in the history
  • Loading branch information
msoeken authored Oct 31, 2023
1 parent 68a3fd2 commit 656c5ac
Show file tree
Hide file tree
Showing 3 changed files with 226 additions and 2 deletions.
23 changes: 21 additions & 2 deletions azure-quantum/examples/resource_estimation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ python -m pip install azure-quantum

## Example scripts

* **[cli.py](https://github.com/microsoft/qdk-python/blob/main/azure-quantum/examples/resource_estimation/cli.py): A resource estimation CLI that can execute resource
estimation jobs from various input formats and generate JSON output.**
* **[cli.py](https://github.com/microsoft/qdk-python/blob/main/azure-quantum/examples/resource_estimation/cli.py): A resource estimation CLI that can execute resource estimation jobs from various input formats and generate JSON output.**

The input type is determined by file extension:

Expand Down Expand Up @@ -51,3 +50,23 @@ python -m pip install azure-quantum
-p cli_test_files/multiplier.json \
-o output.json
```

* **[rsa.py](https://github.com/microsoft/qdk-python/blob/main/azure-quantum/examples/resource_estimation/rsa.py): Physical resource estimation for RSA using a pre-compiled QIR code.**

You can change the parameters to the factoring algorithm, e.g., the prime product, inside the code.

Usage:

```shell
python rsa.py -r "resource_id" -l "location"
```

* **[ecc.py](https://github.com/microsoft/qdk-python/blob/main/azure-quantum/examples/resource_estimation/ecc.py): Physical resource estimation for Elliptic Curve Cryptography starting from logical resource estimates.**

The possible key sizes are 256, 384, and 521.

Usage:

```shell
python ecc.py -k 256 -r "resource_id" -l "location"
```
117 changes: 117 additions & 0 deletions azure-quantum/examples/resource_estimation/ecc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
##
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
##

# Physical resource estimation for Elliptic Curve Cryptography starting from
# logical resource estimates

import argparse
import os
from azure.quantum import Workspace
from azure.quantum.target.microsoft import MicrosoftEstimator, QubitParams, \
QECScheme
import qsharp

# Configure program arguments
parser = argparse.ArgumentParser(
prog="rsa",
description="Physical resource estimation for Elliptic Curve Cryptography "
"starting from logical resource estimates")

parser.add_argument(
"-k",
"--keysize",
default=256,
help="Key size (256, 384, 521)")

parser.add_argument(
"-r",
"--resource-id",
default=os.environ.get("AZURE_QUANTUM_RESOURCE_ID"),
help="Resource ID of Azure Quantum workspace (must be set, unless set via "
"environment variable AZURE_QUANTUM_RESOURCE_ID)")

parser.add_argument(
"-l",
"--location",
default=os.environ.get("AZURE_QUANTUM_LOCATION"),
help="Location of Azure Quantum workspace (must be set, unless set via "
"environment AZURE_QUANTUM_LOCATION)")

# Parse and validate arguments
args = parser.parse_args()

if not args.resource_id:
parser.error("the following arguments are required: -r/--resource-id")
if not args.location:
parser.error("the following arguments are required: -l/--location")

# define and compile Q# operation
ECCEstimates = qsharp.compile('''
open Microsoft.Quantum.ResourceEstimation;
operation ECCEstimates(keysize: Int) : Unit {
if keysize == 256 {
use qubits = Qubit[2124];
AccountForEstimates([
TCount(7387343750), // 1.72 * 2.0^32
MeasurementCount(118111601) // 1.76 * 2.0^26
], PSSPCLayout(), qubits);
} elif keysize == 384 {
use qubits = Qubit[3151];
AccountForEstimates([
TCount(25941602468), // 1.51 * 2.0^34
MeasurementCount(660351222) // 1.23 * 2.0^29
], PSSPCLayout(), qubits);
} elif keysize == 521 {
use qubits = Qubit[4258];
AccountForEstimates([
TCount(62534723830), // 1.82 * 2.0^35
MeasurementCount(1707249501) // 1.59 * 2.0^30
], PSSPCLayout(), qubits);
} else {
fail $"keysize {keysize} is not supported";
}
}
''')

# connect to Azure Quantum workspace (you can find the information for your
# resource_id and location on the Overview page of your Quantum workspace)
workspace = Workspace(resource_id=args.resource_id, location=args.location)
estimator = MicrosoftEstimator(workspace)

params = estimator.make_params(num_items=4)

params.arguments["keysize"] = int(args.keysize)

# Error budget
params.error_budget = 0.333

# Gate-based (reasonable)
params.items[0].qubit_params.name = QubitParams.GATE_NS_E3
# Gate-based (optimistic)
params.items[1].qubit_params.name = QubitParams.GATE_NS_E4
# Majorana (reasonable)
params.items[2].qubit_params.name = QubitParams.MAJ_NS_E4
params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
# Majorana (optimistic)
params.items[3].qubit_params.name = QubitParams.MAJ_NS_E6
params.items[3].qec_scheme.name = QECScheme.FLOQUET_CODE

job = estimator.submit(ECCEstimates, input_params=params)
results = job.get_results()

table = results.summary_data_frame(labels=[
"Gate-based (reasonable)",
"Gate-based (optimistic)",
"Majorana (reasonable)",
"Majorana (optimistic)"
])

print()
print(table[["Physical qubits", "Physical runtime"]])

## Access non-formatted values, e.g.,
# print(results[0]["physicalCounts"]["physicalQubits"])
# print(results[0]["physicalCounts"]["runtime"])
88 changes: 88 additions & 0 deletions azure-quantum/examples/resource_estimation/rsa.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
##
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
##

# Physical resource estimation for RSA using a pre-compiled QIR code

import argparse
import os
from azure.quantum import Workspace
from azure.quantum.target.microsoft import MicrosoftEstimator, QubitParams, \
QECScheme

# Configure program arguments
parser = argparse.ArgumentParser(
prog="rsa",
description="Physical resource estimation for RSA using a pre-compiled "
"QIR code")

parser.add_argument(
"-r",
"--resource-id",
default=os.environ.get("AZURE_QUANTUM_RESOURCE_ID"),
help="Resource ID of Azure Quantum workspace (must be set, unless set via "
"environment variable AZURE_QUANTUM_RESOURCE_ID)")

parser.add_argument(
"-l",
"--location",
default=os.environ.get("AZURE_QUANTUM_LOCATION"),
help="Location of Azure Quantum workspace (must be set, unless set via "
"environment AZURE_QUANTUM_LOCATION)")

# Parse and validate arguments
args = parser.parse_args()

if not args.resource_id:
parser.error("the following arguments are required: -r/--resource-id")
if not args.location:
parser.error("the following arguments are required: -l/--location")

# download QIR bitcode

import urllib.request
bitcode = urllib.request.urlopen("https://aka.ms/RE/eh_factoring").read()

# connect to Azure Quantum workspace (you can find the information for your
# resource_id and location on the Overview page of your Quantum workspace)
workspace = Workspace(resource_id=args.resource_id, location=args.location)
estimator = MicrosoftEstimator(workspace)

params = estimator.make_params(num_items=4)

params.arguments["product"] = "25195908475657893494027183240048398571429282126204032027777137836043662020707595556264018525880784406918290641249515082189298559149176184502808489120072844992687392807287776735971418347270261896375014971824691165077613379859095700097330459748808428401797429100642458691817195118746121515172654632282216869987549182422433637259085141865462043576798423387184774447920739934236584823824281198163815010674810451660377306056201619676256133844143603833904414952634432190114657544454178424020924616515723350778707749817125772467962926386356373289912154831438167899885040445364023527381951378636564391212010397122822120720357"
params.arguments["generator"] = 7
params.arguments["exp_window_len"] = 5
params.arguments["mul_window_len"] = 5

# Error budget
params.error_budget = 0.333

# Gate-based (reasonable)
params.items[0].qubit_params.name = QubitParams.GATE_NS_E3
# Gate-based (optimistic)
params.items[1].qubit_params.name = QubitParams.GATE_NS_E4
# Majorana (reasonable)
params.items[2].qubit_params.name = QubitParams.MAJ_NS_E4
params.items[2].qec_scheme.name = QECScheme.FLOQUET_CODE
# Majorana (optimistic)
params.items[3].qubit_params.name = QubitParams.MAJ_NS_E6
params.items[3].qec_scheme.name = QECScheme.FLOQUET_CODE

job = estimator.submit(bitcode, input_params=params)
results = job.get_results()

table = results.summary_data_frame(labels=[
"Gate-based (reasonable)",
"Gate-based (optimistic)",
"Majorana (reasonable)",
"Majorana (optimistic)"
])

print()
print(table[["Physical qubits", "Physical runtime"]])

## Access non-formatted values, e.g.,
# print(results[0]["physicalCounts"]["physicalQubits"])
# print(results[0]["physicalCounts"]["runtime"])

0 comments on commit 656c5ac

Please sign in to comment.